From 0bfcd4bc9cbffe80515f0a66d8c6382475c05fcb Mon Sep 17 00:00:00 2001 From: Welp Date: Wed, 5 May 2021 08:59:36 -0700 Subject: [PATCH 001/116] Make weight() use include_contents The behavior of existing calls should not be affected by this change. --- src/item.cpp | 8 +++++--- src/item.h | 5 +++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/item.cpp b/src/item.cpp index 5abee103d7c07..397bc8852b289 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -5097,7 +5097,7 @@ int item::price( bool practical ) const } // TODO: MATERIALS add a density field to materials.json -units::mass item::weight( bool, bool integral ) const +units::mass item::weight( bool include_contents, bool integral ) const { if( is_null() ) { return 0_gram; @@ -5131,6 +5131,10 @@ units::mass item::weight( bool, bool integral ) const ret *= 0.75; } + if (include_contents) { + ret += contents.item_weight_modifier(); + } + // if this is a gun apply all of its gunmods' weight multipliers if( type->gun ) { for( const item *mod : gunmods() ) { @@ -5189,8 +5193,6 @@ units::mass item::weight( bool, bool integral ) const if( magazine_current() ) { ret += magazine_current()->weight(); } - } else { - ret += contents.item_weight_modifier(); } return ret; diff --git a/src/item.h b/src/item.h index 6290008679cd7..9df2b72a65b32 100644 --- a/src/item.h +++ b/src/item.h @@ -566,6 +566,11 @@ class item : public visitable */ bool merge_charges( const item &rhs ); + /** + * Total weight of an item accounting for all contained/integrated items + * @param include_contents if true include weight of contained items + * @param integral if true return effective weight if this item was integrated into another + */ units::mass weight( bool include_contents = true, bool integral = false ) const; /** From 6a130f85fe9919b1aea195bb6aff47318f8ca66f Mon Sep 17 00:00:00 2001 From: Welp Date: Wed, 5 May 2021 17:53:16 -0700 Subject: [PATCH 002/116] Simplify weight(), remove accidental double-count of gunmods and ammo --- src/item.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/item.cpp b/src/item.cpp index 397bc8852b289..4e8eb32f36c10 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -5131,9 +5131,6 @@ units::mass item::weight( bool include_contents, bool integral ) const ret *= 0.75; } - if (include_contents) { - ret += contents.item_weight_modifier(); - } // if this is a gun apply all of its gunmods' weight multipliers if( type->gun ) { @@ -5170,6 +5167,10 @@ units::mass item::weight( bool include_contents, bool integral ) const } } + if( include_contents ) { + ret += contents.item_weight_modifier(); + } + // if this is an ammo belt add the weight of any implicitly contained linkages if( type->magazine && type->magazine->linkage ) { item links( *type->magazine->linkage ); @@ -5186,15 +5187,6 @@ units::mass item::weight( bool include_contents, bool integral ) const ret -= std::min( max_barrel_weight, barrel_weight ); } - if( is_gun() ) { - for( const item *elem : gunmods() ) { - ret += elem->weight( true, true ); - } - if( magazine_current() ) { - ret += magazine_current()->weight(); - } - } - return ret; } From c20465baada978dcc8a8a0944ef14ac0f55b1ae8 Mon Sep 17 00:00:00 2001 From: Welp Date: Thu, 6 May 2021 11:30:21 -0700 Subject: [PATCH 003/116] Remove double count of ammo in internal magazines. The special case for plutonium cells confused me a bit, I think anything that would get caught by it gets caught by the count by charges section above. --- src/item.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/item.cpp b/src/item.cpp index 4e8eb32f36c10..d9100c811475b 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -5158,13 +5158,6 @@ units::mass item::weight( bool include_contents, bool integral ) const ret *= 0.85; } - } else if( magazine_integral() && ( !is_magazine() || is_gun() ) ) { - if( ammo_current() == itype_plut_cell ) { - ret += ammo_remaining() * find_type( ammotype( - *ammo_types().begin() )->default_ammotype() )->weight / PLUTONIUM_CHARGES; - } else if( ammo_data() ) { - ret += ammo_remaining() * ammo_data()->weight; - } } if( include_contents ) { From 3e95d01c5806928b6ec2c7bb0b3870091e0529ce Mon Sep 17 00:00:00 2001 From: Welp Date: Thu, 6 May 2021 13:54:58 -0700 Subject: [PATCH 004/116] Add Tests --- tests/item_contents_test.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/item_contents_test.cpp b/tests/item_contents_test.cpp index 7a07eed26732e..cdfa228639cab 100644 --- a/tests/item_contents_test.cpp +++ b/tests/item_contents_test.cpp @@ -18,6 +18,10 @@ TEST_CASE( "item_contents" ) const units::volume tool_belt_vol = tool_belt.volume(); const units::mass tool_belt_weight = tool_belt.weight(); + //check empty weight is consistent + CHECK( tool_belt.weight( true ) == tool_belt.type->weight ); + CHECK( tool_belt.weight( false ) == tool_belt.type->weight ); + item hammer( "hammer" ); item tongs( "tongs" ); item wrench( "wrench" ); @@ -53,6 +57,8 @@ TEST_CASE( "item_contents" ) // check that the tool belt's weight adds up all its contents properly CHECK( tool_belt.weight() == tool_belt_weight + hammer.weight() + tongs.weight() + wrench.weight() + crowbar.weight() ); + // check that individual (not including contained items) weight is correct + CHECK( tool_belt.weight( false ) == tool_belt.type->weight ); // check that the tool belt is "full" CHECK( !tool_belt.contents.can_contain( hammer ).success() ); From c04fe4cd8d20d8fba179628ee7b898f985f3aa1f Mon Sep 17 00:00:00 2001 From: mqrause Date: Wed, 16 Jun 2021 00:04:55 +0200 Subject: [PATCH 005/116] ignore pocket settings when manually inserting stackable items --- src/activity_actor.cpp | 3 ++- src/item.cpp | 11 +++++------ src/item.h | 5 +++-- src/item_contents.cpp | 4 ++-- src/item_contents.h | 2 +- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index 11ab3fd8f6846..984fc75d120ff 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -2429,7 +2429,8 @@ void insert_item_activity_actor::finish( player_activity &act, Character &who ) if( charges > 0 && holster->can_contain_partial( it ) ) { int result = holster->fill_with( it, charges, /*unseal_pockets=*/true, - /*allow_sealed=*/true ); + /*allow_sealed=*/true, + /*ignore_settings*/true ); success = result > 0; if( success ) { diff --git a/src/item.cpp b/src/item.cpp index 67d8ac5162046..6566a3c6c720a 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -7331,11 +7331,10 @@ bool item::can_contain_partial( const item &it ) const } std::pair item::best_pocket( const item &it, item_location &parent, - const bool allow_sealed ) + const bool allow_sealed, const bool ignore_settings ) { item_location nested_location( parent, this ); - return contents.best_pocket( it, nested_location, false, - /*allow_sealed=*/allow_sealed ); + return contents.best_pocket( it, nested_location, false, allow_sealed, ignore_settings ); } bool item::spill_contents( Character &c ) @@ -8940,7 +8939,8 @@ void item::set_item_temperature( float new_temperature ) int item::fill_with( const item &contained, const int amount, const bool unseal_pockets, - const bool allow_sealed ) + const bool allow_sealed, + const bool ignore_settings ) { if( amount <= 0 ) { return 0; @@ -8959,8 +8959,7 @@ int item::fill_with( const item &contained, const int amount, if( count_by_charges ) { contained_item.charges = 1; } - pocket = best_pocket( contained_item, loc, - /*allow_sealed=*/allow_sealed ).second; + pocket = best_pocket( contained_item, loc, allow_sealed, ignore_settings ).second; } if( pocket == nullptr ) { break; diff --git a/src/item.h b/src/item.h index 6290008679cd7..06b55d81b002b 100644 --- a/src/item.h +++ b/src/item.h @@ -755,7 +755,8 @@ class item : public visitable */ int fill_with( const item &contained, int amount = INFINITE_CHARGES, bool unseal_pockets = false, - bool allow_sealed = false ); + bool allow_sealed = false, + bool ignore_settings = false ); /** * How much more of this liquid (in charges) can be put in this container. @@ -1277,7 +1278,7 @@ class item : public visitable bool can_contain_partial( const item &it ) const; /*@}*/ std::pair best_pocket( const item &it, item_location &parent, - bool allow_sealed = false ); + bool allow_sealed = false, bool ignore_settings = false ); units::length max_containable_length() const; units::volume max_containable_volume() const; diff --git a/src/item_contents.cpp b/src/item_contents.cpp index e9b93f6fae5ca..4ef5ffccbb0e7 100644 --- a/src/item_contents.cpp +++ b/src/item_contents.cpp @@ -473,7 +473,7 @@ void item_contents::force_insert_item( const item &it, item_pocket::pocket_type } std::pair item_contents::best_pocket( const item &it, - item_location &parent, bool nested, const bool allow_sealed ) + item_location &parent, bool nested, const bool allow_sealed, const bool ignore_settings ) { if( !can_contain( it ).success() ) { return { item_location(), nullptr }; @@ -497,7 +497,7 @@ std::pair item_contents::best_pocket( const item & if( !pocket.can_contain( it ).success() ) { continue; } - if( !pocket.settings.accepts_item( it ) ) { + if( !ignore_settings && !pocket.settings.accepts_item( it ) ) { // Item forbidden by whitelist / blacklist continue; } diff --git a/src/item_contents.h b/src/item_contents.h index 331cc3a9567bd..be44d79790dff 100644 --- a/src/item_contents.h +++ b/src/item_contents.h @@ -41,7 +41,7 @@ class item_contents * only checks CONTAINER pocket type */ std::pair best_pocket( const item &it, item_location &parent, - bool nested, bool allow_sealed = false ); + bool nested, bool allow_sealed = false, bool ignore_settings = false ); units::length max_containable_length() const; units::volume max_containable_volume() const; From 547b6580bfb56470b8b0b39e8da68bc44d52bb40 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Mon, 21 Jun 2021 17:08:47 -0700 Subject: [PATCH 006/116] Allow "armor" to replace "armor_portion_data" `armor_portion_data` is a really long key name, and it doesn't need to be that long - it's quite annoying to type as is. Change the parsing code to accept it, and update the script to use the new, shorter key. --- src/item_factory.cpp | 8 +++++--- tools/json_tools/convert_to_portions.py | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/item_factory.cpp b/src/item_factory.cpp index 268614af0a89c..77114cf4ac1e1 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -1905,11 +1905,13 @@ std::string enum_to_string( layer_level data ) void islot_armor::load( const JsonObject &jo ) { - if( jo.has_array( "armor_portion_data" ) ) { + if( jo.has_array( "armor_portion_data" ) || jo.has_array( "armor" ) ) { + const JsonArray &arr = jo.has_array( "armor" ) ? jo.get_array( "armor" ) : + jo.get_array( "armor_portion_data" ); bool dont_add_first = false; if( !data.empty() ) { // Uses copy-from dont_add_first = true; - const JsonObject &obj = *jo.get_array( "armor_portion_data" ).begin(); + const JsonObject &obj = *arr.begin(); armor_portion_data tempData; if( obj.has_array( "encumbrance" ) ) { @@ -1938,7 +1940,7 @@ void islot_armor::load( const JsonObject &jo ) } } - for( const JsonObject obj : jo.get_array( "armor_portion_data" ) ) { + for( const JsonObject obj : arr ) { // If this item used copy-from, data[0] is already set, so skip adding first data if( dont_add_first ) { obj.allow_omitted_members(); diff --git a/tools/json_tools/convert_to_portions.py b/tools/json_tools/convert_to_portions.py index 60a423c782b2a..bb864459b8a60 100755 --- a/tools/json_tools/convert_to_portions.py +++ b/tools/json_tools/convert_to_portions.py @@ -25,12 +25,12 @@ def portionize(jo): dat["encumbrance"] = 0 dat["encumbrance"] = [dat["encumbrance"], dat.pop("max_encumbrance")] - if "armor_portion_data" not in jo: - jo["armor_portion_data"] = [dat] + if "armor" not in jo: + jo["armor"] = [dat] else: dat["//0"] = "Autogenned for item with non-portion and portion data" dat["//1"] = "Ensure that this works correctly!" - jo["armor_portion_data"].insert(0, dat) + jo["armor"].insert(0, dat) return jo From 86adadf87145018a434a27fd43abac0b6645ee8e Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Mon, 21 Jun 2021 17:12:54 -0700 Subject: [PATCH 007/116] Replace "armor_portion_data" with "armor" in data/ Now that we accept the shorter key, use it everywhere. --- data/json/items/armor/coats.json | 74 +++++++++---------- data/json/items/armor/gloves.json | 2 +- data/json/items/armor/helmets.json | 28 +++---- data/json/items/armor/holster.json | 2 +- data/json/items/armor/hoods.json | 2 +- data/json/items/armor/legs_clothes.json | 2 +- data/json/items/armor/masks.json | 2 +- data/json/items/armor/storage.json | 8 +- data/json/items/armor/suits_clothes.json | 16 ++-- data/json/items/armor/suits_protection.json | 42 +++++------ data/json/items/armor/swimming.json | 6 +- data/json/items/armor/torso_armor.json | 4 +- data/json/items/armor/torso_clothes.json | 16 ++-- data/json/items/tool_armor.json | 32 ++++---- data/mods/Aftershock/items/armor.json | 2 +- .../Aftershock/items/armor/winter_masks.json | 4 +- .../Aftershock/items/armor/winter_suits.json | 4 +- data/mods/Aftershock/suit_operating_time.md | 2 +- .../Magiclysm/items/black_dragon_items.json | 8 +- data/mods/TEST_DATA/items.json | 4 +- 20 files changed, 130 insertions(+), 130 deletions(-) diff --git a/data/json/items/armor/coats.json b/data/json/items/armor/coats.json index 2de782c9b6f22..952a1d622f620 100644 --- a/data/json/items/armor/coats.json +++ b/data/json/items/armor/coats.json @@ -15,7 +15,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "yellow", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 100, "encumbrance": [ 22, 26 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 100, "encumbrance": [ 22, 22 ] } ], @@ -84,7 +84,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 26, 30 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 26, 26 ] } ], @@ -153,7 +153,7 @@ "symbol": "[", "looks_like": "coat_fur", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 30, 35 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 30, 30 ] } ], @@ -194,7 +194,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "white", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 2, 5 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 2, 2 ] } ], @@ -238,7 +238,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "yellow", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 7, 15 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 7, 7 ] } ], @@ -276,7 +276,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "yellow", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": 12 }, { "covers": [ "arm_l", "arm_r" ], "coverage": 40, "encumbrance": 2 }, { "covers": [ "leg_l", "leg_r" ], "coverage": 50, "encumbrance": 0 } @@ -321,7 +321,7 @@ "symbol": "[", "looks_like": "coat_rain", "color": "light_red", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 18, 27 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 18, 21 ] } ], @@ -375,7 +375,7 @@ "symbol": "[", "looks_like": "trenchcoat", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 7, 13 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 90, "encumbrance": [ 7, 9 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 7, 7 ] } @@ -443,7 +443,7 @@ "symbol": "[", "looks_like": "duster_leather", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 9, 16 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 90, "encumbrance": [ 9, 11 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 9, 9 ] } @@ -547,7 +547,7 @@ "symbol": "[", "looks_like": "duster", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 8, 15 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 90, "encumbrance": [ 8, 10 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 8, 8 ] } @@ -625,7 +625,7 @@ "symbol": "[", "looks_like": "duster_leather", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 85, "encumbrance": [ 7, 13 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 85, "encumbrance": [ 7, 9 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 85, "encumbrance": [ 7, 7 ] } @@ -702,7 +702,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "blue", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 11, 20 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": [ 11, 13 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 11, 11 ] } @@ -798,7 +798,7 @@ "symbol": "[", "looks_like": "coat_lab", "color": "blue", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 85, "encumbrance": [ 5, 10 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 85, "encumbrance": [ 5, 5 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 85, "encumbrance": [ 5, 5 ] } @@ -838,7 +838,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "green", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 7, 15 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 7, 9 ] } ], @@ -905,7 +905,7 @@ "symbol": "[", "looks_like": "coat_lab", "color": "white", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 8, 13 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 8, 8 ] } ], @@ -936,7 +936,7 @@ "symbol": "[", "looks_like": "jacket_leather", "color": "cyan", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 13, 15 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 13, 13 ] } ], @@ -974,7 +974,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "light_red", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 9, 13 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 9, 9 ] } ], @@ -1012,7 +1012,7 @@ "symbol": "[", "looks_like": "jacket_windbreaker", "color": "light_blue", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 9, 11 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 9, 9 ] } ], @@ -1056,7 +1056,7 @@ "symbol": "[", "looks_like": "jacket_windbreaker", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 10, 15 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 10, 10 ] } ], @@ -1097,7 +1097,7 @@ "looks_like": "jacket_leather", "repairs_like": "jacket_leather", "color": "red", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 15, 20 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 15, 15 ] } ], @@ -1137,7 +1137,7 @@ "symbol": "[", "looks_like": "jacket_windbreaker", "color": "blue", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 4, 8 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 4, 4 ] } ], @@ -1175,7 +1175,7 @@ "symbol": "[", "looks_like": "jacket_light", "color": "cyan", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 6, 9 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 6, 7 ] } ], @@ -1326,7 +1326,7 @@ "symbol": "[", "looks_like": "robe", "color": "white", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 2, 5 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 90, "encumbrance": [ 2, 2 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 2, 2 ] } @@ -1358,7 +1358,7 @@ "symbol": "[", "looks_like": "kimono", "color": "blue", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 80, "encumbrance": [ 1, 3 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 80, "encumbrance": [ 1, 1 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 80, "encumbrance": [ 1, 1 ] } @@ -1433,7 +1433,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "blue", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 85, "encumbrance": [ 10, 20 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 85, "encumbrance": [ 10, 10 ] } ], @@ -1487,7 +1487,7 @@ "symbol": "[", "looks_like": "cloak", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 80, "encumbrance": [ 8, 15 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 80, "encumbrance": [ 8, 10 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 80, "encumbrance": [ 8, 8 ] } @@ -1576,7 +1576,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "light_blue", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 15, 22 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 15, 15 ] } ], @@ -1631,7 +1631,7 @@ "symbol": "[", "looks_like": "duster", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 7, 12 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 90, "encumbrance": [ 7, 10 ] } ], @@ -1699,7 +1699,7 @@ "symbol": "[", "looks_like": "duster_fur", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 9, 17 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 90, "encumbrance": [ 9, 11 ] } ], @@ -1778,7 +1778,7 @@ "symbol": "[", "looks_like": "duster_leather", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 8, 15 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 90, "encumbrance": [ 8, 10 ] } ], @@ -1848,7 +1848,7 @@ "symbol": "[", "looks_like": "duster_survivor", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 85, "encumbrance": [ 7, 13 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 85, "encumbrance": [ 7, 9 ] } ], @@ -2065,7 +2065,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 7, 15 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 7, 7 ] } ], @@ -2096,7 +2096,7 @@ "symbol": "[", "looks_like": "trenchcoat_leather", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 9, 19 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 9, 9 ] } ], @@ -2138,7 +2138,7 @@ "symbol": "[", "looks_like": "trenchcoat", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 8, 17 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 8, 8 ] } ], @@ -2171,7 +2171,7 @@ "symbol": "[", "looks_like": "trenchcoat", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 85, "encumbrance": [ 7, 15 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 85, "encumbrance": [ 7, 7 ] } ], @@ -2281,7 +2281,7 @@ "symbol": "[", "looks_like": "suit", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 13, 16 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": [ 13, 14 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 13, 13 ] } @@ -2372,7 +2372,7 @@ "symbol": "[", "looks_like": "coat_winter", "color": "white", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 10, 20 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 10, 10 ] } ], diff --git a/data/json/items/armor/gloves.json b/data/json/items/armor/gloves.json index 572a68700dc7e..fe759ff13b570 100644 --- a/data/json/items/armor/gloves.json +++ b/data/json/items/armor/gloves.json @@ -972,7 +972,7 @@ "symbol": "[", "looks_like": "gloves_light", "color": "light_blue", - "armor_portion_data": [ + "armor": [ { "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 2 }, { "covers": [ "arm_l", "arm_r" ], "coverage": 50, "encumbrance": 2 } ], diff --git a/data/json/items/armor/helmets.json b/data/json/items/armor/helmets.json index e39cfd8157e44..02a89dcf7d7f7 100644 --- a/data/json/items/armor/helmets.json +++ b/data/json/items/armor/helmets.json @@ -87,7 +87,7 @@ "symbol": "[", "looks_like": "helmet_motor", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": 30 }, { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 20 }, { "covers": [ "mouth" ], "coverage": 100, "encumbrance": 15 } @@ -188,7 +188,7 @@ "symbol": "[", "looks_like": "helmet_plate", "color": "light_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 95, "encumbrance": 20 }, { "covers": [ "eyes", "mouth" ], "coverage": 65, "encumbrance": 0 } ], @@ -245,7 +245,7 @@ "symbol": "[", "looks_like": "helmet_larmor", "color": "green", - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 90, "encumbrance": 10 }, { "covers": [ "mouth", "eyes" ], "coverage": 90, "encumbrance": 5 } ], @@ -331,7 +331,7 @@ "symbol": "[", "looks_like": "helmet_motor", "color": "yellow", - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 95, "encumbrance": 50 }, { "covers": [ "eyes" ], "coverage": 75, "encumbrance": 5 }, { "covers": [ "mouth" ], "coverage": 85, "encumbrance": 0 } @@ -355,7 +355,7 @@ "symbol": "[", "looks_like": "helmet_barbute", "color": "light_gray", - "armor_portion_data": [ { "covers": [ "head" ], "coverage": 90, "encumbrance": 10 } ], + "armor": [ { "covers": [ "head" ], "coverage": 90, "encumbrance": 10 } ], "warmth": 10, "material_thickness": 3, "techniques": [ "WBLOCK_1" ], @@ -386,7 +386,7 @@ "symbol": "[", "looks_like": "helmet_barbute", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 95, "encumbrance": 20 }, { "covers": [ "eyes" ], "coverage": 35, "encumbrance": 0 }, { "covers": [ "mouth" ], "coverage": 95, "encumbrance": 10 } @@ -494,7 +494,7 @@ "symbol": "[", "looks_like": "helmet_barbute", "color": "light_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 98, "encumbrance": 20 }, { "covers": [ "eyes" ], "coverage": 65, "encumbrance": 0 }, { "covers": [ "mouth" ], "coverage": 40, "encumbrance": 0 } @@ -520,7 +520,7 @@ "material": [ "plastic", "nomex" ], "symbol": "[", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": 25 }, { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 5 }, { "covers": [ "mouth" ], "coverage": 100, "encumbrance": 15 } @@ -546,7 +546,7 @@ "symbol": "[", "looks_like": "helmet_barbute", "color": "light_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 85, "encumbrance": 10 }, { "covers": [ "eyes" ], "coverage": 25, "encumbrance": 0 } ], @@ -578,7 +578,7 @@ "symbol": "[", "looks_like": "balclava", "color": "white", - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 95, "encumbrance": 20 }, { "covers": [ "eyes", "mouth" ], "coverage": 95, "encumbrance": 5 } ], @@ -611,7 +611,7 @@ "symbol": "[", "looks_like": "helmet_barbute", "color": "light_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": 40 }, { "covers": [ "mouth" ], "coverage": 100, "encumbrance": 30 }, { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 20 } @@ -645,7 +645,7 @@ "symbol": "[", "looks_like": "mask_gas", "color": "white", - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": 23 }, { "covers": [ "eyes", "mouth" ], "coverage": 100, "encumbrance": 5 } ], @@ -680,7 +680,7 @@ "symbol": "[", "looks_like": "helmet_plate", "color": "light_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 80, "encumbrance": 35 }, { "covers": [ "eyes", "mouth" ], "coverage": 80, "encumbrance": 10 } ], @@ -760,7 +760,7 @@ "symbol": "[", "looks_like": "helmet_plate", "color": "yellow", - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 95, "encumbrance": 30 }, { "covers": [ "eyes" ], "coverage": 75, "encumbrance": 0 }, { "covers": [ "mouth" ], "coverage": 75, "encumbrance": 0 } diff --git a/data/json/items/armor/holster.json b/data/json/items/armor/holster.json index b9089a167857d..626c346e1f5b0 100644 --- a/data/json/items/armor/holster.json +++ b/data/json/items/armor/holster.json @@ -215,7 +215,7 @@ "description": "A western style holster as worn by cowboys and gunfighters in the movies and on TV. Has loops across the back to hold spare ammo. Activate to holster/draw a gun.", "price_postapoc": 500, "sided": true, - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 5, "encumbrance": [ 1, 1 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 5, "encumbrance": [ 2, 3 ] } ], diff --git a/data/json/items/armor/hoods.json b/data/json/items/armor/hoods.json index 4e3649c008d37..c2195ca8f1926 100644 --- a/data/json/items/armor/hoods.json +++ b/data/json/items/armor/hoods.json @@ -13,7 +13,7 @@ "symbol": "[", "looks_like": "cowboy_hat", "color": "white", - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": 20 }, { "covers": [ "eyes", "mouth" ], "coverage": 100, "encumbrance": 5 } ], diff --git a/data/json/items/armor/legs_clothes.json b/data/json/items/armor/legs_clothes.json index 2cec4d2ef900e..c4ff4cb400773 100644 --- a/data/json/items/armor/legs_clothes.json +++ b/data/json/items/armor/legs_clothes.json @@ -102,7 +102,7 @@ "symbol": "[", "looks_like": "pants_ski", "color": "green", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 100, "encumbrance": [ 19, 23 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": [ 19, 21 ] }, { "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": [ 19, 19 ] } diff --git a/data/json/items/armor/masks.json b/data/json/items/armor/masks.json index a6407e28c343e..831faa1d1959a 100644 --- a/data/json/items/armor/masks.json +++ b/data/json/items/armor/masks.json @@ -113,7 +113,7 @@ "symbol": "[", "looks_like": "balclava", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "head", "eyes" ], "coverage": 90, "encumbrance": 10 }, { "covers": [ "mouth" ], "coverage": 90, "encumbrance": 0 } ], diff --git a/data/json/items/armor/storage.json b/data/json/items/armor/storage.json index 94e9fe29ee658..fb9ba31d5f2fb 100644 --- a/data/json/items/armor/storage.json +++ b/data/json/items/armor/storage.json @@ -233,7 +233,7 @@ "symbol": ")", "looks_like": "plastic_shopping_bag", "color": "light_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "arm_l", "arm_r" ], "coverage": 5, "encumbrance": [ 50, 50 ] }, { "covers": [ "hand_l", "hand_r" ], "coverage": 5, "encumbrance": [ 50, 50 ] } ], @@ -321,7 +321,7 @@ "looks_like": "plastic_shopping_bag", "color": "light_gray", "sided": true, - "armor_portion_data": [ + "armor": [ { "covers": [ "arm_l", "arm_r" ], "coverage": 4, "encumbrance": [ 30, 33 ] }, { "covers": [ "hand_l", "hand_r" ], "coverage": 4, "encumbrance": [ 30, 32 ] } ], @@ -1064,7 +1064,7 @@ "symbol": "[", "color": "white", "sided": true, - "armor_portion_data": [ + "armor": [ { "covers": [ "arm_l", "arm_r" ], "coverage": 4, "encumbrance": [ 1, 30 ] }, { "covers": [ "hand_l", "hand_r" ], "coverage": 4, "encumbrance": [ 1, 30 ] } ], @@ -1490,7 +1490,7 @@ "looks_like": "duffelbag", "color": "brown", "sided": true, - "armor_portion_data": [ + "armor": [ { "covers": [ "hand_l", "hand_r" ], "coverage": 5, "encumbrance": [ 4, 48 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 5, "encumbrance": [ 4, 48 ] } ], diff --git a/data/json/items/armor/suits_clothes.json b/data/json/items/armor/suits_clothes.json index 652b0f48446f9..1d3637643d72c 100644 --- a/data/json/items/armor/suits_clothes.json +++ b/data/json/items/armor/suits_clothes.json @@ -14,7 +14,7 @@ "symbol": "[", "looks_like": "armor_larmor", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": 20 }, { "covers": [ "arm_l", "arm_r" ], "coverage": 75, "encumbrance": 20 }, { "covers": [ "leg_l", "leg_r" ], "coverage": 75, "encumbrance": 20 } @@ -39,7 +39,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "pink", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 17, 30 ] }, { "covers": [ "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 95, "encumbrance": [ 17, 20 ] } ], @@ -67,7 +67,7 @@ "symbol": "[", "looks_like": "wolfsuit", "color": "light_green", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 100, "encumbrance": [ 26, 30 ] }, { "covers": [ "mouth", "eyes" ], "coverage": 95, "encumbrance": [ 26, 26 ] }, { "covers": [ "head" ], "coverage": 100, "encumbrance": [ 26, 26 ] } @@ -92,7 +92,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "yellow", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 1, 2 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 50, "encumbrance": [ 1, 1 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 80, "encumbrance": [ 1, 2 ] } @@ -121,7 +121,7 @@ "symbol": "[", "looks_like": "jumpsuit", "color": "yellow", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 1, 2 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 50, "encumbrance": [ 1, 1 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 80, "encumbrance": [ 1, 2 ] } @@ -161,7 +161,7 @@ "symbol": "[", "looks_like": "jumpsuit", "color": "yellow", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 3, 7 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 50, "encumbrance": [ 2, 2 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 60, "encumbrance": [ 2, 5 ] } @@ -187,7 +187,7 @@ "symbol": "[", "looks_like": "jumpsuit", "color": "light_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": 3 }, { "covers": [ "arm_l", "arm_r", "leg_l", "leg_r" ], "coverage": 90, "encumbrance": 3 } ], @@ -222,7 +222,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso", "leg_l", "leg_r" ], "coverage": 100, "encumbrance": 20 }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": 20 }, { "covers": [ "head" ], "coverage": 60, "encumbrance": 15 }, diff --git a/data/json/items/armor/suits_protection.json b/data/json/items/armor/suits_protection.json index c8b916b003ebc..cba679206370c 100644 --- a/data/json/items/armor/suits_protection.json +++ b/data/json/items/armor/suits_protection.json @@ -13,7 +13,7 @@ "symbol": "[", "looks_like": "hazmat_suit", "color": "light_red", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 100, "encumbrance": [ 10, 15 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": [ 10, 15 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 100, "encumbrance": [ 10, 10 ] } @@ -91,7 +91,7 @@ "symbol": "[", "looks_like": "armor_larmor", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 18, 22 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 90, "encumbrance": [ 18, 18 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 18, 18 ] } @@ -186,7 +186,7 @@ "symbol": "[", "looks_like": "armor_larmor", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 21, 25 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 90, "encumbrance": [ 21, 21 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 21, 21 ] } @@ -236,7 +236,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 12, 18 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 90, "encumbrance": [ 12, 12 ] } ], @@ -314,7 +314,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "light_red", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 10, 16 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": [ 10, 14 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 10, 13 ] } @@ -352,7 +352,7 @@ "looks_like": "armor_nomad", "symbol": "[", "color": "light_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 80, "encumbrance": [ 8, 12 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 80, "encumbrance": [ 8, 12 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 80, "encumbrance": [ 8, 10 ] } @@ -391,7 +391,7 @@ "symbol": "[", "color": "brown", "looks_like": "armor_larmor", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 17, 22 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 90, "encumbrance": [ 17, 19 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 17, 17 ] } @@ -530,7 +530,7 @@ "symbol": "[", "looks_like": "armor_nomad", "color": "green", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 100, "encumbrance": [ 15, 26 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": [ 15, 19 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 100, "encumbrance": [ 15, 15 ] } @@ -588,7 +588,7 @@ "symbol": "[", "looks_like": "hazmat_suit", "color": "white", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 100, "encumbrance": [ 10, 15 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": [ 10, 12 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 100, "encumbrance": [ 10, 10 ] } @@ -754,7 +754,7 @@ "symbol": "[", "looks_like": "survivor_suit", "color": "light_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 100, "encumbrance": [ 10, 26 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": [ 10, 14 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 100, "encumbrance": [ 10, 10 ] } @@ -873,7 +873,7 @@ "symbol": "[", "looks_like": "survivor_suit", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 100, "encumbrance": [ 17, 31 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": [ 17, 21 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 100, "encumbrance": [ 17, 17 ] } @@ -903,7 +903,7 @@ "symbol": "[", "looks_like": "survivor_suit", "color": "green", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 100, "encumbrance": [ 7, 15 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": [ 7, 7 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 100, "encumbrance": [ 7, 7 ] } @@ -971,7 +971,7 @@ "symbol": "[", "looks_like": "hazmat_suit", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": [ 7, 7 ] }, { "covers": [ "torso" ], "coverage": 100, "encumbrance": [ 7, 13 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": [ 7, 10 ] }, @@ -1027,7 +1027,7 @@ "symbol": "[", "looks_like": "jumpsuit", "color": "light_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 7, 13 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": [ 7, 10 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 7, 7 ] } @@ -1060,7 +1060,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 100, "encumbrance": [ 12, 20 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": [ 12, 17 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 100, "encumbrance": [ 12, 12 ] } @@ -1095,7 +1095,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 12, 19 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": [ 12, 16 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 12, 12 ] } @@ -1128,7 +1128,7 @@ "symbol": "[", "looks_like": "jumpsuit", "color": "light_red", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 14, 15 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 95, "encumbrance": [ 14, 14 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 14, 14 ] } @@ -1156,7 +1156,7 @@ "symbol": "[", "looks_like": "survivor_suit", "color": "light_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 100, "encumbrance": [ 20, 28 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": [ 20, 25 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 100, "encumbrance": [ 20, 20 ] } @@ -1197,7 +1197,7 @@ "symbol": "[", "looks_like": "survivor_suit", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 100, "encumbrance": [ 17, 30 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": [ 17, 22 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 100, "encumbrance": [ 17, 17 ] } @@ -1232,7 +1232,7 @@ "symbol": "[", "looks_like": "hsurvivor_suit", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 100, "encumbrance": [ 22, 39 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": [ 22, 28 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 100, "encumbrance": [ 22, 22 ] } @@ -1262,7 +1262,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "green", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 1, 2 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 50, "encumbrance": [ 1, 1 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 80, "encumbrance": [ 1, 2 ] } diff --git a/data/json/items/armor/swimming.json b/data/json/items/armor/swimming.json index 448ea1349da71..dc0916985b754 100644 --- a/data/json/items/armor/swimming.json +++ b/data/json/items/armor/swimming.json @@ -52,7 +52,7 @@ "symbol": "[", "looks_like": "wetsuit_spring", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 100, "encumbrance": [ 11, 14 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": [ 11, 13 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 100, "encumbrance": [ 11, 11 ] } @@ -139,7 +139,7 @@ "symbol": "[", "looks_like": "wetsuit", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 100, "encumbrance": [ 10, 16 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": [ 10, 14 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 100, "encumbrance": [ 10, 10 ] } @@ -193,7 +193,7 @@ "symbol": "[", "looks_like": "wetsuit", "color": "pink", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 2, 5 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 2, 4 ] } ], diff --git a/data/json/items/armor/torso_armor.json b/data/json/items/armor/torso_armor.json index 77e2660c19f8a..364d5356c544d 100644 --- a/data/json/items/armor/torso_armor.json +++ b/data/json/items/armor/torso_armor.json @@ -262,7 +262,7 @@ "symbol": "[", "looks_like": "jacket_leather", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 85, "encumbrance": [ 20, 23 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 85, "encumbrance": [ 20, 22 ] } ], @@ -426,7 +426,7 @@ "symbol": "[", "looks_like": "jacket_leather", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 28, 30 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 28, 28 ] } ], diff --git a/data/json/items/armor/torso_clothes.json b/data/json/items/armor/torso_clothes.json index 149013aa8211e..68da869b45b55 100644 --- a/data/json/items/armor/torso_clothes.json +++ b/data/json/items/armor/torso_clothes.json @@ -13,7 +13,7 @@ "symbol": "[", "looks_like": "vest_leather", "color": "brown", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 70, "encumbrance": [ 2, 5 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 70, "encumbrance": [ 2, 2 ] } ], @@ -61,7 +61,7 @@ "symbol": "[", "looks_like": "jacket_light", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 85, "encumbrance": [ 16, 20 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 85, "encumbrance": [ 16, 16 ] } ], @@ -129,7 +129,7 @@ "symbol": "[", "looks_like": "longshirt", "color": "white", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 4, 5 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 4, 4 ] } ], @@ -288,7 +288,7 @@ "symbol": "[", "looks_like": "sweater", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 6, 12 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 6, 6 ] } ], @@ -480,7 +480,7 @@ "symbol": "[", "looks_like": "dress", "color": "blue", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 75, "encumbrance": [ 5, 7 ] }, { "covers": [ "leg_l", "leg_r" ], "coverage": 75, "encumbrance": [ 5, 5 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 75, "encumbrance": [ 5, 5 ] } @@ -569,7 +569,7 @@ "symbol": "[", "looks_like": "dress_shirt", "color": "light_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": [ 3, 5 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 90, "encumbrance": [ 3, 3 ] } ], @@ -599,7 +599,7 @@ "symbol": "[", "looks_like": "camisole", "color": "yellow", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 90, "encumbrance": 8 }, { "covers": [ "arm_l", "arm_r" ], "coverage": 25, "encumbrance": 1 } ], @@ -900,7 +900,7 @@ "symbol": "[", "looks_like": "hoodie", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 95, "encumbrance": [ 6, 12 ] }, { "covers": [ "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 6, 6 ] } ], diff --git a/data/json/items/tool_armor.json b/data/json/items/tool_armor.json index a0d6ddb7c26c8..1edd3b9fdd37a 100644 --- a/data/json/items/tool_armor.json +++ b/data/json/items/tool_armor.json @@ -923,7 +923,7 @@ "weight": "5600 g", "volume": "4 L", "price": 150000, - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": 20 }, { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 10 }, { "covers": [ "mouth" ], "coverage": 100, "encumbrance": 15 } @@ -1322,7 +1322,7 @@ "material": [ "plastic" ], "symbol": "[", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 10 }, { "covers": [ "mouth" ], "coverage": 100, "encumbrance": 30 } ], @@ -1348,7 +1348,7 @@ "material": [ "plastic" ], "symbol": "[", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 10 }, { "covers": [ "mouth" ], "coverage": 100, "encumbrance": 30 } ], @@ -1375,7 +1375,7 @@ "material": [ "kevlar_layered", "nomex" ], "symbol": "[", "color": "light_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 10 }, { "covers": [ "mouth" ], "coverage": 100, "encumbrance": 30 } ], @@ -1403,7 +1403,7 @@ "material": [ "kevlar_layered", "nomex" ], "symbol": "[", "color": "light_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 15 }, { "covers": [ "mouth" ], "coverage": 100, "encumbrance": 35 } ], @@ -1439,7 +1439,7 @@ "warmth": 30, "environmental_protection": 1, "environmental_protection_with_filter": 16, - "armor_portion_data": [ + "armor": [ { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 10 }, { "covers": [ "mouth" ], "coverage": 100, "encumbrance": 20 } ], @@ -1463,7 +1463,7 @@ "material": [ "kevlar_layered", "steel" ], "symbol": "[", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 10 }, { "covers": [ "mouth" ], "coverage": 100, "encumbrance": 30 } ], @@ -1491,7 +1491,7 @@ "material": [ "kevlar_layered", "cotton" ], "symbol": "[", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 5 }, { "covers": [ "mouth" ], "coverage": 100, "encumbrance": 20 } ], @@ -1519,7 +1519,7 @@ "material": [ "kevlar_layered", "leather" ], "symbol": "[", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 5 }, { "covers": [ "mouth" ], "coverage": 100, "encumbrance": 25 } ], @@ -1547,7 +1547,7 @@ "material": [ "kevlar_layered", "plastic" ], "symbol": "[", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 10 }, { "covers": [ "mouth" ], "coverage": 100, "encumbrance": 30 } ], @@ -1599,7 +1599,7 @@ "material": [ "kevlar_layered", "fur" ], "symbol": "[", "color": "light_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 5 }, { "covers": [ "mouth" ], "coverage": 100, "encumbrance": 30 } ], @@ -1627,7 +1627,7 @@ "material": [ "kevlar_layered", "fur" ], "symbol": "[", "color": "light_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 10 }, { "covers": [ "mouth" ], "coverage": 100, "encumbrance": 35 } ], @@ -1835,7 +1835,7 @@ }, "warmth": 15, "environmental_protection": 10, - "armor_portion_data": [ + "armor": [ { "covers": [ "eyes" ], "coverage": 75, "encumbrance": 5 }, { "covers": [ "mouth" ], "coverage": 75, "encumbrance": 30 } ], @@ -1882,7 +1882,7 @@ }, "warmth": 15, "environmental_protection": 10, - "armor_portion_data": [ + "armor": [ { "covers": [ "eyes" ], "coverage": 75, "encumbrance": 10 }, { "covers": [ "mouth" ], "coverage": 75, "encumbrance": 30 } ], @@ -3218,7 +3218,7 @@ "symbol": "[", "looks_like": "helmet_motor", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": 30 }, { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 5 } ], @@ -3273,7 +3273,7 @@ "symbol": "[", "looks_like": "helmet_motor", "color": "dark_gray", - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": 30 }, { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 5 } ], diff --git a/data/mods/Aftershock/items/armor.json b/data/mods/Aftershock/items/armor.json index e1aa04b0d5b65..16b57ff51c435 100644 --- a/data/mods/Aftershock/items/armor.json +++ b/data/mods/Aftershock/items/armor.json @@ -360,7 +360,7 @@ "flags": [ "OVERSIZE", "BELTED", "ALLOWS_NATURAL_ATTACKS", "PARTIAL_DEAF" ], "name": { "str": "communications cap" }, "description": "A padded cotton cap built around an augmented reality headset. During normal operation it would provide visual information about a ship subsystems and a communications link with the rest of the crew, but severed from a spaceship, only their hearing protection function retains any utility.", - "armor_portion_data": [ + "armor": [ { "covers": [ "eyes" ], "coverage": 33, "encumbrance": 0 }, { "covers": [ "head" ], "coverage": 100, "encumbrance": 2 } ], diff --git a/data/mods/Aftershock/items/armor/winter_masks.json b/data/mods/Aftershock/items/armor/winter_masks.json index a10b724f8639f..5c017c3a435c6 100644 --- a/data/mods/Aftershock/items/armor/winter_masks.json +++ b/data/mods/Aftershock/items/armor/winter_masks.json @@ -25,7 +25,7 @@ "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": 25 }, { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 5 }, { "covers": [ "mouth" ], "coverage": 100, "encumbrance": 15 } @@ -91,7 +91,7 @@ "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "armor_portion_data": [ + "armor": [ { "covers": [ "eyes" ], "coverage": 100, "encumbrance": 15 }, { "covers": [ "mouth" ], "coverage": 100, "encumbrance": 20 } ], diff --git a/data/mods/Aftershock/items/armor/winter_suits.json b/data/mods/Aftershock/items/armor/winter_suits.json index d8a607ba579dc..aa9c33d06edb7 100644 --- a/data/mods/Aftershock/items/armor/winter_suits.json +++ b/data/mods/Aftershock/items/armor/winter_suits.json @@ -22,7 +22,7 @@ "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 100, "encumbrance": 25 }, { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": 25 }, { "covers": [ "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 15 }, @@ -85,7 +85,7 @@ "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": 5 }, { "covers": [ "torso" ], "coverage": 100, "encumbrance": 35 }, { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": 25 }, diff --git a/data/mods/Aftershock/suit_operating_time.md b/data/mods/Aftershock/suit_operating_time.md index 4a346e910efef..1f07e9388aa8c 100644 --- a/data/mods/Aftershock/suit_operating_time.md +++ b/data/mods/Aftershock/suit_operating_time.md @@ -59,7 +59,7 @@ Consider the Magellan exosuit, which has the following definition: "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "armor_portion_data": [ + "armor": [ { "covers": [ "torso" ], "coverage": 100, "encumbrance": 25 }, { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": 25 }, { "covers": [ "arm_l", "arm_r" ], "coverage": 100, "encumbrance": 15 }, diff --git a/data/mods/Magiclysm/items/black_dragon_items.json b/data/mods/Magiclysm/items/black_dragon_items.json index 10f2bc1a42cc0..4d6c9c33439dd 100644 --- a/data/mods/Magiclysm/items/black_dragon_items.json +++ b/data/mods/Magiclysm/items/black_dragon_items.json @@ -149,7 +149,7 @@ "material": [ "black_dragon_hide", "black_dragon_scales" ], "symbol": "[", "color": "black_white", - "armor_portion_data": [ + "armor": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": 32 }, { "covers": [ "eyes", "mouth" ], "coverage": 100, "encumbrance": 20 } ], @@ -169,7 +169,7 @@ "description": "A helmet made from incredibly durable black dragonscale, held together with black dragonhide. The visor is raised.", "use_action": { "type": "transform", "target": "helmet_black_dragon_scale", "msg": "You put down your visor." }, "symbol": "[", - "armor_portion_data": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": 32 } ], + "armor": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": 32 } ], "delete": { "qualities": [ [ "GLARE", 1 ] ], "flags": [ "SUN_GLASSES" ] } }, { @@ -334,7 +334,7 @@ "use_action": { "type": "transform", "target": "helmet_xlblack_dragon_scale_raised", "msg": "You raise your visor." }, "weight": "1256 g", "volume": "4500 ml", - "armor_portion_data": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": 42 } ], + "armor": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": 42 } ], "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY", "SUN_GLASSES" ] }, { @@ -344,7 +344,7 @@ "name": { "str": "XL black dragonscale helmet (raised visor)", "str_pl": "XL black dragonscale helmets (raised visor)" }, "description": "A massive helmet made from incredibly durable black dragonscale, held together with black dragonhide. It is large enough to fit even the strangest of heads. The visor is raised", "use_action": { "type": "transform", "target": "helmet_xlblack_dragon_scale", "msg": "You put down your visor." }, - "armor_portion_data": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": 42 } ], + "armor": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": 42 } ], "weight": "1256 g", "volume": "4500 ml", "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ] diff --git a/data/mods/TEST_DATA/items.json b/data/mods/TEST_DATA/items.json index bd4789d06d0a6..82ea1d26f9bca 100644 --- a/data/mods/TEST_DATA/items.json +++ b/data/mods/TEST_DATA/items.json @@ -1552,7 +1552,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "dark_gray", - "armor_portion_data": [ { "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 12, 25 ] } ], + "armor": [ { "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], "coverage": 95, "encumbrance": [ 12, 25 ] } ], "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, @@ -1612,7 +1612,7 @@ "name": { "str_sp": "faux fur pants suit test thing" }, "description": "A TEST OBJECT SHOULD NOT BE IN GAME", "material": [ "faux_fur", "cotton" ], - "armor_portion_data": [ + "armor": [ { "covers": [ "torso", "leg_r", "arm_r" ], "coverage": 100, "encumbrance": [ 10, 25 ] }, { "covers": [ "arm_l", "leg_l", "head" ], "coverage": 50, "encumbrance": 5 } ], From 82988e3a76cfc0e6def23aa6c42d0547380de978 Mon Sep 17 00:00:00 2001 From: AccountAlias <85119255+AccountAlias@users.noreply.github.com> Date: Tue, 6 Jul 2021 14:54:41 -0400 Subject: [PATCH 008/116] fix issue #48526 --- src/melee.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/melee.cpp b/src/melee.cpp index 5a2aee40555ce..5bae12812005e 100644 --- a/src/melee.cpp +++ b/src/melee.cpp @@ -539,7 +539,8 @@ bool Character::melee_attack_abstract( Creature &t, bool allow_special, add_msg( m_bad, _( "This weapon is too unwieldy to attack with!" ) ); return false; } - int move_cost = attack_speed( *cur_weapon ); + int move_cost = attack_speed( cur_weapon->has_flag( flag_UNARMED_WEAPON ) ? * + ( new item() ) : *cur_weapon ); if( is_avatar() && move_cost > 1000 && calendar::turn > melee_warning_turn ) { const auto &action = query_popup() From d9c4258c9ad36e9eafef0c9271a783c3b5f90b7f Mon Sep 17 00:00:00 2001 From: AccountAlias <85119255+AccountAlias@users.noreply.github.com> Date: Tue, 6 Jul 2021 15:17:14 -0400 Subject: [PATCH 009/116] Update src/melee.cpp Co-authored-by: anothersimulacrum --- src/melee.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/melee.cpp b/src/melee.cpp index 5bae12812005e..f8ace70546395 100644 --- a/src/melee.cpp +++ b/src/melee.cpp @@ -539,8 +539,8 @@ bool Character::melee_attack_abstract( Creature &t, bool allow_special, add_msg( m_bad, _( "This weapon is too unwieldy to attack with!" ) ); return false; } - int move_cost = attack_speed( cur_weapon->has_flag( flag_UNARMED_WEAPON ) ? * - ( new item() ) : *cur_weapon ); + int move_cost = attack_speed( cur_weapon->has_flag( flag_UNARMED_WEAPON ) ? + null_item_reference() : *cur_weapon ); if( is_avatar() && move_cost > 1000 && calendar::turn > melee_warning_turn ) { const auto &action = query_popup() From 4f90dbb1217f408e0673596a1872b0340454c351 Mon Sep 17 00:00:00 2001 From: LaVeyanFiend <51099123+LaVeyanFiend@users.noreply.github.com> Date: Tue, 6 Jul 2021 16:30:08 -0400 Subject: [PATCH 010/116] Shocker zombies no longer drop CBMs(in vanilla) (#47451) * Shockers are magic blob stuff, not CBMs * Aftershock stopgap measure --- data/json/harvest.json | 48 ------------------- data/json/monsters/zed_electric.json | 6 +-- data/json/monsters/zed_skeletal.json | 2 +- .../Aftershock/itemgroups/bionics_groups.json | 48 +++++++++++++++++++ data/mods/Aftershock/mobs/zombies.json | 28 +++++++++++ 5 files changed, 80 insertions(+), 52 deletions(-) diff --git a/data/json/harvest.json b/data/json/harvest.json index d13f5abbad47a..7f34cc065f8f9 100644 --- a/data/json/harvest.json +++ b/data/json/harvest.json @@ -1277,27 +1277,6 @@ { "drop": "stick_fiber", "base_num": [ 4, 8 ], "scale_num": [ 0.5, 0.7 ], "max": 10, "type": "bone" } ] }, - { - "id": "CBM_CIV", - "type": "harvest", - "entries": [ - { - "drop": "bio_power_storage", - "type": "bionic", - "flags": [ "FILTHY", "NO_STERILE", "NO_PACKED" ], - "faults": [ "fault_bionic_salvaged" ] - }, - { - "drop": "bionics_common", - "type": "bionic_group", - "flags": [ "FILTHY", "NO_STERILE", "NO_PACKED" ], - "faults": [ "fault_bionic_salvaged" ] - }, - { "drop": "meat_tainted", "type": "flesh", "mass_ratio": 0.25 }, - { "drop": "fat_tainted", "type": "flesh", "mass_ratio": 0.08 }, - { "drop": "bone_tainted", "type": "bone", "mass_ratio": 0.1 } - ] - }, { "id": "CBM_SCI", "type": "harvest", @@ -1353,33 +1332,6 @@ { "drop": "bone_tainted", "type": "bone", "mass_ratio": 0.1 } ] }, - { - "id": "CBM_SUBS", - "type": "harvest", - "entries": [ - { - "drop": "bio_power_storage", - "type": "bionic", - "flags": [ "FILTHY", "NO_STERILE", "NO_PACKED" ], - "faults": [ "fault_bionic_salvaged" ] - }, - { - "drop": "bionics_subs", - "type": "bionic_group", - "flags": [ "FILTHY", "NO_STERILE", "NO_PACKED" ], - "faults": [ "fault_bionic_salvaged" ] - }, - { - "drop": "bionics_subs", - "type": "bionic_group", - "flags": [ "FILTHY", "NO_STERILE", "NO_PACKED" ], - "faults": [ "fault_bionic_salvaged" ] - }, - { "drop": "meat_tainted", "type": "flesh", "mass_ratio": 0.25 }, - { "drop": "fat_tainted", "type": "flesh", "mass_ratio": 0.08 }, - { "drop": "bone_tainted", "type": "bone", "mass_ratio": 0.1 } - ] - }, { "id": "CBM_OP", "type": "harvest", diff --git a/data/json/monsters/zed_electric.json b/data/json/monsters/zed_electric.json index cd0af42c05415..03da33c0eff64 100644 --- a/data/json/monsters/zed_electric.json +++ b/data/json/monsters/zed_electric.json @@ -27,7 +27,7 @@ "armor_bullet": 6, "vision_night": 3, "luminance": 16, - "harvest": "CBM_SUBS", + "harvest": "zombie", "special_attacks": [ [ "SHOCKSTORM", 15 ], [ "SMASH", 30 ] ], "special_when_hit": [ "ZAPBACK", 75 ], "death_drops": "default_zombie_death_drops", @@ -73,7 +73,7 @@ "melee_cut": 0, "dodge": 2, "luminance": 8, - "harvest": "CBM_CIV", + "harvest": "zombie", "special_attacks": [ [ "SHOCKSTORM", 25 ] ], "special_when_hit": [ "ZAPBACK", 100 ], "death_drops": "default_zombie_death_drops", @@ -122,7 +122,7 @@ "melee_damage": [ { "damage_type": "electric", "amount": 6 } ], "vision_night": 3, "luminance": 16, - "harvest": "CBM_SUBS", + "harvest": "zombie", "emit_fields": [ { "emit_id": "emit_shock_cloud", "delay": "1 s" } ], "special_when_hit": [ "ZAPBACK", 75 ], "death_drops": "default_zombie_death_drops", diff --git a/data/json/monsters/zed_skeletal.json b/data/json/monsters/zed_skeletal.json index f3c08171c2590..8d2fa25893af5 100644 --- a/data/json/monsters/zed_skeletal.json +++ b/data/json/monsters/zed_skeletal.json @@ -103,7 +103,7 @@ "armor_acid": 3, "vision_day": 30, "vision_night": 3, - "harvest": "CBM_CIV", + "harvest": "mr_bones", "special_attacks": [ [ "scratch", 10 ], { "type": "bite", "cooldown": 5 }, [ "SHOCKSTORM", 25 ] ], "death_drops": "default_zombie_clothes", "death_function": [ "NORMAL" ], diff --git a/data/mods/Aftershock/itemgroups/bionics_groups.json b/data/mods/Aftershock/itemgroups/bionics_groups.json index af4462a89a5bf..2b0b0cd0123de 100644 --- a/data/mods/Aftershock/itemgroups/bionics_groups.json +++ b/data/mods/Aftershock/itemgroups/bionics_groups.json @@ -58,5 +58,53 @@ "id": "bionics_subs", "type": "item_group", "items": [ [ "afs_bio_missiles", 10 ], [ "afs_bio_dopamine_stimulators", 15 ] ] + }, + { + "id": "CBM_SUBS", + "type": "harvest", + "entries": [ + { + "drop": "bio_power_storage", + "type": "bionic", + "flags": [ "FILTHY", "NO_STERILE", "NO_PACKED" ], + "faults": [ "fault_bionic_salvaged" ] + }, + { + "drop": "bionics_subs", + "type": "bionic_group", + "flags": [ "FILTHY", "NO_STERILE", "NO_PACKED" ], + "faults": [ "fault_bionic_salvaged" ] + }, + { + "drop": "bionics_subs", + "type": "bionic_group", + "flags": [ "FILTHY", "NO_STERILE", "NO_PACKED" ], + "faults": [ "fault_bionic_salvaged" ] + }, + { "drop": "meat_tainted", "type": "flesh", "mass_ratio": 0.25 }, + { "drop": "fat_tainted", "type": "flesh", "mass_ratio": 0.08 }, + { "drop": "bone_tainted", "type": "bone", "mass_ratio": 0.1 } + ] + }, + { + "id": "CBM_CIV", + "type": "harvest", + "entries": [ + { + "drop": "bio_power_storage", + "type": "bionic", + "flags": [ "FILTHY", "NO_STERILE", "NO_PACKED" ], + "faults": [ "fault_bionic_salvaged" ] + }, + { + "drop": "bionics_common", + "type": "bionic_group", + "flags": [ "FILTHY", "NO_STERILE", "NO_PACKED" ], + "faults": [ "fault_bionic_salvaged" ] + }, + { "drop": "meat_tainted", "type": "flesh", "mass_ratio": 0.25 }, + { "drop": "fat_tainted", "type": "flesh", "mass_ratio": 0.08 }, + { "drop": "bone_tainted", "type": "bone", "mass_ratio": 0.1 } + ] } ] diff --git a/data/mods/Aftershock/mobs/zombies.json b/data/mods/Aftershock/mobs/zombies.json index 4b2510661e697..3736086ec200a 100644 --- a/data/mods/Aftershock/mobs/zombies.json +++ b/data/mods/Aftershock/mobs/zombies.json @@ -674,5 +674,33 @@ "PUSH_MON", "FILTHY" ] + }, + { + "id": "mon_zombie_brute_shocker", + "type": "MONSTER", + "name": { "str": "shocker brute" }, + "copy-from": "mon_zombie_brute_shocker", + "harvest": "CBM_SUBS" + }, + { + "id": "mon_zombie_electric", + "type": "MONSTER", + "name": { "str": "shocker zombie" }, + "copy-from": "mon_zombie_electric", + "harvest": "CBM_CIV" + }, + { + "id": "mon_zombie_nullfield", + "type": "MONSTER", + "name": { "str": "incandescent husk" }, + "copy-from": "mon_zombie_nullfield", + "harvest": "CBM_SUBS" + }, + { + "id": "mon_skeleton_electric", + "type": "MONSTER", + "name": { "str": "skeletal shocker" }, + "copy-from": "mon_skeleton_electric", + "harvest": "CBM_CIV" } ] From 5ca12e4b12c09f3bd21a77eb865ae4d006632f86 Mon Sep 17 00:00:00 2001 From: AccountAlias <85119255+AccountAlias@users.noreply.github.com> Date: Tue, 6 Jul 2021 16:31:35 -0400 Subject: [PATCH 011/116] Update melee.cpp --- src/melee.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/melee.cpp b/src/melee.cpp index f8ace70546395..456d57c12df05 100644 --- a/src/melee.cpp +++ b/src/melee.cpp @@ -535,12 +535,13 @@ bool Character::melee_attack_abstract( Creature &t, bool allow_special, } } - if( cur_weapon->attack_time() > attack_speed( *cur_weapon ) * 20 ) { + int move_cost = attack_speed( cur_weapon->has_flag( flag_UNARMED_WEAPON ) ? + null_item_reference() : *cur_weapon ); + + if( cur_weapon->attack_time() > move_cost * 20 ) { add_msg( m_bad, _( "This weapon is too unwieldy to attack with!" ) ); return false; } - int move_cost = attack_speed( cur_weapon->has_flag( flag_UNARMED_WEAPON ) ? - null_item_reference() : *cur_weapon ); if( is_avatar() && move_cost > 1000 && calendar::turn > melee_warning_turn ) { const auto &action = query_popup() From 5100ea4524a85b7085e4731e4e5134bb87d5e601 Mon Sep 17 00:00:00 2001 From: SariusSkelrets <68650913+SariusSkelrets@users.noreply.github.com> Date: Tue, 6 Jul 2021 16:40:49 -0400 Subject: [PATCH 012/116] New pupating zombies (#48876) * More_Pupating_Zombies * fix typo * fix more typos * fix another typo * uncopy the hulks * Fix hive_raptor_spawn not working and * Hive hulks aren't bags * Lint of the three files * Remove attackmon to solve infighting issue * All hive hulks aren't bags * Update data/json/monsters/zed-pupating.json Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> * Update data/json/monsters/zed-pupating.json Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> * Update data/json/monsters/zed-pupating.json Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> * Update data/json/monster_special_attacks/spells.json Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> * Update data/json/monsters/zed-pupating.json Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> --- data/json/monster_special_attacks/spells.json | 16 ++ data/json/monstergroups/zombie_upgrades.json | 18 ++- data/json/monsters/zed-pupating.json | 139 ++++++++++++++++++ 3 files changed, 170 insertions(+), 3 deletions(-) diff --git a/data/json/monster_special_attacks/spells.json b/data/json/monster_special_attacks/spells.json index e7a239828601c..fcb6994e2b4b7 100644 --- a/data/json/monster_special_attacks/spells.json +++ b/data/json/monster_special_attacks/spells.json @@ -189,6 +189,22 @@ "effect": "summon", "effect_str": "mon_spawn_raptor" }, + { + "type": "SPELL", + "id": "hive_raptor_spawn", + "name": { "str": "Spawn Raptor" }, + "description": "Summons a zombie-spawn raptor without killing the zombie.", + "flags": [ "HOSTILE_SUMMON", "RANDOM_DAMAGE", "PERMANENT" ], + "valid_targets": [ "ground", "self" ], + "min_damage": 1, + "max_damage": 1, + "min_aoe": 3, + "max_aoe": 3, + "base_casting_time": 100, + "shape": "blast", + "effect": "summon", + "effect_str": "mon_spawn_raptor" + }, { "type": "SPELL", "id": "shady_raptor_spawn", diff --git a/data/json/monstergroups/zombie_upgrades.json b/data/json/monstergroups/zombie_upgrades.json index a9044da69c7c1..934f2c6e295f5 100644 --- a/data/json/monstergroups/zombie_upgrades.json +++ b/data/json/monstergroups/zombie_upgrades.json @@ -87,9 +87,11 @@ "default": "mon_zombie_brute", "//": "Brute upgrades. Note that 'freq' units are tenth of a percent, with default filling in the gap.", "monsters": [ - { "monster": "mon_zombie_brute_grappler", "freq": 330, "cost_multiplier": 10 }, - { "monster": "mon_zombie_brute_ninja", "freq": 265, "cost_multiplier": 10 }, - { "monster": "mon_zombie_hulk", "freq": 265, "cost_multiplier": 50 }, + { "monster": "mon_zombie_brute_grappler", "freq": 240, "cost_multiplier": 10 }, + { "monster": "mon_zombie_brute_ninja", "freq": 175, "cost_multiplier": 10 }, + { "monster": "mon_brute_pupa", "freq": 100, "cost_multiplier": 10 }, + { "monster": "mon_brute_pupa_decoy", "freq": 100, "cost_multiplier": 10 }, + { "monster": "mon_zombie_hulk", "freq": 245, "cost_multiplier": 50 }, { "monster": "mon_gas_zombie", "freq": 140, "cost_multiplier": 10 } ] }, @@ -107,6 +109,16 @@ { "monster": "mon_zombie_waif", "freq": 200, "cost_multiplier": 7 } ] }, + { + "type": "monstergroup", + "name": "GROUP_BRUTE_PUPA", + "default": "mon_null", + "//": "this is a sub-group of pupating zombies that can only evolve from pupating zombie brutes. Note that 'freq' units are tenth of a percent, with default filling in the gap.", + "monsters": [ + { "monster": "mon_hulk_pupa", "freq": 500, "cost_multiplier": 50 }, + { "monster": "mon_hulk_pupa_decoy", "freq": 500, "cost_multiplier": 50 } + ] + }, { "type": "monstergroup", "name": "GROUP_ZOMBIE_ELECTRIC_UPGRADE", diff --git a/data/json/monsters/zed-pupating.json b/data/json/monsters/zed-pupating.json index ea40b60c81045..91b0641dd6b59 100644 --- a/data/json/monsters/zed-pupating.json +++ b/data/json/monsters/zed-pupating.json @@ -61,6 +61,145 @@ ] } }, + { + "id": "mon_brute_pupa_decoy", + "type": "MONSTER", + "name": { "str": "pupating brute" }, + "description": "This muscular human corpse is wrapped in sticky black fibers that cover everything from the neck down. Beneath the wrapping there is a strange rhythmic movement, grotesque to behold.", + "copy-from": "mon_zombie_brute", + "delete": { "categories": [ "CLASSIC" ] }, + "speed": 95, + "regenerates": 10, + "upgrades": { "half_life": 21, "into_group": "GROUP_BRUTE_PUPA" }, + "extend": { "flags": [ "SLUDGETRAIL", "SLUDGEPROOF" ] } + }, + { + "id": "mon_brute_pupa", + "type": "MONSTER", + "name": { "str": "pupating brute" }, + "description": "This muscular human corpse is wrapped in sticky black fibers that cover everything from the neck down. Beneath the wrapping there is a strange rhythmic movement, grotesque to behold.", + "copy-from": "mon_brute_pupa_decoy", + "extend": { + "special_attacks": [ + { + "type": "spell", + "spell_data": { "id": "big_raptor_spawn", "hit_self": true }, + "cooldown": 50, + "monster_message": "The pupating brute bursts, and gore-smeared winged beasts climb out of the corpse!" + } + ] + } + }, + { + "id": "mon_hulk_pupa_decoy", + "type": "MONSTER", + "name": { "str": "hive hulk" }, + "//": "Not using copy_from as it messes with monster evolution.", + "description": "The bloated torso of this gigantic corpse is wrapped in sticky black fibers. Beneath the wrapping there is a strange rhythmic movement, grotesque to behold.", + "default_faction": "zombie", + "bodytype": "human", + "species": [ "ZOMBIE", "HUMAN" ], + "diff": 5, + "volume": "875000 ml", + "weight": "200 kg", + "hp": 300, + "speed": 85, + "material": [ "flesh" ], + "symbol": "Z", + "color": "white_magenta", + "aggression": 100, + "morale": 100, + "melee_skill": 4, + "melee_dice": 3, + "melee_dice_sides": 7, + "melee_cut": 0, + "armor_bash": 8, + "armor_cut": 10, + "armor_bullet": 10, + "vision_day": 83, + "vision_night": 4, + "harvest": "zombie", + "special_attacks": [ [ "SMASH", 30 ] ], + "death_drops": "mon_zombie_hulk_death_drops", + "death_function": [ "NORMAL" ], + "regenerates": 10, + "flags": [ + "SEES", + "HEARS", + "SMELLS", + "STUMBLES", + "WARM", + "BASHES", + "DESTROYS", + "POISON", + "NO_BREATHE", + "REVIVES", + "PUSH_MON", + "PUSH_VEH", + "SLUDGETRAIL", + "SLUDGEPROOF", + "FILTHY" + ] + }, + { + "id": "mon_hulk_pupa", + "type": "MONSTER", + "name": { "str": "hive hulk" }, + "//": "Not using copy_from as it messes with monster evolution.", + "description": "The bloated torso of this gigantic corpse is wrapped in sticky black fibers. Beneath the wrapping there is a strange rhythmic movement, grotesque to behold.", + "default_faction": "zombie", + "bodytype": "human", + "species": [ "ZOMBIE", "HUMAN" ], + "diff": 5, + "volume": "875000 ml", + "weight": "200 kg", + "hp": 300, + "speed": 85, + "material": [ "flesh" ], + "symbol": "Z", + "color": "white_magenta", + "aggression": 100, + "morale": 100, + "melee_skill": 4, + "melee_dice": 3, + "melee_dice_sides": 7, + "melee_cut": 0, + "armor_bash": 8, + "armor_cut": 10, + "armor_bullet": 10, + "vision_day": 83, + "vision_night": 4, + "harvest": "zombie", + "special_attacks": [ + [ "SMASH", 30 ], + { + "type": "spell", + "spell_data": { "id": "hive_raptor_spawn", "hit_self": true }, + "cooldown": 30, + "monster_message": "The hive hulk opens its mouth, and a gore-smeared winged beast flies out of it!" + } + ], + "death_drops": "mon_zombie_hulk_death_drops", + "death_function": [ "NORMAL" ], + "regenerates": 10, + "flags": [ + "SEES", + "HEARS", + "SMELLS", + "STUMBLES", + "WARM", + "BASHES", + "DESTROYS", + "POISON", + "NO_BREATHE", + "REVIVES", + "PUSH_MON", + "PUSH_VEH", + "SLUDGETRAIL", + "SLUDGEPROOF", + "FILTHY" + ] + }, { "id": "mon_zombie_pupa_decoy_shady", "type": "MONSTER", From 8c079112f3d9652abc06718e14f13798369e1178 Mon Sep 17 00:00:00 2001 From: LyleSY Date: Tue, 6 Jul 2021 18:51:03 -0400 Subject: [PATCH 013/116] fungalize the children bugfix (#49660) --- data/json/monsters/zed_children.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/data/json/monsters/zed_children.json b/data/json/monsters/zed_children.json index 6512ba1615ce2..2bbfcb29dc874 100644 --- a/data/json/monsters/zed_children.json +++ b/data/json/monsters/zed_children.json @@ -28,7 +28,7 @@ "death_drops": { "subtype": "collection", "groups": [ [ "default_zombie_clothes", 100 ], [ "child_items", 65 ] ] }, "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_child_scorched", - "zombify_into": "mon_zombie_child_fungus", + "fungalize_into": "mon_zombie_child_fungus", "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ], "//": "no GUILT because it no longer looks enough like a child to evoke pity" }, @@ -66,7 +66,7 @@ }, "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_child_scorched", - "zombify_into": "mon_zombie_child_fungus", + "fungalize_into": "mon_zombie_child_fungus", "upgrades": { "half_life": 14, "into_group": "GROUP_CHILD_ZOMBIE_UPGRADE" }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "GUILT", "NO_BREATHE", "REVIVES", "FILTHY" ] }, @@ -99,7 +99,7 @@ "death_drops": { "subtype": "collection", "groups": [ [ "default_zombie_clothes", 100 ], [ "child_items", 65 ] ] }, "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_child_scorched", - "zombify_into": "mon_zombie_child_fungus", + "fungalize_into": "mon_zombie_child_fungus", "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "CLIMBS", "FILTHY" ], "//": "no GUILT because it no longer looks enough like a child to evoke pity" }, @@ -133,7 +133,7 @@ "death_drops": { "subtype": "collection", "groups": [ [ "default_zombie_clothes", 100 ], [ "child_items", 65 ] ] }, "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_child_scorched", - "zombify_into": "mon_zombie_child_fungus", + "fungalize_into": "mon_zombie_child_fungus", "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "GUILT", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ], "//": "GUILT because it still looks enough like a child to evoke pity" }, @@ -167,7 +167,7 @@ "death_drops": { "subtype": "collection", "groups": [ [ "default_zombie_clothes", 100 ], [ "child_items", 65 ] ] }, "death_function": [ "BOOMER" ], "burn_into": "mon_zombie_child_scorched", - "zombify_into": "mon_zombie_child_fungus", + "fungalize_into": "mon_zombie_child_fungus", "flags": [ "SEES", "HEARS", "STUMBLES", "WARM", "GUILT", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ], "//": "GUILT because it still looks enough like a child to evoke pity" }, @@ -200,7 +200,7 @@ "death_drops": { "subtype": "collection", "groups": [ [ "default_zombie_clothes", 100 ], [ "child_items", 65 ] ] }, "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_child_scorched", - "zombify_into": "mon_zombie_child_fungus", + "fungalize_into": "mon_zombie_child_fungus", "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "CLIMBS", "FILTHY" ], "//": "no GUILT because it no longer looks enough like a child to evoke pity" }, @@ -236,7 +236,7 @@ "death_drops": { "subtype": "collection", "groups": [ [ "default_zombie_clothes", 100 ], [ "child_items", 65 ] ] }, "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_child_scorched", - "zombify_into": "mon_zombie_child_fungus", + "fungalize_into": "mon_zombie_child_fungus", "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "GUILT", "POISON", "NO_BREATHE", "REVIVES", "HARDTOSHOOT", "FILTHY" ], "//": "GUILT because it still looks enough like a child to evoke pity" } From 3c7edb50bf9f0d5953280deca24bd586720a260a Mon Sep 17 00:00:00 2001 From: AccountAlias <85119255+AccountAlias@users.noreply.github.com> Date: Tue, 6 Jul 2021 19:00:35 -0400 Subject: [PATCH 014/116] Prevent dodge and block while driving (#49656) * Prevent dodge and block while driving --- src/character.cpp | 6 ++++++ src/character.h | 3 +++ src/melee.cpp | 4 ++-- src/ranged.cpp | 8 +------- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/character.cpp b/src/character.cpp index bdea5a970b71e..bec02bfbbbb29 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -13190,3 +13190,9 @@ bool Character::has_flag( const json_character_flag &flag ) const // If this is a performance problem create a map of flags stored for a character and updated on trait, mutation, bionic add/remove, activate/deactivate, effect gain/loss return has_trait_flag( flag ) || has_bionic_with_flag( flag ) || has_effect_with_flag( flag ); } + +bool Character::is_driving() const +{ + const optional_vpart_position vp = get_map().veh_at( pos() ); + return vp && vp->vehicle().is_moving() && vp->vehicle().player_in_control( *this ); +} diff --git a/src/character.h b/src/character.h index 3784c49fd0760..5b67d1ae51002 100644 --- a/src/character.h +++ b/src/character.h @@ -2655,6 +2655,9 @@ class Character : public Creature, public visitable /** Creates an auditory hallucination */ void sound_hallu(); + /** Checks if a Character is driving */ + bool is_driving() const; + /** Drenches the player with water, saturation is the percent gotten wet */ void drench( int saturation, const body_part_set &flags, bool ignore_waterproof ); /** Recalculates morale penalty/bonus from wetness based on mutations, equipment and temperature */ diff --git a/src/melee.cpp b/src/melee.cpp index 5a2aee40555ce..67881bd7f215f 100644 --- a/src/melee.cpp +++ b/src/melee.cpp @@ -976,7 +976,7 @@ float Character::get_dodge() const { //If we're asleep or busy we can't dodge if( in_sleep_state() || has_effect( effect_narcosis ) || - has_effect( efftype_id( "winded" ) ) ) { + has_effect( efftype_id( "winded" ) ) || is_driving() ) { return 0.0f; } @@ -1774,7 +1774,7 @@ bool Character::block_hit( Creature *source, bodypart_id &bp_hit, damage_instanc // Shouldn't block if player is asleep or winded if( in_sleep_state() || has_effect( effect_narcosis ) || - has_effect( efftype_id( "winded" ) ) ) { + has_effect( efftype_id( "winded" ) ) || is_driving() ) { return false; } diff --git a/src/ranged.cpp b/src/ranged.cpp index 7966a97f9e30f..f856aa0526b88 100644 --- a/src/ranged.cpp +++ b/src/ranged.cpp @@ -1778,12 +1778,6 @@ item::sound_data item::gun_noise( const bool burst ) const return { 0, "" }; // silent weapons } -static bool is_driving( const Character &p ) -{ - const optional_vpart_position vp = get_map().veh_at( p.pos() ); - return vp && vp->vehicle().is_moving() && vp->vehicle().player_in_control( p ); -} - static double dispersion_from_skill( double skill, double weapon_dispersion ) { if( skill >= MAX_SKILL ) { @@ -1823,7 +1817,7 @@ dispersion_sources Character::get_weapon_dispersion( const item &obj ) const } dispersion.add_range( arm_encumb / 5.0 ); - if( is_driving( *this ) ) { + if( is_driving() ) { // get volume of gun (or for auxiliary gunmods the parent gun) const item *parent = has_item( obj ) ? find_parent( obj ) : nullptr; const int vol = ( parent ? parent->volume() : obj.volume() ) / 250_ml; From 6069a2d7f3fd7f3c62bf4691d524db1dbcb4f455 Mon Sep 17 00:00:00 2001 From: mqrause Date: Wed, 7 Jul 2021 01:00:40 +0200 Subject: [PATCH 015/116] remove item::has_pockets and replace calls with item::is_container --- src/game.cpp | 8 ++++---- src/item.cpp | 6 +++--- src/item.h | 5 ----- src/visitable.cpp | 2 +- tests/pocket_test.cpp | 6 +++--- 5 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index e7456a56cd51b..1056e6427c069 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2223,7 +2223,7 @@ int game::inventory_item_menu( item_location locThisItem, addentry( 'p', pgettext( "action", "part reload" ), u.rate_action_reload( oThisItem ) ); addentry( 'm', pgettext( "action", "mend" ), rate_action_mend( u, oThisItem ) ); addentry( 'D', pgettext( "action", "disassemble" ), rate_action_disassemble( u, oThisItem ) ); - if( oThisItem.has_pockets() ) { + if( oThisItem.is_container() ) { addentry( 'i', pgettext( "action", "insert" ), rate_action_insert( u, locThisItem ) ); if( oThisItem.contents.num_item_stacks() > 0 ) { addentry( 'o', pgettext( "action", "open" ), hint_rating::good ); @@ -2391,17 +2391,17 @@ int game::inventory_item_menu( item_location locThisItem, } break; case 'v': - if( oThisItem.has_pockets() ) { + if( oThisItem.is_container() ) { oThisItem.contents.favorite_settings_menu( oThisItem.tname( 1, false ) ); } break; case 'i': - if( oThisItem.has_pockets() ) { + if( oThisItem.is_container() ) { game_menus::inv::insert_items( u, locThisItem ); } break; case 'o': - if( oThisItem.has_pockets() && oThisItem.contents.num_item_stacks() > 0 ) { + if( oThisItem.is_container() && oThisItem.contents.num_item_stacks() > 0 ) { game_menus::inv::common( locThisItem, u ); } break; diff --git a/src/item.cpp b/src/item.cpp index 4945f1b835b8c..e8d0c4a71baab 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -890,7 +890,7 @@ item item::in_container( const itype_id &cont, const int qty, const bool sealed return *this; } item container( cont, birthday() ); - if( container.has_pockets() ) { + if( container.is_container() ) { if( count_by_charges() ) { container.fill_with( *this, qty ); } else { @@ -7528,7 +7528,7 @@ std::pair item::best_pocket( const item &it, item_ bool item::spill_contents( Character &c ) { - if( !has_pockets() || is_container_empty() ) { + if( !is_container() || is_container_empty() ) { return true; } @@ -7544,7 +7544,7 @@ bool item::spill_contents( Character &c ) bool item::spill_contents( const tripoint &pos ) { - if( !has_pockets() || is_container_empty() ) { + if( !is_container() || is_container_empty() ) { return true; } return contents.spill_contents( pos ); diff --git a/src/item.h b/src/item.h index f78ca13bf3dca..04f5f64232ed2 100644 --- a/src/item.h +++ b/src/item.h @@ -783,11 +783,6 @@ class item : public visitable // recursive function that checks pockets for remaining free space units::volume check_for_free_space() const; units::volume get_selected_stack_volume( const std::map &without ) const; - // checks if the item can have things placed in it - bool has_pockets() const { - // what has it gots in them, precious - return contents.has_pocket_type( item_pocket::pocket_type::CONTAINER ); - } /** * Puts the given item into this one. */ diff --git a/src/visitable.cpp b/src/visitable.cpp index c4969073b901f..45fb6c6f1fe68 100644 --- a/src/visitable.cpp +++ b/src/visitable.cpp @@ -749,7 +749,7 @@ static int charges_of_internal( const T &self, const M &main, const itype_id &id found_tool_with_UPS = true; } } - if( !e->has_pockets() ) { + if( !e->is_container() ) { return qty < limit ? VisitResponse::SKIP : VisitResponse::ABORT; } diff --git a/tests/pocket_test.cpp b/tests/pocket_test.cpp index e97efc2e7b938..ba0c26cdfdff6 100644 --- a/tests/pocket_test.cpp +++ b/tests/pocket_test.cpp @@ -1090,7 +1090,7 @@ TEST_CASE( "best pocket in item contents", "[pocket][item][best]" ) SECTION( "item with one watertight pocket has best_pocket for liquid" ) { // Must have a CONTAINER pocket, first and foremost item skin( "test_waterskin" ); - REQUIRE( skin.has_pockets() ); + REQUIRE( skin.is_container() ); REQUIRE( skin.contents.has_pocket_type( item_pocket::pocket_type::CONTAINER ) ); // Prerequisite: It can contain water item liquid( "test_liquid" ); @@ -1104,7 +1104,7 @@ TEST_CASE( "best pocket in item contents", "[pocket][item][best]" ) SECTION( "item with many different pockets can have best_pocket for different items" ) { // Utility belt has CONTAINER pockets item util_belt( "test_utility_belt" ); - REQUIRE( util_belt.has_pockets() ); + REQUIRE( util_belt.is_container() ); REQUIRE( util_belt.contents.has_pocket_type( item_pocket::pocket_type::CONTAINER ) ); // It can contain small and large tools item screwdriver( "test_screwdriver" ); @@ -1153,7 +1153,7 @@ TEST_CASE( "best pocket in item contents", "[pocket][item][best]" ) SECTION( "sealed pockets cannot be best_pocket" ) { // Regular aluminum beverage can and something to fill it with item can( "test_can_drink" ); - REQUIRE( can.has_pockets() ); + REQUIRE( can.is_container() ); REQUIRE( can.contents.has_pocket_type( item_pocket::pocket_type::CONTAINER ) ); item liquid( "test_liquid" ); REQUIRE( can.can_contain( liquid ) ); From f5c4c514274839085b813e451c3bcc973bbe7c45 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Tue, 6 Jul 2021 16:06:13 -0700 Subject: [PATCH 016/116] Allow gun variants to have plural names (#49638) Convert the 610 to have a plural name, as it should have. --- data/json/items/gun/10mm.json | 2 +- src/item_factory.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/data/json/items/gun/10mm.json b/data/json/items/gun/10mm.json index 45b6bb7ffbf73..7d8a54e1c8cbd 100644 --- a/data/json/items/gun/10mm.json +++ b/data/json/items/gun/10mm.json @@ -9,7 +9,7 @@ "variants": [ { "id": "sw_610", - "name": { "str": "S&W 610" }, + "name": { "str_sp": "S&W 610" }, "description": "The Smith and Wesson 610 is a classic six-shooter revolver chambered for 10mm rounds, or for S&W's own .40 round.", "weight": 1 } diff --git a/src/item_factory.cpp b/src/item_factory.cpp index 268614af0a89c..51c7036377da0 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -1779,6 +1779,7 @@ void gun_variant_data::deserialize( JsonIn &jsin ) void gun_variant_data::load( const JsonObject &jo ) { + brand_name.make_plural(); mandatory( jo, false, "id", id ); mandatory( jo, false, "name", brand_name ); mandatory( jo, false, "description", alt_description ); From e163259ec67bb863afe2553ef94e36239567b1ef Mon Sep 17 00:00:00 2001 From: Paul Fenwick Date: Tue, 6 Jul 2021 16:21:59 -0700 Subject: [PATCH 017/116] Kegs no longer errorneously suggest they can be used for fermenting. (#49628) Only the fermenting vat does this. --- data/json/furniture_and_terrain/furniture-storage.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/furniture_and_terrain/furniture-storage.json b/data/json/furniture_and_terrain/furniture-storage.json index f0949f3ed1c35..ea36a295ef3ca 100644 --- a/data/json/furniture_and_terrain/furniture-storage.json +++ b/data/json/furniture_and_terrain/furniture-storage.json @@ -780,7 +780,7 @@ "id": "f_wood_keg", "name": "wooden keg", "looks_like": "f_standing_tank", - "description": "A large standing wooden barrel, completely watertight. Good for storing liquids of all kinds or fermenting alcohol.", + "description": "A large standing wooden barrel, completely watertight. Good for storing liquids of all kinds.", "symbol": "H", "color": "brown", "move_cost_mod": -1, From 76053d6ae39c6c0c6f9b86a9f72b1c508f132a6e Mon Sep 17 00:00:00 2001 From: C-LR <70963914+C-LR@users.noreply.github.com> Date: Wed, 7 Jul 2021 01:41:53 +0200 Subject: [PATCH 018/116] Correct contribute md (#49603) * Fix the position of a "cd" in the workflow guide of CONTRIBUTING.md Setting a commit template outside of a repo will result in a fail. It is very minimal but it helps keep the guide useful to everybody. No links Fix "cd" command position in CONTRIBUTING.md --- .github/CONTRIBUTING.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index bd959ede62aea..adfcece442844 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -111,12 +111,13 @@ Helpful pages: 3. Set commit message template. + $ cd Cataclysm-DDA + # Changes the active directory in the prompt to the newly cloned "Cataclysm-DDA" directory $ git config --local commit.template .gitmessage + # Set commit message template to the custom one in the repo 4. Add this repository as a remote. - $ cd Cataclysm-DDA - # Changes the active directory in the prompt to the newly cloned "Cataclysm-DDA" directory $ git remote add -f upstream https://github.com/CleverRaven/Cataclysm-DDA.git # Assigns the original repository to a remote called "upstream" From 95cc52b63ed0ea6845799c66de16c0af2632ae98 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Tue, 6 Jul 2021 18:43:45 -0700 Subject: [PATCH 019/116] Convert armor to use armor_portion_data (AFS) I want to make changes to how armor data is specified, and I don't want to maintain two separate interfaces for it, so let's convert existing data to one interface. Items using copy-from were audited, and where they made changes, data was respecified as at the moment, copy-from modifying sub-elements of armor portion data is incorrect (there are lots of questions with no good answers there). --- data/mods/Aftershock/items/armor.json | 88 ++++++------------- .../Aftershock/items/cast_spell_items.json | 5 +- data/mods/Aftershock/items/ethereal.json | 16 +++- data/mods/Aftershock/items/items.json | 5 +- data/mods/Aftershock/items/obsolete.json | 44 ++++------ data/mods/Aftershock/items/tool_armor.json | 12 ++- data/mods/Aftershock/items/tools.json | 16 ++-- data/mods/Aftershock/items/weapons.json | 11 ++- 8 files changed, 81 insertions(+), 116 deletions(-) diff --git a/data/mods/Aftershock/items/armor.json b/data/mods/Aftershock/items/armor.json index 16b57ff51c435..39ce4c7a037b6 100644 --- a/data/mods/Aftershock/items/armor.json +++ b/data/mods/Aftershock/items/armor.json @@ -13,15 +13,12 @@ "material": [ "glass", "superalloy", "platinum" ], "symbol": "[", "color": "cyan", - "covers": [ "torso" ], "looks_like": "molle_pack", - "coverage": 30, - "encumbrance": 5, - "max_encumbrance": 10, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "100 L", "max_contains_weight": "500 kg", "moves": 300 } ], "warmth": 5, "material_thickness": 2, - "flags": [ "BELTED", "ONLY_ONE", "LEAK_DAM" ] + "flags": [ "BELTED", "ONLY_ONE", "LEAK_DAM" ], + "armor": [ { "encumbrance": [ 5, 10 ], "coverage": 30, "covers": [ "torso" ] } ] }, { "id": "afs_titanium_vest", @@ -36,10 +33,8 @@ "symbol": "[", "looks_like": "armor_scrapsuit", "color": "white", - "covers": [ "torso" ], - "coverage": 80, - "encumbrance": 4, - "material_thickness": 2 + "material_thickness": 2, + "armor": [ { "encumbrance": 4, "coverage": 80, "covers": [ "torso" ] } ] }, { "id": "afs_holo_cloak_mk2", @@ -64,13 +59,11 @@ "material": [ "graphene_weave" ], "symbol": "[", "color": "dark_gray", - "covers": [ "torso", "head", "arm_l", "arm_r", "leg_l", "leg_r" ], - "coverage": 85, - "encumbrance": 4, "warmth": 30, "material_thickness": 3, "flags": [ "OVERSIZE", "HOOD", "OUTER", "NO_REPAIR", "SUPER_FANCY", "STURDY" ], - "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "BONUS_DODGE", "add": 1 } ] } ] } + "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "BONUS_DODGE", "add": 1 } ] } ] }, + "armor": [ { "encumbrance": 4, "coverage": 85, "covers": [ "torso", "head", "arm_l", "arm_r", "leg_l", "leg_r" ] } ] }, { "id": "xl_jeans", @@ -131,12 +124,10 @@ "material": [ "glass", "steel" ], "symbol": "[", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 12, "material_thickness": 3, "use_action": [ "SOLARPACK" ], - "flags": [ "FRAGILE", "OUTER", "ONLY_ONE", "SOLARPACK" ] + "flags": [ "FRAGILE", "OUTER", "ONLY_ONE", "SOLARPACK" ], + "armor": [ { "encumbrance": 12, "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "q_solarpack_on", @@ -152,13 +143,11 @@ "material": [ "glass", "steel" ], "symbol": "[", "color": "blue", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 20, "material_thickness": 1, "use_action": [ "SOLARPACK_OFF" ], "solar_efficiency": 0.3, - "flags": [ "FRAGILE", "OUTER", "ONLY_ONE", "SOLARPACK_ON" ] + "flags": [ "FRAGILE", "OUTER", "ONLY_ONE", "SOLARPACK_ON" ], + "armor": [ { "encumbrance": 20, "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "xlswat_armor", @@ -177,9 +166,6 @@ "symbol": "[", "looks_like": "touring_suit", "color": "dark_gray", - "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], - "coverage": 95, - "encumbrance": 25, "warmth": 35, "material_thickness": 9, "valid_mods": [ "steel_padded" ], @@ -188,7 +174,8 @@ "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "750 ml", "max_contains_weight": "2 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "750 ml", "max_contains_weight": "2 kg", "moves": 80 } - ] + ], + "armor": [ { "encumbrance": 25, "coverage": 95, "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ] } ] }, { "id": "xlballistic_vest_empty", @@ -203,12 +190,10 @@ "material": [ "nylon" ], "symbol": "[", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 85, - "encumbrance": 6, "warmth": 15, "material_thickness": 8, - "flags": [ "OVERSIZE", "STURDY", "OUTER", "WATER_FRIENDLY" ] + "flags": [ "OVERSIZE", "STURDY", "OUTER", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 6, "coverage": 85, "covers": [ "torso" ] } ] }, { "id": "xlballistic_vest_esapi", @@ -222,12 +207,10 @@ "material": [ "nylon", "ceramic" ], "symbol": "[", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 85, - "encumbrance": 10, "warmth": 15, "material_thickness": 26, - "flags": [ "OVERSIZE", "STURDY", "OUTER", "WATER_FRIENDLY", "NO_REPAIR" ] + "flags": [ "OVERSIZE", "STURDY", "OUTER", "WATER_FRIENDLY", "NO_REPAIR" ], + "armor": [ { "encumbrance": 10, "coverage": 85, "covers": [ "torso" ] } ] }, { "id": "xlboots_combat", @@ -246,13 +229,11 @@ "symbol": "[", "looks_like": "boots", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 25, "warmth": 25, "material_thickness": 5, "environmental_protection": 2, - "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 25, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "xlgloves_tactical", @@ -269,12 +250,10 @@ "symbol": "[", "looks_like": "fire_gauntlets", "color": "dark_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 13, "warmth": 20, "material_thickness": 5, - "flags": [ "OVERSIZE", "VARSIZE", "STURDY" ] + "flags": [ "OVERSIZE", "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": 13, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "tripaw_xlgloves_tactical", @@ -291,12 +270,10 @@ "symbol": "[", "looks_like": "fire_gauntlets", "color": "dark_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 5, "warmth": 20, "material_thickness": 3, - "flags": [ "OVERSIZE", "VARSIZE", "STURDY" ] + "flags": [ "OVERSIZE", "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": 5, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "xlleather_belt", @@ -379,10 +356,6 @@ "material": [ "steel", "plastic" ], "symbol": "[", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 20, - "encumbrance": 2, - "max_encumbrance": 15, "material_thickness": 2, "use_action": { "type": "holster", "holster_prompt": "Stash ammo", "holster_msg": "You stash your %s." }, "pocket_data": [ @@ -425,7 +398,8 @@ "moves": 60 } ], - "flags": [ "WATER_FRIENDLY", "BELTED" ] + "flags": [ "WATER_FRIENDLY", "BELTED" ], + "armor": [ { "encumbrance": [ 2, 15 ], "coverage": 20, "covers": [ "torso" ] } ] }, { "id": "wetsuit_cecalia", @@ -441,10 +415,6 @@ "symbol": "[", "looks_like": "wetsuit", "color": "light_gray", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 90, - "encumbrance": 2, - "max_encumbrance": 5, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "350 ml", "max_contains_weight": "1 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "350 ml", "max_contains_weight": "1 kg", "moves": 80 }, @@ -454,7 +424,8 @@ "warmth": 30, "material_thickness": 1, "environmental_protection": 2, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ], + "armor": [ { "encumbrance": [ 2, 5 ], "coverage": 90, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "id": "combat_wetsuit_cecalia", @@ -470,10 +441,6 @@ "symbol": "[", "looks_like": "wetsuit", "color": "light_gray", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 90, - "encumbrance": 2, - "max_encumbrance": 5, "use_action": { "type": "holster", "holster_prompt": "Stash ammo", "holster_msg": "You stash your %s." }, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "350 ml", "max_contains_weight": "1 kg", "moves": 80 }, @@ -509,6 +476,7 @@ "warmth": 30, "material_thickness": 2, "environmental_protection": 3, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ], + "armor": [ { "encumbrance": [ 2, 5 ], "coverage": 90, "covers": [ "torso", "arm_l", "arm_r" ] } ] } ] diff --git a/data/mods/Aftershock/items/cast_spell_items.json b/data/mods/Aftershock/items/cast_spell_items.json index 98cbb5aff37b5..c8d216ee547cf 100644 --- a/data/mods/Aftershock/items/cast_spell_items.json +++ b/data/mods/Aftershock/items/cast_spell_items.json @@ -10,11 +10,10 @@ "material": [ "superalloy" ], "symbol": "[", "color": "light_red", - "covers": [ "torso" ], "charges_per_use": 1, - "coverage": 0, "warmth": 0, - "flags": [ "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS", "ONLY_ONE", "NO_UNLOAD", "NO_RELOAD" ] + "flags": [ "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS", "ONLY_ONE", "NO_UNLOAD", "NO_RELOAD" ], + "armor": [ { "coverage": 0, "covers": [ "torso" ] } ] }, { "id": "afs_holo_transposition_caster", diff --git a/data/mods/Aftershock/items/ethereal.json b/data/mods/Aftershock/items/ethereal.json index 3ae15d5addf67..2628d6ecf13bc 100644 --- a/data/mods/Aftershock/items/ethereal.json +++ b/data/mods/Aftershock/items/ethereal.json @@ -10,8 +10,12 @@ "symbol": "o", "warmth": 150, "color": "green", - "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ], - "flags": [ "AURA", "SEMITANGIBLE", "OVERSIZE", "ONLY_ONE", "TRADER_AVOID", "NO_TAKEOFF", "CLIMATE_CONTROL", "NONCONDUCTIVE" ] + "flags": [ "AURA", "SEMITANGIBLE", "OVERSIZE", "ONLY_ONE", "TRADER_AVOID", "NO_TAKEOFF", "CLIMATE_CONTROL", "NONCONDUCTIVE" ], + "armor": [ + { + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ] + } + ] }, { "id": "cold_res_cream_greater", @@ -24,10 +28,14 @@ "symbol": "o", "warmth": 150, "color": "green", - "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ], "flags": [ "AURA", "SEMITANGIBLE", "OVERSIZE", "ONLY_ONE", "TRADER_AVOID", "NO_TAKEOFF", "CLIMATE_CONTROL", "NONCONDUCTIVE" ], "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "ARMOR_COLD", "multiply": -0.25 } ] } ] - } + }, + "armor": [ + { + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ] + } + ] } ] diff --git a/data/mods/Aftershock/items/items.json b/data/mods/Aftershock/items/items.json index 2850b072dc91f..9efde1a91fd57 100644 --- a/data/mods/Aftershock/items/items.json +++ b/data/mods/Aftershock/items/items.json @@ -182,10 +182,9 @@ "material": [ "titanium" ], "symbol": "[", "color": "light_gray", - "covers": [ "hand_l", "hand_r" ], "sided": true, - "coverage": 5, - "flags": [ "WATCH", "STURDY", "BELTED", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY", "OVERSIZE" ] + "flags": [ "WATCH", "STURDY", "BELTED", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY", "OVERSIZE" ], + "armor": [ { "coverage": 5, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "afs_titanium_ring", diff --git a/data/mods/Aftershock/items/obsolete.json b/data/mods/Aftershock/items/obsolete.json index 3dcb09a95aea0..888232598bacf 100644 --- a/data/mods/Aftershock/items/obsolete.json +++ b/data/mods/Aftershock/items/obsolete.json @@ -298,11 +298,7 @@ "price": 100000000, "price_postapoc": 50000, "material": [ "superalloy", "kevlar" ], - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, "material_thickness": 2, - "encumbrance": 4, - "max_encumbrance": 9, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 } @@ -320,7 +316,14 @@ "OUTER", "STURDY" ], - "looks_like": "depowered_armor" + "looks_like": "depowered_armor", + "armor": [ + { + "encumbrance": [ 4, 9 ], + "coverage": 100, + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "afs_hev_helmet", @@ -334,10 +337,7 @@ "price": 10000000, "price_postapoc": 5000, "material": [ "superalloy", "plastic" ], - "covers": [ "head", "eyes", "mouth" ], - "coverage": 100, "material_thickness": 2, - "encumbrance": 15, "warmth": 20, "environmental_protection": 11, "qualities": [ [ "GLARE", 3 ] ], @@ -369,7 +369,8 @@ "light_disposable_cell" ] } - ] + ], + "armor": [ { "encumbrance": 15, "coverage": 100, "covers": [ "head", "eyes", "mouth" ] } ] }, { "id": "afs_hev_helmet_on", @@ -396,12 +397,10 @@ "symbol": "[", "looks_like": "quiver", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 20, - "encumbrance": 5, "material_thickness": 1, "pocket_data": [ { "ammo_restriction": { "arrow": 40, "bolt": 40 }, "moves": 20 } ], - "flags": [ "BELTED", "OVERSIZE", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "OVERSIZE", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 5, "coverage": 20, "covers": [ "torso" ] } ] }, { "id": "afs_survivor_belt", @@ -430,12 +429,10 @@ "symbol": "[", "looks_like": "armor_blarmor", "color": "brown", - "covers": [ "torso" ], - "coverage": 100, - "encumbrance": 16, "warmth": 25, "material_thickness": 3, - "flags": [ "RAINPROOF", "STURDY", "OUTER", "ONLY_ONE", "VARSIZE" ] + "flags": [ "RAINPROOF", "STURDY", "OUTER", "ONLY_ONE", "VARSIZE" ], + "armor": [ { "encumbrance": 16, "coverage": 100, "covers": [ "torso" ] } ] }, { "id": "afs_mbr_titanium", @@ -452,10 +449,6 @@ "symbol": "[", "looks_like": "kevlar", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 85, - "encumbrance": 3, - "max_encumbrance": 7, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 } @@ -463,7 +456,8 @@ "warmth": 15, "material_thickness": 3, "use_action": { "type": "holster", "holster_prompt": "Stash ammo", "holster_msg": "You stash your %s." }, - "flags": [ "STURDY", "OUTER" ] + "flags": [ "STURDY", "OUTER" ], + "armor": [ { "encumbrance": [ 3, 7 ], "coverage": 85, "covers": [ "torso" ] } ] }, { "id": "afs_sunesthesia", @@ -643,12 +637,10 @@ "symbol": "[", "looks_like": "armor_blarmor", "color": "white", - "covers": [ "torso" ], - "coverage": 95, - "encumbrance": 14, "warmth": 20, "material_thickness": 2, - "flags": [ "OUTER", "VARSIZE" ] + "flags": [ "OUTER", "VARSIZE" ], + "armor": [ { "encumbrance": 14, "coverage": 95, "covers": [ "torso" ] } ] }, { "type": "GENERIC", diff --git a/data/mods/Aftershock/items/tool_armor.json b/data/mods/Aftershock/items/tool_armor.json index 57ea1950fb1cf..10cb0d0ce8ab0 100644 --- a/data/mods/Aftershock/items/tool_armor.json +++ b/data/mods/Aftershock/items/tool_armor.json @@ -33,13 +33,17 @@ "need_charges": 5, "need_charges_msg": "The %s's batteries are dead." }, - "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "warmth": 20, "environmental_protection": 10, - "coverage": 100, "material_thickness": 1, - "encumbrance": 5, - "flags": [ "VARSIZE", "SKINTIGHT", "RAINPROOF", "STURDY", "WATERPROOF", "HYGROMETER" ] + "flags": [ "VARSIZE", "SKINTIGHT", "RAINPROOF", "STURDY", "WATERPROOF", "HYGROMETER" ], + "armor": [ + { + "encumbrance": 5, + "coverage": 100, + "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "afs_cryopod_bodyglove_on", diff --git a/data/mods/Aftershock/items/tools.json b/data/mods/Aftershock/items/tools.json index 634d7b151cc72..5d0c6819e3493 100644 --- a/data/mods/Aftershock/items/tools.json +++ b/data/mods/Aftershock/items/tools.json @@ -184,13 +184,11 @@ "copy-from": "UPS_off", "name": { "str": "UPS", "str_pl": "UPS's" }, "description": "This is a unified power supply, or UPS. It is a device developed jointly by military and scientific interests for use in combat and the field. The UPS is designed to power armor and some guns, but drains batteries quickly. It can be worn strapped to either leg for ease of access, and it's been waterproofed to protect the delicate electronics. Has its own custom battery, rechargeable and with higher capacity, but not removable", - "coverage": 5, "ammo": [ "battery" ], - "encumbrance": 2, - "covers": [ "leg_l", "leg_r" ], "sided": true, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "battery": 1500 } } ], - "flags": [ "RECHARGE", "WAIST", "NO_UNLOAD", "NO_RELOAD", "FRAGILE", "OVERSIZE", "WATERPROOF", "IS_UPS" ] + "flags": [ "RECHARGE", "WAIST", "NO_UNLOAD", "NO_RELOAD", "FRAGILE", "OVERSIZE", "WATERPROOF", "IS_UPS" ], + "armor": [ { "encumbrance": 2, "coverage": 5, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "adv_UPS_off", @@ -198,11 +196,9 @@ "copy-from": "adv_UPS_off", "name": { "str": "advanced UPS", "str_pl": "advanced UPS's" }, "description": "This is an advanced version of the unified power supply, or UPS. This device has been significantly redesigned to provide better efficiency as well as to consume plutonium fuel cells rather than batteries, and is both slimmer and lighter to wear. Sadly, its plutonium reactor can't be charged in UPS charging station.", - "coverage": 5, - "encumbrance": 1, - "covers": [ "leg_l", "leg_r" ], "sided": true, - "flags": [ "WAIST", "FRAGILE", "OVERSIZE", "IS_UPS" ] + "flags": [ "WAIST", "FRAGILE", "OVERSIZE", "IS_UPS" ], + "armor": [ { "encumbrance": 1, "coverage": 5, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "bionic_maintenance_toolkit", @@ -290,7 +286,6 @@ "color": "dark_gray", "material": [ "glass", "titanium" ], "copy-from": "fancy_sunglasses", - "covers": [ "eyes", "torso" ], "ammo": [ "battery" ], "charges_per_use": 2, "use_action": [ @@ -316,7 +311,8 @@ "max_contains_weight": "20 kg", "item_restriction": [ "medium_battery_cell", "medium_plus_battery_cell", "medium_atomic_battery_cell", "medium_disposable_cell" ] } - ] + ], + "armor": [ { "covers": [ "eyes", "torso" ] } ] }, { "id": "vr_laptop_holosuite", diff --git a/data/mods/Aftershock/items/weapons.json b/data/mods/Aftershock/items/weapons.json index fab508133ca3c..61938e5dbb8e7 100644 --- a/data/mods/Aftershock/items/weapons.json +++ b/data/mods/Aftershock/items/weapons.json @@ -156,9 +156,8 @@ "to_hit": 0, "flags": [ "NO_REPAIR", "NONCONDUCTIVE", "SLOW_WIELD", "DURABLE_MELEE", "UNARMED_WEAPON" ], "techniques": [ "WBLOCK_1" ], - "coverage": 100, - "encumbrance": 5, - "material_thickness": 1 + "material_thickness": 1, + "armor": [ { "encumbrance": 5, "coverage": 100 } ] }, { "type": "GENERIC", @@ -283,7 +282,7 @@ "longest_side": "183 cm", "price_postapoc": 40000, "bashing": 10, - "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 20 }, + "armor_data": { "material_thickness": 1, "armor": [ { "encumbrance": 20, "coverage": 5, "covers": [ "torso" ] } ] }, "reload_noise_volume": 3, "loudness": 8, "ranged_damage": { "damage_type": "stab", "amount": 17 }, @@ -321,7 +320,7 @@ "longest_side": "183 cm", "price_postapoc": 40000, "bashing": 10, - "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 20 }, + "armor_data": { "material_thickness": 1, "armor": [ { "encumbrance": 20, "coverage": 5, "covers": [ "torso" ] } ] }, "reload_noise_volume": 3, "loudness": 8, "ranged_damage": { "damage_type": "stab", "amount": 17 }, @@ -374,7 +373,7 @@ "longest_side": "152 cm", "price_postapoc": 2000, "bashing": 12, - "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 20 }, + "armor_data": { "material_thickness": 1, "armor": [ { "encumbrance": 20, "coverage": 5, "covers": [ "torso" ] } ] }, "reload_noise_volume": 3, "loudness": 8, "ranged_damage": { "damage_type": "stab", "amount": 12 }, From 5b002c5c56f8ec045e79819f2d7caa4248e29cd9 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Tue, 6 Jul 2021 18:44:13 -0700 Subject: [PATCH 020/116] Convert armor to use armor_portion_data (CRT) I want to make changes to how armor data is specified, and I don't want to maintain two separate interfaces for it, so let's convert existing data to one interface. Items using copy-from were audited, and where they made changes, data was respecified as at the moment, copy-from modifying sub-elements of armor portion data is incorrect (there are lots of questions with no good answers there). --- .../CRT_EXPANSION/crt_gear/advanced_gear.json | 17 ++-- data/mods/CRT_EXPANSION/items/crt_armor.json | 84 +++++++------------ .../mods/CRT_EXPANSION/items/crt_clothes.json | 35 +++----- .../items/crt_makeshift_survival.json | 11 +-- .../CRT_EXPANSION/items/crt_toolarmor.json | 30 +++---- 5 files changed, 64 insertions(+), 113 deletions(-) diff --git a/data/mods/CRT_EXPANSION/crt_gear/advanced_gear.json b/data/mods/CRT_EXPANSION/crt_gear/advanced_gear.json index 6f646b8f256e9..ff01f286cee9f 100644 --- a/data/mods/CRT_EXPANSION/crt_gear/advanced_gear.json +++ b/data/mods/CRT_EXPANSION/crt_gear/advanced_gear.json @@ -12,8 +12,6 @@ "material": [ "plastic", "steel" ], "symbol": "[", "color": "light_green", - "coverage": 0, - "encumbrance": 0, "warmth": 0, "//": "Legacy artifact data is set for all stats +2", "relic_data": { @@ -32,7 +30,8 @@ }, "material_thickness": 10, "environmental_protection": 0, - "flags": [ "ONLY_ONE", "TRADER_AVOID", "BELTED", "NO_TAKEOFF" ] + "flags": [ "ONLY_ONE", "TRADER_AVOID", "BELTED", "NO_TAKEOFF" ], + "armor": [ { "encumbrance": 0, "coverage": 0 } ] }, { "id": "ds_armor", @@ -48,9 +47,6 @@ "material": [ "superalloy", "nomex", "kevlar" ], "symbol": "[", "color": "light_gray", - "covers": [ "head", "eyes", "mouth", "torso", "leg_l", "leg_r", "arm_l", "arm_r", "hand_l", "hand_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 25, "warmth": 15, "pocket_data": [ { @@ -65,6 +61,13 @@ "material_thickness": 3, "environmental_protection": 18, "use_action": [ "WEATHER_TOOL" ], - "flags": [ "ELECTRIC_IMMUNE", "GAS_PROOF", "VARSIZE", "OVERSIZE", "STURDY", "ONLY_ONE", "WATERPROOF", "CLIMATE_CONTROL" ] + "flags": [ "ELECTRIC_IMMUNE", "GAS_PROOF", "VARSIZE", "OVERSIZE", "STURDY", "ONLY_ONE", "WATERPROOF", "CLIMATE_CONTROL" ], + "armor": [ + { + "encumbrance": 25, + "coverage": 100, + "covers": [ "head", "eyes", "mouth", "torso", "leg_l", "leg_r", "arm_l", "arm_r", "hand_l", "hand_r", "foot_l", "foot_r" ] + } + ] } ] diff --git a/data/mods/CRT_EXPANSION/items/crt_armor.json b/data/mods/CRT_EXPANSION/items/crt_armor.json index 2f6d322632d9b..a1c092bd8241c 100644 --- a/data/mods/CRT_EXPANSION/items/crt_armor.json +++ b/data/mods/CRT_EXPANSION/items/crt_armor.json @@ -12,14 +12,12 @@ "material": [ "neoprene", "kevlar" ], "symbol": "[", "color": "dark_gray", - "covers": [ "eyes", "mouth" ], - "coverage": 100, - "encumbrance": 20, "warmth": 30, "material_thickness": 2, "environmental_protection": 10, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "WATERPROOF", "STURDY", "SUN_GLASSES", "VARSIZE", "WATCH", "THERMOMETER" ] + "flags": [ "WATERPROOF", "STURDY", "SUN_GLASSES", "VARSIZE", "WATCH", "THERMOMETER" ], + "armor": [ { "encumbrance": 20, "coverage": 100, "covers": [ "eyes", "mouth" ] } ] }, { "id": "crt_boots", @@ -31,9 +29,9 @@ "weight": "1500 g", "price": 250000, "warmth": 40, - "encumbrance": 17, "material_thickness": 5, - "environmental_protection": 5 + "environmental_protection": 5, + "armor": [ { "encumbrance": 17 } ] }, { "id": "crt_la_boots", @@ -49,13 +47,11 @@ "material": [ "rubber", "superalloy", "nomex" ], "symbol": "[", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 10, "warmth": 25, "material_thickness": 3, "environmental_protection": 2, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 10, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "crt_gloves", @@ -63,12 +59,11 @@ "type": "ARMOR", "name": { "str": "pair of CRIT fingertip-less gloves", "str_pl": "pairs of CRIT fingertip-less gloves" }, "description": "A pair of standard-issue gloves. Made with superalloy mesh for those with gene-modding and/or mutations while still allowing greater manipulation of items and moderate protection.", - "encumbrance": 12, - "coverage": 85, "warmth": 20, "material": [ "kevlar", "superalloy" ], "material_thickness": 2, - "flags": [ "ALLOWS_NATURAL_ATTACKS", "STURDY", "WATERPROOF" ] + "flags": [ "ALLOWS_NATURAL_ATTACKS", "STURDY", "WATERPROOF" ], + "armor": [ { "encumbrance": 12, "coverage": 85, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "crt_gloves_liner", @@ -76,12 +71,11 @@ "type": "ARMOR", "name": { "str": "pair of CRIT fingertip-less liners", "str_pl": "pairs of CRIT fingertip-less liners" }, "description": "A pair of standard-issue glove liners. Made with neoprene and rubber mesh for warmth and fingertip-less for those with gene-modding and/or mutations while still allowing greater manipulation of items and moderate protection.", - "encumbrance": 3, - "coverage": 85, "warmth": 15, "material": [ "neoprene", "rubber" ], "material_thickness": 1, - "flags": [ "ALLOWS_NATURAL_ATTACKS", "SKINTIGHT" ] + "flags": [ "ALLOWS_NATURAL_ATTACKS", "SKINTIGHT" ], + "armor": [ { "encumbrance": 3, "coverage": 85, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "crt_backpack", @@ -91,10 +85,10 @@ "description": "A standard-issue pack. Based on the MOLLE backpack's design, this smaller pack strikes a fine balance between storage space and encumbrance and allows a larger weapon to be holstered, drawing and holstering is still rather awkward even with the magnetized clips, but practice helps.", "color": "dark_gray", "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "9 L", "max_contains_weight": "27 kg", "moves": 200 } ], - "encumbrance": 3, "material_thickness": 3, "material": [ "leather", "kevlar" ], - "flags": [ "BELTED", "OVERSIZE", "NO_QUICKDRAW", "STURDY", "WATERPROOF" ] + "flags": [ "BELTED", "OVERSIZE", "NO_QUICKDRAW", "STURDY", "WATERPROOF" ], + "armor": [ { "encumbrance": [ 3, 20 ], "coverage": 20, "covers": [ "torso" ] } ] }, { "id": "crt_chestrig", @@ -134,13 +128,11 @@ "material": [ "superalloy", "neoprene", "rubber" ], "symbol": "[", "color": "white", - "covers": [ "arm_l", "arm_r" ], - "coverage": 100, - "encumbrance": 20, "warmth": 17, "material_thickness": 4, "environmental_protection": 3, - "flags": [ "STURDY", "BELTED", "BLOCK_WHILE_WORN", "WATER_FRIENDLY" ] + "flags": [ "STURDY", "BELTED", "BLOCK_WHILE_WORN", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 20, "coverage": 100, "covers": [ "arm_l", "arm_r" ] } ] }, { "id": "crt_belt", @@ -165,10 +157,6 @@ "material": [ "neoprene", "rubber", "kevlar" ], "symbol": "[", "color": "black_green", - "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], - "coverage": 100, - "encumbrance": 10, - "max_encumbrance": 20, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, @@ -178,7 +166,8 @@ "warmth": 20, "material_thickness": 3, "environmental_protection": 9, - "flags": [ "POCKETS", "OUTER", "COLLAR", "STURDY", "WATERPROOF", "RAINPROOF" ] + "flags": [ "POCKETS", "OUTER", "COLLAR", "STURDY", "WATERPROOF", "RAINPROOF" ], + "armor": [ { "encumbrance": [ 10, 20 ], "coverage": 100, "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ] } ] }, { "id": "crt_aarmor", @@ -194,10 +183,6 @@ "material": [ "kevlar", "nomex", "plastic" ], "symbol": "[", "color": "light_green", - "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], - "coverage": 100, - "encumbrance": 17, - "max_encumbrance": 25, "warmth": 25, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, @@ -205,7 +190,8 @@ ], "material_thickness": 5, "environmental_protection": 25, - "flags": [ "VARSIZE", "WATERPROOF", "HOOD", "COLLAR", "RAINPROOF", "STURDY", "RAD_RESIST", "OUTER" ] + "flags": [ "VARSIZE", "WATERPROOF", "HOOD", "COLLAR", "RAINPROOF", "STURDY", "RAD_RESIST", "OUTER" ], + "armor": [ { "encumbrance": [ 17, 25 ], "coverage": 100, "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ] } ] }, { "id": "crt_legrig", @@ -218,16 +204,13 @@ "material": [ "plastic", "cotton", "rubber" ], "symbol": "[", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 30, - "encumbrance": 1, - "max_encumbrance": 3, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 } ], "material_thickness": 2, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "BELTED", "RAINPROOF", "ALLOWS_TAIL" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "BELTED", "RAINPROOF", "ALLOWS_TAIL" ], + "armor": [ { "encumbrance": [ 1, 3 ], "coverage": 30, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "crt_earmor", @@ -243,10 +226,6 @@ "material": [ "steel", "kevlar" ], "symbol": "[", "color": "cyan", - "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], - "coverage": 90, - "encumbrance": 27, - "max_encumbrance": 35, "warmth": 20, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, @@ -254,7 +233,8 @@ ], "material_thickness": 4, "environmental_protection": 5, - "flags": [ "VARSIZE", "STURDY", "BELTED" ] + "flags": [ "VARSIZE", "STURDY", "BELTED" ], + "armor": [ { "encumbrance": [ 27, 35 ], "coverage": 90, "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ] } ] }, { "id": "crt_earmor_boots", @@ -270,13 +250,11 @@ "material": [ "kevlar", "superalloy" ], "symbol": "[", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 30, "warmth": 5, "material_thickness": 3, "environmental_protection": 4, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY", "OUTER", "OVERSIZE" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY", "OUTER", "OVERSIZE" ], + "armor": [ { "encumbrance": 30, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "crt_sarmor", @@ -290,10 +268,6 @@ "material": [ "neoprene", "kevlar", "superalloy" ], "symbol": "[", "color": "light_blue", - "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], - "coverage": 100, - "encumbrance": 3, - "max_encumbrance": 7, "warmth": 20, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, @@ -301,7 +275,8 @@ ], "material_thickness": 2, "environmental_protection": 3, - "flags": [ "VARSIZE", "STURDY" ] + "flags": [ "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": [ 3, 7 ], "coverage": 100, "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ] } ] }, { "id": "crt_warmor", @@ -315,10 +290,6 @@ "material": [ "hardsteel", "kevlar" ], "symbol": "[", "color": "light_green", - "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], - "coverage": 100, - "encumbrance": 24, - "max_encumbrance": 40, "warmth": 25, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "2 L", "max_contains_weight": "3 kg", "moves": 80 }, @@ -326,6 +297,7 @@ ], "material_thickness": 3, "environmental_protection": 10, - "flags": [ "VARSIZE", "WATERPROOF", "OUTER", "OVERSIZE", "COLLAR", "STURDY", "NO_QUICKDRAW" ] + "flags": [ "VARSIZE", "WATERPROOF", "OUTER", "OVERSIZE", "COLLAR", "STURDY", "NO_QUICKDRAW" ], + "armor": [ { "encumbrance": [ 24, 40 ], "coverage": 100, "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ] } ] } ] diff --git a/data/mods/CRT_EXPANSION/items/crt_clothes.json b/data/mods/CRT_EXPANSION/items/crt_clothes.json index 8cc97601e9a26..7337555eec893 100644 --- a/data/mods/CRT_EXPANSION/items/crt_clothes.json +++ b/data/mods/CRT_EXPANSION/items/crt_clothes.json @@ -19,8 +19,8 @@ "color": "light_gray", "material": [ "neoprene", "kevlar" ], "warmth": 35, - "coverage": 100, - "flags": [ "WATERPROOF", "VARSIZE", "STURDY" ] + "flags": [ "WATERPROOF", "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": [ 11, 22 ], "coverage": 100, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "crt_dress_pants", @@ -32,11 +32,9 @@ "symbol": "[", "material": [ "cotton", "neoprene" ], "warmth": 17, - "covers": [ "leg_l", "leg_r" ], - "encumbrance": 10, - "coverage": 100, "material_thickness": 2, - "flags": [ "WATERPROOF", "VARSIZE", "FANCY" ] + "flags": [ "WATERPROOF", "VARSIZE", "FANCY" ], + "armor": [ { "encumbrance": [ 10, 11 ], "coverage": 100, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "crt_helmet_liner", @@ -62,13 +60,11 @@ "material": [ "cotton", "plastic", "rubber" ], "symbol": "[", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 65, - "encumbrance": 15, "warmth": 15, "material_thickness": 1, "environmental_protection": 2, - "flags": [ "VARSIZE", "WATERPROOF", "FANCY" ] + "flags": [ "VARSIZE", "WATERPROOF", "FANCY" ], + "armor": [ { "encumbrance": 15, "coverage": 65, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "crt_rec_gloves", @@ -82,13 +78,11 @@ "material": [ "cotton", "neoprene" ], "symbol": "[", "color": "dark_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 90, - "encumbrance": 4, "warmth": 10, "material_thickness": 1, "environmental_protection": 2, - "flags": [ "SKINTIGHT", "WATER_FRIENDLY" ] + "flags": [ "SKINTIGHT", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 4, "coverage": 90, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "crt_belt", @@ -123,10 +117,6 @@ "material": [ "cotton", "neoprene", "rubber" ], "symbol": "[", "color": "black_green", - "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], - "coverage": 100, - "encumbrance": 6, - "max_encumbrance": 13, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, @@ -136,7 +126,8 @@ "warmth": 15, "material_thickness": 1, "environmental_protection": 2, - "flags": [ "POCKETS", "OUTER", "OVERSIZE", "COLLAR", "WATERPROOF", "RAINPROOF", "FANCY" ] + "flags": [ "POCKETS", "OUTER", "OVERSIZE", "COLLAR", "WATERPROOF", "RAINPROOF", "FANCY" ], + "armor": [ { "encumbrance": [ 6, 13 ], "coverage": 100, "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ] } ] }, { "id": "crt_rec_hat", @@ -149,12 +140,10 @@ "material": [ "cotton", "neoprene", "rubber" ], "symbol": "[", "color": "white", - "covers": [ "head" ], - "coverage": 50, - "encumbrance": 10, "warmth": 15, "material_thickness": 1, "environmental_protection": 1, - "flags": [ "FANCY", "VARSIZE", "RAINPROOF", "WATERPROOF" ] + "flags": [ "FANCY", "VARSIZE", "RAINPROOF", "WATERPROOF" ], + "armor": [ { "encumbrance": 10, "coverage": 50, "covers": [ "head" ] } ] } ] diff --git a/data/mods/CRT_EXPANSION/items/crt_makeshift_survival.json b/data/mods/CRT_EXPANSION/items/crt_makeshift_survival.json index 0582358dda85d..8aa5494576c94 100644 --- a/data/mods/CRT_EXPANSION/items/crt_makeshift_survival.json +++ b/data/mods/CRT_EXPANSION/items/crt_makeshift_survival.json @@ -12,12 +12,10 @@ "material": [ "dry_plant" ], "symbol": "[", "color": "black_green", - "covers": [ "torso", "leg_l", "leg_r" ], - "coverage": 50, - "encumbrance": 15, "warmth": 7, "material_thickness": 3, - "flags": [ "OVERSIZE" ] + "flags": [ "OVERSIZE" ], + "armor": [ { "encumbrance": 15, "coverage": 50, "covers": [ "torso", "leg_l", "leg_r" ] } ] }, { "id": "crt_plant_band", @@ -32,10 +30,9 @@ "material": [ "dry_plant" ], "symbol": "[", "color": "black_green", - "coverage": 0, - "encumbrance": 0, "warmth": 7, "material_thickness": 1, - "flags": [ "OVERSIZE" ] + "flags": [ "OVERSIZE" ], + "armor": [ { "encumbrance": 0, "coverage": 0 } ] } ] diff --git a/data/mods/CRT_EXPANSION/items/crt_toolarmor.json b/data/mods/CRT_EXPANSION/items/crt_toolarmor.json index 551b49fd24be8..66fea36a97fe8 100644 --- a/data/mods/CRT_EXPANSION/items/crt_toolarmor.json +++ b/data/mods/CRT_EXPANSION/items/crt_toolarmor.json @@ -22,9 +22,6 @@ "material": [ "plastic", "kevlar" ], "symbol": "[", "color": "dark_gray", - "covers": [ "eyes", "mouth" ], - "coverage": 100, - "encumbrance": 50, "warmth": 20, "material_thickness": 5, "environmental_protection": 16, @@ -39,7 +36,8 @@ "USE_UPS", "NO_UNLOAD", "SLEEP_IGNORE" - ] + ], + "armor": [ { "encumbrance": 50, "coverage": 100, "covers": [ "eyes", "mouth" ] } ] }, { "id": "crt_gasmask_on", @@ -59,9 +57,6 @@ "material": [ "plastic", "kevlar" ], "symbol": "[", "color": "light_green", - "covers": [ "eyes", "mouth" ], - "coverage": 100, - "encumbrance": 5, "warmth": 75, "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "PERCEPTION", "add": 2 } ] } ] }, "material_thickness": 5, @@ -81,7 +76,8 @@ "USE_UPS", "NO_UNLOAD", "SLEEP_IGNORE" - ] + ], + "armor": [ { "encumbrance": 5, "coverage": 100, "covers": [ "eyes", "mouth" ] } ] }, { "id": "crt_em_vest", @@ -97,7 +93,6 @@ "material": [ "kevlar", "superalloy" ], "symbol": "[", "color": "light_gray", - "covers": [ "torso" ], "max_charges": 300, "initial_charges": 300, "charges_per_use": 1, @@ -110,8 +105,6 @@ "need_charges_msg": "Power levels too low for safe bootup…" }, "//": "Artifact data is charge_type solar", - "coverage": 85, - "encumbrance": 50, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "2 L", "max_contains_weight": "6 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "2 L", "max_contains_weight": "6 kg", "moves": 80 } @@ -119,7 +112,8 @@ "warmth": 10, "material_thickness": 4, "environmental_protection": 4, - "flags": [ "WATER_FRIENDLY", "STURDY", "VARSIZE", "USE_UPS", "NO_UNLOAD", "OUTER" ] + "flags": [ "WATER_FRIENDLY", "STURDY", "VARSIZE", "USE_UPS", "NO_UNLOAD", "OUTER" ], + "armor": [ { "encumbrance": 50, "coverage": 85, "covers": [ "torso" ] } ] }, { "id": "crt_em_vest_on", @@ -135,9 +129,6 @@ "material": [ "kevlar", "superalloy" ], "symbol": "[", "color": "light_green", - "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], - "coverage": 100, - "encumbrance": 5, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "2 L", "max_contains_weight": "6 kg", "moves": 40 }, { "pocket_type": "CONTAINER", "max_contains_volume": "2 L", "max_contains_weight": "6 kg", "moves": 40 } @@ -170,7 +161,8 @@ "USE_UPS", "NO_UNLOAD", "OUTER" - ] + ], + "armor": [ { "encumbrance": 5, "coverage": 100, "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ] } ] }, { "id": "crt_helmet", @@ -250,9 +242,6 @@ "material": [ "cotton" ], "symbol": "[", "color": "blue", - "covers": [ "mouth" ], - "coverage": 95, - "encumbrance": 7, "warmth": 0, "material_thickness": 1, "environmental_protection": 3, @@ -261,6 +250,7 @@ "initial_charges": 50, "charges_per_use": 1, "turns_per_charge": 5, - "flags": [ "WET" ] + "flags": [ "WET" ], + "armor": [ { "encumbrance": 7, "coverage": 95, "covers": [ "mouth" ] } ] } ] From ced7832fced932257d2e6d366e70adb96be1d9d6 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Tue, 6 Jul 2021 18:44:56 -0700 Subject: [PATCH 021/116] Convert armor to use armor_portion_data (Magiclysm I want to make changes to how armor data is specified, and I don't want to maintain two separate interfaces for it, so let's convert existing data to one interface. Items using copy-from were audited, and where they made changes, data was respecified as at the moment, copy-from modifying sub-elements of armor portion data is incorrect (there are lots of questions with no good answers there). --- .../Spells/attunements/Force_Mage.json | 12 +- .../mods/Magiclysm/enchantments/Soulfire.json | 4 +- data/mods/Magiclysm/items/alchemy_items.json | 6 +- data/mods/Magiclysm/items/archery.json | 2 +- .../Magiclysm/items/black_dragon_items.json | 89 ++++++------- data/mods/Magiclysm/items/enchanted.json | 12 +- .../mods/Magiclysm/items/enchanted_belts.json | 29 ++-- .../mods/Magiclysm/items/enchanted_boots.json | 20 +-- .../Magiclysm/items/enchanted_bracers.json | 7 +- .../Magiclysm/items/enchanted_cloaks.json | 18 +-- .../mods/Magiclysm/items/enchanted_masks.json | 12 +- .../Magiclysm/items/enchanted_ranged.json | 2 +- .../mods/Magiclysm/items/enchanted_rings.json | 20 ++- data/mods/Magiclysm/items/ethereal_items.json | 124 ++++++++++-------- 14 files changed, 167 insertions(+), 190 deletions(-) diff --git a/data/mods/Magiclysm/Spells/attunements/Force_Mage.json b/data/mods/Magiclysm/Spells/attunements/Force_Mage.json index 46d25875e1788..3e82de7e33d6c 100644 --- a/data/mods/Magiclysm/Spells/attunements/Force_Mage.json +++ b/data/mods/Magiclysm/Spells/attunements/Force_Mage.json @@ -34,9 +34,6 @@ "to_hit": -10, "symbol": "[", "color": "brown", - "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ], - "coverage": 100, - "encumbrance": 0, "environmental_protection": 2, "relic_data": { "passive_effects": [ @@ -52,7 +49,14 @@ } ] }, - "flags": [ "WATERPROOF", "TRADER_AVOID", "SEMITANGIBLE", "ONLY_ONE", "OVERSIZE", "AURA" ] + "flags": [ "WATERPROOF", "TRADER_AVOID", "SEMITANGIBLE", "ONLY_ONE", "OVERSIZE", "AURA" ], + "armor": [ + { + "encumbrance": 0, + "coverage": 100, + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ] + } + ] }, { "id": "force_magical_armor", diff --git a/data/mods/Magiclysm/enchantments/Soulfire.json b/data/mods/Magiclysm/enchantments/Soulfire.json index 16ecdb83a9bd5..8b22743d59056 100644 --- a/data/mods/Magiclysm/enchantments/Soulfire.json +++ b/data/mods/Magiclysm/enchantments/Soulfire.json @@ -32,10 +32,10 @@ "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "MAX_HP", "multiply": -0.4 } ] } ] }, - "covers": [ "torso" ], "symbol": "~", "color": "red", "weight": "1 g", - "volume": "1 ml" + "volume": "1 ml", + "armor": [ { "covers": [ "torso" ] } ] } ] diff --git a/data/mods/Magiclysm/items/alchemy_items.json b/data/mods/Magiclysm/items/alchemy_items.json index e3c3a17f1e0b9..57b53300bcd33 100644 --- a/data/mods/Magiclysm/items/alchemy_items.json +++ b/data/mods/Magiclysm/items/alchemy_items.json @@ -61,13 +61,11 @@ "material": [ "copper", "wood" ], "symbol": "[", "color": "brown", - "covers": [ "head" ], - "coverage": 5, - "encumbrance": 1, "warmth": 0, "material_thickness": 1, "flags": [ "BELTED" ], - "qualities": [ [ "MANA_FOCUS", 1 ] ] + "qualities": [ [ "MANA_FOCUS", 1 ] ], + "armor": [ { "encumbrance": 1, "coverage": 5, "covers": [ "head" ] } ] }, { "id": "potion_starter", diff --git a/data/mods/Magiclysm/items/archery.json b/data/mods/Magiclysm/items/archery.json index 35c9a6ef06756..ee336b12d1011 100644 --- a/data/mods/Magiclysm/items/archery.json +++ b/data/mods/Magiclysm/items/archery.json @@ -26,7 +26,7 @@ "weight": "740 g", "volume": "5 L", "bashing": 14, - "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 14 }, + "armor_data": { "material_thickness": 1, "armor": [ { "encumbrance": 14, "coverage": 5, "covers": [ "torso" ] } ] }, "reload_noise_volume": 2, "loudness": 5, "ranged_damage": { "damage_type": "stab", "amount": 15 }, diff --git a/data/mods/Magiclysm/items/black_dragon_items.json b/data/mods/Magiclysm/items/black_dragon_items.json index 4d6c9c33439dd..151d3f8847c01 100644 --- a/data/mods/Magiclysm/items/black_dragon_items.json +++ b/data/mods/Magiclysm/items/black_dragon_items.json @@ -104,13 +104,11 @@ "material": [ "black_dragon_hide", "black_dragon_scales" ], "symbol": "[", "color": "black_white", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 30, "warmth": 25, "material_thickness": 5, "environmental_protection": 3, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 30, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "boots_black_dragon_hide", @@ -126,13 +124,11 @@ "material": [ "black_dragon_hide" ], "symbol": "[", "color": "black_white", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 20, "warmth": 20, "material_thickness": 3, "environmental_protection": 3, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "helmet_black_dragon_scale", @@ -186,14 +182,12 @@ "material": [ "black_dragon_hide" ], "symbol": "[", "color": "black_white", - "covers": [ "head" ], - "coverage": 100, - "encumbrance": 20, "warmth": 15, "material_thickness": 3, "environmental_protection": 1, "techniques": [ "WBLOCK_1" ], - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 100, "covers": [ "head" ] } ] }, { "id": "suit_black_dragon_scale", @@ -209,13 +203,11 @@ "material": [ "black_dragon_hide", "black_dragon_scales" ], "symbol": "[", "color": "black_white", - "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], - "coverage": 100, - "encumbrance": 25, "warmth": 25, "material_thickness": 5, "environmental_protection": 3, - "flags": [ "VARSIZE", "WATERPROOF", "RAINPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "RAINPROOF", "STURDY" ], + "armor": [ { "encumbrance": 25, "coverage": 100, "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ] } ] }, { "id": "suit_black_dragon_hide", @@ -231,13 +223,11 @@ "material": [ "black_dragon_hide" ], "symbol": "[", "color": "black_white", - "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], - "coverage": 100, - "encumbrance": 18, "warmth": 15, "material_thickness": 3, "environmental_protection": 2, - "flags": [ "VARSIZE", "WATERPROOF", "RAINPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "RAINPROOF", "STURDY" ], + "armor": [ { "encumbrance": 18, "coverage": 100, "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ] } ] }, { "id": "gauntlets_black_dragon_scale", @@ -252,13 +242,11 @@ "material": [ "black_dragon_hide", "black_dragon_scales" ], "symbol": "[", "color": "black_white", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 20, "warmth": 20, "material_thickness": 4, "environmental_protection": 3, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_black_dragon_hide", @@ -273,13 +261,11 @@ "material": [ "black_dragon_hide" ], "symbol": "[", "color": "black_white", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 8, "warmth": 13, "material_thickness": 2, "environmental_protection": 1, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 8, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "boots_xlblack_dragon_scale", @@ -289,8 +275,8 @@ "description": "Massive boots made of incredibly durable black dragonscale, modified to fit even the strangest of bodies. Very protective, and surprisingly light.", "weight": "1545 g", "volume": "6250 ml", - "encumbrance": 40, - "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 40, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "boots_xlblack_dragon_hide", @@ -300,8 +286,8 @@ "description": "Massive boots made of very durable black dragonhide, modified to fit even the strangest of bodies. Very protective, and surprisingly light.", "weight": "955 g", "volume": "6250 ml", - "encumbrance": 25, - "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 25, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "gauntlets_xlblack_dragon_scale", @@ -311,8 +297,8 @@ "description": "A pair of heavy-duty gauntlets made of incredibly durable black dragonscale that covers your hands, or whatever you use as hands.", "weight": "680 g", "volume": "2 L", - "encumbrance": 30, - "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 30, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_xlblack_dragon_hide", @@ -322,8 +308,8 @@ "description": "A pair of gloves made of very durable black dragonhide, modified to be easy to wear while providing maximum protection under extreme conditions. Sized to fit even the strangest of anatomy.", "weight": "430 g", "volume": "1500 ml", - "encumbrance": 18, - "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 18, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "helmet_xlblack_dragon_scale", @@ -334,7 +320,10 @@ "use_action": { "type": "transform", "target": "helmet_xlblack_dragon_scale_raised", "msg": "You raise your visor." }, "weight": "1256 g", "volume": "4500 ml", - "armor": [ { "covers": [ "head" ], "coverage": 100, "encumbrance": 42 } ], + "armor": [ + { "covers": [ "head" ], "coverage": 100, "encumbrance": 42 }, + { "covers": [ "eyes", "mouth" ], "coverage": 100, "encumbrance": 20 } + ], "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY", "SUN_GLASSES" ] }, { @@ -357,19 +346,19 @@ "description": "A massive helmet made from very durable black dragonhide. It protects your head well, and doesn't cover your face, but is large enough to fit even the strangest of heads.", "weight": "815 g", "volume": "4500 ml", - "encumbrance": 26, - "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 26, "coverage": 100, "covers": [ "head" ] } ] }, { "id": "suit_xlblack_dragon_scale", - "copy-from": "suit_black_dragon_scale", + "copy-from": "3uit_black_dragon_scale", "type": "ARMOR", "name": { "str": "XL black dragonscale armor" }, "description": "A massive full suit of incredibly durable black dragon scale mail. It comes with all the accoutrements that cover your torso, legs, and arms; sized to fit even the strangest of bodies.", "weight": "6250 g", "volume": "18 L", - "encumbrance": 35, - "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "RAINPROOF", "STURDY" ] + "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "RAINPROOF", "STURDY" ], + "armor": [ { "encumbrance": 35, "coverage": 100, "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ] } ] }, { "id": "suit_xlblack_dragon_hide", @@ -379,8 +368,8 @@ "description": "A massive full suit of very durable black dragonhide armor. It comes with all the accoutrements that cover your torso, legs, and arms; sized to fit even the strangest of bodies.", "weight": "5500 g", "volume": "18 L", - "encumbrance": 26, - "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "RAINPROOF", "STURDY" ] + "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "RAINPROOF", "STURDY" ], + "armor": [ { "encumbrance": 26, "coverage": 100, "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ] } ] }, { "id": "backpack_black_dragon_hide", @@ -396,10 +385,6 @@ "symbol": "[", "looks_like": "backpack", "color": "black", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 5, - "max_encumbrance": 30, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -413,7 +398,8 @@ "warmth": 8, "material_thickness": 3, "environmental_protection": 3, - "flags": [ "WATER_FRIENDLY", "STURDY", "BELTED", "WATERPROOF" ] + "flags": [ "WATER_FRIENDLY", "STURDY", "BELTED", "WATERPROOF" ], + "armor": [ { "encumbrance": [ 5, 30 ], "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "backpack_xl_black_dragon_hide", @@ -425,8 +411,6 @@ "price": 280000, "price_postapoc": 3450, "symbol": "[", - "encumbrance": 8, - "max_encumbrance": 40, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -440,6 +424,7 @@ "warmth": 9, "material_thickness": 4, "environmental_protection": 3, - "extend": { "flags": [ "OVERSIZE" ] } + "extend": { "flags": [ "OVERSIZE" ] }, + "armor": [ { "encumbrance": [ 8, 40 ], "coverage": 40, "covers": [ "torso" ] } ] } ] diff --git a/data/mods/Magiclysm/items/enchanted.json b/data/mods/Magiclysm/items/enchanted.json index a8cf279b6c59a..aa024b3dd172e 100644 --- a/data/mods/Magiclysm/items/enchanted.json +++ b/data/mods/Magiclysm/items/enchanted.json @@ -92,16 +92,14 @@ "material": [ "cotton" ], "symbol": "^", "color": "light_blue", - "covers": [ "head" ], - "coverage": 50, - "encumbrance": 12, "warmth": 7, "material_thickness": 2, "environmental_protection": 2, "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "MAX_MANA", "multiply": 0.2, "add": 500 } ] } ] }, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 12, "coverage": 50, "covers": [ "head" ] } ] }, { "id": "debug_fireball_hammer", @@ -131,13 +129,11 @@ "material": [ "black_dragon_hide" ], "symbol": "[", "color": "dark_gray", - "covers": [ "torso", "head", "arm_l", "arm_r", "leg_l", "leg_r" ], - "coverage": 85, - "encumbrance": 4, "warmth": 30, "material_thickness": 3, "flags": [ "OVERSIZE", "HOOD", "OUTER", "NO_REPAIR", "SUPER_FANCY", "STURDY", "TRADER_KEEP_EQUIPPED" ], - "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "BONUS_DODGE", "add": 1 } ] } ] } + "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "BONUS_DODGE", "add": 1 } ] } ] }, + "armor": [ { "encumbrance": 4, "coverage": 85, "covers": [ "torso", "head", "arm_l", "arm_r", "leg_l", "leg_r" ] } ] }, { "id": "wolfshead_cufflinks", diff --git a/data/mods/Magiclysm/items/enchanted_belts.json b/data/mods/Magiclysm/items/enchanted_belts.json index 9c2628ab984d4..8ccf537cbbeac 100644 --- a/data/mods/Magiclysm/items/enchanted_belts.json +++ b/data/mods/Magiclysm/items/enchanted_belts.json @@ -11,14 +11,13 @@ "material": [ "leather" ], "symbol": "[", "color": "brown", - "covers": [ "torso" ], - "coverage": 5, "material_thickness": 2, "pocket_data": [ { "max_contains_volume": "500 ml", "max_contains_weight": "400 g", "moves": 60, "flag_restriction": [ "BELT_CLIP" ] } ], "use_action": { "type": "holster", "holster_prompt": "Stick what into your belt", "holster_msg": "You tuck your %s into your %s" }, - "flags": [ "WAIST", "WATER_FRIENDLY", "STURDY" ] + "flags": [ "WAIST", "WATER_FRIENDLY", "STURDY" ], + "armor": [ { "coverage": 5, "covers": [ "torso" ] } ] }, { "type": "TOOL_ARMOR", @@ -50,9 +49,6 @@ "id": "mbelt_pockets_lesser", "name": { "str": "lesser dimensional toolbelt" }, "description": "A sturdy workman's belt that fits around your waist, covered in easy to access pouches. Like all dimensional spaces, they hold more than they should with a fair weight reduction.", - "coverage": 10, - "encumbrance": 4, - "max_encumbrance": 10, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -90,7 +86,8 @@ "weight_multiplier": 0.5, "volume_multiplier": 0.35 } - ] + ], + "armor": [ { "encumbrance": [ 4, 10 ], "coverage": 10, "covers": [ "torso" ] } ] }, { "type": "TOOL_ARMOR", @@ -98,9 +95,6 @@ "id": "mbelt_pockets_greater", "name": { "str": "greater dimensional toolbelt" }, "description": "A heavy duty workman's belt that fits around your waist, covered in easy to access pouches. Like all dimensional spaces, they hold far more than they should with a substantial weight reduction.", - "coverage": 10, - "encumbrance": 6, - "max_encumbrance": 8, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -138,7 +132,8 @@ "weight_multiplier": 0.3, "volume_multiplier": 0.2 } - ] + ], + "armor": [ { "encumbrance": [ 6, 8 ], "coverage": 10, "covers": [ "torso" ] } ] }, { "type": "TOOL_ARMOR", @@ -146,9 +141,6 @@ "id": "mbelt_weaponry", "name": { "str": "Belt of Weaponry", "str_pl": "Belts of Weaponry" }, "description": "A wide girdle that fits around your waist, you can sheath or holster any weapon into it in the blink of an eye, and it seemingly stores them somewhere else.", - "coverage": 10, - "encumbrance": 3, - "max_encumbrance": 3, "pocket_data": [ { "holster": true, @@ -183,7 +175,8 @@ "weight_multiplier": 0.0 } ], - "use_action": { "type": "holster", "holster_prompt": "Stick what into your belt", "holster_msg": "You tuck your %s into your %s" } + "use_action": { "type": "holster", "holster_prompt": "Stick what into your belt", "holster_msg": "You tuck your %s into your %s" }, + "armor": [ { "encumbrance": [ 3, 3 ], "coverage": 10, "covers": [ "torso" ] } ] }, { "type": "ARMOR", @@ -191,7 +184,6 @@ "name": { "str": "technomancer's toolbelt" }, "weight": "2000 g", "color": "brown", - "covers": [ "torso" ], "pocket_data": [ { "pocket_type": "CONTAINER", @@ -208,8 +200,6 @@ "material": [ "leather", "steel" ], "volume": "4 L", "flags": [ "VARSIZE", "WATER_FRIENDLY", "STURDY", "WAIST", "OVERSIZE" ], - "coverage": 10, - "encumbrance": 4, "material_thickness": 4, "use_action": [ { "type": "holster", "holster_prompt": "Sheath blade", "holster_msg": "You sheath your %s" }, "CROWBAR" ], "qualities": [ @@ -224,7 +214,8 @@ [ "SAW_M_FINE", 1 ], [ "WRENCH_FINE", 1 ], [ "SCREW_FINE", 1 ] - ] + ], + "armor": [ { "encumbrance": 4, "coverage": 10, "covers": [ "torso" ] } ] }, { "type": "TOOL_ARMOR", diff --git a/data/mods/Magiclysm/items/enchanted_boots.json b/data/mods/Magiclysm/items/enchanted_boots.json index d99ce8999b1dd..8e5a44bd91f2c 100644 --- a/data/mods/Magiclysm/items/enchanted_boots.json +++ b/data/mods/Magiclysm/items/enchanted_boots.json @@ -8,11 +8,11 @@ "price_postapoc": "750 USD", "description": "Rugged yet extremely comfortable and well fitting boots of worn leather and steel, they look like they've seen a lot of use and will likely see a lot more. They make your movement a lot less work.", "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "MOVE_COST", "add": -30 } ] } ] }, - "encumbrance": 8, "warmth": 30, "material_thickness": 3, "environmental_protection": 3, - "flags": [ "WATERPROOF", "STURDY" ] + "flags": [ "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 8, "coverage": 95, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "mboots_haste", @@ -28,11 +28,11 @@ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "SPEED", "add": 10 } ] } ] }, - "encumbrance": 8, "warmth": 30, "material_thickness": 3, "environmental_protection": 3, - "flags": [ "WATERPROOF", "STURDY" ] + "flags": [ "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 8, "coverage": 95, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "mboots_escape", @@ -46,11 +46,11 @@ "relic_data": { "charge_info": { "recharge_type": "periodic", "time": "24 h", "regenerate_ammo": true } }, "pocket_data": [ { "pocket_type": "MAGAZINE", "ammo_restriction": { "crystallized_mana": 1 } } ], "use_action": { "type": "cast_spell", "spell_id": "magus_escape", "no_fail": true, "level": 10, "need_worn": true }, - "encumbrance": 8, "warmth": 30, "material_thickness": 3, "environmental_protection": 3, - "flags": [ "WATERPROOF", "STURDY", "NO_UNLOAD", "NO_RELOAD" ] + "flags": [ "WATERPROOF", "STURDY", "NO_UNLOAD", "NO_RELOAD" ], + "armor": [ { "encumbrance": 8, "coverage": 95, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "mboots_freerunner", @@ -65,11 +65,11 @@ { "has": "WORN", "condition": "ALWAYS", "mutations": [ "PARKOUR" ], "values": [ { "value": "MOVE_COST", "add": -5 } ] } ] }, - "encumbrance": 8, "warmth": 15, "material_thickness": 3, "environmental_protection": 3, - "flags": [ "WATERPROOF", "STURDY" ] + "flags": [ "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 8, "coverage": 95, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "mboots_grounding", @@ -79,11 +79,11 @@ "looks_like": "boots_hiking", "price_postapoc": "350 USD", "description": "Rugged yet extremely comfortable and well fitting boots of leather with small engraved runes seemingly filled with rubber. When worn, you are immune to damage from electricity.", - "encumbrance": 8, "warmth": 30, "material_thickness": 3, "environmental_protection": 3, "flags": [ "WATERPROOF", "STURDY" ], - "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "ARMOR_ELEC", "add": -20 } ] } ] } + "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "ARMOR_ELEC", "add": -20 } ] } ] }, + "armor": [ { "encumbrance": 8, "coverage": 95, "covers": [ "foot_l", "foot_r" ] } ] } ] diff --git a/data/mods/Magiclysm/items/enchanted_bracers.json b/data/mods/Magiclysm/items/enchanted_bracers.json index c5353f4b9cbc1..49f1af91fcc8a 100644 --- a/data/mods/Magiclysm/items/enchanted_bracers.json +++ b/data/mods/Magiclysm/items/enchanted_bracers.json @@ -12,12 +12,10 @@ "material": [ "steel", "leather" ], "symbol": "[", "color": "light_gray", - "covers": [ "arm_l", "arm_r" ], - "coverage": 45, - "encumbrance": 10, "warmth": 10, "material_thickness": 5, - "flags": [ "BELTED", "STURDY", "BLOCK_WHILE_WORN", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "STURDY", "BLOCK_WHILE_WORN", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 10, "coverage": 45, "covers": [ "arm_l", "arm_r" ] } ] }, { "copy-from": "mbracer_steel_pair", @@ -26,7 +24,6 @@ "name": { "str": "steel bracer" }, "weight": "770 g", "volume": "1250 ml", - "covers": [ "arm_l", "arm_r" ], "sided": true }, { diff --git a/data/mods/Magiclysm/items/enchanted_cloaks.json b/data/mods/Magiclysm/items/enchanted_cloaks.json index 74e97f49b2f35..c7a0c4c0af853 100644 --- a/data/mods/Magiclysm/items/enchanted_cloaks.json +++ b/data/mods/Magiclysm/items/enchanted_cloaks.json @@ -17,11 +17,9 @@ "price": 100000, "symbol": "w", "color": "blue", - "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], - "coverage": 0, - "encumbrance": 0, "flags": [ "OUTER", "OVERSIZE", "NONCONDUCTIVE", "WATER_FRIENDLY", "RAINPROOF" ], - "relic_data": { "passive_effects": [ { "id": "ench_fishform" } ] } + "relic_data": { "passive_effects": [ { "id": "ench_fishform" } ] }, + "armor": [ { "encumbrance": 0, "coverage": 0, "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ] } ] }, { "id": "ench_bearform", @@ -55,11 +53,9 @@ "price": 200000, "symbol": "w", "color": "brown", - "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], - "coverage": 0, - "encumbrance": 0, "flags": [ "OUTER", "OVERSIZE", "NONCONDUCTIVE", "WATER_FRIENDLY", "RAINPROOF" ], - "relic_data": { "passive_effects": [ { "id": "ench_bearform" } ] } + "relic_data": { "passive_effects": [ { "id": "ench_bearform" } ] }, + "armor": [ { "encumbrance": 0, "coverage": 0, "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ] } ] }, { "id": "ench_deerform", @@ -91,10 +87,8 @@ "price": 150000, "symbol": "w", "color": "green", - "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], - "coverage": 0, - "encumbrance": 0, "flags": [ "OUTER", "OVERSIZE", "NONCONDUCTIVE", "WATER_FRIENDLY", "RAINPROOF" ], - "relic_data": { "passive_effects": [ { "id": "ench_deerform" } ] } + "relic_data": { "passive_effects": [ { "id": "ench_deerform" } ] }, + "armor": [ { "encumbrance": 0, "coverage": 0, "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ] } ] } ] diff --git a/data/mods/Magiclysm/items/enchanted_masks.json b/data/mods/Magiclysm/items/enchanted_masks.json index e65e38e377bf7..82fe2de62d8b1 100644 --- a/data/mods/Magiclysm/items/enchanted_masks.json +++ b/data/mods/Magiclysm/items/enchanted_masks.json @@ -12,13 +12,11 @@ "material": [ "steel", "leather" ], "symbol": "[", "color": "dark_gray", - "covers": [ "eyes", "mouth" ], - "coverage": 95, - "encumbrance": 10, "warmth": 10, "material_thickness": 2, "environmental_protection": 1, - "flags": [ "WATER_FRIENDLY", "STURDY" ] + "flags": [ "WATER_FRIENDLY", "STURDY" ], + "armor": [ { "encumbrance": 10, "coverage": 95, "covers": [ "eyes", "mouth" ] } ] }, { "type": "TOOL_ARMOR", @@ -38,14 +36,12 @@ "name": { "str": "mask of perfect vision", "str_pl": "masks of perfect vision" }, "description": "A decidedly steampunk-looking half mask that covers the eye area of the face, it has large lenses that correct and greatly enhance the vision of the wearer.", "copy-from": "mmask", - "covers": [ "eyes" ], - "coverage": 100, - "encumbrance": 5, "environmental_protection": 6, "flags": [ "FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_NEARSIGHT", "FIX_FARSIGHT", "ZOOM" ], "qualities": [ [ "GLARE", 2 ] ], "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "PERCEPTION", "multiply": 0.25 } ] } ] - } + }, + "armor": [ { "encumbrance": 5, "coverage": 100, "covers": [ "eyes" ] } ] } ] diff --git a/data/mods/Magiclysm/items/enchanted_ranged.json b/data/mods/Magiclysm/items/enchanted_ranged.json index 21ec01c9a39ce..4fb94e65dff40 100644 --- a/data/mods/Magiclysm/items/enchanted_ranged.json +++ b/data/mods/Magiclysm/items/enchanted_ranged.json @@ -22,7 +22,7 @@ "SHEATH_BOW" ], "min_strength": 9, - "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 13 }, + "armor_data": { "material_thickness": 1, "armor": [ { "encumbrance": 13, "coverage": 5, "covers": [ "torso" ] } ] }, "valid_mod_locations": [ [ "sights", 1 ], [ "accessories", 1 ], [ "dampening", 1 ] ], "ranged_damage": { "damage_type": "stab", "amount": 9 }, "range": 13, diff --git a/data/mods/Magiclysm/items/enchanted_rings.json b/data/mods/Magiclysm/items/enchanted_rings.json index cd0bd583d432b..dce8b1f5c88c4 100644 --- a/data/mods/Magiclysm/items/enchanted_rings.json +++ b/data/mods/Magiclysm/items/enchanted_rings.json @@ -11,11 +11,10 @@ "material": [ "copper" ], "symbol": "[", "color": "light_red", - "covers": [ "hand_l", "hand_r" ], "sided": true, - "coverage": 0, "warmth": 0, - "flags": [ "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS", "FANCY", "ONE_PER_LAYER", "SKINTIGHT" ] + "flags": [ "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS", "FANCY", "ONE_PER_LAYER", "SKINTIGHT" ], + "armor": [ { "coverage": 0, "covers": [ "hand_l", "hand_r" ] } ] }, { "abstract": "mring_silver", @@ -29,11 +28,10 @@ "material": [ "silver" ], "symbol": "[", "color": "light_gray", - "covers": [ "hand_l", "hand_r" ], "sided": true, - "coverage": 0, "warmth": 0, - "flags": [ "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS", "FANCY", "ONE_PER_LAYER", "SKINTIGHT" ] + "flags": [ "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS", "FANCY", "ONE_PER_LAYER", "SKINTIGHT" ], + "armor": [ { "coverage": 0, "covers": [ "hand_l", "hand_r" ] } ] }, { "abstract": "mring_gold", @@ -47,11 +45,10 @@ "material": [ "gold" ], "symbol": "[", "color": "yellow", - "covers": [ "hand_l", "hand_r" ], "sided": true, - "coverage": 0, "warmth": 0, - "flags": [ "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS", "FANCY", "ONE_PER_LAYER", "SKINTIGHT" ] + "flags": [ "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS", "FANCY", "ONE_PER_LAYER", "SKINTIGHT" ], + "armor": [ { "coverage": 0, "covers": [ "hand_l", "hand_r" ] } ] }, { "abstract": "mring_platinum", @@ -65,11 +62,10 @@ "material": [ "platinum" ], "symbol": "[", "color": "light_gray", - "covers": [ "hand_l", "hand_r" ], "sided": true, - "coverage": 0, "warmth": 0, - "flags": [ "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS", "FANCY", "ONE_PER_LAYER", "SKINTIGHT" ] + "flags": [ "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS", "FANCY", "ONE_PER_LAYER", "SKINTIGHT" ], + "armor": [ { "coverage": 0, "covers": [ "hand_l", "hand_r" ] } ] }, { "copy-from": "mring_copper", diff --git a/data/mods/Magiclysm/items/ethereal_items.json b/data/mods/Magiclysm/items/ethereal_items.json index 3f8e466fdaa56..774ac5c6cab3f 100644 --- a/data/mods/Magiclysm/items/ethereal_items.json +++ b/data/mods/Magiclysm/items/ethereal_items.json @@ -13,12 +13,10 @@ "symbol": "[", "color": "light_gray", "armor_data": { - "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 0, "warmth": 20, "material_thickness": 4, - "environmental_protection": 10 + "environmental_protection": 10, + "armor": [ { "encumbrance": 0, "coverage": 100, "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ] } ] }, "qualities": [ [ "HAMMER", 1 ] ], "flags": [ "VARSIZE", "STURDY", "UNARMED_WEAPON", "DURABLE_MELEE", "NONCONDUCTIVE", "MAGIC_FOCUS" ], @@ -51,15 +49,13 @@ "material": [ "superalloy" ], "symbol": "[", "color": "light_gray", - "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 0, "warmth": 20, "material_thickness": 4, "environmental_protection": 10, "qualities": [ [ "HAMMER", 1 ] ], "flags": [ "VARSIZE", "STURDY", "UNARMED_WEAPON", "DURABLE_MELEE", "NONCONDUCTIVE", "MAGIC_FOCUS" ], - "techniques": [ "WBLOCK_3" ] + "techniques": [ "WBLOCK_3" ], + "armor": [ { "encumbrance": 0, "coverage": 100, "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ] } ] }, { "id": "magic_lamp", @@ -74,8 +70,8 @@ "bashing": 8, "symbol": ",", "color": "light_green", - "covers": [ "head" ], - "flags": [ "LIGHT_300", "AURA", "SEMITANGIBLE" ] + "flags": [ "LIGHT_300", "AURA", "SEMITANGIBLE" ], + "armor": [ { "covers": [ "head" ] } ] }, { "id": "magic_light", @@ -88,8 +84,8 @@ "price": 0, "symbol": ",", "color": "light_green", - "covers": [ "head" ], - "flags": [ "LIGHT_8", "AURA", "SEMITANGIBLE" ] + "flags": [ "LIGHT_8", "AURA", "SEMITANGIBLE" ], + "armor": [ { "covers": [ "head" ] } ] }, { "id": "shield_ice", @@ -105,13 +101,11 @@ "material": [ "steel" ], "symbol": "[", "color": "light_gray", - "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], "sided": true, - "coverage": 70, - "encumbrance": 15, "material_thickness": 3, "techniques": [ "WBLOCK_3" ], - "flags": [ "OVERSIZE", "BELTED", "RESTRICT_HANDS", "BLOCK_WHILE_WORN" ] + "flags": [ "OVERSIZE", "BELTED", "RESTRICT_HANDS", "BLOCK_WHILE_WORN" ], + "armor": [ { "encumbrance": 15, "coverage": 70, "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ] } ] }, { "id": "ice_gliders", @@ -126,14 +120,12 @@ "material": [ "steel" ], "symbol": "[", "color": "brown", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 0, "warmth": 30, "material_thickness": 3, "environmental_protection": 2, "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "MOVE_COST", "add": -5 } ] } ] }, - "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "ROLLER_QUAD", "BELTED" ] + "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "ROLLER_QUAD", "BELTED" ], + "armor": [ { "encumbrance": 0, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "type": "GENERIC", @@ -276,13 +268,10 @@ "material": [ "flesh" ], "symbol": "[", "color": "green", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 5, - "max_encumbrance": 10, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "25 L", "max_contains_weight": "75 kg", "moves": 60 } ], "material_thickness": 3, - "flags": [ "BELTED", "TRADER_AVOID", "WATERPROOF", "STURDY", "NO_UNWIELD", "ONLY_ONE", "NO_REPAIR", "NO_SALVAGE" ] + "flags": [ "BELTED", "TRADER_AVOID", "WATERPROOF", "STURDY", "NO_UNWIELD", "ONLY_ONE", "NO_REPAIR", "NO_SALVAGE" ], + "armor": [ { "encumbrance": [ 5, 10 ], "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "bonespear", @@ -406,9 +395,13 @@ "price": 3646, "symbol": "o", "color": "white", - "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ], "flags": [ "AURA", "SEMITANGIBLE", "OVERSIZE", "ONLY_ONE", "TRADER_AVOID", "NO_TAKEOFF", "NONCONDUCTIVE" ], - "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "BONUS_DODGE", "add": 2 } ] } ] } + "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "BONUS_DODGE", "add": 2 } ] } ] }, + "armor": [ + { + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ] + } + ] }, { "id": "acid_res_aura", @@ -420,11 +413,15 @@ "price": 3646, "symbol": "o", "color": "green", - "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ], "flags": [ "AURA", "SEMITANGIBLE", "OVERSIZE", "ONLY_ONE", "TRADER_AVOID", "NO_TAKEOFF", "NONCONDUCTIVE" ], "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "ARMOR_ACID", "multiply": -0.25 } ] } ] - } + }, + "armor": [ + { + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ] + } + ] }, { "id": "acid_res_aura_greater", @@ -436,11 +433,15 @@ "price": 3646, "symbol": "o", "color": "green", - "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ], "flags": [ "AURA", "SEMITANGIBLE", "OVERSIZE", "ONLY_ONE", "TRADER_AVOID", "NO_TAKEOFF", "NONCONDUCTIVE" ], "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "ARMOR_ACID", "multiply": -0.6 } ] } ] - } + }, + "armor": [ + { + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ] + } + ] }, { "id": "armor_frost", @@ -453,13 +454,17 @@ "material": [ "steel" ], "symbol": "[", "color": "light_gray", - "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 10, "warmth": 0, "material_thickness": 2, "environmental_protection": 2, - "flags": [ "ONLY_ONE", "OVERSIZE", "PERSONAL", "STURDY" ] + "flags": [ "ONLY_ONE", "OVERSIZE", "PERSONAL", "STURDY" ], + "armor": [ + { + "encumbrance": 10, + "coverage": 100, + "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "aura_stoneskin", @@ -472,13 +477,17 @@ "material": [ "stone" ], "symbol": "[", "color": "light_gray", - "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 20, "warmth": 5, "material_thickness": 2, "environmental_protection": 2, - "flags": [ "ONLY_ONE", "OVERSIZE", "PERSONAL", "STURDY" ] + "flags": [ "ONLY_ONE", "OVERSIZE", "PERSONAL", "STURDY" ], + "armor": [ + { + "encumbrance": 20, + "coverage": 100, + "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "burn_scar", @@ -502,10 +511,9 @@ "volume": "1 ml", "symbol": "~", "color": "light_red", - "covers": [ "eyes", "mouth" ], - "encumbrance": 18, "relic_data": { "passive_effects": [ { "id": "ench_overcharge_burn_scar" } ] }, - "flags": [ "NO_TAKEOFF", "TRADER_AVOID", "BLIND" ] + "flags": [ "NO_TAKEOFF", "TRADER_AVOID", "BLIND" ], + "armor": [ { "encumbrance": 18, "covers": [ "eyes", "mouth" ] } ] }, { "id": "protect_env", @@ -517,8 +525,12 @@ "symbol": "o", "color": "blue", "environmental_protection": 15, - "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ], - "flags": [ "AURA", "SEMITANGIBLE", "OVERSIZE", "ONLY_ONE", "TRADER_AVOID", "NO_TAKEOFF", "NONCONDUCTIVE" ] + "flags": [ "AURA", "SEMITANGIBLE", "OVERSIZE", "ONLY_ONE", "TRADER_AVOID", "NO_TAKEOFF", "NONCONDUCTIVE" ], + "armor": [ + { + "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ] + } + ] }, { "id": "thorns_electric", @@ -727,11 +739,8 @@ "weight": "1 g", "volume": "1 ml", "material": [ "steel" ], - "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "symbol": "o", "color": "green", - "coverage": 100, - "encumbrance": 0, "warmth": 0, "material_thickness": 2, "environmental_protection": 2, @@ -744,7 +753,14 @@ "hit_me_effect": [ { "id": "dragon_shell_retaliation_black", "hit_self": false } ] } ] - } + }, + "armor": [ + { + "encumbrance": 0, + "coverage": 100, + "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "subzero_talons", @@ -784,12 +800,16 @@ "description": "A summoned medieval armor. It glows softly and looks sturdy.", "material": [ "superalloy" ], "//": "I added a helmet to the summon", - "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 5, "warmth": 0, "material_thickness": 4, - "flags": [ "ONLY_ONE", "OVERSIZE", "PERSONAL", "VARSIZE", "STURDY", "NO_REPAIR", "NO_SALVAGE", "LIGHT_2", "TRADER_AVOID" ] + "flags": [ "ONLY_ONE", "OVERSIZE", "PERSONAL", "VARSIZE", "STURDY", "NO_REPAIR", "NO_SALVAGE", "LIGHT_2", "TRADER_AVOID" ], + "armor": [ + { + "encumbrance": 5, + "coverage": 100, + "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "jar_3l_force", From 1750a87962b0b678ec26c032312bd61933ef3bf4 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Tue, 6 Jul 2021 18:46:06 -0700 Subject: [PATCH 022/116] Convert armor to use armor_portion_data (DSA) I want to make changes to how armor data is specified, and I don't want to maintain two separate interfaces for it, so let's convert existing data to one interface. Items using copy-from were audited, and where they made changes, data was respecified as at the moment, copy-from modifying sub-elements of armor portion data is incorrect (there are lots of questions with no good answers there). --- data/mods/Dark-Skies-Above/obsolete.json | 25 ++++++++++++------------ 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/data/mods/Dark-Skies-Above/obsolete.json b/data/mods/Dark-Skies-Above/obsolete.json index d9fd020b4da5b..b30c457cd2b1d 100644 --- a/data/mods/Dark-Skies-Above/obsolete.json +++ b/data/mods/Dark-Skies-Above/obsolete.json @@ -57,10 +57,6 @@ "symbol": "[", "looks_like": "power_armor", "color": "light_gray", - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r", "head" ], - "coverage": 95, - "encumbrance": 24, - "max_encumbrance": 40, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "2 L", "max_contains_weight": "4 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "2 L", "max_contains_weight": "4 kg", "moves": 80 } @@ -68,7 +64,14 @@ "warmth": 50, "material_thickness": 4, "environmental_protection": 6, - "flags": [ "WATERPROOF", "STURDY" ] + "flags": [ "WATERPROOF", "STURDY" ], + "armor": [ + { + "encumbrance": [ 24, 40 ], + "coverage": 95, + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r", "head" ] + } + ] }, { "id": "dks_riotshield", @@ -83,13 +86,11 @@ "material": [ "plastic" ], "symbol": "[", "color": "dark_gray", - "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], "sided": true, - "coverage": 85, - "encumbrance": 16, "material_thickness": 3, "techniques": [ "WBLOCK_2" ], - "flags": [ "OVERSIZE", "BELTED", "RESTRICT_HANDS", "BLOCK_WHILE_WORN" ] + "flags": [ "OVERSIZE", "BELTED", "RESTRICT_HANDS", "BLOCK_WHILE_WORN" ], + "armor": [ { "encumbrance": 16, "coverage": 85, "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ] } ] }, { "id": "dks_battleshield", @@ -104,12 +105,10 @@ "material": [ "steel" ], "symbol": "[", "color": "dark_gray", - "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], "sided": true, - "coverage": 90, - "encumbrance": 20, "material_thickness": 3, "techniques": [ "WBLOCK_3" ], - "flags": [ "OVERSIZE", "BELTED", "RESTRICT_HANDS", "BLOCK_WHILE_WORN" ] + "flags": [ "OVERSIZE", "BELTED", "RESTRICT_HANDS", "BLOCK_WHILE_WORN" ], + "armor": [ { "encumbrance": 20, "coverage": 90, "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ] } ] } ] From 91fe054842200c4bf36369f593927441e45490e5 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Tue, 6 Jul 2021 18:46:38 -0700 Subject: [PATCH 023/116] Convert armor to use armor_portion_data (tests) I want to make changes to how armor data is specified, and I don't want to maintain two separate interfaces for it, so let's convert existing data to one interface. Items using copy-from were audited, and where they made changes, data was respecified as at the moment, copy-from modifying sub-elements of armor portion data is incorrect (there are lots of questions with no good answers there). --- data/mods/TEST_DATA/items.json | 117 +++++++++++++++------------------ 1 file changed, 53 insertions(+), 64 deletions(-) diff --git a/data/mods/TEST_DATA/items.json b/data/mods/TEST_DATA/items.json index 82ea1d26f9bca..08620df87f192 100644 --- a/data/mods/TEST_DATA/items.json +++ b/data/mods/TEST_DATA/items.json @@ -30,14 +30,13 @@ "material": [ "copper" ], "symbol": "[", "color": "light_red", - "covers": [ "hand_l", "hand_r" ], "sided": true, - "coverage": 0, "warmth": 0, "flags": [ "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS", "FANCY", "ONLY_ONE", "SKINTIGHT" ], "name": { "str": "ring of strength +1", "str_pl": "rings of strength +1" }, "description": "A copper ring that makes you a little stronger when you wear it.", - "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "STRENGTH", "add": 1 } ] } ] } + "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "STRENGTH", "add": 1 } ] } ] }, + "armor": [ { "coverage": 0, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "test_rag", @@ -109,9 +108,6 @@ "symbol": "[", "looks_like": "holster", "color": "brown", - "covers": [ "torso" ], - "coverage": 20, - "encumbrance": 2, "material_thickness": 2, "pocket_data": [ { @@ -152,7 +148,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Store tool or blade", "holster_msg": "You put your %1$s in your %2$s" }, - "flags": [ "WAIST", "NO_QUICKDRAW", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "NO_QUICKDRAW", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 2, "coverage": 20, "covers": [ "torso" ] } ] }, { "id": "test_utility_belt", @@ -168,9 +165,6 @@ "symbol": "[", "looks_like": "holster", "color": "yellow", - "covers": [ "TORSO" ], - "coverage": 30, - "encumbrance": 5, "material_thickness": 4, "pocket_data": [ { @@ -239,7 +233,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Store tool or blade", "holster_msg": "You put your %1$s in your %2$s" }, - "flags": [ "WAIST", "NO_QUICKDRAW", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "NO_QUICKDRAW", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 5, "coverage": 30, "covers": [ "TORSO" ] } ] }, { "type": "GENERIC", @@ -490,11 +485,10 @@ "symbol": "[", "looks_like": "socks_wool", "color": "white", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, "warmth": 5, "material_thickness": 1, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "test_croc_socks", @@ -508,11 +502,10 @@ "symbol": "[", "looks_like": "socks_wool", "color": "green", - "covers": [ "foot_l", "foot_r" ], - "coverage": 50, "warmth": 2, "material_thickness": 1, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 50, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "test_longshirt", @@ -526,12 +519,10 @@ "symbol": "[", "looks_like": "dress_shirt", "color": "blue", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 90, - "encumbrance": 3, "warmth": 5, "material_thickness": 0.2, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 3, "coverage": 90, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "id": "test_ear_plugs", @@ -544,9 +535,9 @@ "material": [ "plastic" ], "symbol": ";", "color": "light_gray", - "coverage": 1, "material_thickness": 1, - "flags": [ "DEAF", "OVERSIZE", "POWERARMOR_COMPATIBLE" ] + "flags": [ "DEAF", "OVERSIZE", "POWERARMOR_COMPATIBLE" ], + "armor": [ { "coverage": 1 } ] }, { "id": "test_hazmat_suit", @@ -561,13 +552,17 @@ "symbol": "[", "looks_like": "beekeeping_suit", "color": "yellow", - "covers": [ "head", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 37, "warmth": 40, "material_thickness": 2, "environmental_protection": 20, - "flags": [ "VARSIZE", "WATERPROOF", "RAINPROOF", "GAS_PROOF", "RAD_PROOF", "ELECTRIC_IMMUNE", "OUTER" ] + "flags": [ "VARSIZE", "WATERPROOF", "RAINPROOF", "GAS_PROOF", "RAD_PROOF", "ELECTRIC_IMMUNE", "OUTER" ], + "armor": [ + { + "encumbrance": 37, + "coverage": 100, + "covers": [ "head", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "test_zentai", @@ -581,11 +576,15 @@ "material": [ "lycra" ], "symbol": "[", "color": "dark_gray", - "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, "warmth": 20, "material_thickness": 1, - "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ] + "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ], + "armor": [ + { + "coverage": 100, + "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "test_sunglasses", @@ -602,13 +601,11 @@ "symbol": "[", "looks_like": "glasses_eye", "color": "dark_gray", - "covers": [ "eyes" ], - "coverage": 85, - "encumbrance": 1, "material_thickness": 1, "environmental_protection": 1, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "WATER_FRIENDLY", "SUN_GLASSES", "FRAGILE" ] + "flags": [ "WATER_FRIENDLY", "SUN_GLASSES", "FRAGILE" ], + "armor": [ { "encumbrance": 1, "coverage": 85, "covers": [ "eyes" ] } ] }, { "id": "test_umbrella", @@ -808,7 +805,7 @@ "material": [ "leather" ], "symbol": ")", "color": "brown", - "armor_data": { "covers": [ "leg_l", "leg_r" ], "sided": true, "coverage": 5, "material_thickness": 2 }, + "armor_data": { "sided": true, "material_thickness": 2, "armor": [ { "coverage": 5, "covers": [ "leg_l", "leg_r" ] } ] }, "pocket_data": [ { "max_item_volume": "15 ml", @@ -887,14 +884,11 @@ "symbol": "[", "looks_like": "ragpouch", "color": "green", - "covers": [ "torso" ], - "coverage": 30, - "encumbrance": 2, - "max_encumbrance": 15, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "15 L", "max_contains_weight": "30 kg", "moves": 300 } ], "warmth": 6, "material_thickness": 2, - "flags": [ "BELTED" ] + "flags": [ "BELTED" ], + "armor": [ { "encumbrance": [ 2, 15 ], "coverage": 30, "covers": [ "torso" ] } ] }, { "id": "test_briefcase", @@ -911,10 +905,7 @@ "symbol": "[", "looks_like": "plastic_shopping_bag", "color": "light_gray", - "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], "sided": true, - "coverage": 10, - "encumbrance": 30, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -925,7 +916,8 @@ } ], "material_thickness": 2, - "flags": [ "FANCY", "OVERSIZE", "BELTED", "RESTRICT_HANDS", "WATER_FRIENDLY" ] + "flags": [ "FANCY", "OVERSIZE", "BELTED", "RESTRICT_HANDS", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 30, "coverage": 10, "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ] } ] }, { "id": "test_quiver", @@ -941,13 +933,11 @@ "symbol": "[", "looks_like": "bscabbard", "color": "brown", - "covers": [ "leg_l", "leg_r" ], "sided": true, - "coverage": 10, - "encumbrance": 3, "material_thickness": 1, "pocket_data": [ { "ammo_restriction": { "arrow": 20, "bolt": 20 }, "moves": 20 } ], - "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 3, "coverage": 10, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "test_arrow_wood", @@ -1432,9 +1422,6 @@ "symbol": "[", "looks_like": "depowered_armor", "color": "light_gray", - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 50, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1449,7 +1436,14 @@ "material_thickness": 14, "environmental_protection": 16, "use_action": { "type": "transform", "msg": "The %s engages.", "target": "test_power_armor_on", "active": true }, - "flags": [ "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE" ] + "flags": [ "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE" ], + "armor": [ + { + "encumbrance": 50, + "coverage": 100, + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "test_power_armor_on", @@ -1462,8 +1456,7 @@ "flags": [ "USE_UPS", "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE", "TRADER_AVOID", "CLIMATE_CONTROL" ], "power_draw": 4000000, "revert_to": "test_power_armor", - "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "The %s armor disengages.", "target": "test_power_armor" }, - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "The %s armor disengages.", "target": "test_power_armor" } }, { "id": "test_meower_armor", @@ -1579,10 +1572,6 @@ "symbol": "[", "looks_like": "pants", "color": "brown", - "covers": [ "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 16, - "max_encumbrance": 20, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "350 ml", "max_contains_weight": "1 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "350 ml", "max_contains_weight": "1 kg", "moves": 80 }, @@ -1593,7 +1582,8 @@ "material_thickness": 3, "valid_mods": [ "steel_padded" ], "environmental_protection": 3, - "flags": [ "VARSIZE", "POCKETS" ] + "flags": [ "VARSIZE", "POCKETS" ], + "armor": [ { "encumbrance": [ 16, 20 ], "coverage": 95, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "test_pants_faux_fur", @@ -1602,7 +1592,6 @@ "name": { "str_sp": "faux fur pants" }, "description": "A pair of long cotton pants lined with warm imitation fur.", "material": [ "faux_fur", "cotton" ], - "covers": [ "leg_l", "leg_r" ], "warmth": 70 }, { @@ -1665,7 +1654,7 @@ "sealed_data": { "spoil_multiplier": 0.0 } } ], - "armor_data": { "covers": [ "torso" ], "coverage": 10, "encumbrance": 4, "material_thickness": 2 }, + "armor_data": { "material_thickness": 2, "armor": [ { "encumbrance": 4, "coverage": 10, "covers": [ "torso" ] } ] }, "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] }, { @@ -1723,7 +1712,7 @@ "sealed_data": { "spoil_multiplier": 0.0 } } ], - "armor_data": { "covers": [ "torso" ], "coverage": 10, "encumbrance": 4, "material_thickness": 2 }, + "armor_data": { "material_thickness": 2, "armor": [ { "encumbrance": 4, "coverage": 10, "covers": [ "torso" ] } ] }, "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] }, { @@ -1760,7 +1749,7 @@ "item_restriction": [ "test_watertight_open_sealed_multipocket_container_2x250ml", "test_solid_1ml" ] } ], - "armor_data": { "covers": [ "torso" ], "coverage": 10, "encumbrance": 4, "material_thickness": 2 }, + "armor_data": { "material_thickness": 2, "armor": [ { "encumbrance": 4, "coverage": 10, "covers": [ "torso" ] } ] }, "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] }, { @@ -1784,7 +1773,7 @@ ] } ], - "armor_data": { "covers": [ "torso" ], "coverage": 10, "encumbrance": 4, "material_thickness": 2 }, + "armor_data": { "material_thickness": 2, "armor": [ { "encumbrance": 4, "coverage": 10, "covers": [ "torso" ] } ] }, "flags": [ "BELTED" ] }, { From bb39692db9613e158cee7ca474864a92ba322681 Mon Sep 17 00:00:00 2001 From: Hirmuolio <22011552+Hirmuolio@users.noreply.github.com> Date: Wed, 7 Jul 2021 04:47:21 +0300 Subject: [PATCH 024/116] Fix welding requirement on some recipes (#49538) * update old weld req --- data/json/construction.json | 18 +++++------ data/json/recipes/armor/other.json | 3 +- data/json/recipes/weapon/ranged.json | 31 +++++-------------- .../recipes/recipes_firearms_single.json | 25 +++++---------- 4 files changed, 24 insertions(+), 53 deletions(-) diff --git a/data/json/construction.json b/data/json/construction.json index 33f32023f2be8..567871dc77076 100644 --- a/data/json/construction.json +++ b/data/json/construction.json @@ -1127,7 +1127,7 @@ "category": "CONSTRUCT", "required_skills": [ [ "fabrication", 6 ] ], "time": "120 m", - "qualities": [ [ { "id": "WELD", "level": 2 } ], [ { "id": "GLARE", "level": 2 } ] ], + "using": [ [ "welding_standard", 2 ] ], "components": [ [ [ "rebar", 16 ] ] ], "pre_terrain": "t_pit", "post_terrain": "t_reb_cage" @@ -1168,7 +1168,7 @@ "category": "CONSTRUCT", "required_skills": [ [ "fabrication", 6 ] ], "time": "120 m", - "qualities": [ [ { "id": "WELD", "level": 2 } ], [ { "id": "GLARE", "level": 2 } ] ], + "using": [ [ "welding_standard", 2 ] ], "components": [ [ [ "rebar", 16 ] ] ], "pre_terrain": "t_pit", "post_terrain": "t_reb_cage" @@ -1223,7 +1223,7 @@ "category": "CONSTRUCT", "required_skills": [ [ "fabrication", 5 ] ], "time": "120 m", - "qualities": [ [ { "id": "WELD", "level": 2 } ], [ { "id": "GLARE", "level": 2 } ] ], + "using": [ [ "welding_standard", 2 ] ], "components": [ [ [ "rebar", 8 ] ], [ [ "2x4", 12 ] ], [ [ "pipe", 4 ] ] ], "pre_terrain": "t_pit_shallow", "post_terrain": "t_ov_smreb_cage" @@ -1250,7 +1250,7 @@ "category": "CONSTRUCT", "required_skills": [ [ "fabrication", 6 ] ], "time": "180 m", - "qualities": [ [ { "id": "WELD", "level": 2 } ], [ { "id": "GLARE", "level": 2 } ] ], + "using": [ [ "welding_standard", 2 ] ], "components": [ [ [ "rebar", 12 ] ], [ [ "2x4", 12 ] ], [ [ "pipe", 4 ] ] ], "pre_terrain": "t_pit", "post_terrain": "t_ov_reb_cage" @@ -2110,12 +2110,8 @@ "category": "FURN", "required_skills": [ [ "fabrication", 2 ], [ "cooking", 1 ] ], "time": "180 m", - "qualities": [ - [ { "id": "HAMMER", "level": 2 } ], - [ { "id": "SAW_M", "level": 1 } ], - [ { "id": "WELD", "level": 2 } ], - [ { "id": "GLARE", "level": 2 } ] - ], + "qualities": [ [ { "id": "HAMMER", "level": 2 } ], [ { "id": "SAW_M", "level": 1 } ] ], + "using": [ [ "welding_standard", 2 ] ], "components": [ [ [ "metal_tank", 4 ] ], [ [ "water_faucet", 1 ] ] ], "pre_special": "check_empty", "post_terrain": "f_standing_tank" @@ -3754,10 +3750,10 @@ "qualities": [ [ { "id": "HAMMER", "level": 2 } ], [ { "id": "SAW_M", "level": 1 } ], - [ { "id": "WELD", "level": 2 } ], [ { "id": "DRILL", "level": 3 } ], [ { "id": "WRENCH", "level": 2 } ] ], + "using": [ [ "welding_standard", 2 ] ], "components": [ [ [ "fire_brick", 40 ] ], [ [ "cu_pipe", 4 ] ], diff --git a/data/json/recipes/armor/other.json b/data/json/recipes/armor/other.json index 69218f4560f08..aa82eb974f15e 100644 --- a/data/json/recipes/armor/other.json +++ b/data/json/recipes/armor/other.json @@ -222,7 +222,8 @@ "difficulty": 4, "time": "60 m", "book_learn": [ [ "textbook_fabrication", 4 ], [ "welding_book", 4 ] ], - "qualities": [ { "id": "ANVIL", "level": 1 }, { "id": "WELD", "level": 1 }, { "id": "CUT", "level": 1 } ], + "qualities": [ { "id": "ANVIL", "level": 1 }, { "id": "CUT", "level": 1 } ], + "using": [ [ "welding_standard", 1 ] ], "proficiencies": [ { "proficiency": "prof_plasticworking" } ], "tools": [ [ [ "surface_heat", 5, "LIST" ] ] ], "components": [ [ [ "plastic_chunk", 20 ] ] ] diff --git a/data/json/recipes/weapon/ranged.json b/data/json/recipes/weapon/ranged.json index f397a6a7de41c..bd29efe9f1732 100644 --- a/data/json/recipes/weapon/ranged.json +++ b/data/json/recipes/weapon/ranged.json @@ -326,13 +326,8 @@ "difficulty": 1, "time": "4 h", "book_learn": [ [ "manual_shotgun", 1 ] ], - "qualities": [ - { "id": "SAW_M", "level": 1 }, - { "id": "GLARE", "level": 2 }, - { "id": "HAMMER", "level": 2 }, - { "id": "FILE", "level": 1 }, - { "id": "WELD", "level": 1 } - ], + "qualities": [ { "id": "SAW_M", "level": 1 }, { "id": "HAMMER", "level": 2 }, { "id": "FILE", "level": 1 } ], + "using": [ [ "welding_standard", 1 ] ], "tools": [ [ [ "shot_00", -1 ], @@ -435,13 +430,8 @@ "difficulty": 2, "time": "5 h", "book_learn": [ [ "manual_shotgun", 1 ] ], - "qualities": [ - { "id": "SAW_M", "level": 1 }, - { "id": "GLARE", "level": 2 }, - { "id": "HAMMER", "level": 2 }, - { "id": "FILE", "level": 1 }, - { "id": "WELD", "level": 1 } - ], + "qualities": [ { "id": "SAW_M", "level": 1 }, { "id": "HAMMER", "level": 2 }, { "id": "FILE", "level": 1 } ], + "using": [ [ "welding_standard", 1 ] ], "tools": [ [ [ "shot_00", -1 ], @@ -485,13 +475,8 @@ "difficulty": 2, "time": "2 h", "book_learn": [ [ "manual_shotgun", 1 ] ], - "qualities": [ - { "id": "SAW_M", "level": 1 }, - { "id": "GLARE", "level": 2 }, - { "id": "HAMMER", "level": 2 }, - { "id": "FILE", "level": 1 }, - { "id": "WELD", "level": 1 } - ], + "qualities": [ { "id": "SAW_M", "level": 1 }, { "id": "HAMMER", "level": 2 }, { "id": "FILE", "level": 1 } ], + "using": [ [ "welding_standard", 1 ] ], "proficiencies": [ { "proficiency": "prof_metalworking" }, { "proficiency": "prof_welding_basic" }, @@ -515,9 +500,9 @@ { "id": "HAMMER", "level": 2 }, { "id": "FILE", "level": 1 }, { "id": "WRENCH", "level": 1 }, - { "id": "DRILL", "level": 2 }, - { "id": "WELD", "level": 1 } + { "id": "DRILL", "level": 2 } ], + "using": [ [ "welding_standard", 1 ] ], "tools": [ [ [ "shot_00", -1 ], diff --git a/data/mods/Generic_Guns/recipes/recipes_firearms_single.json b/data/mods/Generic_Guns/recipes/recipes_firearms_single.json index a15454afdf260..4ab9d5459cf73 100644 --- a/data/mods/Generic_Guns/recipes/recipes_firearms_single.json +++ b/data/mods/Generic_Guns/recipes/recipes_firearms_single.json @@ -157,13 +157,8 @@ "time": "2 h", "autolearn": true, "book_learn": [ [ "manual_shotgun", 1 ] ], - "qualities": [ - { "id": "SAW_M", "level": 1 }, - { "id": "GLARE", "level": 2 }, - { "id": "HAMMER", "level": 2 }, - { "id": "FILE", "level": 1 }, - { "id": "WELD", "level": 1 } - ], + "qualities": [ { "id": "SAW_M", "level": 1 }, { "id": "HAMMER", "level": 2 }, { "id": "FILE", "level": 1 } ], + "using": [ [ "welding_standard", 1 ] ], "tools": [ [ [ "shot_buck", -1 ], @@ -248,13 +243,8 @@ "time": "2 h", "autolearn": true, "book_learn": [ [ "manual_shotgun", 1 ] ], - "qualities": [ - { "id": "SAW_M", "level": 1 }, - { "id": "GLARE", "level": 2 }, - { "id": "HAMMER", "level": 2 }, - { "id": "FILE", "level": 1 }, - { "id": "WELD", "level": 1 } - ], + "qualities": [ { "id": "SAW_M", "level": 1 }, { "id": "HAMMER", "level": 2 }, { "id": "FILE", "level": 1 } ], + "using": [ [ "welding_standard", 1 ] ], "tools": [ [ [ "shot_buck", -1 ], @@ -299,12 +289,11 @@ "book_learn": [ [ "manual_shotgun", 1 ] ], "qualities": [ { "id": "SAW_M", "level": 1 }, - { "id": "GLARE", "level": 2 }, { "id": "HAMMER", "level": 2 }, { "id": "FILE", "level": 1 }, - { "id": "WRENCH", "level": 1 }, - { "id": "WELD", "level": 1 } + { "id": "WRENCH", "level": 1 } ], + "using": [ [ "welding_standard", 1 ] ], "tools": [ [ [ "shot_buck", -1 ], @@ -346,7 +335,7 @@ "difficulty": 1, "time": "2 h", "autolearn": true, - "qualities": [ { "id": "WELD", "level": 1 } ], + "using": [ [ "welding_standard", 1 ] ], "proficiencies": [ { "proficiency": "prof_metalworking" }, { "proficiency": "prof_welding_basic" }, From c3db295b84d44a14e61f1797728e2a614cb7848a Mon Sep 17 00:00:00 2001 From: curstwist <39442864+curstwist@users.noreply.github.com> Date: Tue, 6 Jul 2021 21:53:58 -0400 Subject: [PATCH 025/116] add vehicles (#49605) --- data/json/vehicles/carts.json | 86 ++++++++++++++++++++++++++++++++++ data/json/vehicles/trains.json | 11 +++++ 2 files changed, 97 insertions(+) diff --git a/data/json/vehicles/carts.json b/data/json/vehicles/carts.json index c848c1aa1cfa1..e95f24cb9187c 100644 --- a/data/json/vehicles/carts.json +++ b/data/json/vehicles/carts.json @@ -247,5 +247,91 @@ { "x": 0, "y": 0, "chance": 40, "item_groups": [ "pants" ] }, { "x": 0, "y": 0, "chance": 20, "item_groups": [ "underwear" ] } ] + }, + { + "id": "cart_livestock_stall", + "type": "vehicle", + "name": "Large Animal Transport Cart", + "blueprint": [ + [ "o|o" ], + [ "o|o" ] + ], + "parts": [ + { "x": 0, "y": 0, "parts": [ "frame_vertical_T_left", "seat", "roof", "engine_electric" ] }, + { "x": 0, "y": 0, "part": "controls" }, + { "x": 0, "y": 1, "parts": [ "frame_vertical_T_right", "seat", "roof" ] }, + { "x": 0, "y": 1, "part": "storage_battery" }, + { "x": 1, "y": 0, "parts": [ "frame_nw", "halfboard_nw", "wheel_mount_light_steerable" ] }, + { "x": 1, "y": 0, "part": "wheel_small" }, + { "x": 1, "y": 1, "parts": [ "frame_ne", "halfboard_ne", "wheel_mount_light_steerable" ] }, + { "x": 1, "y": 1, "part": "wheel_small" }, + { "x": -1, "y": 0, "parts": [ "frame_sw", "livestock_stall", "wheel_mount_light", "wheel_small" ] }, + { "x": -1, "y": 1, "parts": [ "frame_se", "livestock_stall", "wheel_mount_light", "wheel_small" ] } + ], + "items": [ + { "x": -1, "y": 0, "chance": 25, "//repeat": 2, "item_groups": [ "snacks" ] }, + { "x": -1, "y": 1, "chance": 25, "//repeat": 2, "item_groups": [ "snacks" ] } + ] + }, + { + "id": "cart_animal_compartment", + "type": "vehicle", + "name": "Animal Transport Cart", + "blueprint": [ + [ "o|o" ], + [ "o|o" ] + ], + "parts": [ + { "x": 0, "y": 0, "parts": [ "frame_vertical_T_left", "seat", "roof", "engine_electric" ] }, + { "x": 0, "y": 0, "part": "controls" }, + { "x": 0, "y": 1, "parts": [ "frame_vertical_T_right", "seat", "roof" ] }, + { "x": 0, "y": 1, "part": "storage_battery" }, + { "x": 1, "y": 0, "parts": [ "frame_nw", "halfboard_nw", "wheel_mount_light_steerable" ] }, + { "x": 1, "y": 0, "part": "wheel_small" }, + { "x": 1, "y": 1, "parts": [ "frame_ne", "halfboard_ne", "wheel_mount_light_steerable" ] }, + { "x": 1, "y": 1, "part": "wheel_small" }, + { "x": -1, "y": 0, "parts": [ "frame_sw", "animal_compartment", "wheel_mount_light", "wheel_small" ] }, + { "x": -1, "y": 1, "parts": [ "frame_se", "animal_compartment", "wheel_mount_light", "wheel_small" ] } + ], + "items": [ + { "x": -1, "y": 0, "chance": 25, "//repeat": 2, "item_groups": [ "snacks" ] }, + { "x": -1, "y": 1, "chance": 25, "//repeat": 2, "item_groups": [ "snacks" ] } + ] + }, + { + "id": "cart_chassis", + "type": "vehicle", + "name": "Cart Chassis", + "blueprint": [ + [ "o|o" ], + [ "o|o" ] + ], + "parts": [ + { "x": 0, "y": 0, "part": "frame_vertical_left" }, + { "x": 0, "y": 1, "part": "frame_vertical_right" }, + { "x": 1, "y": 0, "parts": [ "frame_nw", "wheel_mount_light_steerable" ] }, + { "x": 1, "y": 0, "part": "wheel_small" }, + { "x": 1, "y": 1, "parts": [ "frame_ne", "wheel_mount_light_steerable" ] }, + { "x": 1, "y": 1, "part": "wheel_small" }, + { "x": -1, "y": 0, "parts": [ "frame_sw", "wheel_mount_light", "wheel_small" ] }, + { "x": -1, "y": 1, "parts": [ "frame_se", "wheel_mount_light", "wheel_small" ] } + ] + }, + { + "id": "cart_chassis_2", + "type": "vehicle", + "name": "Cart Chassis", + "blueprint": [ + [ "o|o" ], + [ "o|o" ] + ], + "parts": [ + { "x": 0, "y": 0, "part": "frame_vertical_left" }, + { "x": 0, "y": 1, "part": "frame_vertical_right" }, + { "x": 1, "y": 0, "part": "frame_nw" }, + { "x": 1, "y": 1, "part": "frame_ne" }, + { "x": -1, "y": 0, "part": "frame_sw" }, + { "x": -1, "y": 1, "part": "frame_se" } + ] } ] diff --git a/data/json/vehicles/trains.json b/data/json/vehicles/trains.json index b15175495f7dd..b74f58d83ab97 100644 --- a/data/json/vehicles/trains.json +++ b/data/json/vehicles/trains.json @@ -405,5 +405,16 @@ "name": "Trolley", "blueprint": [ "O" ], "parts": [ { "x": 0, "y": 0, "parts": [ "frame_vertical", "cargo_space", "rail_wheel_small_pair" ] } ] + }, + { + "id": "miniature_train_loco_steerable", + "type": "vehicle", + "name": "Miniature Train Locomotive", + "blueprint": [ "oo" ], + "parts": [ + { "x": 1, "y": 0, "parts": [ "frame_vertical_2", "engine_steam_small", "rail_wheel_steerable" ] }, + { "x": 0, "y": 0, "parts": [ "frame_vertical_2", "seat", "rail_wheel_steerable", "controls" ] }, + { "x": 0, "y": 0, "parts": [ { "part": "fuel_bunker", "fuel": "coal_lump" } ] } + ] } ] From 8905337f81de1dd31b37f28caf14e8321c692f23 Mon Sep 17 00:00:00 2001 From: Cyrano7 Date: Tue, 6 Jul 2021 19:00:09 -0700 Subject: [PATCH 026/116] Cleanup JSON_INFO.md (#49531) * Update JSON_INFO Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> --- doc/JSON_INFO.md | 53 ++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index 7fe197ac90d4b..aa41b33f01c16 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -229,7 +229,7 @@ Each of these types is documented separately, either below or in other documentation which should be linked from below (doubtless a few have been missed; feel free to file bugs for missing documentation). -The documentation is organised by file, because objects of the same type tend +The documentation is organized by file, because objects of the same type tend to be defined together in one file or a collection of co-located files. However, the game does not enforce this convention and in practice you could define a JSON object of any type in any file. If you were writing a small mod @@ -338,7 +338,7 @@ This section describes some common features of formatting values in CDDA JSON fi Most values which represent physical quantities (length, volume, time, etc.) are given as a string with a numerical value and an abbreviation of the unit, separated with a space. Generally we use SI units and try to stick to the -conventional SI abbreviations. For example, a volume of 3 litres would be +conventional SI abbreviations. For example, a volume of 3 liters would be defined as `"3 L"`. ### Time duration @@ -680,6 +680,7 @@ For information about tools with option to export ASCII art in format ready to b | vitamin_absorb_mod | (_optional_) Modifier to vitamin absorption, affects all vitamins. (default: `1.0`) | cant_remove_reason | (_optional_) String message to be displayed as the reason it can't be uninstalled. Having any value other than `""` as this will prevent unistalling the bionic. Formatting includes two `%s` for example: `The Telescopic Lenses are part of %1$s eyes now. Removing them would leave %2$s blind.` (default: `""`) | social_modifiers | (_optional_) Json object with optional members: persuade, lie, and intimidate which add or subtract that amount from those types of social checks + ```C++ { "id" : "bio_batteries", @@ -906,11 +907,11 @@ If a fuel has the PERPETUAL flag, engines powered by it never use any fuel. Thi |--- |--- | `name` | Unique ID. Must be one continuous word, use underscores if necessary. | `default` | Default monster, automatically fills in any remaining spawn chances. -| `monsters` | To choose a monster for spawning, the game creates `freq_total` entries (default 1000) and picks one. Each monster will have a number of entries equal to it's `freq` and the default monster will fill in the remaining. See the table below for how to build the single monster definitions. +| `monsters` | To choose a monster for spawning, the game creates `freq_total` entries (default 1000) and picks one. Each monster will have a number of entries equal to its `freq` and the default monster will fill in the remaining. See the table below for how to build the single monster definitions. | `is_safe` | (bool) Check to not trigger safe-mode warning, currently inconsequential. | `is_animal` | (bool) Check if that group has only normal animals, currently inconsequential. -| `freq_total`| (int) Determines the number of entries created for the monster roll, default 1000. If the total eligable `freq`s of a group exceed `freq_total` the entries after the monster that exceeded it **won't be included** in the roll - ie if the first two monsters out of a group of ten each have `freq: 500` the rest of the group won't have a chance to spawn at all! -| `replace_monster_group` | (bool) Check if the group should be replaced completely by another monster group as game time progresses - doesn't affect already spawned monsters, as such mostly superceded by monster evolution. +| `freq_total`| (int) Determines the number of entries created for the monster roll, default 1000. If the total eligible `freq`s of a group exceed `freq_total` the entries after the monster that exceeded it **won't be included** in the roll - i.e., if the first two monsters out of a group of ten each have `freq: 500` the rest of the group won't have a chance to spawn at all! +| `replace_monster_group` | (bool) Check if the group should be replaced completely by another monster group as game time progresses - doesn't affect already spawned monsters, as such mostly superseded by monster evolution. | `new_monster_group_id` | (string) The id of the monster group that should replace this one. | `replacement_time` | (int) The amount of time before the group should be replaced by the new one, in days. Final replacement date is calculated by `replacement_time * evolution factor`. @@ -1252,7 +1253,7 @@ Crafting recipes are defined as a JSON object with the following fields: "required": false, // Whether or not you must have the proficiency to craft it. Incompatible with `time_multiplier` "time_multiplier": 2.0 // The multiplier on time taken to craft this recipe if you do not have this proficiency "fail_multiplier": 2.5 // The multiplier on failure chance when crafting without this proficiency. Defaults to 2.5. Multiple proficiencies will multiply this value. (if all have the default, it's fail_multiplier ^ n, where n is the number of proficiencies that are lacked) - "learning_time_multiplier": 1.2 // The multiplier on learning speed for this proficiency. By default, it's the time of the recipe, divded by the time multiplier, and by the number of proficiencies that can also be learned from it. + "learning_time_multiplier": 1.2 // The multiplier on learning speed for this proficiency. By default, it's the time of the recipe, divided by the time multiplier, and by the number of proficiencies that can also be learned from it. "max_experience": "15 m" // This recipe cannot raise your experience for that proficiency above 15 minutes worth. } ] @@ -1713,7 +1714,7 @@ optional. It defaults to ": ". #### `achievement` Achievements are goals for the player to aspire to, in the usual sense of the -term as popularised in other games. +term as popularized in other games. An achievement is specified via requirements, each of which is a constraint on an `event_statistic`. For example: @@ -1903,7 +1904,7 @@ it is present to help catch errors. "scent_mask": -200,// int added to your target scent value. (default: 0) "scent_type": "sc_flower",// scent_typeid, defined in scent_types.json, The type scent you emit. (default: empty) "consume_time_modifier": 1.0f,//time to eat or drink is multiplied by this -"bleed_resist": 1000, // Int quantifiying your resistance to bleed effect, if its > to the intensity of the effect you don't get any bleeding. (default: 0) +"bleed_resist": 1000, // Int quantifying your resistance to bleed effect, if it's > to the intensity of the effect you don't get any bleeding. (default: 0) "fat_to_max_hp": 1.0, // Amount of hp_max gained for each unit of bmi above character_weight_category::normal. (default: 0.0) "healthy_rate": 0.0, // How fast your health can change. If set to 0 it never changes. (default: 1.0) "weakness_to_water": 5, // How much damage water does to you, negative values heal you. (default: 0) @@ -1921,7 +1922,7 @@ it is present to help catch errors. "healing_awake": 1.0, // Healing rate per turn while awake. "healing_resting": 0.5, // Healing rate per turn while resting. "mending_modifier": 1.2 // Multiplier on how fast your limbs mend - This value would make your limbs mend 20% faster -"transform": { "target": "BIOLUM1", // Trait_id of the mutation this one will transfomr into +"transform": { "target": "BIOLUM1", // Trait_id of the mutation this one will transform into "msg_transform": "You turn your photophore OFF.", // message displayed upon transformation "active": false , // Will the target mutation start powered ( turn ON ). "moves": 100 // how many moves this costs. (default: 0) @@ -1982,7 +1983,7 @@ it is present to help catch errors. "floor_bedding_warmth": -500, "spell_data": { "id": "bear_trap" }, // data required for trapfunc::spell() "trigger_weight": "200 g", // If an item with this weight or more is thrown onto the trap, it triggers. TODO: what is the default? - "drops": [ "beartrap" ], // For disassembly? + "drops": [ "beartrap" ], // ID of item spawned when disassembled "flags": [ "EXAMPLE_FLAG" ], // A set of valid flags for this trap "vehicle_data": { "damage": 300, @@ -2018,7 +2019,7 @@ Vehicle components when installed on a vehicle. "symbol": "0", // (Optional) ASCII character displayed when part is working "symbols": { // (Optional) ASCII characters displayed when the part is working, "left": "0", "right": "0" // listed by variant suffix. See below for more on variants -"standard_symbols: false, // (Optional) Use the standard ASCII characters for variants +"standard_symbols": false, // (Optional) Use the standard ASCII characters for variants // must have one of symbol, symbols, or standard_symbols "looks_like": "small_wheel", // (Optional) hint to tilesets if this part has no tile, // use the looks_like tile. @@ -2047,7 +2048,7 @@ Vehicle components when installed on a vehicle. "flags": [ // Flags associated with the part "EXTERNAL", "MOUNT_OVER", "WHEEL", "MOUNT_POINT", "VARIABLE_SIZE" ], -"requirements": { // (Optional) Special installation, removal, or repair requirementsi +"requirements": { // (Optional) Special installation, removal, or repair requirements // for the part. Each field consists of an object, with fields // "skills", "time", and "using". "install": { @@ -2163,13 +2164,13 @@ The following `wheel_types` are available: #### The following optional fields are specific to ROTORs. ```c++ -"rotor_diameter": 15, // Rotor diamater in meters. Larger rotors provide more lift. +"rotor_diameter": 15, // Rotor diameter in meters. Larger rotors provide more lift. ``` #### The following optional fields are specific to WORKBENCHes. These values apply to crafting tasks performed at the WORKBENCH. ```c++ -"multiplier": 1.1, // Crafting speed multipler. +"multiplier": 1.1, // Crafting speed multiplier. "mass": 1000000, // Maximum mass in grams of a completed craft that can be crafted. "volume": "20L", // Maximum volume (as a string) of a completed craft that can be craft. ``` @@ -2416,7 +2417,7 @@ According to Date: Tue, 6 Jul 2021 21:02:08 -0500 Subject: [PATCH 027/116] add bow saw item (#49340) from https://github.com/GMC-Modding-Team/Community-Mod-Compilation-redux/tree/master/data/Unleash_The_Mods/Working_mods/More_tools + minor edits --- .../locations_commercial.json | 1 + data/json/itemgroups/tools.json | 4 ++++ data/json/items/tool/woodworking.json | 18 ++++++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/data/json/itemgroups/Locations_MapExtras/locations_commercial.json b/data/json/itemgroups/Locations_MapExtras/locations_commercial.json index f267a01bcdfb5..fa7588bbf8332 100644 --- a/data/json/itemgroups/Locations_MapExtras/locations_commercial.json +++ b/data/json/itemgroups/Locations_MapExtras/locations_commercial.json @@ -1193,6 +1193,7 @@ { "item": "cordless_drill", "prob": 70, "charges": [ 0, 500 ] }, [ "thermometer", 60 ], [ "saw", 90 ], + { "item": "bow_saw", "prob": 30 }, { "item": "chainsaw_off", "prob": 10, "charges": [ 0, 450 ] }, [ "bucket", 100 ], [ "tree_spile", 100 ], diff --git a/data/json/itemgroups/tools.json b/data/json/itemgroups/tools.json index 691fdf6d83d05..993a87bdf287a 100644 --- a/data/json/itemgroups/tools.json +++ b/data/json/itemgroups/tools.json @@ -56,6 +56,7 @@ { "item": "misc_repairkit", "prob": 25, "charges-min": 0 }, [ "pliers", 60 ], [ "saw", 60 ], + { "item": "bow_saw", "prob": 50 }, [ "screwdriver", 100 ], [ "screwdriver_set", 50 ], [ "wrench", 40 ], @@ -110,6 +111,7 @@ [ "sandpaper", 65 ], [ "hacksaw", 30 ], [ "saw", 65 ], + { "item": "bow_saw", "prob": 40 }, [ "pin_reamer", 18 ], [ "clamp", 30 ], [ "boxcutter", 20 ], @@ -642,6 +644,7 @@ [ "wrench", 50 ], [ "hammer", 40 ], [ "saw", 50 ], + { "item": "bow_saw", "prob": 40 }, [ "ax", 20 ], [ "hacksaw", 50 ], [ "chipper", 60 ], @@ -673,6 +676,7 @@ [ "ax", 100 ], { "item": "chainsaw_off", "prob": 80, "charges": [ 0, 400 ] }, [ "saw", 100 ], + { "item": "bow_saw", "prob": 80 }, { "item": "circsaw_off", "prob": 50, "charges": [ 0, 500 ] }, [ "circsaw_blade", 10 ], { "item": "elec_chainsaw_off", "prob": 35, "charges": [ 0, 500 ] } diff --git a/data/json/items/tool/woodworking.json b/data/json/items/tool/woodworking.json index 6343db479c51c..3f30fe14f59fb 100644 --- a/data/json/items/tool/woodworking.json +++ b/data/json/items/tool/woodworking.json @@ -18,6 +18,24 @@ "techniques": [ "WBLOCK_1", "BRUTAL", "SWEEP" ], "flags": [ "NONCONDUCTIVE", "SHEATH_AXE" ] }, + { + "id": "bow_saw", + "type": "TOOL", + "name": { "str": "bow saw" }, + "description": "The bow saw is more at home outdoors than inside. Bow saws are used for trimming trees, pruning, and cutting firewood, but may be used for other rough cuts as well.", + "weight": "800 g", + "volume": "900 ml", + "longest_side": "40 cm", + "price": "30 USD", + "price_postapoc": "1 USD", + "to_hit": -2, + "cutting": 1, + "material": [ "steel", "plastic" ], + "symbol": "(", + "color": "red", + "qualities": [ [ "AXE", 2 ], [ "SAW_W", 2 ], [ "BUTCHER", -90 ] ], + "flags": [ "NONCONDUCTIVE", "BELT_CLIP" ] + }, { "id": "chainsaw_off", "type": "TOOL", From 6e829ef63433be40f48a0bc30f8ee08a4bbe484c Mon Sep 17 00:00:00 2001 From: Venera3 <72006894+Venera3@users.noreply.github.com> Date: Wed, 7 Jul 2021 04:22:08 +0200 Subject: [PATCH 028/116] Add bleed resistance to monsters (#49546) Co-authored-by: anothersimulacrum --- data/json/monsters/cyborgs.json | 1 + data/json/monsters/fish.json | 4 ++++ data/json/monsters/fungus.json | 16 ++++++++++++++++ data/json/monsters/insect_spider.json | 9 +++++++++ data/json/monsters/jabberwock.json | 3 +++ data/json/monsters/marloss.json | 2 ++ data/json/monsters/mi-go.json | 6 ++++++ data/json/monsters/mutant.json | 2 ++ data/json/monsters/mutant_mammal.json | 2 ++ data/json/monsters/nether.json | 10 ++++++++++ data/json/monsters/power_leech.json | 3 +++ data/json/monsters/slimes.json | 3 +++ data/json/monsters/slugs.json | 2 ++ data/json/monsters/triffid.json | 9 +++++++++ data/json/monsters/zanimal_upgrade.json | 13 +++++++++++++ data/json/monsters/zed-animal.json | 1 + data/json/monsters/zed-pupating.json | 3 +++ data/json/monsters/zed-winged.json | 2 ++ data/json/monsters/zed_acid.json | 3 +++ data/json/monsters/zed_burned.json | 3 +++ data/json/monsters/zed_children.json | 6 ++++++ data/json/monsters/zed_electric.json | 3 +++ data/json/monsters/zed_explosive.json | 1 + data/json/monsters/zed_ferrous.json | 4 ++++ data/json/monsters/zed_fusion.json | 7 +++++++ data/json/monsters/zed_lab.json | 1 + data/json/monsters/zed_misc.json | 20 ++++++++++++++++++++ data/json/monsters/zed_radiation.json | 5 +++++ data/json/monsters/zed_skeletal.json | 4 ++++ data/json/monsters/zed_soldiers.json | 7 +++++++ doc/MONSTERS.md | 5 +++++ src/character.h | 2 +- src/creature.cpp | 10 +--------- src/creature.h | 5 +++++ src/monattack.cpp | 11 +++-------- src/monster.cpp | 17 ++++++++++++++++- src/monster.h | 3 +++ src/monstergenerator.cpp | 2 ++ src/mtype.h | 3 +++ tests/creature_effect_test.cpp | 5 +++-- 40 files changed, 197 insertions(+), 21 deletions(-) diff --git a/data/json/monsters/cyborgs.json b/data/json/monsters/cyborgs.json index ac6a6bb8123c0..26268c190334f 100644 --- a/data/json/monsters/cyborgs.json +++ b/data/json/monsters/cyborgs.json @@ -193,6 +193,7 @@ "melee_cut": 12, "armor_bash": 12, "armor_cut": 28, + "bleed_rate": 50, "vision_night": 3, "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "GRAB", 7 ], [ "scratch", 20 ] ], "death_drops": { "subtype": "collection", "groups": [ [ "robots", 80 ] ] }, diff --git a/data/json/monsters/fish.json b/data/json/monsters/fish.json index cccbc26cab972..6060db27211ef 100644 --- a/data/json/monsters/fish.json +++ b/data/json/monsters/fish.json @@ -25,6 +25,7 @@ "armor_bash": 20, "armor_cut": 30, "armor_bullet": 24, + "bleed_rate": 60, "vision_day": 30, "vision_night": 20, "path_settings": { "max_dist": 50, "avoid_traps": true, "avoid_sharp": true }, @@ -628,6 +629,7 @@ "dodge": 2, "armor_cut": 8, "armor_bullet": 6, + "bleed_rate": 85, "harvest": "shellfish", "anger_triggers": [ "PLAYER_CLOSE", "HURT" ], "fear_triggers": [ "FIRE" ], @@ -645,6 +647,7 @@ "volume": "625 L", "weight": "815 kg", "melee_dice": 2, + "bleed_rate": 60, "special_attacks": [ [ "PARROT", 20 ], { "id": "scratch", "damage_max_instance": [ { "damage_type": "cut", "amount": 23, "armor_multiplier": 0.8 } ] } @@ -677,6 +680,7 @@ "armor_bash": 10, "armor_cut": 18, "armor_bullet": 14, + "bleed_rate": 65, "vision_day": 30, "vision_night": 15, "path_settings": { "max_dist": 50, "avoid_traps": true, "avoid_sharp": true }, diff --git a/data/json/monsters/fungus.json b/data/json/monsters/fungus.json index 4841d66df4bd4..1742844e2f5bc 100644 --- a/data/json/monsters/fungus.json +++ b/data/json/monsters/fungus.json @@ -22,6 +22,7 @@ "melee_dice_sides": 6, "melee_cut": 0, "armor_bash": 2, + "bleed_rate": 0, "vision_day": 30, "vision_night": 3, "harvest": "zombie", @@ -52,6 +53,7 @@ "armor_bash": 4, "armor_cut": 4, "armor_bullet": 3, + "bleed_rate": 0, "luminance": 40, "harvest": "exempt", "special_attacks": [ [ "FUNGUS_HAZE", 25 ] ], @@ -82,6 +84,7 @@ "armor_bash": 10, "armor_cut": 10, "armor_bullet": 8, + "bleed_rate": 0, "harvest": "exempt", "special_attacks": [ [ "FUNGUS_BRISTLE", 10 ] ], "death_function": [ "DISINTEGRATE" ], @@ -112,6 +115,7 @@ "armor_bash": 10, "armor_cut": 4, "armor_bullet": 3, + "bleed_rate": 0, "harvest": "exempt", "special_attacks": [ [ "FUNGUS_INJECT", 10 ] ], "death_function": [ "FUNGUS" ], @@ -141,6 +145,7 @@ "armor_bash": 10, "armor_cut": 10, "armor_bullet": 8, + "bleed_rate": 0, "harvest": "exempt", "special_attacks": [ [ "FUNGUS", 10 ] ], "death_function": [ "DISINTEGRATE" ], @@ -169,6 +174,7 @@ "melee_dice_sides": 4, "melee_cut": 0, "armor_bash": 4, + "bleed_rate": 0, "harvest": "fungaloid", "special_attacks": [ [ "FUNGUS", 30 ] ], "death_function": [ "FUNGUS", "NORMAL" ], @@ -189,6 +195,7 @@ "armor_bullet": 20, "armor_stab": 20, "armor_acid": 3, + "bleed_rate": 0, "special_attacks": [ [ "FUNGUS", 20 ], { @@ -316,6 +323,7 @@ "armor_bash": 4, "armor_cut": 4, "armor_bullet": 3, + "bleed_rate": 0, "harvest": "fungaloid", "special_attacks": [ [ "FUNGUS_GROWTH", 10000 ] ], "death_function": [ "NORMAL" ], @@ -340,6 +348,7 @@ "morale": 75, "melee_cut": 0, "dodge": 2, + "bleed_rate": 0, "harvest": "exempt", "special_attacks": [ [ "PLANT", 100 ] ], "death_function": [ "DISINTEGRATE" ], @@ -369,6 +378,7 @@ "melee_dice_sides": 6, "melee_cut": 0, "armor_bash": 3, + "bleed_rate": 0, "vision_day": 5, "vision_night": 5, "harvest": "zombie", @@ -401,6 +411,7 @@ "melee_dice": 2, "melee_dice_sides": 4, "melee_cut": 0, + "bleed_rate": 0, "vision_day": 5, "vision_night": 5, "harvest": "exempt", @@ -435,6 +446,7 @@ "melee_cut": 2, "dodge": 4, "armor_fire": 5, + "bleed_rate": 0, "vision_day": 5, "vision_night": 3, "harvest": "zombie", @@ -469,6 +481,7 @@ "armor_bash": 20, "armor_cut": 45, "armor_bullet": 36, + "bleed_rate": 0, "vision_day": 5, "vision_night": 5, "harvest": "mr_bones", @@ -513,6 +526,7 @@ "melee_dice_sides": 6, "melee_cut": 2, "dodge": 2, + "bleed_rate": 0, "vision_day": 30, "vision_night": 5, "harvest": "zombie", @@ -552,6 +566,7 @@ "armor_bash": 1, "armor_cut": 1, "armor_bullet": 1, + "bleed_rate": 0, "vision_day": 3, "vision_night": 3, "harvest": "arachnid", @@ -585,6 +600,7 @@ "armor_bash": 2, "armor_cut": 6, "armor_bullet": 5, + "bleed_rate": 0, "vision_day": 5, "vision_night": 5, "harvest": "arachnid", diff --git a/data/json/monsters/insect_spider.json b/data/json/monsters/insect_spider.json index 8a21bad7e797f..d4524cc36f30d 100644 --- a/data/json/monsters/insect_spider.json +++ b/data/json/monsters/insect_spider.json @@ -22,6 +22,7 @@ "melee_cut": 4, "dodge": 4, "armor_bash": 6, + "bleed_rate": 60, "harvest": "arachnid_acid", "death_function": [ "NORMAL" ], "flags": [ "SMELLS", "HEARS", "GOODHEARING", "BASHES", "BORES", "POISON", "SUNDEATH", "ACIDPROOF", "ACIDTRAIL" ] @@ -50,6 +51,7 @@ "armor_bash": 12, "armor_cut": 8, "armor_bullet": 6, + "bleed_rate": 60, "harvest": "meatslug", "death_function": [ "WORM" ], "flags": [ "DIGS", "HEARS", "POISON", "GOODHEARING", "BASHES", "DESTROYS" ] @@ -478,6 +480,7 @@ "armor_cut": 25, "armor_bullet": 12, "armor_stab": 14, + "bleed_rate": 80, "vision_day": 9, "vision_night": 6, "anger_triggers": [ "STALK", "PLAYER_CLOSE" ], @@ -570,6 +573,7 @@ "armor_bullet": 45, "armor_cut": 35, "armor_stab": 15, + "bleed_rate": 60, "vision_day": 12, "vision_night": 7, "anger_triggers": [ "STALK", "PLAYER_WEAK", "HURT" ], @@ -1442,6 +1446,7 @@ "armor_cut": 14, "armor_stab": 12, "armor_bullet": 12, + "bleed_rate": 80, "vision_day": 17, "vision_night": 7, "harvest": "arachnid_wasp", @@ -1503,6 +1508,7 @@ "armor_cut": 30, "armor_stab": 18, "armor_bullet": 22, + "bleed_rate": 60, "harvest": "arachnid_wasp_queen", "reproduction": { "baby_egg": "egg_wasp", "baby_count": 4, "baby_timer": 5 }, "extend": { "flags": [ "PUSH_MON" ] }, @@ -1811,6 +1817,7 @@ "armor_bash": 12, "armor_cut": 14, "armor_bullet": 11, + "bleed_rate": 80, "vision_day": 5, "vision_night": 5, "special_attacks": [ [ "ACID", 15 ] ], @@ -1901,6 +1908,7 @@ "armor_bash": 10, "armor_cut": 12, "armor_bullet": 10, + "bleed_rate": 80, "vision_day": 5, "vision_night": 5, "harvest": "arachnid", @@ -1920,6 +1928,7 @@ "volume": "625 L", "weight": "815 kg", "melee_dice": 2, + "bleed_rate": 60, "special_attacks": [ [ "SMASH", 30 ], [ "BIO_OP_TAKEDOWN", 20 ], [ "RANGED_PULL", 20 ], [ "GRAB", 5 ] ], "extend": { "flags": [ "DESTROYS", "PUSH_MON", "PUSH_VEH", "RANGED_ATTACKER" ] } }, diff --git a/data/json/monsters/jabberwock.json b/data/json/monsters/jabberwock.json index 8e49506b21980..02e28e71aad1f 100644 --- a/data/json/monsters/jabberwock.json +++ b/data/json/monsters/jabberwock.json @@ -22,6 +22,7 @@ "armor_bash": 2, "armor_cut": 2, "armor_bullet": 2, + "bleed_rate": 80, "vision_day": 50, "vision_night": 3, "special_attacks": [ [ "FLESH_GOLEM", 10 ], [ "ABSORB_MEAT", 10 ] ], @@ -53,6 +54,7 @@ "armor_bash": 6, "armor_cut": 4, "armor_bullet": 3, + "bleed_rate": 60, "vision_day": 50, "vision_night": 3, "special_attacks": [ [ "FLESH_GOLEM", 8 ], [ "ABSORB_MEAT", 1 ] ], @@ -85,6 +87,7 @@ "armor_bash": 12, "armor_cut": 8, "armor_bullet": 6, + "bleed_rate": 40, "vision_day": 50, "vision_night": 3, "special_attacks": [ [ "FLESH_GOLEM", 5 ] ], diff --git a/data/json/monsters/marloss.json b/data/json/monsters/marloss.json index 66d143afd1c05..8426ec1a6fcc3 100644 --- a/data/json/monsters/marloss.json +++ b/data/json/monsters/marloss.json @@ -21,6 +21,7 @@ "melee_dice_sides": 4, "melee_cut": 0, "dodge": 1, + "bleed_rate": 50, "harvest": "human", "vision_day": 30, "vision_night": 3, @@ -52,6 +53,7 @@ "melee_dice_sides": 4, "melee_cut": 0, "dodge": 1, + "bleed_rate": 50, "harvest": "human", "vision_day": 30, "vision_night": 3, diff --git a/data/json/monsters/mi-go.json b/data/json/monsters/mi-go.json index e9df4f4ff78cd..62357c24b73a1 100644 --- a/data/json/monsters/mi-go.json +++ b/data/json/monsters/mi-go.json @@ -24,6 +24,7 @@ "armor_bash": 4, "armor_cut": 12, "armor_bullet": 10, + "bleed_rate": 75, "vision_day": 50, "vision_night": 20, "harvest": "zombie_meatslug", @@ -74,6 +75,7 @@ "armor_bash": 4, "armor_cut": 12, "armor_bullet": 10, + "bleed_rate": 50, "vision_day": 50, "vision_night": 20, "harvest": "zombie_meatslug", @@ -125,6 +127,7 @@ "armor_bash": 5, "armor_cut": 13, "armor_bullet": 10, + "bleed_rate": 75, "vision_day": 50, "vision_night": 20, "harvest": "zombie_meatslug", @@ -175,6 +178,7 @@ "armor_bash": 17, "armor_cut": 22, "armor_bullet": 18, + "bleed_rate": 50, "vision_day": 50, "vision_night": 20, "harvest": "zombie_meatslug", @@ -229,6 +233,7 @@ "armor_bash": 19, "armor_cut": 27, "armor_bullet": 22, + "bleed_rate": 25, "vision_day": 50, "vision_night": 25, "harvest": "zombie_meatslug", @@ -282,6 +287,7 @@ "armor_bash": 4, "armor_cut": 5, "armor_bullet": 4, + "bleed_rate": 25, "vision_day": 50, "vision_night": 25, "harvest": "zombie_meatslug", diff --git a/data/json/monsters/mutant.json b/data/json/monsters/mutant.json index 00adc491841d8..52b1cfc52c779 100644 --- a/data/json/monsters/mutant.json +++ b/data/json/monsters/mutant.json @@ -55,6 +55,7 @@ "armor_bash": 5, "armor_cut": 5, "armor_bullet": 4, + "bleed_rate": 75, "vision_day": 25, "vision_night": 5, "harvest": "human_fur", @@ -97,6 +98,7 @@ "armor_bash": 7, "armor_cut": 7, "armor_bullet": 6, + "bleed_rate": 50, "vision_night": 15, "harvest": "human_large_fur", "special_attacks": [ diff --git a/data/json/monsters/mutant_mammal.json b/data/json/monsters/mutant_mammal.json index 68f47f28b1c50..b8b573988e929 100644 --- a/data/json/monsters/mutant_mammal.json +++ b/data/json/monsters/mutant_mammal.json @@ -24,6 +24,7 @@ "dodge": 3, "armor_bash": 8, "armor_cut": 12, + "bleed_rate": 80, "vision_day": 30, "vision_night": 10, "path_settings": { "max_dist": 10 }, @@ -283,6 +284,7 @@ "dodge": 2, "armor_bash": 8, "armor_cut": 10, + "bleed_rate": 60, "vision_day": 50, "vision_night": 5, "harvest": "mutant_mammal_large_fur", diff --git a/data/json/monsters/nether.json b/data/json/monsters/nether.json index d285cf229bfe5..8071ff1307a89 100644 --- a/data/json/monsters/nether.json +++ b/data/json/monsters/nether.json @@ -56,6 +56,7 @@ "melee_dice_sides": 4, "melee_cut": 0, "dodge": 2, + "bleed_rate": 50, "harvest": "human", "special_attacks": [ [ "FEAR_PARALYZE", 0 ] ], "death_function": [ "AMIGARA", "NORMAL" ], @@ -260,6 +261,7 @@ "melee_cut": 0, "dodge": 1, "armor_bash": 4, + "bleed_rate": 20, "vision_day": 50, "vision_night": 40, "luminance": 25, @@ -293,6 +295,7 @@ "melee_cut": 6, "dodge": 7, "armor_bash": 8, + "bleed_rate": 40, "harvest": "exempt", "death_function": [ "MELT" ], "flags": [ @@ -333,6 +336,7 @@ "melee_dice_sides": 6, "melee_cut": 0, "dodge": 4, + "bleed_rate": 60, "vision_day": 30, "harvest": "gozu", "special_attacks": [ [ "FEAR_PARALYZE", 20 ] ], @@ -361,6 +365,7 @@ "melee_dice_sides": 4, "melee_cut": 0, "dodge": 4, + "bleed_rate": 60, "path_settings": { "avoid_traps": true, "avoid_sharp": true }, "harvest": "demihuman", "death_function": [ "NORMAL" ], @@ -418,6 +423,7 @@ "dodge": 5, "armor_cut": 50, "armor_bullet": 40, + "bleed_rate": 20, "vision_day": 50, "vision_night": 50, "harvest": "exempt", @@ -462,6 +468,7 @@ "dodge": 5, "armor_cut": 50, "armor_bullet": 40, + "bleed_rate": 0, "vision_day": 50, "vision_night": 50, "harvest": "exempt", @@ -572,6 +579,7 @@ "dodge": 8, "armor_cut": 5, "armor_bullet": 4, + "bleed_rate": 40, "vision_day": 50, "//": "a good candidate for an alien anatomy harvest", "harvest": "exempt", @@ -740,6 +748,7 @@ "melee_cut": 0, "dodge": 2, "armor_bash": 8, + "bleed_rate": 20, "harvest": "exempt", "special_attacks": [ [ "TENTACLE", 5 ] ], "death_function": [ "MELT" ], @@ -795,6 +804,7 @@ "melee_cut": 8, "dodge": 1, "armor_bash": 6, + "bleed_rate": 50, "harvest": "meatslug", "special_attacks": [ [ "GENE_STING", 20 ] ], "death_function": [ "NORMAL" ], diff --git a/data/json/monsters/power_leech.json b/data/json/monsters/power_leech.json index f103c93c9d557..a93d257256003 100644 --- a/data/json/monsters/power_leech.json +++ b/data/json/monsters/power_leech.json @@ -17,6 +17,7 @@ "aggression": 100, "morale": 100, "armor_bash": 15, + "bleed_rate": 30, "vision_day": 30, "vision_night": 12, "luminance": 200, @@ -57,6 +58,7 @@ "aggression": 100, "morale": 100, "armor_bash": 15, + "bleed_rate": 30, "vision_day": 30, "vision_night": 8, "luminance": 200, @@ -95,6 +97,7 @@ "aggression": 100, "morale": 100, "armor_bash": 15, + "bleed_rate": 30, "vision_day": 30, "vision_night": 8, "luminance": 200, diff --git a/data/json/monsters/slimes.json b/data/json/monsters/slimes.json index 230e6956aad0b..c32d81d0c4ae4 100644 --- a/data/json/monsters/slimes.json +++ b/data/json/monsters/slimes.json @@ -25,6 +25,7 @@ "armor_bash": 12, "armor_stab": 14, "armor_acid": 15, + "bleed_rate": 30, "harvest": "exempt", "special_attacks": [ [ "FORMBLOB", 30 ] ], "death_function": [ "BLOBSPLIT" ], @@ -54,6 +55,7 @@ "melee_dice_sides": 4, "melee_cut": 0, "armor_bash": 12, + "bleed_rate": 20, "harvest": "exempt", "special_attacks": [ [ "CALLBLOBS", 0 ] ], "death_function": [ "BRAINBLOB" ], @@ -87,6 +89,7 @@ "armor_bullet": 3, "armor_stab": 20, "armor_acid": 20, + "bleed_rate": 30, "harvest": "exempt", "special_attacks": [ [ "FORMBLOB", 20 ] ], "death_function": [ "BLOBSPLIT" ], diff --git a/data/json/monsters/slugs.json b/data/json/monsters/slugs.json index 94a9ad034227c..8f65107620027 100644 --- a/data/json/monsters/slugs.json +++ b/data/json/monsters/slugs.json @@ -22,6 +22,7 @@ "melee_cut": 0, "dodge": 12, "armor_bash": 4, + "bleed_rate": 30, "vision_day": 10, "vision_night": 30, "harvest": "exempt", @@ -65,6 +66,7 @@ "armor_bash": 8, "armor_cut": 2, "armor_bullet": 2, + "bleed_rate": 60, "vision_day": 30, "harvest": "mutant_meatslug", "special_attacks": [ [ "ACID", 10 ] ], diff --git a/data/json/monsters/triffid.json b/data/json/monsters/triffid.json index 49014177de483..4395fd8b13587 100644 --- a/data/json/monsters/triffid.json +++ b/data/json/monsters/triffid.json @@ -43,6 +43,7 @@ "aggression": 100, "morale": 100, "melee_cut": 0, + "bleed_rate": 80, "harvest": "biollante", "special_attacks": [ [ "SPIT_SAP", 2 ] ], "death_drops": { "subtype": "collection", "groups": [ [ "biollante", 8 ] ], "//": "80% chance of an item from group biollante" }, @@ -67,6 +68,7 @@ "morale": 100, "melee_cut": 0, "armor_bash": 8, + "bleed_rate": 50, "harvest": "exempt", "special_attacks": [ [ "GROW_VINE", 60 ] ], "death_function": [ "KILL_VINES" ], @@ -90,6 +92,7 @@ "morale": 100, "melee_cut": 0, "armor_bash": 2, + "bleed_rate": 80, "harvest": "exempt", "special_attacks": [ [ "VINE", 100 ] ], "death_function": [ "VINE_CUT" ], @@ -139,6 +142,7 @@ "melee_dice": 1, "melee_dice_sides": 4, "melee_cut": 4, + "bleed_rate": 75, "harvest": "triffid_paralytic", "upgrades": { "age_grow": 14, "into": "mon_triffid" }, "special_attacks": [ [ "TRIFFID_GROWTH", 28800 ] ], @@ -169,6 +173,7 @@ "armor_bash": 10, "armor_cut": 4, "armor_bullet": 3, + "bleed_rate": 60, "harvest": "triffid_paralytic", "death_function": [ "NORMAL" ], "fungalize_into": "mon_fungaloid", @@ -197,6 +202,7 @@ "armor_bash": 12, "armor_cut": 8, "armor_bullet": 6, + "bleed_rate": 40, "harvest": "triffid_queen", "special_attacks": [ [ "GROWPLANTS", 20 ] ], "death_function": [ "NORMAL" ], @@ -225,6 +231,7 @@ "melee_cut": 0, "dodge": 4, "armor_bash": 18, + "bleed_rate": 10, "harvest": "triffid_small", "death_function": [ "NORMAL" ], "flags": [ "HEARS", "GOODHEARING", "NOHEAD", "HARDTOSHOOT", "GRABS", "SWIMS", "PLASTIC" ] @@ -252,6 +259,7 @@ "armor_bash": 4, "armor_cut": 6, "armor_bullet": 5, + "bleed_rate": 60, "harvest": "triffid_fungal_fighter", "attack_effs": [ { "id": "paralyzepoison", "//": "applying this multiple times makes intensity go up by 3 instead of 1", "duration": 33 }, @@ -281,6 +289,7 @@ "aggression": 100, "morale": 100, "melee_cut": 0, + "bleed_rate": 60, "harvest": "triffid_paralytic", "special_attacks": [ [ "SPIT_SAP", 3 ], [ "PARA_STING", 12 ] ], "death_function": [ "NORMAL" ], diff --git a/data/json/monsters/zanimal_upgrade.json b/data/json/monsters/zanimal_upgrade.json index a65290baff1a7..5beff93f879e4 100644 --- a/data/json/monsters/zanimal_upgrade.json +++ b/data/json/monsters/zanimal_upgrade.json @@ -25,6 +25,7 @@ "armor_bullet": 12, "armor_stab": 30, "armor_acid": 3, + "bleed_rate": 50, "vision_night": 3, "harvest": "mr_bones", "special_attacks": [ { "type": "bite", "cooldown": 5 } ], @@ -50,6 +51,7 @@ "armor_bullet": 5, "vision_night": 1 }, + "bleed_rate": 50, "upgrades": { "half_life": 21, "into": "mon_dog_zombie_hulk" }, "special_attacks": [ [ "SMASH", 30 ], { "type": "bite", "move_cost": 150, "cooldown": 2, "accuracy": 4, "no_infection_chance": 12 } ], "extend": { "flags": [ "GROUP_BASH", "PUSH_VEH" ] } @@ -69,6 +71,7 @@ "armor_bash": 8, "armor_cut": 12, "armor_bullet": 10, + "bleed_rate": 0, "upgrades": { }, "special_attacks": [ [ "SMASH", 20 ], { "type": "bite", "move_cost": 188, "cooldown": 2, "accuracy": 4, "no_infection_chance": 12 } ], "extend": { "flags": [ "DESTROYS" ] } @@ -87,6 +90,7 @@ "armor_bullet": 24, "armor_bash": 12, "armor_acid": 1, + "bleed_rate": 0, "special_attacks": [ [ "SMASH", 45 ], { "id": "scratch", "damage_max_instance": [ { "damage_type": "cut", "amount": 15, "armor_multiplier": 0.6 } ] } @@ -111,6 +115,7 @@ "armor_bullet": 5, "vision_night": 1 }, + "bleed_rate": 50, "special_attacks": [ [ "SMASH", 30 ], { "id": "impale" } ], "extend": { "flags": [ "GROUP_BASH", "PUSH_VEH", "HIT_AND_RUN" ] } }, @@ -122,6 +127,7 @@ "description": "Billowing clouds of yellow-streaked gas precede boar-shaped shadows. Glimpses of a zombie boar are quickly obscured by the gases leaving its body through open wounds.", "diff": 5, "color": "red", + "bleed_rate": 50, "weight": "150 kg", "harvest": "exempt", "emit_fields": [ { "emit_id": "emit_tear_gas_stream", "delay": "1 s" } ], @@ -156,6 +162,7 @@ "armor_bullet": 12, "armor_stab": 30, "armor_acid": 3, + "bleed_rate": 50, "vision_night": 3, "harvest": "mr_bones", "special_attacks": [ { "type": "bite", "cooldown": 5 } ], @@ -176,6 +183,7 @@ "melee_dice": 6, "melee_cut": 8, "dodge": 5, + "bleed_rate": 50, "vision_night": 12, "special_attacks": [ { "id": "scratch", "move_cost": 190, "damage_max_instance": [ { "damage_type": "cut", "amount": 12 } ] }, @@ -207,6 +215,7 @@ "armor_bullet": 32, "armor_stab": 30, "armor_acid": 3, + "bleed_rate": 0, "vision_day": 10, "harvest": "mr_bones", "special_attacks": [ [ "scratch", 10 ], { "type": "bite", "cooldown": 5 } ], @@ -220,6 +229,7 @@ "description": "An uncanny shadow envelops this creature, as if light itself were too repulsed to touch it. All you can make out is the outline of a large, shambling cat.", "color": "light_gray", "vision_day": 3, + "bleed_rate": 50, "vision_night": 45, "flags": [ "SEES", @@ -250,6 +260,7 @@ "melee_skill": 4, "melee_dice": 3, "dodge": 3, + "bleed_rate": 50, "special_attacks": [ [ "ACID_BARF", 10 ] ], "death_function": [ "ACID", "NORMAL" ], "flags": [ @@ -287,6 +298,7 @@ "armor_bash": 10, "armor_cut": 10, "armor_bullet": 8, + "bleed_rate": 50, "vision_night": 6, "special_attacks": [ [ "SMASH", 30 ], [ "GRAB", 7 ] ], "flags": [ @@ -321,6 +333,7 @@ "armor_bash": 8, "armor_cut": 8, "armor_bullet": 6, + "bleed_rate": 0, "vision_night": 7, "harvest": "zombie_thorny", "attack_effs": [ { "id": "paralyzepoison", "duration": 33 } ], diff --git a/data/json/monsters/zed-animal.json b/data/json/monsters/zed-animal.json index 1e0dcc041a0fe..ed99674f551d9 100644 --- a/data/json/monsters/zed-animal.json +++ b/data/json/monsters/zed-animal.json @@ -118,6 +118,7 @@ "melee_dice_sides": 4, "melee_cut": 2, "dodge": 1, + "bleed_rate": 50, "vision_day": 30, "vision_night": 4, "harvest": "zombie", diff --git a/data/json/monsters/zed-pupating.json b/data/json/monsters/zed-pupating.json index 91b0641dd6b59..720b425073b94 100644 --- a/data/json/monsters/zed-pupating.json +++ b/data/json/monsters/zed-pupating.json @@ -9,6 +9,7 @@ "armor_bash": 7, "armor_cut": 5, "armor_bullet": 5, + "bleed_rate": 50, "special_attacks": [ { "type": "bite", "cooldown": 3 } ], "regenerates": 10, "extend": { "flags": [ "SLUDGETRAIL", "SLUDGEPROOF" ] } @@ -40,6 +41,7 @@ "armor_bash": 8, "armor_cut": 6, "armor_bullet": 6, + "bleed_rate": 50, "special_attacks": [ { "type": "bite", "cooldown": 3 } ], "regenerates": 10, "extend": { "flags": [ "SLUDGETRAIL", "SLUDGEPROOF" ] } @@ -212,6 +214,7 @@ "armor_bullet": 6, "special_attacks": [ { "type": "bite", "cooldown": 3 } ], "regenerates": 5, + "bleed_rate": 0, "vision_day": 8, "vision_night": 15, "extend": { "flags": [ "SLUDGETRAIL", "SLUDGEPROOF", "NIGHT_INVISIBILITY" ] } diff --git a/data/json/monsters/zed-winged.json b/data/json/monsters/zed-winged.json index 8c7c26b093cd2..a3486fa0b58dc 100644 --- a/data/json/monsters/zed-winged.json +++ b/data/json/monsters/zed-winged.json @@ -20,6 +20,7 @@ "melee_dice": 2, "melee_dice_sides": 2, "melee_cut": 0, + "bleed_rate": 50, "vision_night": 3, "harvest": "zombie", "special_attacks": [ @@ -73,6 +74,7 @@ "armor_bash": 2, "armor_cut": 2, "armor_bullet": 2, + "bleed_rate": 0, "vision_night": 7, "harvest": "zombie", "special_attacks": [ diff --git a/data/json/monsters/zed_acid.json b/data/json/monsters/zed_acid.json index 328abbac67496..f86a90c6a635d 100644 --- a/data/json/monsters/zed_acid.json +++ b/data/json/monsters/zed_acid.json @@ -73,6 +73,7 @@ "armor_cut": 2, "armor_bullet": 2, "armor_stab": 12, + "bleed_rate": 50, "vision_night": 3, "luminance": 0, "harvest": "zombie", @@ -135,6 +136,7 @@ "melee_dice_sides": 6, "melee_cut": 0, "dodge": 1, + "bleed_rate": 50, "vision_night": 3, "harvest": "zombie", "special_attacks": [ [ "ACID", 20 ] ], @@ -272,6 +274,7 @@ "armor_bullet": 3, "vision_night": 1 }, + "bleed_rate": 50, "proportional": { "hp": 1.8, "speed": 1.3, "volume": 1.4, "weigth": 1.1 }, "special_when_hit": [ "ACIDSPLASH", 100 ] } diff --git a/data/json/monsters/zed_burned.json b/data/json/monsters/zed_burned.json index a5e022bafe5b7..6f94b14a48ae6 100644 --- a/data/json/monsters/zed_burned.json +++ b/data/json/monsters/zed_burned.json @@ -26,6 +26,7 @@ "armor_bullet": 4, "armor_acid": 3, "armor_fire": 15, + "bleed_rate": 0, "vision_day": 10, "vision_night": 3, "harvest": "zombie", @@ -73,6 +74,7 @@ "armor_bullet": 10, "armor_acid": 5, "armor_fire": 15, + "bleed_rate": 0, "vision_day": 10, "vision_night": 3, "harvest": "zombie", @@ -107,6 +109,7 @@ "armor_bullet": 7, "armor_acid": 3, "armor_fire": 15, + "bleed_rate": 0, "vision_day": 10, "vision_night": 3, "harvest": "zombie", diff --git a/data/json/monsters/zed_children.json b/data/json/monsters/zed_children.json index 2bbfcb29dc874..575db8b2af31c 100644 --- a/data/json/monsters/zed_children.json +++ b/data/json/monsters/zed_children.json @@ -21,6 +21,7 @@ "melee_dice_sides": 4, "melee_cut": 2, "dodge": 3, + "bleed_rate": 50, "harvest": "zombie", "vision_day": 30, "vision_night": 3, @@ -92,6 +93,7 @@ "melee_dice_sides": 2, "melee_cut": 1, "dodge": 1, + "bleed_rate": 50, "vision_day": 10, "vision_night": 10, "harvest": "zombie", @@ -125,6 +127,7 @@ "melee_dice": 2, "melee_dice_sides": 2, "melee_cut": 1, + "bleed_rate": 50, "dodge": 1, "vision_day": 30, "vision_night": 5, @@ -160,6 +163,7 @@ "melee_cut": 2, "dodge": 1, "armor_bash": 1, + "bleed_rate": 50, "vision_day": 30, "vision_night": 5, "harvest": "zombie", @@ -193,6 +197,7 @@ "melee_dice_sides": 4, "melee_cut": 3, "dodge": 2, + "bleed_rate": 50, "vision_day": 10, "vision_night": 10, "harvest": "zombie", @@ -229,6 +234,7 @@ "dodge": 2, "armor_cut": 5, "armor_bullet": 4, + "bleed_rate": 50, "vision_day": 30, "vision_night": 5, "harvest": "zombie", diff --git a/data/json/monsters/zed_electric.json b/data/json/monsters/zed_electric.json index 03da33c0eff64..efa0f204ac83e 100644 --- a/data/json/monsters/zed_electric.json +++ b/data/json/monsters/zed_electric.json @@ -25,6 +25,7 @@ "armor_bash": 3, "armor_cut": 8, "armor_bullet": 6, + "bleed_rate": 0, "vision_night": 3, "luminance": 16, "harvest": "zombie", @@ -72,6 +73,7 @@ "melee_damage": [ { "damage_type": "electric", "amount": 8 } ], "melee_cut": 0, "dodge": 2, + "bleed_rate": 50, "luminance": 8, "harvest": "zombie", "special_attacks": [ [ "SHOCKSTORM", 25 ] ], @@ -118,6 +120,7 @@ "melee_skill": 5, "melee_dice": 1, "melee_dice_sides": 2, + "bleed_rate": 0, "//2": "melee damage is quite weak since the shockfield around it is its most dangerous function", "melee_damage": [ { "damage_type": "electric", "amount": 6 } ], "vision_night": 3, diff --git a/data/json/monsters/zed_explosive.json b/data/json/monsters/zed_explosive.json index 47f11eda5b05e..766d6b5072e79 100644 --- a/data/json/monsters/zed_explosive.json +++ b/data/json/monsters/zed_explosive.json @@ -70,6 +70,7 @@ "armor_bash": 5, "armor_cut": 5, "armor_bullet": 4, + "bleed_rate": 50, "vision_night": 3, "harvest": "zombie", "fungalize_into": "mon_boomer_fungus", diff --git a/data/json/monsters/zed_ferrous.json b/data/json/monsters/zed_ferrous.json index 7ef920f5c26ff..7daa684791f61 100644 --- a/data/json/monsters/zed_ferrous.json +++ b/data/json/monsters/zed_ferrous.json @@ -69,6 +69,7 @@ "armor_cut": 8, "armor_bullet": 8, "armor_stab": 8, + "bleed_rate": 50, "vision_night": 3, "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "GRAB", 7 ], [ "scratch", 20 ] ], @@ -118,6 +119,7 @@ "armor_cut": 15, "armor_bullet": 15, "armor_stab": 15, + "bleed_rate": 0, "vision_night": 3, "luminance": 0, "harvest": "zombie", @@ -163,6 +165,7 @@ "melee_dice_sides": 6, "melee_cut": 12, "dodge": 1, + "bleed_rate": 0, "vision_night": 3, "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "GRAB", 7 ], [ "scratch", 20 ], [ "impale", 25 ] ], @@ -210,6 +213,7 @@ "melee_dice": 3, "melee_dice_sides": 8, "melee_cut": 2, + "bleed_rate": 0, "vision_day": 14, "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "GRAB", 7 ], [ "scratch", 20 ] ], diff --git a/data/json/monsters/zed_fusion.json b/data/json/monsters/zed_fusion.json index 65ce920c03cea..c24ca3f68fc9e 100644 --- a/data/json/monsters/zed_fusion.json +++ b/data/json/monsters/zed_fusion.json @@ -103,6 +103,7 @@ "armor_bash": 10, "armor_cut": 20, "armor_bullet": 16, + "bleed_rate": 0, "harvest": "exempt", "special_attacks": [ [ "FLESH_TENDRIL", 1 ] ], "death_function": [ "GAS" ], @@ -163,6 +164,7 @@ "armor_bash": 6, "armor_cut": 6, "armor_bullet": 5, + "bleed_rate": 50, "vision_night": 50, "harvest": "exempt", "special_attacks": [ { "type": "leap", "cooldown": 5, "max_range": 5, "allow_no_target": true }, [ "scratch", 5 ] ], @@ -195,6 +197,7 @@ "armor_bash": 6, "armor_cut": 6, "armor_bullet": 5, + "bleed_rate": 50, "harvest": "exempt", "starting_ammo": { "barb_paralysis": 100 }, "special_attacks": [ @@ -236,6 +239,7 @@ "armor_bash": 2, "armor_cut": 10, "armor_bullet": 10, + "bleed_rate": 50, "vision_day": 1, "special_attacks": [ { "type": "leap", "cooldown": 5, "max_range": 3, "allow_no_target": true }, [ "scratch", 5 ] ], "death_function": [ "GAS" ], @@ -265,6 +269,7 @@ "armor_bash": 6, "armor_cut": 10, "armor_bullet": 6, + "bleed_rate": 50, "vision_day": 2, "vision_night": 2, "harvest": "exempt", @@ -293,6 +298,7 @@ "armor_bash": 25, "armor_cut": 25, "armor_bullet": 20, + "bleed_rate": 50, "harvest": "exempt", "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "IMMOBILE", "WARM", "POISON", "IMMOBILE", "NO_BREATHE", "FILTHY" ] @@ -318,6 +324,7 @@ "armor_bash": 15, "armor_cut": 15, "armor_bullet": 10, + "bleed_rate": 0, "harvest": "exempt", "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "IMMOBILE", "WARM", "POISON", "IMMOBILE", "NO_BREATHE", "FILTHY" ] diff --git a/data/json/monsters/zed_lab.json b/data/json/monsters/zed_lab.json index 2022c945d063e..2ecba334e2048 100644 --- a/data/json/monsters/zed_lab.json +++ b/data/json/monsters/zed_lab.json @@ -156,6 +156,7 @@ "armor_bash": 40, "armor_cut": 40, "armor_bullet": 30, + "bleed_rate": 50, "vision_night": 5, "luminance": 16, "special_attacks": [ diff --git a/data/json/monsters/zed_misc.json b/data/json/monsters/zed_misc.json index afd33a3c5ed05..615eb9bd17c66 100644 --- a/data/json/monsters/zed_misc.json +++ b/data/json/monsters/zed_misc.json @@ -23,6 +23,7 @@ "armor_bash": 12, "armor_cut": 2, "armor_bullet": 1, + "bleed_rate": 0, "vision_night": 7, "harvest": "zombie", "special_attacks": [ @@ -109,6 +110,7 @@ "armor_bash": 5, "armor_cut": 2, "armor_bullet": 2, + "bleed_rate": 0, "vision_day": 15, "vision_night": 3, "harvest": "zombie", @@ -215,6 +217,7 @@ "armor_bash": 4, "armor_cut": 6, "armor_bullet": 5, + "bleed_rate": 50, "vision_night": 4, "harvest": "zombie", "special_attacks": [ [ "SMASH", 30 ], [ "GRAB", 7 ] ], @@ -266,6 +269,7 @@ "armor_cut": 14, "armor_bullet": 8, "armor_stab": 8, + "bleed_rate": 50, "vision_night": 3, "harvest": "zombie", "special_attacks": [ [ "SMASH", 30 ], [ "BIO_OP_TAKEDOWN", 20 ], [ "RANGED_PULL", 20 ], [ "GRAB_DRAG", 10 ] ], @@ -315,6 +319,7 @@ "armor_bash": 8, "armor_cut": 5, "armor_bullet": 4, + "bleed_rate": 0, "vision_day": 5, "vision_night": 40, "harvest": "zombie", @@ -361,6 +366,7 @@ "melee_dice": 2, "melee_dice_sides": 4, "melee_cut": 0, + "bleed_rate": 50, "vision_day": 7, "vision_night": 4, "harvest": "zombie", @@ -408,6 +414,7 @@ "melee_dice_sides": 4, "melee_cut": 0, "dodge": 1, + "bleed_rate": 50, "vision_day": 30, "vision_night": 3, "harvest": "zombie", @@ -455,6 +462,7 @@ "melee_dice_sides": 5, "melee_cut": 0, "dodge": 2, + "bleed_rate": 50, "vision_day": 30, "vision_night": 5, "harvest": "zombie", @@ -505,6 +513,7 @@ "armor_cut": 4, "armor_bullet": 10, "armor_stab": 10, + "bleed_rate": 0, "vision_day": 30, "vision_night": 3, "harvest": "zombie", @@ -537,6 +546,7 @@ "armor_bash": 8, "armor_cut": 12, "armor_bullet": 10, + "bleed_rate": 0, "vision_day": 83, "vision_night": 4, "harvest": "zombie", @@ -582,6 +592,7 @@ "melee_dice_sides": 4, "melee_cut": 2, "dodge": 3, + "bleed_rate": 50, "vision_night": 5, "harvest": "zombie", "special_attacks": [ @@ -658,6 +669,7 @@ "armor_bash": 8, "armor_cut": 10, "armor_bullet": 8, + "bleed_rate": 0, "vision_day": 25, "vision_night": 5, "harvest": "zombie", @@ -720,6 +732,7 @@ "armor_bash": 2, "armor_cut": 2, "armor_bullet": 2, + "bleed_rate": 0, "vision_day": 50, "vision_night": 5, "harvest": "zombie", @@ -768,6 +781,7 @@ "melee_dice_sides": 6, "melee_cut": 2, "dodge": 2, + "bleed_rate": 0, "vision_day": 50, "vision_night": 5, "harvest": "zombie", @@ -867,6 +881,7 @@ "armor_bash": 5, "armor_cut": 5, "armor_bullet": 4, + "bleed_rate": 0, "vision_day": 45, "vision_night": 15, "harvest": "zombie", @@ -908,6 +923,7 @@ "melee_dice_sides": 4, "melee_cut": 5, "dodge": 2, + "bleed_rate": 50, "vision_day": 50, "vision_night": 8, "harvest": "zombie", @@ -1066,6 +1082,7 @@ "armor_bash": 5, "armor_cut": 3, "armor_bullet": 2, + "bleed_rate": 0, "vision_day": 25, "vision_night": 5, "harvest": "zombie", @@ -1112,6 +1129,7 @@ "melee_cut": 2, "dodge": 4, "armor_fire": 5, + "bleed_rate": 50, "vision_day": 50, "vision_night": 3, "harvest": "exempt", @@ -1160,6 +1178,7 @@ "armor_cut": 8, "armor_stab": 8, "armor_bullet": 10, + "bleed_rate": 50, "dodge": 7, "armor_fire": 5, "vision_day": 30, @@ -1383,6 +1402,7 @@ "armor_bash": 2, "armor_cut": 4, "armor_bullet": 3, + "bleed_rate": 50, "vision_night": 5, "harvest": "zombie_thorny", "attack_effs": [ { "id": "paralyzepoison", "duration": 33 } ], diff --git a/data/json/monsters/zed_radiation.json b/data/json/monsters/zed_radiation.json index 1941df0cf89bf..2e24ba85692d2 100644 --- a/data/json/monsters/zed_radiation.json +++ b/data/json/monsters/zed_radiation.json @@ -24,6 +24,7 @@ "armor_bash": 6, "armor_cut": 6, "armor_bullet": 5, + "bleed_rate": 0, "vision_day": 50, "vision_night": 3, "harvest": "zombie", @@ -57,6 +58,7 @@ "armor_bash": 4, "armor_cut": 4, "armor_bullet": 3, + "bleed_rate": 50, "vision_day": 50, "vision_night": 3, "harvest": "zombie", @@ -90,6 +92,7 @@ "armor_bash": 5, "armor_cut": 5, "armor_bullet": 4, + "bleed_rate": 50, "vision_day": 50, "vision_night": 3, "luminance": 8, @@ -124,6 +127,7 @@ "armor_bash": 6, "armor_cut": 6, "armor_bullet": 5, + "bleed_rate": 50, "vision_day": 50, "vision_night": 3, "luminance": 16, @@ -158,6 +162,7 @@ "armor_bash": 8, "armor_cut": 8, "armor_bullet": 6, + "bleed_rate": 50, "vision_day": 50, "vision_night": 3, "luminance": 32, diff --git a/data/json/monsters/zed_skeletal.json b/data/json/monsters/zed_skeletal.json index 8d2fa25893af5..e5a7aaac6c16a 100644 --- a/data/json/monsters/zed_skeletal.json +++ b/data/json/monsters/zed_skeletal.json @@ -25,6 +25,7 @@ "armor_bullet": 24, "armor_stab": 30, "armor_acid": 3, + "bleed_rate": 50, "vision_day": 30, "vision_night": 3, "harvest": "mr_bones", @@ -61,6 +62,7 @@ "armor_bullet": 30, "armor_bash": 12, "armor_acid": 1, + "bleed_rate": 0, "vision_day": 35, "vision_night": 3, "harvest": "mr_bones", @@ -101,6 +103,7 @@ "armor_bullet": 30, "armor_stab": 30, "armor_acid": 3, + "bleed_rate": 0, "vision_day": 30, "vision_night": 3, "harvest": "mr_bones", @@ -134,6 +137,7 @@ "armor_bash": 20, "armor_cut": 45, "armor_bullet": 36, + "bleed_rate": 0, "vision_day": 50, "vision_night": 4, "harvest": "mr_bones", diff --git a/data/json/monsters/zed_soldiers.json b/data/json/monsters/zed_soldiers.json index 601d3c93b765b..b4b9e30c3a5d3 100644 --- a/data/json/monsters/zed_soldiers.json +++ b/data/json/monsters/zed_soldiers.json @@ -62,6 +62,7 @@ "armor_bash": 12, "armor_cut": 25, "armor_bullet": 20, + "bleed_rate": 50, "vision_day": 30, "vision_night": 35, "harvest": "zombie", @@ -98,6 +99,7 @@ "description": "Fragments of visible uniform hint that this monstrosity was once a soldier. Anything human is invisible, hidden inside a sheath of living shadow. It moves with preternatural fluidity and grace.", "copy-from": "mon_zombie_soldier_blackops_1", "looks_like": "mon_zombie_soldier_blackops_1", + "bleed_rate": 0, "relative": { "hp": 20, "speed": 10, "melee_skill": 1, "dodge": 1, "vision_night": 15 }, "delete": { "upgrades": { "half_life": 38, "into": "mon_zombie_soldier_blackops_2" } }, "extend": { @@ -120,6 +122,7 @@ "copy-from": "mon_zombie_soldier", "looks_like": "mon_zombie_soldier", "diff": 20, + "bleed_rate": 50, "delete": { "upgrades": { "half_life": 28, "into_group": "GROUP_SOLDIER_UPGRADE" } }, "relative": { "hp": 20, "speed": 10, "melee_skill": 1, "vision_day": 10, "vision_night": 10 }, "extend": { @@ -150,6 +153,7 @@ "copy-from": "mon_zombie_soldier", "looks_like": "mon_zombie_soldier", "diff": 20, + "bleed_rate": 50, "delete": { "upgrades": { "half_life": 28, "into_group": "GROUP_SOLDIER_UPGRADE" } }, "relative": { "hp": 40, "speed": -10, "melee_skill": 2, "armor_bash": 5 }, "extend": { @@ -199,6 +203,7 @@ "armor_bash": 20, "armor_cut": 30, "armor_bullet": 24, + "bleed_rate": 50, "vision_day": 30, "vision_night": 5, "harvest": "zombie_kevlar", @@ -238,6 +243,7 @@ "armor_bash": 30, "armor_cut": 50, "armor_bullet": 40, + "bleed_rate": 0, "vision_day": 50, "vision_night": 10, "harvest": "zombie_kevlar", @@ -376,6 +382,7 @@ "armor_bullet": 51, "armor_acid": 20, "armor_fire": 20, + "bleed_rate": 0, "vision_day": 30, "vision_night": 3, "harvest": "zombie", diff --git a/doc/MONSTERS.md b/doc/MONSTERS.md index ad1f898c68274..71e5a7feacaee 100644 --- a/doc/MONSTERS.md +++ b/doc/MONSTERS.md @@ -328,6 +328,11 @@ Amount of light passively output by monster. Ranges from 0 to 10. Monster hit points. +## "bleed_rate" +(integer, optional) + +Percent multiplier on all bleed effects' duration applied to the monster. Values below the default of 100 mean a resistance to bleed, values above 100 make the monster bleed longer and more intensive. 0 translates to bleed immunity. + ## "death_drops" (string or item group, optional) diff --git a/src/character.h b/src/character.h index 5b67d1ae51002..4c07ddd7d7002 100644 --- a/src/character.h +++ b/src/character.h @@ -1864,7 +1864,7 @@ class Character : public Creature, public visitable bool cast_spell( spell &sp, bool fake_spell, cata::optional target ); void make_bleed( const effect_source &source, const bodypart_id &bp, time_duration duration, - int intensity = 1, bool permanent = false, bool force = false, bool defferred = false ); + int intensity = 1, bool permanent = false, bool force = false, bool defferred = false ) override; /** Calls Creature::normalize() * nulls out the player's weapon diff --git a/src/creature.cpp b/src/creature.cpp index 380a482f6e94d..14f2914a23351 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -57,11 +57,9 @@ struct mutation_branch; static const anatomy_id anatomy_human_anatomy( "human_anatomy" ); -static const efftype_id effect_bleed( "bleed" ); static const efftype_id effect_blind( "blind" ); static const efftype_id effect_bounced( "bounced" ); static const efftype_id effect_downed( "downed" ); -static const efftype_id effect_dripping_mechanical_fluid( "dripping_mechanical_fluid" ); static const efftype_id effect_foamcrete_slow( "foamcrete_slow" ); static const efftype_id effect_lying_down( "lying_down" ); static const efftype_id effect_no_sight( "no_sight" ); @@ -1068,13 +1066,7 @@ void Creature::deal_damage_handle_type( const effect_source &source, const damag case damage_type::STAB: case damage_type::BULLET: // these are bleed inducing damage types - if( is_avatar() || is_npc() ) { - as_character()->make_bleed( source, bp, 1_minutes * rng( 1, adjusted_damage ) ); - } else if( in_species( species_ROBOT ) ) { - add_effect( source, effect_dripping_mechanical_fluid, 1_seconds * rng( 1, adjusted_damage ), bp ); - } else { - add_effect( source, effect_bleed, 1_minutes * rng( 1, adjusted_damage ), bp ); - } + make_bleed( source, bp, 1_minutes * rng( 1, adjusted_damage ) ); default: break; diff --git a/src/creature.h b/src/creature.h index 18277686792f7..42224344a9c10 100644 --- a/src/creature.h +++ b/src/creature.h @@ -438,6 +438,11 @@ class Creature : public location, public viewer // accrue? mutates damage and pain virtual void deal_damage_handle_type( const effect_source &source, const damage_unit &du, bodypart_id bp, int &damage, int &pain ); + + // Pass handling bleed to creature/character + virtual void make_bleed( const effect_source &source, const bodypart_id &bp, time_duration duration, + int intensity = 1, bool permanent = false, bool force = false, bool defferred = false ) = 0; + // directly decrements the damage. ONLY handles damage, doesn't // increase pain, apply effects, etc virtual void apply_damage( Creature *source, bodypart_id bp, int amount, diff --git a/src/monattack.cpp b/src/monattack.cpp index 7b8af4eb154e8..35028297ac63f 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -4471,12 +4471,7 @@ bool mattack::longswipe( monster *z ) _( "The %1$s slashes at your neck, cutting your throat for %2$d damage!" ), _( "The %1$s slashes at 's neck, cutting their throat for %2$d damage!" ), z->name(), dam ); - if( target->is_player() || target->is_npc() ) { - target->as_character()->make_bleed( effect_source( z ), bodypart_id( "head" ), 15_minutes ); - } else { - target->add_effect( effect_source( z ), effect_bleed, 15_minutes, bodypart_id( "head" ) ); - } - + target->make_bleed( effect_source( z ), bodypart_id( "head" ), 15_minutes ); } else { target->add_msg_player_or_npc( _( "The %1$s slashes at your %2$s, but glances off your armor!" ), _( "The %1$s slashes at 's %2$s, but glances off armor!" ), @@ -5291,7 +5286,7 @@ bool mattack::bio_op_impale( monster *z ) // Handle mons earlier - less to check for target->deal_damage( z, bodypart_id( "torso" ), damage_instance( damage_type::STAB, dam ) ); if( do_bleed ) { - target->add_effect( effect_bleed, rng( 3_minutes, 10_minutes ), bodypart_id( "torso" ), true ); + target->make_bleed( effect_source( z ), bodypart_id( "torso" ), rng( 3_minutes, 10_minutes ) ); } if( seen ) { add_msg( _( "The %1$s impales %2$s!" ), z->name(), target->disp_name() ); @@ -5312,7 +5307,7 @@ bool mattack::bio_op_impale( monster *z ) target->add_msg_if_player( m_bad, _( "and deals %d damage!" ), t_dam ); if( do_bleed ) { - target->as_character()->make_bleed( effect_source( z ), hit, rng( 75_turns, 125_turns ), 1, true ); + target->make_bleed( effect_source( z ), hit, rng( 75_turns, 125_turns ) ); } } else { target->add_msg_player_or_npc( _( "but fails to penetrate your armor!" ), diff --git a/src/monster.cpp b/src/monster.cpp index b2dc062840bce..c3d4079179ef3 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -1376,7 +1376,7 @@ bool monster::is_immune_effect( const efftype_id &effect ) const } if( effect == effect_bleed ) { - return type->bloodType() == fd_null; + return ( type->bloodType() == fd_null || type->bleed_rate == 0 ); } if( effect == effect_venom_dmg || @@ -1441,6 +1441,21 @@ bool monster::is_immune_damage( const damage_type dt ) const } } +void monster::make_bleed( const effect_source &source, const bodypart_id &bp, + time_duration duration, int intensity, bool permanent, bool force, bool defferred ) +{ + if( type->bleed_rate == 0 ) { + return; + } + + duration = ( duration * type->bleed_rate ) / 100; + if( type->in_species( species_ROBOT ) ) { + add_effect( source, effect_dripping_mechanical_fluid, duration, bp ); + } else { + add_effect( source, effect_bleed, duration, bp, permanent, intensity, force, defferred ); + } +} + bool monster::is_dead_state() const { return hp <= 0; diff --git a/src/monster.h b/src/monster.h index 9eaab5efe7168..d497b57d393c9 100644 --- a/src/monster.h +++ b/src/monster.h @@ -315,6 +315,9 @@ class monster : public Creature bool is_immune_effect( const efftype_id & ) const override; bool is_immune_damage( damage_type ) const override; + void make_bleed( const effect_source &source, const bodypart_id &bp, time_duration duration, + int intensity = 1, bool permanent = false, bool force = false, bool defferred = false ) override; + void absorb_hit( const bodypart_id &bp, damage_instance &dam ) override; bool block_hit( Creature *source, bodypart_id &bp_hit, damage_instance &d ) override; bool melee_attack( Creature &target ); diff --git a/src/monstergenerator.cpp b/src/monstergenerator.cpp index 92cef866b1c4f..1c760e4f04532 100644 --- a/src/monstergenerator.cpp +++ b/src/monstergenerator.cpp @@ -776,6 +776,8 @@ void mtype::load( const JsonObject &jo, const std::string &src ) assign( jo, "armor_acid", armor_acid, strict, 0 ); assign( jo, "armor_fire", armor_fire, strict, 0 ); + optional( jo, was_loaded, "bleed_rate", bleed_rate, 100 ); + assign( jo, "vision_day", vision_day, strict, 0 ); assign( jo, "vision_night", vision_night, strict, 0 ); diff --git a/src/mtype.h b/src/mtype.h index 96392f9002e52..ac9b6e7dbba7b 100644 --- a/src/mtype.h +++ b/src/mtype.h @@ -286,6 +286,9 @@ struct mtype { int armor_acid = -1; /** innate armor vs. acid */ int armor_fire = -1; /** innate armor vs. fire */ + // Bleed rate in percent, 0 makes the monster immune to bleeding + int bleed_rate = 100; + // Vision range is linearly scaled depending on lighting conditions int vision_day = 40; /** vision range in bright light */ int vision_night = 1; /** vision range in total darkness */ diff --git a/tests/creature_effect_test.cpp b/tests/creature_effect_test.cpp index fa15b090bec9f..4ba584f555609 100644 --- a/tests/creature_effect_test.cpp +++ b/tests/creature_effect_test.cpp @@ -455,9 +455,10 @@ TEST_CASE( "monster is_immune_effect", "[creature][monster][effect][immune]" ) fungaloid.clear_effects(); REQUIRE_FALSE( fungaloid.made_of_any( Creature::cmat_flesh ) ); REQUIRE( fungaloid.type->in_species( species_FUNGUS ) ); + REQUIRE( fungaloid.type->bleed_rate == 0 ); - THEN( "they bleed plant sap for now" ) { - CHECK_FALSE( fungaloid.is_immune_effect( effect_bleed ) ); + THEN( "their zero bleed rate makes them immune to bleed" ) { + CHECK( fungaloid.is_immune_effect( effect_bleed ) ); } THEN( "they can't be poisoned" ) { From efcbdcc771424505b88cfa4c52c640eca08cf810 Mon Sep 17 00:00:00 2001 From: Ilya Agafonov Date: Wed, 7 Jul 2021 07:22:49 +0500 Subject: [PATCH 029/116] Use normal distribution to generate random height in new character screen (#49270) * fix random height * use Character::randomize_height * use clamp() for limit the randomness, as @pehamm suggested * astyle fix * use std::round instead of round Co-authored-by: pehamm <76401419+pehamm@users.noreply.github.com> * learning c++ in 21 days Co-authored-by: John Bytheway <52664+jbytheway@users.noreply.github.com> * int instead of double * use one distribution * changed normal_roll to 168.35 mean, 15.5 sd Co-authored-by: pehamm <76401419+pehamm@users.noreply.github.com> Co-authored-by: John Bytheway <52664+jbytheway@users.noreply.github.com> --- src/character.cpp | 9 +++++++++ src/character.h | 2 ++ src/newcharacter.cpp | 5 ++--- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/character.cpp b/src/character.cpp index bec02bfbbbb29..98adfc776b085 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -504,6 +504,15 @@ character_id Character::getID() const return this->id; } +void Character::randomize_height() +{ + // Height distribution data is taken from CDC distributes statistics for the US population + // https://github.com/CleverRaven/Cataclysm-DDA/pull/49270#issuecomment-861339732 + const int x = std::round( normal_roll( 168.35, 15.50 ) ); + // clamping to 145..200 because this is the bounds of what player can set, see newplayer.cpp + init_height = clamp( x, 145, 200 ); +} + void Character::randomize_blood() { // Blood type distribution data is taken from this study on blood types of diff --git a/src/character.h b/src/character.h index 4c07ddd7d7002..30e694d4b8e13 100644 --- a/src/character.h +++ b/src/character.h @@ -2136,6 +2136,8 @@ class Character : public Creature, public visitable std::string height_string() const; // returns the height of the player character in cm int height() const; + // Randomizes characters' height + void randomize_height(); // returns bodyweight of the Character units::mass bodyweight() const; // returns total weight of installed bionics diff --git a/src/newcharacter.cpp b/src/newcharacter.cpp index d53e725ce3d19..c8e80598dae39 100644 --- a/src/newcharacter.cpp +++ b/src/newcharacter.cpp @@ -199,8 +199,7 @@ void avatar::randomize( const bool random_scenario, points_left &points, bool pl } // if adjusting min and max age from 16 and 55, make sure to see set_description() init_age = rng( 16, 55 ); - // if adjusting min and max height from 145 and 200, make sure to see set_description() - init_height = rng( 145, 200 ); + randomize_height(); randomize_blood(); bool cities_enabled = world_generator->active_world->WORLD_OPTIONS["CITY_SIZE"].getValue() != "0"; if( random_scenario ) { @@ -3306,7 +3305,7 @@ tab_direction set_description( avatar &you, const bool allow_reroll, no_name_entered = you.name.empty(); } you.set_base_age( rng( 16, 55 ) ); - you.set_base_height( rng( 145, 200 ) ); + you.randomize_height(); you.randomize_blood(); } else if( action == "CHANGE_GENDER" ) { you.male = !you.male; From 92cfcaca2e437a7a02d138b558c715b3de69cf87 Mon Sep 17 00:00:00 2001 From: faefux <49350286+faefux@users.noreply.github.com> Date: Wed, 7 Jul 2021 03:27:12 +0100 Subject: [PATCH 030/116] Changed time and energy to create a washboard. (#49613) * Lengthened time to make washboard * Changed to 'MODERATE_EXERSIZE' --- data/json/recipes/tools/tools_hand.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/json/recipes/tools/tools_hand.json b/data/json/recipes/tools/tools_hand.json index a92e2e5837484..a45caf4df5388 100644 --- a/data/json/recipes/tools/tools_hand.json +++ b/data/json/recipes/tools/tools_hand.json @@ -1090,13 +1090,13 @@ }, { "type": "recipe", - "activity_level": "LIGHT_EXERCISE", + "activity_level": "MODERATE_EXERCISE", "result": "washboard", "category": "CC_OTHER", "subcategory": "CSC_OTHER_TOOLS", "skill_used": "fabrication", "difficulty": 1, - "time": "1 m", + "time": "25 m", "autolearn": true, "proficiencies": [ { "proficiency": "prof_carving" } ], "qualities": [ { "id": "CUT", "level": 1 } ], From 787139f58b11ca6725a66357113ce8d59cfb21bb Mon Sep 17 00:00:00 2001 From: curstwist <39442864+curstwist@users.noreply.github.com> Date: Tue, 6 Jul 2021 22:28:42 -0400 Subject: [PATCH 031/116] lab snippets for signs (#49607) * Create lab_signs.json * readability fix * Update lab_signs.json * changes from review --- data/json/snippets/lab_signs.json | 85 +++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 data/json/snippets/lab_signs.json diff --git a/data/json/snippets/lab_signs.json b/data/json/snippets/lab_signs.json new file mode 100644 index 0000000000000..3916f8526c360 --- /dev/null +++ b/data/json/snippets/lab_signs.json @@ -0,0 +1,85 @@ +[ + { + "type": "snippet", + "category": "lab_access_signage", + "//": "signage for the civilian areas (public).", + "text": [ + "***LAB***\nAuthorized Personnel Only", + "Restricted\nAccess\nArea", + "Be Prepared to present ID", + "No visitors beyond this point" + ] + }, + { + "type": "snippet", + "category": "lab_maintenance_signage", + "//": "signage for the maintenance areas (non-public).", + "text": [ + "Restricted\nAccess\nArea", + "Be Prepared to present ID", + "Keep hands free from machinery", + "STOP\nFor Your\nSafety", + "NOTICE\nSafety Glasses Required", + "DANGER\nKeep Hands Clear\nWhen Equipment\nIs Running" + ] + }, + { + "type": "snippet", + "category": "lab_security_signage", + "//": "signage for the civilian security areas (non-public).", + "text": [ + "Restricted\nAccess\nArea", + "Be Prepared to present ID", + "Keep guns holstered or locked up", + "Tasers Save Lives", + "STOP\nWhere's your gun?", + "NOTICE\nCheck in with your squad on the hour." + ] + }, + { + "type": "snippet", + "category": "lab_safety_snippet", + "//": "signage for research scientist levels (working lab areas).", + "text": [ + "Keep Equipment Clean and Hygenic", + "PPE Required", + "Biohazard", + "Do not look into laser with remaining eye", + "There have been\n[4]\ndays without a life-threatening workplace accident", + "Be Alert, Don't get Hurt!", + "Safety First\nWork Safely", + "THINK!\nDON'T CONTAMINATE!\nDon't store food in sample refrigerators!", + "Report ALL Accidents", + "Think!\nDo it the safe way.\nDo it the right way.\nDo it everyday.", + "3 causes of accidents are\nI didn't think\nI didn't see\nI didn't know", + "Think Safety First!", + "Not to be operated by fuckwits", + "Stokey the Chemist says:\n'Only YOU can prevent lab fires. Because you're the asshole who started the last three.'", + "Biohazard", + "Biohazard", + "Biohazard" + ] + }, + { + "type": "snippet", + "category": "lab_volunteer_snippet", + "//": "propaganda signage for the volunteer mutant level.", + "text": [ + "For Country\n For\n Mom", + "Report any unusual or new symptoms", + "Report any unusual or new manifestations", + " Thank You\n For\nYour Service", + " Remember:\nYou're our\n best hope", + "Go Boldly Into Your Future!", + "Metamorphosis Checks at 6:00, 12:00, 18:00", + "Bob palmed his midday dose.\nBob's in the infirmary now\nDon't be Bob: Take doses as advised.", + "Dream Journals\n Save\n Lives", + "Who is your spirit animal?", + "Embrace the Wonder\nEmbrace the Unknown", + "Your best self is yearning to break free!", + "Humans only have 5 senses", + "Find your spirit animal guide!\n Group meditation\n Wednesdays 13:00", + " Do Not\n Share\nMedications" + ] + } +] From 1855104556c1221e61b886e1d6964fbb33122929 Mon Sep 17 00:00:00 2001 From: Kanexan <51104434+Kanexan@users.noreply.github.com> Date: Tue, 6 Jul 2021 21:36:25 -0500 Subject: [PATCH 032/116] Lab rats and lab rat spawns (#49426) * Add lab rats, spawns * Re-linting * Re-re-linting. * Adding a missing space. * Update fear triggers, flags Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> * Remove redundant fears. Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> --- data/json/monstergroups/lab.json | 16 ++++++++++------ data/json/monsters/mammal.json | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/data/json/monstergroups/lab.json b/data/json/monstergroups/lab.json index b67cd2eb03c8d..5875a65b99ba8 100644 --- a/data/json/monstergroups/lab.json +++ b/data/json/monstergroups/lab.json @@ -20,7 +20,8 @@ { "monster": "mon_zombie_static", "freq": 50, "cost_multiplier": 3 }, { "monster": "mon_zombie_brute_shocker", "freq": 10, "cost_multiplier": 5 }, { "monster": "mon_zombie_hulk", "freq": 1, "cost_multiplier": 50 }, - { "monster": "mon_skeleton_hulk", "freq": 1, "cost_multiplier": 50 } + { "monster": "mon_skeleton_hulk", "freq": 1, "cost_multiplier": 50 }, + { "monster": "mon_lab_rat", "freq": 30, "cost_multiplier": 20, "pack_size": [ 4, 8 ] } ] }, { @@ -56,9 +57,10 @@ { "monster": "mon_zombie_armored", "freq": 5, "cost_multiplier": 5 }, { "monster": "mon_zombie_electric", "freq": 50, "cost_multiplier": 3 }, { "monster": "mon_zombie_necro", "freq": 15, "cost_multiplier": 15 }, - { "monster": "mon_zombie_brute_shocker", "freq": 10, "cost_multiplier": 5 } + { "monster": "mon_zombie_brute_shocker", "freq": 10, "cost_multiplier": 5 }, + { "monster": "mon_lab_rat", "freq": 30, "cost_multiplier": 20, "pack_size": [ 4, 8 ] } ], - "freq_total": 2592 + "freq_total": 2622 }, { "type": "monstergroup", @@ -92,9 +94,10 @@ { "monster": "mon_zombie_bio_op", "freq": 50, "cost_multiplier": 5 }, { "monster": "mon_zombie_bio_op2", "freq": 25, "cost_multiplier": 5, "starts": 1440 }, { "monster": "mon_zombie_armored", "freq": 5, "cost_multiplier": 5 }, - { "monster": "mon_zombie_brute_shocker", "freq": 5, "cost_multiplier": 5 } + { "monster": "mon_zombie_brute_shocker", "freq": 5, "cost_multiplier": 5 }, + { "monster": "mon_lab_rat", "freq": 50, "cost_multiplier": 20, "pack_size": [ 4, 8 ] } ], - "freq_total": 2589 + "freq_total": 2639 }, { "type": "monstergroup", @@ -179,7 +182,8 @@ { "monster": "mon_zombie_armored", "freq": 1, "cost_multiplier": 5 }, { "monster": "mon_zombie_electric", "freq": 10, "cost_multiplier": 3 }, { "monster": "mon_zombie_necro", "freq": 1, "cost_multiplier": 15 }, - { "monster": "mon_zombie_brute_shocker", "freq": 1, "cost_multiplier": 5 } + { "monster": "mon_zombie_brute_shocker", "freq": 1, "cost_multiplier": 5 }, + { "monster": "mon_lab_rat", "freq": 20, "cost_multiplier": 20, "pack_size": [ 2, 8 ] } ] } ] diff --git a/data/json/monsters/mammal.json b/data/json/monsters/mammal.json index f70942fe69945..dcf74bac048d7 100644 --- a/data/json/monsters/mammal.json +++ b/data/json/monsters/mammal.json @@ -162,6 +162,38 @@ "special_attacks": [ [ "EAT_FOOD", 120 ] ], "flags": [ "SEES", "SMELLS", "HEARS", "WARM", "SWIMS", "ANIMAL", "STUMBLES", "PATH_AVOID_DANGER_1" ] }, + { + "id": "mon_lab_rat", + "type": "MONSTER", + "name": { "str": "lab rat" }, + "description": "The albino Norway rat, an omnivorous rodent with sleek white fur and a long, rough tail. While its ancestors were harbingers of plague, these clever animals are omnipresent in modern biomedical research.", + "default_faction": "rat", + "bodytype": "pig", + "categories": [ "WILDLIFE" ], + "species": [ "MAMMAL" ], + "volume": "320 ml", + "weight": "320 g", + "hp": 6, + "speed": 100, + "material": [ "flesh" ], + "symbol": "r", + "color": "white", + "aggression": -15, + "morale": -50, + "melee_skill": 3, + "melee_dice": 1, + "melee_dice_sides": 1, + "melee_cut": 1, + "dodge": 2, + "vision_day": 30, + "vision_night": 15, + "harvest": "mammal_tiny", + "path_settings": { "max_dist": 10 }, + "fear_triggers": [ "PLAYER_CLOSE", "SOUND" ], + "death_function": [ "NORMAL" ], + "special_attacks": [ [ "EAT_FOOD", 120 ] ], + "flags": [ "SEES", "SMELLS", "HEARS", "KEENNOSE", "WARM", "SWIMS", "ANIMAL", "PATH_AVOID_DANGER_1" ] + }, { "id": "mon_boar_wild_piglet", "type": "MONSTER", From 8b2485a30f84e51db244b980a1ed10a3477fe9c3 Mon Sep 17 00:00:00 2001 From: krulunio <49376929+krulunio@users.noreply.github.com> Date: Wed, 7 Jul 2021 04:39:21 +0200 Subject: [PATCH 033/116] Add military helipad basecamp (#49353) * Add power tools Creates and adds fake power tools to various furniture * Add fake_oven * Add fake_water_purifier and update clean water recipe * Add military helipad basecamp * Linting Co-authored-by: I-am-Erk <45136638+I-am-Erk@users.noreply.github.com> --- .../fbmc_helipad/fbmc_helipad_common.json | 79 +++++++++ .../fbmc_helipad/fbmc_helipad_garage.json | 14 ++ .../overmap_terrain_faction_base.json | 7 + .../recipe_modular_helipad_common.json | 151 ++++++++++++++++++ .../recipe_modular_helipad_garage.json | 25 +++ .../json/recipes/basecamps/recipe_groups.json | 6 + 6 files changed, 282 insertions(+) create mode 100644 data/json/mapgen/basecamps/fbmc_helipad/fbmc_helipad_common.json create mode 100644 data/json/mapgen/basecamps/fbmc_helipad/fbmc_helipad_garage.json create mode 100644 data/json/recipes/basecamps/fbmc_helipad/recipe_modular_helipad_common.json create mode 100644 data/json/recipes/basecamps/fbmc_helipad/recipe_modular_helipad_garage.json diff --git a/data/json/mapgen/basecamps/fbmc_helipad/fbmc_helipad_common.json b/data/json/mapgen/basecamps/fbmc_helipad/fbmc_helipad_common.json new file mode 100644 index 0000000000000..a09b2389814fd --- /dev/null +++ b/data/json/mapgen/basecamps/fbmc_helipad/fbmc_helipad_common.json @@ -0,0 +1,79 @@ +[ + { + "type": "mapgen", + "update_mapgen_id": "fbmc_helipad_0", + "method": "json", + "object": { "set": [ { "point": "furniture", "id": "f_bulletin", "x": 15, "y": 15 } ] } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_helipad_barricade_wood", + "method": "json", + "object": { + "set": [ + { "point": "terrain", "id": "t_wall_wood", "x": 5, "y": 16 }, + { "point": "terrain", "id": "t_wall_wood", "x": 8, "y": 16 }, + { "point": "terrain", "id": "t_wall_wood", "x": 10, "y": 16 }, + { "point": "terrain", "id": "t_wall_wood", "x": 11, "y": 16 }, + { "point": "terrain", "id": "t_wall_wood", "x": 13, "y": 16 }, + { "point": "terrain", "id": "t_wall_wood", "x": 14, "y": 16 }, + { "point": "terrain", "id": "t_wall_wood", "x": 19, "y": 16 } + ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_helipad_barricade_migo_resin", + "method": "json", + "object": { + "set": [ + { "point": "terrain", "id": "t_wall_resin", "x": 5, "y": 16 }, + { "point": "terrain", "id": "t_wall_resin", "x": 8, "y": 16 }, + { "point": "terrain", "id": "t_wall_resin", "x": 10, "y": 16 }, + { "point": "terrain", "id": "t_wall_resin", "x": 11, "y": 16 }, + { "point": "terrain", "id": "t_wall_resin", "x": 13, "y": 16 }, + { "point": "terrain", "id": "t_wall_resin", "x": 14, "y": 16 }, + { "point": "terrain", "id": "t_wall_resin", "x": 19, "y": 16 } + ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_helipad_root_cellar", + "method": "json", + "object": { "set": [ { "point": "terrain", "id": "t_rootcellar", "x": 13, "y": 15 } ] } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_helipad_butchery_rack", + "method": "json", + "object": { + "set": [ + { "point": "furniture", "id": "f_butcher_rack", "x": 10, "y": 15 }, + { "point": "furniture", "id": "f_table", "x": 11, "y": 15 } + ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_helipad_reinforce_doors", + "method": "json", + "object": { + "set": [ + { "point": "terrain", "id": "t_rdoor_c", "x": 16, "y": 16 }, + { "point": "terrain", "id": "t_rdoor_c", "x": 17, "y": 16 } + ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_helipad_radio", + "method": "json", + "object": { + "set": [ + { "point": "terrain", "id": "t_radio_controls", "x": 19, "y": 15 }, + { "point": "terrain", "id": "t_radio_tower", "x": 20, "y": 15 } + ] + } + } +] diff --git a/data/json/mapgen/basecamps/fbmc_helipad/fbmc_helipad_garage.json b/data/json/mapgen/basecamps/fbmc_helipad/fbmc_helipad_garage.json new file mode 100644 index 0000000000000..5db37f58c7fbb --- /dev/null +++ b/data/json/mapgen/basecamps/fbmc_helipad/fbmc_helipad_garage.json @@ -0,0 +1,14 @@ +[ + { + "type": "mapgen", + "om_terrain": [ "faction_base_helipad_garage_0" ], + "method": "json", + "object": { "fill_ter": "t_dirt" } + }, + { + "type": "mapgen", + "update_mapgen_id": "faction_base_helipad_garage_0", + "method": "json", + "object": { "set": [ { "point": "furniture", "id": "f_null", "x": 0, "y": 0 } ] } + } +] diff --git a/data/json/overmap/overmap_terrain/overmap_terrain_faction_base.json b/data/json/overmap/overmap_terrain/overmap_terrain_faction_base.json index 9d285c8bb4b88..2b59716298ddd 100644 --- a/data/json/overmap/overmap_terrain/overmap_terrain_faction_base.json +++ b/data/json/overmap/overmap_terrain/overmap_terrain_faction_base.json @@ -192,6 +192,13 @@ }, { "type": "overmap_terrain", + "id": "faction_base_helipad_garage_0", + "copy-from": "faction_base_camp_0", + "name": "military helipad garage", + "color": "red", + "delete": { "flags": [ "SOURCE_PEOPLE" ] } + }, + { "id": "faction_base_mansion_e1", "name": "mansion base entrance", "sym": "M", diff --git a/data/json/recipes/basecamps/fbmc_helipad/recipe_modular_helipad_common.json b/data/json/recipes/basecamps/fbmc_helipad/recipe_modular_helipad_common.json new file mode 100644 index 0000000000000..b7fceb8fc6212 --- /dev/null +++ b/data/json/recipes/basecamps/fbmc_helipad/recipe_modular_helipad_common.json @@ -0,0 +1,151 @@ +[ + { + "type": "recipe", + "result": "faction_base_helipad_0", + "description": "We should survey the base site and set up a bulletin board.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "skill_used": "fabrication", + "autolearn": false, + "never_learn": true, + "time": "1 h", + "construction_blueprint": "fbmc_helipad_0", + "blueprint_provides": [ + { "id": "gathering" }, + { "id": "firewood" }, + { "id": "sorting" }, + { "id": "logging" }, + { "id": "foraging" }, + { "id": "kitchen" }, + { "id": "kitchen_recipes_1" }, + { "id": "kitchen_recipes_2" }, + { "id": "primitive_camp_recipes_1" }, + { "id": "fbmc_helipad_0" } + ], + "blueprint_resources": [ "fake_oven", "fake_water_purifier" ], + "blueprint_requires": [ { "id": "not_an_upgrade" } ], + "blueprint_name": "basic survey", + "check_blueprint_needs": false + }, + { + "type": "recipe", + "result": "faction_base_helipad_barricade_wood", + "description": "We need to barricade front windows, let's build wooden walls over them.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_helipad_barricade_wood", + "blueprint_name": "wooden barricades", + "blueprint_provides": [ { "id": "fbmc_helipad_barricade" }, { "id": "bed", "amount": 4 } ], + "blueprint_requires": [ { "id": "fbmc_helipad_0" } ], + "blueprint_excludes": [ { "id": "fbmc_helipad_barricade" } ] + }, + { + "type": "recipe", + "result": "faction_base_helipad_migo_resin", + "description": "We need to barricade front windows, let's build mi-go resin walls over them.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_helipad_barricade_migo_resin", + "blueprint_name": "mi-go resin barricades", + "blueprint_provides": [ { "id": "fbmc_helipad_barricade" }, { "id": "bed", "amount": 4 } ], + "blueprint_requires": [ { "id": "fbmc_helipad_0" } ], + "blueprint_excludes": [ { "id": "fbmc_helipad_barricade" } ] + }, + { + "type": "recipe", + "result": "faction_base_helipad_root_cellar", + "description": "Digging a root cellar will allow us trapping small game and preserving it.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_helipad_root_cellar", + "blueprint_name": "root cellar", + "blueprint_provides": [ { "id": "fbmc_helipad_root_cellar" }, { "id": "pantry" }, { "id": "trapping" } ], + "blueprint_requires": [ { "id": "fbmc_helipad_barricade" } ], + "blueprint_excludes": [ { "id": "fbmc_helipad_root_cellar" } ] + }, + { + "type": "recipe", + "result": "faction_base_helipad_butchery_rack", + "description": "We could build butchery rack to start hunting larger animals.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_helipad_butchery_rack", + "blueprint_name": "butchery rack", + "blueprint_provides": [ { "id": "fbmc_helipad_butchery_rack" }, { "id": "hunting" } ], + "blueprint_requires": [ { "id": "fbmc_helipad_root_cellar" } ], + "blueprint_excludes": [ { "id": "fbmc_helipad_butchery_rack" } ] + }, + { + "type": "recipe", + "result": "faction_base_helipad_reinforce_doors", + "description": "We should reinforce front doors to make this base safer.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_helipad_reinforce_doors", + "blueprint_name": "reinforce doors", + "blueprint_provides": [ { "id": "fbmc_helipad_reinforce_doors" }, { "id": "bed", "amount": 4 }, { "id": "relaying" }, { "id": "walls" } ], + "blueprint_requires": [ { "id": "fbmc_helipad_barricade" } ], + "blueprint_excludes": [ { "id": "fbmc_helipad_reinforce_doors" } ] + }, + { + "type": "recipe", + "result": "faction_base_helipad_radio", + "description": "Let's set up a radio tower to improve our recruitment efforts.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_helipad_radio", + "blueprint_name": "radio tower", + "blueprint_provides": [ + { "id": "fbmc_helipad_radio" }, + { "id": "radio" }, + { "id": "recruiting" }, + { "id": "scouting" }, + { "id": "patroling" } + ], + "blueprint_requires": [ { "id": "fbmc_helipad_reinforce_doors" }, { "id": "fbmc_helipad_root_cellar" } ], + "blueprint_excludes": [ { "id": "fbmc_helipad_radio" } ], + "blueprint_needs": { + "time": "2 d", + "skills": [ [ "fabrication", 3 ] ], + "inline": { + "tools": [ ], + "qualities": [ [ { "id": "HAMMER", "level": 2 } ], [ { "id": "SAW_M" } ], [ { "id": "SCREW" } ], [ { "id": "WRENCH" } ] ], + "components": [ + [ + [ "wind_turbine", 4 ], + [ "xl_wind_turbine", 1 ], + [ "solar_panel", 4 ], + [ "reinforced_solar_panel", 4 ], + [ "solar_panel_v2", 2 ], + [ "reinforced_solar_panel_v2", 2 ] + ], + [ [ "storage_battery", 1 ], [ "medium_storage_battery", 4 ], [ "small_storage_battery", 32 ] ], + [ [ "sheet_metal", 2 ], [ "wire", 8 ] ], + [ [ "pipe", 24 ] ], + [ [ "processor", 2 ] ], + [ [ "RAM", 2 ] ], + [ [ "large_lcd_screen", 1 ] ], + [ [ "e_scrap", 8 ] ], + [ [ "frame", 1 ] ], + [ [ "circuit", 4 ] ], + [ [ "power_supply", 2 ] ], + [ [ "amplifier", 2 ] ], + [ [ "cable", 80 ] ], + [ [ "motor_small", 1 ], [ "motor_tiny", 2 ] ] + ] + } + } + } +] diff --git a/data/json/recipes/basecamps/fbmc_helipad/recipe_modular_helipad_garage.json b/data/json/recipes/basecamps/fbmc_helipad/recipe_modular_helipad_garage.json new file mode 100644 index 0000000000000..1158cbe6b3058 --- /dev/null +++ b/data/json/recipes/basecamps/fbmc_helipad/recipe_modular_helipad_garage.json @@ -0,0 +1,25 @@ +[ + { + "type": "recipe", + "result": "faction_base_helipad_garage_0", + "description": "Survey military helipad garage.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "skill_used": "fabrication", + "autolearn": false, + "never_learn": true, + "time": "180 m", + "construction_blueprint": "faction_base_helipad_garage_0", + "blueprint_provides": [ + { "id": "fbmc_helipad_garage_0" }, + { "id": "tool_storage" }, + { "id": "dismantling" }, + { "id": "blacksmith" }, + { "id": "power_saw_recipes" } + ], + "blueprint_resources": [ "fake_planer", "fake_drill_press" ], + "blueprint_requires": [ { "id": "not_an_upgrade" } ], + "blueprint_name": "military helipad garage survey", + "check_blueprint_needs": false + } +] diff --git a/data/json/recipes/basecamps/recipe_groups.json b/data/json/recipes/basecamps/recipe_groups.json index aa650df1a82c6..35f3469e07af1 100644 --- a/data/json/recipes/basecamps/recipe_groups.json +++ b/data/json/recipes/basecamps/recipe_groups.json @@ -25,6 +25,7 @@ "description": "Central Stairs Evac Shelter Base", "om_terrains": [ "shelter_2", "shelter_2_vandal" ] }, + { "id": "faction_base_helipad_0", "description": "Military Helipad Base", "om_terrains": [ "helipad_nw" ] }, { "id": "faction_base_outpost_normal_0", "description": "Normal Military Outpost Base", @@ -90,6 +91,11 @@ { "id": "faction_base_storehouse_0", "description": "Central Storage Building", "om_terrains": [ "field" ] }, { "id": "faction_base_saltworks_0", "description": "Saltworks Area", "om_terrains": [ "field" ] }, { "id": "faction_base_workshop_0", "description": "Fabrication Workshop", "om_terrains": [ "field" ] }, + { + "id": "faction_base_helipad_garage_0", + "description": "Military Helipad Garage", + "om_terrains": [ "helipad_ne" ] + }, { "id": "faction_base_mansion_e1", "description": "Mansion's Entrance", "om_terrains": [ "mansion_e1" ] }, { "id": "faction_base_mansion_e2", "description": "Mansion's Entrance", "om_terrains": [ "mansion_e2" ] }, { "id": "faction_base_mansion_t1", "description": "Mansion's Swimming Pool", "om_terrains": [ "mansion_t1" ] }, From 7582846907b05205b1edcbd36b76e37c583742cb Mon Sep 17 00:00:00 2001 From: NetSysFire <59517351+NetSysFire@users.noreply.github.com> Date: Wed, 7 Jul 2021 05:30:05 +0200 Subject: [PATCH 034/116] Fix typo in stone.json (#49690) --- data/json/items/resources/stone.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/items/resources/stone.json b/data/json/items/resources/stone.json index 76f74ce2a7aa7..7608c5f9e57b6 100644 --- a/data/json/items/resources/stone.json +++ b/data/json/items/resources/stone.json @@ -5,7 +5,7 @@ "symbol": "*", "color": "light_gray", "name": { "str": "flaking rock" }, - "description": "A rock the size of a baseball, which chips in a semi-predictable way if stuck, leaving a sharp edge. Makes a decent melee weapon, and is also good for throwing at enemies.", + "description": "A rock the size of a baseball, which chips in a semi-predictable way if struck, leaving a sharp edge. Makes a decent melee weapon, and is also good for throwing at enemies.", "category": "spare_parts", "material": [ "stone" ], "ammo_type": "rock", From 65e09f0de2c39c63cbb4ac33bfe5e9557f9dbd08 Mon Sep 17 00:00:00 2001 From: Saicchi <47158232+Saicchi@users.noreply.github.com> Date: Wed, 7 Jul 2021 02:53:15 -0300 Subject: [PATCH 035/116] add missing type to faction_base_mansion_e1 (#49692) Co-authored-by: Saicchi --- .../overmap/overmap_terrain/overmap_terrain_faction_base.json | 1 + 1 file changed, 1 insertion(+) diff --git a/data/json/overmap/overmap_terrain/overmap_terrain_faction_base.json b/data/json/overmap/overmap_terrain/overmap_terrain_faction_base.json index 2b59716298ddd..ff3e8ce0b8258 100644 --- a/data/json/overmap/overmap_terrain/overmap_terrain_faction_base.json +++ b/data/json/overmap/overmap_terrain/overmap_terrain_faction_base.json @@ -199,6 +199,7 @@ "delete": { "flags": [ "SOURCE_PEOPLE" ] } }, { + "type": "overmap_terrain", "id": "faction_base_mansion_e1", "name": "mansion base entrance", "sym": "M", From aa93bb8de0464063c4da45479ff75f3c023bf38d Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Tue, 6 Jul 2021 22:53:57 -0700 Subject: [PATCH 036/116] Convert armor to use armor_portion_data pt. 0 (#49677) I want to make changes to how armor data is specified, and I don't want to maintain two separate interfaces for it, so let's convert existing data to one interface. Items using copy-from were audited, and where they made changes, data was respecified as at the moment, copy-from modifying sub-elements of armor portion data is incorrect (there are lots of questions with no good answers there). --- data/json/items/armor/ammo_pouch.json | 75 ++-- data/json/items/armor/arms_armor.json | 71 ++-- data/json/items/armor/ballistic_armor.json | 24 +- data/json/items/armor/bandolier.json | 53 +-- data/json/items/armor/belts.json | 44 +-- data/json/items/armor/boots.json | 393 +++++++-------------- data/json/items/armor/cloaks.json | 75 ++-- data/json/items/armor/coats.json | 129 +++---- data/json/items/armor/eyewear.json | 161 ++++----- 9 files changed, 359 insertions(+), 666 deletions(-) diff --git a/data/json/items/armor/ammo_pouch.json b/data/json/items/armor/ammo_pouch.json index 6af7807031579..117b203e1f709 100644 --- a/data/json/items/armor/ammo_pouch.json +++ b/data/json/items/armor/ammo_pouch.json @@ -14,9 +14,6 @@ "symbol": "[", "looks_like": "leather_pouch", "color": "brown", - "covers": [ "torso" ], - "coverage": 10, - "encumbrance": 5, "material_thickness": 1, "pocket_data": [ { @@ -69,7 +66,8 @@ "moves": 35 } ], - "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 5, "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "ammo_satchel", @@ -84,9 +82,6 @@ "symbol": "[", "looks_like": "ragpouch", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 20, - "encumbrance": 4, "material_thickness": 2, "pocket_data": [ { @@ -99,7 +94,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Stash ammo", "holster_msg": "You stash your %s." }, - "flags": [ "WATER_FRIENDLY", "WAIST" ] + "flags": [ "WATER_FRIENDLY", "WAIST" ], + "armor": [ { "encumbrance": 4, "coverage": 20, "covers": [ "torso" ] } ] }, { "id": "chestpouch", @@ -114,8 +110,6 @@ "symbol": "[", "looks_like": "ragpouch", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 15, "material_thickness": 2, "pocket_data": [ { @@ -128,7 +122,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Stash ammo", "holster_msg": "You stash your %s." }, - "flags": [ "WATER_FRIENDLY", "BELTED" ] + "flags": [ "WATER_FRIENDLY", "BELTED" ], + "armor": [ { "coverage": 15, "covers": [ "torso" ] } ] }, { "id": "chestrig", @@ -143,8 +138,6 @@ "symbol": "[", "looks_like": "tool_belt", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 15, "material_thickness": 2, "pocket_data": [ { @@ -181,7 +174,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Stash ammo", "holster_msg": "You stash your %s." }, - "flags": [ "WATER_FRIENDLY", "BELTED" ] + "flags": [ "WATER_FRIENDLY", "BELTED" ], + "armor": [ { "coverage": 15, "covers": [ "torso" ] } ] }, { "id": "xl_chestrig", @@ -205,9 +199,6 @@ "symbol": "[", "looks_like": "quiver", "color": "brown", - "covers": [ "torso" ], - "coverage": 30, - "encumbrance": 10, "material_thickness": 4, "pocket_data": [ { @@ -257,7 +248,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Stash javelins", "holster_msg": "You stash your %s." }, - "flags": [ "WATER_FRIENDLY", "OVERSIZE", "BELTED" ] + "flags": [ "WATER_FRIENDLY", "OVERSIZE", "BELTED" ], + "armor": [ { "encumbrance": 10, "coverage": 30, "covers": [ "torso" ] } ] }, { "id": "legpouch", @@ -272,10 +264,7 @@ "symbol": "[", "looks_like": "ragpouch", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], "sided": true, - "coverage": 5, - "encumbrance": 1, "material_thickness": 2, "pocket_data": [ { @@ -288,7 +277,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Stash ammo", "holster_msg": "You stash your %s." }, - "flags": [ "WATER_FRIENDLY", "BELTED", "OVERSIZE", "ALLOWS_NATURAL_ATTACKS", "NOT_FOOTWEAR" ] + "flags": [ "WATER_FRIENDLY", "BELTED", "OVERSIZE", "ALLOWS_NATURAL_ATTACKS", "NOT_FOOTWEAR" ], + "armor": [ { "encumbrance": 1, "coverage": 5, "covers": [ "foot_l", "foot_r" ] } ] }, { "type": "ARMOR", @@ -303,9 +293,7 @@ "symbol": "[", "looks_like": "ammo_satchel", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], "sided": true, - "coverage": 15, "material_thickness": 2, "pocket_data": [ { @@ -326,7 +314,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Stash ammo", "holster_msg": "You stash your %s." }, - "flags": [ "WATER_FRIENDLY", "BELTED" ] + "flags": [ "WATER_FRIENDLY", "BELTED" ], + "armor": [ { "coverage": 15, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "quiver", @@ -342,13 +331,11 @@ "symbol": "[", "looks_like": "bscabbard", "color": "brown", - "covers": [ "leg_l", "leg_r" ], "sided": true, - "coverage": 10, - "encumbrance": 3, "material_thickness": 1, "pocket_data": [ { "ammo_restriction": { "arrow": 20, "bolt": 20 }, "moves": 20 } ], - "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 3, "coverage": 10, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "quiver_birchbark", @@ -364,13 +351,11 @@ "symbol": "[", "looks_like": "quiver", "color": "light_gray", - "covers": [ "leg_l", "leg_r" ], "sided": true, - "coverage": 10, - "encumbrance": 10, "material_thickness": 1, "pocket_data": [ { "ammo_restriction": { "arrow": 20, "bolt": 20 }, "moves": 20 } ], - "flags": [ "WAIST", "VARSIZE", "OVERSIZE", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "VARSIZE", "OVERSIZE", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 10, "coverage": 10, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "quiver_large", @@ -386,12 +371,10 @@ "symbol": "[", "looks_like": "quiver", "color": "brown", - "covers": [ "torso" ], - "coverage": 15, - "encumbrance": 3, "material_thickness": 1, "pocket_data": [ { "ammo_restriction": { "arrow": 60, "bolt": 60 }, "moves": 20 } ], - "flags": [ "BELTED", "OVERSIZE", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "OVERSIZE", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 3, "coverage": 15, "covers": [ "torso" ] } ] }, { "id": "quiver_large_birchbark", @@ -407,12 +390,10 @@ "symbol": "[", "looks_like": "quiver_birchbark", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 15, - "encumbrance": 14, "material_thickness": 1, "pocket_data": [ { "ammo_restriction": { "arrow": 60, "bolt": 60 }, "moves": 20 } ], - "flags": [ "BELTED", "VARSIZE", "OVERSIZE", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "VARSIZE", "OVERSIZE", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 14, "coverage": 15, "covers": [ "torso" ] } ] }, { "id": "tacvest", @@ -427,9 +408,6 @@ "material": [ "cotton" ], "symbol": "[", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 20, - "encumbrance": 2, "material_thickness": 2, "use_action": { "type": "holster", "holster_prompt": "Stash ammo", "holster_msg": "You stash your %s." }, "pocket_data": [ @@ -470,7 +448,8 @@ "moves": 60 } ], - "flags": [ "WATER_FRIENDLY", "WAIST" ] + "flags": [ "WATER_FRIENDLY", "WAIST" ], + "armor": [ { "encumbrance": 2, "coverage": 20, "covers": [ "torso" ] } ] }, { "id": "xl_tacvest", @@ -497,9 +476,6 @@ "material": [ "kevlar_layered" ], "symbol": "[", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 85, - "encumbrance": 17, "warmth": 15, "material_thickness": 4, "pocket_data": [ @@ -541,6 +517,7 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Stash ammo", "holster_msg": "You stash your %s." }, - "flags": [ "OVERSIZE", "STURDY", "OUTER" ] + "flags": [ "OVERSIZE", "STURDY", "OUTER" ], + "armor": [ { "encumbrance": 17, "coverage": 85, "covers": [ "torso" ] } ] } ] diff --git a/data/json/items/armor/arms_armor.json b/data/json/items/armor/arms_armor.json index 19abbbf64451e..ded8c45663e7f 100644 --- a/data/json/items/armor/arms_armor.json +++ b/data/json/items/armor/arms_armor.json @@ -15,13 +15,11 @@ "symbol": "[", "looks_like": "arm_splint", "color": "brown", - "covers": [ "arm_l", "arm_r" ], - "coverage": 75, - "encumbrance": 25, "warmth": 5, "material_thickness": 3, "techniques": [ "WBLOCK_1" ], - "flags": [ "BELTED", "WATER_FRIENDLY", "BLOCK_WHILE_WORN" ] + "flags": [ "BELTED", "WATER_FRIENDLY", "BLOCK_WHILE_WORN" ], + "armor": [ { "encumbrance": 25, "coverage": 75, "covers": [ "arm_l", "arm_r" ] } ] }, { "id": "armguard_chitin", @@ -38,13 +36,11 @@ "symbol": "[", "looks_like": "armguard_hard", "color": "green", - "covers": [ "arm_l", "arm_r" ], - "coverage": 90, - "encumbrance": 10, "warmth": 10, "material_thickness": 3, "environmental_protection": 2, - "flags": [ "STURDY", "BELTED", "BLOCK_WHILE_WORN", "WATER_FRIENDLY" ] + "flags": [ "STURDY", "BELTED", "BLOCK_WHILE_WORN", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 10, "coverage": 90, "covers": [ "arm_l", "arm_r" ] } ] }, { "id": "xl_armguard_chitin", @@ -93,13 +89,11 @@ "material": [ "plastic", "neoprene" ], "symbol": "[", "color": "dark_gray", - "covers": [ "arm_l", "arm_r" ], - "coverage": 80, - "encumbrance": 5, "warmth": 20, "material_thickness": 3, "environmental_protection": 1, - "flags": [ "BELTED", "WATER_FRIENDLY", "BLOCK_WHILE_WORN" ] + "flags": [ "BELTED", "WATER_FRIENDLY", "BLOCK_WHILE_WORN" ], + "armor": [ { "encumbrance": 5, "coverage": 80, "covers": [ "arm_l", "arm_r" ] } ] }, { "id": "xl_armguard_hard", @@ -126,13 +120,11 @@ "symbol": "[", "looks_like": "arm_warmers", "color": "brown", - "covers": [ "arm_l", "arm_r" ], - "coverage": 90, - "encumbrance": 10, "warmth": 25, "material_thickness": 4, "valid_mods": [ "steel_padded" ], - "flags": [ "STURDY", "BELTED", "BLOCK_WHILE_WORN", "WATER_FRIENDLY" ] + "flags": [ "STURDY", "BELTED", "BLOCK_WHILE_WORN", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 10, "coverage": 90, "covers": [ "arm_l", "arm_r" ] } ] }, { "id": "xl_armguard_larmor", @@ -159,12 +151,10 @@ "symbol": "[", "looks_like": "armguard_metal", "color": "light_gray", - "covers": [ "arm_l", "arm_r" ], - "coverage": 95, - "encumbrance": 20, "warmth": 20, "material_thickness": 4, - "flags": [ "VARSIZE", "BELTED", "STURDY", "BLOCK_WHILE_WORN" ] + "flags": [ "VARSIZE", "BELTED", "STURDY", "BLOCK_WHILE_WORN" ], + "armor": [ { "encumbrance": 20, "coverage": 95, "covers": [ "arm_l", "arm_r" ] } ] }, { "id": "xl_armguard_lightplate", @@ -191,13 +181,11 @@ "symbol": "[", "looks_like": "armguard_hard", "color": "light_gray", - "covers": [ "arm_l", "arm_r" ], - "coverage": 80, - "encumbrance": 15, "warmth": 20, "material_thickness": 3, "environmental_protection": 1, - "flags": [ "BELTED", "BLOCK_WHILE_WORN", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "BLOCK_WHILE_WORN", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 15, "coverage": 80, "covers": [ "arm_l", "arm_r" ] } ] }, { "id": "xl_armguard_metal", @@ -224,12 +212,10 @@ "symbol": "[", "looks_like": "armguard_larmor", "color": "blue", - "covers": [ "arm_l", "arm_r" ], - "coverage": 80, - "encumbrance": 10, "warmth": 5, "material_thickness": 3, - "flags": [ "BELTED", "BLOCK_WHILE_WORN" ] + "flags": [ "BELTED", "BLOCK_WHILE_WORN" ], + "armor": [ { "encumbrance": 10, "coverage": 80, "covers": [ "arm_l", "arm_r" ] } ] }, { "id": "armguard_scrap", @@ -248,12 +234,10 @@ "symbol": "[", "looks_like": "armguard_metal", "color": "light_gray", - "covers": [ "arm_l", "arm_r" ], - "coverage": 80, - "encumbrance": 18, "warmth": 10, "material_thickness": 2, - "flags": [ "BELTED", "BLOCK_WHILE_WORN" ] + "flags": [ "BELTED", "BLOCK_WHILE_WORN" ], + "armor": [ { "encumbrance": 18, "coverage": 80, "covers": [ "arm_l", "arm_r" ] } ] }, { "id": "xl_armguard_scrap", @@ -280,13 +264,11 @@ "symbol": "[", "looks_like": "arm_warmers", "color": "light_red", - "covers": [ "arm_l", "arm_r" ], - "coverage": 70, - "encumbrance": 5, "warmth": 20, "material_thickness": 2, "environmental_protection": 1, - "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ] + "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 5, "coverage": 70, "covers": [ "arm_l", "arm_r" ] } ] }, { "id": "xl_armguard_soft", @@ -313,11 +295,9 @@ "symbol": "[", "looks_like": "armguard_metal", "color": "light_red", - "covers": [ "arm_l", "arm_r" ], - "coverage": 95, - "encumbrance": 20, "material_thickness": 4, - "flags": [ "VARSIZE", "STURDY" ] + "flags": [ "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 95, "covers": [ "arm_l", "arm_r" ] } ] }, { "id": "xl_chainmail_arms", @@ -344,10 +324,9 @@ "symbol": "[", "looks_like": "armguard_hard", "color": "dark_gray", - "covers": [ "arm_l", "arm_r" ], - "coverage": 30, "material_thickness": 5, - "flags": [ "WATER_FRIENDLY", "BELTED" ] + "flags": [ "WATER_FRIENDLY", "BELTED" ], + "armor": [ { "coverage": 30, "covers": [ "arm_l", "arm_r" ] } ] }, { "id": "vambrace_larmor", @@ -364,13 +343,11 @@ "symbol": "[", "looks_like": "armguard_larmor", "color": "brown", - "covers": [ "arm_l", "arm_r" ], - "coverage": 50, - "encumbrance": 8, "warmth": 10, "material_thickness": 3, "environmental_protection": 1, - "flags": [ "STURDY", "BELTED", "WATER_FRIENDLY" ] + "flags": [ "STURDY", "BELTED", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 8, "coverage": 50, "covers": [ "arm_l", "arm_r" ] } ] }, { "id": "xl_vambrace_larmor", diff --git a/data/json/items/armor/ballistic_armor.json b/data/json/items/armor/ballistic_armor.json index 6903474bca130..d4056cb76224f 100644 --- a/data/json/items/armor/ballistic_armor.json +++ b/data/json/items/armor/ballistic_armor.json @@ -14,12 +14,10 @@ "symbol": "[", "looks_like": "modularvest", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 85, - "encumbrance": 6, "warmth": 15, "material_thickness": 6, - "flags": [ "STURDY", "OUTER", "WATER_FRIENDLY" ] + "flags": [ "STURDY", "OUTER", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 6, "coverage": 85, "covers": [ "torso" ] } ] }, { "id": "ballistic_vest_esapi", @@ -35,12 +33,10 @@ "symbol": "[", "looks_like": "modularvestceramic", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 85, - "encumbrance": 10, "warmth": 15, "material_thickness": 16, - "flags": [ "STURDY", "OUTER", "WATER_FRIENDLY", "NO_REPAIR" ] + "flags": [ "STURDY", "OUTER", "WATER_FRIENDLY", "NO_REPAIR" ], + "armor": [ { "encumbrance": 10, "coverage": 85, "covers": [ "torso" ] } ] }, { "id": "dragonskin", @@ -58,13 +54,11 @@ "symbol": "[", "looks_like": "kevlar", "color": "light_red", - "covers": [ "torso" ], - "coverage": 95, - "encumbrance": 8, "warmth": 12, "material_thickness": 3, "//": "Ceramic disks inside block addition of steel plating modification", - "flags": [ "STURDY", "OUTER", "NO_REPAIR" ] + "flags": [ "STURDY", "OUTER", "NO_REPAIR" ], + "armor": [ { "encumbrance": 8, "coverage": 95, "covers": [ "torso" ] } ] }, { "id": "dragonskinempty", @@ -83,11 +77,9 @@ "symbol": "[", "looks_like": "dragonskin", "color": "light_red", - "covers": [ "torso" ], - "coverage": 25, - "encumbrance": 6, "warmth": 10, "material_thickness": 2, - "flags": [ "STURDY", "OUTER" ] + "flags": [ "STURDY", "OUTER" ], + "armor": [ { "encumbrance": 6, "coverage": 25, "covers": [ "torso" ] } ] } ] diff --git a/data/json/items/armor/bandolier.json b/data/json/items/armor/bandolier.json index d20d91322a436..e345cd71c0952 100644 --- a/data/json/items/armor/bandolier.json +++ b/data/json/items/armor/bandolier.json @@ -12,9 +12,6 @@ "symbol": "[", "looks_like": "leather_belt", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 10, - "encumbrance": 1, "material_thickness": 1, "pocket_data": [ { @@ -42,7 +39,8 @@ "moves": 20 } ], - "flags": [ "WATER_FRIENDLY", "WAIST", "OVERSIZE" ] + "flags": [ "WATER_FRIENDLY", "WAIST", "OVERSIZE" ], + "armor": [ { "encumbrance": 1, "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "bandolier_rifle", @@ -57,9 +55,6 @@ "symbol": "[", "looks_like": "leather_belt", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 10, - "encumbrance": 1, "material_thickness": 1, "pocket_data": [ { @@ -83,7 +78,8 @@ "moves": 20 } ], - "flags": [ "WATER_FRIENDLY", "WAIST", "OVERSIZE" ] + "flags": [ "WATER_FRIENDLY", "WAIST", "OVERSIZE" ], + "armor": [ { "encumbrance": 1, "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "bandolier_shotgun", @@ -98,12 +94,10 @@ "symbol": "[", "looks_like": "leather_belt", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 10, - "encumbrance": 2, "material_thickness": 1, "pocket_data": [ { "ammo_restriction": { "410shot": 25, "shot": 25, "20x66mm": 25, "signal_flare": 25 }, "moves": 25 } ], - "flags": [ "WATER_FRIENDLY", "WAIST", "OVERSIZE" ] + "flags": [ "WATER_FRIENDLY", "WAIST", "OVERSIZE" ], + "armor": [ { "encumbrance": 2, "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "torso_bandolier_grenade", @@ -128,12 +122,10 @@ "symbol": "[", "looks_like": "leather_belt", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 12, - "encumbrance": 3, "material_thickness": 1, "pocket_data": [ { "ammo_restriction": { "410shot": 50, "shot": 50, "20x66mm": 50, "signal_flare": 50 }, "moves": 35 } ], - "flags": [ "WATER_FRIENDLY", "OVERSIZE", "BELTED" ] + "flags": [ "WATER_FRIENDLY", "OVERSIZE", "BELTED" ], + "armor": [ { "encumbrance": 3, "coverage": 12, "covers": [ "torso" ] } ] }, { "id": "flintlock_pouch", @@ -148,9 +140,6 @@ "symbol": "[", "looks_like": "ammo_pouch", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 10, - "encumbrance": 2, "material_thickness": 1, "pocket_data": [ { @@ -158,7 +147,8 @@ "moves": 20 } ], - "flags": [ "WATER_FRIENDLY", "WAIST", "OVERSIZE" ] + "flags": [ "WATER_FRIENDLY", "WAIST", "OVERSIZE" ], + "armor": [ { "encumbrance": 2, "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "bandolier_wrist", @@ -173,10 +163,7 @@ "symbol": "[", "looks_like": "leather_belt", "color": "dark_gray", - "covers": [ "hand_l", "hand_r" ], "sided": true, - "coverage": 5, - "encumbrance": 1, "material_thickness": 1, "pocket_data": [ { @@ -200,7 +187,8 @@ "moves": 20 } ], - "flags": [ "WATER_FRIENDLY", "BELTED", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "WATER_FRIENDLY", "BELTED", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 1, "coverage": 5, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "grenade_pouch", @@ -215,13 +203,11 @@ "symbol": "[", "looks_like": "ammo_satchel", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], "sided": true, - "coverage": 10, - "encumbrance": 4, "material_thickness": 1, "pocket_data": [ { "ammo_restriction": { "40x46mm": 4, "40x53mm": 4 }, "moves": 20 } ], - "flags": [ "WATER_FRIENDLY", "BELTED", "OVERSIZE" ] + "flags": [ "WATER_FRIENDLY", "BELTED", "OVERSIZE" ], + "armor": [ { "encumbrance": 4, "coverage": 10, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "stone_pouch", @@ -236,13 +222,11 @@ "symbol": "[", "looks_like": "ammo_satchel", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], "sided": true, - "coverage": 10, - "encumbrance": 4, "material_thickness": 1, "pocket_data": [ { "ammo_restriction": { "rock": 10 }, "moves": 20 } ], - "flags": [ "WATER_FRIENDLY", "BELTED", "OVERSIZE" ] + "flags": [ "WATER_FRIENDLY", "BELTED", "OVERSIZE" ], + "armor": [ { "encumbrance": 4, "coverage": 10, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "grenadebandolier", @@ -257,8 +241,6 @@ "symbol": "[", "looks_like": "leather_belt", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 15, "material_thickness": 2, "pocket_data": [ { @@ -291,6 +273,7 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Stash grenades", "holster_msg": "You stash your %s." }, - "flags": [ "WATER_FRIENDLY", "BELTED" ] + "flags": [ "WATER_FRIENDLY", "BELTED" ], + "armor": [ { "coverage": 15, "covers": [ "torso" ] } ] } ] diff --git a/data/json/items/armor/belts.json b/data/json/items/armor/belts.json index 3ee42bbea12ca..7352faadf4e79 100644 --- a/data/json/items/armor/belts.json +++ b/data/json/items/armor/belts.json @@ -13,10 +13,6 @@ "symbol": "[", "looks_like": "holster", "color": "yellow", - "covers": [ "torso" ], - "coverage": 5, - "encumbrance": 2, - "max_encumbrance": 5, "pocket_data": [ { "max_contains_volume": "1 L", "max_contains_weight": "1500 g", "moves": 100 }, { @@ -29,7 +25,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Attach what to belt loop?", "holster_msg": "You clip your %s to your %s" }, - "flags": [ "WAIST", "NO_QUICKDRAW", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "NO_QUICKDRAW", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 2, 5 ], "coverage": 5, "covers": [ "torso" ] } ] }, { "abstract": "judo_belt_abstract", @@ -44,11 +41,9 @@ "to_hit": -1, "material": [ "cotton" ], "symbol": "[", - "covers": [ "torso" ], - "coverage": 5, - "encumbrance": 2, "material_thickness": 2, - "flags": [ "WAIST", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 2, "coverage": 5, "covers": [ "torso" ] } ] }, { "id": "judo_belt_black", @@ -119,8 +114,6 @@ "material": [ "leather", "steel" ], "symbol": "[", "color": "brown", - "covers": [ "torso" ], - "coverage": 5, "material_thickness": 1.5, "pocket_data": [ { @@ -133,7 +126,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Stick what into your belt", "holster_msg": "You tuck your %s into your %s" }, - "flags": [ "WAIST", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "WATER_FRIENDLY" ], + "armor": [ { "coverage": 5, "covers": [ "torso" ] } ] }, { "id": "obi_gi", @@ -163,10 +157,6 @@ "symbol": "[", "looks_like": "fireman_belt", "color": "brown", - "covers": [ "torso" ], - "coverage": 5, - "encumbrance": 2, - "max_encumbrance": 5, "pocket_data": [ { "max_contains_volume": "500 ml", "max_item_volume": "125 ml", "max_contains_weight": "1500 g", "moves": 100 }, { @@ -179,7 +169,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Attach what to holder?", "holster_msg": "You attach your %s to your %s." }, - "flags": [ "WAIST", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 2, 5 ], "coverage": 5, "covers": [ "torso" ] } ] }, { "id": "survivor_belt_notools", @@ -194,10 +185,6 @@ "symbol": "[", "looks_like": "holster", "color": "brown", - "covers": [ "torso" ], - "coverage": 15, - "encumbrance": 2, - "max_encumbrance": 12, "material_thickness": 2, "pocket_data": [ { @@ -257,7 +244,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Store tool or blade", "holster_msg": "You put your %1$s in your %2$s" }, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "STURDY", "WAIST", "OVERSIZE" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "STURDY", "WAIST", "OVERSIZE" ], + "armor": [ { "encumbrance": [ 2, 12 ], "coverage": 15, "covers": [ "torso" ] } ] }, { "id": "tool_belt", @@ -273,10 +261,6 @@ "symbol": "[", "looks_like": "holster", "color": "brown", - "covers": [ "torso" ], - "coverage": 20, - "encumbrance": 2, - "max_encumbrance": 12, "material_thickness": 2, "pocket_data": [ { "max_contains_volume": "1 L", "max_contains_weight": "1500 g", "max_item_length": "40 cm", "moves": 100 }, @@ -327,7 +311,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Store tool or blade", "holster_msg": "You put your %1$s in your %2$s" }, - "flags": [ "WAIST", "NO_QUICKDRAW", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "NO_QUICKDRAW", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 2, 12 ], "coverage": 20, "covers": [ "torso" ] } ] }, { "id": "webbing_belt", @@ -342,8 +327,6 @@ "symbol": "[", "looks_like": "leather_belt", "color": "yellow", - "covers": [ "torso" ], - "coverage": 5, "material_thickness": 1.5, "pocket_data": [ { @@ -356,6 +339,7 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Store tool or blade", "holster_msg": "You put your %1$s in your %2$s" }, - "flags": [ "WAIST", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "WATER_FRIENDLY" ], + "armor": [ { "coverage": 5, "covers": [ "torso" ] } ] } ] diff --git a/data/json/items/armor/boots.json b/data/json/items/armor/boots.json index 416967eb95a5e..03e89e83795c2 100644 --- a/data/json/items/armor/boots.json +++ b/data/json/items/armor/boots.json @@ -13,11 +13,9 @@ "symbol": "[", "looks_like": "flip_flops", "color": "brown", - "covers": [ "foot_l", "foot_r" ], - "coverage": 40, - "encumbrance": 10, "material_thickness": 2, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 10, "coverage": 40, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "boots", @@ -34,13 +32,11 @@ "symbol": "[", "looks_like": "dress_shoes", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 90, - "encumbrance": 12, "warmth": 20, "material_thickness": 2.5, "environmental_protection": 2, - "flags": [ "VARSIZE", "WATERPROOF" ] + "flags": [ "VARSIZE", "WATERPROOF" ], + "armor": [ { "encumbrance": 12, "coverage": 90, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "xl_boots", @@ -65,10 +61,9 @@ "symbol": "[", "looks_like": "boots", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "encumbrance": 16, "material_thickness": 3, - "flags": [ "VARSIZE", "WATERPROOF" ] + "flags": [ "VARSIZE", "WATERPROOF" ], + "armor": [ { "encumbrance": 16, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "boots_bunker", @@ -86,13 +81,11 @@ "symbol": "[", "looks_like": "boots_steel", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 40, "warmth": 35, "material_thickness": 4.5, "environmental_protection": 8, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 40, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "boots_chitin", @@ -110,13 +103,11 @@ "symbol": "[", "looks_like": "boots_bone", "color": "green", - "covers": [ "foot_l", "foot_r" ], - "coverage": 95, - "encumbrance": 14, "warmth": 10, "material_thickness": 4, "environmental_protection": 3, - "flags": [ "STURDY" ] + "flags": [ "STURDY" ], + "armor": [ { "encumbrance": 14, "coverage": 95, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "xl_boots_chitin", @@ -162,13 +153,11 @@ "symbol": "[", "looks_like": "boots", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 25, "warmth": 25, "material_thickness": 2.5, "environmental_protection": 2, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 25, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "foot_protectors_eod", @@ -179,16 +168,14 @@ "weight": "1220 g", "volume": "3 L", "price": 50000, - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 40, "warmth": 10, "material": [ "steel", "nomex" ], "symbol": "[", "color": "light_gray", "environmental_protection": 2, "material_thickness": 7, - "flags": [ "STURDY", "OUTER" ] + "flags": [ "STURDY", "OUTER" ], + "armor": [ { "encumbrance": 40, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "toecaps", @@ -203,13 +190,11 @@ "material": [ "plastic", "steel" ], "symbol": "[", "color": "brown", - "covers": [ "foot_l", "foot_r" ], - "coverage": 15, - "encumbrance": 10, "warmth": 10, "material_thickness": 3, "environmental_protection": 1, - "flags": [ "OUTER", "STURDY" ] + "flags": [ "OUTER", "STURDY" ], + "armor": [ { "encumbrance": 10, "coverage": 15, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "boots_fsurvivor", @@ -227,13 +212,11 @@ "symbol": "[", "looks_like": "boots_combat", "color": "light_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 35, "warmth": 15, "material_thickness": 5, "environmental_protection": 10, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 35, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "xl_boots_fsurvivor", @@ -258,13 +241,11 @@ "symbol": "[", "looks_like": "boots", "color": "brown", - "covers": [ "foot_l", "foot_r" ], - "coverage": 90, - "encumbrance": 20, "warmth": 60, "material_thickness": 3, "environmental_protection": 2, - "flags": [ "VARSIZE", "WATERPROOF" ] + "flags": [ "VARSIZE", "WATERPROOF" ], + "armor": [ { "encumbrance": 20, "coverage": 90, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "xl_boots_fur", @@ -314,13 +295,11 @@ "symbol": "[", "looks_like": "boots_bunker", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 32, "warmth": 15, "material_thickness": 3, "environmental_protection": 10, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "STURDY" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "STURDY" ], + "armor": [ { "encumbrance": 32, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "boots_hiking", @@ -338,13 +317,11 @@ "symbol": "[", "looks_like": "boots", "color": "brown", - "covers": [ "foot_l", "foot_r" ], - "coverage": 95, - "encumbrance": 12, "warmth": 30, "material_thickness": 2, "environmental_protection": 2, - "flags": [ "VARSIZE", "WATERPROOF" ] + "flags": [ "VARSIZE", "WATERPROOF" ], + "armor": [ { "encumbrance": 12, "coverage": 95, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "boots_hsurvivor", @@ -362,13 +339,11 @@ "symbol": "[", "looks_like": "boots_combat", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 35, "warmth": 15, "material_thickness": 5, "environmental_protection": 5, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 35, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "xl_boots_hsurvivor", @@ -394,13 +369,11 @@ "symbol": "[", "looks_like": "boots", "color": "brown", - "covers": [ "foot_l", "foot_r" ], - "coverage": 95, - "encumbrance": 18, "warmth": 25, "material_thickness": 5, "environmental_protection": 2, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 18, "coverage": 95, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "xl_boots_larmor", @@ -426,13 +399,11 @@ "symbol": "[", "looks_like": "boots_combat", "color": "green", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 18, "warmth": 15, "material_thickness": 4, "environmental_protection": 3, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 18, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "xl_boots_lsurvivor", @@ -458,13 +429,11 @@ "symbol": "[", "looks_like": "boots_steel", "color": "light_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 28, "warmth": 20, "material_thickness": 4, "environmental_protection": 1, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 28, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "xl_boots_plate", @@ -489,13 +458,11 @@ "symbol": "[", "looks_like": "boots", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 30, "warmth": 10, "material_thickness": 3, "environmental_protection": 12, - "flags": [ "WATERPROOF" ] + "flags": [ "WATERPROOF" ], + "armor": [ { "encumbrance": 30, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "boots_scrap", @@ -513,12 +480,10 @@ "symbol": "[", "looks_like": "boots_steel", "color": "light_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 80, - "encumbrance": 20, "warmth": 10, "material_thickness": 2, - "flags": [ "VARSIZE", "WATERPROOF" ] + "flags": [ "VARSIZE", "WATERPROOF" ], + "armor": [ { "encumbrance": 20, "coverage": 80, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "xl_boots_scrap", @@ -545,13 +510,11 @@ "symbol": "[", "looks_like": "boots_combat", "color": "brown", - "covers": [ "foot_l", "foot_r" ], - "coverage": 90, - "encumbrance": 20, "warmth": 30, "material_thickness": 2.5, "environmental_protection": 3, - "flags": [ "VARSIZE", "WATERPROOF" ] + "flags": [ "VARSIZE", "WATERPROOF" ], + "armor": [ { "encumbrance": 20, "coverage": 90, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "boots_survivor", @@ -569,13 +532,11 @@ "symbol": "[", "looks_like": "boots_combat", "color": "brown", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 24, "warmth": 15, "material_thickness": 3.5, "environmental_protection": 3, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 24, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "boots_western", @@ -584,14 +545,14 @@ "name": { "str": "pair of western boots", "str_pl": "pairs of western boots" }, "description": "Stiff leather boots with intricate embroidery and one-inch heels. They look good, but aren't made for running. Each boot is large enough to conceal a small holdout pistol.", "price_postapoc": 750, - "coverage": 95, "proportional": { "weight": 1.2, "volume": 1.2, "price": 2, "encumbrance": 2 }, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "250 ml", "max_contains_weight": "600 g", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "250 ml", "max_contains_weight": "600 g", "moves": 80 } ], "use_action": { "type": "holster" }, - "extend": { "flags": [ "FANCY" ] } + "extend": { "flags": [ "FANCY" ] }, + "armor": [ { "encumbrance": 12, "coverage": 95, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "boots_winter", @@ -607,13 +568,11 @@ "symbol": "[", "looks_like": "boots_larmor", "color": "light_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 90, - "encumbrance": 25, "warmth": 80, "material_thickness": 5, "environmental_protection": 1, - "flags": [ "VARSIZE", "WATERPROOF" ] + "flags": [ "VARSIZE", "WATERPROOF" ], + "armor": [ { "encumbrance": 25, "coverage": 90, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "xl_boots_winter", @@ -639,13 +598,11 @@ "symbol": "[", "looks_like": "boots_fur", "color": "light_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 38, "warmth": 75, "material_thickness": 5, "environmental_protection": 5, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 38, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "xl_boots_wsurvivor", @@ -671,13 +628,11 @@ "symbol": "[", "looks_like": "boots_combat", "color": "brown", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 38, "warmth": 15, "material_thickness": 4, "environmental_protection": 3, - "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 38, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "cleats", @@ -694,12 +649,10 @@ "symbol": "[", "looks_like": "sneakers", "color": "light_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 80, - "encumbrance": 15, "warmth": 20, "material_thickness": 2, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 15, "coverage": 80, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "golf_shoes", @@ -716,12 +669,10 @@ "symbol": "[", "looks_like": "dress_shoes", "color": "light_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 70, - "encumbrance": 12, "warmth": 15, "material_thickness": 2, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 12, "coverage": 70, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "clogs", @@ -738,13 +689,11 @@ "symbol": "[", "looks_like": "leathersandals", "color": "yellow", - "covers": [ "foot_l", "foot_r" ], - "coverage": 85, - "encumbrance": 20, "warmth": 5, "material_thickness": 4, "environmental_protection": 1, - "flags": [ "VARSIZE", "WATERPROOF" ] + "flags": [ "VARSIZE", "WATERPROOF" ], + "armor": [ { "encumbrance": 20, "coverage": 85, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "clownshoes", @@ -762,12 +711,10 @@ "symbol": "[", "looks_like": "sneakers", "color": "light_red", - "covers": [ "foot_l", "foot_r" ], - "coverage": 85, - "encumbrance": 60, "warmth": 20, "material_thickness": 2.5, - "environmental_protection": 2 + "environmental_protection": 2, + "armor": [ { "encumbrance": 60, "coverage": 85, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "dance_shoes", @@ -784,12 +731,10 @@ "symbol": "[", "looks_like": "dress_shoes", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 60, - "encumbrance": 5, "warmth": 10, "material_thickness": 1.5, - "flags": [ "VARSIZE", "FANCY" ] + "flags": [ "VARSIZE", "FANCY" ], + "armor": [ { "encumbrance": 5, "coverage": 60, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "dress_shoes", @@ -807,12 +752,10 @@ "symbol": "[", "looks_like": "sneakers", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 60, - "encumbrance": 15, "warmth": 10, "material_thickness": 2.0, - "flags": [ "VARSIZE", "FANCY" ] + "flags": [ "VARSIZE", "FANCY" ], + "armor": [ { "encumbrance": 15, "coverage": 60, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "flip_flops", @@ -828,11 +771,9 @@ "symbol": "[", "looks_like": "sneakers", "color": "blue", - "covers": [ "foot_l", "foot_r" ], - "coverage": 10, - "encumbrance": 35, "material_thickness": 1, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 35, "coverage": 10, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "flip_flops_exp", @@ -849,12 +790,10 @@ "symbol": "[", "looks_like": "flip_flops", "color": "brown", - "covers": [ "foot_l", "foot_r" ], - "coverage": 12, - "encumbrance": 30, "material_thickness": 1, "environmental_protection": 1, - "flags": [ "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 30, "coverage": 12, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "footrags", @@ -869,12 +808,10 @@ "symbol": "[", "looks_like": "socks", "color": "brown", - "covers": [ "foot_l", "foot_r" ], - "coverage": 65, - "encumbrance": 2, "warmth": 5, "material_thickness": 1.5, - "flags": [ "SKINTIGHT", "OVERSIZE", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "SKINTIGHT", "OVERSIZE", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 2, "coverage": 65, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "footrags_fur", @@ -889,12 +826,10 @@ "symbol": "[", "looks_like": "socks_wool", "color": "brown", - "covers": [ "foot_l", "foot_r" ], - "coverage": 65, - "encumbrance": 5, "warmth": 20, "material_thickness": 1.5, - "flags": [ "OVERSIZE", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "OVERSIZE", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 5, "coverage": 65, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "footrags_leather", @@ -909,12 +844,10 @@ "symbol": "[", "looks_like": "socks", "color": "brown", - "covers": [ "foot_l", "foot_r" ], - "coverage": 65, - "encumbrance": 5, "warmth": 10, "material_thickness": 1.5, - "flags": [ "OVERSIZE", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "OVERSIZE", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 5, "coverage": 65, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "footrags_wool", @@ -929,12 +862,10 @@ "symbol": "[", "looks_like": "socks_wool", "color": "blue", - "covers": [ "foot_l", "foot_r" ], - "coverage": 65, - "encumbrance": 5, "warmth": 15, "material_thickness": 1.5, - "flags": [ "SKINTIGHT", "OVERSIZE", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "SKINTIGHT", "OVERSIZE", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 5, "coverage": 65, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "geta", @@ -951,13 +882,11 @@ "symbol": "[", "looks_like": "clogs", "color": "yellow", - "covers": [ "foot_l", "foot_r" ], - "coverage": 10, - "encumbrance": 10, "warmth": 5, "material_thickness": 2, "environmental_protection": 1, - "flags": [ "VARSIZE", "WATERPROOF" ] + "flags": [ "VARSIZE", "WATERPROOF" ], + "armor": [ { "encumbrance": 10, "coverage": 10, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "heels", @@ -975,11 +904,9 @@ "symbol": "[", "looks_like": "dress_shoes", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 30, - "encumbrance": 50, "material_thickness": 1.5, - "flags": [ "VARSIZE", "FANCY" ] + "flags": [ "VARSIZE", "FANCY" ], + "armor": [ { "encumbrance": 50, "coverage": 30, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "knee_high_boots", @@ -997,13 +924,11 @@ "symbol": "[", "looks_like": "boots_larmor", "color": "dark_gray", - "covers": [ "foot_l", "foot_r", "leg_r", "leg_l" ], - "coverage": 65, - "encumbrance": 20, "warmth": 20, "material_thickness": 2, "environmental_protection": 2, - "flags": [ "VARSIZE", "WATERPROOF" ] + "flags": [ "VARSIZE", "WATERPROOF" ], + "armor": [ { "encumbrance": 20, "coverage": 65, "covers": [ "foot_l", "foot_r", "leg_r", "leg_l" ] } ] }, { "id": "leathersandals", @@ -1019,11 +944,9 @@ "symbol": "[", "looks_like": "flip_flops", "color": "brown", - "covers": [ "foot_l", "foot_r" ], - "coverage": 30, - "encumbrance": 5, "material_thickness": 1.5, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 5, "coverage": 30, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "lowtops", @@ -1040,11 +963,10 @@ "symbol": "[", "looks_like": "sneakers", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 80, "warmth": 5, "material_thickness": 1.5, - "flags": [ "VARSIZE", "WATER_FRIENDLY" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY" ], + "armor": [ { "coverage": 80, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "mocassins", @@ -1059,12 +981,10 @@ "symbol": "[", "looks_like": "leathersandals", "color": "brown", - "covers": [ "foot_l", "foot_r" ], - "coverage": 50, - "encumbrance": 2, "warmth": 20, "material_thickness": 1.0, - "flags": [ "VARSIZE", "WATERPROOF" ] + "flags": [ "VARSIZE", "WATERPROOF" ], + "armor": [ { "encumbrance": 2, "coverage": 50, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "motorbike_boots", @@ -1081,13 +1001,11 @@ "symbol": "[", "looks_like": "boots_steel", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 95, - "encumbrance": 30, "warmth": 35, "material_thickness": 2.5, "environmental_protection": 3, - "flags": [ "VARSIZE", "WATERPROOF" ] + "flags": [ "VARSIZE", "WATERPROOF" ], + "armor": [ { "encumbrance": 30, "coverage": 95, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "roller_blades", @@ -1104,13 +1022,11 @@ "symbol": "[", "looks_like": "rollerskates", "color": "light_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 25, "warmth": 20, "material_thickness": 3, "environmental_protection": 2, - "flags": [ "VARSIZE", "WATERPROOF", "ROLLER_INLINE", "REQUIRES_BALANCE" ] + "flags": [ "VARSIZE", "WATERPROOF", "ROLLER_INLINE", "REQUIRES_BALANCE" ], + "armor": [ { "encumbrance": 25, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "rollerskates", @@ -1128,13 +1044,11 @@ "symbol": "[", "looks_like": "roller_blades", "color": "brown", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 25, "warmth": 30, "material_thickness": 3, "environmental_protection": 2, - "flags": [ "VARSIZE", "WATERPROOF", "ROLLER_QUAD", "REQUIRES_BALANCE" ] + "flags": [ "VARSIZE", "WATERPROOF", "ROLLER_QUAD", "REQUIRES_BALANCE" ], + "armor": [ { "encumbrance": 25, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "shoes_birchbark", @@ -1149,12 +1063,10 @@ "symbol": "[", "looks_like": "clogs", "color": "light_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 50, - "encumbrance": 15, "warmth": 10, "material_thickness": 1.0, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 15, "coverage": 50, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "shoes_bowling", @@ -1170,12 +1082,10 @@ "symbol": "[", "looks_like": "dress_shoes", "color": "light_blue", - "covers": [ "foot_l", "foot_r" ], - "coverage": 80, - "encumbrance": 10, "warmth": 20, "material_thickness": 2, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 10, "coverage": 80, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "slippers", @@ -1192,12 +1102,10 @@ "symbol": "[", "looks_like": "socks_wool", "color": "brown", - "covers": [ "foot_l", "foot_r" ], - "coverage": 30, - "encumbrance": 30, "warmth": 25, "material_thickness": 0.5, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 30, "coverage": 30, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "sneakers", @@ -1213,12 +1121,10 @@ "symbol": "[", "looks_like": "shoes_bowling", "color": "light_blue", - "covers": [ "foot_l", "foot_r" ], - "coverage": 80, - "encumbrance": 4, "warmth": 20, "material_thickness": 1, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 4, "coverage": 80, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "straw_sandals", @@ -1234,11 +1140,9 @@ "symbol": "[", "looks_like": "leathersandals", "color": "light_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 30, - "encumbrance": 14, "material_thickness": 1, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 14, "coverage": 30, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "swim_fins", @@ -1253,12 +1157,10 @@ "symbol": "[", "looks_like": "clownshoes", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 85, - "encumbrance": 25, "warmth": 5, "material_thickness": 2.5, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "FIN" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "FIN" ], + "armor": [ { "encumbrance": 25, "coverage": 85, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "thigh_high_boots", @@ -1276,13 +1178,11 @@ "symbol": "[", "looks_like": "boots_larmor", "color": "dark_gray", - "covers": [ "foot_l", "foot_r", "leg_r", "leg_l" ], - "coverage": 80, - "encumbrance": 25, "warmth": 20, "material_thickness": 2, "environmental_protection": 2, - "flags": [ "VARSIZE", "WATERPROOF" ] + "flags": [ "VARSIZE", "WATERPROOF" ], + "armor": [ { "encumbrance": 25, "coverage": 80, "covers": [ "foot_l", "foot_r", "leg_r", "leg_l" ] } ] }, { "id": "wetsuit_booties", @@ -1297,13 +1197,11 @@ "symbol": "[", "looks_like": "boots_rubber", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 15, "warmth": 30, "material_thickness": 2, "environmental_protection": 1, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ], + "armor": [ { "encumbrance": 15, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "roller_shoes_off", @@ -1319,13 +1217,11 @@ "symbol": "[", "looks_like": "sneakers", "color": "light_blue", - "covers": [ "foot_l", "foot_r" ], - "coverage": 80, - "encumbrance": 4, "warmth": 20, "material_thickness": 2, "use_action": { "type": "transform", "target": "roller_shoes_on", "msg": "You pop the wheels out.", "moves": 500 }, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 4, "coverage": 80, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "roller_shoes_on", @@ -1340,13 +1236,11 @@ "symbol": "[", "looks_like": "sneakers", "color": "light_blue", - "covers": [ "foot_l", "foot_r" ], - "coverage": 80, - "encumbrance": 4, "warmth": 20, "material_thickness": 2, "use_action": { "type": "transform", "target": "roller_shoes_off", "msg": "You pop the wheels back in.", "moves": 500 }, - "flags": [ "VARSIZE", "ROLLER_ONE", "REQUIRES_BALANCE" ] + "flags": [ "VARSIZE", "ROLLER_ONE", "REQUIRES_BALANCE" ], + "armor": [ { "encumbrance": 4, "coverage": 80, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "chainmail_feet", @@ -1362,11 +1256,9 @@ "material": [ "iron", "cotton" ], "symbol": "[", "color": "light_red", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 20, "material_thickness": 4, - "flags": [ "VARSIZE", "STURDY" ] + "flags": [ "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "xl_chainmail_feet", @@ -1389,12 +1281,10 @@ "symbol": "[", "looks_like": "leg_warmers_xl", "color": "light_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 60, - "encumbrance": 7, "warmth": 40, "material_thickness": 2, - "flags": [ "VARSIZE", "OVERSIZE" ] + "flags": [ "VARSIZE", "OVERSIZE" ], + "armor": [ { "encumbrance": 7, "coverage": 60, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "nomex_socks", @@ -1410,13 +1300,11 @@ "symbol": "[", "looks_like": "socks", "color": "light_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 6, "warmth": 5, "material_thickness": 1, "environmental_protection": 2, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT", "STURDY" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT", "STURDY" ], + "armor": [ { "encumbrance": 6, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "xlnomex_socks", @@ -1441,11 +1329,10 @@ "symbol": "[", "looks_like": "socks_wool", "color": "white", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, "warmth": 5, "material_thickness": 0.2, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "xlsocks", @@ -1470,10 +1357,9 @@ "symbol": "[", "looks_like": "socks", "color": "light_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 80, "material_thickness": 0.3, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 80, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "socks_bag", @@ -1488,11 +1374,9 @@ "symbol": "[", "looks_like": "socks", "color": "light_blue", - "covers": [ "foot_l", "foot_r" ], - "coverage": 70, - "encumbrance": 3, "material_thickness": 0.01, - "flags": [ "WATERPROOF", "OVERSIZE" ] + "flags": [ "WATERPROOF", "OVERSIZE" ], + "armor": [ { "encumbrance": 3, "coverage": 70, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "socks_bowling", @@ -1508,10 +1392,9 @@ "symbol": "[", "looks_like": "socks", "color": "white", - "covers": [ "foot_l", "foot_r" ], - "coverage": 80, "warmth": 2, - "flags": [ "SKINTIGHT" ] + "flags": [ "SKINTIGHT" ], + "armor": [ { "coverage": 80, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "socks_wool", @@ -1526,12 +1409,10 @@ "symbol": "[", "looks_like": "socks", "color": "blue", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 5, "warmth": 30, "material_thickness": 0.3, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "encumbrance": 5, "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "xlsocks_wool", @@ -1556,12 +1437,10 @@ "symbol": "[", "looks_like": "leg_warmers", "color": "dark_gray", - "covers": [ "foot_l", "foot_r", "leg_r", "leg_l" ], - "coverage": 75, - "encumbrance": 5, "warmth": 10, "material_thickness": 0.1, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "encumbrance": 5, "coverage": 75, "covers": [ "foot_l", "foot_r", "leg_r", "leg_l" ] } ] }, { "id": "stockings_tent_legs", @@ -1576,12 +1455,10 @@ "symbol": "[", "looks_like": "leg_warmers", "color": "dark_gray", - "covers": [ "foot_l", "foot_r", "leg_r", "leg_l" ], - "coverage": 75, - "encumbrance": 10, "warmth": 10, "material_thickness": 0.1, - "flags": [ "VARSIZE", "SKINTIGHT", "OVERSIZE" ] + "flags": [ "VARSIZE", "SKINTIGHT", "OVERSIZE" ], + "armor": [ { "encumbrance": 10, "coverage": 75, "covers": [ "foot_l", "foot_r", "leg_r", "leg_l" ] } ] }, { "id": "tabi_dress", @@ -1596,11 +1473,10 @@ "symbol": "[", "looks_like": "socks", "color": "dark_gray", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, "warmth": 5, "material_thickness": 0.2, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "tabi_gi", @@ -1616,10 +1492,9 @@ "symbol": "[", "looks_like": "socks", "color": "white", - "covers": [ "foot_l", "foot_r" ], - "coverage": 100, "warmth": 5, "material_thickness": 0.2, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] } ] diff --git a/data/json/items/armor/cloaks.json b/data/json/items/armor/cloaks.json index 858f6cda17596..c7ca30a355133 100644 --- a/data/json/items/armor/cloaks.json +++ b/data/json/items/armor/cloaks.json @@ -14,13 +14,17 @@ "symbol": "[", "looks_like": "towel", "color": "light_red", - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 60, - "encumbrance": 50, "warmth": 20, "material_thickness": 0.3, "environmental_protection": 1, - "flags": [ "OVERSIZE", "OUTER", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "OVERSIZE", "OUTER", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ + { + "encumbrance": 50, + "coverage": 60, + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "cape_fp", @@ -37,12 +41,10 @@ "symbol": "]", "looks_like": "cloak", "color": "pink", - "covers": [ "torso" ], - "coverage": 50, - "encumbrance": 4, "warmth": 10, "material_thickness": 0.3, - "flags": [ "OVERSIZE", "BELTED" ] + "flags": [ "OVERSIZE", "BELTED" ], + "armor": [ { "encumbrance": 4, "coverage": 50, "covers": [ "torso" ] } ] }, { "id": "cloak", @@ -58,13 +60,11 @@ "symbol": "[", "looks_like": "coat_rain", "color": "green", - "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], - "coverage": 65, - "encumbrance": 4, "warmth": 30, "material_thickness": 0.4, "environmental_protection": 3, - "flags": [ "OVERSIZE", "HOOD", "OUTER" ] + "flags": [ "OVERSIZE", "HOOD", "OUTER" ], + "armor": [ { "encumbrance": 4, "coverage": 65, "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ] } ] }, { "id": "cloak_fur", @@ -80,13 +80,11 @@ "symbol": "[", "looks_like": "cloak_leather", "color": "brown", - "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], - "coverage": 65, - "encumbrance": 6, "warmth": 60, "material_thickness": 0.6, "environmental_protection": 3, - "flags": [ "OVERSIZE", "HOOD", "OUTER", "WATERPROOF", "RAINPROOF" ] + "flags": [ "OVERSIZE", "HOOD", "OUTER", "WATERPROOF", "RAINPROOF" ], + "armor": [ { "encumbrance": 6, "coverage": 65, "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ] } ] }, { "id": "cloak_leather", @@ -102,13 +100,11 @@ "symbol": "[", "looks_like": "cloak", "color": "dark_gray", - "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], - "coverage": 65, - "encumbrance": 6, "warmth": 40, "material_thickness": 1.5, "environmental_protection": 3, - "flags": [ "OVERSIZE", "HOOD", "OUTER", "WATERPROOF", "RAINPROOF" ] + "flags": [ "OVERSIZE", "HOOD", "OUTER", "WATERPROOF", "RAINPROOF" ], + "armor": [ { "encumbrance": 6, "coverage": 65, "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ] } ] }, { "id": "cloak_wool", @@ -124,13 +120,11 @@ "symbol": "[", "looks_like": "cloak", "color": "blue", - "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], - "coverage": 65, - "encumbrance": 5, "warmth": 50, "material_thickness": 0.5, "environmental_protection": 3, - "flags": [ "OVERSIZE", "HOOD", "OUTER" ] + "flags": [ "OVERSIZE", "HOOD", "OUTER" ], + "armor": [ { "encumbrance": 5, "coverage": 65, "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ] } ] }, { "id": "jedi_cloak", @@ -147,13 +141,17 @@ "symbol": "[", "looks_like": "robe", "color": "brown", - "covers": [ "leg_r", "leg_l", "torso", "arm_l", "arm_r", "head", "hand_l", "hand_r" ], - "coverage": 65, - "encumbrance": 3, "warmth": 50, "material_thickness": 0.3, "environmental_protection": 5, - "flags": [ "OVERSIZE", "OUTER", "HELMET_COMPAT" ] + "flags": [ "OVERSIZE", "OUTER", "HELMET_COMPAT" ], + "armor": [ + { + "encumbrance": 3, + "coverage": 65, + "covers": [ "leg_r", "leg_l", "torso", "arm_l", "arm_r", "head", "hand_l", "hand_r" ] + } + ] }, { "id": "optical_cloak", @@ -169,9 +167,6 @@ "symbol": "[", "looks_like": "cloak", "color": "light_gray", - "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], - "coverage": 65, - "encumbrance": 50, "warmth": 10, "material_thickness": 0.5, "environmental_protection": 4, @@ -184,7 +179,8 @@ "need_charges": 20, "need_charges_msg": "You don't have enough UPS charges to turn on the %s" }, - "flags": [ "USE_UPS", "OVERSIZE", "HOOD", "WATERPROOF", "OUTER", "VARSIZE" ] + "flags": [ "USE_UPS", "OVERSIZE", "HOOD", "WATERPROOF", "OUTER", "VARSIZE" ], + "armor": [ { "encumbrance": 50, "coverage": 65, "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ] } ] }, { "id": "optical_cloak_on", @@ -202,8 +198,7 @@ "menu_text": "Turn off", "msg": "The %s flickers for a moment as it becomes opaque.", "target": "optical_cloak" - }, - "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ] + } }, { "id": "poncho", @@ -219,13 +214,11 @@ "symbol": "[", "looks_like": "cloak", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 85, - "encumbrance": 5, "warmth": 35, "material_thickness": 1, "environmental_protection": 1, - "flags": [ "VARSIZE", "OUTER" ] + "flags": [ "VARSIZE", "OUTER" ], + "armor": [ { "encumbrance": 5, "coverage": 85, "covers": [ "torso" ] } ] }, { "id": "snuggie", @@ -241,12 +234,10 @@ "symbol": "[", "looks_like": "blanket", "color": "light_red", - "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], - "coverage": 85, - "encumbrance": 20, "warmth": 50, "material_thickness": 2, "environmental_protection": 1, - "flags": [ "OVERSIZE", "OUTER" ] + "flags": [ "OVERSIZE", "OUTER" ], + "armor": [ { "encumbrance": 20, "coverage": 85, "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ] } ] } ] diff --git a/data/json/items/armor/coats.json b/data/json/items/armor/coats.json index 952a1d622f620..7d21ef80c0f28 100644 --- a/data/json/items/armor/coats.json +++ b/data/json/items/armor/coats.json @@ -63,12 +63,10 @@ "symbol": "[", "looks_like": "robe", "color": "dark_gray", - "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], - "coverage": 90, - "encumbrance": 10, "warmth": 20, "material_thickness": 1, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 10, "coverage": 90, "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ] } ] }, { "id": "coat_fur", @@ -298,13 +296,11 @@ "symbol": "[", "looks_like": "coat_rain", "color": "light_gray", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 95, - "encumbrance": 12, "warmth": 10, "material_thickness": 0.2, "environmental_protection": 3, - "flags": [ "VARSIZE", "WATERPROOF", "RAINPROOF", "HOOD", "OUTER" ] + "flags": [ "VARSIZE", "WATERPROOF", "RAINPROOF", "HOOD", "OUTER" ], + "armor": [ { "encumbrance": 12, "coverage": 95, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "id": "coat_winter", @@ -757,12 +753,10 @@ "symbol": "[", "looks_like": "skirt", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 100, - "encumbrance": 6, "warmth": 10, "material_thickness": 0.3, - "flags": [ "VARSIZE", "STURDY" ] + "flags": [ "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": 6, "coverage": 100, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "hakama", @@ -777,12 +771,10 @@ "symbol": "[", "looks_like": "skirt", "color": "blue", - "covers": [ "leg_l", "leg_r" ], - "coverage": 100, - "encumbrance": 10, "warmth": 15, "material_thickness": 0.3, - "flags": [ "VARSIZE", "OUTER" ] + "flags": [ "VARSIZE", "OUTER" ], + "armor": [ { "encumbrance": 10, "coverage": 100, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "house_coat", @@ -1221,12 +1213,10 @@ "symbol": "[", "looks_like": "robe", "color": "white", - "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], - "coverage": 95, - "encumbrance": 10, "warmth": 10, "material_thickness": 0.5, - "flags": [ "VARSIZE", "STURDY" ] + "flags": [ "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": 10, "coverage": 95, "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ] } ] }, { "id": "karate_gi", @@ -1242,11 +1232,10 @@ "symbol": "[", "looks_like": "judo_gi", "color": "white", - "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], - "coverage": 80, "warmth": 5, "material_thickness": 0.5, - "flags": [ "VARSIZE", "STURDY" ] + "flags": [ "VARSIZE", "STURDY" ], + "armor": [ { "coverage": 80, "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ] } ] }, { "id": "kariginu", @@ -1263,12 +1252,10 @@ "symbol": "[", "looks_like": "robe", "color": "white", - "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], - "coverage": 100, - "encumbrance": 17, "warmth": 23, "material_thickness": 0.5, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 17, "coverage": 100, "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ] } ] }, { "id": "kasaya", @@ -1285,12 +1272,10 @@ "symbol": "[", "looks_like": "kimono", "color": "brown", - "covers": [ "leg_l", "leg_r", "torso" ], - "coverage": 90, - "encumbrance": 2, "warmth": 20, "material_thickness": 0.5, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 2, "coverage": 90, "covers": [ "leg_l", "leg_r", "torso" ] } ] }, { "id": "keikogi", @@ -1306,11 +1291,10 @@ "symbol": "[", "looks_like": "judo_gi", "color": "white", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 80, "warmth": 5, "material_thickness": 0.3, - "flags": [ "VARSIZE", "STURDY" ] + "flags": [ "VARSIZE", "STURDY" ], + "armor": [ { "coverage": 80, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "id": "kimono", @@ -1390,12 +1374,10 @@ "symbol": "[", "looks_like": "house_coat", "color": "black", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 60, - "encumbrance": 3, "warmth": 10, "material_thickness": 0.3, - "flags": [ "VARSIZE", "SUPER_FANCY", "OUTER" ] + "flags": [ "VARSIZE", "SUPER_FANCY", "OUTER" ], + "armor": [ { "encumbrance": 3, "coverage": 60, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "id": "kittel", @@ -1412,12 +1394,10 @@ "symbol": "[", "looks_like": "robe", "color": "white", - "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], - "coverage": 80, - "encumbrance": 10, "warmth": 17, "material_thickness": 0.3, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 10, "coverage": 80, "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ] } ] }, { "id": "peacoat", @@ -1555,12 +1535,10 @@ "symbol": "[", "looks_like": "trenchcoat", "color": "brown", - "covers": [ "leg_l", "leg_r", "torso" ], - "coverage": 90, - "encumbrance": 2, "warmth": 12, "material_thickness": 0.5, - "flags": [ "VARSIZE", "OUTER" ] + "flags": [ "VARSIZE", "OUTER" ], + "armor": [ { "encumbrance": 2, "coverage": 90, "covers": [ "leg_l", "leg_r", "torso" ] } ] }, { "id": "ski_jacket", @@ -1881,10 +1859,6 @@ "symbol": "[", "looks_like": "sleeveless_duster", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 90, - "encumbrance": 7, - "max_encumbrance": 15, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "1500 ml", "max_contains_weight": "4 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "1500 ml", "max_contains_weight": "4 kg", "moves": 80 }, @@ -1896,7 +1870,8 @@ "warmth": 15, "material_thickness": 0.3, "environmental_protection": 1, - "flags": [ "VARSIZE", "POCKETS", "OUTER" ] + "flags": [ "VARSIZE", "POCKETS", "OUTER" ], + "armor": [ { "encumbrance": [ 7, 15 ], "coverage": 90, "covers": [ "torso" ] } ] }, { "id": "sleeveless_trenchcoat_fur", @@ -1913,10 +1888,6 @@ "symbol": "[", "looks_like": "sleeveless_duster_fur", "color": "brown", - "covers": [ "torso" ], - "coverage": 90, - "encumbrance": 9, - "max_encumbrance": 19, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "1500 ml", "max_contains_weight": "4 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "1500 ml", "max_contains_weight": "4 kg", "moves": 80 }, @@ -1929,7 +1900,8 @@ "material_thickness": 3, "valid_mods": [ "steel_padded" ], "environmental_protection": 1, - "flags": [ "VARSIZE", "POCKETS", "OUTER" ] + "flags": [ "VARSIZE", "POCKETS", "OUTER" ], + "armor": [ { "encumbrance": [ 9, 19 ], "coverage": 90, "covers": [ "torso" ] } ] }, { "id": "sleeveless_trenchcoat_faux_fur", @@ -1956,10 +1928,6 @@ "symbol": "[", "looks_like": "sleeveless_duster_leather", "color": "brown", - "covers": [ "torso" ], - "coverage": 90, - "encumbrance": 8, - "max_encumbrance": 17, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "1500 ml", "max_contains_weight": "4 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "1500 ml", "max_contains_weight": "4 kg", "moves": 80 }, @@ -1972,7 +1940,8 @@ "material_thickness": 1.5, "valid_mods": [ "steel_padded" ], "environmental_protection": 1, - "flags": [ "VARSIZE", "POCKETS", "OUTER" ] + "flags": [ "VARSIZE", "POCKETS", "OUTER" ], + "armor": [ { "encumbrance": [ 8, 17 ], "coverage": 90, "covers": [ "torso" ] } ] }, { "id": "sleeveless_trenchcoat_survivor", @@ -1990,10 +1959,6 @@ "symbol": "[", "looks_like": "sleeveless_duster_survivor", "color": "brown", - "covers": [ "torso" ], - "coverage": 85, - "encumbrance": 7, - "max_encumbrance": 15, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "3 L", "max_contains_weight": "6 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "3 L", "max_contains_weight": "6 kg", "moves": 80 }, @@ -2006,7 +1971,8 @@ "material_thickness": 3, "valid_mods": [ "steel_padded" ], "environmental_protection": 3, - "flags": [ "VARSIZE", "POCKETS", "HOOD", "COLLAR", "STURDY", "WATERPROOF", "RAINPROOF", "OUTER" ] + "flags": [ "VARSIZE", "POCKETS", "HOOD", "COLLAR", "STURDY", "WATERPROOF", "RAINPROOF", "OUTER" ], + "armor": [ { "encumbrance": [ 7, 15 ], "coverage": 85, "covers": [ "torso" ] } ] }, { "id": "sleeveless_tunic", @@ -2022,12 +1988,10 @@ "symbol": "[", "looks_like": "vest_leather", "color": "dark_gray", - "covers": [ "torso", "leg_l", "leg_r" ], - "coverage": 65, - "encumbrance": 3, "warmth": 2, "material_thickness": 1, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 3, "coverage": 65, "covers": [ "torso", "leg_l", "leg_r" ] } ] }, { "id": "thawb", @@ -2044,12 +2008,10 @@ "symbol": "[", "looks_like": "robe", "color": "white", - "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], - "coverage": 90, - "encumbrance": 7, "warmth": 20, "material_thickness": 2, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 7, "coverage": 90, "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ] } ] }, { "id": "trenchcoat", @@ -2239,12 +2201,10 @@ "symbol": "[", "looks_like": "sweatshirt", "color": "dark_gray", - "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], - "coverage": 75, - "encumbrance": 3, "warmth": 2, "material_thickness": 0.3, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 3, "coverage": 75, "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ] } ] }, { "id": "tunic_rag", @@ -2259,12 +2219,10 @@ "symbol": "[", "looks_like": "tunic", "color": "light_red", - "covers": [ "torso", "leg_l", "leg_r" ], - "coverage": 65, - "encumbrance": 5, "warmth": 15, "material_thickness": 0.3, - "flags": [ "OVERSIZE" ] + "flags": [ "OVERSIZE" ], + "armor": [ { "encumbrance": 5, "coverage": 65, "covers": [ "torso", "leg_l", "leg_r" ] } ] }, { "id": "tux", @@ -2327,10 +2285,6 @@ "symbol": "[", "looks_like": "blazer", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 60, - "encumbrance": 2, - "max_encumbrance": 5, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -2356,7 +2310,8 @@ ], "warmth": 5, "material_thickness": 0.5, - "flags": [ "VARSIZE", "FANCY" ] + "flags": [ "VARSIZE", "FANCY" ], + "armor": [ { "encumbrance": [ 2, 5 ], "coverage": 60, "covers": [ "torso" ] } ] }, { "id": "winter_jacket_army", diff --git a/data/json/items/armor/eyewear.json b/data/json/items/armor/eyewear.json index 17c851be62bdd..fc9c14d567679 100644 --- a/data/json/items/armor/eyewear.json +++ b/data/json/items/armor/eyewear.json @@ -14,13 +14,11 @@ "symbol": "[", "looks_like": "sunglasses", "color": "light_gray", - "covers": [ "eyes" ], - "coverage": 80, - "encumbrance": 10, "material_thickness": 1, "environmental_protection": 1, "qualities": [ [ "GLARE", 3 ] ], - "flags": [ "SUN_GLASSES" ] + "flags": [ "SUN_GLASSES" ], + "armor": [ { "encumbrance": 10, "coverage": 80, "covers": [ "eyes" ] } ] }, { "id": "eyepatch_leather", @@ -36,11 +34,9 @@ "symbol": "[", "looks_like": "glasses_safety", "color": "light_gray", - "covers": [ "eyes" ], - "coverage": 50, - "encumbrance": 30, "material_thickness": 1, - "flags": [ "WATER_FRIENDLY", "SKINTIGHT" ] + "flags": [ "WATER_FRIENDLY", "SKINTIGHT" ], + "armor": [ { "encumbrance": 30, "coverage": 50, "covers": [ "eyes" ] } ] }, { "id": "fancy_sunglasses", @@ -57,13 +53,11 @@ "symbol": "[", "looks_like": "sunglasses", "color": "dark_gray", - "covers": [ "eyes" ], - "coverage": 95, - "encumbrance": 1, "material_thickness": 1, "environmental_protection": 1, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FRAGILE" ] + "flags": [ "FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FRAGILE" ], + "armor": [ { "encumbrance": 1, "coverage": 95, "covers": [ "eyes" ] } ] }, { "id": "fitover_sunglasses", @@ -80,13 +74,11 @@ "symbol": "[", "looks_like": "sunglasses", "color": "dark_gray", - "covers": [ "eyes" ], - "coverage": 90, - "encumbrance": 1, "material_thickness": 1, "environmental_protection": 1, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "WATER_FRIENDLY", "SUN_GLASSES", "VARSIZE", "OUTER", "FRAGILE" ] + "flags": [ "WATER_FRIENDLY", "SUN_GLASSES", "VARSIZE", "OUTER", "FRAGILE" ], + "armor": [ { "encumbrance": 1, "coverage": 90, "covers": [ "eyes" ] } ] }, { "id": "glasses_bal", @@ -104,14 +96,12 @@ "symbol": "[", "looks_like": "glasses_safety", "color": "dark_gray", - "covers": [ "eyes" ], - "coverage": 100, - "encumbrance": 5, "warmth": 5, "material_thickness": 3, "environmental_protection": 4, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "WATER_FRIENDLY", "SUN_GLASSES" ] + "flags": [ "WATER_FRIENDLY", "SUN_GLASSES" ], + "armor": [ { "encumbrance": 5, "coverage": 100, "covers": [ "eyes" ] } ] }, { "id": "glasses_bifocal", @@ -128,12 +118,11 @@ "symbol": "[", "looks_like": "glasses_eye", "color": "cyan", - "covers": [ "eyes" ], - "coverage": 75, "material_thickness": 1, "environmental_protection": 1, "use_action": { "type": "firestarter", "moves": 1000, "moves_slow": 25000, "need_sunlight": true }, - "flags": [ "WATER_FRIENDLY", "FIRESTARTER", "FIX_NEARSIGHT", "FIX_FARSIGHT", "FRAGILE" ] + "flags": [ "WATER_FRIENDLY", "FIRESTARTER", "FIX_NEARSIGHT", "FIX_FARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 75, "covers": [ "eyes" ] } ] }, { "id": "glasses_eye", @@ -150,11 +139,10 @@ "symbol": "[", "looks_like": "sunglasses", "color": "cyan", - "covers": [ "eyes" ], - "coverage": 75, "material_thickness": 1, "environmental_protection": 1, - "flags": [ "WATER_FRIENDLY", "FIX_NEARSIGHT", "FRAGILE" ] + "flags": [ "WATER_FRIENDLY", "FIX_NEARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 75, "covers": [ "eyes" ] } ] }, { "id": "glasses_monocle", @@ -172,11 +160,10 @@ "symbol": "[", "looks_like": "glasses_eye", "color": "cyan", - "covers": [ "eyes" ], - "coverage": 20, "material_thickness": 1, "environmental_protection": 1, - "flags": [ "FANCY", "FIX_NEARSIGHT", "FRAGILE" ] + "flags": [ "FANCY", "FIX_NEARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 20, "covers": [ "eyes" ] } ] }, { "id": "glasses_reading", @@ -194,12 +181,11 @@ "symbol": "[", "looks_like": "glasses_eye", "color": "cyan", - "covers": [ "eyes" ], - "coverage": 75, "material_thickness": 1, "environmental_protection": 1, "use_action": { "type": "firestarter", "moves": 1000, "moves_slow": 25000, "need_sunlight": true }, - "flags": [ "WATER_FRIENDLY", "FIRESTARTER", "FIX_FARSIGHT", "FRAGILE" ] + "flags": [ "WATER_FRIENDLY", "FIRESTARTER", "FIX_FARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 75, "covers": [ "eyes" ] } ] }, { "id": "glasses_safety", @@ -216,13 +202,11 @@ "symbol": "[", "looks_like": "glasses_eye", "color": "light_gray", - "covers": [ "eyes" ], - "coverage": 95, - "encumbrance": 5, "warmth": 5, "material_thickness": 2, "environmental_protection": 1, - "flags": [ "WATER_FRIENDLY", "OUTER" ] + "flags": [ "WATER_FRIENDLY", "OUTER" ], + "armor": [ { "encumbrance": 5, "coverage": 95, "covers": [ "eyes" ] } ] }, { "id": "goggles_ski", @@ -239,14 +223,12 @@ "symbol": "[", "looks_like": "sunglasses", "color": "dark_gray", - "covers": [ "eyes" ], - "coverage": 100, - "encumbrance": 15, "warmth": 50, "material_thickness": 2, "environmental_protection": 6, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "SUN_GLASSES" ] + "flags": [ "SUN_GLASSES" ], + "armor": [ { "encumbrance": 15, "coverage": 100, "covers": [ "eyes" ] } ] }, { "id": "goggles_welding", @@ -263,14 +245,12 @@ "symbol": "[", "looks_like": "glasses_safety", "color": "dark_gray", - "covers": [ "eyes" ], - "coverage": 100, - "encumbrance": 60, "warmth": 10, "material_thickness": 4, "environmental_protection": 6, "qualities": [ [ "GLARE", 2 ] ], - "flags": [ "SUN_GLASSES", "FLASH_PROTECTION" ] + "flags": [ "SUN_GLASSES", "FLASH_PROTECTION" ], + "armor": [ { "encumbrance": 60, "coverage": 100, "covers": [ "eyes" ] } ] }, { "id": "iggaak", @@ -287,13 +267,11 @@ "symbol": "[", "looks_like": "sunglasses", "color": "light_gray", - "covers": [ "eyes" ], - "coverage": 90, - "encumbrance": 9, "warmth": 5, "material_thickness": 1, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "WATER_FRIENDLY", "SUN_GLASSES" ] + "flags": [ "WATER_FRIENDLY", "SUN_GLASSES" ], + "armor": [ { "encumbrance": 9, "coverage": 90, "covers": [ "eyes" ] } ] }, { "id": "sunglasses", @@ -310,13 +288,11 @@ "symbol": "[", "looks_like": "glasses_eye", "color": "dark_gray", - "covers": [ "eyes" ], - "coverage": 85, - "encumbrance": 1, "material_thickness": 1, "environmental_protection": 1, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "WATER_FRIENDLY", "SUN_GLASSES", "FRAGILE" ] + "flags": [ "WATER_FRIENDLY", "SUN_GLASSES", "FRAGILE" ], + "armor": [ { "encumbrance": 1, "coverage": 85, "covers": [ "eyes" ] } ] }, { "id": "survivor_goggles", @@ -332,14 +308,12 @@ "symbol": "[", "looks_like": "glasses_bal", "color": "dark_gray", - "covers": [ "eyes" ], - "coverage": 100, - "encumbrance": 20, "warmth": 5, "material_thickness": 4, "environmental_protection": 15, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "WATER_FRIENDLY", "SUN_GLASSES", "OVERSIZE", "VARSIZE", "STURDY" ] + "flags": [ "WATER_FRIENDLY", "SUN_GLASSES", "OVERSIZE", "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 100, "covers": [ "eyes" ] } ] }, { "id": "sunglasses_bifocal", @@ -356,12 +330,11 @@ "symbol": "[", "looks_like": "glasses_eye", "color": "dark_gray", - "covers": [ "eyes" ], - "coverage": 75, "material_thickness": 1, "environmental_protection": 1, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "WATER_FRIENDLY", "SUN_GLASSES", "FIX_NEARSIGHT", "FIX_FARSIGHT", "FRAGILE" ] + "flags": [ "WATER_FRIENDLY", "SUN_GLASSES", "FIX_NEARSIGHT", "FIX_FARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 75, "covers": [ "eyes" ] } ] }, { "id": "sunglasses_eye", @@ -378,12 +351,11 @@ "symbol": "[", "looks_like": "sunglasses", "color": "dark_gray", - "covers": [ "eyes" ], - "coverage": 75, "material_thickness": 1, "environmental_protection": 1, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "WATER_FRIENDLY", "SUN_GLASSES", "FIX_NEARSIGHT", "FRAGILE" ] + "flags": [ "WATER_FRIENDLY", "SUN_GLASSES", "FIX_NEARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 75, "covers": [ "eyes" ] } ] }, { "id": "sunglasses_reading", @@ -401,12 +373,11 @@ "symbol": "[", "looks_like": "sunglasses", "color": "dark_gray", - "covers": [ "eyes" ], - "coverage": 75, "material_thickness": 1, "environmental_protection": 1, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "WATER_FRIENDLY", "SUN_GLASSES", "FIX_FARSIGHT", "FRAGILE" ] + "flags": [ "WATER_FRIENDLY", "SUN_GLASSES", "FIX_FARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 75, "covers": [ "eyes" ] } ] }, { "id": "fancy_glasses_bifocal", @@ -423,12 +394,11 @@ "symbol": "[", "looks_like": "glasses_bifocal", "color": "yellow", - "covers": [ "eyes" ], - "coverage": 75, "material_thickness": 1, "environmental_protection": 1, "use_action": { "type": "firestarter", "moves": 1000, "moves_slow": 25000, "need_sunlight": true }, - "flags": [ "FANCY", "WATER_FRIENDLY", "FIRESTARTER", "FIX_NEARSIGHT", "FIX_FARSIGHT", "FRAGILE" ] + "flags": [ "FANCY", "WATER_FRIENDLY", "FIRESTARTER", "FIX_NEARSIGHT", "FIX_FARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 75, "covers": [ "eyes" ] } ] }, { "id": "fancy_glasses_eye", @@ -445,11 +415,10 @@ "symbol": "[", "looks_like": "glasses_eye", "color": "yellow", - "covers": [ "eyes" ], - "coverage": 75, "material_thickness": 1, "environmental_protection": 1, - "flags": [ "FANCY", "WATER_FRIENDLY", "FIX_NEARSIGHT", "FRAGILE" ] + "flags": [ "FANCY", "WATER_FRIENDLY", "FIX_NEARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 75, "covers": [ "eyes" ] } ] }, { "id": "fancy_glasses_reading", @@ -467,12 +436,11 @@ "symbol": "[", "looks_like": "glasses_reading", "color": "yellow", - "covers": [ "eyes" ], - "coverage": 75, "material_thickness": 1, "environmental_protection": 1, "use_action": { "type": "firestarter", "moves": 1000, "moves_slow": 25000, "need_sunlight": true }, - "flags": [ "FANCY", "WATER_FRIENDLY", "FIRESTARTER", "FIX_FARSIGHT", "FRAGILE" ] + "flags": [ "FANCY", "WATER_FRIENDLY", "FIRESTARTER", "FIX_FARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 75, "covers": [ "eyes" ] } ] }, { "id": "fancy_sunglasses_bifocal", @@ -489,12 +457,11 @@ "symbol": "[", "looks_like": "sunglasses", "color": "dark_gray", - "covers": [ "eyes" ], - "coverage": 75, "material_thickness": 1, "environmental_protection": 1, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_NEARSIGHT", "FIX_FARSIGHT", "FRAGILE" ] + "flags": [ "FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_NEARSIGHT", "FIX_FARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 75, "covers": [ "eyes" ] } ] }, { "id": "fancy_sunglasses_eye", @@ -511,12 +478,11 @@ "symbol": "[", "looks_like": "sunglasses", "color": "dark_gray", - "covers": [ "eyes" ], - "coverage": 75, "material_thickness": 1, "environmental_protection": 1, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_NEARSIGHT", "FRAGILE" ] + "flags": [ "FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_NEARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 75, "covers": [ "eyes" ] } ] }, { "id": "fancy_sunglasses_reading", @@ -534,12 +500,11 @@ "symbol": "[", "looks_like": "sunglasses", "color": "dark_gray", - "covers": [ "eyes" ], - "coverage": 75, "material_thickness": 1, "environmental_protection": 1, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_FARSIGHT", "FRAGILE" ] + "flags": [ "FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_FARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 75, "covers": [ "eyes" ] } ] }, { "id": "transition_glasses_bifocal", @@ -556,12 +521,11 @@ "symbol": "[", "looks_like": "glasses_bifocal", "color": "light_gray", - "covers": [ "eyes" ], - "coverage": 75, "material_thickness": 1, "environmental_protection": 1, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_NEARSIGHT", "FIX_FARSIGHT", "FRAGILE" ] + "flags": [ "FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_NEARSIGHT", "FIX_FARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 75, "covers": [ "eyes" ] } ] }, { "id": "transition_glasses_eye", @@ -578,12 +542,11 @@ "symbol": "[", "looks_like": "glasses_eye", "color": "light_gray", - "covers": [ "eyes" ], - "coverage": 75, "material_thickness": 1, "environmental_protection": 1, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_NEARSIGHT", "FRAGILE" ] + "flags": [ "FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_NEARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 75, "covers": [ "eyes" ] } ] }, { "id": "transition_glasses_reading", @@ -601,12 +564,11 @@ "symbol": "[", "looks_like": "glasses_reading", "color": "light_gray", - "covers": [ "eyes" ], - "coverage": 75, "material_thickness": 1, "environmental_protection": 1, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_FARSIGHT", "FRAGILE" ] + "flags": [ "FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_FARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 75, "covers": [ "eyes" ] } ] }, { "id": "fancy_transition_glasses_bifocal", @@ -623,12 +585,11 @@ "symbol": "[", "looks_like": "glasses_bifocal", "color": "white", - "covers": [ "eyes" ], - "coverage": 75, "material_thickness": 1, "environmental_protection": 1, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "SUPER_FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_NEARSIGHT", "FIX_FARSIGHT", "FRAGILE" ] + "flags": [ "SUPER_FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_NEARSIGHT", "FIX_FARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 75, "covers": [ "eyes" ] } ] }, { "id": "fancy_transition_glasses_eye", @@ -645,12 +606,11 @@ "symbol": "[", "looks_like": "glasses_eye", "color": "white", - "covers": [ "eyes" ], - "coverage": 75, "material_thickness": 1, "environmental_protection": 1, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "SUPER_FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_NEARSIGHT", "FRAGILE" ] + "flags": [ "SUPER_FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_NEARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 75, "covers": [ "eyes" ] } ] }, { "id": "fancy_transition_glasses_reading", @@ -668,11 +628,10 @@ "symbol": "[", "looks_like": "glasses_reading", "color": "white", - "covers": [ "eyes" ], - "coverage": 75, "material_thickness": 1, "environmental_protection": 1, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "SUPER_FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_FARSIGHT", "FRAGILE" ] + "flags": [ "SUPER_FANCY", "WATER_FRIENDLY", "SUN_GLASSES", "FIX_FARSIGHT", "FRAGILE" ], + "armor": [ { "coverage": 75, "covers": [ "eyes" ] } ] } ] From ad6f22db0f5023373e6ededf39537f7c8078bbe9 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Tue, 6 Jul 2021 22:54:09 -0700 Subject: [PATCH 037/116] Convert armor to use armor_portion_data pt. 2 (#49680) I want to make changes to how armor data is specified, and I don't want to maintain two separate interfaces for it, so let's convert existing data to one interface. Items using copy-from were audited, and where they made changes, data was respecified as at the moment, copy-from modifying sub-elements of armor portion data is incorrect (there are lots of questions with no good answers there). --- data/json/items/armor/pets_horse_armor.json | 6 +- data/json/items/armor/power_armor.json | 86 ++--- data/json/items/armor/scarfs.json | 21 +- data/json/items/armor/sheath.json | 59 +--- data/json/items/armor/storage.json | 347 ++++++-------------- data/json/items/armor/suits_clothes.json | 10 +- data/json/items/armor/suits_protection.json | 126 ++++--- data/json/items/armor/swimming.json | 64 ++-- data/json/items/armor/torso_armor.json | 115 +++---- data/json/items/armor/torso_clothes.json | 128 +++----- data/json/items/armor/undergarment.json | 166 ++++------ 11 files changed, 417 insertions(+), 711 deletions(-) diff --git a/data/json/items/armor/pets_horse_armor.json b/data/json/items/armor/pets_horse_armor.json index cd8c13f12c555..c40da5ff3c023 100644 --- a/data/json/items/armor/pets_horse_armor.json +++ b/data/json/items/armor/pets_horse_armor.json @@ -156,9 +156,6 @@ "symbol": "[", "looks_like": "dump_pouch", "color": "green", - "covers": [ "hand_l", "hand_r" ], - "coverage": 50, - "encumbrance": 30, "warmth": 10, "material_thickness": 2, "flags": [ "BELTED", "WATER_FRIENDLY" ], @@ -178,6 +175,7 @@ "max_item_length": "60 cm", "moves": 200 } - ] + ], + "armor": [ { "encumbrance": 30, "coverage": 50, "covers": [ "hand_l", "hand_r" ] } ] } ] diff --git a/data/json/items/armor/power_armor.json b/data/json/items/armor/power_armor.json index 68603dbeb973c..17c990fb24d8a 100644 --- a/data/json/items/armor/power_armor.json +++ b/data/json/items/armor/power_armor.json @@ -16,9 +16,6 @@ "symbol": "[", "looks_like": "power_armor_basic", "color": "light_gray", - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 95, - "encumbrance": 40, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -83,7 +80,14 @@ "warmth": 50, "material_thickness": 8, "environmental_protection": 6, - "flags": [ "WATERPROOF", "STURDY" ] + "flags": [ "WATERPROOF", "STURDY" ], + "armor": [ + { + "encumbrance": 40, + "coverage": 95, + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "depowered_helmet", @@ -101,14 +105,12 @@ "symbol": "[", "looks_like": "power_armor_helmet_basic", "color": "light_gray", - "covers": [ "head", "eyes", "mouth" ], - "coverage": 95, - "encumbrance": 40, "warmth": 50, "material_thickness": 8, "environmental_protection": 6, "qualities": [ [ "GLARE", 2 ] ], - "flags": [ "WATERPROOF", "STURDY", "SUN_GLASSES" ] + "flags": [ "WATERPROOF", "STURDY", "SUN_GLASSES" ], + "armor": [ { "encumbrance": 40, "coverage": 95, "covers": [ "head", "eyes", "mouth" ] } ] }, { "id": "power_armor_basic", @@ -126,9 +128,6 @@ "symbol": "[", "looks_like": "depowered_armor", "color": "light_gray", - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 50, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -196,7 +195,14 @@ "environmental_protection": 16, "ammo": "battery", "use_action": { "type": "transform", "msg": "The %s engages.", "target": "power_armor_basic_on", "active": true }, - "flags": [ "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE" ] + "flags": [ "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE" ], + "armor": [ + { + "encumbrance": 50, + "coverage": 100, + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "power_armor_basic_on", @@ -209,8 +215,7 @@ "flags": [ "USE_UPS", "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE", "TRADER_AVOID", "CLIMATE_CONTROL" ], "power_draw": 4000000, "revert_to": "power_armor_basic", - "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "The %s armor disengages.", "target": "power_armor_basic" }, - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "The %s armor disengages.", "target": "power_armor_basic" } }, { "id": "power_armor_frame", @@ -228,8 +233,6 @@ "symbol": "[", "looks_like": "backpack_tactical_large", "color": "light_gray", - "coverage": 100, - "encumbrance": 40, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -242,7 +245,8 @@ ], "power_armor": true, "material_thickness": 10, - "flags": [ "WATERPROOF", "STURDY", "BELTED" ] + "flags": [ "WATERPROOF", "STURDY", "BELTED" ], + "armor": [ { "encumbrance": 40, "coverage": 100 } ] }, { "id": "power_armor_heavy", @@ -261,9 +265,6 @@ "symbol": "[", "looks_like": "power_armor_basic", "color": "dark_gray", - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 60, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -331,7 +332,14 @@ "environmental_protection": 16, "ammo": "battery", "use_action": { "type": "transform", "msg": "The %s engages.", "target": "power_armor_heavy_on", "active": true }, - "flags": [ "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE" ] + "flags": [ "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE" ], + "armor": [ + { + "encumbrance": 60, + "coverage": 100, + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "power_armor_heavy_on", @@ -344,8 +352,7 @@ "flags": [ "USE_UPS", "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE", "TRADER_AVOID", "CLIMATE_CONTROL" ], "power_draw": 4000000, "revert_to": "power_armor_heavy", - "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "The %s armor disengages.", "target": "power_armor_heavy" }, - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "The %s armor disengages.", "target": "power_armor_heavy" } }, { "id": "power_armor_helmet_basic", @@ -363,15 +370,13 @@ "symbol": "[", "looks_like": "depowered_helmet", "color": "light_gray", - "covers": [ "head", "eyes", "mouth" ], - "coverage": 100, - "encumbrance": 50, "warmth": 90, "power_armor": true, "material_thickness": 14, "environmental_protection": 16, "qualities": [ [ "GLARE", 2 ] ], - "flags": [ "WATCH", "WATERPROOF", "STURDY", "PARTIAL_DEAF", "THERMOMETER", "SUN_GLASSES" ] + "flags": [ "WATCH", "WATERPROOF", "STURDY", "PARTIAL_DEAF", "THERMOMETER", "SUN_GLASSES" ], + "armor": [ { "encumbrance": 50, "coverage": 100, "covers": [ "head", "eyes", "mouth" ] } ] }, { "id": "power_armor_helmet_heavy", @@ -389,15 +394,13 @@ "symbol": "[", "looks_like": "power_armor_helmet_basic", "color": "dark_gray", - "covers": [ "head", "eyes", "mouth" ], - "coverage": 100, - "encumbrance": 60, "warmth": 60, "power_armor": true, "material_thickness": 16, "environmental_protection": 16, "qualities": [ [ "GLARE", 2 ] ], - "flags": [ "WATCH", "WATERPROOF", "STURDY", "PARTIAL_DEAF", "THERMOMETER", "SUN_GLASSES" ] + "flags": [ "WATCH", "WATERPROOF", "STURDY", "PARTIAL_DEAF", "THERMOMETER", "SUN_GLASSES" ], + "armor": [ { "encumbrance": 60, "coverage": 100, "covers": [ "head", "eyes", "mouth" ] } ] }, { "id": "power_armor_helmet_light", @@ -415,15 +418,13 @@ "symbol": "[", "looks_like": "power_armor_helmet_basic", "color": "dark_gray", - "covers": [ "head", "eyes", "mouth" ], - "coverage": 100, - "encumbrance": 40, "warmth": 60, "power_armor": true, "material_thickness": 8, "environmental_protection": 16, "qualities": [ [ "GLARE", 1 ] ], - "flags": [ "WATCH", "WATERPROOF", "STURDY", "THERMOMETER", "SUN_GLASSES", "SWIM_GOGGLES" ] + "flags": [ "WATCH", "WATERPROOF", "STURDY", "THERMOMETER", "SUN_GLASSES", "SWIM_GOGGLES" ], + "armor": [ { "encumbrance": 40, "coverage": 100, "covers": [ "head", "eyes", "mouth" ] } ] }, { "id": "power_armor_light", @@ -441,9 +442,6 @@ "symbol": "[", "looks_like": "depowered_armor", "color": "dark_gray", - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 40, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -511,7 +509,14 @@ "environmental_protection": 16, "ammo": "battery", "use_action": { "type": "transform", "msg": "The %s engages.", "target": "power_armor_light_on", "active": true }, - "flags": [ "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE" ] + "flags": [ "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE" ], + "armor": [ + { + "encumbrance": 40, + "coverage": 100, + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "power_armor_light_on", @@ -524,7 +529,6 @@ "flags": [ "USE_UPS", "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE", "TRADER_AVOID", "CLIMATE_CONTROL" ], "power_draw": 4000000, "revert_to": "power_armor_light", - "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "The %s armor disengages.", "target": "power_armor_light" }, - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "The %s armor disengages.", "target": "power_armor_light" } } ] diff --git a/data/json/items/armor/scarfs.json b/data/json/items/armor/scarfs.json index 66b26acfdacf7..3cad996d5aa55 100644 --- a/data/json/items/armor/scarfs.json +++ b/data/json/items/armor/scarfs.json @@ -13,12 +13,10 @@ "symbol": "[", "looks_like": "scarf", "color": "white", - "covers": [ "mouth" ], - "coverage": 70, - "encumbrance": 20, "warmth": 40, "material_thickness": 1, - "flags": [ "OVERSIZE", "HOOD", "FANCY", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "OVERSIZE", "HOOD", "FANCY", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 20, "coverage": 70, "covers": [ "mouth" ] } ] }, { "id": "headscarf", @@ -35,12 +33,10 @@ "symbol": "[", "looks_like": "scarf", "color": "yellow", - "covers": [ "head" ], - "coverage": 70, - "encumbrance": 4, "warmth": 7, "material_thickness": 0.1, - "flags": [ "OVERSIZE", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "OVERSIZE", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 4, "coverage": 70, "covers": [ "head" ] } ] }, { "id": "keffiyeh", @@ -56,13 +52,11 @@ "symbol": "[", "looks_like": "scarf", "color": "white", - "covers": [ "mouth" ], - "coverage": 85, - "encumbrance": 10, "warmth": 30, "material_thickness": 1, "environmental_protection": 2, - "flags": [ "OVERSIZE", "HOOD", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "OVERSIZE", "HOOD", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 10, "coverage": 85, "covers": [ "mouth" ] } ] }, { "id": "marloss_scarf", @@ -71,7 +65,6 @@ "looks_like": "scarf", "name": { "str": "cyan scarf" }, "description": "A simple cloth scarf worn by Marloss Voices. Wherever the Voices go, long sought peace soon follows, for better or for worse.", - "color": "cyan", - "covers": [ "mouth" ] + "color": "cyan" } ] diff --git a/data/json/items/armor/sheath.json b/data/json/items/armor/sheath.json index d91fae5597491..e97fc73168821 100644 --- a/data/json/items/armor/sheath.json +++ b/data/json/items/armor/sheath.json @@ -12,9 +12,6 @@ "symbol": "[", "looks_like": "sheath", "color": "brown", - "covers": [ "torso" ], - "coverage": 5, - "encumbrance": 2, "material_thickness": 1, "pocket_data": [ { @@ -27,7 +24,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Sheath axe", "holster_msg": "You sheath your %s" }, - "flags": [ "NONCONDUCTIVE", "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] + "flags": [ "NONCONDUCTIVE", "WAIST", "OVERSIZE", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 2, "coverage": 5, "covers": [ "torso" ] } ] }, { "id": "baldric", @@ -43,10 +41,6 @@ "symbol": "[", "looks_like": "sheath", "color": "brown", - "covers": [ "torso" ], - "coverage": 10, - "encumbrance": 3, - "max_encumbrance": 5, "material_thickness": 1, "pocket_data": [ { @@ -60,7 +54,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Sheath sword", "holster_msg": "You sheath your %s" }, - "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 3, 5 ], "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "bootsheath", @@ -76,11 +71,7 @@ "symbol": "[", "looks_like": "sheath", "color": "brown", - "covers": [ "foot_l", "foot_r" ], "sided": true, - "coverage": 5, - "encumbrance": 2, - "max_encumbrance": 3, "material_thickness": 1, "pocket_data": [ { @@ -94,7 +85,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Sheath knife", "holster_msg": "You sheath your %s" }, - "flags": [ "BELTED", "OVERSIZE", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY", "NOT_FOOTWEAR" ] + "flags": [ "BELTED", "OVERSIZE", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY", "NOT_FOOTWEAR" ], + "armor": [ { "encumbrance": [ 2, 3 ], "coverage": 5, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "bootsheath_birchbark", @@ -110,11 +102,7 @@ "symbol": "[", "looks_like": "bootsheath", "color": "brown", - "covers": [ "foot_l", "foot_r" ], "sided": true, - "coverage": 5, - "encumbrance": 2, - "max_encumbrance": 3, "material_thickness": 1, "pocket_data": [ { @@ -128,7 +116,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Sheath knife", "holster_msg": "You sheath your %s" }, - "flags": [ "BELTED", "OVERSIZE", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY", "NOT_FOOTWEAR" ] + "flags": [ "BELTED", "OVERSIZE", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY", "NOT_FOOTWEAR" ], + "armor": [ { "encumbrance": [ 2, 3 ], "coverage": 5, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "bscabbard", @@ -144,10 +133,6 @@ "symbol": "[", "looks_like": "baldric", "color": "brown", - "covers": [ "torso" ], - "coverage": 10, - "encumbrance": 6, - "max_encumbrance": 10, "material_thickness": 1, "pocket_data": [ { @@ -161,7 +146,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Sheath sword", "holster_msg": "You sheath your %s" }, - "flags": [ "BELTED", "OVERSIZE", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "OVERSIZE", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 6, 10 ], "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "scabbard", @@ -177,11 +163,7 @@ "symbol": "[", "looks_like": "holster", "color": "brown", - "covers": [ "leg_l", "leg_r" ], "sided": true, - "coverage": 15, - "encumbrance": 3, - "max_encumbrance": 4, "material_thickness": 1, "pocket_data": [ { @@ -195,7 +177,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Sheath sword", "holster_msg": "You sheath your %s" }, - "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 3, 4 ], "coverage": 15, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "sheath", @@ -210,10 +193,7 @@ "symbol": "|", "looks_like": "scabbard", "color": "brown", - "covers": [ "leg_l", "leg_r" ], "sided": true, - "coverage": 5, - "max_encumbrance": 1, "material_thickness": 1, "pocket_data": [ { @@ -227,7 +207,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Sheath knife", "holster_msg": "You sheath your %s" }, - "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ], + "armor": [ { "coverage": 5, "covers": [ "leg_l", "leg_r" ], "encumbrance": [ 0, 1 ] } ] }, { "id": "sheath_birchbark", @@ -242,10 +223,7 @@ "symbol": "|", "looks_like": "sheath", "color": "brown", - "covers": [ "leg_l", "leg_r" ], "sided": true, - "coverage": 5, - "max_encumbrance": 1, "material_thickness": 1, "pocket_data": [ { @@ -259,7 +237,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Sheath knife", "holster_msg": "You sheath your %s" }, - "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ], + "armor": [ { "coverage": 5, "covers": [ "leg_l", "leg_r" ], "encumbrance": [ 0, 1 ] } ] }, { "id": "spearsling", @@ -275,9 +254,6 @@ "symbol": "[", "looks_like": "bscabbard", "color": "brown", - "covers": [ "torso" ], - "coverage": 5, - "encumbrance": 2, "material_thickness": 1, "pocket_data": [ { @@ -290,6 +266,7 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Holster spear", "holster_msg": "You holster your %s." }, - "flags": [ "BELTED", "OVERSIZE", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "OVERSIZE", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 2, "coverage": 5, "covers": [ "torso" ] } ] } ] diff --git a/data/json/items/armor/storage.json b/data/json/items/armor/storage.json index fb9ba31d5f2fb..b1611517c4da8 100644 --- a/data/json/items/armor/storage.json +++ b/data/json/items/armor/storage.json @@ -12,10 +12,6 @@ "symbol": "[", "looks_like": "ragpouch", "color": "green", - "covers": [ "torso" ], - "coverage": 30, - "encumbrance": 2, - "max_encumbrance": 25, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -27,7 +23,8 @@ ], "warmth": 6, "material_thickness": 2, - "flags": [ "BELTED" ] + "flags": [ "BELTED" ], + "armor": [ { "encumbrance": [ 2, 25 ], "coverage": 30, "covers": [ "torso" ] } ] }, { "id": "backpack_hiking", @@ -42,10 +39,6 @@ "symbol": "[", "looks_like": "backpack", "color": "brown", - "covers": [ "torso" ], - "coverage": 50, - "encumbrance": 10, - "max_encumbrance": 40, "warmth": 10, "material_thickness": 2, "pocket_data": [ @@ -99,7 +92,8 @@ } ], "use_action": { "type": "holster", "holster_prompt": "Sheath blade", "holster_msg": "You sheath your %s" }, - "flags": [ "BELTED", "WATERPROOF", "ONLY_ONE", "OVERSIZE" ] + "flags": [ "BELTED", "WATERPROOF", "ONLY_ONE", "OVERSIZE" ], + "armor": [ { "encumbrance": [ 10, 40 ], "coverage": 50, "covers": [ "torso" ] } ] }, { "id": "backpack_giant", @@ -115,10 +109,6 @@ "symbol": "[", "looks_like": "backpack", "color": "green", - "covers": [ "torso", "leg_l", "leg_r" ], - "coverage": 75, - "encumbrance": 20, - "max_encumbrance": 60, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -131,7 +121,8 @@ ], "warmth": 5, "material_thickness": 2, - "flags": [ "BELTED" ] + "flags": [ "BELTED" ], + "armor": [ { "encumbrance": [ 20, 60 ], "coverage": 75, "covers": [ "torso", "leg_l", "leg_r" ] } ] }, { "id": "backpack_leather", @@ -146,10 +137,6 @@ "symbol": "[", "looks_like": "backpack", "color": "brown", - "covers": [ "torso" ], - "coverage": 30, - "encumbrance": 4, - "max_encumbrance": 26, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -161,7 +148,8 @@ ], "warmth": 9, "material_thickness": 3, - "flags": [ "BELTED", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 4, 26 ], "coverage": 30, "covers": [ "torso" ] } ] }, { "id": "backpack_tactical_large", @@ -176,10 +164,6 @@ "symbol": "[", "looks_like": "backpack", "color": "green", - "covers": [ "torso" ], - "coverage": 50, - "encumbrance": 10, - "max_encumbrance": 55, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -216,7 +200,8 @@ ], "warmth": 10, "material_thickness": 2, - "flags": [ "BELTED", "WATERPROOF", "ONLY_ONE", "OVERSIZE" ] + "flags": [ "BELTED", "WATERPROOF", "ONLY_ONE", "OVERSIZE" ], + "armor": [ { "encumbrance": [ 10, 55 ], "coverage": 50, "covers": [ "torso" ] } ] }, { "id": "basket_laundry", @@ -263,10 +248,6 @@ "symbol": "[", "looks_like": "rucksack", "color": "black", - "covers": [ "torso" ], - "coverage": 50, - "encumbrance": 16, - "max_encumbrance": 65, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -303,7 +284,8 @@ ], "warmth": 10, "material_thickness": 2, - "flags": [ "BELTED", "WATERPROOF", "ONLY_ONE", "OVERSIZE" ] + "flags": [ "BELTED", "WATERPROOF", "ONLY_ONE", "OVERSIZE" ], + "armor": [ { "encumbrance": [ 16, 65 ], "coverage": 50, "covers": [ "torso" ] } ] }, { "id": "bindle", @@ -352,14 +334,12 @@ "moves": 300 } ], - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 20, "warmth": 5, "bashing": 16, "cutting": 4, "price": 3500, - "flags": [ "BELTED", "OVERSIZE", "NO_REPAIR" ] + "flags": [ "BELTED", "OVERSIZE", "NO_REPAIR" ], + "armor": [ { "encumbrance": 20, "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "briefcase", @@ -377,10 +357,7 @@ "symbol": "[", "looks_like": "plastic_shopping_bag", "color": "light_gray", - "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], "sided": true, - "coverage": 10, - "encumbrance": 30, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -392,7 +369,8 @@ } ], "material_thickness": 2, - "flags": [ "FANCY", "OVERSIZE", "BELTED", "RESTRICT_HANDS", "WATER_FRIENDLY" ] + "flags": [ "FANCY", "OVERSIZE", "BELTED", "RESTRICT_HANDS", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 30, "coverage": 10, "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ] } ] }, { "id": "case_violin", @@ -410,10 +388,7 @@ "symbol": "&", "looks_like": "briefcase", "color": "dark_gray", - "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], "sided": true, - "coverage": 10, - "encumbrance": 30, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -425,7 +400,8 @@ } ], "material_thickness": 5, - "flags": [ "FANCY", "OVERSIZE", "BELTED", "RESTRICT_HANDS", "WATER_FRIENDLY" ] + "flags": [ "FANCY", "OVERSIZE", "BELTED", "RESTRICT_HANDS", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 30, "coverage": 10, "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ] } ] }, { "id": "daypack", @@ -442,11 +418,7 @@ "price": 5500, "price_postapoc": 500, "material": [ "cotton", "plastic" ], - "covers": [ "torso" ], - "coverage": 50, "material_thickness": 1, - "encumbrance": 2, - "max_encumbrance": 18, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -458,7 +430,8 @@ } ], "warmth": 5, - "flags": [ "BELTED", "OVERSIZE", "STURDY" ] + "flags": [ "BELTED", "OVERSIZE", "STURDY" ], + "armor": [ { "encumbrance": [ 2, 18 ], "coverage": 50, "covers": [ "torso" ] } ] }, { "id": "dive_bag", @@ -474,10 +447,6 @@ "symbol": "[", "looks_like": "backpack", "color": "yellow", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 2, - "max_encumbrance": 30, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -488,7 +457,8 @@ } ], "material_thickness": 1, - "flags": [ "WATER_FRIENDLY", "BELTED" ] + "flags": [ "WATER_FRIENDLY", "BELTED" ], + "armor": [ { "encumbrance": [ 2, 30 ], "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "duffelbag", @@ -503,10 +473,6 @@ "symbol": "[", "looks_like": "rucksack", "color": "green", - "covers": [ "torso" ], - "coverage": 50, - "encumbrance": 5, - "max_encumbrance": 35, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -519,7 +485,8 @@ ], "warmth": 10, "material_thickness": 2, - "flags": [ "BELTED", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 5, 35 ], "coverage": 50, "covers": [ "torso" ] } ] }, { "id": "dump_pouch", @@ -536,10 +503,6 @@ "symbol": "[", "looks_like": "holster", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 10, - "encumbrance": 1, - "max_encumbrance": 3, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -551,7 +514,8 @@ } ], "material_thickness": 0.5, - "flags": [ "WAIST", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 1, 3 ], "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "fanny", @@ -568,10 +532,6 @@ "symbol": "[", "looks_like": "holster", "color": "green", - "covers": [ "torso" ], - "coverage": 10, - "encumbrance": 1, - "max_encumbrance": 3, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -583,7 +543,8 @@ } ], "material_thickness": 0.1, - "flags": [ "WAIST", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 1, 3 ], "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "golf_bag", @@ -599,10 +560,6 @@ "symbol": "[", "looks_like": "quiver_large", "color": "green", - "covers": [ "torso" ], - "coverage": 35, - "encumbrance": 30, - "max_encumbrance": 35, "//": "The main section of the golf bag actually assumes things will stick out of it, but specifically contains them, so some extra wiggle room was added.", "pocket_data": [ { @@ -623,7 +580,8 @@ "warmth": 5, "material_thickness": 3, "flags": [ "BELTED", "OVERSIZE" ], - "use_action": { "type": "holster", "holster_prompt": "Sheath golf club", "holster_msg": "You awkwardly sheath your %s" } + "use_action": { "type": "holster", "holster_prompt": "Sheath golf club", "holster_msg": "You awkwardly sheath your %s" }, + "armor": [ { "encumbrance": [ 30, 35 ], "coverage": 35, "covers": [ "torso" ] } ] }, { "id": "hide_bag", @@ -637,12 +595,9 @@ "color": "pink", "proportional": { "weight": 6.0, "volume": 6.0, "price": 6.0, "quench": 6.0, "calories": 6.0, "healthy": 6.0, "fun": 6.0 }, "armor_data": { - "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], "sided": true, - "coverage": 5, - "encumbrance": 10, - "max_encumbrance": 100, - "material_thickness": 0.1 + "material_thickness": 0.1, + "armor": [ { "encumbrance": [ 10, 100 ], "coverage": 5, "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ] } ] }, "pocket_data": [ { @@ -668,12 +623,9 @@ "price_postapoc": 10, "proportional": { "weight": 6.0, "volume": 6.0, "price": 6.0, "quench": 6.0, "calories": 6.0, "healthy": 6.0, "fun": 6.0 }, "armor_data": { - "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], "sided": true, - "coverage": 5, - "encumbrance": 10, - "max_encumbrance": 100, - "material_thickness": 0.1 + "material_thickness": 0.1, + "armor": [ { "encumbrance": [ 10, 100 ], "coverage": 5, "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ] } ] }, "pocket_data": [ { @@ -724,9 +676,6 @@ "symbol": "[", "looks_like": "backpack", "color": "green", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 30, "warmth": 5, "material_thickness": 2, "pocket_data": [ @@ -738,7 +687,8 @@ "rigid": true } ], - "flags": [ "OVERSIZE", "BELTED", "WATER_FRIENDLY" ] + "flags": [ "OVERSIZE", "BELTED", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 30, "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "leather_pouch", @@ -755,10 +705,6 @@ "symbol": "[", "looks_like": "holster", "color": "brown", - "covers": [ "torso" ], - "coverage": 15, - "encumbrance": 1, - "max_encumbrance": 3, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -769,7 +715,8 @@ } ], "material_thickness": 0.1, - "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 1, 3 ], "coverage": 15, "covers": [ "torso" ] } ] }, { "id": "legrig", @@ -783,10 +730,6 @@ "material": [ "cotton" ], "symbol": "[", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 20, - "encumbrance": 2, - "max_encumbrance": 5, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -806,7 +749,8 @@ } ], "material_thickness": 0.2, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "BELTED" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "BELTED" ], + "armor": [ { "encumbrance": [ 2, 5 ], "coverage": 20, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "armrig", @@ -821,11 +765,7 @@ "symbol": "[", "looks_like": "armguard_soft", "color": "dark_gray", - "covers": [ "arm_l", "arm_r" ], "sided": true, - "coverage": 20, - "encumbrance": 2, - "max_encumbrance": 7, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -836,7 +776,8 @@ } ], "material_thickness": 2, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "BELTED" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "BELTED" ], + "armor": [ { "encumbrance": [ 2, 7 ], "coverage": 20, "covers": [ "arm_l", "arm_r" ] } ] }, { "id": "makeshift_knapsack", @@ -851,10 +792,6 @@ "symbol": "[", "looks_like": "ragpouch", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 30, - "encumbrance": 2, - "max_encumbrance": 9, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -866,7 +803,8 @@ ], "warmth": 5, "material_thickness": 0.2, - "flags": [ "BELTED", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 2, 9 ], "coverage": 30, "covers": [ "torso" ] } ] }, { "id": "makeshift_sling", @@ -882,10 +820,6 @@ "symbol": "[", "looks_like": "ragpouch", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 4, - "max_encumbrance": 15, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -898,7 +832,8 @@ ], "warmth": 10, "material_thickness": 1, - "flags": [ "OVERSIZE", "BELTED", "WATER_FRIENDLY" ] + "flags": [ "OVERSIZE", "BELTED", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 4, 15 ], "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "mbag", @@ -917,10 +852,6 @@ "symbol": "[", "looks_like": "purse", "color": "green", - "covers": [ "torso" ], - "coverage": 30, - "encumbrance": 8, - "max_encumbrance": 12, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -932,7 +863,8 @@ } ], "material_thickness": 1, - "flags": [ "BELTED", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 8, 12 ], "coverage": 30, "covers": [ "torso" ] } ] }, { "id": "molle_pack", @@ -948,10 +880,6 @@ "symbol": "[", "looks_like": "backpack", "color": "green", - "covers": [ "torso" ], - "coverage": 35, - "encumbrance": 5, - "max_encumbrance": 20, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -988,7 +916,8 @@ ], "warmth": 10, "material_thickness": 2, - "flags": [ "BELTED", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 5, 20 ], "coverage": 35, "covers": [ "torso" ] } ] }, { "id": "net_backpack", @@ -1001,10 +930,6 @@ "material": [ "cotton" ], "symbol": "[", "color": "green", - "covers": [ "torso" ], - "coverage": 20, - "encumbrance": 1, - "max_encumbrance": 25, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1016,7 +941,8 @@ } ], "material_thickness": 1, - "flags": [ "BELTED", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 1, 25 ], "coverage": 20, "covers": [ "torso" ] } ] }, { "id": "petpack", @@ -1031,9 +957,6 @@ "symbol": "[", "looks_like": "backpack", "color": "blue", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 35, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1048,7 +971,8 @@ "material_thickness": 2, "properties": [ [ "creature_size_capacity", "SMALL" ] ], "use_action": [ "CAPTURE_MONSTER_ACT" ], - "flags": [ "BELTED", "WATERPROOF" ] + "flags": [ "BELTED", "WATERPROOF" ], + "armor": [ { "encumbrance": 35, "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "plastic_shopping_bag", @@ -1088,10 +1012,6 @@ "symbol": "[", "looks_like": "ragpouch", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 10, - "encumbrance": 2, - "max_encumbrance": 7, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1102,7 +1022,8 @@ } ], "material_thickness": 1, - "flags": [ "FANCY", "BELTED", "WATER_FRIENDLY" ] + "flags": [ "FANCY", "BELTED", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 2, 7 ], "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "ragpouch", @@ -1118,10 +1039,6 @@ "material": [ "cotton" ], "symbol": "[", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 15, - "encumbrance": 5, - "max_encumbrance": 10, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1132,7 +1049,8 @@ } ], "material_thickness": 0.2, - "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] + "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 5, 10 ], "coverage": 15, "covers": [ "torso" ] } ] }, { "id": "rucksack", @@ -1148,10 +1066,6 @@ "symbol": "[", "looks_like": "backpack", "color": "green", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 10, - "max_encumbrance": 50, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1188,7 +1102,8 @@ ], "warmth": 8, "material_thickness": 0.2, - "flags": [ "BELTED", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 10, 50 ], "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "runner_bag", @@ -1205,10 +1120,6 @@ "symbol": "[", "looks_like": "backpack", "color": "green", - "covers": [ "torso" ], - "coverage": 20, - "encumbrance": 1, - "max_encumbrance": 6, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1221,7 +1132,8 @@ ], "warmth": 2, "material_thickness": 0.1, - "flags": [ "BELTED", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 1, 6 ], "coverage": 20, "covers": [ "torso" ] } ] }, { "id": "slingpack", @@ -1239,10 +1151,6 @@ "symbol": "[", "looks_like": "purse", "color": "green", - "covers": [ "torso" ], - "coverage": 30, - "encumbrance": 2, - "max_encumbrance": 9, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1255,7 +1163,8 @@ ], "warmth": 2, "material_thickness": 1, - "flags": [ "BELTED", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 2, 9 ], "coverage": 30, "covers": [ "torso" ] } ] }, { "id": "straw_basket", @@ -1271,10 +1180,7 @@ "symbol": "[", "looks_like": "plastic_shopping_bag", "color": "light_gray", - "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], "sided": true, - "coverage": 4, - "encumbrance": 30, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1286,7 +1192,8 @@ } ], "material_thickness": 2, - "flags": [ "OVERSIZE", "BELTED", "RESTRICT_HANDS", "WATER_FRIENDLY" ] + "flags": [ "OVERSIZE", "BELTED", "RESTRICT_HANDS", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 30, "coverage": 4, "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ] } ] }, { "id": "suitcase_l", @@ -1303,10 +1210,7 @@ "symbol": "[", "looks_like": "suitcase_m", "color": "red", - "covers": [ "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r" ], "sided": true, - "coverage": 5, - "encumbrance": 70, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1318,7 +1222,8 @@ } ], "material_thickness": 3, - "flags": [ "OVERSIZE", "BELTED", "RESTRICT_HANDS", "WATER_FRIENDLY" ] + "flags": [ "OVERSIZE", "BELTED", "RESTRICT_HANDS", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 70, "coverage": 5, "covers": [ "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r" ] } ] }, { "id": "suitcase_m", @@ -1334,10 +1239,7 @@ "symbol": "[", "looks_like": "briefcase", "color": "blue", - "covers": [ "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r" ], "sided": true, - "coverage": 5, - "encumbrance": 50, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1349,7 +1251,8 @@ } ], "material_thickness": 3, - "flags": [ "OVERSIZE", "BELTED", "RESTRICT_HANDS", "WATER_FRIENDLY" ] + "flags": [ "OVERSIZE", "BELTED", "RESTRICT_HANDS", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 50, "coverage": 5, "covers": [ "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r" ] } ] }, { "id": "survivor_duffel_bag", @@ -1364,10 +1267,6 @@ "symbol": "[", "looks_like": "rucksack", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 8, - "max_encumbrance": 30, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1380,7 +1279,8 @@ ], "warmth": 10, "material_thickness": 2, - "flags": [ "WATER_FRIENDLY", "STURDY", "BELTED", "OVERSIZE" ] + "flags": [ "WATER_FRIENDLY", "STURDY", "BELTED", "OVERSIZE" ], + "armor": [ { "encumbrance": [ 8, 30 ], "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "survivor_pack", @@ -1395,10 +1295,6 @@ "symbol": "[", "looks_like": "backpack", "color": "brown", - "covers": [ "torso" ], - "coverage": 30, - "encumbrance": 3, - "max_encumbrance": 24, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1411,7 +1307,8 @@ ], "warmth": 6, "material_thickness": 2, - "flags": [ "WATER_FRIENDLY", "STURDY", "BELTED" ] + "flags": [ "WATER_FRIENDLY", "STURDY", "BELTED" ], + "armor": [ { "encumbrance": [ 3, 24 ], "coverage": 30, "covers": [ "torso" ] } ] }, { "id": "survivor_rucksack", @@ -1426,10 +1323,6 @@ "symbol": "[", "looks_like": "rucksack", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 3, - "max_encumbrance": 28, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1442,7 +1335,8 @@ ], "warmth": 8, "material_thickness": 2, - "flags": [ "WATER_FRIENDLY", "STURDY", "BELTED", "OVERSIZE" ] + "flags": [ "WATER_FRIENDLY", "STURDY", "BELTED", "OVERSIZE" ], + "armor": [ { "encumbrance": [ 3, 28 ], "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "survivor_runner_pack", @@ -1457,10 +1351,6 @@ "symbol": "[", "looks_like": "backpack", "color": "brown", - "covers": [ "torso" ], - "coverage": 30, - "encumbrance": 3, - "max_encumbrance": 12, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1473,7 +1363,8 @@ ], "warmth": 2, "material_thickness": 2, - "flags": [ "WATER_FRIENDLY", "STURDY", "BELTED" ] + "flags": [ "WATER_FRIENDLY", "STURDY", "BELTED" ], + "armor": [ { "encumbrance": [ 3, 12 ], "coverage": 30, "covers": [ "torso" ] } ] }, { "id": "swag_bag", @@ -1519,10 +1410,6 @@ "symbol": "[", "looks_like": "backpack", "color": "yellow", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 3, - "max_encumbrance": 25, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1559,7 +1446,8 @@ ], "warmth": 8, "material_thickness": 2, - "flags": [ "BELTED", "WATERPROOF" ] + "flags": [ "BELTED", "WATERPROOF" ], + "armor": [ { "encumbrance": [ 3, 25 ], "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "vest", @@ -1575,10 +1463,6 @@ "symbol": "[", "looks_like": "tank_top", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 60, - "encumbrance": 2, - "max_encumbrance": 5, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1611,7 +1495,8 @@ ], "warmth": 5, "material_thickness": 0.4, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": [ 2, 5 ], "coverage": 60, "covers": [ "torso" ] } ] }, { "id": "wicker_backpack", @@ -1625,10 +1510,6 @@ "material": [ "dry_plant" ], "symbol": "[", "color": "green", - "covers": [ "torso" ], - "coverage": 25, - "encumbrance": 5, - "max_encumbrance": 20, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1640,7 +1521,8 @@ } ], "material_thickness": 2, - "flags": [ "BELTED", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 5, 20 ], "coverage": 25, "covers": [ "torso" ] } ] }, { "id": "debug_backpack", @@ -1655,8 +1537,6 @@ "symbol": "[", "looks_like": "backpack", "color": "yellow", - "encumbrance": 0, - "max_encumbrance": 0, "pocket_data": [ { "rigid": true, @@ -1669,7 +1549,8 @@ ], "warmth": 0, "material_thickness": 0, - "flags": [ "BELTED", "WATER_FRIENDLY", "TARDIS" ] + "flags": [ "BELTED", "WATER_FRIENDLY", "TARDIS" ], + "armor": [ { "encumbrance": [ 0, 0 ] } ] }, { "id": "long_duffelbag", @@ -1684,10 +1565,6 @@ "symbol": "[", "looks_like": "rucksack", "color": "green", - "covers": [ "torso" ], - "coverage": 80, - "encumbrance": 8, - "max_encumbrance": 42, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1700,7 +1577,8 @@ ], "warmth": 8, "material_thickness": 2, - "flags": [ "BELTED", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 8, 42 ], "coverage": 80, "covers": [ "torso" ] } ] }, { "id": "rifle_case_soft", @@ -1715,10 +1593,6 @@ "symbol": "[", "looks_like": "slingpack", "color": "green", - "covers": [ "torso" ], - "coverage": 10, - "encumbrance": 2, - "max_encumbrance": 6, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1738,7 +1612,8 @@ ], "warmth": 1, "material_thickness": 2, - "flags": [ "BELTED", "OVERSIZE" ] + "flags": [ "BELTED", "OVERSIZE" ], + "armor": [ { "encumbrance": [ 2, 6 ], "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "rifle_case_soft_leather", @@ -1753,10 +1628,6 @@ "symbol": "[", "looks_like": "slingpack", "color": "brown", - "covers": [ "torso" ], - "coverage": 10, - "encumbrance": 2, - "max_encumbrance": 6, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1776,7 +1647,8 @@ ], "warmth": 1, "material_thickness": 2, - "flags": [ "WATER_FRIENDLY", "STURDY", "BELTED", "OVERSIZE" ] + "flags": [ "WATER_FRIENDLY", "STURDY", "BELTED", "OVERSIZE" ], + "armor": [ { "encumbrance": [ 2, 6 ], "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "rifle_case_soft_2", @@ -1791,10 +1663,6 @@ "symbol": "[", "looks_like": "slingpack", "color": "green", - "covers": [ "torso" ], - "coverage": 15, - "encumbrance": 2, - "max_encumbrance": 14, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1830,7 +1698,8 @@ ], "warmth": 1, "material_thickness": 2, - "flags": [ "BELTED", "OVERSIZE" ] + "flags": [ "BELTED", "OVERSIZE" ], + "armor": [ { "encumbrance": [ 2, 14 ], "coverage": 15, "covers": [ "torso" ] } ] }, { "id": "rifle_case_soft_leather_2", @@ -1845,10 +1714,6 @@ "symbol": "[", "looks_like": "slingpack", "color": "brown", - "covers": [ "torso" ], - "coverage": 15, - "encumbrance": 2, - "max_encumbrance": 14, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1884,7 +1749,8 @@ ], "warmth": 1, "material_thickness": 2, - "flags": [ "WATER_FRIENDLY", "STURDY", "BELTED", "OVERSIZE" ] + "flags": [ "WATER_FRIENDLY", "STURDY", "BELTED", "OVERSIZE" ], + "armor": [ { "encumbrance": [ 2, 14 ], "coverage": 15, "covers": [ "torso" ] } ] }, { "id": "rifle_case_xl_soft_leather", @@ -1899,10 +1765,6 @@ "symbol": "[", "looks_like": "slingpack", "color": "brown", - "covers": [ "torso" ], - "coverage": 15, - "encumbrance": 2, - "max_encumbrance": 6, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1922,7 +1784,8 @@ ], "warmth": 1, "material_thickness": 2, - "flags": [ "WATER_FRIENDLY", "STURDY", "BELTED", "OVERSIZE" ] + "flags": [ "WATER_FRIENDLY", "STURDY", "BELTED", "OVERSIZE" ], + "armor": [ { "encumbrance": [ 2, 6 ], "coverage": 15, "covers": [ "torso" ] } ] }, { "id": "camera_bag", @@ -1939,10 +1802,6 @@ "symbol": "[", "looks_like": "slingpack", "color": "yellow", - "covers": [ "torso" ], - "coverage": 25, - "encumbrance": 3, - "max_encumbrance": 5, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1963,7 +1822,8 @@ ], "warmth": 2, "material_thickness": 1, - "flags": [ "BELTED", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 3, 5 ], "coverage": 25, "covers": [ "torso" ] } ] }, { "id": "bookstrap", @@ -1978,11 +1838,7 @@ "symbol": "[", "looks_like": "leather_belt", "color": "brown", - "covers": [ "leg_l", "leg_r" ], "sided": true, - "coverage": 5, - "encumbrance": 0, - "max_encumbrance": 11, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1994,6 +1850,7 @@ } ], "material_thickness": 1, - "flags": [ "BELTED", "WATER_FRIENDLY" ] + "flags": [ "BELTED", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 0, 11 ], "coverage": 5, "covers": [ "leg_l", "leg_r" ] } ] } ] diff --git a/data/json/items/armor/suits_clothes.json b/data/json/items/armor/suits_clothes.json index 1d3637643d72c..c87928791e498 100644 --- a/data/json/items/armor/suits_clothes.json +++ b/data/json/items/armor/suits_clothes.json @@ -244,10 +244,14 @@ "material": [ "lycra" ], "symbol": "[", "color": "dark_gray", - "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, "warmth": 20, "material_thickness": 0.1, - "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ] + "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ], + "armor": [ + { + "coverage": 100, + "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] } ] diff --git a/data/json/items/armor/suits_protection.json b/data/json/items/armor/suits_protection.json index cba679206370c..0ea12e2b90030 100644 --- a/data/json/items/armor/suits_protection.json +++ b/data/json/items/armor/suits_protection.json @@ -67,13 +67,17 @@ "symbol": "[", "looks_like": "hazmat_suit", "color": "light_red", - "covers": [ "head", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 35, "warmth": 50, "material_thickness": 7, "environmental_protection": 20, - "flags": [ "VARSIZE", "WATERPROOF", "RAINPROOF", "GAS_PROOF", "STURDY", "RAD_PROOF", "ELECTRIC_IMMUNE", "OUTER" ] + "flags": [ "VARSIZE", "WATERPROOF", "RAINPROOF", "GAS_PROOF", "STURDY", "RAD_PROOF", "ELECTRIC_IMMUNE", "OUTER" ], + "armor": [ + { + "encumbrance": 35, + "coverage": 100, + "covers": [ "head", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "armor_blarmor", @@ -133,12 +137,10 @@ "symbol": "[", "looks_like": "armor_larmor", "color": "green", - "covers": [ "torso", "leg_l", "leg_r" ], - "coverage": 90, - "encumbrance": 10, "warmth": 10, "material_thickness": 4, - "flags": [ "STURDY" ] + "flags": [ "STURDY" ], + "armor": [ { "encumbrance": 10, "coverage": 90, "covers": [ "torso", "leg_l", "leg_r" ] } ] }, { "id": "xl_armor_chitin", @@ -285,12 +287,10 @@ "symbol": "[", "looks_like": "armor_larmor", "color": "light_gray", - "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], - "coverage": 95, - "encumbrance": 20, "warmth": 20, "material_thickness": 4, - "flags": [ "VARSIZE", "OUTER", "STURDY" ] + "flags": [ "VARSIZE", "OUTER", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 95, "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ] } ] }, { "id": "xl_armor_lightplate", @@ -455,12 +455,10 @@ "symbol": "[", "looks_like": "armor_lightplate", "color": "light_gray", - "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], - "coverage": 90, - "encumbrance": 45, "warmth": 20, "material_thickness": 5, - "flags": [ "VARSIZE", "OUTER" ] + "flags": [ "VARSIZE", "OUTER" ], + "armor": [ { "encumbrance": 45, "coverage": 90, "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ] } ] }, { "id": "xl_armor_plate", @@ -487,12 +485,10 @@ "symbol": "[", "looks_like": "kevlar", "color": "light_gray", - "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], - "coverage": 85, - "encumbrance": 10, "warmth": 10, "material_thickness": 6, - "flags": [ "STURDY", "OUTER" ] + "flags": [ "STURDY", "OUTER" ], + "armor": [ { "encumbrance": 10, "coverage": 85, "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ] } ] }, { "id": "armor_samurai", @@ -509,12 +505,10 @@ "symbol": "[", "looks_like": "armor_lightplate", "color": "dark_gray", - "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r", "hand_l", "hand_r" ], - "coverage": 85, - "encumbrance": 15, "warmth": 25, "material_thickness": 4, - "flags": [ "VARSIZE", "STURDY", "OUTER" ] + "flags": [ "VARSIZE", "STURDY", "OUTER" ], + "armor": [ { "encumbrance": 15, "coverage": 85, "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r", "hand_l", "hand_r" ] } ] }, { "id": "armor_scavenger", @@ -566,12 +560,10 @@ "symbol": "[", "looks_like": "armor_lightplate", "color": "light_gray", - "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ], - "coverage": 80, - "encumbrance": 18, "warmth": 10, "material_thickness": 2, - "flags": [ "OUTER" ] + "flags": [ "OUTER" ], + "armor": [ { "encumbrance": 18, "coverage": 80, "covers": [ "torso", "leg_l", "leg_r", "arm_l", "arm_r" ] } ] }, { "id": "beekeeping_suit", @@ -622,12 +614,10 @@ "symbol": "[", "looks_like": "armor_blarmor", "color": "light_red", - "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 20, "warmth": 30, "material_thickness": 6, - "flags": [ "VARSIZE", "STURDY" ] + "flags": [ "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 95, "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ] } ] }, { "id": "xl_chainmail_hauberk", @@ -652,12 +642,10 @@ "symbol": "[", "looks_like": "touring_suit", "color": "light_red", - "covers": [ "torso", "head", "arm_l", "arm_r", "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 20, "warmth": 30, "material_thickness": 6, - "flags": [ "VARSIZE", "STURDY", "HELMET_COMPAT" ] + "flags": [ "VARSIZE", "STURDY", "HELMET_COMPAT" ], + "armor": [ { "encumbrance": 20, "coverage": 95, "covers": [ "torso", "head", "arm_l", "arm_r", "leg_l", "leg_r" ] } ] }, { "id": "xl_chainmail_suit", @@ -681,11 +669,15 @@ "material": [ "iron", "cotton" ], "symbol": "[", "color": "light_red", - "covers": [ "torso", "head", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r", "mouth", "eyes" ], - "coverage": 100, - "encumbrance": 30, "material_thickness": 4, - "flags": [ "VARSIZE", "STURDY", "HELMET_COMPAT", "ELECTRIC_IMMUNE", "OUTER" ] + "flags": [ "VARSIZE", "STURDY", "HELMET_COMPAT", "ELECTRIC_IMMUNE", "OUTER" ], + "armor": [ + { + "encumbrance": 30, + "coverage": 100, + "covers": [ "torso", "head", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r", "mouth", "eyes" ] + } + ] }, { "id": "cleansuit", @@ -701,13 +693,17 @@ "symbol": "[", "looks_like": "jumpsuit", "color": "white", - "covers": [ "leg_l", "leg_r", "foot_l", "foot_r", "head", "torso", "arm_l", "arm_r" ], - "coverage": 100, - "encumbrance": 25, "warmth": 10, "material_thickness": 1, "environmental_protection": 10, - "flags": [ "VARSIZE", "WATERPROOF", "HOOD", "RAINPROOF", "RAD_RESIST", "OUTER" ] + "flags": [ "VARSIZE", "WATERPROOF", "HOOD", "RAINPROOF", "RAD_RESIST", "OUTER" ], + "armor": [ + { + "encumbrance": 25, + "coverage": 100, + "covers": [ "leg_l", "leg_r", "foot_l", "foot_r", "head", "torso", "arm_l", "arm_r" ] + } + ] }, { "id": "entry_suit", @@ -722,13 +718,17 @@ "symbol": "[", "looks_like": "jumpsuit", "color": "light_gray", - "covers": [ "head", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 50, "warmth": 30, "material_thickness": 5, "environmental_protection": 20, - "flags": [ "VARSIZE", "WATERPROOF", "RAINPROOF", "GAS_PROOF", "STURDY", "OUTER" ] + "flags": [ "VARSIZE", "WATERPROOF", "RAINPROOF", "GAS_PROOF", "STURDY", "OUTER" ], + "armor": [ + { + "encumbrance": 50, + "coverage": 100, + "covers": [ "head", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "xl_entry_suit", @@ -819,13 +819,11 @@ "symbol": "[", "looks_like": "coat_winter", "color": "light_gray", - "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], - "coverage": 80, - "encumbrance": 15, "warmth": 30, "material_thickness": 5, "valid_mods": [ "steel_padded" ], - "flags": [ "VARSIZE", "STURDY" ] + "flags": [ "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": 15, "coverage": 80, "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ] } ] }, { "id": "xl_gambeson", @@ -849,13 +847,17 @@ "symbol": "[", "looks_like": "beekeeping_suit", "color": "yellow", - "covers": [ "head", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 37, "warmth": 40, "material_thickness": 2, "environmental_protection": 20, - "flags": [ "VARSIZE", "WATERPROOF", "RAINPROOF", "GAS_PROOF", "RAD_PROOF", "ELECTRIC_IMMUNE", "OUTER" ] + "flags": [ "VARSIZE", "WATERPROOF", "RAINPROOF", "GAS_PROOF", "RAD_PROOF", "ELECTRIC_IMMUNE", "OUTER" ], + "armor": [ + { + "encumbrance": 37, + "coverage": 100, + "covers": [ "head", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "hsurvivor_suit", @@ -941,13 +943,11 @@ "symbol": "[", "looks_like": "jumpsuit", "color": "light_gray", - "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], - "coverage": 100, - "encumbrance": 6, "warmth": 5, "material_thickness": 2, "environmental_protection": 2, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT", "STURDY" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT", "STURDY" ], + "armor": [ { "encumbrance": 6, "coverage": 100, "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ] } ] }, { "id": "xl_nomex_suit", @@ -1005,12 +1005,10 @@ "symbol": "[", "looks_like": "jumpsuit", "color": "dark_gray", - "covers": [ "foot_l", "foot_r", "leg_l", "leg_r", "torso", "arm_l", "arm_r" ], - "coverage": 95, - "encumbrance": 18, "warmth": 15, "material_thickness": 1, - "flags": [ "VARSIZE", "SKINTIGHT", "HOOD", "WATERPROOF", "SLOWS_THIRST", "SLOWS_MOVEMENT" ] + "flags": [ "VARSIZE", "SKINTIGHT", "HOOD", "WATERPROOF", "SLOWS_THIRST", "SLOWS_MOVEMENT" ], + "armor": [ { "encumbrance": 18, "coverage": 95, "covers": [ "foot_l", "foot_r", "leg_l", "leg_r", "torso", "arm_l", "arm_r" ] } ] }, { "id": "suit", diff --git a/data/json/items/armor/swimming.json b/data/json/items/armor/swimming.json index dc0916985b754..0570c1cf90e2e 100644 --- a/data/json/items/armor/swimming.json +++ b/data/json/items/armor/swimming.json @@ -12,11 +12,10 @@ "symbol": "[", "looks_like": "panties", "color": "light_red", - "covers": [ "leg_l", "leg_r" ], - "coverage": 15, "warmth": 5, "material_thickness": 0.01, - "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ] + "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ], + "armor": [ { "coverage": 15, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "trunks", @@ -33,10 +32,9 @@ "symbol": "[", "looks_like": "shorts", "color": "blue", - "covers": [ "leg_l", "leg_r" ], - "coverage": 35, "material_thickness": 0.1, - "flags": [ "VARSIZE", "WATER_FRIENDLY" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY" ], + "armor": [ { "coverage": 35, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "wetsuit", @@ -91,13 +89,11 @@ "symbol": "[", "looks_like": "hood_rain", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 100, - "encumbrance": 10, "warmth": 30, "material_thickness": 3, "environmental_protection": 1, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ], + "armor": [ { "encumbrance": 10, "coverage": 100, "covers": [ "head" ] } ] }, { "id": "hood_h20survivor", @@ -115,13 +111,11 @@ "symbol": "[", "looks_like": "wetsuit_hood", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 100, - "encumbrance": 25, "warmth": 15, "material_thickness": 3, "environmental_protection": 10, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "STURDY", "OUTER", "HELMET_COMPAT" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "STURDY", "OUTER", "HELMET_COMPAT" ], + "armor": [ { "encumbrance": 25, "coverage": 100, "covers": [ "head" ] } ] }, { "id": "h20survivor_suit", @@ -171,13 +165,11 @@ "symbol": "[", "looks_like": "gloves_rubber", "color": "dark_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 25, "warmth": 15, "material_thickness": 1, "environmental_protection": 10, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "STURDY" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "STURDY" ], + "armor": [ { "encumbrance": 25, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "wetsuit_spring", @@ -232,12 +224,16 @@ "symbol": "[", "looks_like": "chainmail_hauberk", "color": "light_red", - "covers": [ "torso", "head", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 30, "warmth": 5, "material_thickness": 3, - "flags": [ "VARSIZE", "STURDY", "WATER_FRIENDLY", "ELECTRIC_IMMUNE", "HELMET_COMPAT" ] + "flags": [ "VARSIZE", "STURDY", "WATER_FRIENDLY", "ELECTRIC_IMMUNE", "HELMET_COMPAT" ], + "armor": [ + { + "encumbrance": 30, + "coverage": 100, + "covers": [ "torso", "head", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "shark_suit", @@ -254,12 +250,16 @@ "symbol": "[", "looks_like": "chainmail_suit", "color": "light_red", - "covers": [ "torso", "head", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 30, "warmth": 5, "material_thickness": 3, - "flags": [ "VARSIZE", "STURDY", "WATER_FRIENDLY" ] + "flags": [ "VARSIZE", "STURDY", "WATER_FRIENDLY" ], + "armor": [ + { + "encumbrance": 30, + "coverage": 100, + "covers": [ "torso", "head", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "goggles_swim", @@ -275,13 +275,11 @@ "symbol": "[", "looks_like": "goggles_welding", "color": "light_blue", - "covers": [ "eyes" ], - "coverage": 100, - "encumbrance": 10, "warmth": 10, "material_thickness": 1, "environmental_protection": 4, - "flags": [ "WATER_FRIENDLY", "SWIM_GOGGLES" ] + "flags": [ "WATER_FRIENDLY", "SWIM_GOGGLES" ], + "armor": [ { "encumbrance": 10, "coverage": 100, "covers": [ "eyes" ] } ] }, { "id": "wetsuit_gloves", @@ -297,12 +295,10 @@ "symbol": "[", "looks_like": "gloves_tactical", "color": "dark_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 10, "warmth": 30, "material_thickness": 2, "environmental_protection": 1, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ], + "armor": [ { "encumbrance": 10, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] } ] diff --git a/data/json/items/armor/torso_armor.json b/data/json/items/armor/torso_armor.json index 364d5356c544d..9a5b479a3a504 100644 --- a/data/json/items/armor/torso_armor.json +++ b/data/json/items/armor/torso_armor.json @@ -15,12 +15,10 @@ "symbol": "[", "looks_like": "cuirass_lightplate", "color": "yellow", - "covers": [ "torso" ], - "coverage": 90, - "encumbrance": 15, "warmth": 15, "material_thickness": 3, - "flags": [ "VARSIZE", "OUTER", "STURDY" ] + "flags": [ "VARSIZE", "OUTER", "STURDY" ], + "armor": [ { "encumbrance": 15, "coverage": 90, "covers": [ "torso" ] } ] }, { "id": "xl_armor_cuirass", @@ -44,12 +42,10 @@ "looks_like": "vest_leather", "copy-from": "armor_chitin", "color": "brown", - "covers": [ "torso" ], - "coverage": 80, - "encumbrance": 20, "warmth": 20, "material_thickness": 8, - "flags": [ "VARSIZE", "STURDY" ] + "flags": [ "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 80, "covers": [ "torso" ] } ] }, { "id": "xl_armor_lamellar", @@ -74,12 +70,10 @@ "symbol": "[", "looks_like": "armor_lamellar", "color": "light_gray", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 90, - "encumbrance": 15, "warmth": 15, "material_thickness": 4, - "flags": [ "VARSIZE", "OUTER", "STURDY" ] + "flags": [ "VARSIZE", "OUTER", "STURDY" ], + "armor": [ { "encumbrance": 15, "coverage": 90, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "id": "xl_armor_lorica", @@ -104,12 +98,10 @@ "symbol": "O", "looks_like": "armor_scrapsuit", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 80, - "encumbrance": 20, "warmth": 10, "material_thickness": 12, - "flags": [ "BELTED" ] + "flags": [ "BELTED" ], + "armor": [ { "encumbrance": 20, "coverage": 80, "covers": [ "torso" ] } ] }, { "id": "chainmail_vest", @@ -126,11 +118,9 @@ "symbol": "[", "looks_like": "vest_leather", "color": "light_red", - "covers": [ "torso" ], - "coverage": 95, - "encumbrance": 20, "material_thickness": 4, - "flags": [ "VARSIZE", "STURDY" ] + "flags": [ "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 95, "covers": [ "torso" ] } ] }, { "id": "xl_chainmail_vest", @@ -156,13 +146,11 @@ "symbol": "H", "looks_like": "cuirass_lightplate", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 90, - "encumbrance": 20, "warmth": 20, "material_thickness": 3, "environmental_protection": 1, - "flags": [ "WATER_FRIENDLY", "STURDY", "OUTER" ] + "flags": [ "WATER_FRIENDLY", "STURDY", "OUTER" ], + "armor": [ { "encumbrance": 20, "coverage": 90, "covers": [ "torso" ] } ] }, { "id": "cuirass_lightplate", @@ -179,12 +167,10 @@ "symbol": "[", "looks_like": "chestguard_hard", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 95, - "encumbrance": 20, "warmth": 20, "material_thickness": 4, - "flags": [ "VARSIZE", "OUTER", "STURDY" ] + "flags": [ "VARSIZE", "OUTER", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 95, "covers": [ "torso" ] } ] }, { "id": "xl_cuirass_lightplate", @@ -211,12 +197,10 @@ "symbol": "[", "looks_like": "cuirass_lightplate", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 80, - "encumbrance": 18, "warmth": 10, "material_thickness": 2, - "flags": [ "OUTER" ] + "flags": [ "OUTER" ], + "armor": [ { "encumbrance": 18, "coverage": 80, "covers": [ "torso" ] } ] }, { "id": "xl_cuirass_scrap", @@ -240,13 +224,11 @@ "symbol": "[", "looks_like": "coat_lab", "color": "white", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 100, - "encumbrance": 5, "warmth": 25, "material_thickness": 3, "valid_mods": [ "steel_padded" ], - "flags": [ "STURDY" ] + "flags": [ "STURDY" ], + "armor": [ { "encumbrance": 5, "coverage": 100, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "id": "jacket_leather_mod", @@ -299,12 +281,10 @@ "material": [ "cotton", "budget_steel" ], "symbol": "[", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 100, - "encumbrance": 8, "warmth": 10, "material_thickness": 1, - "flags": [ "VARSIZE", "OUTER" ] + "flags": [ "VARSIZE", "OUTER" ], + "armor": [ { "encumbrance": 8, "coverage": 100, "covers": [ "torso" ] } ] }, { "id": "lame_saber", @@ -319,12 +299,10 @@ "material": [ "cotton", "budget_steel" ], "symbol": "[", "color": "light_gray", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 100, - "encumbrance": 8, "warmth": 10, "material_thickness": 1, - "flags": [ "VARSIZE", "OUTER" ] + "flags": [ "VARSIZE", "OUTER" ], + "armor": [ { "encumbrance": 8, "coverage": 100, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "id": "football_armor", @@ -341,12 +319,10 @@ "symbol": "[", "looks_like": "chestguard_hard", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 45, - "encumbrance": 35, "warmth": 10, "material_thickness": 6, - "flags": [ "BELTED" ] + "flags": [ "BELTED" ], + "armor": [ { "encumbrance": 35, "coverage": 45, "covers": [ "torso" ] } ] }, { "id": "kevlar", @@ -365,12 +341,10 @@ "symbol": "[", "looks_like": "vest_leather", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 85, - "encumbrance": 5, "warmth": 15, "material_thickness": 3, - "flags": [ "STURDY", "SKINTIGHT" ] + "flags": [ "STURDY", "SKINTIGHT" ], + "armor": [ { "encumbrance": 5, "coverage": 85, "covers": [ "torso" ] } ] }, { "id": "lsurvivor_armor", @@ -386,10 +360,6 @@ "symbol": "[", "looks_like": "lsurvivor_suit", "color": "green", - "covers": [ "torso" ], - "coverage": 95, - "encumbrance": 8, - "max_encumbrance": 16, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "700 ml", "max_contains_weight": "3 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "700 ml", "max_contains_weight": "3 kg", "moves": 80 }, @@ -401,7 +371,8 @@ "warmth": 15, "material_thickness": 4, "environmental_protection": 1, - "flags": [ "VARSIZE", "WATERPROOF", "RAINPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "RAINPROOF", "STURDY" ], + "armor": [ { "encumbrance": [ 8, 16 ], "coverage": 95, "covers": [ "torso" ] } ] }, { "id": "xl_lsurvivor_armor", @@ -452,11 +423,10 @@ "material": [ "cotton" ], "symbol": "[", "color": "white", - "covers": [ "torso" ], - "coverage": 65, "warmth": 5, "material_thickness": 3, - "flags": [ "SKINTIGHT" ] + "flags": [ "SKINTIGHT" ], + "armor": [ { "coverage": 65, "covers": [ "torso" ] } ] }, { "id": "plastron_plastic", @@ -470,12 +440,10 @@ "material": [ "plastic" ], "symbol": "[", "color": "white", - "covers": [ "torso" ], - "coverage": 35, - "encumbrance": 2, "warmth": 5, "material_thickness": 3, - "flags": [ "SKINTIGHT" ] + "flags": [ "SKINTIGHT" ], + "armor": [ { "encumbrance": 2, "coverage": 35, "covers": [ "torso" ] } ] }, { "id": "vest_leather_mod", @@ -491,10 +459,6 @@ "symbol": "[", "looks_like": "vest_leather", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 90, - "encumbrance": 17, - "max_encumbrance": 24, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "700 ml", "max_contains_weight": "2 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "700 ml", "max_contains_weight": "2 kg", "moves": 80 }, @@ -504,7 +468,8 @@ "warmth": 30, "material_thickness": 3, "environmental_protection": 1, - "flags": [ "VARSIZE", "POCKETS", "OUTER" ] + "flags": [ "VARSIZE", "POCKETS", "OUTER" ], + "armor": [ { "encumbrance": [ 17, 24 ], "coverage": 90, "covers": [ "torso" ] } ] }, { "id": "jacket_eod", @@ -516,16 +481,14 @@ "weight": "16300 g", "volume": "15 L", "price": 200000, - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 100, - "encumbrance": 80, "warmth": 65, "material": [ "kevlar_layered", "kevlar_rigid", "nomex" ], "symbol": "[", "color": "light_gray", "environmental_protection": 2, "material_thickness": 15, - "flags": [ "STURDY", "OUTER", "RAINPROOF", "ONLY_ONE" ] + "flags": [ "STURDY", "OUTER", "RAINPROOF", "ONLY_ONE" ], + "armor": [ { "encumbrance": 80, "coverage": 100, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "id": "jacket_eod_light", @@ -537,15 +500,13 @@ "weight": "7000 g", "volume": "15 L", "price": 200000, - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 100, - "encumbrance": 40, "warmth": 40, "material": [ "kevlar_layered", "kevlar_rigid", "nomex" ], "symbol": "[", "color": "light_gray", "environmental_protection": 2, "material_thickness": 7, - "flags": [ "STURDY", "OUTER", "RAINPROOF", "ONLY_ONE" ] + "flags": [ "STURDY", "OUTER", "RAINPROOF", "ONLY_ONE" ], + "armor": [ { "encumbrance": 40, "coverage": 100, "covers": [ "torso", "arm_l", "arm_r" ] } ] } ] diff --git a/data/json/items/armor/torso_clothes.json b/data/json/items/armor/torso_clothes.json index 68da869b45b55..cbd4d77a5c3ea 100644 --- a/data/json/items/armor/torso_clothes.json +++ b/data/json/items/armor/torso_clothes.json @@ -108,12 +108,10 @@ "symbol": "[", "looks_like": "robe", "color": "pink", - "covers": [ "torso", "leg_l", "leg_r" ], - "coverage": 85, - "encumbrance": 7, "warmth": 15, "material_thickness": 0.2, - "flags": [ "VARSIZE", "FANCY" ] + "flags": [ "VARSIZE", "FANCY" ], + "armor": [ { "encumbrance": 7, "coverage": 85, "covers": [ "torso", "leg_l", "leg_r" ] } ] }, { "id": "dress_shirt", @@ -161,12 +159,10 @@ "symbol": "[", "looks_like": "dress", "color": "white", - "covers": [ "torso", "leg_l", "leg_r" ], - "coverage": 90, - "encumbrance": 45, "warmth": 30, "material_thickness": 0.2, - "flags": [ "VARSIZE", "SUPER_FANCY" ] + "flags": [ "VARSIZE", "SUPER_FANCY" ], + "armor": [ { "encumbrance": 45, "coverage": 90, "covers": [ "torso", "leg_l", "leg_r" ] } ] }, { "id": "flag_shirt", @@ -182,11 +178,10 @@ "symbol": "[", "looks_like": "tshirt", "color": "light_red", - "covers": [ "torso" ], - "coverage": 90, "warmth": 10, "material_thickness": 0.2, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "coverage": 90, "covers": [ "torso" ] } ] }, { "id": "flotation_vest", @@ -204,12 +199,10 @@ "symbol": "[", "looks_like": "vest_leather", "color": "yellow", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 40, "warmth": 5, "material_thickness": 4, - "flags": [ "FLOTATION", "WATER_FRIENDLY", "BELTED" ] + "flags": [ "FLOTATION", "WATER_FRIENDLY", "BELTED" ], + "armor": [ { "encumbrance": 40, "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "flotation_vest_ms", @@ -226,12 +219,10 @@ "symbol": "[", "looks_like": "vest_leather", "color": "brown", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 50, "warmth": 5, "material_thickness": 2, - "flags": [ "FLOTATION", "WATER_FRIENDLY", "BELTED" ] + "flags": [ "FLOTATION", "WATER_FRIENDLY", "BELTED" ], + "armor": [ { "encumbrance": 50, "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "gown", @@ -247,12 +238,10 @@ "symbol": "[", "looks_like": "dress", "color": "dark_gray", - "covers": [ "torso", "leg_l", "leg_r" ], - "coverage": 75, - "encumbrance": 14, "warmth": 5, "material_thickness": 0.3, - "flags": [ "VARSIZE", "SUPER_FANCY" ] + "flags": [ "VARSIZE", "SUPER_FANCY" ], + "armor": [ { "encumbrance": 14, "coverage": 75, "covers": [ "torso", "leg_l", "leg_r" ] } ] }, { "id": "halter_top", @@ -269,11 +258,10 @@ "symbol": "[", "looks_like": "tank_top", "color": "pink", - "covers": [ "torso" ], - "coverage": 25, "warmth": 2, "material_thickness": 0.1, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "coverage": 25, "covers": [ "torso" ] } ] }, { "id": "hoodie", @@ -320,9 +308,6 @@ "symbol": "[", "looks_like": "tshirt", "color": "yellow", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 90, - "encumbrance": 7, "warmth": 25, "material_thickness": 0.3, "snippet_category": [ @@ -371,7 +356,8 @@ "text": "A volleyball jersey made of thick material imprinted with the logo of the Ooarai Ducks." } ], - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 7, "coverage": 90, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "id": "leotard", @@ -385,11 +371,10 @@ "material": [ "lycra" ], "symbol": "[", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 55, "warmth": 5, "material_thickness": 0.01, - "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ] + "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ], + "armor": [ { "coverage": 55, "covers": [ "torso" ] } ] }, { "id": "linuxtshirt", @@ -405,9 +390,6 @@ "symbol": "[", "looks_like": "tshirt", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 90, - "encumbrance": 5, "warmth": 5, "material_thickness": 0.1, "snippet_category": [ @@ -444,7 +426,8 @@ "text": "A t-shirt with the Debian logo on it, underneath it says \"The Universal Operating System\"" } ], - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 5, "coverage": 90, "covers": [ "torso" ] } ] }, { "id": "longshirt", @@ -459,12 +442,10 @@ "symbol": "[", "looks_like": "dress_shirt", "color": "blue", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 90, - "encumbrance": 3, "warmth": 5, "material_thickness": 0.2, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 3, "coverage": 90, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "id": "maid_dress", @@ -512,12 +493,10 @@ "symbol": "[", "looks_like": "tshirt", "color": "light_red", - "covers": [ "torso" ], - "coverage": 90, - "encumbrance": 7, "warmth": 15, "material_thickness": 0.2, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 7, "coverage": 90, "covers": [ "torso" ] } ] }, { "id": "postman_shirt", @@ -533,8 +512,6 @@ "symbol": "[", "looks_like": "polo_shirt", "color": "light_blue", - "covers": [ "torso" ], - "coverage": 90, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -553,7 +530,8 @@ ], "warmth": 5, "material_thickness": 0.1, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "coverage": 90, "covers": [ "torso" ] } ] }, { "id": "sheriffshirt", @@ -621,12 +599,10 @@ "symbol": "[", "looks_like": "longshirt", "color": "white", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 90, - "encumbrance": 5, "warmth": 5, "material_thickness": 0.2, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 5, "coverage": 90, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "id": "sundress", @@ -642,10 +618,9 @@ "symbol": "[", "looks_like": "dress", "color": "yellow", - "covers": [ "torso", "leg_l", "leg_r" ], - "coverage": 65, "material_thickness": 0.1, - "flags": [ "VARSIZE", "FANCY" ] + "flags": [ "VARSIZE", "FANCY" ], + "armor": [ { "coverage": 65, "covers": [ "torso", "leg_l", "leg_r" ] } ] }, { "id": "sweater", @@ -660,13 +635,11 @@ "symbol": "[", "looks_like": "longshirt", "color": "blue", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 95, - "encumbrance": 10, "warmth": 40, "material_thickness": 1, "valid_mods": [ "steel_padded" ], - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 10, "coverage": 95, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "id": "sweatshirt", @@ -682,13 +655,11 @@ "symbol": "[", "looks_like": "longshirt", "color": "light_red", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 95, - "encumbrance": 10, "warmth": 30, "material_thickness": 1, "valid_mods": [ "steel_padded" ], - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 10, "coverage": 95, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "id": "technician_shirt_gray", @@ -704,10 +675,6 @@ "symbol": "[", "looks_like": "polo_shirt", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 4, - "max_encumbrance": 5, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -724,7 +691,8 @@ { "id": "technician_shirt_gray", "text": "A gray work t-shirt with a small front pocket." }, { "id": "technician_shirt_lightblue", "text": "A light-blue work t-shirt with a small front pocket." } ], - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": [ 4, 5 ], "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "tshirt", @@ -739,11 +707,10 @@ "symbol": "[", "looks_like": "camisole", "color": "white", - "covers": [ "torso" ], - "coverage": 90, "warmth": 5, "material_thickness": 0.1, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "coverage": 90, "covers": [ "torso" ] } ] }, { "id": "tshirt_text", @@ -759,8 +726,6 @@ "symbol": "[", "looks_like": "tshirt", "color": "white", - "covers": [ "torso" ], - "coverage": 90, "warmth": 5, "material_thickness": 0.1, "snippet_category": [ @@ -769,7 +734,8 @@ "text": "A short-sleeved cotton shirt with the text \"chown -R us ~your/base\" printed on the front." } ], - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "coverage": 90, "covers": [ "torso" ] } ] }, { "id": "tshirt_tour", @@ -831,14 +797,11 @@ "symbol": "[", "looks_like": "longshirt", "color": "brown", - "covers": [ "torso" ], - "coverage": 50, - "encumbrance": 4, - "max_encumbrance": 5, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "250 ml", "max_contains_weight": "1 kg", "moves": 400 } ], "warmth": 5, "material_thickness": 0.4, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": [ 4, 5 ], "coverage": 50, "covers": [ "torso" ] } ] }, { "id": "vest_leather", @@ -854,10 +817,6 @@ "symbol": "[", "looks_like": "vest", "color": "brown", - "covers": [ "torso" ], - "coverage": 90, - "encumbrance": 4, - "max_encumbrance": 8, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -885,7 +844,8 @@ "material_thickness": 1.5, "environmental_protection": 1, "valid_mods": [ "steel_padded" ], - "flags": [ "VARSIZE", "POCKETS", "OUTER" ] + "flags": [ "VARSIZE", "POCKETS", "OUTER" ], + "armor": [ { "encumbrance": [ 4, 8 ], "coverage": 90, "covers": [ "torso" ] } ] }, { "id": "wool_hoodie", diff --git a/data/json/items/armor/undergarment.json b/data/json/items/armor/undergarment.json index 09f710565fc9f..de9473626974e 100644 --- a/data/json/items/armor/undergarment.json +++ b/data/json/items/armor/undergarment.json @@ -12,12 +12,10 @@ "symbol": "[", "looks_like": "armguard_larmor", "color": "light_gray", - "covers": [ "arm_l", "arm_r" ], - "coverage": 80, - "encumbrance": 1, "warmth": 20, "material_thickness": 0.5, - "flags": [ "SKINTIGHT" ] + "flags": [ "SKINTIGHT" ], + "armor": [ { "encumbrance": 1, "coverage": 80, "covers": [ "arm_l", "arm_r" ] } ] }, { "id": "xl_arm_warmers", @@ -43,10 +41,9 @@ "symbol": "[", "looks_like": "tank_top", "color": "green", - "covers": [ "torso" ], - "coverage": 60, "material_thickness": 0.1, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ], + "armor": [ { "coverage": 60, "covers": [ "torso" ] } ] }, { "id": "bikini_top", @@ -61,10 +58,9 @@ "symbol": "[", "looks_like": "bra", "color": "light_red", - "covers": [ "torso" ], - "coverage": 10, "material_thickness": 0.1, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ], + "armor": [ { "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "bikini_top_fur", @@ -79,11 +75,10 @@ "symbol": "[", "looks_like": "bikini_top", "color": "brown", - "covers": [ "torso" ], - "coverage": 10, "warmth": 10, "material_thickness": 0.5, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "bikini_top_leather", @@ -98,11 +93,10 @@ "symbol": "[", "looks_like": "bikini_top", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 10, "warmth": 5, "material_thickness": 0.5, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "boxer_briefs", @@ -117,11 +111,10 @@ "symbol": "[", "looks_like": "shorts", "color": "light_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 20, "warmth": 5, "material_thickness": 0.1, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 20, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "xlboxer_briefs", @@ -146,11 +139,10 @@ "symbol": "[", "looks_like": "boxer_briefs", "color": "light_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 25, "warmth": 5, "material_thickness": 0.01, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 25, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "xlboxer_shorts", @@ -175,11 +167,10 @@ "symbol": "[", "looks_like": "boxer_briefs", "color": "light_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 25, "warmth": 5, "material_thickness": 0.1, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 25, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "xlboy_shorts", @@ -204,11 +195,10 @@ "symbol": "[", "looks_like": "tank_top", "color": "white", - "covers": [ "torso" ], - "coverage": 15, "warmth": 5, "material_thickness": 0.1, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 15, "covers": [ "torso" ] } ] }, { "id": "briefs", @@ -223,11 +213,10 @@ "symbol": "[", "looks_like": "boxer_briefs", "color": "white", - "covers": [ "leg_l", "leg_r" ], - "coverage": 15, "warmth": 5, "material_thickness": 0.1, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 15, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "camisole", @@ -244,10 +233,9 @@ "symbol": "[", "looks_like": "tank_top", "color": "light_blue", - "covers": [ "torso" ], - "coverage": 45, "material_thickness": 0.1, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 45, "covers": [ "torso" ] } ] }, { "id": "chestwrap", @@ -262,11 +250,10 @@ "symbol": "[", "looks_like": "tshirt", "color": "brown", - "covers": [ "torso" ], - "coverage": 25, "warmth": 5, "material_thickness": 0.2, - "flags": [ "SKINTIGHT", "OVERSIZE" ] + "flags": [ "SKINTIGHT", "OVERSIZE" ], + "armor": [ { "coverage": 25, "covers": [ "torso" ] } ] }, { "id": "chestwrap_fur", @@ -281,12 +268,10 @@ "symbol": "[", "looks_like": "chestwrap_leather", "color": "brown", - "covers": [ "torso" ], - "coverage": 25, - "encumbrance": 5, "warmth": 20, "material_thickness": 0.2, - "flags": [ "SKINTIGHT", "OVERSIZE" ] + "flags": [ "SKINTIGHT", "OVERSIZE" ], + "armor": [ { "encumbrance": 5, "coverage": 25, "covers": [ "torso" ] } ] }, { "id": "chestwrap_leather", @@ -301,12 +286,10 @@ "symbol": "[", "looks_like": "chestwrap", "color": "brown", - "covers": [ "torso" ], - "coverage": 25, - "encumbrance": 5, "warmth": 10, "material_thickness": 0.5, - "flags": [ "SKINTIGHT", "OVERSIZE" ] + "flags": [ "SKINTIGHT", "OVERSIZE" ], + "armor": [ { "encumbrance": 5, "coverage": 25, "covers": [ "torso" ] } ] }, { "id": "chestwrap_wool", @@ -321,12 +304,10 @@ "symbol": "[", "looks_like": "chestwrap", "color": "blue", - "covers": [ "torso" ], - "coverage": 25, - "encumbrance": 5, "warmth": 15, "material_thickness": 0.2, - "flags": [ "SKINTIGHT", "OVERSIZE" ] + "flags": [ "SKINTIGHT", "OVERSIZE" ], + "armor": [ { "encumbrance": 5, "coverage": 25, "covers": [ "torso" ] } ] }, { "id": "corset", @@ -343,13 +324,11 @@ "symbol": "[", "looks_like": "vest_leather", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 75, - "encumbrance": 15, "warmth": 25, "material_thickness": 3, "environmental_protection": 1, - "flags": [ "VARSIZE", "FANCY", "SKINTIGHT" ] + "flags": [ "VARSIZE", "FANCY", "SKINTIGHT" ], + "armor": [ { "encumbrance": 15, "coverage": 75, "covers": [ "torso" ] } ] }, { "id": "leg_warmers", @@ -364,12 +343,10 @@ "symbol": "[", "looks_like": "leggings", "color": "light_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 60, - "encumbrance": 1, "warmth": 20, "material_thickness": 0.1, - "flags": [ "SKINTIGHT" ] + "flags": [ "SKINTIGHT" ], + "armor": [ { "encumbrance": 1, "coverage": 60, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "leg_warmers_f", @@ -384,12 +361,10 @@ "symbol": "[", "looks_like": "leg_warmers", "color": "brown", - "covers": [ "leg_l", "leg_r" ], - "coverage": 60, - "encumbrance": 3, "warmth": 40, "material_thickness": 0.2, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 3, "coverage": 60, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "leg_warmers_xl", @@ -404,12 +379,10 @@ "symbol": "[", "looks_like": "leg_warmers", "color": "light_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 60, - "encumbrance": 7, "warmth": 20, "material_thickness": 2, - "flags": [ "VARSIZE", "SKINTIGHT", "OVERSIZE" ] + "flags": [ "VARSIZE", "SKINTIGHT", "OVERSIZE" ], + "armor": [ { "encumbrance": 7, "coverage": 60, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "long_underpants", @@ -424,12 +397,10 @@ "symbol": "[", "looks_like": "leggings", "color": "light_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 3, "warmth": 30, "material_thickness": 0.2, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "encumbrance": 3, "coverage": 95, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "long_undertop", @@ -444,12 +415,10 @@ "symbol": "[", "looks_like": "longshirt", "color": "light_gray", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 95, - "encumbrance": 3, "warmth": 30, "material_thickness": 0.2, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "encumbrance": 3, "coverage": 95, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "id": "long_undertop_sleeveless", @@ -464,12 +433,10 @@ "symbol": "[", "looks_like": "long_undertop", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 95, - "encumbrance": 3, "warmth": 30, "material_thickness": 0.2, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "encumbrance": 3, "coverage": 95, "covers": [ "torso" ] } ] }, { "id": "panties", @@ -484,11 +451,10 @@ "symbol": "[", "looks_like": "briefs", "color": "white", - "covers": [ "leg_l", "leg_r" ], - "coverage": 15, "warmth": 5, "material_thickness": 0.1, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 15, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "thermal_shirt", @@ -502,11 +468,10 @@ "material": [ "lycra" ], "symbol": "[", "color": "dark_gray", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 95, "warmth": 20, "material_thickness": 0.1, - "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ] + "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ], + "armor": [ { "coverage": 95, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "id": "sports_bra", @@ -521,11 +486,10 @@ "symbol": "[", "looks_like": "bra", "color": "white", - "covers": [ "torso" ], - "coverage": 30, "warmth": 5, "material_thickness": 0.1, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ], + "armor": [ { "coverage": 30, "covers": [ "torso" ] } ] }, { "id": "xlsports_bra", @@ -550,10 +514,9 @@ "symbol": "[", "looks_like": "tshirt", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 40, "material_thickness": 0.1, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ], + "armor": [ { "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "tights", @@ -569,11 +532,10 @@ "symbol": "[", "looks_like": "leggings", "color": "dark_gray", - "covers": [ "foot_l", "foot_r", "leg_r", "leg_l" ], - "coverage": 100, "warmth": 10, "material_thickness": 0.1, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 100, "covers": [ "foot_l", "foot_r", "leg_r", "leg_l" ] } ] }, { "id": "under_armor", @@ -588,11 +550,10 @@ "symbol": "[", "looks_like": "longshirt", "color": "dark_gray", - "covers": [ "torso" ], - "coverage": 95, "warmth": 20, "material_thickness": 0.05, - "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ] + "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ], + "armor": [ { "coverage": 95, "covers": [ "torso" ] } ] }, { "id": "under_armor_shorts", @@ -607,11 +568,10 @@ "symbol": "[", "looks_like": "shorts", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 45, "warmth": 20, "material_thickness": 0.1, - "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ] + "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ], + "armor": [ { "coverage": 45, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "undershirt", @@ -626,11 +586,10 @@ "symbol": "[", "looks_like": "tshirt", "color": "white", - "covers": [ "torso" ], - "coverage": 60, "warmth": 10, "material_thickness": 0.1, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 60, "covers": [ "torso" ] } ] }, { "id": "unitard", @@ -644,10 +603,9 @@ "material": [ "lycra" ], "symbol": "[", "color": "dark_gray", - "covers": [ "torso", "leg_l", "leg_r" ], - "coverage": 90, "warmth": 20, "material_thickness": 0.02, - "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ] + "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ], + "armor": [ { "coverage": 90, "covers": [ "torso", "leg_l", "leg_r" ] } ] } ] From 6db93b3516bafd4f2276bdda3cd834790d0dc3a1 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Tue, 6 Jul 2021 22:54:23 -0700 Subject: [PATCH 038/116] Convert armor to use armor_portion_data pt. 1 (#49679) I want to make changes to how armor data is specified, and I don't want to maintain two separate interfaces for it, so let's convert existing data to one interface. Items using copy-from were audited, and where they made changes, data was respecified as at the moment, copy-from modifying sub-elements of armor portion data is incorrect (there are lots of questions with no good answers there). --- data/json/items/armor/gloves.json | 260 ++++++++---------------- data/json/items/armor/hats.json | 183 ++++++----------- data/json/items/armor/helmets.json | 83 +++----- data/json/items/armor/holster.json | 59 ++---- data/json/items/armor/hoods.json | 52 ++--- data/json/items/armor/jewelry.json | 67 +++--- data/json/items/armor/legs_armor.json | 111 ++++------ data/json/items/armor/legs_clothes.json | 205 +++++++------------ data/json/items/armor/masks.json | 48 ++--- data/json/items/armor/misc.json | 65 +++--- 10 files changed, 394 insertions(+), 739 deletions(-) diff --git a/data/json/items/armor/gloves.json b/data/json/items/armor/gloves.json index fe759ff13b570..4ee20eb31ff5e 100644 --- a/data/json/items/armor/gloves.json +++ b/data/json/items/armor/gloves.json @@ -14,13 +14,11 @@ "symbol": "[", "looks_like": "gloves_leather", "color": "white", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 10, "warmth": 30, "material_thickness": 2, "environmental_protection": 2, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "encumbrance": 10, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "boxing_gloves", @@ -37,13 +35,11 @@ "symbol": "[", "looks_like": "gloves_leather", "color": "red", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 70, "warmth": 20, "material_thickness": 3, "environmental_protection": 3, - "flags": [ "VARSIZE", "OVERSIZE", "STURDY" ] + "flags": [ "VARSIZE", "OVERSIZE", "STURDY" ], + "armor": [ { "encumbrance": 70, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "chainmail_hands", @@ -59,11 +55,9 @@ "material": [ "iron", "cotton" ], "symbol": "[", "color": "light_red", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 30, "material_thickness": 2, - "flags": [ "VARSIZE", "STURDY" ] + "flags": [ "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": 30, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "xl_chainmail_hands", @@ -89,13 +83,11 @@ "symbol": "[", "looks_like": "gloves_leather", "color": "dark_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 50, "warmth": 25, "material_thickness": 3, "environmental_protection": 6, - "flags": [ "VARSIZE", "STURDY", "WATERPROOF" ] + "flags": [ "VARSIZE", "STURDY", "WATERPROOF" ], + "armor": [ { "encumbrance": 50, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gauntlets_chitin", @@ -113,13 +105,11 @@ "symbol": "[", "looks_like": "gauntlets_larmor", "color": "green", - "covers": [ "hand_l", "hand_r" ], - "coverage": 95, - "encumbrance": 12, "warmth": 20, "material_thickness": 4, "environmental_protection": 4, - "flags": [ "STURDY" ] + "flags": [ "STURDY" ], + "armor": [ { "encumbrance": 12, "coverage": 95, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "xl_gauntlets_chitin", @@ -163,13 +153,11 @@ "material": [ "leather", "cotton" ], "symbol": "[", "color": "white", - "covers": [ "hand_r" ], - "encumbrance": 4, - "coverage": 100, "warmth": 15, "material_thickness": 2.0, "environmental_protection": 1, - "flags": [ "STURDY" ] + "flags": [ "STURDY" ], + "armor": [ { "encumbrance": 4, "coverage": 100, "covers": [ "hand_r" ] } ] }, { "id": "gauntlet_fencing_l", @@ -185,13 +173,11 @@ "material": [ "leather", "cotton" ], "symbol": "[", "color": "white", - "covers": [ "hand_l" ], - "encumbrance": 4, - "coverage": 100, "warmth": 15, "material_thickness": 2.0, "environmental_protection": 1, - "flags": [ "STURDY" ] + "flags": [ "STURDY" ], + "armor": [ { "encumbrance": 4, "coverage": 100, "covers": [ "hand_l" ] } ] }, { "id": "gauntlets_larmor", @@ -209,13 +195,11 @@ "symbol": "[", "looks_like": "gloves_leather", "color": "brown", - "covers": [ "hand_l", "hand_r" ], - "coverage": 60, - "encumbrance": 4, "warmth": 15, "material_thickness": 3, "environmental_protection": 1, - "flags": [ "VARSIZE", "STURDY", "ALLOWS_NATURAL_ATTACKS", "ALLOWS_TALONS" ] + "flags": [ "VARSIZE", "STURDY", "ALLOWS_NATURAL_ATTACKS", "ALLOWS_TALONS" ], + "armor": [ { "encumbrance": 4, "coverage": 60, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "xl_gauntlets_larmor", @@ -239,11 +223,9 @@ "symbol": "[", "looks_like": "gloves_wraps", "color": "light_blue", - "covers": [ "hand_l", "hand_r" ], - "coverage": 70, - "encumbrance": 7, "material_thickness": 0.01, - "flags": [ "WATERPROOF", "OVERSIZE", "OUTER", "ALLOWS_TALONS" ] + "flags": [ "WATERPROOF", "OVERSIZE", "OUTER", "ALLOWS_TALONS" ], + "armor": [ { "encumbrance": 7, "coverage": 70, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_fingerless", @@ -259,11 +241,10 @@ "symbol": "[", "looks_like": "gloves_light", "color": "dark_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 50, "warmth": 10, "material_thickness": 0.5, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS", "ALLOWS_TALONS" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS", "ALLOWS_TALONS" ], + "armor": [ { "coverage": 50, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_fingerless_mod", @@ -280,12 +261,10 @@ "symbol": "[", "looks_like": "gloves_fingerless", "color": "dark_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 50, - "encumbrance": 3, "warmth": 5, "material_thickness": 0.5, - "flags": [ "VARSIZE", "ALLOWS_NATURAL_ATTACKS", "ALLOWS_TALONS" ] + "flags": [ "VARSIZE", "ALLOWS_NATURAL_ATTACKS", "ALLOWS_TALONS" ], + "armor": [ { "encumbrance": 3, "coverage": 50, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_fsurvivor", @@ -302,13 +281,11 @@ "symbol": "[", "looks_like": "fire_gauntlets", "color": "light_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 30, "warmth": 15, "material_thickness": 3, "environmental_protection": 10, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 30, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "xl_gloves_fsurvivor", @@ -332,11 +309,9 @@ "symbol": "[", "looks_like": "fire_gauntlets", "color": "brown", - "covers": [ "hand_l", "hand_r" ], - "coverage": 95, - "encumbrance": 30, "warmth": 70, - "material_thickness": 3 + "material_thickness": 3, + "armor": [ { "encumbrance": 30, "coverage": 95, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "xl_gloves_fur", @@ -384,13 +359,11 @@ "symbol": "[", "looks_like": "fire_gauntlets", "color": "dark_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 30, "warmth": 15, "material_thickness": 4, "environmental_protection": 5, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 30, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "xl_gloves_hsurvivor", @@ -415,11 +388,10 @@ "symbol": "[", "looks_like": "gloves_leather", "color": "white", - "covers": [ "hand_r" ], - "coverage": 95, "warmth": 20, "material_thickness": 0.5, - "flags": [ "WATER_FRIENDLY", "FANCY" ] + "flags": [ "WATER_FRIENDLY", "FANCY" ], + "armor": [ { "coverage": 95, "covers": [ "hand_r" ] } ] }, { "id": "gloves_leather", @@ -435,13 +407,11 @@ "symbol": "[", "looks_like": "gloves_light", "color": "dark_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 95, - "encumbrance": 10, "warmth": 25, "material_thickness": 0.5, "valid_mods": [ "steel_padded" ], - "flags": [ "VARSIZE", "WATERPROOF" ] + "flags": [ "VARSIZE", "WATERPROOF" ], + "armor": [ { "encumbrance": 10, "coverage": 95, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "xl_gloves_leather", @@ -465,12 +435,10 @@ "symbol": "[", "looks_like": "gloves_leather", "color": "light_blue", - "covers": [ "hand_l", "hand_r" ], - "coverage": 95, - "encumbrance": 2, "warmth": 20, "material_thickness": 0.2, - "flags": [ "WATER_FRIENDLY" ] + "flags": [ "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 2, "coverage": 95, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "xl_gloves_light", @@ -494,12 +462,10 @@ "symbol": "[", "looks_like": "gloves_light", "color": "light_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 95, - "encumbrance": 1, "warmth": 15, "material_thickness": 0.1, - "flags": [ "WATER_FRIENDLY", "SKINTIGHT" ] + "flags": [ "WATER_FRIENDLY", "SKINTIGHT" ], + "armor": [ { "encumbrance": 1, "coverage": 95, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "xl_gloves_liner", @@ -524,13 +490,11 @@ "symbol": "[", "looks_like": "gloves_survivor", "color": "green", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 10, "warmth": 15, "material_thickness": 1, "environmental_protection": 3, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 10, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "xl_gloves_lsurvivor", @@ -555,13 +519,11 @@ "material": [ "kevlar_layered", "cotton" ], "symbol": "[", "color": "green", - "covers": [ "hand_l", "hand_r" ], - "coverage": 85, - "encumbrance": 8, "warmth": 12, "material_thickness": 1, "environmental_protection": 3, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 8, "coverage": 85, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "xl_gloves_lsurvivor_fingerless", @@ -586,13 +548,11 @@ "material": [ "kevlar_layered", "leather" ], "symbol": "[", "color": "brown", - "covers": [ "hand_l", "hand_r" ], - "coverage": 85, - "encumbrance": 16, "warmth": 12, "material_thickness": 3, "environmental_protection": 3, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY", "ALLOWS_NATURAL_ATTACKS", "ALLOWS_TALONS" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY", "ALLOWS_NATURAL_ATTACKS", "ALLOWS_TALONS" ], + "armor": [ { "encumbrance": 16, "coverage": 85, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "xl_gloves_survivor_fingerless", @@ -617,12 +577,10 @@ "symbol": "[", "looks_like": "gloves_light", "color": "white", - "covers": [ "hand_l", "hand_r" ], - "coverage": 90, - "encumbrance": 1, "material_thickness": 0.1, "environmental_protection": 6, - "flags": [ "WATER_FRIENDLY", "WATERPROOF", "SKINTIGHT" ] + "flags": [ "WATER_FRIENDLY", "WATERPROOF", "SKINTIGHT" ], + "armor": [ { "encumbrance": 1, "coverage": 90, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_plate", @@ -640,13 +598,11 @@ "symbol": "[", "looks_like": "fire_gauntlets", "color": "light_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 20, "warmth": 20, "material_thickness": 4, "environmental_protection": 1, - "flags": [ "VARSIZE", "STURDY" ] + "flags": [ "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "xl_gloves_plate", @@ -671,13 +627,11 @@ "symbol": "[", "looks_like": "gloves_light", "color": "yellow", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 4, "warmth": 10, "material_thickness": 0.35, "environmental_protection": 8, - "flags": [ "WATERPROOF" ] + "flags": [ "WATERPROOF" ], + "armor": [ { "encumbrance": 4, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_survivor", @@ -694,13 +648,11 @@ "symbol": "[", "looks_like": "fire_gauntlets", "color": "brown", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 20, "warmth": 15, "material_thickness": 3, "environmental_protection": 3, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_tactical", @@ -718,13 +670,11 @@ "symbol": "[", "looks_like": "fire_gauntlets", "color": "dark_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 13, "warmth": 20, "material_thickness": 1.5, "environmental_protection": 2, - "flags": [ "VARSIZE", "STURDY" ] + "flags": [ "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": 13, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_winter", @@ -741,11 +691,9 @@ "symbol": "[", "looks_like": "gloves_leather", "color": "light_blue", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 40, "warmth": 70, - "material_thickness": 4 + "material_thickness": 4, + "armor": [ { "encumbrance": 40, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_wool", @@ -761,11 +709,9 @@ "symbol": "[", "looks_like": "gloves_winter", "color": "blue", - "covers": [ "hand_l", "hand_r" ], - "coverage": 95, - "encumbrance": 20, "warmth": 60, - "material_thickness": 3 + "material_thickness": 3, + "armor": [ { "encumbrance": 20, "coverage": 95, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "xl_gloves_wool", @@ -789,13 +735,11 @@ "symbol": "[", "looks_like": "gloves_leather", "color": "brown", - "covers": [ "hand_l", "hand_r" ], - "coverage": 95, - "encumbrance": 20, "warmth": 25, "material_thickness": 2, "environmental_protection": 5, - "flags": [ "WATERPROOF", "STURDY" ] + "flags": [ "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 95, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_cut_resistant", @@ -812,13 +756,11 @@ "symbol": "[", "looks_like": "gloves_work", "color": "light_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 95, - "encumbrance": 40, "warmth": 10, "material_thickness": 2, "environmental_protection": 1, - "flags": [ "STURDY" ] + "flags": [ "STURDY" ], + "armor": [ { "encumbrance": 40, "coverage": 95, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_wraps", @@ -834,11 +776,10 @@ "symbol": "[", "looks_like": "gloves_light", "color": "white", - "covers": [ "hand_l", "hand_r" ], - "coverage": 50, "warmth": 5, "material_thickness": 2, - "flags": [ "SKINTIGHT", "OVERSIZE", "ALLOWS_NATURAL_ATTACKS", "ALLOWS_TALONS" ] + "flags": [ "SKINTIGHT", "OVERSIZE", "ALLOWS_NATURAL_ATTACKS", "ALLOWS_TALONS" ], + "armor": [ { "coverage": 50, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_wraps_fur", @@ -854,12 +795,10 @@ "symbol": "[", "looks_like": "gloves_wraps", "color": "white", - "covers": [ "hand_l", "hand_r" ], - "coverage": 50, - "encumbrance": 5, "warmth": 20, "material_thickness": 2, - "flags": [ "OVERSIZE", "ALLOWS_NATURAL_ATTACKS", "ALLOWS_TALONS" ] + "flags": [ "OVERSIZE", "ALLOWS_NATURAL_ATTACKS", "ALLOWS_TALONS" ], + "armor": [ { "encumbrance": 5, "coverage": 50, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_wraps_leather", @@ -875,12 +814,10 @@ "symbol": "[", "looks_like": "gloves_wraps", "color": "white", - "covers": [ "hand_l", "hand_r" ], - "coverage": 50, - "encumbrance": 5, "warmth": 10, "material_thickness": 2, - "flags": [ "OVERSIZE", "ALLOWS_NATURAL_ATTACKS", "ALLOWS_TALONS" ] + "flags": [ "OVERSIZE", "ALLOWS_NATURAL_ATTACKS", "ALLOWS_TALONS" ], + "armor": [ { "encumbrance": 5, "coverage": 50, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_wraps_wool", @@ -896,12 +833,10 @@ "symbol": "[", "looks_like": "gloves_wraps", "color": "blue", - "covers": [ "hand_l", "hand_r" ], - "coverage": 50, - "encumbrance": 2, "warmth": 15, "material_thickness": 2, - "flags": [ "SKINTIGHT", "OVERSIZE", "ALLOWS_NATURAL_ATTACKS", "ALLOWS_TALONS" ] + "flags": [ "SKINTIGHT", "OVERSIZE", "ALLOWS_NATURAL_ATTACKS", "ALLOWS_TALONS" ], + "armor": [ { "encumbrance": 2, "coverage": 50, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_wsurvivor", @@ -918,13 +853,11 @@ "symbol": "[", "looks_like": "gloves_winter", "color": "light_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 37, "warmth": 75, "material_thickness": 4, "environmental_protection": 5, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 37, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "xl_gloves_wsurvivor", @@ -949,13 +882,11 @@ "symbol": "[", "looks_like": "gloves_survivor", "color": "brown", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 30, "warmth": 15, "material_thickness": 2, "environmental_protection": 3, - "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 30, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "long_glove_white", @@ -994,12 +925,10 @@ "symbol": "[", "looks_like": "gloves_wool", "color": "blue", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 80, "warmth": 70, "material_thickness": 1, - "flags": [ "OVERSIZE", "OUTER" ] + "flags": [ "OVERSIZE", "OUTER" ], + "armor": [ { "encumbrance": 80, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "nomex_gloves", @@ -1015,13 +944,11 @@ "symbol": "[", "looks_like": "gloves_light", "color": "light_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 6, "warmth": 5, "material_thickness": 1, "environmental_protection": 2, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT", "STURDY" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT", "STURDY" ], + "armor": [ { "encumbrance": 6, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "sockmitts", @@ -1036,11 +963,10 @@ "symbol": "[", "looks_like": "mittens", "color": "white", - "covers": [ "hand_l", "hand_r" ], - "coverage": 40, "warmth": 5, "material_thickness": 0.2, - "flags": [ "VARSIZE", "SKINTIGHT", "ALLOWS_NATURAL_ATTACKS", "ALLOWS_TALONS" ] + "flags": [ "VARSIZE", "SKINTIGHT", "ALLOWS_NATURAL_ATTACKS", "ALLOWS_TALONS" ], + "armor": [ { "coverage": 40, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "stockings_tent_arms", @@ -1055,12 +981,10 @@ "symbol": "[", "looks_like": "arm_warmers", "color": "dark_gray", - "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], - "coverage": 75, - "encumbrance": 10, "warmth": 10, "material_thickness": 0.2, - "flags": [ "VARSIZE", "SKINTIGHT", "OVERSIZE" ] + "flags": [ "VARSIZE", "SKINTIGHT", "OVERSIZE" ], + "armor": [ { "encumbrance": 10, "coverage": 75, "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ] } ] }, { "id": "winter_gloves_army", @@ -1077,11 +1001,9 @@ "symbol": "[", "looks_like": "fire_gauntlets", "color": "white", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 20, "warmth": 50, - "material_thickness": 2 + "material_thickness": 2, + "armor": [ { "encumbrance": 20, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_golf", @@ -1098,12 +1020,10 @@ "symbol": "[", "looks_like": "gloves_light", "color": "dark_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 90, - "encumbrance": 5, "warmth": 20, "material_thickness": 0.5, - "flags": [ "VARSIZE", "WATERPROOF", "SKINTIGHT" ] + "flags": [ "VARSIZE", "WATERPROOF", "SKINTIGHT" ], + "armor": [ { "encumbrance": 5, "coverage": 90, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_eod", @@ -1114,16 +1034,14 @@ "weight": "800 g", "volume": "1500 ml", "price": 70000, - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 20, "warmth": 40, "material": [ "kevlar_layered", "nomex" ], "symbol": "[", "color": "light_gray", "environmental_protection": 2, "material_thickness": 5, - "flags": [ "STURDY", "OUTER", "RAINPROOF", "ONLY_ONE" ] + "flags": [ "STURDY", "OUTER", "RAINPROOF", "ONLY_ONE" ], + "armor": [ { "encumbrance": 20, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "gloves_studded", @@ -1140,11 +1058,9 @@ "symbol": "[", "looks_like": "gloves_leather", "color": "light_gray", - "covers": [ "hand_l", "hand_r" ], - "coverage": 100, - "encumbrance": 5, "warmth": 5, "material_thickness": 2, - "flags": [ "WATER_FRIENDLY", "STAB", "DURABLE_MELEE" ] + "flags": [ "WATER_FRIENDLY", "STAB", "DURABLE_MELEE" ], + "armor": [ { "encumbrance": 5, "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] } ] diff --git a/data/json/items/armor/hats.json b/data/json/items/armor/hats.json index 1f64e44ac7ab4..4c6c1301eeafb 100644 --- a/data/json/items/armor/hats.json +++ b/data/json/items/armor/hats.json @@ -13,13 +13,11 @@ "symbol": "[", "looks_like": "cowboy_hat", "color": "brown", - "covers": [ "head" ], - "coverage": 50, - "encumbrance": 20, "warmth": 8, "material_thickness": 0.3, "environmental_protection": 2, - "flags": [ "VARSIZE", "SUN_GLASSES" ] + "flags": [ "VARSIZE", "SUN_GLASSES" ], + "armor": [ { "encumbrance": 20, "coverage": 50, "covers": [ "head" ] } ] }, { "id": "bandana_head", @@ -41,10 +39,9 @@ "symbol": "[", "looks_like": "scarf", "color": "blue", - "covers": [ "head" ], - "coverage": 80, "warmth": 5, - "material_thickness": 0.1 + "material_thickness": 0.1, + "armor": [ { "coverage": 80, "covers": [ "head" ] } ] }, { "id": "beret", @@ -60,11 +57,10 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 40, "warmth": 10, "material_thickness": 0.3, - "flags": [ "VARSIZE", "WATER_FRIENDLY" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY" ], + "armor": [ { "coverage": 40, "covers": [ "head" ] } ] }, { "id": "beret_wool", @@ -79,11 +75,10 @@ "symbol": "[", "looks_like": "beret", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 40, "warmth": 15, "material_thickness": 0.3, - "flags": [ "VARSIZE", "WATERPROOF" ] + "flags": [ "VARSIZE", "WATERPROOF" ], + "armor": [ { "coverage": 40, "covers": [ "head" ] } ] }, { "id": "bowhat", @@ -99,13 +94,11 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 50, - "encumbrance": 15, "warmth": 5, "material_thickness": 0.3, "environmental_protection": 1, - "flags": [ "FANCY", "VARSIZE" ] + "flags": [ "FANCY", "VARSIZE" ], + "armor": [ { "encumbrance": 15, "coverage": 50, "covers": [ "head" ] } ] }, { "id": "chaplet", @@ -120,10 +113,9 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 40, "material_thickness": 0.1, - "flags": [ "OVERSIZE", "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "OVERSIZE", "WATER_FRIENDLY", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "coverage": 40, "covers": [ "head" ] } ] }, { "id": "cowboy_hat", @@ -138,13 +130,11 @@ "symbol": "[", "looks_like": "bowhat", "color": "brown", - "covers": [ "head" ], - "coverage": 50, - "encumbrance": 10, "warmth": 7, "material_thickness": 0.3, "environmental_protection": 2, - "flags": [ "VARSIZE", "SUN_GLASSES" ] + "flags": [ "VARSIZE", "SUN_GLASSES" ], + "armor": [ { "encumbrance": 10, "coverage": 50, "covers": [ "head" ] } ] }, { "id": "drinking_hat", @@ -159,12 +149,10 @@ "material": [ "cotton", "plastic" ], "weight": "733 g", "volume": "1500 ml", - "encumbrance": 5, - "covers": [ "head" ], - "coverage": 15, "material_thickness": 0.2, "pocket_data": [ { "max_contains_volume": "500 ml", "max_contains_weight": "1 kg", "watertight": true, "rigid": true } ], - "flags": [ "OVERSIZE", "BELTED", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY" ] + "flags": [ "OVERSIZE", "BELTED", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 5, "coverage": 15, "covers": [ "head" ] } ] }, { "id": "eboshi", @@ -180,11 +168,9 @@ "symbol": "[", "looks_like": "bowhat", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 60, - "encumbrance": 10, "warmth": 4, - "material_thickness": 0.2 + "material_thickness": 0.2, + "armor": [ { "encumbrance": 10, "coverage": 60, "covers": [ "head" ] } ] }, { "id": "hat_boonie", @@ -199,13 +185,11 @@ "symbol": "[", "looks_like": "cowboy_hat", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 65, - "encumbrance": 10, "warmth": 10, "material_thickness": 0.3, "environmental_protection": 2, - "flags": [ "VARSIZE", "SUN_GLASSES" ] + "flags": [ "VARSIZE", "SUN_GLASSES" ], + "armor": [ { "encumbrance": 10, "coverage": 65, "covers": [ "head" ] } ] }, { "id": "hat_ball", @@ -222,13 +206,11 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 50, - "encumbrance": 10, "warmth": 5, "material_thickness": 0.1, "environmental_protection": 2, - "flags": [ "SUN_GLASSES" ] + "flags": [ "SUN_GLASSES" ], + "armor": [ { "encumbrance": 10, "coverage": 50, "covers": [ "head" ] } ] }, { "id": "hat_chef", @@ -244,12 +226,10 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "white", - "covers": [ "head" ], - "coverage": 75, - "encumbrance": 15, "warmth": 5, "material_thickness": 0.1, - "environmental_protection": 1 + "environmental_protection": 1, + "armor": [ { "encumbrance": 15, "coverage": 75, "covers": [ "head" ] } ] }, { "id": "hat_cotton", @@ -264,11 +244,10 @@ "symbol": "[", "looks_like": "hat_ball", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 65, "warmth": 20, "material_thickness": 0.1, - "flags": [ "VARSIZE", "HELMET_COMPAT" ] + "flags": [ "VARSIZE", "HELMET_COMPAT" ], + "armor": [ { "coverage": 65, "covers": [ "head" ] } ] }, { "id": "hat_fur", @@ -283,11 +262,9 @@ "symbol": "[", "looks_like": "hat_knit", "color": "brown", - "covers": [ "head" ], - "coverage": 95, - "encumbrance": 10, "warmth": 70, - "material_thickness": 0.3 + "material_thickness": 0.3, + "armor": [ { "encumbrance": 10, "coverage": 95, "covers": [ "head" ] } ] }, { "id": "hat_faux_fur", @@ -297,7 +274,6 @@ "name": { "str": "faux fur hat" }, "description": "A stylish hat made of faux fur. Like real fur, but without the suffering, if the tag is to be believed. Very warm.", "material": [ "faux_fur", "cotton" ], - "covers": [ "head" ], "warmth": 60 }, { @@ -314,13 +290,11 @@ "symbol": "[", "looks_like": "hat_ball", "color": "yellow", - "covers": [ "head" ], - "coverage": 80, - "encumbrance": 15, "warmth": 5, "material_thickness": 4, "techniques": [ "WBLOCK_1" ], - "flags": [ "WATERPROOF" ] + "flags": [ "WATERPROOF" ], + "armor": [ { "encumbrance": 15, "coverage": 80, "covers": [ "head" ] } ] }, { "id": "hat_hard_hooded", @@ -337,13 +311,11 @@ "symbol": "[", "looks_like": "hat_hard", "color": "yellow", - "covers": [ "head" ], - "coverage": 80, - "encumbrance": 13, "warmth": 6, "material_thickness": 4, "techniques": [ "WBLOCK_1" ], - "flags": [ "WATERPROOF" ] + "flags": [ "WATERPROOF" ], + "armor": [ { "encumbrance": 13, "coverage": 80, "covers": [ "head" ] } ] }, { "id": "hat_hunting", @@ -358,13 +330,11 @@ "symbol": "[", "looks_like": "hat_ball", "color": "light_red", - "covers": [ "head" ], - "coverage": 85, - "encumbrance": 10, "warmth": 50, "material_thickness": 0.3, "environmental_protection": 2, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 10, "coverage": 85, "covers": [ "head" ] } ] }, { "id": "hat_knit", @@ -379,11 +349,10 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 65, "warmth": 40, "material_thickness": 0.5, - "flags": [ "VARSIZE", "HELMET_COMPAT" ] + "flags": [ "VARSIZE", "HELMET_COMPAT" ], + "armor": [ { "coverage": 65, "covers": [ "head" ] } ] }, { "id": "hat_newsboy", @@ -399,11 +368,10 @@ "symbol": "[", "looks_like": "hat_ball", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 50, "warmth": 30, "material_thickness": 0.2, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "coverage": 50, "covers": [ "head" ] } ] }, { "id": "hat_noise_cancelling", @@ -418,12 +386,10 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 5, - "encumbrance": 17, "warmth": 5, "material_thickness": 0.1, - "flags": [ "DEAF", "HELMET_COMPAT" ] + "flags": [ "DEAF", "HELMET_COMPAT" ], + "armor": [ { "encumbrance": 17, "coverage": 5, "covers": [ "head" ] } ] }, { "id": "hat_sombrero", @@ -440,13 +406,11 @@ "symbol": "[", "looks_like": "cowboy_hat", "color": "light_red", - "covers": [ "head" ], - "coverage": 50, - "encumbrance": 20, "warmth": 2, "material_thickness": 0.2, "environmental_protection": 4, - "flags": [ "OUTER", "SUN_GLASSES" ] + "flags": [ "OUTER", "SUN_GLASSES" ], + "armor": [ { "encumbrance": 20, "coverage": 50, "covers": [ "head" ] } ] }, { "id": "kippah", @@ -462,11 +426,10 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "blue", - "covers": [ "head" ], - "coverage": 40, "warmth": 3, "material_thickness": 0.1, - "flags": [ "HELMET_COMPAT" ] + "flags": [ "HELMET_COMPAT" ], + "armor": [ { "coverage": 40, "covers": [ "head" ] } ] }, { "id": "kufi", @@ -482,12 +445,10 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "white", - "covers": [ "head" ], - "coverage": 50, - "encumbrance": 10, "warmth": 6, "material_thickness": 0.1, - "environmental_protection": 1 + "environmental_protection": 1, + "armor": [ { "encumbrance": 10, "coverage": 50, "covers": [ "head" ] } ] }, { "id": "maid_hat", @@ -503,12 +464,10 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "white", - "covers": [ "head" ], - "coverage": 25, - "encumbrance": 10, "warmth": 10, "material_thickness": 0.05, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 10, "coverage": 25, "covers": [ "head" ] } ] }, { "id": "porkpie", @@ -524,13 +483,11 @@ "symbol": "[", "looks_like": "bowhat", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 50, - "encumbrance": 15, "warmth": 5, "material_thickness": 0.2, "environmental_protection": 1, - "flags": [ "FANCY", "VARSIZE" ] + "flags": [ "FANCY", "VARSIZE" ], + "armor": [ { "encumbrance": 15, "coverage": 50, "covers": [ "head" ] } ] }, { "id": "postman_hat", @@ -546,13 +503,11 @@ "symbol": "[", "looks_like": "hat_ball", "color": "blue", - "covers": [ "head" ], - "coverage": 60, - "encumbrance": 10, "warmth": 10, "material_thickness": 0.1, "environmental_protection": 2, - "flags": [ "SUN_GLASSES" ] + "flags": [ "SUN_GLASSES" ], + "armor": [ { "encumbrance": 10, "coverage": 60, "covers": [ "head" ] } ] }, { "id": "straw_hat", @@ -567,12 +522,11 @@ "symbol": "[", "looks_like": "cowboy_hat", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 40, "warmth": 2, "material_thickness": 0.2, "environmental_protection": 2, - "flags": [ "VARSIZE", "SUN_GLASSES" ] + "flags": [ "VARSIZE", "SUN_GLASSES" ], + "armor": [ { "coverage": 40, "covers": [ "head" ] } ] }, { "id": "tinfoil_hat", @@ -588,9 +542,8 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "yellow", - "covers": [ "head" ], - "coverage": 90, - "flags": [ "PSYSHIELD_PARTIAL", "SKINTIGHT", "TRADER_AVOID" ] + "flags": [ "PSYSHIELD_PARTIAL", "SKINTIGHT", "TRADER_AVOID" ], + "armor": [ { "coverage": 90, "covers": [ "head" ] } ] }, { "id": "tophat", @@ -607,13 +560,11 @@ "symbol": "[", "looks_like": "porkpie", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 50, - "encumbrance": 20, "warmth": 5, "material_thickness": 0.2, "environmental_protection": 1, - "flags": [ "VARSIZE", "SUPER_FANCY" ] + "flags": [ "VARSIZE", "SUPER_FANCY" ], + "armor": [ { "encumbrance": 20, "coverage": 50, "covers": [ "head" ] } ] }, { "id": "tricorne", @@ -628,13 +579,11 @@ "symbol": "[", "looks_like": "bowhat", "color": "brown", - "covers": [ "head" ], - "coverage": 50, - "encumbrance": 10, "warmth": 7, "material_thickness": 0.2, "environmental_protection": 1, - "flags": [ "VARSIZE", "WATERPROOF", "WATER_FRIENDLY", "FANCY" ] + "flags": [ "VARSIZE", "WATERPROOF", "WATER_FRIENDLY", "FANCY" ], + "armor": [ { "encumbrance": 10, "coverage": 50, "covers": [ "head" ] } ] }, { "id": "turban", @@ -651,12 +600,10 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "white", - "covers": [ "head" ], - "coverage": 50, - "encumbrance": 5, "warmth": 10, "material_thickness": 0.3, - "flags": [ "OVERSIZE", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "OVERSIZE", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 5, "coverage": 50, "covers": [ "head" ] } ] }, { "id": "hat_golf", @@ -673,12 +620,10 @@ "symbol": "[", "looks_like": "hat_ball", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 40, - "encumbrance": 10, "warmth": 5, "material_thickness": 0.1, "environmental_protection": 1, - "flags": [ "SUN_GLASSES" ] + "flags": [ "SUN_GLASSES" ], + "armor": [ { "encumbrance": 10, "coverage": 40, "covers": [ "head" ] } ] } ] diff --git a/data/json/items/armor/helmets.json b/data/json/items/armor/helmets.json index 02a89dcf7d7f7..2ed565e6b4ef9 100644 --- a/data/json/items/armor/helmets.json +++ b/data/json/items/armor/helmets.json @@ -14,13 +14,11 @@ "symbol": "[", "looks_like": "helmet_plate", "color": "light_gray", - "covers": [ "head" ], - "coverage": 55, - "encumbrance": 50, "warmth": 5, "material_thickness": 2, "qualities": [ [ "COOK", 3 ], [ "BOIL", 2 ], [ "CONTAIN", 1 ], [ "CHEM", 1 ] ], - "techniques": [ "WBLOCK_1" ] + "techniques": [ "WBLOCK_1" ], + "armor": [ { "encumbrance": 50, "coverage": 55, "covers": [ "head" ] } ] }, { "id": "headgear", @@ -37,13 +35,11 @@ "symbol": "[", "looks_like": "balclava", "color": "red", - "covers": [ "head" ], - "coverage": 75, - "encumbrance": 20, "warmth": 10, "material_thickness": 3, "environmental_protection": 1, - "flags": [ "VARSIZE", "OVERSIZE", "STURDY" ] + "flags": [ "VARSIZE", "OVERSIZE", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 75, "covers": [ "head" ] } ] }, { "id": "helmet_army", @@ -62,13 +58,11 @@ "symbol": "[", "looks_like": "hat_hard", "color": "green", - "covers": [ "head" ], - "coverage": 85, - "encumbrance": 20, "warmth": 20, "material_thickness": 9, "techniques": [ "WBLOCK_1" ], - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 85, "covers": [ "head" ] } ] }, { "id": "tac_fullhelmet", @@ -115,13 +109,11 @@ "symbol": "[", "looks_like": "tac_fullhelmet", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 95, - "encumbrance": 16, "warmth": 20, "material_thickness": 8, "techniques": [ "WBLOCK_1" ], - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 16, "coverage": 95, "covers": [ "head" ] } ] }, { "id": "firehelmet", @@ -140,13 +132,11 @@ "symbol": "[", "looks_like": "cowboy_hat", "color": "yellow", - "covers": [ "head" ], - "coverage": 75, - "encumbrance": 40, "warmth": 15, "material_thickness": 6, "environmental_protection": 6, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 40, "coverage": 75, "covers": [ "head" ] } ] }, { "id": "helmet_ball", @@ -165,13 +155,11 @@ "symbol": "[", "looks_like": "hat_hard", "color": "blue", - "covers": [ "head" ], - "coverage": 95, - "encumbrance": 20, "warmth": 15, "material_thickness": 3, "environmental_protection": 1, - "techniques": [ "WBLOCK_1" ] + "techniques": [ "WBLOCK_1" ], + "armor": [ { "encumbrance": 20, "coverage": 95, "covers": [ "head" ] } ] }, { "id": "helmet_barbute", @@ -222,12 +210,10 @@ "symbol": "[", "looks_like": "hat_hard", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 75, - "encumbrance": 15, "warmth": 15, "material_thickness": 4, - "techniques": [ "WBLOCK_1" ] + "techniques": [ "WBLOCK_1" ], + "armor": [ { "encumbrance": 15, "coverage": 75, "covers": [ "head" ] } ] }, { "id": "helmet_chitin", @@ -278,13 +264,11 @@ "symbol": "[", "looks_like": "helmet_barbute", "color": "brown", - "covers": [ "head" ], - "coverage": 90, - "encumbrance": 20, "warmth": 35, "material_thickness": 3, "techniques": [ "WBLOCK_1" ], - "flags": [ "VARSIZE", "STURDY" ] + "flags": [ "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 90, "covers": [ "head" ] } ] }, { "id": "xl_helmet_conical", @@ -420,13 +404,11 @@ "symbol": "[", "looks_like": "hat_hard", "color": "brown", - "covers": [ "head" ], - "coverage": 85, - "encumbrance": 20, "warmth": 10, "material_thickness": 3, "techniques": [ "WBLOCK_1" ], - "flags": [ "VARSIZE", "WATER_FRIENDLY", "STURDY" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 85, "covers": [ "head" ] } ] }, { "id": "xl_helmet_larmor", @@ -449,11 +431,9 @@ "material": [ "leather", "bone" ], "symbol": "[", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 85, - "encumbrance": 26, "material_thickness": 3, - "flags": [ "WATER_FRIENDLY" ] + "flags": [ "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 26, "coverage": 85, "covers": [ "head" ] } ] }, { "id": "helmet_liner", @@ -471,11 +451,10 @@ "symbol": "[", "looks_like": "balclava", "color": "green", - "covers": [ "head" ], - "coverage": 100, "warmth": 30, "material_thickness": 0.5, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 100, "covers": [ "head" ] } ] }, { "id": "helmet_lobster", @@ -713,12 +692,10 @@ "symbol": "[", "looks_like": "helmet_bike", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 65, - "encumbrance": 20, "warmth": 10, "material_thickness": 4, - "techniques": [ "WBLOCK_1" ] + "techniques": [ "WBLOCK_1" ], + "armor": [ { "encumbrance": 20, "coverage": 65, "covers": [ "head" ] } ] }, { "id": "pickelhaube", @@ -738,12 +715,10 @@ "symbol": "[", "looks_like": "helmet_plate", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 70, - "encumbrance": 20, "warmth": 15, "material_thickness": 3, - "flags": [ "STAB" ] + "flags": [ "STAB" ], + "armor": [ { "encumbrance": 20, "coverage": 70, "covers": [ "head" ] } ] }, { "id": "helmet_corinthian", @@ -794,12 +769,10 @@ "symbol": "[", "looks_like": "pot_helmet", "color": "light_gray", - "covers": [ "head" ], - "coverage": 55, - "encumbrance": 50, "warmth": 5, "material_thickness": 2, "techniques": [ "WBLOCK_1" ], - "flags": [ "OVERSIZE" ] + "flags": [ "OVERSIZE" ], + "armor": [ { "encumbrance": 50, "coverage": 55, "covers": [ "head" ] } ] } ] diff --git a/data/json/items/armor/holster.json b/data/json/items/armor/holster.json index 626c346e1f5b0..fe852acd38dbe 100644 --- a/data/json/items/armor/holster.json +++ b/data/json/items/armor/holster.json @@ -12,10 +12,6 @@ "symbol": "[", "looks_like": "quiver_large", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 5, - "encumbrance": 3, - "max_encumbrance": 15, "material_thickness": 1, "pocket_data": [ { @@ -29,7 +25,8 @@ } ], "use_action": { "type": "holster" }, - "flags": [ "BELTED", "OVERSIZE", "NO_QUICKDRAW" ] + "flags": [ "BELTED", "OVERSIZE", "NO_QUICKDRAW" ], + "armor": [ { "encumbrance": [ 3, 15 ], "coverage": 5, "covers": [ "torso" ] } ] }, { "id": "baldric_holster", @@ -44,9 +41,6 @@ "symbol": "[", "looks_like": "quiver_large", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 20, - "encumbrance": 2, "material_thickness": 1, "pocket_data": [ { @@ -105,7 +99,8 @@ } ], "use_action": { "type": "holster" }, - "flags": [ "WATER_FRIENDLY", "BELTED", "OVERSIZE" ] + "flags": [ "WATER_FRIENDLY", "BELTED", "OVERSIZE" ], + "armor": [ { "encumbrance": 2, "coverage": 20, "covers": [ "torso" ] } ] }, { "id": "bootstrap", @@ -120,11 +115,7 @@ "symbol": "[", "looks_like": "holster", "color": "brown", - "covers": [ "foot_l", "foot_r" ], "sided": true, - "coverage": 5, - "encumbrance": 3, - "max_encumbrance": 4, "material_thickness": 1, "flags": [ "BELTED", "OVERSIZE", "ALLOWS_NATURAL_ATTACKS", "NOT_FOOTWEAR" ], "pocket_data": [ @@ -138,7 +129,8 @@ "moves": 150 } ], - "use_action": { "type": "holster" } + "use_action": { "type": "holster" }, + "armor": [ { "encumbrance": [ 3, 4 ], "coverage": 5, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "bow_sling", @@ -153,10 +145,6 @@ "symbol": "[", "looks_like": "slingpack", "color": "green", - "covers": [ "torso" ], - "coverage": 5, - "encumbrance": 3, - "max_encumbrance": 7, "material_thickness": 1, "flags": [ "OVERSIZE", "WAIST" ], "pocket_data": [ @@ -171,7 +159,8 @@ "flag_restriction": [ "SHEATH_BOW" ] } ], - "use_action": { "type": "holster" } + "use_action": { "type": "holster" }, + "armor": [ { "encumbrance": [ 3, 7 ], "coverage": 5, "covers": [ "torso" ] } ] }, { "id": "holster", @@ -186,11 +175,7 @@ "symbol": "[", "looks_like": "sheath", "color": "light_gray", - "covers": [ "leg_l", "leg_r" ], "sided": true, - "coverage": 5, - "encumbrance": 3, - "max_encumbrance": 4, "material_thickness": 1, "pocket_data": [ { @@ -205,7 +190,8 @@ } ], "use_action": { "type": "holster" }, - "flags": [ "WAIST", "OVERSIZE" ] + "flags": [ "WAIST", "OVERSIZE" ], + "armor": [ { "encumbrance": [ 3, 4 ], "coverage": 5, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "western_holster", @@ -266,8 +252,6 @@ "name": { "str": "fast draw holster" }, "description": "A comfortable quick draw holster for small guns. Activate to holster/draw a gun.", "price_postapoc": 500, - "encumbrance": 1, - "max_encumbrance": 2, "pocket_data": [ { "magazine_well": "200 ml", @@ -280,7 +264,8 @@ "moves": 30 } ], - "use_action": { "type": "holster" } + "use_action": { "type": "holster" }, + "armor": [ { "encumbrance": [ 1, 2 ], "coverage": 5, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "bholster", @@ -293,9 +278,6 @@ "price": 3000, "price_postapoc": 500, "material": [ "lycra" ], - "covers": [ "leg_l", "leg_r" ], - "encumbrance": 1, - "max_encumbrance": 3, "pocket_data": [ { "magazine_well": "150 ml", @@ -309,7 +291,8 @@ } ], "use_action": { "type": "holster" }, - "flags": [ "SKINTIGHT", "WATER_FRIENDLY" ] + "flags": [ "SKINTIGHT", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": [ 1, 3 ], "coverage": 5, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "survivor_vest", @@ -324,10 +307,6 @@ "symbol": "[", "looks_like": "tacvest", "color": "green", - "covers": [ "torso" ], - "coverage": 20, - "encumbrance": 4, - "max_encumbrance": 12, "material_thickness": 2, "pocket_data": [ { @@ -362,7 +341,8 @@ } ], "use_action": { "type": "holster" }, - "flags": [ "WATER_FRIENDLY", "STURDY", "WAIST" ] + "flags": [ "WATER_FRIENDLY", "STURDY", "WAIST" ], + "armor": [ { "encumbrance": [ 4, 12 ], "coverage": 20, "covers": [ "torso" ] } ] }, { "id": "xl_survivor_vest", @@ -386,11 +366,7 @@ "symbol": "[", "looks_like": "quiver_large", "color": "light_gray", - "covers": [ "leg_l", "leg_r" ], "sided": true, - "coverage": 10, - "encumbrance": 2, - "max_encumbrance": 7, "material_thickness": 1, "pocket_data": [ { @@ -404,6 +380,7 @@ } ], "use_action": { "type": "holster" }, - "flags": [ "WAIST", "OVERSIZE" ] + "flags": [ "WAIST", "OVERSIZE" ], + "armor": [ { "encumbrance": [ 2, 7 ], "coverage": 10, "covers": [ "leg_l", "leg_r" ] } ] } ] diff --git a/data/json/items/armor/hoods.json b/data/json/items/armor/hoods.json index c2195ca8f1926..58547ad001199 100644 --- a/data/json/items/armor/hoods.json +++ b/data/json/items/armor/hoods.json @@ -37,11 +37,9 @@ "symbol": "[", "looks_like": "balclava", "color": "light_red", - "covers": [ "head" ], - "coverage": 95, - "encumbrance": 10, "material_thickness": 4, - "flags": [ "VARSIZE", "STURDY", "HELMET_COMPAT" ] + "flags": [ "VARSIZE", "STURDY", "HELMET_COMPAT" ], + "armor": [ { "encumbrance": 10, "coverage": 95, "covers": [ "head" ] } ] }, { "id": "xl_chainmail_hood", @@ -68,13 +66,11 @@ "symbol": "[", "looks_like": "hood_survivor", "color": "light_gray", - "covers": [ "head" ], - "coverage": 100, - "encumbrance": 30, "warmth": 15, "material_thickness": 5, "environmental_protection": 10, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY", "OUTER", "HELMET_COMPAT" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY", "OUTER", "HELMET_COMPAT" ], + "armor": [ { "encumbrance": 30, "coverage": 100, "covers": [ "head" ] } ] }, { "id": "xl_hood_fsurvivor", @@ -101,13 +97,11 @@ "symbol": "[", "looks_like": "hood_survivor", "color": "green", - "covers": [ "head" ], - "coverage": 100, - "encumbrance": 15, "warmth": 10, "material_thickness": 4, "environmental_protection": 3, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY", "OUTER", "HELMET_COMPAT" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY", "OUTER", "HELMET_COMPAT" ], + "armor": [ { "encumbrance": 15, "coverage": 100, "covers": [ "head" ] } ] }, { "id": "xl_hood_lsurvivor", @@ -155,12 +149,11 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "yellow", - "covers": [ "head" ], - "coverage": 100, "warmth": 10, "material_thickness": 0.3, "environmental_protection": 1, - "flags": [ "WATERPROOF", "OUTER", "HELMET_COMPAT" ] + "flags": [ "WATERPROOF", "OUTER", "HELMET_COMPAT" ], + "armor": [ { "coverage": 100, "covers": [ "head" ] } ] }, { "id": "hood_survivor", @@ -178,14 +171,12 @@ "symbol": "[", "looks_like": "hood_rain", "color": "brown", - "covers": [ "head" ], - "coverage": 100, - "encumbrance": 25, "warmth": 15, "material_thickness": 4, "environmental_protection": 3, "techniques": [ "WBLOCK_1" ], - "flags": [ "VARSIZE", "WATERPROOF", "STURDY", "OUTER", "HELMET_COMPAT" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY", "OUTER", "HELMET_COMPAT" ], + "armor": [ { "encumbrance": 25, "coverage": 100, "covers": [ "head" ] } ] }, { "id": "hood_wsurvivor", @@ -203,13 +194,11 @@ "symbol": "[", "looks_like": "hood_survivor", "color": "light_gray", - "covers": [ "head" ], - "coverage": 100, - "encumbrance": 37, "warmth": 75, "material_thickness": 5, "environmental_protection": 5, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY", "OUTER", "HELMET_COMPAT" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY", "OUTER", "HELMET_COMPAT" ], + "armor": [ { "encumbrance": 37, "coverage": 100, "covers": [ "head" ] } ] }, { "id": "xl_hood_wsurvivor", @@ -236,14 +225,12 @@ "symbol": "[", "looks_like": "hood_survivor", "color": "brown", - "covers": [ "head" ], - "coverage": 100, - "encumbrance": 40, "warmth": 15, "material_thickness": 3, "environmental_protection": 3, "techniques": [ "WBLOCK_1" ], - "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY", "OUTER", "HELMET_COMPAT" ] + "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY", "OUTER", "HELMET_COMPAT" ], + "armor": [ { "encumbrance": 40, "coverage": 100, "covers": [ "head" ] } ] }, { "id": "nomex_hood", @@ -259,13 +246,11 @@ "symbol": "[", "looks_like": "hood_rain", "color": "light_gray", - "covers": [ "head" ], - "coverage": 100, - "encumbrance": 6, "warmth": 5, "material_thickness": 3, "environmental_protection": 2, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT", "STURDY" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT", "STURDY" ], + "armor": [ { "encumbrance": 6, "coverage": 100, "covers": [ "head" ] } ] }, { "id": "hood_gut", @@ -280,11 +265,10 @@ "symbol": "[", "looks_like": "hood_rain", "color": "light_gray", - "covers": [ "head" ], - "coverage": 95, "warmth": 10, "material_thickness": 0.1, "environmental_protection": 1, - "flags": [ "WATERPROOF", "RAINPROOF", "OUTER", "HELMET_COMPAT" ] + "flags": [ "WATERPROOF", "RAINPROOF", "OUTER", "HELMET_COMPAT" ], + "armor": [ { "coverage": 95, "covers": [ "head" ] } ] } ] diff --git a/data/json/items/armor/jewelry.json b/data/json/items/armor/jewelry.json index 3f02bcb03d685..bbf33b3dcb804 100644 --- a/data/json/items/armor/jewelry.json +++ b/data/json/items/armor/jewelry.json @@ -86,9 +86,8 @@ "symbol": "[", "looks_like": "gold_dental_grill", "color": "yellow", - "covers": [ "mouth" ], - "encumbrance": 10, - "flags": [ "SKINTIGHT" ] + "flags": [ "SKINTIGHT" ], + "armor": [ { "encumbrance": 10, "covers": [ "mouth" ] } ] }, { "id": "garnet_dental_grill", @@ -105,9 +104,8 @@ "symbol": "[", "looks_like": "gold_dental_grill", "color": "red", - "covers": [ "mouth" ], - "encumbrance": 10, - "flags": [ "SKINTIGHT" ] + "flags": [ "SKINTIGHT" ], + "armor": [ { "encumbrance": 10, "covers": [ "mouth" ] } ] }, { "id": "amethyst_dental_grill", @@ -230,11 +228,10 @@ "symbol": "[", "looks_like": "gold_watch", "color": "light_gray", - "covers": [ "hand_l", "hand_r" ], "sided": true, - "coverage": 5, "use_action": [ "WEATHER_TOOL" ], - "flags": [ "WATCH", "ALARMCLOCK", "WATER_FRIENDLY", "THERMOMETER", "BELTED", "ALLOWS_NATURAL_ATTACKS", "OVERSIZE" ] + "flags": [ "WATCH", "ALARMCLOCK", "WATER_FRIENDLY", "THERMOMETER", "BELTED", "ALLOWS_NATURAL_ATTACKS", "OVERSIZE" ], + "armor": [ { "coverage": 5, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "collarpin", @@ -799,8 +796,8 @@ "material": [ "gold" ], "symbol": "[", "color": "yellow", - "covers": [ "mouth" ], - "flags": [ "SKINTIGHT" ] + "flags": [ "SKINTIGHT" ], + "armor": [ { "covers": [ "mouth" ] } ] }, { "id": "gold_ear", @@ -899,10 +896,9 @@ "material": [ "steel", "gold" ], "symbol": "[", "color": "yellow", - "covers": [ "hand_l", "hand_r" ], "sided": true, - "coverage": 5, - "flags": [ "WATCH", "ALARMCLOCK", "FANCY", "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "OVERSIZE" ] + "flags": [ "WATCH", "ALARMCLOCK", "FANCY", "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "OVERSIZE" ], + "armor": [ { "coverage": 5, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "tieclip", @@ -930,10 +926,9 @@ "material": [ "steel", "silver" ], "symbol": "[", "color": "light_gray", - "covers": [ "hand_l", "hand_r" ], "sided": true, - "coverage": 10, - "flags": [ "WATCH", "ALARMCLOCK", "FANCY", "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY", "OVERSIZE" ] + "flags": [ "WATCH", "ALARMCLOCK", "FANCY", "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY", "OVERSIZE" ], + "armor": [ { "coverage": 10, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "silver_bracelet", @@ -977,10 +972,9 @@ "material": [ "gold", "silver" ], "symbol": "[", "color": "yellow", - "covers": [ "hand_l", "hand_r" ], "sided": true, - "coverage": 10, - "flags": [ "WATCH", "ALARMCLOCK", "SUPER_FANCY", "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY", "OVERSIZE" ] + "flags": [ "WATCH", "ALARMCLOCK", "SUPER_FANCY", "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY", "OVERSIZE" ], + "armor": [ { "coverage": 10, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "small_relic", @@ -1066,10 +1060,9 @@ "material": [ "platinum" ], "symbol": "[", "color": "white", - "covers": [ "hand_l", "hand_r" ], "sided": true, - "coverage": 5, - "flags": [ "WATCH", "ALARMCLOCK", "SUPER_FANCY", "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "OVERSIZE" ] + "flags": [ "WATCH", "ALARMCLOCK", "SUPER_FANCY", "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "OVERSIZE" ], + "armor": [ { "coverage": 5, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "platinum_bracelet", @@ -1099,8 +1092,8 @@ "material": [ "platinum", "silver" ], "symbol": "[", "color": "white", - "covers": [ "mouth" ], - "flags": [ "SKINTIGHT" ] + "flags": [ "SKINTIGHT" ], + "armor": [ { "covers": [ "mouth" ] } ] }, { "id": "platinum_ear", @@ -1328,10 +1321,9 @@ "ascii_picture": "wristwatch", "symbol": "[", "color": "dark_gray", - "covers": [ "hand_l", "hand_r" ], "sided": true, - "coverage": 5, - "flags": [ "WATCH", "ALARMCLOCK", "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY", "OVERSIZE" ] + "flags": [ "WATCH", "ALARMCLOCK", "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY", "OVERSIZE" ], + "armor": [ { "coverage": 5, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "rad_badge", @@ -1361,9 +1353,9 @@ "symbol": "[", "color": "yellow", "//": "should cover TORSO but give no encumbrance penalties", - "coverage": 2, "material_thickness": 2, - "flags": [ "ALLOWS_NATURAL_ATTACKS", "OUTER", "OVERSIZE", "WATER_FRIENDLY" ] + "flags": [ "ALLOWS_NATURAL_ATTACKS", "OUTER", "OVERSIZE", "WATER_FRIENDLY" ], + "armor": [ { "coverage": 2 } ] }, { "id": "badge_cybercop", @@ -2970,10 +2962,9 @@ "looks_like": "crown_golden", "symbol": "[", "color": "red", - "coverage": 5, - "encumbrance": 1, "material_thickness": 1, - "flags": [ "SUPER_FANCY" ] + "flags": [ "SUPER_FANCY" ], + "armor": [ { "encumbrance": 1, "coverage": 5 } ] }, { "id": "diamond_platinum_tiara", @@ -3092,10 +3083,9 @@ "looks_like": "crown_golden", "symbol": "[", "color": "red", - "coverage": 5, - "encumbrance": 1, "material_thickness": 1, - "flags": [ "SUPER_FANCY" ] + "flags": [ "SUPER_FANCY" ], + "armor": [ { "encumbrance": 1, "coverage": 5 } ] }, { "id": "diamond_gold_tiara", @@ -3214,10 +3204,9 @@ "looks_like": "crown_golden", "symbol": "[", "color": "red", - "coverage": 5, - "encumbrance": 1, "material_thickness": 1, - "flags": [ "SUPER_FANCY" ] + "flags": [ "SUPER_FANCY" ], + "armor": [ { "encumbrance": 1, "coverage": 5 } ] }, { "id": "diamond_silver_tiara", diff --git a/data/json/items/armor/legs_armor.json b/data/json/items/armor/legs_armor.json index 5a16806c1af82..76a5fc9a7629d 100644 --- a/data/json/items/armor/legs_armor.json +++ b/data/json/items/armor/legs_armor.json @@ -15,12 +15,10 @@ "symbol": "[", "looks_like": "leg_splint", "color": "brown", - "covers": [ "leg_l", "leg_r" ], - "coverage": 75, - "encumbrance": 25, "warmth": 5, "material_thickness": 3, - "flags": [ "BELTED", "WATER_FRIENDLY", "ALLOWS_TAIL" ] + "flags": [ "BELTED", "WATER_FRIENDLY", "ALLOWS_TAIL" ], + "armor": [ { "encumbrance": 25, "coverage": 75, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "legguard_chitin", @@ -37,13 +35,11 @@ "symbol": "[", "looks_like": "legguard_hard", "color": "green", - "covers": [ "leg_l", "leg_r" ], - "coverage": 80, - "encumbrance": 4, "warmth": 10, "material_thickness": 4, "environmental_protection": 2, - "flags": [ "STURDY", "BELTED", "BLOCK_WHILE_WORN", "WATER_FRIENDLY", "ALLOWS_TAIL" ] + "flags": [ "STURDY", "BELTED", "BLOCK_WHILE_WORN", "WATER_FRIENDLY", "ALLOWS_TAIL" ], + "armor": [ { "encumbrance": 4, "coverage": 80, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "legguard_acidchitin", @@ -74,10 +70,6 @@ "symbol": "[", "looks_like": "pants_cargo", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 100, - "encumbrance": 24, - "max_encumbrance": 30, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -112,7 +104,8 @@ "material_thickness": 2, "valid_mods": [ "steel_padded" ], "environmental_protection": 6, - "flags": [ "VARSIZE", "POCKETS", "STURDY", "WATERPROOF", "OUTER" ] + "flags": [ "VARSIZE", "POCKETS", "STURDY", "WATERPROOF", "OUTER" ], + "armor": [ { "encumbrance": [ 24, 30 ], "coverage": 100, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "chainmail_legs", @@ -129,11 +122,9 @@ "symbol": "[", "looks_like": "legguard_hard", "color": "light_red", - "covers": [ "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 20, "material_thickness": 4, - "flags": [ "VARSIZE", "STURDY" ] + "flags": [ "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 95, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "xl_chainmail_legs", @@ -158,12 +149,10 @@ "symbol": "[", "looks_like": "pants_leather", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 65, - "encumbrance": 3, "warmth": 10, "material_thickness": 3, - "flags": [ "OUTER" ] + "flags": [ "OUTER" ], + "armor": [ { "encumbrance": 3, "coverage": 65, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "chaps_cut_resistant", @@ -190,10 +179,6 @@ "symbol": "[", "looks_like": "pants", "color": "white", - "covers": [ "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 13, - "max_encumbrance": 15, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -212,7 +197,8 @@ ], "warmth": 20, "material_thickness": 2, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": [ 13, 15 ], "coverage": 95, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "knee_pads", @@ -229,10 +215,9 @@ "symbol": "[", "looks_like": "legguard_hard", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 30, "material_thickness": 5, - "flags": [ "WATER_FRIENDLY", "BELTED", "ALLOWS_TAIL" ] + "flags": [ "WATER_FRIENDLY", "BELTED", "ALLOWS_TAIL" ], + "armor": [ { "coverage": 30, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "legguard_bronze", @@ -249,12 +234,10 @@ "symbol": "[", "looks_like": "legguard_lightplate", "color": "yellow", - "covers": [ "leg_l", "leg_r" ], - "coverage": 70, - "encumbrance": 10, "warmth": 15, "material_thickness": 4, - "flags": [ "BELTED", "STURDY", "ALLOWS_TAIL" ] + "flags": [ "BELTED", "STURDY", "ALLOWS_TAIL" ], + "armor": [ { "encumbrance": 10, "coverage": 70, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "xl_legguard_bronze", @@ -280,13 +263,11 @@ "symbol": "[", "looks_like": "leg_warmers", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 75, - "encumbrance": 10, "warmth": 20, "material_thickness": 4, "environmental_protection": 1, - "flags": [ "BELTED", "WATER_FRIENDLY", "ALLOWS_TAIL" ] + "flags": [ "BELTED", "WATER_FRIENDLY", "ALLOWS_TAIL" ], + "armor": [ { "encumbrance": 10, "coverage": 75, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "legguard_lightplate", @@ -303,12 +284,10 @@ "symbol": "[", "looks_like": "legguard_hard", "color": "light_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 20, "warmth": 20, "material_thickness": 4, - "flags": [ "VARSIZE", "BELTED", "STURDY", "ALLOWS_TAIL" ] + "flags": [ "VARSIZE", "BELTED", "STURDY", "ALLOWS_TAIL" ], + "armor": [ { "encumbrance": 20, "coverage": 95, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "xl_legguard_lightplate", @@ -334,12 +313,10 @@ "symbol": "[", "looks_like": "legguard_lightplate", "color": "light_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 70, - "encumbrance": 6, "warmth": 10, "material_thickness": 4, - "flags": [ "BELTED", "WATER_FRIENDLY", "ALLOWS_TAIL" ] + "flags": [ "BELTED", "WATER_FRIENDLY", "ALLOWS_TAIL" ], + "armor": [ { "encumbrance": 6, "coverage": 70, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "xl_legguard_metal", @@ -365,12 +342,10 @@ "symbol": "[", "looks_like": "legguard_hard", "color": "blue", - "covers": [ "leg_l", "leg_r" ], - "coverage": 80, - "encumbrance": 10, "warmth": 5, "material_thickness": 3, - "flags": [ "BELTED", "ALLOWS_TAIL" ] + "flags": [ "BELTED", "ALLOWS_TAIL" ], + "armor": [ { "encumbrance": 10, "coverage": 80, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "legguard_scrap", @@ -389,12 +364,10 @@ "symbol": "[", "looks_like": "legguard_metal", "color": "light_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 80, - "encumbrance": 18, "warmth": 10, "material_thickness": 2, - "flags": [ "BELTED", "ALLOWS_TAIL" ] + "flags": [ "BELTED", "ALLOWS_TAIL" ], + "armor": [ { "encumbrance": 18, "coverage": 80, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "xl_legguard_scrap", @@ -419,10 +392,6 @@ "symbol": "[", "looks_like": "pants_survivor", "color": "green", - "covers": [ "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 8, - "max_encumbrance": 16, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -470,7 +439,8 @@ "warmth": 12, "material_thickness": 3, "environmental_protection": 1, - "flags": [ "VARSIZE", "WATERPROOF", "POCKETS", "RAINPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "POCKETS", "RAINPROOF", "STURDY" ], + "armor": [ { "encumbrance": [ 8, 16 ], "coverage": 95, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "xl_lsurvivor_pants", @@ -495,13 +465,11 @@ "symbol": "[", "looks_like": "pants_leather", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 100, - "encumbrance": 20, "warmth": 35, "material_thickness": 1.5, "environmental_protection": 2, - "flags": [ "VARSIZE", "WATERPROOF" ] + "flags": [ "VARSIZE", "WATERPROOF" ], + "armor": [ { "encumbrance": 20, "coverage": 100, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "pants_survivor", @@ -517,10 +485,6 @@ "symbol": "[", "looks_like": "pants_army", "color": "green", - "covers": [ "leg_l", "leg_r" ], - "coverage": 100, - "encumbrance": 10, - "max_encumbrance": 20, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -583,7 +547,8 @@ "material_thickness": 4, "valid_mods": [ "steel_padded" ], "environmental_protection": 3, - "flags": [ "VARSIZE", "POCKETS", "STURDY", "WATERPROOF" ] + "flags": [ "VARSIZE", "POCKETS", "STURDY", "WATERPROOF" ], + "armor": [ { "encumbrance": [ 10, 20 ], "coverage": 100, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "xl_pants_survivor", @@ -603,16 +568,14 @@ "weight": "6400 g", "volume": "12 L", "price": 200000, - "covers": [ "leg_l", "leg_r" ], - "coverage": 100, - "encumbrance": 80, "warmth": 65, "material": [ "kevlar_layered", "nomex" ], "symbol": "[", "color": "light_gray", "environmental_protection": 2, "material_thickness": 15, - "flags": [ "STURDY", "OUTER", "RAINPROOF", "ONLY_ONE" ] + "flags": [ "STURDY", "OUTER", "RAINPROOF", "ONLY_ONE" ], + "armor": [ { "encumbrance": 80, "coverage": 100, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "trousers_eod_light", @@ -623,15 +586,13 @@ "weight": "3000 g", "volume": "12 L", "price": 200000, - "covers": [ "leg_l", "leg_r" ], - "coverage": 100, - "encumbrance": 40, "warmth": 40, "material": [ "kevlar_layered", "nomex" ], "symbol": "[", "color": "light_gray", "environmental_protection": 2, "material_thickness": 7, - "flags": [ "STURDY", "OUTER", "RAINPROOF", "ONLY_ONE" ] + "flags": [ "STURDY", "OUTER", "RAINPROOF", "ONLY_ONE" ], + "armor": [ { "encumbrance": 40, "coverage": 100, "covers": [ "leg_l", "leg_r" ] } ] } ] diff --git a/data/json/items/armor/legs_clothes.json b/data/json/items/armor/legs_clothes.json index c4ff4cb400773..a992d7f202ddd 100644 --- a/data/json/items/armor/legs_clothes.json +++ b/data/json/items/armor/legs_clothes.json @@ -13,10 +13,6 @@ "symbol": "[", "looks_like": "kilt", "color": "brown", - "covers": [ "leg_l", "leg_r" ], - "coverage": 90, - "encumbrance": 7, - "max_encumbrance": 11, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -28,7 +24,8 @@ ], "warmth": 8, "material_thickness": 0.3, - "flags": [ "VARSIZE", "POCKETS" ] + "flags": [ "VARSIZE", "POCKETS" ], + "armor": [ { "encumbrance": [ 7, 11 ], "coverage": 90, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "b_shorts", @@ -45,8 +42,6 @@ "symbol": "[", "looks_like": "shorts", "color": "cyan", - "covers": [ "leg_l", "leg_r" ], - "coverage": 50, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -65,7 +60,8 @@ ], "warmth": 5, "material_thickness": 0.1, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "coverage": 50, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "breeches", @@ -81,12 +77,10 @@ "symbol": "[", "looks_like": "pants", "color": "brown", - "covers": [ "leg_l", "leg_r" ], - "coverage": 80, - "encumbrance": 8, "warmth": 10, "material_thickness": 0.4, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 8, "coverage": 80, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "fishing_waders", @@ -134,10 +128,9 @@ "symbol": "[", "looks_like": "boxer_briefs", "color": "light_red", - "covers": [ "leg_l", "leg_r" ], - "coverage": 15, "material_thickness": 0.1, - "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ] + "flags": [ "VARSIZE", "WATER_FRIENDLY", "SKINTIGHT" ], + "armor": [ { "coverage": 15, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "hot_pants_fur", @@ -152,11 +145,10 @@ "symbol": "[", "looks_like": "hot_pants_leather", "color": "brown", - "covers": [ "leg_l", "leg_r" ], - "coverage": 15, "warmth": 10, "material_thickness": 0.2, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 15, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "hot_pants_leather", @@ -171,11 +163,10 @@ "symbol": "[", "looks_like": "hot_pants", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 15, "warmth": 5, "material_thickness": 0.1, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "coverage": 15, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "jeans", @@ -191,10 +182,6 @@ "symbol": "[", "looks_like": "pants", "color": "blue", - "covers": [ "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 12, - "max_encumbrance": 16, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -237,7 +224,8 @@ "id": "jeans5", "text": "An old pair of blue jeans. You are not sure if they are faded through age or stone washed." } - ] + ], + "armor": [ { "encumbrance": [ 12, 16 ], "coverage": 95, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "jeans_red", @@ -254,10 +242,6 @@ "symbol": "[", "looks_like": "jeans", "color": "red", - "covers": [ "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 12, - "max_encumbrance": 16, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -290,7 +274,8 @@ ], "warmth": 10, "material_thickness": 0.25, - "flags": [ "VARSIZE", "POCKETS" ] + "flags": [ "VARSIZE", "POCKETS" ], + "armor": [ { "encumbrance": [ 12, 16 ], "coverage": 95, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "kilt", @@ -305,8 +290,6 @@ "symbol": "[", "looks_like": "skirt", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 50, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -318,7 +301,8 @@ ], "warmth": 20, "material_thickness": 0.3, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "coverage": 50, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "kilt_leather", @@ -333,8 +317,6 @@ "symbol": "[", "looks_like": "kilt", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 50, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -346,7 +328,8 @@ ], "warmth": 10, "material_thickness": 1.5, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "coverage": 50, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "leggings", @@ -361,11 +344,10 @@ "symbol": "[", "looks_like": "leg_warmers", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 100, "warmth": 20, "material_thickness": 0.1, - "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ] + "flags": [ "VARSIZE", "SKINTIGHT", "WATER_FRIENDLY" ], + "armor": [ { "coverage": 100, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "loincloth", @@ -380,10 +362,9 @@ "symbol": "[", "looks_like": "briefs", "color": "brown", - "covers": [ "leg_l", "leg_r" ], - "coverage": 5, "material_thickness": 0.5, - "flags": [ "VARSIZE", "SKINTIGHT", "OVERSIZE" ] + "flags": [ "VARSIZE", "SKINTIGHT", "OVERSIZE" ], + "armor": [ { "coverage": 5, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "loincloth_fur", @@ -398,11 +379,10 @@ "symbol": "[", "looks_like": "loincloth_leather", "color": "brown", - "covers": [ "leg_l", "leg_r" ], - "coverage": 5, "warmth": 5, "material_thickness": 1, - "flags": [ "VARSIZE", "SKINTIGHT", "OVERSIZE" ] + "flags": [ "VARSIZE", "SKINTIGHT", "OVERSIZE" ], + "armor": [ { "coverage": 5, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "loincloth_leather", @@ -417,10 +397,9 @@ "symbol": "[", "looks_like": "loincloth", "color": "brown", - "covers": [ "leg_l", "leg_r" ], - "coverage": 5, "material_thickness": 1, - "flags": [ "VARSIZE", "SKINTIGHT", "OVERSIZE" ] + "flags": [ "VARSIZE", "SKINTIGHT", "OVERSIZE" ], + "armor": [ { "coverage": 5, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "loincloth_wool", @@ -435,11 +414,10 @@ "symbol": "[", "looks_like": "loincloth", "color": "blue", - "covers": [ "leg_l", "leg_r" ], - "coverage": 5, "warmth": 5, "material_thickness": 1, - "flags": [ "VARSIZE", "SKINTIGHT", "OVERSIZE" ] + "flags": [ "VARSIZE", "SKINTIGHT", "OVERSIZE" ], + "armor": [ { "coverage": 5, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "nanoskirt", @@ -455,10 +433,9 @@ "symbol": "[", "looks_like": "skirt", "color": "pink", - "covers": [ "leg_l", "leg_r" ], - "coverage": 7, "material_thickness": 0.5, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "coverage": 7, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "pants", @@ -475,10 +452,6 @@ "symbol": "[", "looks_like": "jeans", "color": "brown", - "covers": [ "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 7, - "max_encumbrance": 11, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -511,7 +484,8 @@ ], "warmth": 15, "material_thickness": 0.2, - "flags": [ "VARSIZE", "POCKETS" ] + "flags": [ "VARSIZE", "POCKETS" ], + "armor": [ { "encumbrance": [ 7, 11 ], "coverage": 95, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "pants_army", @@ -527,10 +501,6 @@ "symbol": "[", "looks_like": "pants_cargo", "color": "green", - "covers": [ "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 9, - "max_encumbrance": 18, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -599,7 +569,8 @@ ], "warmth": 20, "material_thickness": 0.25, - "flags": [ "VARSIZE", "POCKETS" ] + "flags": [ "VARSIZE", "POCKETS" ], + "armor": [ { "encumbrance": [ 9, 18 ], "coverage": 95, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "pants_cargo", @@ -614,10 +585,6 @@ "symbol": "[", "looks_like": "pants", "color": "light_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 8, - "max_encumbrance": 16, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -664,7 +631,8 @@ ], "warmth": 15, "material_thickness": 0.25, - "flags": [ "VARSIZE", "POCKETS" ] + "flags": [ "VARSIZE", "POCKETS" ], + "armor": [ { "encumbrance": [ 8, 16 ], "coverage": 95, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "pants_checkered", @@ -680,10 +648,6 @@ "symbol": "[", "looks_like": "pants", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 2, - "max_encumbrance": 5, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -716,7 +680,8 @@ ], "warmth": 15, "material_thickness": 0.2, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": [ 2, 5 ], "coverage": 95, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "pants_fur", @@ -732,10 +697,6 @@ "symbol": "[", "looks_like": "pants", "color": "brown", - "covers": [ "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 16, - "max_encumbrance": 20, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -770,7 +731,8 @@ "material_thickness": 1, "valid_mods": [ "steel_padded" ], "environmental_protection": 3, - "flags": [ "VARSIZE", "POCKETS" ] + "flags": [ "VARSIZE", "POCKETS" ], + "armor": [ { "encumbrance": [ 16, 20 ], "coverage": 95, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "pants_faux_fur", @@ -779,7 +741,6 @@ "name": { "str_sp": "faux fur pants" }, "description": "A pair of long cotton pants lined with warm imitation fur.", "material": [ "faux_fur", "cotton" ], - "covers": [ "leg_l", "leg_r" ], "warmth": 70 }, { @@ -796,10 +757,6 @@ "symbol": "[", "looks_like": "pants", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 15, - "max_encumbrance": 17, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -819,7 +776,8 @@ "warmth": 25, "material_thickness": 0.75, "valid_mods": [ "steel_padded" ], - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": [ 15, 17 ], "coverage": 95, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "pants_ski", @@ -835,10 +793,6 @@ "symbol": "[", "looks_like": "pants", "color": "blue", - "covers": [ "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 6, - "max_encumbrance": 10, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -872,7 +826,8 @@ "warmth": 70, "material_thickness": 1, "environmental_protection": 3, - "flags": [ "VARSIZE", "POCKETS", "OUTER" ] + "flags": [ "VARSIZE", "POCKETS", "OUTER" ], + "armor": [ { "encumbrance": [ 6, 10 ], "coverage": 95, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "postman_shorts", @@ -889,8 +844,6 @@ "symbol": "[", "looks_like": "shorts_cargo", "color": "blue", - "covers": [ "leg_l", "leg_r" ], - "coverage": 40, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -923,7 +876,8 @@ ], "warmth": 5, "material_thickness": 0.2, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "coverage": 40, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "shorts", @@ -939,10 +893,6 @@ "symbol": "[", "looks_like": "boxer_shorts", "color": "brown", - "covers": [ "leg_l", "leg_r" ], - "coverage": 40, - "encumbrance": 2, - "max_encumbrance": 5, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -975,7 +925,8 @@ ], "warmth": 5, "material_thickness": 0.2, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": [ 2, 5 ], "coverage": 40, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "shorts_cargo", @@ -991,10 +942,6 @@ "symbol": "[", "looks_like": "shorts", "color": "light_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 40, - "encumbrance": 2, - "max_encumbrance": 5, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1041,7 +988,8 @@ ], "warmth": 5, "material_thickness": 0.2, - "flags": [ "VARSIZE", "POCKETS" ] + "flags": [ "VARSIZE", "POCKETS" ], + "armor": [ { "encumbrance": [ 2, 5 ], "coverage": 40, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "shorts_denim", @@ -1057,10 +1005,6 @@ "symbol": "[", "looks_like": "shorts", "color": "light_blue", - "covers": [ "leg_l", "leg_r" ], - "coverage": 40, - "encumbrance": 1, - "max_encumbrance": 2, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1084,7 +1028,8 @@ ], "warmth": 5, "material_thickness": 0.25, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": [ 1, 2 ], "coverage": 40, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "skirt", @@ -1100,12 +1045,11 @@ "symbol": "[", "looks_like": "kilt", "color": "dark_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 50, "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "250 ml", "max_contains_weight": "1 kg", "moves": 80 } ], "warmth": 5, "material_thickness": 0.1, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "coverage": 50, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "skirt_grass", @@ -1120,10 +1064,9 @@ "symbol": "[", "looks_like": "kilt", "color": "yellow", - "covers": [ "leg_l", "leg_r" ], - "coverage": 35, "material_thickness": 1, - "flags": [ "VARSIZE", "OVERSIZE", "WATER_FRIENDLY" ] + "flags": [ "VARSIZE", "OVERSIZE", "WATER_FRIENDLY" ], + "armor": [ { "coverage": 35, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "skirt_leather", @@ -1139,12 +1082,10 @@ "symbol": "[", "looks_like": "skirt", "color": "brown", - "covers": [ "leg_l", "leg_r" ], - "coverage": 35, - "encumbrance": 10, "warmth": 10, "material_thickness": 0.6, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 10, "coverage": 35, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "striped_pants", @@ -1161,10 +1102,6 @@ "symbol": "[", "looks_like": "pants_checkered", "color": "white", - "covers": [ "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 2, - "max_encumbrance": 5, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1197,7 +1134,8 @@ ], "warmth": 15, "material_thickness": 0.2, - "flags": [ "VARSIZE", "POCKETS" ] + "flags": [ "VARSIZE", "POCKETS" ], + "armor": [ { "encumbrance": [ 2, 5 ], "coverage": 95, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "technician_pants_gray", @@ -1214,10 +1152,6 @@ "symbol": "[", "looks_like": "pants", "color": "light_gray", - "covers": [ "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 2, - "max_encumbrance": 5, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1255,7 +1189,8 @@ { "id": "technician_pants_gray", "text": "A pair of gray work pants." }, { "id": "technician_pants_lightblue", "text": "A pair of light-blue work pants." } ], - "flags": [ "VARSIZE", "POCKETS" ] + "flags": [ "VARSIZE", "POCKETS" ], + "armor": [ { "encumbrance": [ 2, 5 ], "coverage": 95, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "winter_pants_army", @@ -1271,10 +1206,6 @@ "symbol": "[", "looks_like": "pants_army", "color": "white", - "covers": [ "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 11, - "max_encumbrance": 22, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -1322,7 +1253,8 @@ "warmth": 50, "material_thickness": 0.5, "valid_mods": [ "steel_padded" ], - "flags": [ "VARSIZE", "POCKETS" ] + "flags": [ "VARSIZE", "POCKETS" ], + "armor": [ { "encumbrance": [ 11, 22 ], "coverage": 95, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "zubon_gi", @@ -1337,10 +1269,9 @@ "symbol": "[", "looks_like": "pants", "color": "white", - "covers": [ "leg_l", "leg_r" ], - "coverage": 80, "warmth": 5, "material_thickness": 0.5, - "flags": [ "VARSIZE", "STURDY" ] + "flags": [ "VARSIZE", "STURDY" ], + "armor": [ { "coverage": 80, "covers": [ "leg_l", "leg_r" ] } ] } ] diff --git a/data/json/items/armor/masks.json b/data/json/items/armor/masks.json index 831faa1d1959a..96881377a1521 100644 --- a/data/json/items/armor/masks.json +++ b/data/json/items/armor/masks.json @@ -12,12 +12,10 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "dark_gray", - "covers": [ "head", "mouth" ], - "coverage": 95, - "encumbrance": 5, "warmth": 30, "material_thickness": 0.5, - "flags": [ "VARSIZE", "SKINTIGHT" ] + "flags": [ "VARSIZE", "SKINTIGHT" ], + "armor": [ { "encumbrance": 5, "coverage": 95, "covers": [ "head", "mouth" ] } ] }, { "id": "balaclava_cut_resistant", @@ -48,12 +46,10 @@ "symbol": "[", "looks_like": "scarf", "color": "blue", - "covers": [ "mouth" ], - "coverage": 95, - "encumbrance": 1, "warmth": 5, "material_thickness": 0.1, - "environmental_protection": 1 + "environmental_protection": 1, + "armor": [ { "encumbrance": 1, "coverage": 95, "covers": [ "mouth" ] } ] }, { "id": "bondage_mask", @@ -70,9 +66,6 @@ "symbol": "[", "looks_like": "balclava", "color": "dark_gray", - "covers": [ "head", "eyes", "mouth" ], - "coverage": 100, - "encumbrance": 30, "warmth": 30, "material_thickness": 0.5, "environmental_protection": 1, @@ -82,7 +75,8 @@ "type": "transform", "target": "bondage_mask_zipped", "msg": "You zip the eyes and mouth of the bondage mask closed." - } + }, + "armor": [ { "encumbrance": 30, "coverage": 100, "covers": [ "head", "eyes", "mouth" ] } ] }, { "id": "bondage_mask_zipped", @@ -136,13 +130,11 @@ "symbol": "[", "looks_like": "glasses_bal", "color": "dark_gray", - "covers": [ "eyes", "mouth" ], - "coverage": 95, - "encumbrance": 20, "warmth": 10, "material_thickness": 4, "environmental_protection": 1, - "flags": [ "WATER_FRIENDLY", "STURDY" ] + "flags": [ "WATER_FRIENDLY", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 95, "covers": [ "eyes", "mouth" ] } ] }, { "id": "mask_dust", @@ -159,12 +151,10 @@ "symbol": "[", "looks_like": "scarf", "color": "white", - "covers": [ "mouth" ], - "coverage": 100, - "encumbrance": 8, "warmth": 5, "material_thickness": 0.1, - "environmental_protection": 2 + "environmental_protection": 2, + "armor": [ { "encumbrance": 8, "coverage": 100, "covers": [ "mouth" ] } ] }, { "id": "mask_guy_fawkes", @@ -181,13 +171,11 @@ "symbol": "[", "looks_like": "mask_hockey", "color": "white", - "covers": [ "eyes", "mouth" ], - "coverage": 95, - "encumbrance": 10, "warmth": 5, "material_thickness": 0.2, "environmental_protection": 1, - "flags": [ "WATER_FRIENDLY" ] + "flags": [ "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 10, "coverage": 95, "covers": [ "eyes", "mouth" ] } ] }, { "id": "mask_hockey", @@ -206,13 +194,11 @@ "symbol": "[", "looks_like": "glasses_safety", "color": "white", - "covers": [ "eyes", "mouth" ], - "coverage": 95, - "encumbrance": 20, "warmth": 5, "material_thickness": 2, "environmental_protection": 1, - "flags": [ "WATER_FRIENDLY", "STURDY" ] + "flags": [ "WATER_FRIENDLY", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 95, "covers": [ "eyes", "mouth" ] } ] }, { "id": "mask_rioter", @@ -228,12 +214,10 @@ "symbol": "[", "looks_like": "scarf", "color": "white", - "covers": [ "head", "mouth" ], - "coverage": 90, - "encumbrance": 8, "warmth": 10, "material_thickness": 0.5, "environmental_protection": 1, - "flags": [ "HELMET_COMPAT" ] + "flags": [ "HELMET_COMPAT" ], + "armor": [ { "encumbrance": 8, "coverage": 90, "covers": [ "head", "mouth" ] } ] } ] diff --git a/data/json/items/armor/misc.json b/data/json/items/armor/misc.json index 021da596251b1..e96a0da493493 100644 --- a/data/json/items/armor/misc.json +++ b/data/json/items/armor/misc.json @@ -13,13 +13,11 @@ "material": [ "cotton" ], "symbol": "[", "color": "pink", - "covers": [ "head" ], - "coverage": 60, - "encumbrance": 5, "warmth": 20, "material_thickness": 0.2, "environmental_protection": 1, - "flags": [ "VARSIZE" ] + "flags": [ "VARSIZE" ], + "armor": [ { "encumbrance": 5, "coverage": 60, "covers": [ "head" ] } ] }, { "id": "clown_nose", @@ -47,11 +45,9 @@ "symbol": "[", "looks_like": "hat_cotton", "color": "yellow", - "covers": [ "head" ], - "coverage": 30, - "encumbrance": 20, "material_thickness": 2, - "flags": [ "SUPER_FANCY" ] + "flags": [ "SUPER_FANCY" ], + "armor": [ { "encumbrance": 20, "coverage": 30, "covers": [ "head" ] } ] }, { "id": "crown_golden_survivor", @@ -66,11 +62,9 @@ "symbol": "[", "looks_like": "crown_golden", "color": "yellow", - "covers": [ "head" ], - "coverage": 30, - "encumbrance": 20, "material_thickness": 2, - "flags": [ "FANCY" ] + "flags": [ "FANCY" ], + "armor": [ { "encumbrance": 20, "coverage": 30, "covers": [ "head" ] } ] }, { "id": "mouthpiece", @@ -87,10 +81,9 @@ "material": [ "plastic" ], "symbol": "[", "color": "yellow", - "covers": [ "mouth" ], - "coverage": 50, "material_thickness": 1, - "flags": [ "VARSIZE", "STURDY", "WATER_FRIENDLY", "SKINTIGHT", "POWERARMOR_COMPATIBLE" ] + "flags": [ "VARSIZE", "STURDY", "WATER_FRIENDLY", "SKINTIGHT", "POWERARMOR_COMPATIBLE" ], + "armor": [ { "coverage": 50, "covers": [ "mouth" ] } ] }, { "id": "tie_skinny", @@ -120,12 +113,10 @@ "symbol": "(", "looks_like": "duffelbag", "color": "light_red", - "covers": [ "torso" ], - "coverage": 10, - "encumbrance": 20, "material_thickness": 4, "flags": [ "OVERSIZE", "BELTED" ], - "use_action": { "menu_text": "Unroll", "type": "transform", "target": "sleeping_bag", "msg": "You unroll the sleeping bag." } + "use_action": { "menu_text": "Unroll", "type": "transform", "target": "sleeping_bag", "msg": "You unroll the sleeping bag." }, + "armor": [ { "encumbrance": 20, "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "sleeping_bag_fur", @@ -141,9 +132,6 @@ "symbol": "[", "looks_like": "sleeping_bag", "color": "brown", - "covers": [ "torso", "head", "mouth", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 80, "warmth": 100, "material_thickness": 5, "environmental_protection": 1, @@ -153,7 +141,14 @@ "type": "transform", "target": "sleeping_bag_fur_roll", "msg": "You roll up the fur sleeping bag, preparing it for transport." - } + }, + "armor": [ + { + "encumbrance": 80, + "coverage": 100, + "covers": [ "torso", "head", "mouth", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "sleeping_bag_fur_roll", @@ -169,9 +164,6 @@ "symbol": "(", "looks_like": "sleeping_bag_roll", "color": "brown", - "covers": [ "torso" ], - "coverage": 10, - "encumbrance": 20, "material_thickness": 5, "flags": [ "OVERSIZE", "BELTED" ], "use_action": { @@ -179,7 +171,8 @@ "type": "transform", "target": "sleeping_bag_fur", "msg": "You unroll up the fur sleeping bag." - } + }, + "armor": [ { "encumbrance": 20, "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "tie_bow", @@ -238,12 +231,10 @@ "symbol": "[", "looks_like": "scarf", "color": "white", - "covers": [ "eyes", "mouth" ], - "coverage": 100, - "encumbrance": 5, "material_thickness": 0.01, "environmental_protection": 1, - "flags": [ "SUPER_FANCY", "OUTER", "OVERSIZE" ] + "flags": [ "SUPER_FANCY", "OUTER", "OVERSIZE" ], + "armor": [ { "encumbrance": 5, "coverage": 100, "covers": [ "eyes", "mouth" ] } ] }, { "id": "tarp", @@ -259,12 +250,16 @@ "symbol": "[", "looks_like": "blanket", "color": "light_blue", - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 90, - "encumbrance": 30, "warmth": 10, "material_thickness": 0.1, "environmental_protection": 1, - "flags": [ "OVERSIZE", "OUTER", "WATERPROOF", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "OVERSIZE", "OUTER", "WATERPROOF", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ + { + "encumbrance": 30, + "coverage": 90, + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] } ] From 06371bc8626dba6a0cf676b9c5bc1e73dce1352c Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Tue, 6 Jul 2021 22:54:33 -0700 Subject: [PATCH 039/116] Convert armor to use armor_portion_data pt. 3 (#49681) I want to make changes to how armor data is specified, and I don't want to maintain two separate interfaces for it, so let's convert existing data to one interface. Items using copy-from were audited, and where they made changes, data was respecified as at the moment, copy-from modifying sub-elements of armor portion data is incorrect (there are lots of questions with no good answers there). --- data/json/items/classes/magazine.json | 2 +- data/json/items/containers.json | 20 +- data/json/items/fluff.json | 5 +- data/json/items/generic.json | 11 +- data/json/items/generic/bedding.json | 82 ++- data/json/items/generic/string.json | 4 +- data/json/items/gun/9mm.json | 6 +- data/json/items/magazine/shot.json | 2 +- data/json/items/melee/unarmed_weapons.json | 6 +- data/json/items/obsolete.json | 92 ++-- data/json/items/ranged/archery.json | 16 +- data/json/items/tool/misc.json | 6 +- data/json/items/tool/musical_instruments.json | 34 +- data/json/items/tool_armor.json | 491 +++++++----------- data/json/obsolete.json | 6 +- 15 files changed, 329 insertions(+), 454 deletions(-) diff --git a/data/json/items/classes/magazine.json b/data/json/items/classes/magazine.json index ffedaabc185e2..4a92539a052b6 100644 --- a/data/json/items/classes/magazine.json +++ b/data/json/items/classes/magazine.json @@ -10,7 +10,7 @@ "material": [ "steel" ], "symbol": "#", "color": "light_gray", - "armor_data": { "covers": [ "torso" ], "coverage": 5, "encumbrance": 10 }, + "armor_data": { "armor": [ { "encumbrance": 10, "coverage": 5, "covers": [ "torso" ] } ] }, "flags": [ "MAG_BELT", "MAG_DESTROY", "BELTED", "OVERSIZE", "WATER_FRIENDLY" ] } ] diff --git a/data/json/items/containers.json b/data/json/items/containers.json index 27217042b41a7..a089dd655298b 100644 --- a/data/json/items/containers.json +++ b/data/json/items/containers.json @@ -25,7 +25,7 @@ "max_contains_weight": "5 kg" } ], - "armor_data": { "covers": [ "torso" ], "coverage": 10, "encumbrance": 4, "material_thickness": 2 }, + "armor_data": { "material_thickness": 2, "armor": [ { "encumbrance": 4, "coverage": 10, "covers": [ "torso" ] } ] }, "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] }, { @@ -581,7 +581,7 @@ "max_contains_weight": "20 kg" } ], - "armor_data": { "covers": [ "torso" ], "coverage": 15, "material_thickness": 1 }, + "armor_data": { "material_thickness": 1, "armor": [ { "coverage": 15, "covers": [ "torso" ] } ] }, "flags": [ "BELTED" ] }, { @@ -762,7 +762,11 @@ "max_contains_weight": "3 kg" } ], - "armor_data": { "covers": [ "leg_l", "leg_r" ], "sided": true, "coverage": 5, "encumbrance": 2, "material_thickness": 2 }, + "armor_data": { + "sided": true, + "material_thickness": 2, + "armor": [ { "encumbrance": 2, "coverage": 5, "covers": [ "leg_l", "leg_r" ] } ] + }, "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] }, { @@ -1061,7 +1065,7 @@ "max_contains_weight": "1 kg" } ], - "armor_data": { "covers": [ "leg_l", "leg_r" ], "sided": true, "coverage": 2, "material_thickness": 1 }, + "armor_data": { "sided": true, "material_thickness": 1, "armor": [ { "coverage": 2, "covers": [ "leg_l", "leg_r" ] } ] }, "qualities": [ [ "BOIL", 1 ] ], "flags": [ "WAIST", "OVERSIZE", "WATER_FRIENDLY" ] }, @@ -1386,7 +1390,7 @@ "max_contains_weight": "3 kg" } ], - "armor_data": { "covers": [ "torso" ], "coverage": 5, "encumbrance": 5, "material_thickness": 2 }, + "armor_data": { "material_thickness": 2, "armor": [ { "encumbrance": 5, "coverage": 5, "covers": [ "torso" ] } ] }, "flags": [ "WAIST", "WATER_FRIENDLY" ] }, { @@ -1439,7 +1443,7 @@ "max_contains_weight": "3 kg" } ], - "armor_data": { "covers": [ "leg_l", "leg_r" ], "sided": true, "coverage": 5, "material_thickness": 2 }, + "armor_data": { "sided": true, "material_thickness": 2, "armor": [ { "coverage": 5, "covers": [ "leg_l", "leg_r" ] } ] }, "flags": [ "WAIST", "WATER_FRIENDLY" ] }, { @@ -1467,7 +1471,7 @@ "max_contains_weight": "6 kg" } ], - "armor_data": { "covers": [ "torso" ], "coverage": 10, "material_thickness": 2 }, + "armor_data": { "material_thickness": 2, "armor": [ { "coverage": 10, "covers": [ "torso" ] } ] }, "flags": [ "WAIST", "WATER_FRIENDLY" ] }, { @@ -1495,7 +1499,7 @@ "max_contains_weight": "10 kg" } ], - "armor_data": { "covers": [ "torso" ], "coverage": 15, "material_thickness": 2 }, + "armor_data": { "material_thickness": 2, "armor": [ { "coverage": 15, "covers": [ "torso" ] } ] }, "flags": [ "BELTED", "WATER_FRIENDLY" ] }, { diff --git a/data/json/items/fluff.json b/data/json/items/fluff.json index 17370a9a3d6db..c89ae049fd3d4 100644 --- a/data/json/items/fluff.json +++ b/data/json/items/fluff.json @@ -295,11 +295,10 @@ "symbol": "?", "looks_like": "briefcase", "color": "light_gray", - "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], "sided": true, - "coverage": 10, "material_thickness": 2, - "flags": [ "OVERSIZE", "BELTED", "RESTRICT_HANDS", "WATER_FRIENDLY" ] + "flags": [ "OVERSIZE", "BELTED", "RESTRICT_HANDS", "WATER_FRIENDLY" ], + "armor": [ { "coverage": 10, "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ] } ] }, { "type": "GENERIC", diff --git a/data/json/items/generic.json b/data/json/items/generic.json index 4162d1904f41d..ee1bc83dd173c 100644 --- a/data/json/items/generic.json +++ b/data/json/items/generic.json @@ -3390,9 +3390,6 @@ "volume": "500 ml", "bashing": 1, "to_hit": -1, - "covers": [ "torso" ], - "encumbrance": 2, - "coverage": 10, "material_thickness": 2, "pocket_data": [ { @@ -3413,7 +3410,8 @@ "robofac_test_data" ] } - ] + ], + "armor": [ { "encumbrance": 2, "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "lanyard", @@ -3432,8 +3430,6 @@ "longest_side": "5 cm", "bashing": 1, "to_hit": -1, - "covers": [ "torso" ], - "encumbrance": 0, "material_thickness": 1, "pocket_data": [ { @@ -3463,7 +3459,8 @@ "condom" ] } - ] + ], + "armor": [ { "encumbrance": 0, "covers": [ "torso" ] } ] }, { "type": "GENERIC", diff --git a/data/json/items/generic/bedding.json b/data/json/items/generic/bedding.json index dcf2871883a75..fd7c0f3b2ba99 100644 --- a/data/json/items/generic/bedding.json +++ b/data/json/items/generic/bedding.json @@ -31,12 +31,16 @@ "symbol": "[", "looks_like": "blanket", "color": "white", - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 15, "warmth": 10, "material_thickness": 0.1, - "flags": [ "OVERSIZE", "OUTER", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "OVERSIZE", "OUTER", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ + { + "encumbrance": 15, + "coverage": 100, + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "blanket", @@ -52,13 +56,17 @@ "symbol": "[", "looks_like": "towel", "color": "blue", - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 35, "warmth": 50, "material_thickness": 1, "environmental_protection": 1, - "flags": [ "OVERSIZE", "OUTER", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "OVERSIZE", "OUTER", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ + { + "encumbrance": 35, + "coverage": 100, + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "down_blanket", @@ -74,13 +82,17 @@ "symbol": "[", "looks_like": "blanket", "color": "blue", - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 45, "warmth": 70, "material_thickness": 1, "environmental_protection": 1, - "flags": [ "OVERSIZE", "OUTER", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "OVERSIZE", "OUTER", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ + { + "encumbrance": 45, + "coverage": 100, + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "fur_blanket", @@ -96,13 +108,17 @@ "symbol": "[", "looks_like": "blanket", "color": "brown", - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 55, "warmth": 80, "material_thickness": 2, "environmental_protection": 1, - "flags": [ "OVERSIZE", "OUTER", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "OVERSIZE", "OUTER", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ + { + "encumbrance": 55, + "coverage": 100, + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "quilt", @@ -116,14 +132,18 @@ "material": [ "wool" ], "symbol": "[", "color": "white", - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 40, "warmth": 75, "material_thickness": 1, "environmental_protection": 2, "flags": [ "OVERSIZE", "OUTER", "ALLOWS_NATURAL_ATTACKS" ], - "looks_like": "down_blanket" + "looks_like": "down_blanket", + "armor": [ + { + "encumbrance": 40, + "coverage": 100, + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "quilt_patchwork", @@ -131,8 +151,14 @@ "copy-from": "quilt", "name": { "str": "patchwork quilt" }, "description": "A huge, patchwork wool quilt. Very, very warm.", - "encumbrance": 50, - "warmth": 70 + "warmth": 70, + "armor": [ + { + "encumbrance": 50, + "coverage": 100, + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "sleeping_bag", @@ -148,9 +174,6 @@ "symbol": "[", "looks_like": "blanket", "color": "light_red", - "covers": [ "torso", "head", "mouth", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 80, "warmth": 80, "material_thickness": 3, "environmental_protection": 1, @@ -160,6 +183,13 @@ "type": "transform", "target": "sleeping_bag_roll", "msg": "You roll up the sleeping bag, preparing it for transport." - } + }, + "armor": [ + { + "encumbrance": 80, + "coverage": 100, + "covers": [ "torso", "head", "mouth", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] } ] diff --git a/data/json/items/generic/string.json b/data/json/items/generic/string.json index e83a33ef09eb8..1a6eee3416576 100644 --- a/data/json/items/generic/string.json +++ b/data/json/items/generic/string.json @@ -46,7 +46,7 @@ "type": "GENERIC", "name": { "str": "short rope" }, "description": "A 6-foot (or about 180 cm) long piece of rope. Wear it over a shoulder and tie items to it as a temporary carrying solution.", - "armor_data": { "covers": [ "torso" ], "coverage": 5, "encumbrance": 3, "material_thickness": 2 }, + "armor_data": { "material_thickness": 2, "armor": [ { "encumbrance": 3, "coverage": 5, "covers": [ "torso" ] } ] }, "proportional": { "weight": 6, "volume": 6, "price": 6 }, "pocket_data": [ { @@ -71,7 +71,7 @@ "type": "GENERIC", "name": { "str": "long rope" }, "description": "A 30-foot (or about 9 m) long rope. Useful for keeping yourself safe from falls. Wear it over a shoulder and tie items to it as a temporary carrying solution.", - "armor_data": { "covers": [ "torso" ], "coverage": 10, "encumbrance": 12, "material_thickness": 6 }, + "armor_data": { "material_thickness": 6, "armor": [ { "encumbrance": 12, "coverage": 10, "covers": [ "torso" ] } ] }, "qualities": [ [ "ROPE", 2 ] ], "proportional": { "weight": 5, "volume": 5, "price": 5 }, "pocket_data": [ diff --git a/data/json/items/gun/9mm.json b/data/json/items/gun/9mm.json index e7c43afc64eeb..6c76ecdc0e193 100644 --- a/data/json/items/gun/9mm.json +++ b/data/json/items/gun/9mm.json @@ -309,11 +309,9 @@ "dispersion": 520, "sight_dispersion": 520, "armor_data": { - "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ], "sided": true, - "coverage": 10, - "encumbrance": 30, - "material_thickness": 2 + "material_thickness": 2, + "armor": [ { "encumbrance": 30, "coverage": 10, "covers": [ "arm_l", "arm_r", "hand_l", "hand_r" ] } ] }, "flags": [ "OVERSIZE", "RELOAD_EJECT", "BELTED", "RESTRICT_HANDS" ], "valid_mod_locations": [ ], diff --git a/data/json/items/magazine/shot.json b/data/json/items/magazine/shot.json index b87e1770e494e..7a0e3f8cea87f 100644 --- a/data/json/items/magazine/shot.json +++ b/data/json/items/magazine/shot.json @@ -48,7 +48,7 @@ "symbol": "#", "color": "light_gray", "ammo_type": [ "shot" ], - "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 2 }, + "armor_data": { "material_thickness": 1, "armor": [ { "encumbrance": 2, "coverage": 5, "covers": [ "torso" ] } ] }, "flags": [ "MAG_EJECT", "BELTED", "OVERSIZE", "WATER_FRIENDLY" ], "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "shot": 20 } } ] }, diff --git a/data/json/items/melee/unarmed_weapons.json b/data/json/items/melee/unarmed_weapons.json index c6f7d653b4f1e..a22cd481df10d 100644 --- a/data/json/items/melee/unarmed_weapons.json +++ b/data/json/items/melee/unarmed_weapons.json @@ -29,10 +29,8 @@ "bashing": 2, "price_postapoc": 250, "flags": [ "UNARMED_WEAPON", "DURABLE_MELEE", "NONCONDUCTIVE" ], - "covers": [ "hand_l", "hand_r" ], - "coverage": 50, - "encumbrance": 5, - "material_thickness": 1 + "material_thickness": 1, + "armor": [ { "encumbrance": 5, "coverage": 50, "covers": [ "hand_l", "hand_r" ] } ] }, { "type": "GENERIC", diff --git a/data/json/items/obsolete.json b/data/json/items/obsolete.json index 32da55017b7f4..21f11659f77c0 100644 --- a/data/json/items/obsolete.json +++ b/data/json/items/obsolete.json @@ -535,13 +535,11 @@ "material": [ "bone", "leather" ], "symbol": "[", "color": "white", - "covers": [ "arm_l", "arm_r" ], - "coverage": 95, - "encumbrance": 22, "warmth": 20, "material_thickness": 4, "environmental_protection": 1, - "flags": [ "STURDY", "BELTED", "BLOCK_WHILE_WORN", "WATER_FRIENDLY" ] + "flags": [ "STURDY", "BELTED", "BLOCK_WHILE_WORN", "WATER_FRIENDLY" ], + "armor": [ { "encumbrance": 22, "coverage": 95, "covers": [ "arm_l", "arm_r" ] } ] }, { "id": "armor_bone", @@ -557,12 +555,10 @@ "material": [ "bone", "leather" ], "symbol": "[", "color": "white", - "covers": [ "torso", "leg_l", "leg_r" ], - "coverage": 95, - "encumbrance": 24, "warmth": 20, "material_thickness": 4, - "flags": [ "VARSIZE", "STURDY" ] + "flags": [ "VARSIZE", "STURDY" ], + "armor": [ { "encumbrance": 24, "coverage": 95, "covers": [ "torso", "leg_l", "leg_r" ] } ] }, { "id": "gauntlets_bone", @@ -578,13 +574,11 @@ "material": [ "bone", "leather" ], "symbol": "[", "color": "white", - "covers": [ "hand_l", "hand_r" ], - "coverage": 95, - "encumbrance": 15, "warmth": 20, "material_thickness": 4, "environmental_protection": 4, - "flags": [ "STURDY" ] + "flags": [ "STURDY" ], + "armor": [ { "encumbrance": 15, "coverage": 95, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "helmet_bone", @@ -600,13 +594,11 @@ "material": [ "bone" ], "symbol": "[", "color": "white", - "covers": [ "head", "eyes", "mouth" ], - "coverage": 100, - "encumbrance": 25, "warmth": 10, "material_thickness": 5, "environmental_protection": 3, - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 25, "coverage": 100, "covers": [ "head", "eyes", "mouth" ] } ] }, { "id": "matchbomb", @@ -1708,14 +1700,12 @@ "symbol": "[", "looks_like": "helmet_army", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 100, - "encumbrance": 25, "warmth": 15, "material_thickness": 5, "environmental_protection": 3, "techniques": [ "WBLOCK_1" ], - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 25, "coverage": 100, "covers": [ "head" ] } ] }, { "id": "helmet_xlsurvivor", @@ -1732,14 +1722,12 @@ "symbol": "[", "looks_like": "helmet_survivor", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 100, - "encumbrance": 50, "warmth": 15, "material_thickness": 4, "environmental_protection": 3, "techniques": [ "WBLOCK_1" ], - "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "OVERSIZE", "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 50, "coverage": 100, "covers": [ "head" ] } ] }, { "id": "helmet_hsurvivor", @@ -1756,14 +1744,12 @@ "symbol": "[", "looks_like": "helmet_survivor", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 100, - "encumbrance": 40, "warmth": 25, "material_thickness": 6, "environmental_protection": 5, "techniques": [ "WBLOCK_1" ], - "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ] + "flags": [ "VARSIZE", "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 40, "coverage": 100, "covers": [ "head" ] } ] }, { "id": "l_bak_223", @@ -1991,12 +1977,10 @@ "material": [ "glass", "steel" ], "symbol": "[", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 12, "material_thickness": 3, "use_action": [ "SOLARPACK" ], - "flags": [ "FRAGILE", "OUTER", "ONLY_ONE", "SOLARPACK" ] + "flags": [ "FRAGILE", "OUTER", "ONLY_ONE", "SOLARPACK" ], + "armor": [ { "encumbrance": 12, "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "q_solarpack_on", @@ -2012,13 +1996,11 @@ "material": [ "glass", "steel" ], "symbol": "[", "color": "blue", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 20, "material_thickness": 1, "use_action": [ "SOLARPACK_OFF" ], "solar_efficiency": 0.3, - "flags": [ "FRAGILE", "OUTER", "ONLY_ONE", "SOLARPACK_ON" ] + "flags": [ "FRAGILE", "OUTER", "ONLY_ONE", "SOLARPACK_ON" ], + "armor": [ { "encumbrance": 20, "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "tihar", @@ -2383,13 +2365,11 @@ "symbol": "[", "looks_like": "modularvestkevlar", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 85, - "encumbrance": 7, "warmth": 15, "material_thickness": 4, "use_action": { "type": "holster", "holster_prompt": "Stash ammo", "holster_msg": "You stash your %s." }, - "flags": [ "STURDY", "OUTER" ] + "flags": [ "STURDY", "OUTER" ], + "armor": [ { "encumbrance": 7, "coverage": 85, "covers": [ "torso" ] } ] }, { "id": "modularvestceramic", @@ -2407,13 +2387,11 @@ "symbol": "[", "looks_like": "modularvestkevlar", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 85, - "encumbrance": 15, "warmth": 15, "material_thickness": 9, "use_action": { "type": "holster", "holster_prompt": "Stash ammo", "holster_msg": "You stash your %s." }, - "flags": [ "STURDY", "OUTER" ] + "flags": [ "STURDY", "OUTER" ], + "armor": [ { "encumbrance": 15, "coverage": 85, "covers": [ "torso" ] } ] }, { "id": "modularvesthard", @@ -2431,13 +2409,11 @@ "symbol": "[", "looks_like": "modularvestkevlar", "color": "light_cyan", - "covers": [ "torso" ], - "coverage": 85, - "encumbrance": 25, "warmth": 15, "material_thickness": 5, "use_action": { "type": "holster", "holster_prompt": "Stash ammo", "holster_msg": "You stash your %s." }, - "flags": [ "STURDY", "OUTER" ] + "flags": [ "STURDY", "OUTER" ], + "armor": [ { "encumbrance": 25, "coverage": 85, "covers": [ "torso" ] } ] }, { "id": "modularvestkevlar", @@ -2455,13 +2431,11 @@ "symbol": "[", "looks_like": "vest", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 85, - "encumbrance": 12, "warmth": 15, "material_thickness": 6, "use_action": { "type": "holster", "holster_prompt": "Stash ammo", "holster_msg": "You stash your %s." }, - "flags": [ "STURDY", "OUTER" ] + "flags": [ "STURDY", "OUTER" ], + "armor": [ { "encumbrance": 12, "coverage": 85, "covers": [ "torso" ] } ] }, { "id": "modularveststeel", @@ -2479,13 +2453,11 @@ "symbol": "[", "looks_like": "modularvestkevlar", "color": "light_cyan", - "covers": [ "torso" ], - "coverage": 85, - "encumbrance": 20, "warmth": 15, "material_thickness": 7, "use_action": { "type": "holster", "holster_prompt": "Stash ammo", "holster_msg": "You stash your %s." }, - "flags": [ "STURDY", "OUTER" ] + "flags": [ "STURDY", "OUTER" ], + "armor": [ { "encumbrance": 20, "coverage": 85, "covers": [ "torso" ] } ] }, { "id": "modularvestsuper", @@ -2503,13 +2475,11 @@ "symbol": "[", "looks_like": "modularvestkevlar", "color": "light_cyan", - "covers": [ "torso" ], - "coverage": 85, - "encumbrance": 15, "warmth": 15, "material_thickness": 6, "use_action": { "type": "holster", "holster_prompt": "Stash ammo", "holster_msg": "You stash your %s." }, - "flags": [ "STURDY", "OUTER" ] + "flags": [ "STURDY", "OUTER" ], + "armor": [ { "encumbrance": 15, "coverage": 85, "covers": [ "torso" ] } ] }, { "type": "AMMO", @@ -2841,7 +2811,7 @@ "volume": "3500 ml", "price_postapoc": 5000, "bashing": 12, - "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 20 }, + "armor_data": { "material_thickness": 1, "armor": [ { "encumbrance": 20, "coverage": 5, "covers": [ "torso" ] } ] }, "reload_noise_volume": 3, "loudness": 8, "ranged_damage": { "damage_type": "stab", "amount": 10 }, diff --git a/data/json/items/ranged/archery.json b/data/json/items/ranged/archery.json index b7e84025764cc..00cfc88add9a9 100644 --- a/data/json/items/ranged/archery.json +++ b/data/json/items/ranged/archery.json @@ -399,7 +399,7 @@ "longest_side": "140 cm", "price_postapoc": 50, "bashing": 6, - "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 20 }, + "armor_data": { "material_thickness": 1, "armor": [ { "encumbrance": 20, "coverage": 5, "covers": [ "torso" ] } ] }, "ranged_damage": { "damage_type": "stab", "amount": 1 }, "range": 8, "dispersion": 1250, @@ -437,7 +437,7 @@ "longest_side": "132 cm", "price_postapoc": 500, "bashing": 6, - "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 14 }, + "armor_data": { "material_thickness": 1, "armor": [ { "encumbrance": 14, "coverage": 5, "covers": [ "torso" ] } ] }, "reload_noise_volume": 3, "loudness": 6, "ranged_damage": { "damage_type": "stab", "amount": 4 }, @@ -551,7 +551,7 @@ "longest_side": "152 cm", "price_postapoc": 3000, "bashing": 8, - "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 14 }, + "armor_data": { "material_thickness": 1, "armor": [ { "encumbrance": 14, "coverage": 5, "covers": [ "torso" ] } ] }, "reload_noise_volume": 3, "loudness": 6, "ranged_damage": { "damage_type": "stab", "amount": 8 }, @@ -592,7 +592,7 @@ "longest_side": "183 cm", "price_postapoc": 2000, "bashing": 12, - "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 14 }, + "armor_data": { "material_thickness": 1, "armor": [ { "encumbrance": 14, "coverage": 5, "covers": [ "torso" ] } ] }, "reload_noise_volume": 3, "loudness": 6, "ranged_damage": { "damage_type": "stab", "amount": 6 }, @@ -633,7 +633,7 @@ "longest_side": "152 cm", "price_postapoc": 2000, "bashing": 12, - "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 20 }, + "armor_data": { "material_thickness": 1, "armor": [ { "encumbrance": 20, "coverage": 5, "covers": [ "torso" ] } ] }, "reload_noise_volume": 3, "loudness": 8, "ranged_damage": { "damage_type": "stab", "amount": 6 }, @@ -673,7 +673,7 @@ "longest_side": "183 cm", "price_postapoc": 3000, "bashing": 10, - "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 20 }, + "armor_data": { "material_thickness": 1, "armor": [ { "encumbrance": 20, "coverage": 5, "covers": [ "torso" ] } ] }, "reload_noise_volume": 3, "loudness": 8, "ranged_damage": { "damage_type": "stab", "amount": 6 }, @@ -697,7 +697,7 @@ "volume": "6250 ml", "longest_side": "198 cm", "price_postapoc": 2000, - "armor_data": { "covers": [ "torso" ], "coverage": 7, "material_thickness": 2, "encumbrance": 25 }, + "armor_data": { "material_thickness": 2, "armor": [ { "encumbrance": 25, "coverage": 7, "covers": [ "torso" ] } ] }, "durability": 8, "loudness": 16, "ranged_damage": { "damage_type": "stab", "amount": 11 }, @@ -764,7 +764,7 @@ "longest_side": "150 cm", "price_postapoc": 6000, "bashing": 12, - "armor_data": { "covers": [ "torso" ], "coverage": 5, "material_thickness": 1, "encumbrance": 14 }, + "armor_data": { "material_thickness": 1, "armor": [ { "encumbrance": 14, "coverage": 5, "covers": [ "torso" ] } ] }, "reload_noise_volume": 3, "loudness": 8, "ranged_damage": { "damage_type": "stab", "amount": 5 }, diff --git a/data/json/items/tool/misc.json b/data/json/items/tool/misc.json index c6f851e5ba728..e64c0cafd7307 100644 --- a/data/json/items/tool/misc.json +++ b/data/json/items/tool/misc.json @@ -726,14 +726,12 @@ "material": [ "plastic", "aluminum" ], "symbol": ",", "color": "dark_gray", - "covers": [ "hand_l", "hand_r" ], "sided": true, - "coverage": 5, - "encumbrance": 40, "warmth": 0, "material_thickness": 1, "techniques": [ "WBLOCK_1" ], - "flags": [ "ALLOWS_NATURAL_ATTACKS", "BELT_CLIP", "BELTED", "FRAGILE", "OVERSIZE", "RAIN_PROTECT" ] + "flags": [ "ALLOWS_NATURAL_ATTACKS", "BELT_CLIP", "BELTED", "FRAGILE", "OVERSIZE", "RAIN_PROTECT" ], + "armor": [ { "encumbrance": 40, "coverage": 5, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "testflames", diff --git a/data/json/items/tool/musical_instruments.json b/data/json/items/tool/musical_instruments.json index 1bb367726d3ab..50feec8d572a6 100644 --- a/data/json/items/tool/musical_instruments.json +++ b/data/json/items/tool/musical_instruments.json @@ -245,7 +245,6 @@ "category": "tools", "weight": "200 g", "color": "brown", - "covers": [ "head" ], "use_action": { "type": "musical_instrument", "speed_penalty": 10, @@ -264,7 +263,8 @@ "volume": "250 ml", "longest_side": "18 cm", "flags": [ "BELTED", "SLEEP_IGNORE" ], - "material_thickness": 1 + "material_thickness": 1, + "armor": [ { "covers": [ "head" ] } ] }, { "type": "TOOL_ARMOR", @@ -273,7 +273,6 @@ "category": "tools", "weight": "2200 g", "color": "brown", - "covers": [ "torso" ], "to_hit": 2, "use_action": { "type": "musical_instrument", @@ -297,11 +296,10 @@ "volume": "6750 ml", "longest_side": "97 cm", "warmth": 2, - "encumbrance": 27, "bashing": 8, "flags": [ "BELTED", "SLEEP_IGNORE" ], - "coverage": 10, - "material_thickness": 2 + "material_thickness": 2, + "armor": [ { "encumbrance": 27, "coverage": 10, "covers": [ "torso" ] } ] }, { "type": "TOOL_ARMOR", @@ -310,7 +308,6 @@ "category": "tools", "weight": "3750 g", "color": "red", - "covers": [ "torso" ], "to_hit": 2, "use_action": { "type": "musical_instrument", @@ -339,11 +336,10 @@ "volume": "6750 ml", "longest_side": "97 cm", "warmth": 2, - "encumbrance": 27, "bashing": 8, "flags": [ "BELTED", "SLEEP_IGNORE" ], - "coverage": 10, - "material_thickness": 2 + "material_thickness": 2, + "armor": [ { "encumbrance": 27, "coverage": 10, "covers": [ "torso" ] } ] }, { "type": "TOOL_ARMOR", @@ -352,7 +348,6 @@ "category": "tools", "weight": "2500 g", "color": "green", - "covers": [ "torso" ], "to_hit": -2, "use_action": { "type": "musical_instrument", @@ -379,11 +374,10 @@ "material": [ "leather", "wood" ], "volume": "5 L", "longest_side": "65 cm", - "encumbrance": 15, "bashing": 4, "flags": [ "BELTED", "SLEEP_IGNORE" ], - "coverage": 10, - "material_thickness": 2 + "material_thickness": 2, + "armor": [ { "encumbrance": 15, "coverage": 10, "covers": [ "torso" ] } ] }, { "type": "TOOL_ARMOR", @@ -392,7 +386,6 @@ "category": "tools", "weight": "13600 g", "color": "yellow", - "covers": [ "torso" ], "flags": [ "BELTED", "SLEEP_IGNORE" ], "to_hit": -1, "use_action": { @@ -415,10 +408,9 @@ "material": [ "iron" ], "volume": "12500 ml", "longest_side": "107 cm", - "encumbrance": 30, "bashing": 13, - "coverage": 20, - "material_thickness": 4 + "material_thickness": 4, + "armor": [ { "encumbrance": 30, "coverage": 20, "covers": [ "torso" ] } ] }, { "type": "TOOL_ARMOR", @@ -427,7 +419,6 @@ "category": "tools", "weight": "2200 g", "color": "yellow", - "covers": [ "torso" ], "flags": [ "BELTED", "SLEEP_IGNORE" ], "to_hit": 1, "use_action": { @@ -455,9 +446,8 @@ "material": [ "brass" ], "volume": "4500 ml", "longest_side": "70 cm", - "encumbrance": 30, "bashing": 12, - "coverage": 20, - "material_thickness": 4 + "material_thickness": 4, + "armor": [ { "encumbrance": 30, "coverage": 20, "covers": [ "torso" ] } ] } ] diff --git a/data/json/items/tool_armor.json b/data/json/items/tool_armor.json index 1edd3b9fdd37a..ea3e9cd9d9f2e 100644 --- a/data/json/items/tool_armor.json +++ b/data/json/items/tool_armor.json @@ -12,13 +12,11 @@ "symbol": "[", "looks_like": "armguard_hard", "color": "white", - "covers": [ "arm_l", "arm_r" ], "sided": true, - "coverage": 75, - "encumbrance": 70, "warmth": 5, "material_thickness": 1, - "flags": [ "WATER_FRIENDLY", "OUTER", "SPLINT" ] + "flags": [ "WATER_FRIENDLY", "OUTER", "SPLINT" ], + "armor": [ { "encumbrance": 70, "coverage": 75, "covers": [ "arm_l", "arm_r" ] } ] }, { "id": "arm_xlsplint", @@ -31,8 +29,8 @@ "volume": "2 L", "price": 25000, "price_postapoc": 50, - "encumbrance": 140, - "flags": [ "OVERSIZE", "WATER_FRIENDLY", "OUTER", "SPLINT" ] + "flags": [ "OVERSIZE", "WATER_FRIENDLY", "OUTER", "SPLINT" ], + "armor": [ { "encumbrance": 140 } ] }, { "id": "tourniquet_upper", @@ -47,14 +45,12 @@ "symbol": "{", "looks_like": "armguard_hard", "color": "red", - "covers": [ "arm_l", "arm_r" ], "sided": true, - "coverage": 10, - "encumbrance": 70, "warmth": 0, "material_thickness": 1, "use_action": { "target": "tourniquet_upper_XL", "msg": "You adjust the tourniquet.", "menu_text": "Adjust", "type": "transform" }, - "flags": [ "WATER_FRIENDLY", "OUTER", "TOURNIQUET" ] + "flags": [ "WATER_FRIENDLY", "OUTER", "TOURNIQUET" ], + "armor": [ { "encumbrance": 70, "coverage": 10, "covers": [ "arm_l", "arm_r" ] } ] }, { "id": "tourniquet_upper_XL", @@ -63,7 +59,6 @@ "description": "First aid device used to apply pressure to a limb or extremity in order to limit blood flow. Should be employed only to manage heavy bleedings, because prolonged use will harm the limb. It can be adjusted in size to fit different limbs.", "copy-from": "tourniquet_upper", "looks_like": "tourniquet_upper", - "covers": [ "arm_l", "arm_r" ], "sided": true, "use_action": { "target": "tourniquet_lower", "msg": "You adjust the tourniquet.", "menu_text": "Adjust", "type": "transform" }, "flags": [ "WATER_FRIENDLY", "OUTER", "TOURNIQUET", "OVERSIZE" ] @@ -75,10 +70,10 @@ "description": "First aid device used to apply pressure to a limb or extremity in order to limit blood flow. Should be employed only to manage heavy bleedings, because prolonged use will harm the limb. It can be adjusted in size to fit different limbs.", "copy-from": "tourniquet_upper", "looks_like": "tourniquet_upper", - "covers": [ "leg_l", "leg_r" ], "sided": true, "use_action": { "target": "tourniquet_lower_XL", "msg": "You adjust the tourniquet.", "menu_text": "Adjust", "type": "transform" }, - "flags": [ "WATER_FRIENDLY", "OUTER", "TOURNIQUET" ] + "flags": [ "WATER_FRIENDLY", "OUTER", "TOURNIQUET" ], + "armor": [ { "encumbrance": 70, "coverage": 10, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "tourniquet_lower_XL", @@ -87,7 +82,6 @@ "description": "First aid device used to apply pressure to a limb or extremity in order to limit blood flow. Should be employed only to manage heavy bleedings, because prolonged use will harm the limb. It can be adjusted in size to fit different limbs.", "copy-from": "tourniquet_upper", "looks_like": "tourniquet_upper", - "covers": [ "leg_l", "leg_r" ], "sided": true, "use_action": { "target": "tourniquet_upper", "msg": "You adjust the tourniquet.", "menu_text": "Adjust", "type": "transform" }, "flags": [ "WATER_FRIENDLY", "OUTER", "TOURNIQUET", "OVERSIZE" ] @@ -106,13 +100,11 @@ "symbol": "[", "looks_like": "scarf", "color": "dark_gray", - "covers": [ "eyes" ], - "coverage": 95, - "encumbrance": 10, "warmth": 5, "material_thickness": 0.1, "environmental_protection": 1, - "flags": [ "BLIND" ] + "flags": [ "BLIND" ], + "armor": [ { "encumbrance": 10, "coverage": 95, "covers": [ "eyes" ] } ] }, { "id": "blindfold_duct", @@ -128,13 +120,11 @@ "symbol": "[", "looks_like": "blindfold", "color": "dark_gray", - "covers": [ "eyes" ], - "coverage": 95, - "encumbrance": 10, "warmth": 0, "material_thickness": 1, "environmental_protection": 1, - "flags": [ "BLIND" ] + "flags": [ "BLIND" ], + "armor": [ { "encumbrance": 10, "coverage": 95, "covers": [ "eyes" ] } ] }, { "id": "ear_plugs", @@ -148,9 +138,9 @@ "material": [ "plastic" ], "symbol": ";", "color": "light_gray", - "coverage": 1, "material_thickness": 1, - "flags": [ "DEAF", "OVERSIZE", "POWERARMOR_COMPATIBLE" ] + "flags": [ "DEAF", "OVERSIZE", "POWERARMOR_COMPATIBLE" ], + "armor": [ { "coverage": 1 } ] }, { "id": "gobag", @@ -166,13 +156,11 @@ "symbol": "[", "looks_like": "duffelbag", "color": "green", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 50, - "encumbrance": 35, "warmth": 10, "material_thickness": 3, "flags": [ "BELTED", "WATER_FRIENDLY" ], - "use_action": { "type": "unpack", "group": "gobag_contents", "filthy_volume_threshold": "10 L" } + "use_action": { "type": "unpack", "group": "gobag_contents", "filthy_volume_threshold": "10 L" }, + "armor": [ { "encumbrance": 35, "coverage": 50, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "id": "personal_gobag", @@ -197,13 +185,11 @@ "symbol": "[", "looks_like": "legguard_hard", "color": "white", - "covers": [ "leg_l", "leg_r" ], "sided": true, - "coverage": 75, - "encumbrance": 70, "warmth": 5, "material_thickness": 1, - "flags": [ "WATER_FRIENDLY", "OUTER", "SPLINT", "ALLOWS_TAIL" ] + "flags": [ "WATER_FRIENDLY", "OUTER", "SPLINT", "ALLOWS_TAIL" ], + "armor": [ { "encumbrance": 70, "coverage": 75, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "leg_xlsplint", @@ -215,8 +201,8 @@ "volume": "2 L", "price": 25000, "price_postapoc": 50, - "encumbrance": 140, - "flags": [ "OVERSIZE", "WATER_FRIENDLY", "OUTER", "SPLINT", "ALLOWS_TAIL" ] + "flags": [ "OVERSIZE", "WATER_FRIENDLY", "OUTER", "SPLINT", "ALLOWS_TAIL" ], + "armor": [ { "encumbrance": 140, "coverage": 75, "covers": [ "leg_l", "leg_r" ] } ] }, { "id": "miner_hat", @@ -243,11 +229,8 @@ "need_charges": 1, "need_charges_msg": "The helmet's batteries are dead." }, - "covers": [ "head" ], "techniques": [ "WBLOCK_1" ], "warmth": 5, - "encumbrance": 15, - "coverage": 80, "material_thickness": 4, "pocket_data": [ { @@ -266,7 +249,8 @@ "light_disposable_cell" ] } - ] + ], + "armor": [ { "encumbrance": 15, "coverage": 80, "covers": [ "head" ] } ] }, { "id": "miner_hat_on", @@ -279,7 +263,6 @@ "power_draw": 15000, "revert_to": "miner_hat", "use_action": { "menu_text": "Turn off", "type": "transform", "msg": "The %s flicks off.", "target": "miner_hat" }, - "covers": [ "head" ], "techniques": [ "WBLOCK_1" ] }, { @@ -297,13 +280,11 @@ "material": [ "plastic" ], "symbol": "[", "color": "dark_gray", - "covers": [ "head", "eyes", "mouth" ], - "coverage": 90, "warmth": 5, - "encumbrance": 60, "material_thickness": 3, "qualities": [ [ "GLARE", 3 ] ], - "flags": [ "SUN_GLASSES", "FLASH_PROTECTION" ] + "flags": [ "SUN_GLASSES", "FLASH_PROTECTION" ], + "armor": [ { "encumbrance": 60, "coverage": 90, "covers": [ "head", "eyes", "mouth" ] } ] }, { "id": "welding_mask_crude", @@ -324,13 +305,11 @@ "material": [ "steel" ], "symbol": "[", "color": "dark_gray", - "covers": [ "head", "eyes", "mouth" ], - "coverage": 90, "warmth": 5, - "encumbrance": 60, "material_thickness": 2, "qualities": [ [ "GLARE", 2 ] ], - "flags": [ "SUN_GLASSES", "FLASH_PROTECTION" ] + "flags": [ "SUN_GLASSES", "FLASH_PROTECTION" ], + "armor": [ { "encumbrance": 60, "coverage": 90, "covers": [ "head", "eyes", "mouth" ] } ] }, { "id": "welding_mask_crude_raised", @@ -351,11 +330,9 @@ "material": [ "steel" ], "symbol": "[", "color": "dark_gray", - "covers": [ "head" ], "warmth": 5, - "encumbrance": 60, "material_thickness": 2, - "coverage": 30 + "armor": [ { "encumbrance": 60, "coverage": 30, "covers": [ "head" ] } ] }, { "id": "welding_mask_raised", @@ -376,11 +353,9 @@ "material": [ "plastic" ], "symbol": "[", "color": "dark_gray", - "covers": [ "head" ], "warmth": 5, - "encumbrance": 60, "material_thickness": 3, - "coverage": 30 + "armor": [ { "encumbrance": 60, "coverage": 30, "covers": [ "head" ] } ] }, { "type": "TOOL_ARMOR", @@ -392,13 +367,11 @@ "weight": "112 g", "to_hit": -1, "color": "light_gray", - "covers": [ "hand_l", "hand_r" ], "sided": true, "price": 6000, "price_postapoc": 100, "material": [ "plastic" ], "flags": [ "WATCH", "ALARMCLOCK", "WATER_FRIENDLY", "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "OVERSIZE" ], - "coverage": 15, "symbol": "[", "ammo": "battery", "charges_per_use": 1, @@ -412,7 +385,8 @@ "max_contains_weight": "20 kg", "item_restriction": [ "light_minus_battery_cell", "light_minus_atomic_battery_cell", "light_minus_disposable_cell" ] } - ] + ], + "armor": [ { "coverage": 15, "covers": [ "hand_l", "hand_r" ] } ] }, { "type": "TOOL_ARMOR", @@ -424,15 +398,14 @@ "weight": "30 g", "to_hit": -1, "color": "light_gray", - "covers": [ "hand_l", "hand_r" ], "sided": true, "price": 5000, "price_postapoc": 100, "material": [ "plastic" ], "flags": [ "WATCH", "WATER_FRIENDLY", "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "OVERSIZE" ], - "coverage": 15, "symbol": "[", - "use_action": [ "FITNESS_CHECK" ] + "use_action": [ "FITNESS_CHECK" ], + "armor": [ { "coverage": 15, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "holo_cloak", @@ -447,9 +420,6 @@ "material": [ "superalloy" ], "symbol": "[", "color": "light_gray", - "covers": [ "torso", "head", "arm_l", "arm_r", "leg_l", "leg_r" ], - "coverage": 65, - "encumbrance": 10, "pocket_data": [ { "pocket_type": "MAGAZINE_WELL", @@ -466,7 +436,8 @@ "material_thickness": 0.5, "environmental_protection": 4, "use_action": [ "DIRECTIONAL_HOLOGRAM" ], - "flags": [ "OVERSIZE", "HOOD", "WATERPROOF", "OUTER" ] + "flags": [ "OVERSIZE", "HOOD", "WATERPROOF", "OUTER" ], + "armor": [ { "encumbrance": 10, "coverage": 65, "covers": [ "torso", "head", "arm_l", "arm_r", "leg_l", "leg_r" ] } ] }, { "type": "TOOL_ARMOR", @@ -475,7 +446,6 @@ "name": { "str": "fedora" }, "weight": "350 g", "color": "brown", - "covers": [ "head" ], "use_action": { "menu_text": "Tip", "type": "transform", "target": "fedora", "msg": "You tip your %s." }, "symbol": "[", "description": "A high-crowned, wide-brimmed, sable colored fedora. Its brim helps keep the sun out of your eyes. The perfect hat for treasure hunting.", @@ -485,10 +455,9 @@ "volume": "1750 ml", "warmth": 7, "environmental_protection": 3, - "encumbrance": 10, - "coverage": 50, "flags": [ "FANCY", "VARSIZE", "SUN_GLASSES" ], - "material_thickness": 0.5 + "material_thickness": 0.5, + "armor": [ { "encumbrance": 10, "coverage": 50, "covers": [ "head" ] } ] }, { "id": "thermal_socks", @@ -514,9 +483,7 @@ "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "covers": [ "foot_l", "foot_r" ], "warmth": 10, - "coverage": 100, "material_thickness": 0.3, "pocket_data": [ { @@ -535,7 +502,8 @@ "light_disposable_cell" ] } - ] + ], + "armor": [ { "coverage": 100, "covers": [ "foot_l", "foot_r" ] } ] }, { "id": "thermal_socks_on", @@ -574,9 +542,7 @@ "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ], "warmth": 10, - "coverage": 100, "material_thickness": 0.1, "pocket_data": [ { @@ -595,7 +561,8 @@ "light_disposable_cell" ] } - ] + ], + "armor": [ { "coverage": 100, "covers": [ "torso", "arm_l", "arm_r", "leg_l", "leg_r" ] } ] }, { "id": "thermal_suit_on", @@ -634,9 +601,7 @@ "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "covers": [ "hand_l", "hand_r" ], "warmth": 10, - "coverage": 100, "material_thickness": 0.3, "pocket_data": [ { @@ -655,7 +620,8 @@ "light_disposable_cell" ] } - ] + ], + "armor": [ { "coverage": 100, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "thermal_gloves_on", @@ -694,9 +660,7 @@ "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "covers": [ "head", "mouth" ], "warmth": 10, - "coverage": 100, "material_thickness": 0.3, "pocket_data": [ { @@ -715,7 +679,8 @@ "light_disposable_cell" ] } - ] + ], + "armor": [ { "coverage": 100, "covers": [ "head", "mouth" ] } ] }, { "id": "thermal_mask_on", @@ -747,10 +712,8 @@ "bashing": 4, "to_hit": -1, "use_action": { "type": "firestarter", "moves": 1000, "moves_slow": 25000, "need_sunlight": true }, - "covers": [ "torso" ], - "encumbrance": 2, - "coverage": 10, - "material_thickness": 2 + "material_thickness": 2, + "armor": [ { "encumbrance": 2, "coverage": 10, "covers": [ "torso" ] } ] }, { "id": "wearable_light", @@ -777,8 +740,6 @@ "need_charges": 1, "need_charges_msg": "The headlamp batteries are dead." }, - "covers": [ "head" ], - "coverage": 15, "material_thickness": 1, "pocket_data": [ { @@ -797,7 +758,8 @@ "light_disposable_cell" ] } - ] + ], + "armor": [ { "coverage": 15, "covers": [ "head" ] } ] }, { "id": "wearable_light_on", @@ -836,8 +798,6 @@ "need_charges": 1, "need_charges_msg": "The survivor headlamp batteries are dead." }, - "covers": [ "head" ], - "coverage": 20, "material_thickness": 1, "pocket_data": [ { @@ -856,7 +816,8 @@ "light_disposable_cell" ] } - ] + ], + "armor": [ { "coverage": 20, "covers": [ "head" ] } ] }, { "id": "survivor_light_on", @@ -893,10 +854,8 @@ "target": "wearable_atomic_light_off", "active": true }, - "covers": [ "head" ], - "encumbrance": 5, - "coverage": 20, - "material_thickness": 1 + "material_thickness": 1, + "armor": [ { "encumbrance": 5, "coverage": 20, "covers": [ "head" ] } ] }, { "id": "wearable_atomic_light_off", @@ -990,12 +949,16 @@ "ammo": "battery", "charges_per_use": 5, "use_action": [ "RM13ARMOR_OFF" ], - "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "warmth": 30, "environmental_protection": 15, - "encumbrance": 30, - "coverage": 100, - "material_thickness": 2 + "material_thickness": 2, + "armor": [ + { + "encumbrance": 30, + "coverage": 100, + "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "rm13_armor_on", @@ -1024,9 +987,15 @@ "revert_to": "rm13_armor", "use_action": [ "RM13ARMOR_ON" ], "environmental_protection": 40, - "encumbrance": 10, "qualities": [ [ "GLARE", 2 ] ], - "material_thickness": 5 + "material_thickness": 5, + "armor": [ + { + "encumbrance": 10, + "coverage": 100, + "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "dimensional_anchor", @@ -1061,12 +1030,10 @@ "need_charges": 1, "need_charges_msg": "It seems like this device needs power." }, - "covers": [ "torso" ], "warmth": 10, - "coverage": 50, - "encumbrance": 2, "material_thickness": 2, - "flags": [ "OVERSIZE", "BELTED" ] + "flags": [ "OVERSIZE", "BELTED" ], + "armor": [ { "encumbrance": 2, "coverage": 50, "covers": [ "torso" ] } ] }, { "id": "dimensional_anchor_on", @@ -1084,7 +1051,6 @@ "msg": "The %s LED light flickers off.", "target": "dimensional_anchor" }, - "covers": [ "torso" ], "flags": [ "DIMENSIONAL_ANCHOR", "OVERSIZE", "BELTED" ] }, { @@ -1135,12 +1101,9 @@ "need_charges": 1, "need_charges_msg": "Warning: Operating on minimal power. Protection compromised." }, - "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "warmth": 30, "environmental_protection": 10, - "coverage": 100, "material_thickness": 2, - "encumbrance": 20, "flags": [ "RAD_PROOF", "STURDY", @@ -1152,6 +1115,13 @@ "ALARMCLOCK", "SWIM_GOGGLES", "SUN_GLASSES" + ], + "armor": [ + { + "encumbrance": 20, + "coverage": 100, + "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } ] }, { @@ -1165,7 +1135,6 @@ "turns_per_charge": 25, "revert_to": "phase_immersion_suit", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "Suit shutting down.", "target": "phase_immersion_suit" }, - "covers": [ "head", "mouth", "eyes", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "environmental_protection": 80, "flags": [ "RAD_PROOF", @@ -1213,12 +1182,10 @@ "need_charges": 1, "need_charges_msg": "The %s's filter is used up." }, - "covers": [ "mouth" ], "warmth": 10, "environmental_protection": 1, - "encumbrance": 30, - "coverage": 75, - "material_thickness": 1 + "material_thickness": 1, + "armor": [ { "encumbrance": 30, "coverage": 75, "covers": [ "mouth" ] } ] }, { "id": "rebreather_on", @@ -1232,7 +1199,7 @@ "revert_to": "rebreather", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "Your %s deactivates.", "target": "rebreather" }, "environmental_protection": 15, - "encumbrance": 20 + "armor": [ { "encumbrance": 20, "coverage": 75, "covers": [ "mouth" ] } ] }, { "id": "rebreather_xl", @@ -1260,12 +1227,10 @@ "need_charges": 1, "need_charges_msg": "The %s's filter is used up." }, - "covers": [ "mouth" ], "warmth": 10, "environmental_protection": 1, - "encumbrance": 30, - "coverage": 75, - "material_thickness": 1 + "material_thickness": 1, + "armor": [ { "encumbrance": 30, "coverage": 75, "covers": [ "mouth" ] } ] }, { "id": "rebreather_xl_on", @@ -1278,9 +1243,8 @@ "turns_per_charge": 30, "revert_to": "rebreather_xl", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "Your %s deactivates.", "target": "rebreather_xl" }, - "covers": [ "mouth" ], "environmental_protection": 15, - "encumbrance": 20 + "armor": [ { "encumbrance": 20, "coverage": 75, "covers": [ "mouth" ] } ] }, { "id": "mask_filter", @@ -1296,16 +1260,14 @@ "material": [ "plastic" ], "symbol": "[", "color": "light_gray", - "covers": [ "mouth" ], - "coverage": 100, - "encumbrance": 20, "warmth": 10, "material_thickness": 2, "environmental_protection": 1, "environmental_protection_with_filter": 7, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "gasfilter_s": 100 } } ], "ammo": "gasfilter_s", - "use_action": [ "GASMASK" ] + "use_action": [ "GASMASK" ], + "armor": [ { "encumbrance": 20, "coverage": 100, "covers": [ "mouth" ] } ] }, { "id": "mask_gas", @@ -1663,11 +1625,8 @@ "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "covers": [ "eyes" ], "warmth": 10, "environmental_protection": 6, - "encumbrance": 40, - "coverage": 100, "material_thickness": 2, "pocket_data": [ { @@ -1686,7 +1645,8 @@ "light_disposable_cell" ] } - ] + ], + "armor": [ { "encumbrance": 40, "coverage": 100, "covers": [ "eyes" ] } ] }, { "id": "goggles_nv_on", @@ -1701,7 +1661,7 @@ "revert_to": "goggles_nv", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "Your %s deactivates.", "target": "goggles_nv" }, "warmth": 25, - "encumbrance": 20 + "armor": [ { "encumbrance": 20, "coverage": 100, "covers": [ "eyes" ] } ] }, { "id": "goggles_ir", @@ -1728,11 +1688,8 @@ "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "covers": [ "eyes" ], "warmth": 10, "environmental_protection": 6, - "encumbrance": 40, - "coverage": 100, "material_thickness": 2, "pocket_data": [ { @@ -1751,7 +1708,8 @@ "light_disposable_cell" ] } - ] + ], + "armor": [ { "encumbrance": 40, "coverage": 100, "covers": [ "eyes" ] } ] }, { "id": "goggles_ir_on", @@ -1764,9 +1722,8 @@ "power_draw": 1000, "revert_to": "goggles_ir", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "Your %s deactivates.", "target": "goggles_ir" }, - "covers": [ "eyes" ], "warmth": 25, - "encumbrance": 20 + "armor": [ { "encumbrance": 20, "coverage": 100, "covers": [ "eyes" ] } ] }, { "id": "wearable_rx12", @@ -1932,11 +1889,10 @@ "to_hit": -3, "revert_to": "folding_poncho", "use_action": [ "PACK_ITEM" ], - "covers": [ "torso", "arm_l", "arm_r" ], "flags": [ "WATERPROOF", "RAINPROOF", "HOOD", "OVERSIZE", "OUTER" ], "environmental_protection": 1, - "coverage": 90, - "material_thickness": 0.1 + "material_thickness": 0.1, + "armor": [ { "coverage": 90, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "type": "TOOL", @@ -1969,13 +1925,17 @@ "to_hit": -3, "revert_to": "emer_blanket", "use_action": [ "PACK_ITEM" ], - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], "flags": [ "OVERSIZE", "OUTER", "ALLOWS_NATURAL_ATTACKS" ], "warmth": 50, "environmental_protection": 1, - "encumbrance": 50, - "coverage": 90, - "material_thickness": 0.1 + "material_thickness": 0.1, + "armor": [ + { + "encumbrance": 50, + "coverage": 90, + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] }, { "id": "rad_monitor", @@ -1994,9 +1954,7 @@ "charges_per_use": 1, "ammo": "battery", "use_action": [ "RADGLOVE" ], - "covers": [ "hand_l", "hand_r" ], "sided": true, - "coverage": 5, "material_thickness": 0.1, "flags": [ "BELTED", "FRAGILE", "ALLOWS_NATURAL_ATTACKS", "WATER_FRIENDLY", "OVERSIZE" ], "pocket_data": [ @@ -2008,7 +1966,8 @@ "max_contains_weight": "20 kg", "item_restriction": [ "light_minus_battery_cell", "light_minus_atomic_battery_cell", "light_minus_disposable_cell" ] } - ] + ], + "armor": [ { "coverage": 5, "covers": [ "hand_l", "hand_r" ] } ] }, { "id": "hairpin", @@ -2053,14 +2012,13 @@ "price": 4500, "price_postapoc": 10, "material": [ "cotton" ], - "covers": [ "torso", "leg_l", "leg_r" ], "weight": "370 g", "volume": "500 ml", "to_hit": -1, "use_action": [ "TOWEL" ], "warmth": 10, - "coverage": 50, - "material_thickness": 0.3 + "material_thickness": 0.3, + "armor": [ { "coverage": 50, "covers": [ "torso", "leg_l", "leg_r" ] } ] }, { "id": "towel_wet", @@ -2073,15 +2031,14 @@ "price": 2000, "price_postapoc": 0, "material": [ "cotton" ], - "covers": [ "torso", "leg_l", "leg_r" ], "weight": "400 g", "volume": "500 ml", "to_hit": -1, "revert_to": "towel", "use_action": [ "TOWEL" ], "flags": [ "WET" ], - "coverage": 50, - "material_thickness": 0.3 + "material_thickness": 0.3, + "armor": [ { "coverage": 50, "covers": [ "torso", "leg_l", "leg_r" ] } ] }, { "type": "TOOL_ARMOR", @@ -2090,7 +2047,6 @@ "name": { "str": "straw fedora" }, "weight": "300 g", "color": "light_gray", - "covers": [ "head" ], "use_action": { "menu_text": "Tip", "type": "transform", "target": "straw_fedora", "msg": "You tip your %s." }, "symbol": "[", "description": "Straw fedora hat, comfortable and stylish. Its brim helps keep the sun out of your eyes.", @@ -2100,10 +2056,9 @@ "volume": "1250 ml", "warmth": 5, "environmental_protection": 3, - "encumbrance": 10, - "coverage": 50, "flags": [ "VARSIZE", "SUN_GLASSES" ], - "material_thickness": 1 + "material_thickness": 1, + "armor": [ { "encumbrance": 10, "coverage": 50, "covers": [ "head" ] } ] }, { "id": "patchwork_scarf", @@ -2120,13 +2075,11 @@ "volume": "500 ml", "to_hit": -3, "use_action": { "type": "transform", "msg": "You loosen your %s.", "target": "patchwork_scarf_loose", "menu_text": "Loosen" }, - "covers": [ "mouth" ], "flags": [ "OUTER" ], "warmth": 20, "environmental_protection": 1, - "encumbrance": 3, - "coverage": 85, - "material_thickness": 0.3 + "material_thickness": 0.3, + "armor": [ { "encumbrance": 3, "coverage": 85, "covers": [ "mouth" ] } ] }, { "id": "patchwork_scarf_loose", @@ -2145,13 +2098,11 @@ "to_hit": -3, "revert_to": "patchwork_scarf", "use_action": { "type": "transform", "msg": "You wrap your scarf tighter.", "target": "patchwork_scarf", "menu_text": "Wrap tighter" }, - "covers": [ "mouth" ], "flags": [ "OUTER", "ALLOWS_NATURAL_ATTACKS" ], "warmth": 10, "environmental_protection": 1, - "encumbrance": 2, - "coverage": 45, - "material_thickness": 0.3 + "material_thickness": 0.3, + "armor": [ { "encumbrance": 2, "coverage": 45, "covers": [ "mouth" ] } ] }, { "id": "long_patchwork_scarf", @@ -2168,13 +2119,11 @@ "volume": "1 L", "to_hit": -3, "use_action": { "type": "transform", "msg": "You loosen your %s.", "target": "long_patchwork_scarf_loose", "menu_text": "Loosen" }, - "covers": [ "mouth" ], "flags": [ "OVERSIZE", "POCKETS", "OUTER" ], "warmth": 20, "environmental_protection": 1, - "encumbrance": 3, - "coverage": 85, - "material_thickness": 0.3 + "material_thickness": 0.3, + "armor": [ { "encumbrance": 3, "coverage": 85, "covers": [ "mouth" ] } ] }, { "id": "long_patchwork_scarf_loose", @@ -2198,13 +2147,11 @@ "menu_text": "Wrap tighter" }, "revert_to": "long_patchwork_scarf", - "covers": [ "mouth" ], "flags": [ "OVERSIZE", "POCKETS", "OUTER", "ALLOWS_NATURAL_ATTACKS" ], "warmth": 10, "environmental_protection": 1, - "encumbrance": 2, - "coverage": 45, - "material_thickness": 0.3 + "material_thickness": 0.3, + "armor": [ { "encumbrance": 2, "coverage": 45, "covers": [ "mouth" ] } ] }, { "id": "knit_scarf", @@ -2221,13 +2168,11 @@ "volume": "750 ml", "to_hit": -3, "use_action": { "type": "transform", "msg": "You loosen your %s.", "target": "knit_scarf_loose", "menu_text": "Loosen" }, - "covers": [ "mouth" ], "flags": [ "OUTER" ], "warmth": 30, "environmental_protection": 2, - "encumbrance": 3, - "coverage": 85, - "material_thickness": 1 + "material_thickness": 1, + "armor": [ { "encumbrance": 3, "coverage": 85, "covers": [ "mouth" ] } ] }, { "id": "knit_scarf_loose", @@ -2246,13 +2191,11 @@ "to_hit": -3, "revert_to": "knit_scarf", "use_action": { "type": "transform", "msg": "You wrap your scarf tighter.", "target": "knit_scarf", "menu_text": "Wrap tighter" }, - "covers": [ "mouth" ], "flags": [ "OUTER", "ALLOWS_NATURAL_ATTACKS" ], "warmth": 15, "environmental_protection": 1, - "encumbrance": 2, - "coverage": 45, - "material_thickness": 1 + "material_thickness": 1, + "armor": [ { "encumbrance": 2, "coverage": 45, "covers": [ "mouth" ] } ] }, { "id": "long_knit_scarf", @@ -2269,13 +2212,11 @@ "volume": "1250 ml", "to_hit": -3, "use_action": { "type": "transform", "msg": "You loosen your %s.", "target": "long_knit_scarf_loose", "menu_text": "Loosen" }, - "covers": [ "mouth" ], "flags": [ "OVERSIZE", "POCKETS", "OUTER" ], "warmth": 30, "environmental_protection": 2, - "encumbrance": 3, - "coverage": 85, - "material_thickness": 1 + "material_thickness": 1, + "armor": [ { "encumbrance": 3, "coverage": 85, "covers": [ "mouth" ] } ] }, { "id": "long_knit_scarf_loose", @@ -2294,13 +2235,11 @@ "to_hit": -3, "use_action": { "type": "transform", "msg": "You wrap your scarf tighter.", "target": "long_knit_scarf", "menu_text": "Wrap tighter" }, "revert_to": "long_knit_scarf", - "covers": [ "mouth" ], "flags": [ "OVERSIZE", "POCKETS", "OUTER", "ALLOWS_NATURAL_ATTACKS" ], "warmth": 15, "environmental_protection": 1, - "encumbrance": 2, - "coverage": 45, - "material_thickness": 2 + "material_thickness": 2, + "armor": [ { "encumbrance": 2, "coverage": 45, "covers": [ "mouth" ] } ] }, { "id": "scarf", @@ -2317,13 +2256,11 @@ "volume": "750 ml", "to_hit": -3, "use_action": { "type": "transform", "msg": "You loosen your %s.", "target": "scarf_loose", "menu_text": "Loosen" }, - "covers": [ "mouth" ], "flags": [ "OUTER" ], "warmth": 50, "environmental_protection": 2, - "encumbrance": 3, - "coverage": 85, - "material_thickness": 1 + "material_thickness": 1, + "armor": [ { "encumbrance": 3, "coverage": 85, "covers": [ "mouth" ] } ] }, { "id": "scarf_loose", @@ -2342,13 +2279,11 @@ "to_hit": -3, "revert_to": "scarf", "use_action": { "type": "transform", "msg": "You wrap your scarf a bit tighter.", "target": "scarf", "menu_text": "Wrap tighter" }, - "covers": [ "mouth" ], "flags": [ "OUTER", "ALLOWS_NATURAL_ATTACKS" ], "warmth": 25, "environmental_protection": 1, - "encumbrance": 2, - "coverage": 45, - "material_thickness": 1 + "material_thickness": 1, + "armor": [ { "encumbrance": 2, "coverage": 45, "covers": [ "mouth" ] } ] }, { "id": "scarf_long", @@ -2365,13 +2300,11 @@ "volume": "1250 ml", "to_hit": -3, "use_action": { "type": "transform", "msg": "You loosen your %s.", "target": "scarf_long_loose", "menu_text": "Loosen" }, - "covers": [ "mouth" ], "flags": [ "OVERSIZE", "POCKETS", "OUTER" ], "warmth": 50, "environmental_protection": 2, - "encumbrance": 3, - "coverage": 85, - "material_thickness": 1 + "material_thickness": 1, + "armor": [ { "encumbrance": 3, "coverage": 85, "covers": [ "mouth" ] } ] }, { "id": "scarf_long_loose", @@ -2390,13 +2323,11 @@ "to_hit": -3, "use_action": { "type": "transform", "msg": "You wrap your scarf tighter.", "target": "scarf_long", "menu_text": "Wrap tighter" }, "revert_to": "scarf_long", - "covers": [ "mouth" ], "flags": [ "OVERSIZE", "POCKETS", "OUTER", "ALLOWS_NATURAL_ATTACKS" ], "warmth": 25, "environmental_protection": 1, - "encumbrance": 2, - "coverage": 45, - "material_thickness": 1 + "material_thickness": 1, + "armor": [ { "encumbrance": 2, "coverage": 45, "covers": [ "mouth" ] } ] }, { "id": "scarf_fur", @@ -2413,13 +2344,11 @@ "volume": "1 L", "to_hit": -3, "use_action": { "type": "transform", "msg": "You loosen your %s.", "target": "scarf_fur_loose", "menu_text": "Loosen" }, - "covers": [ "mouth" ], "flags": [ "OUTER" ], "warmth": 70, "environmental_protection": 3, - "encumbrance": 10, - "coverage": 85, - "material_thickness": 2 + "material_thickness": 2, + "armor": [ { "encumbrance": 10, "coverage": 85, "covers": [ "mouth" ] } ] }, { "id": "scarf_fur_loose", @@ -2438,13 +2367,11 @@ "to_hit": -3, "revert_to": "scarf_fur", "use_action": { "type": "transform", "msg": "You wrap your scarf a bit tighter.", "target": "scarf_fur", "menu_text": "Wrap tighter" }, - "covers": [ "mouth" ], "flags": [ "OUTER", "ALLOWS_NATURAL_ATTACKS" ], "warmth": 35, "environmental_protection": 2, - "encumbrance": 10, - "coverage": 45, - "material_thickness": 2 + "material_thickness": 2, + "armor": [ { "encumbrance": 10, "coverage": 45, "covers": [ "mouth" ] } ] }, { "id": "scarf_fur_long", @@ -2461,13 +2388,11 @@ "volume": "2 L", "to_hit": -3, "use_action": { "type": "transform", "msg": "You loosen your %s.", "target": "scarf_fur_long_loose", "menu_text": "Loosen" }, - "covers": [ "mouth" ], "flags": [ "OVERSIZE", "POCKETS", "OUTER" ], "warmth": 70, "environmental_protection": 3, - "encumbrance": 10, - "coverage": 85, - "material_thickness": 2 + "material_thickness": 2, + "armor": [ { "encumbrance": 10, "coverage": 85, "covers": [ "mouth" ] } ] }, { "id": "scarf_fur_long_loose", @@ -2486,12 +2411,11 @@ "to_hit": -3, "use_action": { "type": "transform", "msg": "You wrap your scarf tighter.", "target": "scarf_fur_long", "menu_text": "Wrap tighter" }, "revert_to": "scarf_fur_long", - "covers": [ "mouth" ], "flags": [ "OVERSIZE", "POCKETS", "OUTER", "ALLOWS_NATURAL_ATTACKS" ], "warmth": 35, "environmental_protection": 2, - "coverage": 45, - "material_thickness": 2 + "material_thickness": 2, + "armor": [ { "coverage": 45, "covers": [ "mouth" ] } ] }, { "id": "thermal_outfit", @@ -2517,9 +2441,7 @@ "need_charges": 1, "need_charges_msg": "The %s's batteries are dead." }, - "covers": [ "head", "mouth", "torso", "arm_l", "arm_r", "leg_l", "leg_r", "hand_l", "hand_r", "foot_l", "foot_r" ], "warmth": 10, - "coverage": 100, "material_thickness": 0.1, "pocket_data": [ { @@ -2530,6 +2452,12 @@ "max_contains_weight": "20 kg", "item_restriction": [ "medium_battery_cell", "medium_plus_battery_cell", "medium_atomic_battery_cell", "medium_disposable_cell" ] } + ], + "armor": [ + { + "coverage": 100, + "covers": [ "head", "mouth", "torso", "arm_l", "arm_r", "leg_l", "leg_r", "hand_l", "hand_r", "foot_l", "foot_r" ] + } ] }, { @@ -2543,7 +2471,6 @@ "power_draw": 130000, "revert_to": "thermal_outfit", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "Your %s deactivates.", "target": "thermal_outfit" }, - "covers": [ "head", "mouth", "torso", "arm_l", "arm_r", "leg_l", "leg_r", "hand_l", "hand_r", "foot_l", "foot_r" ], "warmth": 60 }, { @@ -2560,13 +2487,11 @@ "symbol": "[", "looks_like": "sweater", "color": "white", - "covers": [ "torso", "arm_l", "arm_r", "mouth" ], - "coverage": 95, - "encumbrance": 8, "warmth": 35, "material_thickness": 0.5, "use_action": { "target": "turtleneck_rolled", "msg": "You adjust the neck and collar of the turtleneck.", "type": "transform" }, - "flags": [ "VARSIZE", "FANCY", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "VARSIZE", "FANCY", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 8, "coverage": 95, "covers": [ "torso", "arm_l", "arm_r", "mouth" ] } ] }, { "id": "turtleneck_rolled", @@ -2582,13 +2507,11 @@ "symbol": "[", "looks_like": "sweater", "color": "white", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 95, - "encumbrance": 8, "warmth": 35, "material_thickness": 0.5, "use_action": { "target": "turtleneck", "msg": "You adjust the neck and collar of the turtleneck.", "type": "transform" }, - "flags": [ "VARSIZE", "FANCY", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "VARSIZE", "FANCY", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 8, "coverage": 95, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "id": "turtleneck_shirt", @@ -2604,9 +2527,6 @@ "symbol": "[", "looks_like": "sweater", "color": "white", - "covers": [ "torso", "arm_l", "arm_r", "mouth" ], - "coverage": 95, - "encumbrance": 4, "warmth": 20, "material_thickness": 0.5, "use_action": { @@ -2614,7 +2534,8 @@ "msg": "You adjust the neck and collar of the turtleneck shirt.", "type": "transform" }, - "flags": [ "VARSIZE", "FANCY", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "VARSIZE", "FANCY", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 4, "coverage": 95, "covers": [ "torso", "arm_l", "arm_r", "mouth" ] } ] }, { "id": "turtleneck_shirt_rolled", @@ -2630,13 +2551,11 @@ "symbol": "[", "looks_like": "sweater", "color": "white", - "covers": [ "torso", "arm_l", "arm_r" ], - "coverage": 95, - "encumbrance": 4, "warmth": 20, "material_thickness": 0.5, "use_action": { "target": "turtleneck_shirt", "msg": "You adjust the neck and collar of the turtleneck shirt.", "type": "transform" }, - "flags": [ "VARSIZE", "FANCY", "ALLOWS_NATURAL_ATTACKS" ] + "flags": [ "VARSIZE", "FANCY", "ALLOWS_NATURAL_ATTACKS" ], + "armor": [ { "encumbrance": 4, "coverage": 95, "covers": [ "torso", "arm_l", "arm_r" ] } ] }, { "type": "TOOL_ARMOR", @@ -2645,7 +2564,6 @@ "category": "clothing", "weight": "86 g", "color": "dark_gray", - "covers": [ "head", "mouth" ], "use_action": { "type": "transform", "menu_text": "Loosen", @@ -2659,10 +2577,9 @@ "material": [ "wool" ], "volume": "250 ml", "warmth": 50, - "encumbrance": 10, "flags": [ "VARSIZE", "SKINTIGHT" ], - "coverage": 80, - "material_thickness": 1 + "material_thickness": 1, + "armor": [ { "encumbrance": 10, "coverage": 80, "covers": [ "head", "mouth" ] } ] }, { "type": "TOOL_ARMOR", @@ -2672,7 +2589,6 @@ "category": "clothing", "weight": "86 g", "color": "dark_gray", - "covers": [ "head", "mouth" ], "use_action": { "type": "transform", "menu_text": "Tighten", @@ -2687,10 +2603,9 @@ "material": [ "wool" ], "volume": "250 ml", "warmth": 30, - "encumbrance": 10, "flags": [ "VARSIZE", "SKINTIGHT" ], - "coverage": 60, - "material_thickness": 1 + "material_thickness": 1, + "armor": [ { "encumbrance": 10, "coverage": 60, "covers": [ "head", "mouth" ] } ] }, { "type": "TOOL_ARMOR", @@ -2705,7 +2620,6 @@ "price_postapoc": 50, "material": [ "steel", "cotton" ], "flags": [ "WATER_FRIENDLY" ], - "coverage": 1, "symbol": "[", "use_action": { "type": "manualnoise", @@ -2717,7 +2631,8 @@ "noise_variant": "whistle", "noise": 38, "moves": 100 - } + }, + "armor": [ { "coverage": 1 } ] }, { "id": "powered_earmuffs", @@ -2743,10 +2658,7 @@ "need_charges": 1, "need_charges_msg": "The earmuff's batteries are dead." }, - "covers": [ "head" ], "warmth": 5, - "encumbrance": 5, - "coverage": 10, "material_thickness": 2, "pocket_data": [ { @@ -2765,7 +2677,8 @@ "light_disposable_cell" ] } - ] + ], + "armor": [ { "encumbrance": 5, "coverage": 10, "covers": [ "head" ] } ] }, { "id": "powered_earmuffs_on", @@ -2788,10 +2701,7 @@ "charges_per_use": 1, "revert_to": "powered_earmuffs", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "The %s flicks off.", "target": "powered_earmuffs" }, - "covers": [ "head" ], "warmth": 5, - "encumbrance": 5, - "coverage": 10, "material_thickness": 2, "pocket_data": [ { @@ -2810,7 +2720,8 @@ "light_disposable_cell" ] } - ] + ], + "armor": [ { "encumbrance": 5, "coverage": 10, "covers": [ "head" ] } ] }, { "id": "stethoscope", @@ -2824,10 +2735,8 @@ "material": [ "plastic", "aluminum" ], "weight": "150 g", "volume": "250 ml", - "covers": [ "torso" ], - "encumbrance": 1, "flags": [ "BELTED", "SAFECRACK" ], - "coverage": 5 + "armor": [ { "encumbrance": 1, "coverage": 5, "covers": [ "torso" ] } ] }, { "id": "makeshift_stethoscope", @@ -2841,10 +2750,8 @@ "material": [ "plastic" ], "weight": "400 g", "volume": "500 ml", - "covers": [ "torso" ], - "encumbrance": 3, "flags": [ "BELTED", "SAFECRACK" ], - "coverage": 8 + "armor": [ { "encumbrance": 3, "coverage": 8, "covers": [ "torso" ] } ] }, { "id": "solarpack", @@ -2860,12 +2767,10 @@ "material": [ "glass", "steel" ], "symbol": "[", "color": "light_gray", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 12, "material_thickness": 3, "use_action": [ "SOLARPACK" ], - "flags": [ "FRAGILE", "OUTER", "ONLY_ONE", "SOLARPACK" ] + "flags": [ "FRAGILE", "OUTER", "ONLY_ONE", "SOLARPACK" ], + "armor": [ { "encumbrance": 12, "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "solarpack_on", @@ -2882,13 +2787,11 @@ "material": [ "glass", "steel" ], "symbol": "[", "color": "blue", - "covers": [ "torso" ], - "coverage": 40, - "encumbrance": 20, "material_thickness": 1, "use_action": [ "SOLARPACK_OFF" ], "solar_efficiency": 0.05, - "flags": [ "FRAGILE", "OUTER", "ONLY_ONE", "SOLARPACK_ON" ] + "flags": [ "FRAGILE", "OUTER", "ONLY_ONE", "SOLARPACK_ON" ], + "armor": [ { "encumbrance": 20, "coverage": 40, "covers": [ "torso" ] } ] }, { "id": "helmet_riot", @@ -2907,14 +2810,12 @@ "material": [ "plastic", "steel" ], "symbol": "[", "color": "dark_gray", - "covers": [ "head", "eyes", "mouth" ], - "coverage": 95, - "encumbrance": 20, "warmth": 10, "material_thickness": 3, "environmental_protection": 2, "techniques": [ "WBLOCK_1" ], - "flags": [ "WATERPROOF", "STURDY", "SUN_GLASSES" ] + "flags": [ "WATERPROOF", "STURDY", "SUN_GLASSES" ], + "armor": [ { "encumbrance": 20, "coverage": 95, "covers": [ "head", "eyes", "mouth" ] } ] }, { "id": "helmet_riot_raised", @@ -2933,14 +2834,12 @@ "material": [ "plastic", "steel" ], "symbol": "[", "color": "dark_gray", - "covers": [ "head" ], - "coverage": 95, - "encumbrance": 20, "warmth": 10, "material_thickness": 3, "environmental_protection": 2, "techniques": [ "WBLOCK_1" ], - "flags": [ "WATERPROOF", "STURDY" ] + "flags": [ "WATERPROOF", "STURDY" ], + "armor": [ { "encumbrance": 20, "coverage": 95, "covers": [ "head" ] } ] }, { "id": "scuba_tank", @@ -2962,14 +2861,12 @@ "pocket_data": [ { "pocket_type": "MAGAZINE", "airtight": true, "rigid": true, "watertight": true, "ammo_restriction": { "nitrox": 60 } } ], - "covers": [ "torso" ], "flags": [ "WATER_FRIENDLY", "BELTED", "ONLY_ONE", "STURDY", "NO_UNLOAD", "NO_RELOAD" ], "environmental_protection": 1, "environmental_protection_with_filter": 16, - "encumbrance": 30, - "coverage": 25, "material_thickness": 4, - "use_action": [ "DIVE_TANK" ] + "use_action": [ "DIVE_TANK" ], + "armor": [ { "encumbrance": 30, "coverage": 25, "covers": [ "torso" ] } ] }, { "id": "scuba_tank_on", @@ -2994,14 +2891,12 @@ ], "charges_per_use": 1, "turns_per_charge": 60, - "covers": [ "torso", "mouth" ], "flags": [ "WATER_FRIENDLY", "BELTED", "ONLY_ONE", "STURDY", "NO_UNLOAD", "NO_RELOAD" ], "environmental_protection": 1, "environmental_protection_with_filter": 16, - "encumbrance": 30, - "coverage": 25, "material_thickness": 4, - "use_action": [ "DIVE_TANK" ] + "use_action": [ "DIVE_TANK" ], + "armor": [ { "encumbrance": 30, "coverage": 25, "covers": [ "torso", "mouth" ] } ] }, { "id": "small_scuba_tank", @@ -3023,14 +2918,12 @@ "pocket_data": [ { "pocket_type": "MAGAZINE", "airtight": true, "rigid": true, "watertight": true, "ammo_restriction": { "nitrox": 20 } } ], - "covers": [ "torso" ], "flags": [ "WATER_FRIENDLY", "BELTED", "ONLY_ONE", "STURDY", "NO_UNLOAD", "NO_RELOAD" ], "environmental_protection": 1, "environmental_protection_with_filter": 16, - "encumbrance": 30, - "coverage": 25, "material_thickness": 4, - "use_action": [ "DIVE_TANK" ] + "use_action": [ "DIVE_TANK" ], + "armor": [ { "encumbrance": 30, "coverage": 25, "covers": [ "torso" ] } ] }, { "id": "small_scuba_tank_on", @@ -3055,14 +2948,12 @@ ], "charges_per_use": 1, "turns_per_charge": 60, - "covers": [ "torso", "mouth" ], "flags": [ "WATER_FRIENDLY", "BELTED", "ONLY_ONE", "STURDY", "NO_UNLOAD", "NO_RELOAD" ], "environmental_protection": 1, "environmental_protection_with_filter": 16, - "encumbrance": 30, - "coverage": 25, "material_thickness": 4, - "use_action": [ "DIVE_TANK" ] + "use_action": [ "DIVE_TANK" ], + "armor": [ { "encumbrance": 30, "coverage": 25, "covers": [ "torso", "mouth" ] } ] }, { "id": "electric_blanket", @@ -3077,9 +2968,6 @@ "material": [ "cotton" ], "symbol": "[", "color": "brown", - "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ], - "coverage": 100, - "encumbrance": 35, "warmth": 50, "material_thickness": 1, "environmental_protection": 1, @@ -3103,6 +2991,13 @@ "max_contains_weight": "20 kg", "item_restriction": [ "medium_battery_cell", "medium_plus_battery_cell", "medium_atomic_battery_cell", "medium_disposable_cell" ] } + ], + "armor": [ + { + "encumbrance": 35, + "coverage": 100, + "covers": [ "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } ] }, { @@ -3131,9 +3026,6 @@ "material": [ "cotton", "plastic" ], "symbol": "Q", "color": "pink", - "covers": [ "head", "eyes", "mouth" ], - "coverage": 100, - "encumbrance": 30, "warmth": 50, "material_thickness": 1, "environmental_protection": 2, @@ -3158,7 +3050,8 @@ "max_contains_weight": "20 kg", "item_restriction": [ "medium_battery_cell", "medium_plus_battery_cell", "medium_atomic_battery_cell", "medium_disposable_cell" ] } - ] + ], + "armor": [ { "encumbrance": 30, "coverage": 100, "covers": [ "head", "eyes", "mouth" ] } ] }, { "id": "foodperson_mask_on", diff --git a/data/json/obsolete.json b/data/json/obsolete.json index 90fd10d28dc38..b48c2ae8ed950 100644 --- a/data/json/obsolete.json +++ b/data/json/obsolete.json @@ -119,7 +119,6 @@ "name": { "str": "survivor utility belt" }, "weight": "3390 g", "color": "brown", - "covers": [ "torso" ], "symbol": "[", "description": "A custom-built leather utility belt covered with straps and pouches containing many useful hand tools and a sheath to carry a smaller blade. Durable and carefully crafted to be comfortable to wear. Activate to sheathe/draw a weapon.", "price": 50000, @@ -127,8 +126,6 @@ "material": [ "leather", "iron" ], "volume": "4 L", "flags": [ "VARSIZE", "WATER_FRIENDLY", "STURDY", "WAIST", "OVERSIZE" ], - "coverage": 15, - "encumbrance": 4, "material_thickness": 2, "pocket_data": [ { @@ -154,7 +151,8 @@ [ "SAW_M_FINE", 1 ], [ "WRENCH_FINE", 1 ], [ "SCREW_FINE", 1 ] - ] + ], + "armor": [ { "encumbrance": 4, "coverage": 15, "covers": [ "torso" ] } ] }, { "id": "combination_gun_shotgun_pipe", From 76612800d24a1b06fe49b7dcd93f94247ed75beb Mon Sep 17 00:00:00 2001 From: NotFuji <38316883+NotFuji@users.noreply.github.com> Date: Wed, 7 Jul 2021 01:27:21 -0500 Subject: [PATCH 040/116] Remove city horde spawning (#49279) --- src/overmap.cpp | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/overmap.cpp b/src/overmap.cpp index 8014b33cc6528..df96a3d751909 100644 --- a/src/overmap.cpp +++ b/src/overmap.cpp @@ -4348,22 +4348,6 @@ void overmap::place_specials( overmap_special_batch &enabled_specials ) void overmap::place_mongroups() { - // Cities are full of zombies - for( city &elem : cities ) { - if( get_option( "WANDER_SPAWNS" ) ) { - if( !one_in( 16 ) || elem.size > 5 ) { - mongroup m( GROUP_ZOMBIE, - tripoint_om_sm( project_to( elem.pos ), 0 ), - static_cast( elem.size * 2.5 ), - elem.size * 80 ); - // m.set_target( zg.back().posx, zg.back().posy ); - m.horde = true; - m.wander( *this ); - add_mon_group( m ); - } - } - } - if( get_option( "DISABLE_ANIMAL_CLASH" ) ) { // Figure out where swamps are, and place swamp monsters for( int x = 3; x < OMAPX - 3; x += 7 ) { From 061b97fbd291be7880b762b8f99938268cec25c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro?= Date: Wed, 7 Jul 2021 09:45:38 +0200 Subject: [PATCH 041/116] Jsonize cbm trigger costs (#49635) * Jsonize & display CBM trigger costs * astyle * Remove unused variable --- data/json/bionics.json | 30 ++++++++++++++++++++++-------- src/bionics.cpp | 6 ++++-- src/bionics.h | 2 ++ src/bionics_ui.cpp | 4 ++++ src/character.cpp | 24 ++++++++++++++---------- src/game.cpp | 33 ++++++++++++++++++--------------- src/iuse.cpp | 5 +++-- src/melee.cpp | 11 +++++++---- src/monattack.cpp | 5 +++-- src/suffer.cpp | 23 +++++++++++++---------- 10 files changed, 90 insertions(+), 53 deletions(-) diff --git a/data/json/bionics.json b/data/json/bionics.json index 957a19ced61dc..9ac153cf53327 100644 --- a/data/json/bionics.json +++ b/data/json/bionics.json @@ -16,6 +16,7 @@ "flags": [ "BIONIC_TOGGLED", "BIONIC_NPC_USABLE" ], "act_cost": 10, "react_cost": 10, + "trigger_cost": "25kJ", "time": 1 }, { @@ -27,6 +28,7 @@ "flags": [ "BIONIC_TOGGLED", "BIONIC_SLEEP_FRIENDLY" ], "act_cost": "1 J", "react_cost": "1 J", + "trigger_cost": "25 kJ", "time": 1 }, { @@ -620,7 +622,8 @@ "name": { "str": "Electrical Discharge" }, "description": "A malfunctioning bionic which occasionally discharges electricity through your body, causing pain and brief paralysis but no damage.", "occupied_bodyparts": [ [ "torso", 6 ] ], - "flags": [ "BIONIC_FAULTY" ] + "flags": [ "BIONIC_FAULTY" ], + "trigger_cost": "10 kJ" }, { "id": "bio_drain", @@ -804,7 +807,8 @@ "type": "bionic", "name": { "str": "Glowy Thing" }, "description": "You don't think that capacitor is *meant* to glow, but it does, and usually at bad times. A malfunctioning bionic randomly turns on and off, causing you to glow and making you visible in the dark without improving how much you can see in the slightest.", - "flags": [ "BIONIC_FAULTY" ] + "flags": [ "BIONIC_FAULTY" ], + "trigger_cost": "1 kJ" }, { "id": "bio_geiger", @@ -820,7 +824,8 @@ "name": { "str": "Respirator" }, "description": "A complex respiration augmentation system. Improves respiration ability in air and allows breathing water. Will automatically turn on when drowning. Turn on to recharge stamina faster, at moderate power cost. Asthmatics may also use it to stop asthma attacks.", "occupied_bodyparts": [ [ "torso", 8 ], [ "head", 2 ], [ "mouth", 2 ] ], - "flags": [ "BIONIC_TOGGLED" ] + "flags": [ "BIONIC_TOGGLED" ], + "trigger_cost": "25 kJ" }, { "id": "bio_ground_sonar", @@ -850,7 +855,8 @@ [ "foot_l", 2 ], [ "foot_r", 2 ] ], - "flags": [ "BIONIC_TOGGLED", "BIONIC_NPC_USABLE" ] + "flags": [ "BIONIC_TOGGLED", "BIONIC_NPC_USABLE" ], + "trigger_cost": "3 kJ" }, { "id": "bio_heatsink", @@ -986,6 +992,7 @@ "flags": [ "BIONIC_TOGGLED", "BIONIC_SLEEP_FRIENDLY" ], "act_cost": "2 J", "react_cost": "2 J", + "trigger_cost": "25 J", "time": 1 }, { @@ -1074,6 +1081,7 @@ "flags": [ "BIONIC_TOGGLED", "BIONIC_NPC_USABLE" ], "act_cost": "10 kJ", "react_cost": "10 kJ", + "trigger_cost": "1 kJ", "time": 1 }, { @@ -1082,7 +1090,8 @@ "name": { "str": "Sensory Dulling" }, "description": "Your nervous system is wired to allow you to inhibit the signals of pain, allowing you to dull your senses at will. However, the use of this system may cause delayed reaction time and drowsiness.", "occupied_bodyparts": [ [ "head", 2 ] ], - "flags": [ "BIONIC_TOGGLED", "BIONIC_NPC_USABLE" ] + "flags": [ "BIONIC_TOGGLED", "BIONIC_NPC_USABLE" ], + "trigger_cost": "2 kJ" }, { "id": "bio_pokedeye", @@ -1146,6 +1155,7 @@ "flags": [ "BIONIC_TOGGLED" ], "act_cost": "3 J", "react_cost": "3 J", + "trigger_cost": "250 kJ", "time": 1 }, { @@ -1240,7 +1250,8 @@ "name": { "str": "Bionic Short Circuit" }, "description": "A poorly-wired bionic which fails to serve its intended purpose, this malfunctioning device periodically short-circuits, causing systemic muscle tremors.", "occupied_bodyparts": [ [ "torso", 1 ], [ "arm_l", 2 ], [ "arm_r", 2 ], [ "leg_l", 3 ], [ "leg_r", 3 ] ], - "flags": [ "BIONIC_FAULTY" ] + "flags": [ "BIONIC_FAULTY" ], + "trigger_cost": "25 kJ" }, { "id": "bio_synaptic_regen", @@ -1260,7 +1271,8 @@ "name": { "str": "Electroshock Unit" }, "description": "While fighting unarmed, or with a weapon that conducts electricity, there is a chance that a successful hit will shock your opponent, inflicting extra damage and disabling them temporarily at the cost of some energy.", "occupied_bodyparts": [ [ "torso", 8 ], [ "arm_l", 3 ], [ "arm_r", 3 ], [ "hand_l", 1 ], [ "hand_r", 1 ] ], - "flags": [ "BIONIC_TOGGLED", "BIONIC_NPC_USABLE" ] + "flags": [ "BIONIC_TOGGLED", "BIONIC_NPC_USABLE" ], + "trigger_cost": "2 kJ" }, { "id": "bio_shockwave", @@ -1430,7 +1442,8 @@ "description": "Your leg joints have been equipped with servomotors that provide power-assisted movement. They are optimized for running, but walking also requires less effort when this bionic is online. However, when it's offline it will hamper your movement, as you struggle against its moving parts.", "occupied_bodyparts": [ [ "leg_l", 12 ], [ "leg_r", 12 ] ], "flags": [ "BIONIC_TOGGLED" ], - "mutation_conflicts": [ "LEG_TENTACLES", "LEG_TENT_BRACE" ] + "mutation_conflicts": [ "LEG_TENTACLES", "LEG_TENT_BRACE" ], + "trigger_cost": "35 J" }, { "id": "bio_trip", @@ -1449,6 +1462,7 @@ "flags": [ "BIONIC_TOGGLED" ], "act_cost": "6 J", "react_cost": "6 J", + "trigger_cost": "75 kJ", "time": 1 }, { diff --git a/src/bionics.cpp b/src/bionics.cpp index c53da94026df3..b4af1beb94f80 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -293,6 +293,7 @@ void bionic_data::load( const JsonObject &jsobj, const std::string & ) assign( jsobj, "weight_capacity_bonus", weight_capacity_bonus, false ); assign( jsobj, "act_cost", power_activate, false, 0_kJ ); assign( jsobj, "deact_cost", power_deactivate, false, 0_kJ ); + assign( jsobj, "trigger_cost", power_trigger, false, 0_kJ ); optional( jsobj, was_loaded, "time", charge_time, 0 ); @@ -1724,10 +1725,11 @@ void Character::process_bionic( const int b ) } else if( bio.id == bio_painkiller ) { const int pkill = get_painkiller(); const int pain = get_pain(); + const units::energy trigger_cost = bio.info().power_trigger; int max_pkill = std::min( 150, pain ); if( pkill < max_pkill ) { mod_painkiller( 1 ); - mod_power_level( -2_kJ ); + mod_power_level( -trigger_cost ); } // Only dull pain so extreme that we can't pkill it safely @@ -1735,7 +1737,7 @@ void Character::process_bionic( const int b ) mod_pain( -1 ); // Negative side effect: negative stim mod_stim( -1 ); - mod_power_level( -2_kJ ); + mod_power_level( -trigger_cost ); } } else if( bio.id == bio_gills ) { if( has_effect( effect_asthma ) ) { diff --git a/src/bionics.h b/src/bionics.h index e059a913fd769..a6da18701cc45 100644 --- a/src/bionics.h +++ b/src/bionics.h @@ -41,6 +41,8 @@ struct bionic_data { units::energy power_deactivate = 0_kJ; /** Power cost over time, does nothing without a non-zero charge_time */ units::energy power_over_time = 0_kJ; + /** Power cost when the bionic's special effect is triggered */ + units::energy power_trigger = 0_kJ; /** How often a bionic draws or produces power while active in turns */ int charge_time = 0; /** Power bank size **/ diff --git a/src/bionics_ui.cpp b/src/bionics_ui.cpp index 96c6b08f17428..ce7835e5aa08c 100644 --- a/src/bionics_ui.cpp +++ b/src/bionics_ui.cpp @@ -307,6 +307,10 @@ static std::string build_bionic_poweronly_string( const bionic &bio ) properties.push_back( string_format( _( "%s deact" ), units::display( bio_data.power_deactivate ) ) ); } + if( bio_data.power_trigger > 0_kJ ) { + properties.push_back( string_format( _( "%s trigger" ), + units::display( bio_data.power_trigger ) ) ); + } if( bio_data.charge_time > 0 && bio_data.power_over_time > 0_kJ ) { properties.push_back( bio_data.charge_time == 1 ? string_format( _( "%s/turn" ), units::display( bio_data.power_over_time ) ) diff --git a/src/character.cpp b/src/character.cpp index 98adfc776b085..6d3562f4e0626 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -1429,13 +1429,15 @@ float Character::get_melee() const bool Character::uncanny_dodge() { - bool is_u = is_avatar(); bool seen = get_player_view().sees( *this ); - const bool can_dodge_bio = get_power_level() >= 75_kJ && has_active_bionic( bio_uncanny_dodge ); + const units::energy trigger_cost = bio_uncanny_dodge->power_trigger; + + const bool can_dodge_bio = get_power_level() >= trigger_cost && + has_active_bionic( bio_uncanny_dodge ); const bool can_dodge_mut = get_stamina() >= 300 && has_trait_flag( json_flag_UNCANNY_DODGE ); - const bool can_dodge_both = get_power_level() >= 37500_J && + const bool can_dodge_both = get_power_level() >= ( trigger_cost / 2 ) && has_active_bionic( bio_uncanny_dodge ) && get_stamina() >= 150 && has_trait_flag( json_flag_UNCANNY_DODGE ); @@ -1445,10 +1447,10 @@ bool Character::uncanny_dodge() tripoint adjacent = adjacent_tile(); if( can_dodge_both ) { - mod_power_level( -37500_J ); + mod_power_level( -trigger_cost / 2 ); mod_stamina( -150 ); } else if( can_dodge_bio ) { - mod_power_level( -75_kJ ); + mod_power_level( -trigger_cost ); } else if( can_dodge_mut ) { mod_stamina( -300 ); } @@ -4343,12 +4345,13 @@ void Character::do_skill_rust() continue; } - const bool charged_bio_mem = get_power_level() > 25_J && has_active_bionic( bio_memory ); + const bool charged_bio_mem = get_power_level() > bio_memory->power_trigger && + has_active_bionic( bio_memory ); const int oldSkillLevel = skill_level_obj.level(); if( skill_level_obj.rust( charged_bio_mem, rust_rate_tmp ) ) { add_msg_if_player( m_warning, _( "Your knowledge of %s begins to fade, but your memory banks retain it!" ), aSkill.name() ); - mod_power_level( -25_J ); + mod_power_level( -bio_memory->power_trigger ); } const int newSkill = skill_level_obj.level(); if( newSkill < oldSkillLevel ) { @@ -9586,7 +9589,7 @@ void Character::absorb_hit( const bodypart_id &bp, damage_instance &dam ) } else if( elem.type == damage_type::STAB || elem.type == damage_type::BULLET ) { elem.amount -= rng( 1, 8 ); } - mod_power_level( -25_kJ ); + mod_power_level( -bio_ads->power_trigger ); } if( elem.amount < 0 ) { elem.amount = 0; @@ -9884,7 +9887,8 @@ void Character::on_hit( Creature *source, bodypart_id bp_hit, } bool u_see = get_player_view().sees( *this ); - if( has_active_bionic( bionic_id( "bio_ods" ) ) && get_power_level() > 5_kJ ) { + const units::energy trigger_cost_base = bionic_id( "bio_ods" )->power_trigger; + if( has_active_bionic( bionic_id( "bio_ods" ) ) && get_power_level() > ( 5 * trigger_cost_base ) ) { if( is_player() ) { add_msg( m_good, _( "Your offensive defense system shocks %s in mid-attack!" ), source->disp_name() ); @@ -9894,7 +9898,7 @@ void Character::on_hit( Creature *source, bodypart_id bp_hit, source->disp_name() ); } int shock = rng( 1, 4 ); - mod_power_level( units::from_kilojoule( -shock ) ); + mod_power_level( -shock * trigger_cost_base ); damage_instance ods_shock_damage; ods_shock_damage.add_damage( damage_type::ELECTRIC, shock * 5 ); // Should hit body part used for attack diff --git a/src/game.cpp b/src/game.cpp index e7456a56cd51b..25a6e593a9206 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -4635,12 +4635,13 @@ void game::monmove() m.creature_in_field( critter ); } + const bionic_id bio_alarm( "bio_alarm" ); if( !critter.is_dead() && - u.has_active_bionic( bionic_id( "bio_alarm" ) ) && - u.get_power_level() >= 25_kJ && + u.has_active_bionic( bio_alarm ) && + u.get_power_level() >= bio_alarm->power_trigger && rl_dist( u.pos(), critter.pos() ) <= 5 && !critter.is_hallucination() ) { - u.mod_power_level( -25_kJ ); + u.mod_power_level( -bio_alarm->power_trigger ); add_msg( m_warning, _( "Your motion alarm goes off!" ) ); cancel_activity_or_ignore_query( distraction_type::motion_alarm, _( "Your motion alarm goes off!" ) ); @@ -10324,8 +10325,11 @@ void game::place_player_overmap( const tripoint_abs_omt &om_dest ) bool game::phasing_move( const tripoint &dest_loc, const bool via_ramp ) { - if( !u.has_active_bionic( bionic_id( "bio_probability_travel" ) ) || - u.get_power_level() < 250_kJ ) { + const bionic_id bio_probability_travel( "bio_probability_travel" ); + const units::energy trigger_cost = bio_probability_travel->power_trigger; + + if( !u.has_active_bionic( bio_probability_travel ) || + u.get_power_level() < trigger_cost ) { return false; } @@ -10347,19 +10351,18 @@ bool game::phasing_move( const tripoint &dest_loc, const bool via_ramp ) if( u.worn_with_flag( flag_DIMENSIONAL_ANCHOR ) || u.has_flag( flag_DIMENSIONAL_ANCHOR ) ) { u.add_msg_if_player( m_info, _( "You are repelled by the barrier!" ) ); - u.mod_power_level( -250_kJ ); //cost of tunneling one tile. + u.mod_power_level( -trigger_cost ); //cost of tunneling one tile. return false; } - if( tunneldist * 250_kJ > + if( tunneldist * trigger_cost > u.get_power_level() ) { //oops, not enough energy! Tunneling costs 250 bionic power per impassable tile add_msg( _( "You try to quantum tunnel through the barrier but are reflected! Try again with more energy!" ) ); - u.mod_power_level( -250_kJ ); + u.mod_power_level( -trigger_cost ); return false; } - if( tunneldist > 24 ) { add_msg( m_info, _( "It's too dangerous to tunnel that far!" ) ); - u.mod_power_level( -250_kJ ); + u.mod_power_level( -trigger_cost ); return false; } @@ -10374,7 +10377,7 @@ bool game::phasing_move( const tripoint &dest_loc, const bool via_ramp ) add_msg( _( "You quantum tunnel through the %d-tile wide barrier!" ), tunneldist ); //tunneling costs 250 bionic power per impassable tile - u.mod_power_level( -( tunneldist * 250_kJ ) ); + u.mod_power_level( -( tunneldist * trigger_cost ) ); u.moves -= 100; //tunneling costs 100 moves u.setpos( dest ); @@ -10687,12 +10690,12 @@ void game::on_move_effects() u.mod_power_level( units::from_kilojoule( muscle.fuel_energy() ) * bid->passive_fuel_efficiency ); } } - - if( u.has_active_bionic( bionic_id( "bio_jointservo" ) ) ) { + const bionic_id bio_jointservo( "bio_jointservo" ); + if( u.has_active_bionic( bio_jointservo ) ) { if( u.is_running() ) { - u.mod_power_level( -55_J ); + u.mod_power_level( -bio_jointservo->power_trigger * 1.55 ); } else { - u.mod_power_level( -35_J ); + u.mod_power_level( -bio_jointservo->power_trigger ); } } } diff --git a/src/iuse.cpp b/src/iuse.cpp index cf1367c264456..e79092c6a6a8e 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -23,6 +23,7 @@ #include "activity_actor_definitions.h" #include "activity_type.h" #include "avatar.h" +#include "bionics.h" #include "bodypart.h" #include "calendar.h" #include "cata_utility.h" @@ -7774,9 +7775,9 @@ cata::optional iuse::ehandcuffs( player *p, item *it, bool t, const tripoin } if( p->has_item( *it ) ) { - if( p->has_active_bionic( bio_shock ) && p->get_power_level() >= 2_kJ && + if( p->has_active_bionic( bio_shock ) && p->get_power_level() >= bio_shock->power_trigger && one_in( 5 ) ) { - p->mod_power_level( -2_kJ ); + p->mod_power_level( -bio_shock->power_trigger ); it->unset_flag( flag_NO_UNWIELD ); it->ammo_unset(); diff --git a/src/melee.cpp b/src/melee.cpp index 41fb37fae7603..bd0d1b95288f3 100644 --- a/src/melee.cpp +++ b/src/melee.cpp @@ -17,6 +17,7 @@ #include "avatar.h" #include "bodypart.h" +#include "bionics.h" #include "cached_options.h" #include "calendar.h" #include "cata_utility.h" @@ -2018,9 +2019,10 @@ std::string Character::melee_special_effects( Creature &t, damage_instance &d, i std::string target = t.disp_name(); - if( has_active_bionic( bionic_id( "bio_shock" ) ) && get_power_level() >= 2_kJ && + const bionic_id bio_shock( "bio_shock" ); + if( has_active_bionic( bio_shock ) && get_power_level() >= bio_shock->power_trigger && ( !is_armed() || weapon.conductive() ) ) { - mod_power_level( -2_kJ ); + mod_power_level( -bio_shock->power_trigger ); d.add_damage( damage_type::ELECTRIC, rng( 2, 10 ) ); if( is_player() ) { @@ -2030,8 +2032,9 @@ std::string Character::melee_special_effects( Creature &t, damage_instance &d, i } } - if( has_active_bionic( bionic_id( "bio_heat_absorb" ) ) && !is_armed() && t.is_warm() ) { - mod_power_level( 3_kJ ); + const bionic_id bio_heat_absorb( "bio_heat_absorb" ); + if( has_active_bionic( bio_heat_absorb ) && !is_armed() && t.is_warm() ) { + mod_power_level( bio_heat_absorb->power_trigger ); d.add_damage( damage_type::COLD, 3 ); if( is_player() ) { dump += string_format( _( "You drain %s's body heat." ), target ) + "\n"; diff --git a/src/monattack.cpp b/src/monattack.cpp index 35028297ac63f..4ea0deadcfa07 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -18,6 +18,7 @@ #include "activity_type.h" #include "ballistics.h" +#include "bionics.h" #include "bodypart.h" #include "calendar.h" #include "cata_assert.h" @@ -4772,7 +4773,7 @@ bool mattack::riotbot( monster *z ) handcuffs.set_var( "HANDCUFFS_Y", foe->posy() ); const bool is_uncanny = foe->has_active_bionic( bio_uncanny_dodge ) && - foe->get_power_level() > 74_kJ && + foe->get_power_level() > bio_uncanny_dodge.obj().power_trigger && !one_in( 3 ); ///\EFFECT_DEX >13 allows and increases chance to slip out of riot bot handcuffs const bool is_dex = foe->dex_cur > 13 && !one_in( foe->dex_cur - 11 ); @@ -4780,7 +4781,7 @@ bool mattack::riotbot( monster *z ) if( is_uncanny || is_dex ) { if( is_uncanny ) { - foe->mod_power_level( -75_kJ ); + foe->mod_power_level( -bio_uncanny_dodge->power_trigger ); } add_msg( m_good, diff --git a/src/suffer.cpp b/src/suffer.cpp index 009baadf566a1..aed3d0b979d63 100644 --- a/src/suffer.cpp +++ b/src/suffer.cpp @@ -14,6 +14,7 @@ #include "activity_handlers.h" #include "addiction.h" +#include "bionics.h" #include "bodypart.h" #include "calendar.h" #include "cata_utility.h" @@ -247,9 +248,9 @@ void Character::suffer_while_underwater() oxygen += 12; } if( oxygen <= 5 ) { - if( has_bionic( bio_gills ) && get_power_level() >= 25_kJ ) { + if( has_bionic( bio_gills ) && get_power_level() >= bio_gills->power_trigger ) { oxygen += 5; - mod_power_level( -25_kJ ); + mod_power_level( -bio_gills->power_trigger ); } else { add_msg_if_player( m_bad, _( "You're drowning!" ) ); apply_damage( nullptr, bodypart_id( "torso" ), rng( 1, 4 ) ); @@ -615,7 +616,7 @@ void Character::suffer_from_asthma( const int current_stim ) } bool auto_use = has_charges( itype_inhaler, 1 ) || has_charges( itype_oxygen_tank, 1 ) || has_charges( itype_smoxygen_tank, 1 ); - bool oxygenator = has_bionic( bio_gills ) && get_power_level() >= 3_kJ; + bool oxygenator = has_bionic( bio_gills ) && get_power_level() >= ( bio_gills->power_trigger / 8 ); if( underwater ) { oxygen = oxygen / 2; auto_use = false; @@ -635,7 +636,7 @@ void Character::suffer_from_asthma( const int current_stim ) map_inv.has_charges( itype_smoxygen_tank, 1 ); // check if character has an oxygenator first if( oxygenator ) { - mod_power_level( -3_kJ ); + mod_power_level( -bio_gills->power_trigger / 8 ); add_msg_if_player( m_info, _( "You use your Oxygenator to clear it up, " "then go back to sleep." ) ); } else if( auto_use ) { @@ -1161,7 +1162,8 @@ void Character::suffer_from_radiation() void Character::suffer_from_bad_bionics() { // Negative bionics effects - if( has_bionic( bio_dis_shock ) && get_power_level() > 9_kJ && one_turn_in( 2_hours ) && + if( has_bionic( bio_dis_shock ) && get_power_level() > bio_dis_shock->power_trigger && + one_turn_in( 2_hours ) && !has_effect( effect_narcosis ) ) { if( !has_trait( trait_NOPAIN ) ) { add_msg_if_player( m_bad, _( "You suffer a painful electrical discharge!" ) ); @@ -1170,7 +1172,7 @@ void Character::suffer_from_bad_bionics() add_msg_if_player( m_bad, _( "You experience an electrical discharge!" ) ); } moves -= 150; - mod_power_level( -10_kJ ); + mod_power_level( -bio_dis_shock->power_trigger ); if( weapon.typeId() == itype_e_handcuffs && weapon.charges > 0 ) { weapon.charges -= rng( 1, 3 ) * 50; @@ -1225,9 +1227,10 @@ void Character::suffer_from_bad_bionics() add_effect( effect_downed, 1_turns, false, 0, true ); sfx::play_variant_sound( "bionics", "elec_crackle_high", 100 ); } - if( has_bionic( bio_shakes ) && get_power_level() > 24_kJ && one_turn_in( 2_hours ) ) { + if( has_bionic( bio_shakes ) && get_power_level() > bio_shakes->power_trigger && + one_turn_in( 2_hours ) ) { add_msg_if_player( m_bad, _( "Your bionics short-circuit, causing you to tremble and shiver." ) ); - mod_power_level( -25_kJ ); + mod_power_level( -bio_shakes->power_trigger ); add_effect( effect_shakes, 5_minutes ); sfx::play_variant_sound( "bionics", "elec_crackle_med", 100 ); } @@ -1244,10 +1247,10 @@ void Character::suffer_from_bad_bionics() add_effect( effect_formication, 10_minutes, bp ); } if( has_bionic( bio_glowy ) && !has_effect( effect_glowy_led ) && one_turn_in( 50_minutes ) && - get_power_level() > 1_kJ ) { + get_power_level() > bio_glowy->power_trigger ) { add_msg_if_player( m_bad, _( "Your malfunctioning bionic starts to glow!" ) ); add_effect( effect_glowy_led, 5_minutes ); - mod_power_level( -1_kJ ); + mod_power_level( -bio_glowy->power_trigger ); } } From 493281591db740ac3765e13f0d011b6388b8131a Mon Sep 17 00:00:00 2001 From: John Candlebury Date: Wed, 7 Jul 2021 07:05:23 -0600 Subject: [PATCH 042/116] Aftershock: Ballistic gun itemgroups (#49688) --- .../itemgroups/weapons/armories.json | 16 ++- .../weapons/balistic_gun_groups.json | 104 ++++++++++++++++++ .../itemgroups/weapons/energy_gun_groups.json | 92 ---------------- .../weapons/weapon_expansion_groups.json | 95 ++++++++++++++++ data/mods/Aftershock/items/gun/10mm.json | 2 +- 5 files changed, 215 insertions(+), 94 deletions(-) create mode 100644 data/mods/Aftershock/itemgroups/weapons/balistic_gun_groups.json create mode 100644 data/mods/Aftershock/itemgroups/weapons/weapon_expansion_groups.json diff --git a/data/mods/Aftershock/itemgroups/weapons/armories.json b/data/mods/Aftershock/itemgroups/weapons/armories.json index 515e4fbcda422..8c3a9b426775d 100644 --- a/data/mods/Aftershock/itemgroups/weapons/armories.json +++ b/data/mods/Aftershock/itemgroups/weapons/armories.json @@ -4,7 +4,11 @@ "id": "afs_general_armory", "type": "item_group", "subtype": "distribution", - "items": [ { "group": "afs_energy_weapon_armory", "prob": 3 }, { "group": "afs_grenade_armory", "prob": 1 } ] + "items": [ + { "group": "afs_energy_weapon_armory", "prob": 3 }, + { "group": "afs_ballistic_armory", "prob": 3 }, + { "group": "afs_grenade_armory", "prob": 1 } + ] }, { "id": "afs_grenade_armory", @@ -21,5 +25,15 @@ { "group": "afs_any_energy_mag", "prob": 2 }, { "group": "gunmod_energy", "prob": 2 } ] + }, + { + "id": "afs_ballistic_armory", + "type": "item_group", + "subtype": "distribution", + "items": [ + { "group": "afs_any_ballistic_gun", "prob": 6 }, + { "group": "afs_any_ballistic_mag", "prob": 1 }, + { "group": "afs_any_ballistic_ammo", "prob": 4 } + ] } ] diff --git a/data/mods/Aftershock/itemgroups/weapons/balistic_gun_groups.json b/data/mods/Aftershock/itemgroups/weapons/balistic_gun_groups.json new file mode 100644 index 0000000000000..0d33cb3f27ead --- /dev/null +++ b/data/mods/Aftershock/itemgroups/weapons/balistic_gun_groups.json @@ -0,0 +1,104 @@ +[ + { + "id": "afs_any_ballistic_gun", + "type": "item_group", + "subtype": "distribution", + "items": [ + { "group": "afs_any_ballistic_s_gun", "prob": 10 }, + { "group": "afs_any_ballistic_m_gun", "prob": 10 }, + { "group": "afs_any_ballistic_h_gun", "prob": 3 } + ] + }, + { + "id": "afs_any_ballistic_s_gun", + "type": "item_group", + "subtype": "distribution", + "ammo": 100, + "magazine": 100, + "items": [ [ "afs_seyfert_84K", 40 ] ] + }, + { + "id": "afs_any_ballistic_m_gun", + "type": "item_group", + "subtype": "distribution", + "ammo": 100, + "magazine": 100, + "items": [ [ "afs_Accipitermg", 20 ], [ "afs_gibrifle", 40 ] ] + }, + { + "id": "afs_any_ballistic_h_gun", + "type": "item_group", + "subtype": "distribution", + "ammo": 100, + "magazine": 100, + "items": [ [ "afs_gibs_shotgun", 10 ] ] + }, + { + "id": "afs_any_ballistic_mag", + "type": "item_group", + "subtype": "distribution", + "items": [ + { "group": "afs_any_ballistic_s_mag", "prob": 10 }, + { "group": "afs_any_ballistic_m_mag", "prob": 10 }, + { "group": "afs_any_ballistic_h_mag", "prob": 2 } + ] + }, + { + "id": "afs_any_ballistic_s_mag", + "type": "item_group", + "subtype": "distribution", + "ammo": 100, + "magazine": 100, + "items": [ [ "afs_84k_20mag", 40 ] ] + }, + { + "id": "afs_any_ballistic_m_mag", + "type": "item_group", + "subtype": "distribution", + "ammo": 100, + "magazine": 100, + "items": [ [ "afs_UICASTA30", 40 ], [ "afs_UICASTA100drum", 5 ] ] + }, + { + "id": "afs_any_ballistic_h_mag", + "type": "item_group", + "subtype": "distribution", + "ammo": 100, + "magazine": 100, + "items": [ [ "afs_25mm_mag", 20 ] ] + }, + { + "id": "afs_any_ballistic_ammo", + "type": "item_group", + "subtype": "distribution", + "items": [ + { "group": "afs_any_ballistic_s_ammo", "prob": 10 }, + { "group": "afs_any_ballistic_m_ammo", "prob": 10 }, + { "group": "afs_any_ballistic_h_ammo", "prob": 2 } + ] + }, + { + "id": "afs_any_ballistic_s_ammo", + "type": "item_group", + "subtype": "distribution", + "ammo": 100, + "magazine": 100, + "items": [ [ "afs_10mm_caseless_FMJ", 20 ], [ "afs_10mm_caseless_JHP", 40 ], [ "afs_7.50mm_caseless", 5 ] ] + }, + { + "id": "afs_any_ballistic_m_ammo", + "type": "item_group", + "subtype": "distribution", + "ammo": 100, + "magazine": 100, + "items": [ [ "afs_7.50mm_caseless", 40 ] ] + }, + { + "id": "afs_any_ballistic_h_ammo", + "type": "item_group", + "subtype": "distribution", + "ammo": 100, + "magazine": 100, + "items": [ [ "afs_25mm_shot", 40 ] ] + } +] diff --git a/data/mods/Aftershock/itemgroups/weapons/energy_gun_groups.json b/data/mods/Aftershock/itemgroups/weapons/energy_gun_groups.json index 829ca018ce3d8..1516ee5b1b817 100644 --- a/data/mods/Aftershock/itemgroups/weapons/energy_gun_groups.json +++ b/data/mods/Aftershock/itemgroups/weapons/energy_gun_groups.json @@ -40,97 +40,5 @@ "subtype": "distribution", "ammo": 100, "items": [ [ "afs_4g_plasma", 30 ] ] - }, - { - "type": "item_group", - "id": "guns_pistol_rare", - "items": [ { "item": "afs_orion_84K", "prob": 15, "charges-min": 0, "charges-max": 20 } ] - }, - { - "type": "item_group", - "id": "guns_pistol_rare_display", - "items": [ { "item": "afs_orion_84K", "prob": 15, "charges-min": 0, "charges-max": 0 } ] - }, - { - "type": "item_group", - "id": "guns_pistol_obscure", - "items": [ { "item": "afs_orion_84K", "prob": 50, "charges-min": 0, "charges-max": 20 } ] - }, - { - "type": "item_group", - "id": "guns_rifle_rare_display", - "items": [ - { "item": "afs_gibrifle", "prob": 1, "charges-min": 0, "charges-max": 0 }, - { "item": "afs_Accipitermg", "prob": 1, "charges-min": 0, "charges-max": 0 } - ] - }, - { - "type": "item_group", - "id": "guns_rifle_rare", - "items": [ - { "item": "afs_gibrifle", "prob": 25, "charges-min": 0, "charges-max": 30 }, - { "item": "afs_Accipitermg", "prob": 20, "charges-min": 0, "charges-max": 30 } - ] - }, - { - "type": "item_group", - "id": "guns_rifle_milspec", - "items": [ - { "item": "afs_gibrifle", "prob": 50, "charges-min": 0, "charges-max": 30 }, - { "item": "afs_Accipitermg", "prob": 45, "charges-min": 0, "charges-max": 30 } - ] - }, - { - "type": "item_group", - "id": "guns_shotgun_milspec", - "items": [ { "item": "afs_gibs_shotgun", "prob": 20, "charges-min": 0, "charges-max": 40 } ] - }, - { - "type": "item_group", - "id": "mags_pistol_rare", - "items": [ [ "afs_84k_20mag", 15 ] ] - }, - { - "type": "item_group", - "id": "mags_rifle_rare", - "items": [ [ "afs_UICASTA30", 40 ], [ "afs_UICASTA100drum", 20 ] ] - }, - { - "type": "item_group", - "id": "mags_shotgun_rare", - "items": [ [ "afs_25mm_mag", 50 ] ] - }, - { - "type": "item_group", - "id": "ammo_pistol_rare", - "subtype": "distribution", - "entries": [ { "item": "afs_10mm_caseless_FMJ", "prob": 20 }, { "item": "afs_10mm_caseless_JHP", "prob": 15 } ] - }, - { - "type": "item_group", - "id": "ammo_rifle_rare", - "//": "Less common rifle ammo including that only used by police/paramilitary forces.", - "subtype": "distribution", - "entries": [ { "item": "afs_7.50mm_caseless", "prob": 40 }, { "item": "afs_7.50mm_rp", "prob": 50 } ] - }, - { - "type": "item_group", - "id": "ammo_rifle_milspec", - "subtype": "distribution", - "entries": [ { "item": "afs_7.50mm_caseless", "prob": 40 }, { "item": "afs_7.50mm_rp", "prob": 50 } ] - }, - { - "type": "item_group", - "id": "ammo_shotgun_rare", - "//": "Less common shotgun ammo including that only used by police/paramilitary forces.", - "subtype": "distribution", - "entries": [ { "item": "afs_25mm_shot", "prob": 10 } ] - }, - { - "type": "item_group", - "id": "ammo_shotgun_milspec", - "//": "Military specification shotgun ammo found at military sites.", - "subtype": "distribution", - "entries": [ { "item": "afs_25mm_shot", "prob": 10 } ] } ] diff --git a/data/mods/Aftershock/itemgroups/weapons/weapon_expansion_groups.json b/data/mods/Aftershock/itemgroups/weapons/weapon_expansion_groups.json new file mode 100644 index 0000000000000..12cb7edf670de --- /dev/null +++ b/data/mods/Aftershock/itemgroups/weapons/weapon_expansion_groups.json @@ -0,0 +1,95 @@ +[ + { + "//": "This file adds Aftershock weapons to vanilla groups. To be deleted once the total conversion gets going.", + "type": "item_group", + "id": "guns_pistol_rare", + "items": [ { "item": "afs_seyfert_84K", "prob": 15, "charges-min": 0, "charges-max": 20 } ] + }, + { + "type": "item_group", + "id": "guns_pistol_rare_display", + "items": [ { "item": "afs_seyfert_84K", "prob": 15, "charges-min": 0, "charges-max": 0 } ] + }, + { + "type": "item_group", + "id": "guns_pistol_obscure", + "items": [ { "item": "afs_seyfert_84K", "prob": 50, "charges-min": 0, "charges-max": 20 } ] + }, + { + "type": "item_group", + "id": "guns_rifle_rare_display", + "items": [ + { "item": "afs_gibrifle", "prob": 1, "charges-min": 0, "charges-max": 0 }, + { "item": "afs_Accipitermg", "prob": 1, "charges-min": 0, "charges-max": 0 } + ] + }, + { + "type": "item_group", + "id": "guns_rifle_rare", + "items": [ + { "item": "afs_gibrifle", "prob": 25, "charges-min": 0, "charges-max": 30 }, + { "item": "afs_Accipitermg", "prob": 20, "charges-min": 0, "charges-max": 30 } + ] + }, + { + "type": "item_group", + "id": "guns_rifle_milspec", + "items": [ + { "item": "afs_gibrifle", "prob": 50, "charges-min": 0, "charges-max": 30 }, + { "item": "afs_Accipitermg", "prob": 45, "charges-min": 0, "charges-max": 30 } + ] + }, + { + "type": "item_group", + "id": "guns_shotgun_milspec", + "items": [ { "item": "afs_gibs_shotgun", "prob": 20, "charges-min": 0, "charges-max": 40 } ] + }, + { + "type": "item_group", + "id": "mags_pistol_rare", + "items": [ [ "afs_84k_20mag", 15 ] ] + }, + { + "type": "item_group", + "id": "mags_rifle_rare", + "items": [ [ "afs_UICASTA30", 40 ], [ "afs_UICASTA100drum", 20 ] ] + }, + { + "type": "item_group", + "id": "mags_shotgun_rare", + "items": [ [ "afs_25mm_mag", 50 ] ] + }, + { + "type": "item_group", + "id": "ammo_pistol_rare", + "subtype": "distribution", + "entries": [ { "item": "afs_10mm_caseless_FMJ", "prob": 20 }, { "item": "afs_10mm_caseless_JHP", "prob": 15 } ] + }, + { + "type": "item_group", + "id": "ammo_rifle_rare", + "//": "Less common rifle ammo including that only used by police/paramilitary forces.", + "subtype": "distribution", + "entries": [ { "item": "afs_7.50mm_caseless", "prob": 40 }, { "item": "afs_7.50mm_rp", "prob": 50 } ] + }, + { + "type": "item_group", + "id": "ammo_rifle_milspec", + "subtype": "distribution", + "entries": [ { "item": "afs_7.50mm_caseless", "prob": 40 }, { "item": "afs_7.50mm_rp", "prob": 50 } ] + }, + { + "type": "item_group", + "id": "ammo_shotgun_rare", + "//": "Less common shotgun ammo including that only used by police/paramilitary forces.", + "subtype": "distribution", + "entries": [ { "item": "afs_25mm_shot", "prob": 10 } ] + }, + { + "type": "item_group", + "id": "ammo_shotgun_milspec", + "//": "Military specification shotgun ammo found at military sites.", + "subtype": "distribution", + "entries": [ { "item": "afs_25mm_shot", "prob": 10 } ] + } +] diff --git a/data/mods/Aftershock/items/gun/10mm.json b/data/mods/Aftershock/items/gun/10mm.json index 1dfe73939b256..0f1762d922522 100644 --- a/data/mods/Aftershock/items/gun/10mm.json +++ b/data/mods/Aftershock/items/gun/10mm.json @@ -1,6 +1,6 @@ [ { - "id": "afs_orion_84K", + "id": "afs_seyfert_84K", "copy-from": "pistol_base", "looks_like": "glock_17", "type": "GUN", From 3a2191129e200b00d41a4421a02534702deedc23 Mon Sep 17 00:00:00 2001 From: Mom-Bun <43492737+Mom-Bun@users.noreply.github.com> Date: Wed, 7 Jul 2021 08:09:14 -0500 Subject: [PATCH 043/116] [AFTERSHOCK] House Palette + New AFS house (#49641) Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> --- .../Aftershock/itemgroups/clothing_group.json | 14 +++ data/mods/Aftershock/maps/city_buildings.json | 9 ++ .../Aftershock/maps/mapgen/houses/houses.json | 76 +++++++++++++++ .../maps/mapgen_pallete/houses.json | 96 +++++++++++++++++++ .../mods/Aftershock/maps/overmap_terrain.json | 18 ++++ data/mods/Aftershock/region_settings.json | 2 +- .../aftershock_exoplanet/region_settings.json | 2 +- 7 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 data/mods/Aftershock/maps/mapgen/houses/houses.json create mode 100644 data/mods/Aftershock/maps/mapgen_pallete/houses.json diff --git a/data/mods/Aftershock/itemgroups/clothing_group.json b/data/mods/Aftershock/itemgroups/clothing_group.json index b403c9d112b2c..7555fd8168dbe 100644 --- a/data/mods/Aftershock/itemgroups/clothing_group.json +++ b/data/mods/Aftershock/itemgroups/clothing_group.json @@ -172,5 +172,19 @@ "prob": 60 } ] + }, + { + "id": "wardrobe_unisex_afs", + "type": "item_group", + "subtype": "distribution", + "items": [ + { "group": "shoes_unisex_afs", "prob": 50 }, + { "group": "common_gloves_afs", "prob": 20 }, + { "group": "pants_unisex_afs", "prob": 10 }, + { "group": "coats_unisex_afs", "prob": 50 }, + { "group": "hatstore_hats_afs", "prob": 20 }, + { "group": "scarfs_unisex_afs", "prob": 20 }, + { "group": "shirts_unisex_afs", "prob": 10 } + ] } ] diff --git a/data/mods/Aftershock/maps/city_buildings.json b/data/mods/Aftershock/maps/city_buildings.json index d2c90d393751a..9d1c3795747b1 100644 --- a/data/mods/Aftershock/maps/city_buildings.json +++ b/data/mods/Aftershock/maps/city_buildings.json @@ -37,5 +37,14 @@ { "point": [ -1, 2, 0 ], "overmap": "afs_formless_ruins_dynamic_north" } ], "locations": [ "land" ] + }, + { + "id": "afs_house_1", + "type": "city_building", + "overmaps": [ + { "point": [ 0, 0, 0 ], "overmap": "afs_shelter_1_north" }, + { "point": [ 0, 0, 1 ], "overmap": "afs_shelter_1_roof_north" } + ], + "locations": [ "land" ] } ] diff --git a/data/mods/Aftershock/maps/mapgen/houses/houses.json b/data/mods/Aftershock/maps/mapgen/houses/houses.json new file mode 100644 index 0000000000000..00081a19164be --- /dev/null +++ b/data/mods/Aftershock/maps/mapgen/houses/houses.json @@ -0,0 +1,76 @@ +[ + { + "method": "json", + "om_terrain": "afs_shelter_1", + "type": "mapgen", + "weight": 100, + "object": { + "fill_ter": "t_metal_floor", + "rows": [ + " ", + " ", + " ++o+++o++o+++ppp.ppp ", + " +@.x.x.@+.@++......p ", + " +D.+.+.D+.D+++++l+++ ", + " ++n+.++n+xn++q+...o ", + " +D.x......hf+x++l+++ ", + " o@.+......hfn.77.77+ ", + " +n++++x++++n+......o ", + " o...........x......+ ", + " +nx++nx++nx++...++++ ", + " +5.t+5.t+5.t+...+ ", + " ++9+++9+++9++...o ", + " ++++++++++++....+ ", + " +{L.............++++ ", + " oF..........H.....y+ ", + " oV.J........H..2..y+ ", + " oI.J........H..2..y+ ", + " +P.S........H.....y+ ", + " +M^M...E.......Y...+ ", + " +++++R.......+++++++ ", + " +RRRR.JWZ+ ", + " ++++++ooo+ ", + " " + ], + "palettes": [ "standard_afsshelter_palette" ], + "place_item": [ { "item": "television", "repeat": 1, "x": 21, "y": 17 }, { "item": "toaster", "repeat": 1, "x": 6, "y": 17 } ], + "place_monsters": [ { "monster": "AFS_GROUP_MOXIE_LOW_RISK", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 10, "density": 0.1 } ] + } + }, + { + "method": "json", + "om_terrain": "afs_shelter_1_roof", + "type": "mapgen", + "weight": 100, + "object": { + "fill_ter": "t_flat_roof", + "rows": [ + " ", + " ", + " .................... ", + " .................... ", + " .................... ", + " ......&A........... ", + " ......=A............ ", + " ............&....... ", + " ..........=AA....... ", + " .................... ", + " .................... ", + " ................. ", + " ................. ", + " ...&A............ ", + " ...=A............... ", + " ...........&........ ", + " .........=AA........ ", + " ..................X. ", + " ..=&................ ", + " ..AA................ ", + " .................... ", + " .......... ", + " .......... ", + " " + ], + "palettes": [ "roof_palette" ] + } + } +] diff --git a/data/mods/Aftershock/maps/mapgen_pallete/houses.json b/data/mods/Aftershock/maps/mapgen_pallete/houses.json new file mode 100644 index 0000000000000..c6743766db28b --- /dev/null +++ b/data/mods/Aftershock/maps/mapgen_pallete/houses.json @@ -0,0 +1,96 @@ +[ + { + "type": "palette", + "//": "the food should be rotted, but the regular food item groups can work for now", + "id": "standard_afsshelter_palette", + "toilets": { "t": { } }, + "terrain": { + " ": "t_region_groundcover_urban", + ".": "t_metal_floor", + "+": "t_wall_prefab_metal", + "o": [ + [ "t_wall_prefab_glass", 2 ], + [ "t_wall_prefab_glass_shutters", 2 ], + [ "t_wall_prefab_bglass_shutters", 4 ], + [ "t_wall_prefab_bglass", 5 ] + ], + "g": "t_wall_metal", + "h": "t_concrete_wall", + "i": [ [ "t_door_glass_c", 5 ], "t_door_glass_o", 5 ], + "j": [ [ "t_door_locked", 1 ], [ "t_door_c", 5 ], [ "t_door_o", 1 ] ], + "x": [ [ "t_door_locked_interior", 1 ], [ "t_door_c", 5 ], [ "t_door_o", 5 ] ], + "l": [ [ "t_door_metal_c", 5 ], [ "t_door_metal_pickable", 3 ], [ "t_door_metal_locked", 1 ], [ "t_door_metal_o", 5 ] ], + "n": "t_metal_ventilation_shutter", + "p": "t_metal_railing", + "<": "t_stairs_down", + ">": "t_stairs_up" + }, + "furniture": { + "@": "f_bed", + "D": "f_wardrobe", + "9": "f_shower", + "5": "f_sink", + "f": "f_table", + "y": "f_table", + "h": "f_chair", + "P": "f_dishwasher", + "i": "f_bench", + "2": "f_coffee_table", + "F": "f_fridge", + "H": "f_sofa", + "L": "f_cupboard", + "{": "f_cupboard", + "V": "f_cupboard", + "I": "f_cupboard", + "^": "f_sink", + "M": "f_cupboard", + "S": "f_cupboard", + "J": "f_counter", + "q": "f_rack", + "O": "f_oven", + "R": "f_bookcase", + "Y": "f_trashcan", + "E": "f_armchair", + "7": "f_locker", + "W": "f_washer", + "Z": "f_dryer" + }, + "items": { + "t": { "item": "SUS_toilet", "chance": 10, "repeat": [ 1, 3 ] }, + "D": [ { "item": "wardrobe_unisex_afs", "chance": 100, "repeat": [ 1, 2 ] } ], + "O": { "item": "SUS_oven", "chance": 100 }, + "2": [ + { "item": "consumer_electronics", "chance": 10, "repeat": [ 1, 3 ] }, + { "item": "livingroom", "chance": 10, "repeat": [ 1, 3 ] } + ], + "F": { "item": "SUS_fridge", "chance": 80 }, + "P": { "item": "SUS_dishwasher", "chance": 70 }, + "f": [ + { "item": "elecsto_persele", "chance": 10, "repeat": [ 1, 3 ] }, + { "item": "livingroom", "chance": 10, "repeat": [ 1, 3 ] } + ], + "q": [ + { "item": "tools_home", "chance": 40 }, + { "item": "cleaning", "chance": 30, "repeat": [ 1, 2 ] }, + { "item": "mechanics", "chance": 1, "repeat": [ 1, 2 ] }, + { "item": "camping", "chance": 10 }, + { "item": "tools_survival", "chance": 5, "repeat": [ 1, 2 ] } + ], + "7": { "item": "afs_frontier_cryo_g", "chance": 50 }, + "J": { "item": "kitchen_counters", "chance": 5 }, + "L": [ { "item": "SUS_dishes", "chance": 100 }, { "item": "SUS_silverware", "chance": 100 } ], + "{": { "item": "SUS_cookware", "chance": 100 }, + "V": [ { "item": "SUS_utensils", "chance": 50 }, { "item": "SUS_knife_drawer", "chance": 50 } ], + "I": { "item": "SUS_junk_drawer", "chance": 100 }, + "^": { "item": "SUS_kitchen_sink", "chance": 100 }, + "M": [ { "item": "SUS_pantry", "chance": 25 }, { "item": "cannedfood", "chance": 20, "repeat": [ 1, 2 ] } ], + "S": [ { "item": "SUS_breakfast_cupboard", "chance": 30 }, { "item": "SUS_coffee_cupboard", "chance": 50 } ], + "5": [ { "item": "SUS_bathroom_sink", "chance": 80 }, { "item": "SUS_bathroom_medicine", "chance": 60 } ], + "9": { "item": "shower", "chance": 30, "repeat": [ 1, 2 ] }, + "@": { "item": "bed", "chance": 50 }, + "Z": { "item": "wardrobe_unisex_afs", "chance": 100 }, + "W": { "item": "wardrobe_unisex_afs", "chance": 50 }, + "Y": { "item": "trash", "chance": 30, "repeat": [ 1, 4 ] } + } + } +] diff --git a/data/mods/Aftershock/maps/overmap_terrain.json b/data/mods/Aftershock/maps/overmap_terrain.json index fd6fae1a16e15..5930cde32ccd7 100644 --- a/data/mods/Aftershock/maps/overmap_terrain.json +++ b/data/mods/Aftershock/maps/overmap_terrain.json @@ -216,5 +216,23 @@ "color": "i_pink", "see_cost": 2, "mondensity": 2 + }, + { + "type": "overmap_terrain", + "id": [ "afs_shelter_1" ], + "name": "house", + "sym": "<", + "color": "green", + "spawns": { "group": "GROUP_ZOMBIE", "population": [ 1, 4 ], "chance": 50 }, + "flags": [ "SIDEWALK" ], + "see_cost": 3 + }, + { + "type": "overmap_terrain", + "id": [ "afs_shelter_1_roof" ], + "name": "house roof", + "sym": "<", + "color": "green", + "see_cost": 3 } ] diff --git a/data/mods/Aftershock/region_settings.json b/data/mods/Aftershock/region_settings.json index 6745d5a5e58fa..cd6d15df81077 100644 --- a/data/mods/Aftershock/region_settings.json +++ b/data/mods/Aftershock/region_settings.json @@ -15,7 +15,7 @@ "afs_astrobiology_lab": 300, "mall": 700 }, - "houses": { "afs_city_ruinfield": 200, "afs_formless_ruins_dynamic": 300 } + "houses": { "afs_city_ruinfield": 200, "afs_formless_ruins_dynamic": 300, "afs_house_1": 100 } }, "overmap_lake_settings": { "noise_threshold_lake": 0.12 } } diff --git a/data/mods/aftershock_exoplanet/region_settings.json b/data/mods/aftershock_exoplanet/region_settings.json index 615b3cd483879..6181d39bb2e57 100644 --- a/data/mods/aftershock_exoplanet/region_settings.json +++ b/data/mods/aftershock_exoplanet/region_settings.json @@ -16,7 +16,7 @@ "shop_sigma": 80, "park_radius": 20, "park_sigma": 80, - "houses": { "afs_city_ruinfield": 400, "afs_formless_ruins_dynamic": 600 }, + "houses": { "afs_city_ruinfield": 400, "afs_formless_ruins_dynamic": 600, "afs_house_1": 300 }, "parks": { "afs_city_ruinfield": 100 }, "shops": { "afs_augmentation_clinic_1": 400, "afs_astrobiology_lab": 400 } }, From 8d5ba0d64e387ad836a2d3d03247ce6ca9390dfa Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Wed, 7 Jul 2021 14:10:18 +0100 Subject: [PATCH 044/116] aux_nested revision (#49615) * Rewrote aux_nested.json's destroyed_x mapgens and replaced them with a generic destroyed_furniture which pulls straight from the furniture bash itemgroup rather than mimicking it. * Reverted accidental removal of destroyed_glass_door_wall. --- data/json/mapgen/mil_surplus.json | 34 ++++---- data/json/mapgen/nested/aux_nested.json | 107 +----------------------- data/json/mapgen/s_grocery.json | 14 ++-- data/json/mapgen/s_liquor.json | 4 +- 4 files changed, 28 insertions(+), 131 deletions(-) diff --git a/data/json/mapgen/mil_surplus.json b/data/json/mapgen/mil_surplus.json index 57be8a612fd0a..173c5280b3b6e 100644 --- a/data/json/mapgen/mil_surplus.json +++ b/data/json/mapgen/mil_surplus.json @@ -165,15 +165,15 @@ "nested": { "|": { "chunks": [ [ "bile_field", 10 ], [ "shelter_graffiti", 5 ], [ "general_graffiti", 20 ], [ "null", 75 ] ] }, "-": { "chunks": [ [ "bile_field", 10 ], [ "shelter_graffiti", 5 ], [ "general_graffiti", 20 ], [ "null", 75 ] ] }, - "А": { "chunks": [ [ "destroyed_rack", 20 ], [ "null", 80 ] ] }, - "Б": { "chunks": [ [ "destroyed_rack", 20 ], [ "null", 80 ] ] }, - "В": { "chunks": [ [ "destroyed_rack", 20 ], [ "null", 80 ] ] }, - "Г": { "chunks": [ [ "destroyed_rack", 20 ], [ "null", 80 ] ] }, - "Д": { "chunks": [ [ "destroyed_rack", 20 ], [ "null", 80 ] ] }, - "Е": { "chunks": [ [ "destroyed_rack", 20 ], [ "null", 80 ] ] }, - "!": { "chunks": [ [ "destroyed_mannequin", 80 ], [ "null", 20 ] ] }, + "А": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] }, + "Б": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] }, + "В": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] }, + "Г": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] }, + "Д": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] }, + "Е": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] }, + "!": { "chunks": [ [ "destroyed_furniture", 80 ], [ "null", 20 ] ] }, "T": { "chunks": [ [ "deployed_small_tent", 20 ], [ "destroyed_small_tent", 20 ], [ "null", 60 ] ] }, - "S": { "chunks": [ [ "destroyed_chair", 80 ], [ "null", 20 ] ] }, + "S": { "chunks": [ [ "destroyed_furniture", 80 ], [ "null", 20 ] ] }, "1": { "chunks": [ [ "corpse_blood_casings_3x3", 50 ], [ "null", 50 ] ] } } } @@ -519,14 +519,14 @@ "nested": { "|": { "chunks": [ [ "bile_field", 10 ], [ "shelter_graffiti", 5 ], [ "general_graffiti", 20 ], [ "null", 75 ] ] }, "-": { "chunks": [ [ "bile_field", 10 ], [ "shelter_graffiti", 5 ], [ "general_graffiti", 20 ], [ "null", 75 ] ] }, - "А": { "chunks": [ [ "destroyed_rack", 20 ], [ "null", 80 ] ] }, - "Б": { "chunks": [ [ "destroyed_rack", 20 ], [ "null", 80 ] ] }, - "В": { "chunks": [ [ "destroyed_rack", 20 ], [ "null", 80 ] ] }, - "Г": { "chunks": [ [ "destroyed_rack", 20 ], [ "null", 80 ] ] }, - "Д": { "chunks": [ [ "destroyed_rack", 20 ], [ "null", 80 ] ] }, - "Е": { "chunks": [ [ "destroyed_rack", 20 ], [ "null", 80 ] ] }, - "!": { "chunks": [ [ "destroyed_mannequin", 80 ], [ "null", 20 ] ] }, - "S": { "chunks": [ [ "destroyed_chair", 80 ], [ "null", 20 ] ] }, + "А": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] }, + "Б": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] }, + "В": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] }, + "Г": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] }, + "Д": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] }, + "Е": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] }, + "!": { "chunks": [ [ "destroyed_furniture", 80 ], [ "null", 20 ] ] }, + "S": { "chunks": [ [ "destroyed_furniture", 80 ], [ "null", 20 ] ] }, "1": { "chunks": [ [ "corpse_blood_casings_3x3", 50 ], [ "null", 50 ] ] } } } @@ -863,7 +863,7 @@ "items": { ".": { "item": "trash_cart", "chance": 5 } }, "nested": { "|": { "chunks": [ [ "bile_field", 1 ], [ "shelter_graffiti", 10 ], [ "general_graffiti", 20 ], [ "null", 75 ] ] }, - "{": { "chunks": [ [ "destroyed_rack", 20 ], [ "null", 80 ] ] }, + "{": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] }, "D": { "chunks": [ [ "destroyed_glass_door_wall", 80 ], [ "null", 20 ] ] }, "1": { "chunks": [ [ "corpse_blood_casings_3x3", 50 ], [ "null", 50 ] ] } } diff --git a/data/json/mapgen/nested/aux_nested.json b/data/json/mapgen/nested/aux_nested.json index f93148be9c1ea..41dc1caee5ca1 100644 --- a/data/json/mapgen/nested/aux_nested.json +++ b/data/json/mapgen/nested/aux_nested.json @@ -5,72 +5,6 @@ "nested_mapgen_id": "bile_field", "object": { "mapgensize": [ 1, 1 ], "place_fields": [ { "field": "fd_bile", "x": 0, "y": 0, "intensity": 1, "age": 10 } ] } }, - { - "type": "mapgen", - "method": "json", - "nested_mapgen_id": "destroyed_rack", - "object": { - "mapgensize": [ 1, 1 ], - "place_furniture": [ { "furn": "f_null", "x": 0, "y": 0 } ], - "place_item": [ - { "item": "scrap", "x": 0, "y": 0, "repeat": [ 2, 8 ], "chance": 100 }, - { "item": "steel_chunk", "x": 0, "y": 0, "repeat": [ 2, 4 ], "chance": 100 }, - { "item": "sheet_metal_small", "x": 0, "y": 0, "repeat": [ 6, 10 ], "chance": 100 }, - { "item": "pipe", "x": 0, "y": 0, "chance": 100 } - ] - } - }, - { - "type": "mapgen", - "method": "json", - "nested_mapgen_id": "destroyed_glass_fridge", - "object": { - "mapgensize": [ 1, 1 ], - "place_furniture": [ { "furn": "f_null", "x": 0, "y": 0 } ], - "place_item": [ - { "item": "sheet_metal", "x": 0, "y": 0, "repeat": [ 1, 3 ], "chance": 100 }, - { "item": "sheet_metal_small", "x": 0, "y": 0, "repeat": [ 6, 9 ], "chance": 100 }, - { "item": "steel_chunk", "x": 0, "y": 0, "repeat": [ 0, 3 ], "chance": 100 }, - { "item": "scrap", "x": 0, "y": 0, "repeat": [ 2, 8 ], "chance": 100 }, - { "item": "pipe_fittings", "x": 0, "y": 0, "repeat": [ 1, 3 ], "chance": 100 }, - { "item": "cable", "x": 0, "y": 0, "repeat": [ 1, 3 ], "chance": 100 }, - { "item": "hose", "x": 0, "y": 0, "chance": 100 }, - { "item": "cu_pipe", "x": 0, "y": 0, "repeat": [ 1, 4 ], "chance": 100 }, - { "item": "scrap_copper", "x": 0, "y": 0, "repeat": [ 0, 2 ], "chance": 100 }, - { "item": "glass_shard", "x": 0, "y": 0, "repeat": [ 25, 50 ], "chance": 100 }, - { "item": "motor_tiny", "x": 0, "y": 0, "chance": 25 } - ] - } - }, - { - "type": "mapgen", - "method": "json", - "nested_mapgen_id": "destroyed_table", - "object": { - "mapgensize": [ 1, 1 ], - "place_furniture": [ { "furn": "f_null", "x": 0, "y": 0 } ], - "place_item": [ - { "item": "2x4", "x": 0, "y": 0, "repeat": [ 2, 4 ], "chance": 100 }, - { "item": "wood_panel", "x": 0, "y": 0, "repeat": [ 0, 1 ], "chance": 100 }, - { "item": "nail", "x": 0, "y": 0, "repeat": [ 4, 8 ], "chance": 100 }, - { "item": "splinter", "x": 0, "y": 0, "chance": 100 } - ] - } - }, - { - "type": "mapgen", - "method": "json", - "nested_mapgen_id": "destroyed_bookcase", - "object": { - "mapgensize": [ 1, 1 ], - "place_furniture": [ { "furn": "f_null", "x": 0, "y": 0 } ], - "place_item": [ - { "item": "2x4", "x": 0, "y": 0, "repeat": [ 2, 6 ], "chance": 100 }, - { "item": "nail", "x": 0, "y": 0, "repeat": [ 4, 12 ], "chance": 100 }, - { "item": "splinter", "x": 0, "y": 0, "chance": 100 } - ] - } - }, { "type": "mapgen", "method": "json", @@ -81,38 +15,6 @@ "place_item": [ { "item": "glass_shard", "x": 0, "y": 0, "repeat": [ 42, 84 ], "chance": 100 } ] } }, - { - "type": "mapgen", - "method": "json", - "nested_mapgen_id": "destroyed_glass_door_fridge", - "object": { - "mapgensize": [ 1, 1 ], - "place_furniture": [ { "furn": "f_null", "x": 0, "y": 0 } ], - "place_item": [ - { "item": "sheet_metal", "x": 0, "y": 0, "repeat": [ 1, 3 ], "chance": 100 }, - { "item": "sheet_metal_small", "x": 0, "y": 0, "repeat": [ 6, 9 ], "chance": 100 }, - { "item": "steel_chunk", "x": 0, "y": 0, "repeat": [ 0, 3 ], "chance": 100 }, - { "item": "scrap", "x": 0, "y": 0, "repeat": [ 2, 8 ], "chance": 100 }, - { "item": "pipe_fittings", "x": 0, "y": 0, "repeat": [ 1, 3 ], "chance": 100 }, - { "item": "cable", "x": 0, "y": 0, "repeat": [ 1, 3 ], "chance": 100 }, - { "item": "hose", "x": 0, "y": 0, "chance": 100 }, - { "item": "cu_pipe", "x": 0, "y": 0, "repeat": [ 1, 4 ], "chance": 100 }, - { "item": "scrap_copper", "x": 0, "y": 0, "repeat": [ 0, 2 ], "chance": 100 }, - { "item": "glass_shard", "x": 0, "y": 0, "repeat": [ 25, 50 ], "chance": 100 }, - { "item": "motor_tiny", "x": 0, "y": 0, "chance": 25 } - ] - } - }, - { - "type": "mapgen", - "method": "json", - "nested_mapgen_id": "destroyed_mannequin", - "object": { - "mapgensize": [ 1, 1 ], - "place_furniture": [ { "furn": "f_null", "x": 0, "y": 0 } ], - "place_item": [ { "item": "splinter", "repeat": [ 9, 12 ], "x": 0, "y": 0, "chance": 100 } ] - } - }, { "type": "mapgen", "method": "json", @@ -144,15 +46,10 @@ { "type": "mapgen", "method": "json", - "nested_mapgen_id": "destroyed_chair", + "nested_mapgen_id": "destroyed_furniture", "object": { "mapgensize": [ 1, 1 ], - "place_furniture": [ { "furn": "f_null", "x": 0, "y": 0 } ], - "place_item": [ - { "item": "2x4", "x": 0, "y": 0, "chance": 100 }, - { "item": "nail", "x": 0, "y": 0, "repeat": [ 1, 5 ], "chance": 100 }, - { "item": "splinter", "x": 0, "y": 0, "repeat": 3, "chance": 100 } - ] + "place_rubble": [ { "x": 0, "y": 0, "rubble_type": "f_null", "items": true } ] } }, { diff --git a/data/json/mapgen/s_grocery.json b/data/json/mapgen/s_grocery.json index 1784be4ed4026..6a9321084190a 100644 --- a/data/json/mapgen/s_grocery.json +++ b/data/json/mapgen/s_grocery.json @@ -276,13 +276,13 @@ "nested": { "|": { "chunks": [ [ "bile_field", 1 ], [ "shelter_graffiti", 10 ], [ "general_graffiti", 20 ], [ "null", 75 ] ] }, "-": { "chunks": [ [ "bile_field", 1 ], [ "shelter_graffiti", 10 ], [ "general_graffiti", 20 ], [ "null", 75 ] ] }, - "r": { "chunks": [ [ "destroyed_rack", 20 ], [ "null", 80 ] ] }, - "]": { "chunks": [ [ "destroyed_rack", 20 ], [ "null", 80 ] ] }, - "t": { "chunks": [ [ "destroyed_table", 20 ], [ "null", 80 ] ] }, - "7": { "chunks": [ [ "destroyed_bookcase", 10 ], [ "null", 90 ] ] }, + "r": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] }, + "]": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] }, + "t": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] }, + "7": { "chunks": [ [ "destroyed_furniture", 10 ], [ "null", 90 ] ] }, "[": { "chunks": [ [ "destroyed_glass_door_wall", 80 ], [ "null", 20 ] ] }, "=": { "chunks": [ [ "destroyed_glass_door_wall", 80 ], [ "null", 20 ] ] }, - "f": { "chunks": [ [ "destroyed_glass_door_fridge", 20 ], [ "null", 80 ] ] } + "f": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] } } } }, @@ -630,8 +630,8 @@ "nested": { "|": { "chunks": [ [ "bile_field", 1 ], [ "shelter_graffiti", 10 ], [ "general_graffiti", 20 ], [ "null", 75 ] ] }, "-": { "chunks": [ [ "bile_field", 1 ], [ "shelter_graffiti", 10 ], [ "general_graffiti", 20 ], [ "null", 75 ] ] }, - "{": { "chunks": [ [ "destroyed_rack", 20 ], [ "null", 80 ] ] }, - "&": { "chunks": [ [ "destroyed_glass_door_fridge", 20 ], [ "null", 80 ] ] } + "{": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] }, + "&": { "chunks": [ [ "destroyed_furniture", 20 ], [ "null", 80 ] ] } } } }, diff --git a/data/json/mapgen/s_liquor.json b/data/json/mapgen/s_liquor.json index e2cadcc99f8a4..67add2be17008 100644 --- a/data/json/mapgen/s_liquor.json +++ b/data/json/mapgen/s_liquor.json @@ -174,8 +174,8 @@ "|": { "chunks": [ [ "bile_field", 10 ], [ "shelter_graffiti", 5 ], [ "general_graffiti", 20 ], [ "null", 75 ] ] }, "-": { "chunks": [ [ "bile_field", 10 ], [ "shelter_graffiti", 5 ], [ "general_graffiti", 20 ], [ "null", 75 ] ] }, ".": { "chunks": [ [ "bile_field", 10 ], [ "null", 90 ] ] }, - "#": { "chunks": [ [ "bile_field", 20 ], [ "destroyed_rack", 10 ], [ "null", 70 ] ] }, - "&": { "chunks": [ [ "bile_field", 20 ], [ "destroyed_glass_fridge", 30 ], [ "null", 50 ] ] } + "#": { "chunks": [ [ "bile_field", 20 ], [ "destroyed_furniture", 10 ], [ "null", 70 ] ] }, + "&": { "chunks": [ [ "bile_field", 20 ], [ "destroyed_furniture", 30 ], [ "null", 50 ] ] } } } }, From f753f0cb3def349abf1df60627ad97d524a75627 Mon Sep 17 00:00:00 2001 From: Zhilkin Serg Date: Wed, 7 Jul 2021 17:21:37 +0300 Subject: [PATCH 045/116] Lint json --- data/json/mapgen/nested/aux_nested.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/data/json/mapgen/nested/aux_nested.json b/data/json/mapgen/nested/aux_nested.json index 41dc1caee5ca1..501bda059b11f 100644 --- a/data/json/mapgen/nested/aux_nested.json +++ b/data/json/mapgen/nested/aux_nested.json @@ -47,10 +47,7 @@ "type": "mapgen", "method": "json", "nested_mapgen_id": "destroyed_furniture", - "object": { - "mapgensize": [ 1, 1 ], - "place_rubble": [ { "x": 0, "y": 0, "rubble_type": "f_null", "items": true } ] - } + "object": { "mapgensize": [ 1, 1 ], "place_rubble": [ { "x": 0, "y": 0, "rubble_type": "f_null", "items": true } ] } }, { "type": "mapgen", From 328c226aaa6a555a18be3e67ce8012a25c2e0ecc Mon Sep 17 00:00:00 2001 From: John Candlebury Date: Wed, 7 Jul 2021 08:24:58 -0600 Subject: [PATCH 046/116] Aftershock: New droneswarm foes + new simple monster AI behavior (#48740) --- data/mods/Aftershock/effects.json | 11 ++ data/mods/Aftershock/items/corpses.json | 18 ++- data/mods/Aftershock/items/grenades.json | 38 +++++ data/mods/Aftershock/items/inactiverobot.json | 25 +++- .../formless_ruins_dynamic.json | 69 +++++++++ data/mods/Aftershock/maps/nested/road.json | 19 +++ .../Aftershock/maps/overmap_map_extras.json | 12 ++ .../Aftershock/mobs/abstract_monsters.json | 89 ++++++++++++ data/mods/Aftershock/mobs/robots.json | 131 ++++++------------ .../Aftershock/recipes/deconstruction.json | 42 ++++++ data/mods/Aftershock/region_settings.json | 26 +++- .../Aftershock/spells/monster_spells.json | 37 +++++ .../aftershock_exoplanet/region_settings.json | 2 +- doc/JSON_FLAGS.md | 1 + doc/MONSTERS.md | 1 + src/monmove.cpp | 6 +- src/monster.cpp | 4 + src/monstergenerator.cpp | 3 + src/mtype.h | 4 + 19 files changed, 444 insertions(+), 94 deletions(-) create mode 100644 data/mods/Aftershock/maps/nested/road.json create mode 100644 data/mods/Aftershock/maps/overmap_map_extras.json create mode 100644 data/mods/Aftershock/mobs/abstract_monsters.json create mode 100644 data/mods/Aftershock/spells/monster_spells.json diff --git a/data/mods/Aftershock/effects.json b/data/mods/Aftershock/effects.json index 28fb303ecf93f..ffe41b1f3cb8e 100644 --- a/data/mods/Aftershock/effects.json +++ b/data/mods/Aftershock/effects.json @@ -92,5 +92,16 @@ "base_mods": { "dex_mod": [ 0.5 ], "speed_mod": [ 10 ] }, "scaling_mods": { "dex_mod": [ 0.5 ], "speed_mod": [ 10 ] }, "show_in_info": true + }, + { + "type": "effect_type", + "id": "afs_isohypsa_overwatch", + "name": [ "Isohypsa Overwatch" ], + "//~": "This is just a fragment of machine code, it needs no translation.", + "desc": [ "FE09- A3 65 FF ATT $#17A\nFE0B- 4E JMP $5010\nFE0D- A5 24 DEX $#05\n" ], + "rating": "good", + "blocks_effects": [ "sensor_stun", "dazed", "stunned", "blind" ], + "base_mods": { "dex_mod": [ 0.5 ], "speed_mod": [ 50 ] }, + "show_in_info": true } ] diff --git a/data/mods/Aftershock/items/corpses.json b/data/mods/Aftershock/items/corpses.json index 9ae73dc822741..7f6e2216d127b 100644 --- a/data/mods/Aftershock/items/corpses.json +++ b/data/mods/Aftershock/items/corpses.json @@ -201,9 +201,25 @@ "id": "broken_wraitheon_irradiant", "copy-from": "broken_advbot_disarmed", "color": "magenta", - "name": "broken Wraitheon Irradiant", + "name": "broken Irradiant", "description": "The irreparably broken remains of an Irradiant weapons platform. Its mounted plasma cannon self-destructed when the robot was rendered inoperable, but its remains could still be disassembled for some valuable parts." }, + { + "type": "GENERIC", + "id": "broken_wraitheon_isohypsa", + "copy-from": "broken_advbot_disarmed", + "color": "magenta", + "name": { "str_sp": "broken Isohypsa" }, + "description": "The broken shell of an Isohypsa drone coordinator. Most of its sensors and AI units are charred beyond any repair." + }, + { + "type": "GENERIC", + "id": "broken_wraitheon_kaburaya", + "copy-from": "broken_advbot_disarmed", + "color": "magenta", + "name": { "str_sp": "broken Kabura-ya" }, + "description": "A broken Kabura-ya drone. Could be disassembled for a meager amount of parts." + }, { "type": "GENERIC", "id": "broken_advbot_emp", diff --git a/data/mods/Aftershock/items/grenades.json b/data/mods/Aftershock/items/grenades.json index 9113e08deb232..7b030143b674c 100644 --- a/data/mods/Aftershock/items/grenades.json +++ b/data/mods/Aftershock/items/grenades.json @@ -1,4 +1,42 @@ [ + { + "id": "afs_kaburaya_bomb", + "type": "TOOL", + "copy-from": "grenade_canister", + "category": "weapons", + "looks_like": "c4", + "name": "Kabura-ya antipersonnel device", + "description": "A tiny plastic explosive meant to be installed in a Kabura-ya drone. Explodes 3 turns after activation.", + "use_action": { + "need_wielding": true, + "target": "afs_kaburaya_bomb_act", + "msg": "You activate the device.", + "target_charges": 3, + "active": true, + "menu_text": "Pull pin", + "type": "transform" + }, + "flags": [ "RADIO_MODABLE", "RADIO_INVOKE_PROC", "BOMB", "GRENADE" ] + }, + { + "id": "afs_kaburaya_bomb_act", + "type": "TOOL", + "copy-from": "grenade_canister", + "looks_like": "c4", + "name": "Armed Kabura-ya antipersonnel device", + "description": "A tiny plastic explosive meant to be installed within a Kabura-ya drone. It is on the verge of exploding.", + "initial_charges": 3, + "max_charges": 3, + "turns_per_charge": 2, + "use_action": { + "type": "explosion", + "sound_volume": 0, + "sound_msg": "Tick.", + "no_deactivate_msg": "You've already activated the %s; try throwing it instead.", + "explosion": { "power": 100, "max_noise": 25, "shrapnel": { "casing_mass": 217, "fragment_mass": 0.25 }, "distance_factor": 0.2 } + }, + "flags": [ "BOMB", "TRADER_AVOID" ] + }, { "id": "afs_electroshock_grenade_1", "type": "TOOL", diff --git a/data/mods/Aftershock/items/inactiverobot.json b/data/mods/Aftershock/items/inactiverobot.json index c334ea472ff15..aff33347f7ea8 100644 --- a/data/mods/Aftershock/items/inactiverobot.json +++ b/data/mods/Aftershock/items/inactiverobot.json @@ -184,7 +184,7 @@ "price": 600000, "to_hit": -3, "bashing": 8, - "material": [ "alien_resin" ], + "material": [ "aluminum", "plastic" ], "symbol": ";", "color": "green", "use_action": { @@ -195,6 +195,29 @@ "skills": [ "computer" ] } }, + { + "id": "bot_wraitheon_kaburaya", + "type": "TOOL", + "name": { "str": "inactive Kabura-ya drone" }, + "description": "An inactive Karuba-ya hunter drone, folded for ease of storage. If deployed, it will seek and fly to the closest enemy before detonating. Unlike most robots, its activation depends on a successful throw, and not on your computer skill.", + "weight": "550 g", + "volume": "250 ml", + "price": 5000, + "to_hit": -3, + "bashing": 0, + "material": [ "aluminum", "plastic" ], + "symbol": ";", + "color": "green", + "use_action": { + "type": "place_monster", + "monster_id": "mon_wraitheon_kaburaya", + "friendly_msg": "The Kabura-ya emits a short IFF chirp as you throw it.", + "hostile_msg": "The Kabura-ya emits an warning whine after your botched throw!", + "difficulty": 1, + "moves": 100, + "skills": [ "throw" ] + } + }, { "id": "bot_bloodhound_drone", "type": "TOOL", diff --git a/data/mods/Aftershock/maps/mapgen/formless_ruins/formless_ruins_dynamic.json b/data/mods/Aftershock/maps/mapgen/formless_ruins/formless_ruins_dynamic.json index 7f6327ca83929..c78d4579c9a43 100644 --- a/data/mods/Aftershock/maps/mapgen/formless_ruins/formless_ruins_dynamic.json +++ b/data/mods/Aftershock/maps/mapgen/formless_ruins/formless_ruins_dynamic.json @@ -150,6 +150,75 @@ "place_monsters": [ { "monster": "AFS_GROUP_MOXIE_LOW_RISK", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 10, "density": 0.1 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "afs_formless_ruins_dynamic" ], + "//": "emptier map with a droneswarm, very rare", + "weight": 10, + "object": { + "predecessor_mapgen": "field", + "rows": [ + " .1 ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " 1 ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "afs_formless_ruins" ], + "nested": { + "1": { + "chunks": [ + [ "formless_ruins_ribs1", 20 ], + [ "formless_ruins_ribs2", 20 ], + [ "formless_ruins_twoway1", 20 ], + [ "formless_ruins_twoway2", 20 ], + [ "formless_ruins_twoway3", 20 ], + [ "formless_ruins_pillar1", 20 ], + [ "formless_ruins_pillar2", 20 ], + [ "formless_ruins_orderly1", 10 ], + [ "formless_ruins_orderly2", 10 ], + [ "formless_ruins_orderly3", 10 ], + [ "formless_ruins_orderly4", 10 ], + [ "formless_ruins_empty1", 10 ], + [ "formless_ruins_empty2", 10 ], + [ "formless_ruins_empty3", 10 ], + [ "formless_ruins_empty4", 10 ] + ] + } + }, + "place_loot": [ { "group": "afs_formless_ruins_random_loot", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 4 ] } ], + "place_monster": [ + { "monster": "mon_wraitheon_isohypsa", "x": 12, "y": 12, "spawn_data": { "patrol": [ { "x": 12, "y": 12 } ] } }, + { + "monster": "mon_wraitheon_irradiant", + "x": 8, + "y": 8, + "spawn_data": { "patrol": [ { "x": 8, "y": 8 }, { "x": 8, "y": 16 }, { "x": 16, "y": 16 }, { "x": 16, "y": 8 } ] } + }, + { "monster": "mon_wraitheon_kaburaya", "x": 4, "y": 4, "repeat": [ 6, 10 ] } + ] + } + }, { "type": "mapgen", "method": "json", diff --git a/data/mods/Aftershock/maps/nested/road.json b/data/mods/Aftershock/maps/nested/road.json new file mode 100644 index 0000000000000..0b768c2404d66 --- /dev/null +++ b/data/mods/Aftershock/maps/nested/road.json @@ -0,0 +1,19 @@ +[ + { + "type": "mapgen", + "method": "json", + "update_mapgen_id": "mx_wraitheon_droneswarm", + "object": { + "place_monster": [ + { "monster": "mon_wraitheon_isohypsa", "x": 12, "y": 12, "spawn_data": { "patrol": [ { "x": 12, "y": 12 } ] } }, + { + "monster": "mon_wraitheon_irradiant", + "x": 8, + "y": 8, + "spawn_data": { "patrol": [ { "x": 8, "y": 8 }, { "x": 8, "y": 16 }, { "x": 16, "y": 16 }, { "x": 16, "y": 8 } ] } + }, + { "monster": "mon_wraitheon_kaburaya", "x": 4, "y": 4, "repeat": [ 6, 10 ] } + ] + } + } +] diff --git a/data/mods/Aftershock/maps/overmap_map_extras.json b/data/mods/Aftershock/maps/overmap_map_extras.json new file mode 100644 index 0000000000000..ff4307546b412 --- /dev/null +++ b/data/mods/Aftershock/maps/overmap_map_extras.json @@ -0,0 +1,12 @@ +[ + { + "id": "mx_wraitheon_droneswarm", + "type": "map_extra", + "name": { "str": "Wraitheon Droneswarm" }, + "description": "A group of combat drones.", + "generator": { "generator_method": "update_mapgen", "generator_id": "mx_wraitheon_droneswarm" }, + "sym": "w", + "color": "pink", + "autonote": true + } +] diff --git a/data/mods/Aftershock/mobs/abstract_monsters.json b/data/mods/Aftershock/mobs/abstract_monsters.json new file mode 100644 index 0000000000000..d2fbd1dc34a4b --- /dev/null +++ b/data/mods/Aftershock/mobs/abstract_monsters.json @@ -0,0 +1,89 @@ +[ + { + "abstract": "mon_milbot_base", + "type": "MONSTER", + "looks_like": "mon_secubot", + "name": "military robot", + "description": "A military robot still operating due to its internal power core. This one is armed with an electric prod and an integrated 5.56mm.", + "default_faction": "WraitheonRobotics", + "species": [ "ROBOT" ], + "volume": "62500 ml", + "weight": "81500 g", + "hp": 80, + "speed": 100, + "material": [ "steel" ], + "symbol": "R", + "color": "red_green", + "aggression": 50, + "morale": 100, + "melee_skill": 4, + "melee_dice": 2, + "melee_dice_sides": 4, + "dodge": 4, + "armor_bash": 12, + "armor_cut": 12, + "armor_stab": 6, + "armor_fire": 5, + "armor_acid": 12, + "vision_day": 50, + "path_settings": { "max_dist": 5 }, + "death_drops": { "groups": [ [ "broken_robots", 1 ] ] }, + "death_function": [ "BROKEN" ], + "flags": [ "SEES", "HEARS", "BASHES", "ELECTRONIC", "NO_BREATHE", "PRIORITIZE_TARGETS", "PATH_AVOID_DANGER_1" ] + }, + { + "abstract": "mon_defbot_base", + "type": "MONSTER", + "looks_like": "mon_secubot", + "name": "defense robot", + "description": "An automated defense robot still active due to its internal power source. This one is armed with an electric prod and an integrated 9mm firearm.", + "default_faction": "cop_bot", + "species": [ "ROBOT" ], + "diff": 10, + "volume": "62500 ml", + "weight": "81500 g", + "hp": 80, + "speed": 100, + "material": [ "steel" ], + "symbol": "R", + "color": "light_blue", + "aggression": 100, + "morale": 100, + "luminance": 20, + "melee_skill": 4, + "melee_dice": 2, + "melee_dice_sides": 4, + "dodge": 4, + "armor_bash": 10, + "armor_cut": 10, + "armor_stab": 5, + "armor_fire": 5, + "armor_acid": 10, + "vision_day": 50, + "path_settings": { "max_dist": 5 }, + "death_drops": { "groups": [ [ "broken_robots", 1 ] ] }, + "death_function": [ "BROKEN" ], + "flags": [ "SEES", "HEARS", "BASHES", "ELECTRONIC", "NO_BREATHE", "PRIORITIZE_TARGETS", "PATH_AVOID_DANGER_1" ] + }, + { + "abstract": "mon_advbot_base", + "type": "MONSTER", + "copy-from": "mon_defbot_base", + "looks_like": "mon_copbot", + "name": "advanced robot", + "description": "An advanced robot still functioning due to its internal fusion core. This model is armed with a powerful laser-emitter.", + "default_faction": "defense_bot", + "species": [ "ROBOT" ], + "hp": 100, + "armor_bash": 8, + "armor_cut": 6, + "armor_stab": 6, + "armor_fire": 8, + "armor_acid": 12, + "vision_day": 50, + "speed": 110, + "color": "white_cyan", + "aggression": 100, + "dodge": 5 + } +] diff --git a/data/mods/Aftershock/mobs/robots.json b/data/mods/Aftershock/mobs/robots.json index 6bd58ca042a00..274754bc4c9c9 100644 --- a/data/mods/Aftershock/mobs/robots.json +++ b/data/mods/Aftershock/mobs/robots.json @@ -466,38 +466,6 @@ ], "extend": { "flags": [ "DROPS_AMMO" ] } }, - { - "abstract": "mon_milbot_base", - "type": "MONSTER", - "looks_like": "mon_secubot", - "name": "military robot", - "description": "A military robot still operating due to its internal power core. This one is armed with an electric prod and an integrated 5.56mm.", - "default_faction": "WraitheonRobotics", - "species": [ "ROBOT" ], - "volume": "62500 ml", - "weight": "81500 g", - "hp": 80, - "speed": 100, - "material": [ "steel" ], - "symbol": "R", - "color": "red_green", - "aggression": 50, - "morale": 100, - "melee_skill": 4, - "melee_dice": 2, - "melee_dice_sides": 4, - "dodge": 4, - "armor_bash": 12, - "armor_cut": 12, - "armor_stab": 6, - "armor_fire": 5, - "armor_acid": 12, - "vision_day": 50, - "path_settings": { "max_dist": 5 }, - "death_drops": { "groups": [ [ "broken_robots", 1 ] ] }, - "death_function": [ "BROKEN" ], - "flags": [ "SEES", "HEARS", "BASHES", "ELECTRONIC", "NO_BREATHE", "PRIORITIZE_TARGETS", "PATH_AVOID_DANGER_1" ] - }, { "id": "mon_milbot_556", "type": "MONSTER", @@ -592,27 +560,6 @@ ], "extend": { "flags": [ "DROPS_AMMO" ] } }, - { - "abstract": "mon_advbot_base", - "type": "MONSTER", - "copy-from": "mon_defbot_base", - "looks_like": "mon_copbot", - "name": "advanced robot", - "description": "An advanced robot still functioning due to its internal fusion core. This model is armed with a powerful laser-emitter.", - "default_faction": "defense_bot", - "species": [ "ROBOT" ], - "hp": 100, - "armor_bash": 8, - "armor_cut": 6, - "armor_stab": 6, - "armor_fire": 8, - "armor_acid": 12, - "vision_day": 50, - "speed": 110, - "color": "white_cyan", - "aggression": 100, - "dodge": 5 - }, { "id": "mon_advbot_laser", "type": "MONSTER", @@ -680,6 +627,50 @@ { "type": "leap", "cooldown": 10, "max_range": 8 } ] }, + { + "id": "mon_wraitheon_isohypsa", + "type": "MONSTER", + "copy-from": "mon_advbot_base", + "name": "Wraitheon Isohypsa", + "description": "A bulky if not particularly large aerial drone, with an advanced AI overwatch unit and a bulbous carapace, mostly dedicated to mounting high-resolution sensors. As an autonomous drone control platform, the Isohypsa is principally meant to coordinate and enhance the combat capabilities of simpler Wraitheon robots in lieu of human operators.", + "default_faction": "WraitheonRobotics", + "symbol": "y", + "diff": 20, + "speed": 100, + "color": "light_red", + "armor_bash": 20, + "armor_cut": 30, + "armor_fire": 15, + "armor_bullet": 35, + "morale": 20, + "luminance": 20, + "tracking_distance": 20, + "extend": { "flags": [ "FIREPROOF", "PACIFIST", "KEEP_DISTANCE", "FLIES" ] }, + "special_attacks": [ + { + "type": "spell", + "spell_data": { "id": "isohypsa_buff", "hit_self": true }, + "cooldown": 5, + "monster_message": "The Isohypsa emits a rapid sequence of sibilant tones!" + } + ] + }, + { + "id": "mon_wraitheon_kaburaya", + "copy-from": "base_drone", + "type": "MONSTER", + "name": "Wraitheon Kabura-ya", + "description": "A microplane drone designed to seek enemy personnel before detonating at close range.", + "default_faction": "WraitheonRobotics", + "diff": 10, + "speed": 250, + "color": "green", + "armor_cut": 4, + "armor_bullet": 3, + "revert_to_itype": "bot_wraitheon_kaburaya", + "starting_ammo": { "afs_kaburaya_bomb": 1 }, + "special_attacks": [ [ "KAMIKAZE", 0 ] ] + }, { "id": "mon_advbot_emp", "type": "MONSTER", @@ -706,39 +697,5 @@ "targeting_volume": 10 } ] - }, - { - "abstract": "mon_defbot_base", - "type": "MONSTER", - "looks_like": "mon_secubot", - "name": "defense robot", - "description": "An automated defense robot still active due to its internal power source. This one is armed with an electric prod and an integrated 9mm firearm.", - "default_faction": "cop_bot", - "species": [ "ROBOT" ], - "diff": 10, - "volume": "62500 ml", - "weight": "81500 g", - "hp": 80, - "speed": 100, - "material": [ "steel" ], - "symbol": "R", - "color": "light_blue", - "aggression": 100, - "morale": 100, - "luminance": 20, - "melee_skill": 4, - "melee_dice": 2, - "melee_dice_sides": 4, - "dodge": 4, - "armor_bash": 10, - "armor_cut": 10, - "armor_stab": 5, - "armor_fire": 5, - "armor_acid": 10, - "vision_day": 50, - "path_settings": { "max_dist": 5 }, - "death_drops": { "groups": [ [ "broken_robots", 1 ] ] }, - "death_function": [ "BROKEN" ], - "flags": [ "SEES", "HEARS", "BASHES", "ELECTRONIC", "NO_BREATHE", "PRIORITIZE_TARGETS", "PATH_AVOID_DANGER_1" ] } ] diff --git a/data/mods/Aftershock/recipes/deconstruction.json b/data/mods/Aftershock/recipes/deconstruction.json index 8fe5e31e6e793..b7ca56af712e2 100644 --- a/data/mods/Aftershock/recipes/deconstruction.json +++ b/data/mods/Aftershock/recipes/deconstruction.json @@ -152,6 +152,48 @@ [ [ "flamethrower", 1 ] ] ] }, + { + "result": "broken_wraitheon_isohypsa", + "type": "uncraft", + "activity_level": "fake", + "skill_used": "electronics", + "difficulty": 8, + "time": "5 h", + "using": [ [ "soldering_standard", 10 ], [ "welding_standard", 10 ] ], + "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ], + "components": [ + [ [ "ai_module", 4 ] ], + [ [ "self_monitoring_module", 1 ] ], + [ [ "sensor_module", 2 ] ], + [ [ "memory_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 4 ] ], + [ [ "quad_rotors", 5 ] ], + [ [ "targeting_module", 1 ] ], + [ [ "afs_magnet_3", 4 ] ], + [ [ "afs_circuitry_4", 1 ] ], + [ [ "afs_material_1", 10 ] ], + [ [ "afs_material_3", 1 ] ], + [ [ "afs_heat_2_salvage", 2 ] ], + [ [ "afs_energy_storage_4", 1 ] ] + ] + }, + { + "result": "broken_wraitheon_kaburaya", + "type": "uncraft", + "activity_level": "fake", + "skill_used": "electronics", + "difficulty": 4, + "time": "10 m", + "using": [ [ "soldering_standard", 5 ], [ "welding_standard", 10 ] ], + "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "SAW_M_FINE", "level": 1 } ], + "components": [ + [ [ "afs_magnet_1", 1 ] ], + [ [ "afs_circuitry_1", 1 ] ], + [ [ "afs_material_1", 2 ] ], + [ [ "afs_energy_storage_1", 1 ] ] + ] + }, { "result": "broken_bloodhound_drone", "type": "uncraft", diff --git a/data/mods/Aftershock/region_settings.json b/data/mods/Aftershock/region_settings.json index cd6d15df81077..0cc57c09f0dbd 100644 --- a/data/mods/Aftershock/region_settings.json +++ b/data/mods/Aftershock/region_settings.json @@ -17,6 +17,30 @@ }, "houses": { "afs_city_ruinfield": 200, "afs_formless_ruins_dynamic": 300, "afs_house_1": 100 } }, - "overmap_lake_settings": { "noise_threshold_lake": 0.12 } + "overmap_lake_settings": { "noise_threshold_lake": 0.12 }, + "map_extras": { + "road": { + "chance": 75, + "extras": { + "mx_helicopter": 1, + "mx_military": 25, + "mx_science": 40, + "mx_collegekids": 50, + "mx_wraitheon_droneswarm": 10, + "mx_roadblock": 100, + "mx_bandits_block": 80, + "mx_drugdeal": 30, + "mx_supplydrop": 10, + "mx_portal": 5, + "mx_crater": 10, + "mx_portal_in": 4, + "mx_roadworks": 100, + "mx_mayhem": 50, + "mx_casings": 100, + "mx_corpses": 30, + "mx_prison_bus": 15 + } + } + } } ] diff --git a/data/mods/Aftershock/spells/monster_spells.json b/data/mods/Aftershock/spells/monster_spells.json new file mode 100644 index 0000000000000..f7805b5795f16 --- /dev/null +++ b/data/mods/Aftershock/spells/monster_spells.json @@ -0,0 +1,37 @@ +[ + { + "id": "isohypsa_buff", + "type": "SPELL", + "name": { "str": "Isohypsa Coordination" }, + "description": "Increases the speed of simpler Wraitheon drones.", + "valid_targets": [ "self", "ally" ], + "targeted_monster_ids": [ + "mon_chickenbot", + "mon_tankbot", + "afs_mon_sentinel_lx", + "mon_defbot_shot", + "mon_advbot_laser", + "mon_wraitheon_irradiant", + "mon_wraitheon_kaburaya", + "mon_wraitheon_isohypsa", + "mon_advbot_emp" + ], + "flags": [ "NO_HANDS", "NO_LEGS" ], + "effect": "attack", + "effect_str": "afs_isohypsa_overwatch", + "shape": "blast", + "affected_body_parts": [ "torso" ], + "base_casting_time": 100, + "base_energy_cost": 100, + "energy_source": "MANA", + "difficulty": 1, + "max_level": 1, + "min_aoe": 40, + "max_aoe": 40, + "min_range": 10, + "max_range": 10, + "//": "duration is in moves", + "min_duration": 500, + "max_duration": 500 + } +] diff --git a/data/mods/aftershock_exoplanet/region_settings.json b/data/mods/aftershock_exoplanet/region_settings.json index 6181d39bb2e57..0bdd0d4dab127 100644 --- a/data/mods/aftershock_exoplanet/region_settings.json +++ b/data/mods/aftershock_exoplanet/region_settings.json @@ -202,6 +202,6 @@ "trail_terrain": { "t_deaddirt": 1 }, "trailheads": { "trailhead_basic": 1, "trailhead_outhouse": 1, "trailhead_shack": 1 } }, - "map_extras": { } + "map_extras": { "road": { "chance": 75, "extras": { "mx_wraitheon_droneswarm": 10 } } } } ] diff --git a/doc/JSON_FLAGS.md b/doc/JSON_FLAGS.md index 84c67f308f17c..585752303986f 100644 --- a/doc/JSON_FLAGS.md +++ b/doc/JSON_FLAGS.md @@ -954,6 +954,7 @@ Other monster flags. - ```PET_HARNESSABLE```Creature can be attached to an harness. - ```NULL``` Source use only. - ```PACIFIST``` Monster will never do melee attacks. +- ```KEEP_DISTANCE``` Monster will try to keep `tracking_distance` number of tiles between it and its current target. - ```PARALYZE``` Attack may paralyze the player with venom. - ```PLASTIC``` Absorbs physical damage to a great degree. - ```POISON``` Poisonous to eat. diff --git a/doc/MONSTERS.md b/doc/MONSTERS.md index 71e5a7feacaee..2eedc4a7ef2c4 100644 --- a/doc/MONSTERS.md +++ b/doc/MONSTERS.md @@ -65,6 +65,7 @@ Monsters may also have any of these optional properties: | `armor_fire` | (integer) Monster's protection from fire damage | `vision_day` | (integer) Vision range in full daylight, with `50` being the typical maximum | `vision_night` | (integer) Vision range in total darkness, ex. coyote `5`, bear `10`, sewer rat `30`, flaming eye `40` +| `tracking_distance` | (integer) Amount of tiles the monster will keep between itself and its current tracked enemy or followed leader. Defaults to `8`. | `luminance` | (integer) Amount of light passively emitted by the monster, from `0-10` | `death_drops` | (string or item group) Item group to spawn when the monster dies | `death_function` | (array of strings) How the monster behaves on death. See JSON_FLAGS diff --git a/src/monmove.cpp b/src/monmove.cpp index aae3f1882c41d..06e7ec488450a 100644 --- a/src/monmove.cpp +++ b/src/monmove.cpp @@ -73,8 +73,6 @@ static const species_id species_ZOMBIE( "ZOMBIE" ); static const std::string flag_AUTODOC_COUCH( "AUTODOC_COUCH" ); static const std::string flag_LIQUID( "LIQUID" ); -static constexpr int MONSTER_FOLLOW_DIST = 8; - bool monster::wander() { return ( goal == pos() && patrol_route_abs_ms.empty() ); @@ -853,7 +851,9 @@ void monster::move() } if( ( current_attitude == MATT_IGNORE && patrol_route_abs_ms.empty() ) || - ( current_attitude == MATT_FOLLOW && rl_dist( pos(), goal ) <= MONSTER_FOLLOW_DIST ) ) { + ( ( current_attitude == MATT_FOLLOW || + ( has_flag( MF_KEEP_DISTANCE ) && !( current_attitude == MATT_FLEE ) ) ) + && rl_dist( pos(), goal ) <= type->tracking_distance ) ) { moves = 0; stumble(); return; diff --git a/src/monster.cpp b/src/monster.cpp index c3d4079179ef3..e7eb144711b90 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -1256,6 +1256,10 @@ monster_attitude monster::attitude( const Character *u ) const return MATT_FOLLOW; } + if( has_flag( MF_KEEP_DISTANCE ) && rl_dist( pos(), goal ) < type->tracking_distance ) { + return MATT_FLEE; + } + return MATT_ATTACK; } diff --git a/src/monstergenerator.cpp b/src/monstergenerator.cpp index 1c760e4f04532..b03cb280673fd 100644 --- a/src/monstergenerator.cpp +++ b/src/monstergenerator.cpp @@ -158,6 +158,7 @@ std::string enum_to_string( m_flag data ) case MF_REVIVES_HEALTHY: return "REVIVES_HEALTHY"; case MF_NO_NECRO: return "NO_NECRO"; case MF_PACIFIST: return "PACIFIST"; + case MF_KEEP_DISTANCE: return "KEEP_DISTANCE"; case MF_PUSH_MON: return "PUSH_MON"; case MF_PUSH_VEH: return "PUSH_VEH"; case MF_AVOID_DANGER_1: return "PATH_AVOID_DANGER_1"; @@ -759,6 +760,8 @@ void mtype::load( const JsonObject &jo, const std::string &src ) assign( jo, "aggression", agro, strict, -100, 100 ); assign( jo, "morale", morale, strict ); + assign( jo, "tracking_distance", tracking_distance, strict, 8 ); + assign( jo, "mountable_weight_ratio", mountable_weight_ratio, strict ); assign( jo, "attack_cost", attack_cost, strict, 0 ); diff --git a/src/mtype.h b/src/mtype.h index ac9b6e7dbba7b..c7b28b576b3f9 100644 --- a/src/mtype.h +++ b/src/mtype.h @@ -144,6 +144,7 @@ enum m_flag : int { MF_INTERIOR_AMMO, // Monster contain's its ammo inside itself, no need to load on launch. Prevents ammo from being dropped on disable. MF_CLIMBS, // Monsters that can climb certain terrain and furniture MF_PACIFIST, // Monsters that will never use melee attack, useful for having them use grab without attacking the player + MF_KEEP_DISTANCE, // Attempts to keep a short distance (tracking_distance) from its current target. The default tracking distance is 8 tiles MF_PUSH_MON, // Monsters that can push creatures out of their way MF_PUSH_VEH, // Monsters that can push vehicles out of their way MF_NIGHT_INVISIBILITY, // Monsters that are invisible in poor light conditions @@ -256,6 +257,9 @@ struct mtype { int agro = 0; /** chance will attack [-100,100] */ int morale = 0; /** initial morale level at spawn */ + // how close the monster is willing to approach its target while under the MATT_FOLLOW attitude + int tracking_distance = 8; + // Number of hitpoints regenerated per turn. int regenerates = 0; // Monster regenerates very quickly in poorly lit tiles. From b5dc3c4b38591017f1f8492f258effbbdd378e1a Mon Sep 17 00:00:00 2001 From: Eric <52087122+Ramza13@users.noreply.github.com> Date: Wed, 7 Jul 2021 10:26:18 -0400 Subject: [PATCH 047/116] Unhardcode speed modifiers/fix speed enchantment (#47963) --- data/json/bionics.json | 1 + data/json/mutations/mutations.json | 8 ++++---- data/mods/DinoMod/mutations/mutations.json | 2 +- data/mods/Magiclysm/traits/attunements.json | 4 ++-- src/character.cpp | 1 - src/character.h | 7 ++++--- src/magic_enchantment.cpp | 3 --- src/mutation.h | 1 - src/mutation_data.cpp | 1 - src/player.cpp | 8 ++------ src/player_display.cpp | 19 ++++++------------- 11 files changed, 20 insertions(+), 35 deletions(-) diff --git a/data/json/bionics.json b/data/json/bionics.json index 9ac153cf53327..883a97f88f619 100644 --- a/data/json/bionics.json +++ b/data/json/bionics.json @@ -1314,6 +1314,7 @@ [ "foot_l", 2 ], [ "foot_r", 2 ] ], + "enchantments": [ { "condition": "ALWAYS", "values": [ { "value": "SPEED", "multiply": 0.1 } ] } ], "flags": [ "BIONIC_NPC_USABLE" ] }, { diff --git a/data/json/mutations/mutations.json b/data/json/mutations/mutations.json index e6af6ef916f97..b4e1da072d360 100644 --- a/data/json/mutations/mutations.json +++ b/data/json/mutations/mutations.json @@ -255,7 +255,7 @@ "description": "You're just generally quick! You get a 10% bonus to action points.", "starting_trait": true, "category": [ "FISH", "BIRD", "INSECT", "TROGLOBITE", "CHIMERA", "RAPTOR", "MOUSE" ], - "speed_modifier": 1.1 + "enchantments": [ { "condition": "ALWAYS", "values": [ { "value": "SPEED", "multiply": 0.1 } ] } ] }, { "type": "mutation", @@ -1917,7 +1917,7 @@ "bash": 3 } ], - "speed_modifier": 0.8 + "enchantments": [ { "condition": "ALWAYS", "values": [ { "value": "SPEED", "multiply": -0.2 } ] } ] }, { "type": "mutation", @@ -1952,7 +1952,7 @@ "bash": 5 } ], - "speed_modifier": 0.8 + "enchantments": [ "ENCH_TRAIT_MSKIN" ] }, { "type": "mutation", @@ -4617,7 +4617,7 @@ "threshreq": [ "THRESH_MOUSE" ], "category": [ "MOUSE" ], "stealth_modifier": 40, - "speed_modifier": 1.15, + "enchantments": [ { "condition": "ALWAYS", "values": [ { "value": "SPEED", "multiply": 0.15 } ] } ], "movecost_modifier": 0.75 }, { diff --git a/data/mods/DinoMod/mutations/mutations.json b/data/mods/DinoMod/mutations/mutations.json index 901a11cba6b70..31fdd2dfd2405 100644 --- a/data/mods/DinoMod/mutations/mutations.json +++ b/data/mods/DinoMod/mutations/mutations.json @@ -127,7 +127,7 @@ "bullet": 6 } ], - "speed_modifier": 0.95 + "enchantments": [ { "condition": "ALWAYS", "values": [ { "value": "SPEED", "multiply": -0.05 } ] } ] }, { "type": "mutation", diff --git a/data/mods/Magiclysm/traits/attunements.json b/data/mods/Magiclysm/traits/attunements.json index 0cc9497ed6dc9..7ff06b3d9ffbf 100644 --- a/data/mods/Magiclysm/traits/attunements.json +++ b/data/mods/Magiclysm/traits/attunements.json @@ -381,7 +381,6 @@ "description": "Force = Mass x Acceleration. This is the typical thing that people think of nowadays when the word is used, but Force Mages have a different meaning, coming from traditional roots: untyped magical damage appears to be a ghostly \"force.\" This might be the effect of the attunement, but the cause is even more intriguing: they appear to turn Newton's Third Law on its head. Magical scholars of the 21st century have theorized that this isn't really the case; instead of the opposite reaction happening on this plane of existence, a Force Mage uses the Aetherium's alternate Laws to rebound the force back upon itself, effectively doubling the force in the same direction instead. However this ability comes with limitations, as the Force Mage can only do this for melee damage.", "prereqs": [ "MAGUS", "STORMSHAPER" ], "spells_learned": [ [ "force_blade", 5 ], [ "force_magical_armor", 5 ] ], - "speed_modifier": 1.2, "cancels": [ "ARTIFICER", "AURA_MAGE", @@ -410,7 +409,8 @@ "SOULFIRE", "WITHER_MAGE" ], - "flags": [ "ATTUNEMENT" ] + "flags": [ "ATTUNEMENT" ], + "enchantments": [ { "condition": "ALWAYS", "values": [ { "value": "SPEED", "multiply": 0.2 } ] } ] }, { "id": "GAIAS_CHOSEN", diff --git a/src/character.cpp b/src/character.cpp index 6d3562f4e0626..017a7be189faa 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -8078,7 +8078,6 @@ mutation_value_map = { { "mana_regen_multiplier", calc_mutation_value_multiplicative<&mutation_branch::mana_regen_multiplier> }, { "bionic_mana_penalty", calc_mutation_value_multiplicative<&mutation_branch::bionic_mana_penalty> }, { "casting_time_multiplier", calc_mutation_value_multiplicative<&mutation_branch::casting_time_multiplier> }, - { "speed_modifier", calc_mutation_value_multiplicative<&mutation_branch::speed_modifier> }, { "movecost_modifier", calc_mutation_value_multiplicative<&mutation_branch::movecost_modifier> }, { "movecost_flatground_modifier", calc_mutation_value_multiplicative<&mutation_branch::movecost_flatground_modifier> }, { "movecost_obstacle_modifier", calc_mutation_value_multiplicative<&mutation_branch::movecost_obstacle_modifier> }, diff --git a/src/character.h b/src/character.h index 30e694d4b8e13..4aab7ffbf1a19 100644 --- a/src/character.h +++ b/src/character.h @@ -2910,9 +2910,6 @@ class Character : public Creature, public visitable */ void burn_fuel( int b, const auto_toggle_bionic_result &result ); - // a cache of all active enchantment values. - // is recalculated every turn in Character::recalculate_enchantment_cache - pimpl enchantment_cache; player_activity destination_activity; /// A unique ID number, assigned by the game class. Values should never be reused. character_id id; @@ -2972,6 +2969,10 @@ class Character : public Creature, public visitable public: time_point next_climate_control_check; bool last_climate_control_ret; + + // a cache of all active enchantment values. + // is recalculated every turn in Character::recalculate_enchantment_cache + pimpl enchantment_cache; }; Character &get_player_character(); diff --git a/src/magic_enchantment.cpp b/src/magic_enchantment.cpp index 8c178db71af55..3c7df4924e11e 100644 --- a/src/magic_enchantment.cpp +++ b/src/magic_enchantment.cpp @@ -489,9 +489,6 @@ void enchantment::activate_passive( Character &guy ) const guy.mod_int_bonus( get_value_add( enchant_vals::mod::INTELLIGENCE ) ); guy.mod_int_bonus( mult_bonus( enchant_vals::mod::INTELLIGENCE, guy.get_int_base() ) ); - guy.mod_speed_bonus( get_value_add( enchant_vals::mod::SPEED ) ); - guy.mod_speed_bonus( mult_bonus( enchant_vals::mod::SPEED, guy.get_speed_base() ) ); - guy.mod_num_dodges_bonus( get_value_add( enchant_vals::mod::BONUS_DODGE ) ); guy.mod_num_dodges_bonus( mult_bonus( enchant_vals::mod::BONUS_DODGE, guy.get_num_dodges_base() ) ); diff --git a/src/mutation.h b/src/mutation.h index 9357baf48434d..8e30556e810d1 100644 --- a/src/mutation.h +++ b/src/mutation.h @@ -189,7 +189,6 @@ struct mutation_branch { std::pair rand_bash_bonus; // Additional bonuses cata::optional dodge_modifier = cata::nullopt; - cata::optional speed_modifier = cata::nullopt; cata::optional movecost_modifier = cata::nullopt; cata::optional movecost_flatground_modifier = cata::nullopt; cata::optional movecost_obstacle_modifier = cata::nullopt; diff --git a/src/mutation_data.cpp b/src/mutation_data.cpp index 2600d3de911a1..c65f4bd865820 100644 --- a/src/mutation_data.cpp +++ b/src/mutation_data.cpp @@ -423,7 +423,6 @@ void mutation_branch::load( const JsonObject &jo, const std::string & ) optional( jo, was_loaded, "pierce_dmg_bonus", pierce_dmg_bonus, 0.0f ); optional( jo, was_loaded, "bash_dmg_bonus", bash_dmg_bonus, 0 ); optional( jo, was_loaded, "dodge_modifier", dodge_modifier, cata::nullopt ); - optional( jo, was_loaded, "speed_modifier", speed_modifier, cata::nullopt ); optional( jo, was_loaded, "movecost_modifier", movecost_modifier, cata::nullopt ); optional( jo, was_loaded, "movecost_flatground_modifier", movecost_flatground_modifier, cata::nullopt ); diff --git a/src/player.cpp b/src/player.cpp index a251edf09c439..5cfb1b2184525 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -142,7 +142,6 @@ static const proficiency_id proficiency_prof_spotting( "prof_spotting" ); static const bionic_id bio_cqb( "bio_cqb" ); static const bionic_id bio_ground_sonar( "bio_ground_sonar" ); static const bionic_id bio_soporific( "bio_soporific" ); -static const bionic_id bio_speed( "bio_speed" ); static const json_character_flag json_flag_FEATHER_FALL( "FEATHER_FALL" ); @@ -468,13 +467,10 @@ void player::recalc_speed_bonus() } } - float speed_modifier = Character::mutation_value( "speed_modifier" ); + float speed_modifier = static_cast( enchantment_cache->modify_value( + enchant_vals::mod::SPEED, 1 ) ); set_speed_bonus( static_cast( get_speed() * speed_modifier ) - get_speed_base() ); - if( has_bionic( bio_speed ) ) { // multiply by 1.1 - set_speed_bonus( static_cast( get_speed() * 1.1 ) - get_speed_base() ); - } - // Speed cannot be less than 25% of base speed, so minimal speed bonus is -75% base speed. const int min_speed_bonus = static_cast( -0.75 * get_speed_base() ); if( get_speed_bonus() < min_speed_bonus ) { diff --git a/src/player_display.cpp b/src/player_display.cpp index cc403e8e0c21b..22f63abaf37bb 100644 --- a/src/player_display.cpp +++ b/src/player_display.cpp @@ -937,20 +937,13 @@ static void draw_speed_tab( const catacurses::window &w_speed, } } - int quick_bonus = static_cast( newmoves - ( newmoves / 1.1 ) ); - int bio_speed_bonus = quick_bonus; - if( you.has_trait( trait_id( "QUICK" ) ) && you.has_bionic( bionic_id( "bio_speed" ) ) ) { - bio_speed_bonus = static_cast( newmoves / 1.1 - ( newmoves / 1.1 / 1.1 ) ); - std::swap( quick_bonus, bio_speed_bonus ); - } - if( you.has_trait( trait_id( "QUICK" ) ) ) { - mvwprintz( w_speed, point( 1, line ), c_green, - pgettext( "speed bonus", "Quick +%2d%%" ), quick_bonus ); - line++; - } - if( you.has_bionic( bionic_id( "bio_speed" ) ) ) { + float speed_modifier = static_cast( you.enchantment_cache->modify_value( + enchant_vals::mod::SPEED, 1 ) ); + + if( speed_modifier != 1.0f ) { + int misc_bonus = static_cast( newmoves - ( newmoves / speed_modifier ) ); mvwprintz( w_speed, point( 1, line ), c_green, - pgettext( "speed bonus", "Bionic Speed +%2d%%" ), bio_speed_bonus ); + pgettext( "speed bonus", "Bio/Mut/Effects +%2d%%" ), misc_bonus ); line++; } From 83bdbb7589b5eb31ff9d3e29c9be5a413a05e894 Mon Sep 17 00:00:00 2001 From: Eric <52087122+Ramza13@users.noreply.github.com> Date: Wed, 7 Jul 2021 10:27:29 -0400 Subject: [PATCH 048/116] Unhardcode bionic power storage, add field for allowing duplicate bionics (#47777) --- data/json/bionics.json | 2 ++ doc/JSON_INFO.md | 1 + src/bionics.cpp | 47 +++++++----------------------------------- src/bionics.h | 2 ++ src/character.cpp | 16 -------------- src/character.h | 2 -- src/game_inventory.cpp | 1 + src/iexamine.cpp | 9 ++------ src/npctalk_funcs.cpp | 18 ++++++---------- 9 files changed, 21 insertions(+), 77 deletions(-) diff --git a/data/json/bionics.json b/data/json/bionics.json index 883a97f88f619..c141498481765 100644 --- a/data/json/bionics.json +++ b/data/json/bionics.json @@ -1127,6 +1127,7 @@ "type": "bionic", "name": { "str": "Power Storage" }, "capacity": "100 kJ", + "dupes_allowed": true, "description": "A Compact Bionics Module that increases your power capacity by 100 kJ. Having at least one of these is a prerequisite to using powered bionics. You will also need a power supply, found in various CBMs.", "flags": [ "BIONIC_NPC_USABLE" ] }, @@ -1135,6 +1136,7 @@ "type": "bionic", "name": { "str": "Power Storage Mk. II" }, "capacity": "250 kJ", + "dupes_allowed": true, "description": "A Compact Bionics Module that increases your power capacity by 250 kJ.", "flags": [ "BIONIC_NPC_USABLE" ] }, diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index aa41b33f01c16..541fe12ae92ff 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -678,6 +678,7 @@ For information about tools with option to export ASCII art in format ready to b | learned_proficiencies | (_optional_) Array of proficiency ids you gain when installing this CBM, and lose when uninstalling | installation_requirement | (_optional_) Requirement id pointing to a requirement defining the tools and components necessary to install this CBM. | vitamin_absorb_mod | (_optional_) Modifier to vitamin absorption, affects all vitamins. (default: `1.0`) +| dupes_allowed | (_optional_) Boolean to determine if multiple copies of this bionic can be installed. Defaults to false. | cant_remove_reason | (_optional_) String message to be displayed as the reason it can't be uninstalled. Having any value other than `""` as this will prevent unistalling the bionic. Formatting includes two `%s` for example: `The Telescopic Lenses are part of %1$s eyes now. Removing them would leave %2$s blind.` (default: `""`) | social_modifiers | (_optional_) Json object with optional members: persuade, lie, and intimidate which add or subtract that amount from those types of social checks diff --git a/src/bionics.cpp b/src/bionics.cpp index b4af1beb94f80..1187c9cd1b862 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -165,8 +165,6 @@ static const bionic_id bio_magnet( "bio_magnet" ); static const bionic_id bio_meteorologist( "bio_meteorologist" ); static const bionic_id bio_nanobots( "bio_nanobots" ); static const bionic_id bio_painkiller( "bio_painkiller" ); -static const bionic_id bio_power_storage( "bio_power_storage" ); -static const bionic_id bio_power_storage_mkII( "bio_power_storage_mkII" ); static const bionic_id bio_radscrubber( "bio_radscrubber" ); static const bionic_id bio_remote( "bio_remote" ); static const bionic_id bio_resonator( "bio_resonator" ); @@ -330,6 +328,7 @@ void bionic_data::load( const JsonObject &jsobj, const std::string & ) optional( jsobj, was_loaded, "vitamin_absorb_mod", vitamin_absorb_mod, 1.0f ); + optional( jsobj, was_loaded, "dupes_allowed", dupes_allowed, false ); int enchant_num = 0; for( JsonValue jv : jsobj.get_array( "enchantments" ) ) { std::string enchant_name = "INLINE_ENCH_" + name + "_" + std::to_string( enchant_num++ ); @@ -2705,18 +2704,16 @@ int Character::get_free_bionics_slots( const bodypart_id &bp ) const void Character::add_bionic( const bionic_id &b ) { - if( has_bionic( b ) ) { + if( has_bionic( b ) && !b->dupes_allowed ) { debugmsg( "Tried to install bionic %s that is already installed!", b.c_str() ); return; } const units::energy pow_up = b->capacity; mod_max_power_level( pow_up ); - if( b == bio_power_storage || b == bio_power_storage_mkII ) { + if( pow_up > 0_J ) { add_msg_if_player( m_good, _( "Increased storage capacity by %i." ), units::to_kilojoule( pow_up ) ); - // Power Storage CBMs are not real bionic units, so return without adding it to my_bionics - return; } my_bionics->push_back( bionic( b, get_free_invlet( *this ) ) ); @@ -2767,8 +2764,11 @@ void Character::remove_bionic( const bionic_id &b ) bionic_collection new_my_bionics; // any spells you should not forget due to still having a bionic installed that has it. std::set cbm_spells; + bool skipped_installed = false; for( bionic &i : *my_bionics ) { - if( b == i.id ) { + // if we have multiples of the same bionic only remove one + if( b == i.id && !skipped_installed ) { + skipped_installed = true; continue; } @@ -2809,39 +2809,6 @@ int Character::num_bionics() const return my_bionics->size(); } -std::pair Character::amount_of_storage_bionics() const -{ - units::energy lvl = get_max_power_level(); - - // exclude amount of power capacity obtained via non-power-storage CBMs - for( const bionic &it : *my_bionics ) { - lvl -= it.info().capacity; - } - - std::pair results( 0, 0 ); - if( lvl <= 0_kJ ) { - return results; - } - - const units::energy pow_mkI = bio_power_storage->capacity; - const units::energy pow_mkII = bio_power_storage_mkII->capacity; - - while( lvl >= std::min( pow_mkI, pow_mkII ) ) { - if( one_in( 2 ) ) { - if( lvl >= pow_mkI ) { - results.first++; - lvl -= pow_mkI; - } - } else { - if( lvl >= pow_mkII ) { - results.second++; - lvl -= pow_mkII; - } - } - } - return results; -} - bionic &Character::bionic_at_index( int i ) { return ( *my_bionics )[i]; diff --git a/src/bionics.h b/src/bionics.h index a6da18701cc45..0170cd740d9ae 100644 --- a/src/bionics.h +++ b/src/bionics.h @@ -47,6 +47,8 @@ struct bionic_data { int charge_time = 0; /** Power bank size **/ units::energy capacity = 0_kJ; + /** If true multiples of this can be installed */ + bool dupes_allowed = false; /** Is true if a bionic is an active instead of a passive bionic */ bool activated = false; /** diff --git a/src/character.cpp b/src/character.cpp index 017a7be189faa..0b475725eb348 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -11946,14 +11946,6 @@ void Character::place_corpse() } } - // Restore amount of installed pseudo-modules of Power Storage Units - std::pair storage_modules = amount_of_storage_bionics(); - for( int i = 0; i < storage_modules.first; ++i ) { - body.put_in( item( "bio_power_storage" ), item_pocket::pocket_type::CORPSE ); - } - for( int i = 0; i < storage_modules.second; ++i ) { - body.put_in( item( "bio_power_storage_mkII" ), item_pocket::pocket_type::CORPSE ); - } here.add_item_or_charges( pos(), body ); } @@ -11989,14 +11981,6 @@ void Character::place_corpse( const tripoint_abs_omt &om_target ) } } - // Restore amount of installed pseudo-modules of Power Storage Units - std::pair storage_modules = amount_of_storage_bionics(); - for( int i = 0; i < storage_modules.first; ++i ) { - body.put_in( item( "bio_power_storage" ), item_pocket::pocket_type::CORPSE ); - } - for( int i = 0; i < storage_modules.second; ++i ) { - body.put_in( item( "bio_power_storage_mkII" ), item_pocket::pocket_type::CORPSE ); - } bay.add_item_or_charges( fin, body ); } diff --git a/src/character.h b/src/character.h index 4aab7ffbf1a19..d4b156053968f 100644 --- a/src/character.h +++ b/src/character.h @@ -1234,8 +1234,6 @@ class Character : public Creature, public visitable /** Handles bionic activation effects of the entered bionic, returns if anything activated */ bool activate_bionic( int b, bool eff_only = false, bool *close_bionics_ui = nullptr ); std::vector get_bionics() const; - /** Returns amount of Storage CBMs in the corpse **/ - std::pair amount_of_storage_bionics() const; /** Returns true if the player has the entered bionic id */ bool has_bionic( const bionic_id &b ) const; /** Returns true if the player has the entered bionic id and it is powered on */ diff --git a/src/game_inventory.cpp b/src/game_inventory.cpp index ede5ced8f52ce..87c47ebe5fba9 100644 --- a/src/game_inventory.cpp +++ b/src/game_inventory.cpp @@ -1794,6 +1794,7 @@ class bionic_install_preset: public inventory_selector_preset } std::string get_denial( const item_location &loc ) const override { + const ret_val installable = pa.is_installable( loc, true ); if( installable.success() && !p.has_enough_anesth( *loc.get_item()->type, pa ) ) { const int weight = units::to_kilogram( pa.bodyweight() ) / 10; diff --git a/src/iexamine.cpp b/src/iexamine.cpp index 940a8123af914..b50785a19a991 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -209,8 +209,6 @@ static const mtype_id mon_spider_widow_giant_s( "mon_spider_widow_giant_s" ); static const bionic_id bio_lighter( "bio_lighter" ); static const bionic_id bio_lockpick( "bio_lockpick" ); static const bionic_id bio_painkiller( "bio_painkiller" ); -static const bionic_id bio_power_storage( "bio_power_storage" ); -static const bionic_id bio_power_storage_mkII( "bio_power_storage_mkII" ); static const std::string flag_AUTODOC_COUCH( "AUTODOC_COUCH" ); static const std::string flag_BARRICADABLE_WINDOW_CURTAINS( "BARRICADABLE_WINDOW_CURTAINS" ); @@ -4866,11 +4864,8 @@ void iexamine::autodoc( player &p, const tripoint &examp ) std::vector bio_list; std::vector bionic_names; for( const bionic &bio : installed_bionics ) { - if( bio.id != bio_power_storage || - bio.id != bio_power_storage_mkII ) { - bio_list.emplace_back( bio.id ); - bionic_names.emplace_back( bio.info().name.translated() ); - } + bio_list.emplace_back( bio.id ); + bionic_names.emplace_back( bio.info().name.translated() ); } int bionic_index = uilist( _( "Choose bionic to uninstall" ), bionic_names ); if( bionic_index < 0 ) { diff --git a/src/npctalk_funcs.cpp b/src/npctalk_funcs.cpp index fd20fbac74871..4fdd63f2b1e3c 100644 --- a/src/npctalk_funcs.cpp +++ b/src/npctalk_funcs.cpp @@ -92,9 +92,6 @@ static const mtype_id mon_chicken( "mon_chicken" ); static const mtype_id mon_cow( "mon_cow" ); static const mtype_id mon_horse( "mon_horse" ); -static const bionic_id bio_power_storage( "bio_power_storage" ); -static const bionic_id bio_power_storage_mkII( "bio_power_storage_mkII" ); - struct itype; static void spawn_animal( npc &p, const mtype_id &mon ); @@ -493,15 +490,12 @@ void talk_function::bionic_remove( npc &p ) for( const bionic &bio : all_bio ) { if( std::find( bionic_types.begin(), bionic_types.end(), bio.info().itype() ) == bionic_types.end() ) { - if( bio.id != bio_power_storage || - bio.id != bio_power_storage_mkII ) { - bionic_types.push_back( bio.info().itype() ); - if( item::type_is_defined( bio.info().itype() ) ) { - item tmp = item( bio.id.str(), calendar::turn_zero ); - bionic_names.push_back( tmp.tname() + " - " + format_money( 50000 + ( tmp.price( true ) / 4 ) ) ); - } else { - bionic_names.push_back( bio.id.str() + " - " + format_money( 50000 ) ); - } + bionic_types.push_back( bio.info().itype() ); + if( item::type_is_defined( bio.info().itype() ) ) { + item tmp = item( bio.id.str(), calendar::turn_zero ); + bionic_names.push_back( tmp.tname() + " - " + format_money( 50000 + ( tmp.price( true ) / 4 ) ) ); + } else { + bionic_names.push_back( bio.id.str() + " - " + format_money( 50000 ) ); } } } From 1b2fd7b62cebf32a0bda3bdf4c0a43df23899b41 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Wed, 7 Jul 2021 12:33:27 -0700 Subject: [PATCH 049/116] copy-from an extant item (#49717) Whoops, this typo snuck into ced7832fced932257d2e6d366e70adb96be1d9d6 somehow. --- data/mods/Magiclysm/items/black_dragon_items.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/mods/Magiclysm/items/black_dragon_items.json b/data/mods/Magiclysm/items/black_dragon_items.json index 151d3f8847c01..d507dc91c1f71 100644 --- a/data/mods/Magiclysm/items/black_dragon_items.json +++ b/data/mods/Magiclysm/items/black_dragon_items.json @@ -351,7 +351,7 @@ }, { "id": "suit_xlblack_dragon_scale", - "copy-from": "3uit_black_dragon_scale", + "copy-from": "suit_black_dragon_scale", "type": "ARMOR", "name": { "str": "XL black dragonscale armor" }, "description": "A massive full suit of incredibly durable black dragon scale mail. It comes with all the accoutrements that cover your torso, legs, and arms; sized to fit even the strangest of bodies.", From 0c01295b34889032254ad6aa9f22e30151293754 Mon Sep 17 00:00:00 2001 From: arockperson <48835780+arockperson@users.noreply.github.com> Date: Wed, 7 Jul 2021 16:45:35 -0400 Subject: [PATCH 050/116] Update monster_attacks.json (#49715) --- data/json/monster_special_attacks/monster_attacks.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/json/monster_special_attacks/monster_attacks.json b/data/json/monster_special_attacks/monster_attacks.json index 567c4a8ffd608..30b1a0a10a571 100644 --- a/data/json/monster_special_attacks/monster_attacks.json +++ b/data/json/monster_special_attacks/monster_attacks.json @@ -36,8 +36,8 @@ ], "hit_dmg_u": "The %1$s claws at you!", "hit_dmg_npc": "The %1$s claws at !", - "no_dmg_msg_u": "The %1$s tries to claw at you, but fails to.", - "no_dmg_msg_npc": "The %1$s tries to claw , but fails to." + "no_dmg_msg_u": "The %1$s claws at your %2$s, but fails to penetrate armor.", + "no_dmg_msg_npc": "The %1$s tries to claw at , but fails to penetrate armor." }, { "type": "monster_attack", From 47bd4dad76541f885db04b9506dac8bb787fd0e0 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Wed, 7 Jul 2021 13:46:46 -0700 Subject: [PATCH 051/116] Fix zapback test (#49710) Now that power storage bionics are proper bionics, the horrible thing being done here where the bionic is activated by index is no longer working. Bump up the index by 1, because the power storage is taking up index 0. 0 - bio_power_storage 1 - bio_faraday --- tests/mondefense_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/mondefense_test.cpp b/tests/mondefense_test.cpp index fcc2691daf582..5071af65fcdfd 100644 --- a/tests/mondefense_test.cpp +++ b/tests/mondefense_test.cpp @@ -97,7 +97,7 @@ TEST_CASE( "zapback_npc_electricity_immune", "[mondefense]" ) // Don't forget to turn it on... test_zapback( attacker, true ); // Wow this is a raw index? - attacker.activate_bionic( 0 ); + attacker.activate_bionic( 1 ); test_zapback( attacker, false ); } From dc0680a754e9309340c8af99d3a0e51d1dffdcac Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Wed, 7 Jul 2021 13:56:28 -0700 Subject: [PATCH 052/116] Default max_encumber to -1 in armor_portion_data (#49706) When no encumbrance is specified, max encumbrance defaults to 0 - however, if only encumbrance is specified, it defaults to -1. This seems like incorrect behavior, and it certainly doesn't match the behavior of non-armor portion data encumbrance. This fixes 2 failing iteminfo tests, because their encumbrance now (correctly) increases with contained volume. --- src/itype.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/itype.h b/src/itype.h index 35c5f3e1ba2c1..a39feaead0cf3 100644 --- a/src/itype.h +++ b/src/itype.h @@ -216,7 +216,7 @@ struct armor_portion_data { int encumber = 0; // When storage is full, how much it encumbers the player. - int max_encumber = 0; + int max_encumber = -1; // Percentage of the body part that this item covers. // This determines how likely it is to hit the item instead of the player. From 9c27c25707447943c3f79d7acd303a0d89d75ada Mon Sep 17 00:00:00 2001 From: Paul Fenwick Date: Wed, 7 Jul 2021 13:59:17 -0700 Subject: [PATCH 053/116] Make empty corn cobs be made of veggy + wood (#49705) This allows them to be made into charcoal in a kiln, a common use for corn cobs. --- data/json/items/comestibles/raw_veggy.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/items/comestibles/raw_veggy.json b/data/json/items/comestibles/raw_veggy.json index 4a9eb15fbc77d..b9bf3feb0233c 100644 --- a/data/json/items/comestibles/raw_veggy.json +++ b/data/json/items/comestibles/raw_veggy.json @@ -260,7 +260,7 @@ "description": "An empty corn cob. It may seem useless, but it can be used to make stock, a delicious jelly, or as fuel.", "price": 1, "price_postapoc": 1, - "material": [ "veggy" ], + "material": [ "veggy", "wood" ], "volume": "465 ml", "fun": -8, "flags": [ "RAW" ] From fcb756526e3e9c44021d4a6b90d9998486252787 Mon Sep 17 00:00:00 2001 From: Paul Fenwick Date: Wed, 7 Jul 2021 14:04:41 -0700 Subject: [PATCH 054/116] =?UTF-8?q?=F0=9F=8C=BD=20Add=20veggy=5Fany=5Fcorn?= =?UTF-8?q?=5Funcooked=20to=20cooking=20components=20(#49695)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adds a `veggy_any_corn_uncooked` requirement, which includes fresh corn (on the cob), kernels, rehydrated kernels, and canned corn. - Use `veggy_any_corn_uncooked` in `veggy_any_uncooked` - Use `veggy_any_corn_uncooked` in corn casseroles and pan-fried corn. --- data/json/recipes/food/casseroles.json | 2 +- data/json/recipes/food/corn.json | 2 +- data/json/requirements/cooking_components.json | 7 ++++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/data/json/recipes/food/casseroles.json b/data/json/recipes/food/casseroles.json index 4fdc4d9cc37b3..d694b41d77aaf 100644 --- a/data/json/recipes/food/casseroles.json +++ b/data/json/recipes/food/casseroles.json @@ -14,7 +14,7 @@ "qualities": [ { "id": "CUT", "level": 1 }, { "id": "COOK", "level": 3 } ], "tools": [ [ [ "surface_heat", 6, "LIST" ] ], [ [ "casserole", -1 ] ] ], "components": [ - [ [ "corn", 8 ], [ "can_corn", 8 ] ], + [ [ "veggy_any_corn_uncooked", 8, "LIST" ] ], [ [ "salt", 7 ], [ "seasoning_salt", 7 ], [ "soysauce", 4 ] ], [ [ "seasoning_italian", 7 ], diff --git a/data/json/recipes/food/corn.json b/data/json/recipes/food/corn.json index 4e8cecb4339a3..43108157de036 100644 --- a/data/json/recipes/food/corn.json +++ b/data/json/recipes/food/corn.json @@ -13,7 +13,7 @@ "qualities": [ { "id": "CUT", "level": 1 }, { "id": "COOK", "level": 2 } ], "tools": [ [ [ "surface_heat", 6, "LIST" ] ] ], "components": [ - [ [ "corn", 4 ], [ "can_corn", 4 ] ], + [ [ "veggy_any_corn_uncooked", 4, "LIST" ] ], [ [ "salt", 2 ], [ "salt_water", 1 ], [ "saline", 2 ], [ "seasoning_salt", 2 ], [ "soysauce", 1 ] ], [ [ "seasoning_italian", 3 ], diff --git a/data/json/requirements/cooking_components.json b/data/json/requirements/cooking_components.json index 1e314b25eca32..42b535484276c 100644 --- a/data/json/requirements/cooking_components.json +++ b/data/json/requirements/cooking_components.json @@ -725,10 +725,15 @@ ] ] }, + { + "id": "veggy_any_corn_uncooked", + "type": "requirement", + "components": [ [ [ "corn", 1 ], [ "corn_kernels", 1 ], [ "rehydrated_corn_kernels", 1 ], [ "can_corn", 1 ] ] ] + }, { "id": "veggy_any_uncooked", "type": "requirement", - "components": [ [ [ "rehydrated_veggy", 1 ], [ "rehydrated_corn_kernels", 1 ], [ "veggy_any_fresh_uncooked", 1, "LIST" ] ] ] + "components": [ [ [ "rehydrated_veggy", 1 ], [ "veggy_any_corn_uncooked", 1, "LIST" ], [ "veggy_any_fresh_uncooked", 1, "LIST" ] ] ] }, { "id": "veggy_any_fresh_uncooked", From dc17463eaf4e915696884c36a87cd372789d0778 Mon Sep 17 00:00:00 2001 From: Mom-Bun <43492737+Mom-Bun@users.noreply.github.com> Date: Wed, 7 Jul 2021 16:43:51 -0500 Subject: [PATCH 055/116] Triffid Grove Re-work (#47787) * outline for groves * upper levels * roots outline * heart outline * midden loot --- data/json/effects.json | 25 ++ data/json/emit.json | 7 + data/json/field_type.json | 56 +++ .../furniture-triffid.json | 52 +++ .../terrain-triffid.json | 197 ++++++++++ data/json/mapgen/triffid/triffid_fields.json | 147 ++++++++ data/json/mapgen/triffid/triffid_grove.json | 39 ++ .../mapgen/triffid/triffid_grove_roof.json | 39 ++ .../json/mapgen/triffid/triffid_grove_z2.json | 39 ++ .../json/mapgen/triffid/triffid_grove_z3.json | 113 ++++++ data/json/mapgen/triffid/triffid_heart.json | 40 ++ data/json/mapgen/triffid/triffid_roots.json | 353 ++++++++++++++++++ data/json/mapgen/triffid_grove.json | 118 ------ data/json/mapgen_palettes/triffid.json | 44 +++ data/json/monstergroups/triffid.json | 24 +- data/json/monsters/triffid.json | 1 + .../overmap/overmap_special/specials.json | 28 +- .../overmap_terrain_hardcoded.json | 27 -- .../overmap_terrain_triffid.json | 158 ++++++++ src/map.h | 1 - src/mapgen.cpp | 153 -------- src/monster.cpp | 6 + src/overmap.cpp | 4 +- 23 files changed, 1356 insertions(+), 315 deletions(-) create mode 100644 data/json/furniture_and_terrain/furniture-triffid.json create mode 100644 data/json/furniture_and_terrain/terrain-triffid.json create mode 100644 data/json/mapgen/triffid/triffid_fields.json create mode 100644 data/json/mapgen/triffid/triffid_grove.json create mode 100644 data/json/mapgen/triffid/triffid_grove_roof.json create mode 100644 data/json/mapgen/triffid/triffid_grove_z2.json create mode 100644 data/json/mapgen/triffid/triffid_grove_z3.json create mode 100644 data/json/mapgen/triffid/triffid_heart.json create mode 100644 data/json/mapgen/triffid/triffid_roots.json delete mode 100644 data/json/mapgen/triffid_grove.json create mode 100644 data/json/mapgen_palettes/triffid.json create mode 100644 data/json/overmap/overmap_terrain/overmap_terrain_triffid.json diff --git a/data/json/effects.json b/data/json/effects.json index 177060ecdfa8d..056814e222c66 100644 --- a/data/json/effects.json +++ b/data/json/effects.json @@ -494,6 +494,31 @@ "show_in_info": true, "blood_analysis_description": "Poison" }, + { + "type": "effect_type", + "id": "tpollen", + "name": [ "Hard of Breath" ], + "desc": [ "The pollen makes it hard to breathe!" ], + "miss_messages": [ [ "You cough out pollen.", 1 ] ], + "rating": "bad", + "harmful_cough": true, + "pain_sizing": true, + "hurt_sizing": true, + "main_parts_only": true, + "base_mods": { + "per_mod": [ -2, -1 ], + "dex_mod": [ -1, -1 ], + "str_mod": [ -2, 0 ], + "pain_min": [ 2 ], + "pain_chance": [ 150, 900 ], + "hurt_min": [ 2 ], + "hurt_chance": [ 450, 2700 ], + "speed_mod": [ -10 ], + "cough_chance": [ 10 ] + }, + "show_in_info": true, + "blood_analysis_description": "Unknown Organic Toxin" + }, { "id": "venom_dmg", "type": "effect_type", diff --git a/data/json/emit.json b/data/json/emit.json index 3268490447224..81c85d78a202e 100644 --- a/data/json/emit.json +++ b/data/json/emit.json @@ -192,6 +192,13 @@ "intensity": 3, "qty": 50 }, + { + "id": "emit_pollen_stream", + "type": "emit", + "field": "fd_pollen_triffid", + "intensity": 2, + "qty": 24 + }, { "id": "emit_hot_air2_blast", "type": "emit", diff --git a/data/json/field_type.json b/data/json/field_type.json index d5413b0de3676..e448367c0cb59 100644 --- a/data/json/field_type.json +++ b/data/json/field_type.json @@ -523,6 +523,62 @@ "display_field": true, "looks_like": "fd_nuke_gas" }, + { + "id": "fd_pollen_triffid", + "type": "field_type", + "legacy_enum_id": 51, + "intensity_levels": [ + { + "name": "hazy cloud", + "sym": "8", + "dangerous": true, + "translucency": 1, + "effects": [ + { + "effect_id": "tpollen", + "body_part": "mouth", + "intensity": 2, + "min_duration": "2 minutes", + "max_duration": "2 minutes", + "immune_inside_vehicle": true, + "message": "You feel sick from inhaling the hazy cloud.", + "message_type": "bad" + } + ] + }, + { + "name": "triffid pollen", + "color": "light_green", + "transparent": false, + "translucency": 10, + "effects": [ + { + "effect_id": "tpollen", + "body_part": "mouth", + "intensity": 5, + "min_duration": "3 minutes", + "max_duration": "3 minutes", + "immune_inside_vehicle": true, + "message": "You feel sick from inhaling the triffid pollen.", + "message_type": "bad" + } + ] + } + ], + "decay_amount_factor": 5, + "gas_absorption_factor": 15, + "percent_spread": 30, + "outdoor_age_speedup": "3 minutes", + "dirty_transparency_cache": true, + "has_fume": true, + "immunity_data": { "body_part_env_resistance": [ [ "mouth", 15 ] ] }, + "priority": 8, + "half_life": "10 minutes", + "phase": "gas", + "display_items": false, + "display_field": true, + "looks_like": "fd_nuke_gas" + }, { "id": "fd_tear_gas", "type": "field_type", diff --git a/data/json/furniture_and_terrain/furniture-triffid.json b/data/json/furniture_and_terrain/furniture-triffid.json new file mode 100644 index 0000000000000..744cdb2c42520 --- /dev/null +++ b/data/json/furniture_and_terrain/furniture-triffid.json @@ -0,0 +1,52 @@ +[ + { + "type": "furniture", + "id": "f_glowingbulb", + "name": "illuminating plant bulb", + "description": "A small plant grows among the roots here, its green onion-like bulb illuminating the area around it.", + "symbol": "!", + "color": "brown", + "move_cost_mod": 6, + "required_str": -1, + "light_emitted": 15, + "flags": [ "TRANSPARENT", "FLAMMABLE_ASH", "ORGANIC" ], + "bash": { + "str_min": 6, + "str_max": 30, + "sound": "smash!", + "sound_fail": "whump.", + "items": [ { "item": "splinter", "count": [ 3, 5 ] } ] + } + }, + { + "type": "furniture", + "id": "f_brambles", + "name": "brambles", + "symbol": "#", + "bgcolor": "brown", + "description": "A wall of tangled roots blocks the path here, you'd have destroy it to get past.", + "move_cost_mod": -1, + "coverage": 60, + "required_str": -1, + "flags": [ "TRANSPARENT", "BLOCKSDOOR", "SHORT", "THIN_OBSTACLE" ], + "bash": { + "str_min": 10, + "str_max": 60, + "sound": "smash", + "sound_fail": "whump.", + "items": [ { "item": "splinter", "count": [ 10, 15 ] } ] + } + }, + { + "type": "furniture", + "id": "f_midden", + "name": "composting midden", + "description": "A hole that has been dug into the roots here, and a pretty unpleasant smell emits from it.", + "symbol": "O", + "bgcolor": "brown", + "move_cost_mod": 3, + "coverage": 35, + "required_str": -1, + "flags": [ "TRANSPARENT", "CONTAINER", "PLACE_ITEM", "SHORT", "MOUNTABLE" ] + } +] diff --git a/data/json/furniture_and_terrain/terrain-triffid.json b/data/json/furniture_and_terrain/terrain-triffid.json new file mode 100644 index 0000000000000..a83daa9fc00c7 --- /dev/null +++ b/data/json/furniture_and_terrain/terrain-triffid.json @@ -0,0 +1,197 @@ +[ + { + "type": "terrain", + "id": "t_triffid_bark_wall", + "name": "solid bark wall", + "description": "A solid wall of bark, enclosing the trunk of a massive tree. It will probably burn quite well.", + "symbol": "LINE_OXOX", + "color": "brown", + "move_cost": 0, + "coverage": 100, + "roof": "t_barkfloor", + "flags": [ "FLAMMABLE", "NOITEM", "SUPPORTS_ROOF", "WALL", "NO_SCENT", "AUTO_WALL_SYMBOL", "MINEABLE", "BLOCK_WIND" ], + "connects_to": "WALL", + "bash": { + "str_min": 60, + "str_max": 180, + "sound": "crunch!", + "sound_fail": "whump!", + "ter_set": "t_bark_wall_chipped", + "items": [ { "item": "splinter", "count": [ 5, 10 ] } ] + } + }, + { + "type": "terrain", + "id": "t_bark_wall_chipped", + "name": "chipped bark wall", + "description": "A solid wall of bark enclosing the trunk of a massive tree. Some of it has been broken away.", + "symbol": "LINE_OXOX", + "color": "brown", + "move_cost": 0, + "coverage": 100, + "flags": [ "FLAMMABLE", "NOITEM", "SUPPORTS_ROOF", "WALL", "REDUCE_SCENT", "AUTO_WALL_SYMBOL", "MINEABLE", "BLOCK_WIND" ], + "connects_to": "WALL", + "bash": { + "str_min": 40, + "str_max": 160, + "sound": "crunch!", + "sound_fail": "whump!", + "ter_set": "t_bark_wall_broken", + "items": [ { "item": "splinter", "count": [ 5, 10 ] } ] + } + }, + { + "type": "terrain", + "id": "t_bark_wall_broken", + "name": "broken bark wall", + "description": "A formerly solid wall of bark, now almost completely destroyed and waiting to collapse.", + "symbol": "&", + "color": "brown", + "move_cost": 0, + "flags": [ "TRANSPARENT", "FLAMMABLE_ASH", "NOITEM", "SUPPORTS_ROOF", "REDUCE_SCENT", "PERMEABLE", "CONNECT_TO_WALL" ], + "bash": { + "str_min": 8, + "str_max": 150, + "sound": "crash!", + "sound_fail": "whump!", + "ter_set": "t_barkfloor", + "items": [ { "item": "splinter", "count": [ 10, 20 ] } ] + } + }, + { + "type": "terrain", + "id": "t_triffid_wood_wall", + "name": "solid wood wall", + "description": "A solid wall of naturally grown wood. Likely very flammable.", + "symbol": "LINE_OXOX", + "color": "brown", + "move_cost": 0, + "coverage": 100, + "roof": "t_barkfloor", + "flags": [ "FLAMMABLE", "NOITEM", "SUPPORTS_ROOF", "WALL", "NO_SCENT", "AUTO_WALL_SYMBOL", "MINEABLE", "BLOCK_WIND" ], + "connects_to": "WALL", + "bash": { + "str_min": 80, + "str_max": 180, + "sound": "crunch!", + "sound_fail": "whump!", + "ter_set": "t_barkfloor", + "items": [ { "item": "splinter", "count": [ 20, 25 ] } ] + } + }, + { + "type": "terrain", + "id": "t_barkfloor", + "name": "bark", + "description": "A solid piece of bark covers the floor here.", + "symbol": ".", + "color": "cyan", + "move_cost": 2, + "roof": "t_barkfloor", + "flags": [ "TRANSPARENT", "FLAMMABLE_HARD", "SUPPORTS_ROOF", "COLLAPSES", "INDOORS", "FLAT", "ROAD" ], + "bash": { + "sound": "SMASH!", + "ter_set": "t_dirt", + "str_min": 50, + "str_max": 400, + "str_min_supported": 100, + "items": [ { "item": "splinter", "count": [ 2, 8 ] } ] + } + }, + { + "type": "terrain", + "id": "t_triffid_leaves", + "name": "branches with leaves", + "description": "Thin branches emerge here, covered with thick, large leaves.", + "symbol": "#", + "color": "green", + "move_cost": 8, + "coverage": 40, + "flags": [ "TRANSPARENT", "FLAMMABLE_ASH" ], + "bash": { "str_min": 4, "str_max": 60, "sound": "crunch.", "sound_fail": "poof!", "ter_set": "t_null" } + }, + { + "type": "terrain", + "id": "t_root_floor", + "name": "root floor", + "description": "A dirt floor covered with roots.", + "symbol": "#", + "color": "brown", + "move_cost": 2, + "roof": "t_root_floor", + "flags": [ "SUPPORTS_ROOF", "WALL", "NO_SCENT" ], + "bash": { + "str_min": 12, + "str_max": 150, + "sound": "crunch!", + "sound_fail": "whump!", + "ter_set": "t_dirt", + "items": [ { "item": "splinter", "count": [ 2, 5 ] } ] + } + }, + { + "type": "terrain", + "id": "t_triffid_slope_down", + "name": "downward root slope", + "connects_to": "PAVEMENT", + "description": "A downward-facing slope of root-covered dirt.", + "symbol": ">", + "color": "brown", + "roof": "t_barkfloor", + "move_cost": 2, + "flags": [ "TRANSPARENT", "GOES_DOWN", "PLACE_ITEM", "SUPPORTS_ROOF" ] + }, + { + "type": "terrain", + "id": "t_triffid_slope_up", + "name": "upward root slope", + "connects_to": "WALL", + "description": "An upward-facing slope of root-covered dirt.", + "symbol": "<", + "color": "brown", + "roof": "t_barkfloor", + "move_cost": 2, + "flags": [ "TRANSPARENT", "GOES_UP", "PLACE_ITEM", "SUPPORTS_ROOF" ] + }, + { + "type": "terrain", + "id": "t_bramble_door_c", + "name": "closed bramble roots", + "description": "A bramble of roots are here, covering a hole. They could easily be pulled apart.", + "symbol": "+", + "color": "brown", + "move_cost": 0, + "coverage": 95, + "roof": "t_flat_roof", + "flags": [ "FLAMMABLE_ASH", "DOOR", "NOITEM", "BARRICADABLE_DOOR", "CONNECT_TO_WALL", "BLOCK_WIND" ], + "open": "t_bramble_door_o", + "bash": { + "str_min": 12, + "str_max": 150, + "sound": "crunch!", + "sound_fail": "whump!", + "ter_set": "t_null", + "items": [ { "item": "splinter", "count": [ 2, 5 ] } ] + } + }, + { + "type": "terrain", + "id": "t_bramble_door_o", + "name": "open bramble roots", + "description": "A bramble of roots are here, they are pulled apart revealing a hole.", + "symbol": "'", + "color": "brown", + "move_cost": 2, + "roof": "t_flat_roof", + "flags": [ "FLAMMABLE_ASH", "TRANSPARENT", "FLAT", "BARRICADABLE_DOOR", "CONNECT_TO_WALL", "ROAD" ], + "close": "t_bramble_door_c", + "bash": { + "str_min": 12, + "str_max": 150, + "sound": "crunch!", + "sound_fail": "whump!", + "ter_set": "t_null", + "items": [ { "item": "splinter", "count": [ 2, 5 ] } ] + } + } +] diff --git a/data/json/mapgen/triffid/triffid_fields.json b/data/json/mapgen/triffid/triffid_fields.json new file mode 100644 index 0000000000000..4276200618b45 --- /dev/null +++ b/data/json/mapgen/triffid/triffid_fields.json @@ -0,0 +1,147 @@ +[ + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_field" ], + "weight": 100, + "object": { + "fill_ter": "t_region_groundcover_urban", + "rows": [ + " I ", + " ^ I I ", + " I ", + " ? * I * I ", + " X ? ", + " I I * ", + " ^ I ", + " I ", + " * I X ^ * ", + " I ? * I ", + " ", + " ^ * I ^ I ", + " * ", + " I * ? ", + " I ", + " * I ", + " ^ X * ", + " I I ", + " * ", + " I ? * ", + " X ", + " * I ", + " X ^ ", + " X ", + " I I " + ], + "palettes": [ "triffid" ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_field" ], + "weight": 100, + "object": { + "fill_ter": "t_region_groundcover_urban", + "rows": [ + " I ", + " X * * X ", + " ^ ? ? ", + " * X ? ^ ", + " ? ", + " ^ X I ^ * ", + " I ", + " * ^ * ^ ", + " ? X I ", + " ", + " X I * X ? ", + " ^ ^ ", + " ? ? X ", + " I X I * ", + " ? ", + " * X ? * X I ", + " ? ", + " I X ^ X ", + " X ", + " ? I * ", + " X I ", + " * ? X ", + " I ", + " * ^ " + ], + "palettes": [ "triffid" ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_field" ], + "weight": 100, + "object": { + "fill_ter": "t_region_groundcover_urban", + "rows": [ + " ", + " ? X ? ", + " I ", + " I ? I ", + " ? * ", + " ^ * X ", + " I I X ", + " X ? ", + " X ", + " ? ^ I ? ", + " I I ", + " ", + " * X ? * ", + " ? ^ ", + " I I X ", + " * ", + " X ^ ? ", + " I ", + " I ^ ", + " * X ", + " I ? ", + " ", + " I ", + " X " + ], + "palettes": [ "triffid" ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_field" ], + "weight": 100, + "object": { + "fill_ter": "t_region_groundcover_urban", + "rows": [ + " ", + " I * * ", + " * ? ", + " * X I I ", + " ^ X ? ^ ", + " ? * ", + " ^ I X * ", + " * ? I ? ", + " ", + " ^ I ? I ", + " X X ", + " ? ^ * ", + " I I X ", + " * I ", + " ? * ? ", + " ^ I ", + " X I X ", + " * I ", + " I ? ", + " X X ", + " I * I ", + " ", + " ? I ", + " X * " + ], + "palettes": [ "triffid" ] + } + } +] diff --git a/data/json/mapgen/triffid/triffid_grove.json b/data/json/mapgen/triffid/triffid_grove.json new file mode 100644 index 0000000000000..92e4315da381f --- /dev/null +++ b/data/json/mapgen/triffid/triffid_grove.json @@ -0,0 +1,39 @@ +[ + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_grove" ], + "weight": 100, + "object": { + "fill_ter": "t_region_groundcover_urban", + "rows": [ + " ? I ? ", + " I ? I X ? I ", + " I X I I X ^ ###X X ", + " X ? ? ^ X ########## X", + " IX################### ", + " ^############~~~####^ ", + " ?###~~~~~~~~~~~~~~###? ", + " X###~~~~~~~~~~~~~~### ", + " ##~~~~~~~~~~~~~~##^ I", + " I^##~~~~~~~~~~~~~~##?X ", + " ?##~~~~~~~~~~~~~~### ", + " X###~~~~~~~~~~~~~~###^I", + " I###~~~~~~~~~~~~~~### ", + " ###~~~~~~~~~~~~~~##? X", + " ^###~~~~~~~~~~~~~~##^ ", + "? ####~~~~~~~~~~~~~##XI ", + " I###~~~~~~~~~~~~~###? ", + " ? ###~~~~~~~~~~~~~~##X ", + " I^###~~~~~~~~~~~~~~##I ", + " ?X##~~~~~~~~~~~~~~##X ", + " X>########~#########I ", + " ?>>##^XX?####IXX^###X ", + " IX>>X I I I ", + " I ? I " + ], + "palettes": [ "triffid" ], + "terrain": { ">": "t_triffid_slope_down" } + } + } +] diff --git a/data/json/mapgen/triffid/triffid_grove_roof.json b/data/json/mapgen/triffid/triffid_grove_roof.json new file mode 100644 index 0000000000000..14109b14a05eb --- /dev/null +++ b/data/json/mapgen/triffid/triffid_grove_roof.json @@ -0,0 +1,39 @@ +[ + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_grove_roof" ], + "weight": 100, + "object": { + "fill_ter": "t_barkfloor", + "rows": [ + ">>>,,>>>>,,,,,,>,,,,,>>>", + ">,,,,,>>,,,,,,,,,,,,,,>>", + ">>,,,,,,,,,,,,,,,,,,,,,>", + ">>>,,,,,,,,,,,,,,,,,,,,>", + ">>,,,,,,,,,,,,,,,,,,,,,,", + ">,,,,,,,,,,,,,,,,,,,,,,,", + ",>,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ">,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ">,,,,,,,,,,,,,,,,,,,,,,,", + ">,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ">,,,,,,,,,,,,,,,,,,,,,,,", + ">,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ">>,,,,,,,,>,,,,,,,,,,,,>", + ">>,,,,,,,,,>,,,,,,,,,,>>", + ">>>>,,,,,,,,,,,,,,,,,>>>" + ], + "palettes": [ "triffid" ], + "terrain": { ">": "t_open_air" } + } + } +] diff --git a/data/json/mapgen/triffid/triffid_grove_z2.json b/data/json/mapgen/triffid/triffid_grove_z2.json new file mode 100644 index 0000000000000..594eea0b41b03 --- /dev/null +++ b/data/json/mapgen/triffid/triffid_grove_z2.json @@ -0,0 +1,39 @@ +[ + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_grove_z2" ], + "weight": 100, + "object": { + "fill_ter": "t_barkfloor", + "rows": [ + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">>>>>>>>>>>>>>>#####>>>>", + ">>>#######>#####~~~##>>>", + ">>>#~~~~~###~~~~~~~~#>>>", + ">>>#~~~~~~~~~~~~~~~##>>>", + ">>>#~~~~~~~~~~~~~~~#>>>>", + ">>>#~~~~~~~~~~~~~~~#>>>>", + ">>>#~~~~~~~~~~~~~~~##>>>", + ">>>##~~~~~~~~~~~~~~~#>>>", + ">>>>#~~~~~~~~~~~~~~~##>>", + ">>>##~~~~~~~~~~~~~~##>>>", + ">>>>#~~~~~~~~~~~~~~#>>>>", + ">>>##~~~~~~~~~~~~~~#>>>>", + ">>>#~~~~~~~~~~~~~~~##>>>", + ">>>#~~~~~~~~~~~~~~~##>>>", + ">>>#~~~~~~~~~~~~~~~#>>>>", + ">>>######~~~~~~~~~~#>>>>", + ">>>>>#>>############>>>>", + ">>>>>>>>>>>>##>>>##>>>>>", + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">>>>>>>>>>>>>>>>>>>>>>>>" + ], + "palettes": [ "triffid" ], + "terrain": { ">": "t_open_air" } + } + } +] diff --git a/data/json/mapgen/triffid/triffid_grove_z3.json b/data/json/mapgen/triffid/triffid_grove_z3.json new file mode 100644 index 0000000000000..1cee3db103f8f --- /dev/null +++ b/data/json/mapgen/triffid/triffid_grove_z3.json @@ -0,0 +1,113 @@ +[ + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_grove_z3" ], + "weight": 100, + "object": { + "fill_ter": "t_barkfloor", + "rows": [ + ">,,,,>>>>>>>>>>>>>>>>>>>", + ">,####,>>>>>>>>>>>>>>>>>", + ">>,##,>>>>>>>>>>>>>>>>>>", + ">>>>##>>>>>>>>>#####>>>>", + ">>>#######>#####~~~##>>>", + ">>>#~~~~~###~~~~~~~~#>>>", + ">>>#~~~~~~~~~~~~~~~##>>>", + ">>>#~~~~~~~~~~~~~~~#>>>>", + ">>>#~~~~~~~~~~~~~~~#>>>>", + ">>>#~~~~~~~~~~~~~~~##>>>", + ">>>##~~~~~~~~~~~~~~~#>>>", + ">>>>#~~~~~~~~~~~~~~~##>>", + ">>>##~~~~~~~~~~~~~~##>>>", + ">>>>#~~~~~~~~~~~~~~#>>>>", + ">>>##~~~~~~~~~~~~~~#>>>>", + ">>>#~~~~~~~~~~~~~~~##,,,", + ">>>#~~~~~~~~~~~~~~~####,", + ">>>#~~~~~~~~~~~~~~~###,,", + ">>>######~~~~~~~~~~##>>>", + ">>>###>>############>>>>", + ">>,###,>>>>>####,##>>>>>", + ">>###,>>>>>>>,###,>>>>>>", + ">,##,>>>>>>>>>,##,>>>>>>", + ">>>#,>>>>>>>>>>>,>>>>>>>" + ], + "palettes": [ "triffid" ], + "terrain": { ">": "t_open_air" } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_grove_z3" ], + "weight": 100, + "object": { + "fill_ter": "t_barkfloor", + "rows": [ + ">>>>>>>>>>>>,>>>>>>>>>>>", + ">>>>>>>>>>,,#,>>>>>>>>>>", + ">>>>>>>>>>###,>>>>>>>>>>", + ">>>>>>>>>###>>>#####>>>>", + ">>>#############~~~##>>>", + ">>>#~~~~~###~~~~~~~~#>>>", + ">>>#~~~~~~~~~~~~~~~##>>>", + ">>>#~~~~~~~~~~~~~~~#>>>>", + ",,##~~~~~~~~~~~~~~~#>>>>", + "####~~~~~~~~~~~~~~~##>>>", + "##,##~~~~~~~~~~~~~~~#>>>", + ">>>>#~~~~~~~~~~~~~~~##>>", + ">>>##~~~~~~~~~~~~~~##>>>", + ">>>>#~~~~~~~~~~~~~~#>>>>", + ">>>##~~~~~~~~~~~~~~#>>>>", + ">>>#~~~~~~~~~~~~~~~##>>>", + ">>>#~~~~~~~~~~~~~~~##>>>", + ">>>#~~~~~~~~~~~~~~~#>>>>", + ">>>######~~~~~~~~~~#>>>>", + ">>>>>#>>############>>>>", + ">>>>>>>>>>>>####>##>>>>>", + ">>>>>>>>>>>>>>##,>>>>>>>", + ">>>>>>>>>>>>>,####,>>>>>", + ">>>>>>>>>>>>>>>,#,>>>>>>" + ], + "palettes": [ "triffid" ], + "terrain": { ">": "t_open_air" } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_grove_z3" ], + "weight": 100, + "object": { + "fill_ter": "t_barkfloor", + "rows": [ + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">>>>>>>>>>>>>>>#####>>>>", + ">>>#######>#####~~~##>>>", + ">>>#~~~~~###~~~~~~~~#>>>", + ">>>#~~~~~~~~~~~~~~~##,>,", + ">>>#~~~~~~~~~~~~~~~#####", + ">>>#~~~~~~~~~~~~~~~###,>", + ">>>#~~~~~~~~~~~~~~~##,>>", + ">>>##~~~~~~~~~~~~~~~#>>>", + ">>>>#~~~~~~~~~~~~~~~##>>", + ">>>##~~~~~~~~~~~~~~##>>>", + ">>>>#~~~~~~~~~~~~~~#>>>>", + ">>>##~~~~~~~~~~~~~~#>>>>", + ">>>#~~~~~~~~~~~~~~~##>>>", + ">>>#~~~~~~~~~~~~~~~##>>>", + ">>>#~~~~~~~~~~~~~~~#>>>>", + ">>>######~~~~~~~~~~#>>>>", + ">>>,################>>>>", + ">>>####>>>>>##>>>##>>>>>", + ">>,##,>>>>>>>>>>,#,>>>>>", + ">>>#,>>>>>>>>>>>>##,>>>>", + ">>>,>>>>>>>>>>>>>,#,>>>>" + ], + "palettes": [ "triffid" ], + "terrain": { ">": "t_open_air" } + } + } +] diff --git a/data/json/mapgen/triffid/triffid_heart.json b/data/json/mapgen/triffid/triffid_heart.json new file mode 100644 index 0000000000000..135b71c5c9326 --- /dev/null +++ b/data/json/mapgen/triffid/triffid_heart.json @@ -0,0 +1,40 @@ +[ + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_finale" ], + "weight": 100, + "object": { + "fill_ter": "t_root_floor", + "rows": [ + "PPPPPPPPPPPPPPPPPPPPPPPP", + "PPPPPPPPT.............TP", + "PPPPPP!....PPPPPPP.....P", + "PP........PP!.": "t_rock", "<": "t_triffid_slope_up" }, + "monster": { "H": { "monster": "mon_triffid_heart" }, "!": { "monster": "mon_creeper_hub", "chance": 60 } } + } + } +] diff --git a/data/json/mapgen/triffid/triffid_roots.json b/data/json/mapgen/triffid/triffid_roots.json new file mode 100644 index 0000000000000..82277fc107ecc --- /dev/null +++ b/data/json/mapgen/triffid/triffid_roots.json @@ -0,0 +1,353 @@ +[ + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_roots" ], + "weight": 100, + "object": { + "fill_ter": "t_root_floor", + "rows": [ + "PP......PPPPPPPPPPDPPPPP", + "P........!PPPPPP..T...PP", + "PPPPDPPPPPPPPPP@.P....!P", + "P......T.!PP.P>@P@..T..P", + "P..T.....PP..P>>@@.PP..P", + "PP!P.....D...PP>>@..P..P", + "PPPPDPPPPPPPPPPPPPPPPPPP", + "PPP....@.......PPPPPPPP.", + "PPPPPPPP.....T....PPPP..", + "PPP...PP...........PP.T.", + "PP.T..PPPPPPPPPDPPPP....", + "P!..PPPPPPP..T.....D.P!P", + "PPPPDPPPPPPP....@@@PPPPP", + "P!PP......PPPPPP@T@P...P", + "..PP...T...PPPP....P...P", + ".T.PPPP......PP....PPP.P", + "......PPPPPDPPPPPPDPPPDP", + "PPPPPDPPPP@@T.PPP....T.P", + "PPPP!....D....@PP......P", + "PPPPP@@@.P....@@D......P", + "PP<.T..@PPPPPDPPPPPPPPPP", + "PP<<...PPPPP.PPD.......P", + "PPP<": "t_triffid_slope_down", "<": "t_triffid_slope_up" }, + "monster": { "!": { "monster": "mon_creeper_hub", "chance": 60 } } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_rootss" ], + "weight": 100, + "object": { + "fill_ter": "t_root_floor", + "rows": [ + "P>PPP>PPPP>>>>>PPPPP>>>>", + "P>>>PP>>PPPP>>>PPPPPP>>>", + "PP>>>P>>>PPP>>>>PP>>>PPP", + "PPP>>PP>>PPP>>>PPP>>>PPP", + "PPPPPPPPPPP>>>PPP>>>PPPP", + "PP.....P!PPP>>>PPP>>PPPP", + "PP....T...PPP>>PPP>>>>PP", + "PPPPPP@@@..PPP>>>PP>PPPP", + "PPPPPPPDPPPPPPPPPPPPPPPP", + "PPPP!P.....DPP.T....DPPP", + "PPPP...T...P@@....PPP..P", + "PP.@@@...PPPPDPPPPP.T..P", + "PPPPDPPPPP.....PPPP!...P", + "P......P!PPP.T..!PPPPDPP", + "P....T....PPPPPPPPP.T...", + "PPPPPP!P...@D....PP!....", + ".PPPPPPPDPPPP..T..PPPDPP", + "T.PPPP....PP.....PPP...P", + "...D...T..PPPPPPPP.T..PP", + "PPPPPPDPPPPPPPPP....PPPP", + "P...........PPPPPPDPPPPP", + "PP.........PPPPP......PP", + "PPP...T..PPPPPPP...T..PP", + "PP.....PPPPPPPPP...PPPPP" + ], + "palettes": [ "triffid" ], + "terrain": { ">": "t_rock" }, + "monster": { "!": { "monster": "mon_creeper_hub", "chance": 60 } } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_rootsn" ], + "weight": 100, + "object": { + "fill_ter": "t_root_floor", + "rows": [ + "PPPPPPPPPP.....PPPPPPPPP", + "PPPPPPPPP....T..PP....PP", + "......PPPPPPDPPPPPP...PP", + ".....T..P@@....PP@.T..PP", + "PP!......D@.T...D@...PPP", + "PPPPPPPPPPP..PPPPPDPPPPP", + "P!....PPPPPPDPPPPPPPPPPP", + "P.T.PDPP!.....PPPPPPPPPP", + "P...P.....T...PPPPP!....", + "P...PPPPPPPPPPPPPPPP..T.", + "PPPDPPPPPP!..T..D@......", + "P........D.....PPPPPPP..", + "P..T...PPPPDPPPPPPPPPPPP", + "P...PPPPP.....PPPPPPPPPP", + "PPPPPPP!...T...PPPPPPPPP", + "PPP>>>PPPP.......PPPPPPP", + "P>>>P>>>PPPPPPPPPPPPPP>>", + "PP>>>>PP>>>PP>>>>PPP>>>>", + "PP>>>PPPP>>PPPP>>>PPPP>>", + "PPP>>PPPP>>>PPPP>>>>PPPP", + "PP>>>PPPPP>>>PP>>PP>>>PP", + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">>>>>>>>>>>>>>>>>>>>>>>>" + ], + "palettes": [ "triffid" ], + "terrain": { ">": "t_rock" }, + "monster": { "!": { "monster": "mon_creeper_hub", "chance": 60 } } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_rootse" ], + "weight": 100, + "object": { + "fill_ter": "t_root_floor", + "rows": [ + "PPPPPPPPPPPPDPPPPPPP>>>>", + "PP!....PP..!PPPPPPPPPP>>", + "PP..T..D.....PPP>>>>PPP>", + "P.....PPP!....PP>>>>>>PP", + "P..!PPP.PPPDPPPP>>>>>>>>", + "PDPPPP....@@@PPP>>>>>>>P", + "P.!PPP.....PPPPP>>>>>PP>", + "....PPP.....PPPP>>>>PP>>", + "..T.P...T.PPPPPP>>PPP>>>", + "...PPP.@@@PPPPPPPPPPP>>>", + "...PPPPPDPPPPPPPPPP>>>>>", + "PPPPP.T....PPPPP>>>>>>>>", + "P...D...PPPPPPPPPPPPPPPP", + "PT..PPDPPPPPPPPP>PPPP>>>", + "P..DP@@@...PPPPP>>>>>>>>", + "P.PD..T...PPPPPPPPP>>>>>", + "PPPPP...!PPPPPPPPP>>>>>>", + "PPPPPPDPPPPPPPPP>PP>>>>>", + "PPPP.....!PP..PP>>>>PP>>", + "P.@@D..TPPP!T.PP>>>>>P>>", + "P..PPP..D.....PP>>PP>>PP", + "P..PPPPPPPPPPPPPPPPP>>>>", + "P.T.PPPPPPPPPPPPP>>>>>>>", + "P....PPPPPPPPPPPP>>>>>>>" + ], + "palettes": [ "triffid" ], + "terrain": { ">": "t_rock" }, + "monster": { "!": { "monster": "mon_creeper_hub", "chance": 60 } } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_rootsw" ], + "weight": 100, + "object": { + "fill_ter": "t_root_floor", + "rows": [ + ">>>>>>>PP....PPPPPPPPPPP", + ">>>>PPPPP.T.PDPPPPPPPPPP", + ">>>PPPPPPPPPP.T..PPPPPPP", + ">>PP>>>PPPP!.....PPPPPPP", + "PP>>>>>PPPPPPDPPPPPPPPPP", + ">>>>>>>PPPPP@@@!PPPPPPPP", + ">>>>>>>PPPP..T..PPP!T.PP", + ">>>>>>>PPP......PP....PP", + "PPP>>>>PPPPPPDPPPPPDPPPP", + ">>PPPP>PPPPP...PP..!TPPP", + ">>>>PPPPPP..T...D......P", + ">>>>>PPPPP!...PPPPPP...P", + ">>>>>>>PPPPPPPPPPPPDPPPP", + ">PP>PPPPP..O.........PPP", + "P>>PPPPP.........O....P@", + ">>>>>>P.......O.......D@", + ">>PPPPPP...O.......O..P@", + "PPPP>>>PP.......O....PPP", + "PP>>>>>PPPPDPPPPPPPPPPPP", + ">>>>>>>PP.@@@..D@...T.PP", + ">>>PPPPPP!..T..PPP!...PP", + "PPPP>>>PPP.....!PPPPDPPP", + ">>>>>>>PPPPPPPPPPP!.T.PP", + ">>>>>>>PPPPPPPPPPP....PP" + ], + "palettes": [ "triffid" ], + "terrain": { ">": "t_rock" }, + "furniture": { "O": "f_midden" }, + "items": { + "O": [ + { "item": "vertebrate_parts", "chance": 80, "repeat": [ 1, 2 ] }, + { "item": "human_parts", "chance": 60, "repeat": [ 1, 2 ] }, + { "item": "wasp_lair", "chance": 70, "repeat": [ 1, 2 ] } + ] + }, + "monster": { "!": { "monster": "mon_creeper_hub", "chance": 60 } } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_rootsen" ], + "weight": 100, + "object": { + "fill_ter": "t_root_floor", + "rows": [ + "PPP...PPPPPPPPPP>>>>>>>>", + "PP....PP..T..PPPPPP>>>>>", + "......D......PPP>>PP>>>>", + "..T..!PPP....PPP>>>>PPP>", + "....PPPPPP@@PPPP>>>>>>PP", + "PPPDPP!..PPDPPPP>>>>>>>>", + "P.@@PPP.......PP>>>>>>>>", + "P..T.PPP..T.!PPP>>>PPPP>", + "PP....PP....PPPPPPP>>>>>", + "PPPPPPPP....PPPP>>>>>>>>", + "..T...PPPPPDPPPP>PPPPP>>", + ".......PP.T..!PPPPP>>>P>", + "...PDPPPD@@.DPPP>>>>>PPP", + "!PPP...TPPPPP..P>>>>>>>>", + "PPPPPPPPPP!..T.P>>>>>>>>", + "PPPPPPPPPPPPPPPPPPPP>>>>", + "PPPPPPPPPPPPPPPPP>>PP>>>", + ">>>PP>>>>>>PP>>>>>>>PP>>", + ">>>PPP>>>>>>PPP>>>>>>PPP", + ">>>>>PPPP>>>PPPPPPP>>>>>", + ">>>>>>>>>PPPP>>>>>P>>>>>", + ">>>>>>>>>>>PPP>>>>>PP>>>", + ">>>>>>>>>>>>>>P>>>>>>P>>", + ">>>>>>>>>>>>>PP>>>>>>>>>" + ], + "palettes": [ "triffid" ], + "terrain": { ">": "t_rock" }, + "monster": { "!": { "monster": "mon_creeper_hub", "chance": 60 } } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_rootsnw" ], + "weight": 100, + "object": { + "fill_ter": "t_root_floor", + "rows": [ + ">>>>>>>PPPPPPPPPPPP..PPP", + ">>>>>>>PPPPP...PP....TPP", + ">>>PPPPPP..T..PD@@.....D", + ">>PPP>>PP!...PPPPPPPPPPP", + "PPP>>>>PPP.....T..PP!.TP", + ">>>>>>>PPPPPP@@...D....P", + ">>>>>>>PPP!.DPPPPPPPDPPP", + ">>>>>>>PPP......D...T.PP", + ">>>>PPPPPP.T..PPPP!...PP", + ">PPPPPPPP!....PPPPPPPPPP", + "PP>>PPPPPPP.....D..T.!PP", + ">>>>>>>PPPPPPPPPP.....PP", + ">>>>>>>PPPPPPT......@@PP", + ">>>>>>>PP!.......PPPDPPP", + "PPP>>>>PPPPPPPPPPPP...PP", + ">PPP>>>PPPPPPP!.....T.PP", + ">>>>P>>PPPPPPPPPPPPPPPPP", + ">>>>>PPP>>>>>PP>>>>>>>>>", + ">>>PPPPP>>>>>>PP>>>>>>>>", + ">PPPP>>>>>>>>>PPP>>>>>>>", + ">>>>PP>>>>>>>>>>PP>>>>>>", + ">>>>>>PP>>>>>>>>>>P>>>>>", + ">>>>>>>>PP>>>>>>PP>>>>>>", + ">>>>>>>>>>P>>>>>>>>>>>>>" + ], + "palettes": [ "triffid" ], + "terrain": { ">": "t_rock" }, + "monster": { "!": { "monster": "mon_creeper_hub", "chance": 60 } } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_rootssw" ], + "weight": 100, + "object": { + "fill_ter": "t_root_floor", + "rows": [ + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">P>>>>>>>>>>>>>>>PP>>>>>", + ">>PP>>>>>>>>>>>>P>>>>>>>", + ">>>PPPP>>>>>>>>>>PP>>>>>", + ">>>>>PPPP>>>>>P>>>>PP>>>", + ">>>>>>PPPP>>>PP>>>PPP>>>", + "P>>>>>>PPPPPPPPPPPPPPPPP", + ">PPPP>>PP.!..PPP....!PPP", + ">>>PPPPP.....PP.T@@.PPPP", + ">>>>>>>PPPPDPPPPPDPPPPPP", + ">>>>>>>PP.T..PP.....P!PP", + ">>>>>>>P.......DP..T..PP", + ">>PPPPPPPPDPPPPPPPPPDPPP", + ">PPPP>>PP.....PPPP.@@..D", + "PPP>>>>PP...T..PPP.T.!PP", + "P>>>>>>PP!......PPPPPPPP", + ">>>>>>>PPPP......@@PPPPP", + ">>>>>>>PPPPPPPPPPPDPPPPP", + ">>PP>PPPPPPPPPD...P..T.P", + "PP>>PPPPP!...@P.TPPP!..P", + ">>>>>>>PP.T.PPPPPPPPPPPP" + ], + "palettes": [ "triffid" ], + "terrain": { ">": "t_rock" }, + "monster": { "!": { "monster": "mon_creeper_hub", "chance": 60 } } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "triffid_rootsse" ], + "weight": 100, + "object": { + "fill_ter": "t_root_floor", + "rows": [ + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">>>>>>>>>>>>>>>>>>>>>>>>", + ">>>>>>>>>>>>>>P>>>>>>>>>", + ">>>>>>>>>>>>>>PP>>>>>>>>", + ">>>>>>>>>>>>>P>>>>>>>>>>", + ">>>>>>>>>>>PP>>>>>>>>>>>", + ">>>>>>>>PPPPP>>>>>P>>>>>", + "PPPPPPPPPPPPPPPPPP>>>>>>", + "PPPPPPPPPPPPPPPPPP>>>P>>", + "PPPPPPPPPPPPPPPP>PP>P>>>", + "PPPPPPPPPPPPPPPP>PP>P>>>", + "P....DPPPPPPPPPP>>>>>>>>", + "D..T.P...T...!PPPPP>>>>>", + "PP!..PPPP..@@@PP>PP>>>>>", + "PPP....PPPPPDPPP>>PPPPP>", + "PPPPPPPPPP....PP>>>>>>>>", + "P.....D@..T..PPP>>>>>PP>", + "P....PP@...PPPPP>>>>PP>>", + "P..T.PPPDPPPPPPP>>PPP>>>", + "P.....PP..TPPPPP>PP>>>>>", + "PP!....PP..!PPPPPPP>>>>>", + "PPPPPPPPPP.PPPPP>>>>>>>>" + ], + "palettes": [ "triffid" ], + "terrain": { ">": "t_rock" }, + "monster": { "!": { "monster": "mon_creeper_hub", "chance": 60 } } + } + } +] diff --git a/data/json/mapgen/triffid_grove.json b/data/json/mapgen/triffid_grove.json deleted file mode 100644 index 28c82e54f66f9..0000000000000 --- a/data/json/mapgen/triffid_grove.json +++ /dev/null @@ -1,118 +0,0 @@ -[ - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "triffid_grove" ], - "weight": 100, - "object": { - "fill_ter": "t_dirt", - "rows": [ - " ", - " 44 4 66 66 4 44 ", - " 44 4 66 66 4 44 ", - " 44 4 66 66 4 44 ", - " 44 4 66 66 4 44 ", - " 44 4 4 44 ", - " 44 4 766667 4 44 ", - " 777777 ", - " 55 77766777 55 ", - " 55 77 77 55 ", - " 66 77 B B 77 66 ", - " 1 >> 1 ", - " 1 >> 1 ", - " 66 77 B B 77 66 ", - " 55 77 77 55 ", - " 55 77766777 55 ", - " 777777 ", - " 44 4 766667 4 44 ", - " 44 4 4 44 ", - " 44 4 66 66 4 44 ", - " 44 4 66 66 4 44 ", - " 44 4 66 66 4 44 ", - " 44 4 66 66 4 44 ", - " " - ], - "terrain": { - " ": [ "t_dirt", "t_dirt", "t_grass", "t_grass", "t_grass", "t_grass", "t_grass", "t_grass", "t_grass" ], - "1": [ "t_tree_young", "t_tree_young", "t_tree_young", "t_tree" ], - "4": [ "t_tree_young", "t_tree_young", "t_tree_willow", "t_tree_hickory", "t_underbrush", "t_shrub", "t_grass" ], - "5": [ "t_tree", "t_tree", "t_tree", "t_tree_pine", "t_tree_pine", "t_tree_birch", "t_tree_birch", "t_tree_maple" ], - "6": [ - "t_tree", - "t_tree", - "t_tree", - "t_tree_apple", - "t_tree_apple", - "t_tree_pear", - "t_tree_pear", - "t_tree_cherry", - "t_tree_peach", - "t_tree_apricot", - "t_tree_plum" - ], - "7": "t_tree", - ">": "t_slope_down" - }, - "furniture": { "^": "f_rubble_rock" }, - "monster": { "B": { "monster": "mon_biollante" } } - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "triffid_grove" ], - "weight": 100, - "object": { - "fill_ter": "t_dirt", - "rows": [ - " 4444 4444 4444 4444 ", - " 4444 4444 4444 4444 ", - " 4444 4444 4444 4444 ", - " ", - " ", - " 56544577544565 ", - " 6 777777 6 ", - " 46 77777777 64 ", - " 5665 77 7 7 77 5665 ", - " 6 7 7 6 ", - " 5 77 B B 77 5 ", - " 4 77 >> 77 4 ", - " 4 77 >> 77 4 ", - " 5 77 B B 77 5 ", - " 6 7 7 6 ", - " 5665 77 7 7 77 5665 ", - " 46 77777777 64 ", - " 6 777777 6 ", - " 56544577544565 ", - " ", - " ", - " 4444 4444 4444 4444 ", - " 4444 4444 4444 4444 ", - " 4444 4444 4444 4444 " - ], - "terrain": { - " ": [ "t_dirt", "t_dirt", "t_grass", "t_grass", "t_grass", "t_grass", "t_grass", "t_grass", "t_grass" ], - "1": [ "t_tree_young", "t_tree_young", "t_tree_young", "t_tree" ], - "4": [ "t_tree_young", "t_tree_young", "t_tree_willow", "t_tree_hickory", "t_underbrush", "t_shrub", "t_grass" ], - "5": [ "t_tree", "t_tree", "t_tree", "t_tree_pine", "t_tree_pine", "t_tree_birch", "t_tree_birch", "t_tree_maple" ], - "6": [ - "t_tree", - "t_tree", - "t_tree", - "t_tree_apple", - "t_tree_apple", - "t_tree_pear", - "t_tree_pear", - "t_tree_cherry", - "t_tree_peach", - "t_tree_apricot", - "t_tree_plum" - ], - "7": "t_tree", - ">": "t_slope_down" - }, - "furniture": { "^": "f_rubble_rock" }, - "monster": { "B": { "monster": "mon_biollante" } } - } - } -] diff --git a/data/json/mapgen_palettes/triffid.json b/data/json/mapgen_palettes/triffid.json new file mode 100644 index 0000000000000..e7505d16bfa36 --- /dev/null +++ b/data/json/mapgen_palettes/triffid.json @@ -0,0 +1,44 @@ +[ + { + "type": "palette", + "id": "triffid", + "terrain": { + " ": "t_region_groundcover_urban", + "#": "t_triffid_bark_wall", + "C": "t_barkfloor", + "~": "t_triffid_wood_wall", + ",": "t_triffid_leaves", + "P": "t_root_wall", + ".": "t_root_floor", + "D": [ "t_bramble_door_c", "t_bramble_door_o" ], + "*": "t_water_sh", + "[": "t_water_dp", + "I": [ + "t_tree", + "t_tree_apple", + "t_tree_apple", + "t_tree_pear", + "t_tree_pear", + "t_tree_cherry", + "t_tree_peach", + "t_tree_apricot", + "t_tree_plum", + "t_tree_pine", + "t_tree_birch", + "t_tree_maple", + "t_tree_willow", + "t_tree_hickory", + "t_tree_young", + "t_underbrush", + "t_shrub" + ] + }, + "furniture": { + "^": [ "f_rubble_rock", "f_boulder_small", "f_boulder_medium" ], + "?": [ "f_dandelion", "f_flower_spurge", "f_burdock", "f_flower_tulip", "f_lily", "f_bluebell", "f_dahlia", "f_datura" ], + "T": "f_glowingbulb", + "@": "f_brambles", + "X": "f_mutpoppy" + } + } +] diff --git a/data/json/monstergroups/triffid.json b/data/json/monstergroups/triffid.json index 52c2547a73520..b0b3486557c11 100644 --- a/data/json/monstergroups/triffid.json +++ b/data/json/monstergroups/triffid.json @@ -4,30 +4,38 @@ "name": "GROUP_TRIFFID", "default": "mon_triffid", "monsters": [ - { "monster": "mon_triffid_young", "freq": 100, "cost_multiplier": 1 }, + { "monster": "mon_triffid_young", "freq": 300, "cost_multiplier": 0, "pack_size": [ 2, 4 ] }, { "monster": "mon_fungal_fighter", "freq": 100, "cost_multiplier": 1 }, + { "monster": "mon_triffid", "freq": 100, "cost_multiplier": 2, "pack_size": [ 2, 3 ] }, { "monster": "mon_vinebeast", "freq": 160, "cost_multiplier": 10 }, { "monster": "mon_triffid_queen", "freq": 60, "cost_multiplier": 20 }, - { "monster": "mon_creeper_hub", "freq": 50, "cost_multiplier": 2 }, - { "monster": "mon_biollante", "freq": 50, "cost_multiplier": 2 }, - { "monster": "mon_triffid_heart", "freq": 0, "cost_multiplier": 0 } + { "monster": "mon_biollante", "freq": 100, "cost_multiplier": 2, "pack_size": [ 1, 3 ] }, + { "monster": "mon_triffid_flower", "freq": 100, "cost_multiplier": 4 } ] }, { "type": "monstergroup", "name": "GROUP_TRIFFID_OUTER", "default": "mon_triffid", - "//": "Same as GROUP_TRIFFID with no queen or heart, and creeper hubs/fungal fighters mixed in.", "monsters": [ - { "monster": "mon_triffid_young", "freq": 300, "cost_multiplier": 0, "pack_size": [ 2, 4 ] }, - { "monster": "mon_triffid", "freq": 100, "cost_multiplier": 2, "pack_size": [ 2, 3 ] }, + { "monster": "mon_triffid_young", "freq": 100, "cost_multiplier": 0, "pack_size": [ 2, 4 ] }, + { "monster": "mon_triffid", "freq": 300, "cost_multiplier": 2, "pack_size": [ 2, 3 ] }, { "monster": "mon_fungal_fighter", "freq": 160, "cost_multiplier": 0 }, { "monster": "mon_vinebeast", "freq": 160, "cost_multiplier": 10 }, - { "monster": "mon_creeper_hub", "freq": 50, "cost_multiplier": 2 }, { "monster": "mon_biollante", "freq": 50, "cost_multiplier": 2 }, { "monster": "mon_triffid_flower", "freq": 25, "cost_multiplier": 4 } ] }, + { + "type": "monstergroup", + "name": "GROUP_TRIFFID_HEARTGUARDS", + "default": "mon_triffid", + "monsters": [ + { "monster": "mon_triffid", "freq": 300, "cost_multiplier": 0, "pack_size": [ 4, 6 ] }, + { "monster": "mon_vinebeast", "freq": 260, "cost_multiplier": 2 }, + { "monster": "mon_triffid_queen", "freq": 160, "cost_multiplier": 5 } + ] + }, { "type": "monstergroup", "name": "GROUP_TRIFFID_HEART", diff --git a/data/json/monsters/triffid.json b/data/json/monsters/triffid.json index 4395fd8b13587..faf50b8a47e83 100644 --- a/data/json/monsters/triffid.json +++ b/data/json/monsters/triffid.json @@ -290,6 +290,7 @@ "morale": 100, "melee_cut": 0, "bleed_rate": 60, + "emit_fields": [ { "emit_id": "emit_pollen_stream", "delay": "1 s" } ], "harvest": "triffid_paralytic", "special_attacks": [ [ "SPIT_SAP", 3 ], [ "PARA_STING", 12 ] ], "death_function": [ "NORMAL" ], diff --git a/data/json/overmap/overmap_special/specials.json b/data/json/overmap/overmap_special/specials.json index 98c207020766c..ad0f2fbb22245 100644 --- a/data/json/overmap/overmap_special/specials.json +++ b/data/json/overmap/overmap_special/specials.json @@ -1289,16 +1289,34 @@ "type": "overmap_special", "id": "Triffid Grove", "overmaps": [ - { "point": [ 0, 0, 0 ], "overmap": "triffid_grove" }, - { "point": [ 0, 0, -1 ], "overmap": "triffid_roots" }, - { "point": [ 0, 0, -2 ], "overmap": "triffid_finale" } + { "point": [ 0, 0, 3 ], "overmap": "triffid_grove_roof_north" }, + { "point": [ 0, 0, 2 ], "overmap": "triffid_grove_z3_north" }, + { "point": [ 0, 0, 1 ], "overmap": "triffid_grove_z2_north" }, + { "point": [ 0, 0, 0 ], "overmap": "triffid_grove_north" }, + { "point": [ 0, 1, 0 ], "overmap": "triffid_field_north" }, + { "point": [ 0, -1, 0 ], "overmap": "triffid_field_north" }, + { "point": [ 1, 0, 0 ], "overmap": "triffid_field_north" }, + { "point": [ -1, 0, 0 ], "overmap": "triffid_field_north" }, + { "point": [ 1, 1, 0 ], "overmap": "triffid_field_north" }, + { "point": [ -1, -1, 0 ], "overmap": "triffid_field_north" }, + { "point": [ -1, 1, 0 ], "overmap": "triffid_field_north" }, + { "point": [ 1, -1, 0 ], "overmap": "triffid_field_north" }, + { "point": [ 0, 0, -1 ], "overmap": "triffid_roots_north" }, + { "point": [ 0, -1, -1 ], "overmap": "triffid_rootss_north" }, + { "point": [ 0, 1, -1 ], "overmap": "triffid_rootsn_north" }, + { "point": [ 1, 0, -1 ], "overmap": "triffid_rootse_north" }, + { "point": [ -1, 0, -1 ], "overmap": "triffid_rootsw_north" }, + { "point": [ 1, 1, -1 ], "overmap": "triffid_rootsen_north" }, + { "point": [ -1, 1, -1 ], "overmap": "triffid_rootsnw_north" }, + { "point": [ -1, -1, -1 ], "overmap": "triffid_rootssw_north" }, + { "point": [ 1, -1, -1 ], "overmap": "triffid_rootsse_north" }, + { "point": [ 0, 0, -2 ], "overmap": "triffid_finale_north" } ], "locations": [ "forest" ], "city_distance": [ 10, -1 ], "occurrences": [ 0, 3 ], "flags": [ "TRIFFID" ], - "rotate": false, - "spawns": { "group": "GROUP_TRIFFID", "population": [ 800, 1300 ], "radius": [ 12, 20 ] } + "spawns": { "group": "GROUP_TRIFFID_OUTER", "population": [ 1000, 1600 ], "radius": [ 12, 20 ] } }, { "type": "overmap_special", diff --git a/data/json/overmap/overmap_terrain/overmap_terrain_hardcoded.json b/data/json/overmap/overmap_terrain/overmap_terrain_hardcoded.json index a47b500821000..641a86234638f 100644 --- a/data/json/overmap/overmap_terrain/overmap_terrain_hardcoded.json +++ b/data/json/overmap/overmap_terrain/overmap_terrain_hardcoded.json @@ -229,33 +229,6 @@ "see_cost": 2, "flags": [ "KNOWN_DOWN", "NO_ROTATE" ] }, - { - "type": "overmap_terrain", - "id": "triffid_grove", - "name": "triffid grove", - "sym": "T", - "color": "light_red", - "see_cost": 5, - "flags": [ "KNOWN_DOWN", "NO_ROTATE", "RISK_HIGH" ] - }, - { - "type": "overmap_terrain", - "id": "triffid_roots", - "name": "triffid roots", - "sym": "T", - "color": "light_red", - "see_cost": 5, - "flags": [ "KNOWN_UP", "KNOWN_DOWN", "NO_ROTATE" ] - }, - { - "type": "overmap_terrain", - "id": "triffid_finale", - "name": "triffid heart", - "sym": "T", - "color": "red", - "see_cost": 5, - "flags": [ "KNOWN_UP", "NO_ROTATE" ] - }, { "type": "overmap_terrain", "id": "cavern", diff --git a/data/json/overmap/overmap_terrain/overmap_terrain_triffid.json b/data/json/overmap/overmap_terrain/overmap_terrain_triffid.json new file mode 100644 index 0000000000000..7b0b3679be08f --- /dev/null +++ b/data/json/overmap/overmap_terrain/overmap_terrain_triffid.json @@ -0,0 +1,158 @@ +[ + { + "type": "overmap_terrain", + "id": "triffid_grove", + "name": "triffid grove", + "sym": "T", + "color": "light_red", + "see_cost": 5, + "mondensity": 2, + "flags": [ "KNOWN_UP", "KNOWN_DOWN", "RISK_HIGH" ] + }, + { + "type": "overmap_terrain", + "id": "triffid_roots", + "name": "triffid roots", + "sym": "T", + "color": "light_red", + "see_cost": 5, + "mondensity": 2, + "spawns": { "group": "GROUP_TRIFFID", "population": [ 40, 45 ], "chance": 80 }, + "flags": [ "KNOWN_UP", "KNOWN_DOWN", "RISK_HIGH" ] + }, + { + "type": "overmap_terrain", + "id": "triffid_rootss", + "name": "triffid roots", + "sym": "T", + "color": "light_red", + "see_cost": 5, + "mondensity": 2, + "spawns": { "group": "GROUP_TRIFFID", "population": [ 40, 45 ], "chance": 80 }, + "flags": [ "KNOWN_UP", "KNOWN_DOWN", "RISK_HIGH" ] + }, + { + "type": "overmap_terrain", + "id": "triffid_rootsn", + "name": "triffid roots", + "sym": "T", + "color": "light_red", + "see_cost": 5, + "mondensity": 2, + "spawns": { "group": "GROUP_TRIFFID", "population": [ 40, 45 ], "chance": 80 }, + "flags": [ "KNOWN_UP", "KNOWN_DOWN", "RISK_HIGH" ] + }, + { + "type": "overmap_terrain", + "id": "triffid_rootse", + "name": "triffid roots", + "sym": "T", + "color": "light_red", + "see_cost": 5, + "mondensity": 2, + "spawns": { "group": "GROUP_TRIFFID", "population": [ 40, 45 ], "chance": 80 }, + "flags": [ "KNOWN_UP", "KNOWN_DOWN", "RISK_HIGH" ] + }, + { + "type": "overmap_terrain", + "id": "triffid_rootsw", + "name": "triffid roots", + "sym": "T", + "color": "light_red", + "see_cost": 5, + "mondensity": 2, + "spawns": { "group": "GROUP_TRIFFID", "population": [ 40, 45 ], "chance": 80 }, + "flags": [ "KNOWN_UP", "KNOWN_DOWN", "RISK_HIGH" ] + }, + { + "type": "overmap_terrain", + "id": "triffid_rootsen", + "name": "triffid roots", + "sym": "T", + "color": "light_red", + "see_cost": 5, + "mondensity": 2, + "spawns": { "group": "GROUP_TRIFFID", "population": [ 40, 45 ], "chance": 80 }, + "flags": [ "KNOWN_UP", "KNOWN_DOWN", "RISK_HIGH" ] + }, + { + "type": "overmap_terrain", + "id": "triffid_rootsnw", + "name": "triffid roots", + "sym": "T", + "color": "light_red", + "see_cost": 5, + "mondensity": 2, + "spawns": { "group": "GROUP_TRIFFID", "population": [ 40, 45 ], "chance": 80 }, + "flags": [ "KNOWN_UP", "KNOWN_DOWN", "RISK_HIGH" ] + }, + { + "type": "overmap_terrain", + "id": "triffid_rootssw", + "name": "triffid roots", + "sym": "T", + "color": "light_red", + "see_cost": 5, + "mondensity": 2, + "spawns": { "group": "GROUP_TRIFFID", "population": [ 40, 45 ], "chance": 80 }, + "flags": [ "KNOWN_UP", "KNOWN_DOWN", "RISK_HIGH" ] + }, + { + "type": "overmap_terrain", + "id": "triffid_rootsse", + "name": "triffid roots", + "sym": "T", + "color": "light_red", + "see_cost": 5, + "mondensity": 2, + "spawns": { "group": "GROUP_TRIFFID", "population": [ 40, 45 ], "chance": 80 }, + "flags": [ "KNOWN_UP", "KNOWN_DOWN", "RISK_HIGH" ] + }, + { + "type": "overmap_terrain", + "id": "triffid_finale", + "name": "triffid heart", + "sym": "T", + "color": "red", + "see_cost": 5, + "mondensity": 2, + "spawns": { "group": "GROUP_TRIFFID_HEARTGUARDS", "population": [ 50, 60 ], "chance": 80 }, + "flags": [ "KNOWN_UP", "RISK_HIGH" ] + }, + { + "type": "overmap_terrain", + "id": "triffid_grove_z3", + "name": "triffid grove trunk", + "sym": "T", + "color": "light_red", + "see_cost": 5, + "flags": [ "KNOWN_UP", "KNOWN_DOWN", "RISK_HIGH" ] + }, + { + "type": "overmap_terrain", + "id": "triffid_grove_z2", + "name": "triffid grove trunk", + "sym": "T", + "color": "light_red", + "see_cost": 5, + "flags": [ "KNOWN_UP", "KNOWN_DOWN", "RISK_HIGH" ] + }, + { + "type": "overmap_terrain", + "id": "triffid_grove_roof", + "name": "triffid grove roof", + "sym": "T", + "color": "light_red", + "see_cost": 5, + "flags": [ "KNOWN_DOWN", "RISK_HIGH" ] + }, + { + "type": "overmap_terrain", + "id": "triffid_field", + "name": "vibrant field", + "sym": ".", + "color": "green", + "see_cost": 5, + "mondensity": 2 + } +] diff --git a/src/map.h b/src/map.h index e6116f5a4cdb8..48f4a358ae055 100644 --- a/src/map.h +++ b/src/map.h @@ -1651,7 +1651,6 @@ class map void draw_anthill( const mapgendata &dat ); void draw_slimepit( const mapgendata &dat ); void draw_spider_pit( const mapgendata &dat ); - void draw_triffid( const mapgendata &dat ); void draw_connections( const mapgendata &dat ); // Builds a transparency cache and returns true if the cache was invalidated. diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 4d535dad68ab4..ea4de782eddf7 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -90,10 +90,6 @@ static const mongroup_id GROUP_NETHER( "GROUP_NETHER" ); static const mongroup_id GROUP_ROBOT_SECUBOT( "GROUP_ROBOT_SECUBOT" ); static const mongroup_id GROUP_SEWER( "GROUP_SEWER" ); static const mongroup_id GROUP_SLIME( "GROUP_SLIME" ); -static const mongroup_id GROUP_SPIDER( "GROUP_SPIDER" ); -static const mongroup_id GROUP_TRIFFID( "GROUP_TRIFFID" ); -static const mongroup_id GROUP_TRIFFID_HEART( "GROUP_TRIFFID_HEART" ); -static const mongroup_id GROUP_TRIFFID_OUTER( "GROUP_TRIFFID_OUTER" ); static const mongroup_id GROUP_TURRET( "GROUP_TURRET" ); static const trait_id trait_NPC_STATIC_NPC( "NPC_STATIC_NPC" ); @@ -2904,8 +2900,6 @@ void map::draw_map( mapgendata &dat ) if( is_ot_match( "slimepit", terrain_type, ot_match_type::prefix ) || is_ot_match( "slime_pit", terrain_type, ot_match_type::prefix ) ) { draw_slimepit( dat ); - } else if( is_ot_match( "triffid", terrain_type, ot_match_type::prefix ) ) { - draw_triffid( dat ); } else if( is_ot_match( "spider", terrain_type, ot_match_type::prefix ) ) { draw_spider_pit( dat ); } else if( is_ot_match( "temple", terrain_type, ot_match_type::prefix ) ) { @@ -4635,153 +4629,6 @@ void map::draw_slimepit( const mapgendata &dat ) } } -void map::draw_triffid( const mapgendata &dat ) -{ - const oter_id &terrain_type = dat.terrain_type(); - if( terrain_type == "triffid_roots" ) { - fill_background( this, t_root_wall ); - int node = 0; - int step = 0; - bool node_built[16]; - bool done = false; - for( auto &elem : node_built ) { - elem = false; - } - do { - node_built[node] = true; - step++; - point node2( 1 + 6 * ( node % 4 ), 1 + 6 * static_cast( node / 4 ) ); - // Clear a 4x4 dirt square - square( this, t_dirt, node2, node2 + point( 3, 3 ) ); - // Spawn a monster in there - if( step > 2 ) { // First couple of chambers are safe - int monrng = rng( 1, 25 ); - point spawn( node2 + point( rng( 0, 3 ), rng( 0, 3 ) ) ); - if( monrng <= 24 ) { - place_spawns( GROUP_TRIFFID_OUTER, 1, node2, - node2 + point( 3, 3 ), 1, true ); - } else { - for( int webx = node2.x; webx <= node2.x + 3; webx++ ) { - for( int weby = node2.y; weby <= node2.y + 3; weby++ ) { - add_field( {webx, weby, abs_sub.z}, fd_web, rng( 1, 3 ) ); - } - } - place_spawns( GROUP_SPIDER, 1, spawn, spawn, 1, true ); - } - } - // TODO: Non-monster hazards? - // Next, pick a cell to move to - std::vector move; - if( node % 4 > 0 && !node_built[node - 1] ) { - move.push_back( direction::WEST ); - } - if( node % 4 < 3 && !node_built[node + 1] ) { - move.push_back( direction::EAST ); - } - if( static_cast( node / 4 ) > 0 && !node_built[node - 4] ) { - move.push_back( direction::NORTH ); - } - if( static_cast( node / 4 ) < 3 && !node_built[node + 4] ) { - move.push_back( direction::SOUTH ); - } - - if( move.empty() ) { // Nowhere to go! - square( this, t_slope_down, node2 + point_south_east, node2 + point( 2, 2 ) ); - done = true; - } else { - switch( random_entry( move ) ) { - case direction::NORTH: - square( this, t_dirt, node2 + point( 1, -2 ), node2 + point( 2, -1 ) ); - node -= 4; - break; - case direction::EAST: - square( this, t_dirt, node2 + point( 4, 1 ), node2 + point( 5, 2 ) ); - node++; - break; - case direction::SOUTH: - square( this, t_dirt, node2 + point( 1, 4 ), node2 + point( 2, 5 ) ); - node += 4; - break; - case direction::WEST: - square( this, t_dirt, node2 + point( -2, 1 ), node2 + point( -1, 2 ) ); - node--; - break; - default: - break; - } - } - } while( !done ); - square( this, t_slope_up, point( 2, 2 ), point( 3, 3 ) ); - rotate( rng( 0, 3 ) ); - } else if( terrain_type == "triffid_finale" ) { - fill_background( this, t_root_wall ); - // NOLINTNEXTLINE(cata-use-named-point-constants) - square( this, t_dirt, point( 1, 1 ), point( 4, 4 ) ); - square( this, t_dirt, point( 19, 19 ), point( 22, 22 ) ); - // Drunken walk until we reach the heart (lower right, [19, 19]) - // Chance increases by 1 each turn, and gives the % chance of forcing a move - // to the right or down. - int chance = 0; - point p( 4, 4 ); - do { - ter_set( p, t_dirt ); - - if( chance >= 10 && one_in( 10 ) ) { // Add a spawn - place_spawns( GROUP_TRIFFID, 1, p, p, 1, true ); - } - - if( rng( 0, 99 ) < chance ) { // Force movement down or to the right - if( p.x >= 19 ) { - p.y++; - } else if( p.y >= 19 ) { - p.x++; - } else { - if( one_in( 2 ) ) { - p.x++; - } else { - p.y++; - } - } - } else { - chance++; // Increase chance of forced movement down/right - // Weigh movement towards directions with lots of existing walls - int chance_west = 0; - int chance_east = 0; - int chance_north = 0; - int chance_south = 0; - for( int dist = 1; dist <= 5; dist++ ) { - if( ter( p + point( -dist, 0 ) ) == t_root_wall ) { - chance_west++; - } - if( ter( p + point( dist, 0 ) ) == t_root_wall ) { - chance_east++; - } - if( ter( p + point( 0, -dist ) ) == t_root_wall ) { - chance_north++; - } - if( ter( p + point( 0, dist ) ) == t_root_wall ) { - chance_south++; - } - } - int roll = rng( 0, chance_west + chance_east + chance_north + chance_south ); - if( roll < chance_west && p.x > 0 ) { - p.x--; - } else if( roll < chance_west + chance_east && p.x < EAST_EDGE ) { - p.x++; - } else if( roll < chance_west + chance_east + chance_north && p.y > 0 ) { - p.y--; - } else if( p.y < SOUTH_EDGE ) { - p.y++; - } - } // Done with drunken walk - } while( p.x < 19 || p.y < 19 ); - // NOLINTNEXTLINE(cata-use-named-point-constants) - square( this, t_slope_up, point( 1, 1 ), point( 2, 2 ) ); - place_spawns( GROUP_TRIFFID_HEART, 1, point( 21, 21 ), point( 21, 21 ), 1, true ); - - } -} - void map::draw_connections( const mapgendata &dat ) { const oter_id &terrain_type = dat.terrain_type(); diff --git a/src/monster.cpp b/src/monster.cpp index e7eb144711b90..3576e10e1a6e0 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -87,6 +87,7 @@ static const efftype_id effect_onfire( "onfire" ); static const efftype_id effect_pacified( "pacified" ); static const efftype_id effect_paralyzepoison( "paralyzepoison" ); static const efftype_id effect_poison( "poison" ); +static const efftype_id effect_tpollen( "tpollen" ); static const efftype_id effect_ridden( "ridden" ); static const efftype_id effect_run( "run" ); static const efftype_id effect_stunned( "stunned" ); @@ -109,6 +110,7 @@ static const species_id species_MAMMAL( "MAMMAL" ); static const species_id species_MOLLUSK( "MOLLUSK" ); static const species_id species_NETHER( "NETHER" ); static const species_id species_ROBOT( "ROBOT" ); +static const species_id species_PLANT( "PLANT" ); static const species_id species_ZOMBIE( "ZOMBIE" ); static const trait_id trait_ANIMALDISCORD( "ANIMALDISCORD" ); @@ -1398,6 +1400,10 @@ bool monster::is_immune_effect( const efftype_id &effect ) const !made_of_any( Creature::cmat_flesh ) || type->in_species( species_LEECH_PLANT ); } + if( effect == effect_tpollen ) { + return type->in_species( species_PLANT ); + } + if( effect == effect_stunned ) { return has_flag( MF_STUN_IMMUNE ); } diff --git a/src/overmap.cpp b/src/overmap.cpp index df96a3d751909..c8c4b8c2aeb67 100644 --- a/src/overmap.cpp +++ b/src/overmap.cpp @@ -744,9 +744,7 @@ bool oter_t::is_hardcoded() const "spider_pit_under", "temple", "temple_finale", - "temple_stairs", - "triffid_finale", - "triffid_roots" + "temple_stairs" }; return hardcoded_mapgen.find( get_mapgen_id() ) != hardcoded_mapgen.end(); From a410f3346f46a88874189fb615558f6dd53a115b Mon Sep 17 00:00:00 2001 From: Zhilkin Serg Date: Thu, 8 Jul 2021 01:37:16 +0300 Subject: [PATCH 056/116] Allow custom surround monster groups in scenarios (#47990) --- data/json/monstergroups/misc.json | 39 ++++++++++++++++++++++++++++++ data/json/scenarios.json | 9 ++++--- data/mods/Magiclysm/scenarios.json | 3 ++- doc/JSON_FLAGS.md | 1 - doc/MODDING.md | 3 ++- src/game.cpp | 13 +++++++--- src/scenario.cpp | 8 ++++++ src/scenario.h | 3 +++ 8 files changed, 70 insertions(+), 9 deletions(-) diff --git a/data/json/monstergroups/misc.json b/data/json/monstergroups/misc.json index 1bd7a3f098902..da1d1e6008307 100644 --- a/data/json/monstergroups/misc.json +++ b/data/json/monstergroups/misc.json @@ -5,6 +5,45 @@ "is_safe": true, "default": "mon_null" }, + { + "type": "monstergroup", + "name": "GROUP_BLACK_ROAD", + "default": "mon_zombie", + "monsters": [ + { "monster": "mon_zombie", "freq": 1, "cost_multiplier": 7, "pack_size": [ 5, 20 ] }, + { "monster": "mon_zombie", "freq": 1, "cost_multiplier": 13, "pack_size": [ 15, 40 ] }, + { "monster": "mon_zombie", "freq": 1, "cost_multiplier": 20, "pack_size": [ 25, 60 ] }, + { "monster": "mon_zombie", "freq": 75, "cost_multiplier": 0 }, + { "monster": "mon_zombie_fat", "freq": 75, "cost_multiplier": 2 }, + { "monster": "mon_zombie_fat", "freq": 3, "cost_multiplier": 7, "pack_size": [ 3, 5 ] }, + { "monster": "mon_zombie_tough", "freq": 75, "cost_multiplier": 3 }, + { "monster": "mon_zombie_child", "freq": 75, "cost_multiplier": 1 }, + { "monster": "mon_zombie_rot", "freq": 50, "cost_multiplier": 3 }, + { "monster": "mon_zombie_crawler", "freq": 25, "cost_multiplier": 3 }, + { "monster": "mon_zombie_dog", "freq": 20, "cost_multiplier": 2 }, + { "monster": "mon_zombie_dog", "freq": 1, "cost_multiplier": 4, "pack_size": [ 3, 5 ] }, + { "monster": "mon_zombie_dog", "freq": 1, "cost_multiplier": 16, "pack_size": [ 5, 8 ] }, + { "monster": "mon_zombie_dog", "freq": 1, "cost_multiplier": 24, "pack_size": [ 8, 12 ] }, + { "monster": "mon_dog_zombie_cop", "freq": 5, "cost_multiplier": 4 }, + { "monster": "mon_dog_zombie_rot", "freq": 5, "cost_multiplier": 5 }, + { "monster": "mon_zombie_soldier", "freq": 10, "cost_multiplier": 2 }, + { "monster": "mon_zombie_cop", "freq": 20, "cost_multiplier": 3 }, + { "monster": "mon_zombie_swat", "freq": 10, "cost_multiplier": 3 }, + { "monster": "mon_zombie_hazmat", "freq": 10, "cost_multiplier": 3 }, + { "monster": "mon_zombie_fireman", "freq": 10, "cost_multiplier": 2 }, + { "monster": "mon_zombie_swimmer", "freq": 10, "cost_multiplier": 5 }, + { "monster": "mon_zombie_static", "freq": 10, "cost_multiplier": 5 }, + { "monster": "mon_zombie_survivor", "freq": 1, "cost_multiplier": 25 }, + { "monster": "mon_zombie_survivor_elite", "freq": 1, "cost_multiplier": 25, "starts": 1440 }, + { "monster": "mon_beekeeper", "freq": 1, "cost_multiplier": 5 }, + { "monster": "mon_zombie_technician", "freq": 1, "cost_multiplier": 12 }, + { "monster": "mon_zombie_runner", "freq": 20, "cost_multiplier": 5, "pack_size": [ 1, 4 ] }, + { "monster": "mon_feral_human_pipe", "freq": 4, "cost_multiplier": 1, "pack_size": [ 2, 3 ] }, + { "monster": "mon_feral_human_crowbar", "freq": 4, "cost_multiplier": 1, "pack_size": [ 2, 3 ] }, + { "monster": "mon_feral_human_axe", "freq": 2, "cost_multiplier": 2, "pack_size": [ 1, 2 ] }, + { "monster": "mon_zombie_brainless", "freq": 65, "cost_multiplier": 1 } + ] + }, { "type": "monstergroup", "name": "GROUP_CHUD", diff --git a/data/json/scenarios.json b/data/json/scenarios.json index 04c2e700792e3..a639ca8ac13be 100644 --- a/data/json/scenarios.json +++ b/data/json/scenarios.json @@ -58,7 +58,8 @@ "sloc_school" ], "start_name": "In Large Building", - "flags": [ "SUR_START", "CITY_START", "LONE_START" ] + "surround_groups": [ [ "GROUP_BLACK_ROAD", 70.0 ] ], + "flags": [ "CITY_START", "LONE_START" ] }, { "type": "scenario", @@ -85,7 +86,8 @@ "sloc_police" ], "start_name": "In Town", - "flags": [ "SUR_START", "CITY_START", "LONE_START" ] + "surround_groups": [ [ "GROUP_BLACK_ROAD", 70.0 ] ], + "flags": [ "CITY_START", "LONE_START" ] }, { "type": "scenario", @@ -318,7 +320,8 @@ "sloc_campground" ], "start_name": "Outside Town", - "flags": [ "SUR_START", "LONE_START" ], + "surround_groups": [ [ "GROUP_BLACK_ROAD", 70.0 ] ], + "flags": [ "LONE_START" ], "custom_initial_date": { "season": "winter" }, "add_professions": true, "professions": [ "sheltered_survivor", "sheltered_militia", "winter_scavenger", "winter_army" ] diff --git a/data/mods/Magiclysm/scenarios.json b/data/mods/Magiclysm/scenarios.json index cb7966e68cf34..a76016ef8e5ef 100644 --- a/data/mods/Magiclysm/scenarios.json +++ b/data/mods/Magiclysm/scenarios.json @@ -3,7 +3,8 @@ "type": "scenario", "id": "lost_faith", "name": "Lost Faith", - "flags": [ "SUR_START", "LONE_START" ], + "surround_groups": [ [ "GROUP_BLACK_ROAD", 70.0 ] ], + "flags": [ "LONE_START" ], "points": 2, "description": "You've been preaching your faith for a long time, but the recent events have begun to make you doubt it. Wandering in your temple, you just found books that may restore your faith or shatter it completely.", "start_name": "Church", diff --git a/doc/JSON_FLAGS.md b/doc/JSON_FLAGS.md index 585752303986f..125e43a2e4785 100644 --- a/doc/JSON_FLAGS.md +++ b/doc/JSON_FLAGS.md @@ -1227,7 +1227,6 @@ These branches are also the valid entries for the categories of `dreams` in `dre - ```INFECTED``` Player starts the game infected. - ```FUNGAL_INFECTION``` Player starts the game with a fungal infection. - ```LONE_START``` If starting NPC spawn option is switched to "Scenario-based", this scenario won't spawn a fellow NPC on game start. -- ```SUR_START``` Surrounded start, zombies outside the starting location. #### Profession Flags diff --git a/doc/MODDING.md b/doc/MODDING.md index 573a769785332..c2990d6784af3 100644 --- a/doc/MODDING.md +++ b/doc/MODDING.md @@ -83,7 +83,8 @@ Scenarios are what the game uses to determine your general situation when you cr "hospital_9" ], "start_name": "In Large Building", - "flags": [ "SUR_START", "CITY_START", "LONE_START" ] + "surround_groups": [ [ "GROUP_BLACK_ROAD", 70.0 ] ], + "flags": [ "CITY_START", "LONE_START" ] } ] ```` diff --git a/src/game.cpp b/src/game.cpp index 1836558b29b42..2af02c0750b47 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -743,11 +743,18 @@ bool game::start_game() //Load NPCs. Set nearby npcs to active. load_npcs(); // Spawn the monsters - const bool spawn_near = - get_option( "BLACK_ROAD" ) || get_scenario()->has_flag( "SUR_START" ); // Surrounded start ones + std::vector> surround_groups = get_scenario()->surround_groups(); + const bool surrounded_start_scenario = !surround_groups.empty(); + const bool surrounded_start_options = get_option( "BLACK_ROAD" ); + if( surrounded_start_options && !surrounded_start_scenario ) { + surround_groups.emplace_back( mongroup_id( "GROUP_BLACK_ROAD" ), 70.0f ); + } + const bool spawn_near = surrounded_start_options || surrounded_start_scenario; if( spawn_near ) { - start_loc.surround_with_monsters( omtstart, mongroup_id( "GROUP_ZOMBIE" ), 70 ); + for( const std::pair &sg : surround_groups ) { + start_loc.surround_with_monsters( omtstart, sg.first, sg.second ); + } } m.spawn_monsters( !spawn_near ); // Static monsters diff --git a/src/scenario.cpp b/src/scenario.cpp index 16a7caf257484..03833dded73e5 100644 --- a/src/scenario.cpp +++ b/src/scenario.cpp @@ -120,6 +120,10 @@ void scenario::load( const JsonObject &jo, const std::string & ) if( jo.has_string( "vehicle" ) ) { _starting_vehicle = vproto_id( jo.get_string( "vehicle" ) ); } + + for( JsonArray ja : jo.get_array( "surround_groups" ) ) { + _surround_groups.emplace_back( mongroup_id( ja.get_string( 0 ) ), ja.get_float( 1 ) ); + } } const scenario *scenario::generic() @@ -541,4 +545,8 @@ const std::vector &scenario::missions() const { return _missions; } +const std::vector> &scenario::surround_groups() const +{ + return _surround_groups; +} // vim:ts=4:sw=4:et:tw=0:fdm=marker: diff --git a/src/scenario.h b/src/scenario.h index cfada3918d41d..e08bb0f5e62fa 100644 --- a/src/scenario.h +++ b/src/scenario.h @@ -56,6 +56,8 @@ class scenario vproto_id _starting_vehicle = vproto_id::NULL_ID(); + std::vector> _surround_groups; + void load( const JsonObject &jo, const std::string &src ); bool scenario_traits_conflict_with_profession_traits( const profession &p ) const; @@ -128,6 +130,7 @@ class scenario bool can_pick( const scenario ¤t_scenario, int points ) const; const std::vector &missions() const; + const std::vector> &surround_groups() const; }; From 69365db3a40dd03fcc4a2f552ba36a0f7b779840 Mon Sep 17 00:00:00 2001 From: Jamuro-g <76928284+Jamuro-g@users.noreply.github.com> Date: Thu, 8 Jul 2021 02:07:24 +0200 Subject: [PATCH 057/116] Added tent construct/deconstruct activities (#47959) * tent activities --- data/json/player_activities.json | 22 +++++++ src/activity_actor.cpp | 107 ++++++++++++++++++++++++++++++- src/activity_actor_definitions.h | 63 ++++++++++++++++++ src/iexamine.cpp | 10 +-- src/iuse_actor.cpp | 20 ++---- 5 files changed, 200 insertions(+), 22 deletions(-) diff --git a/data/json/player_activities.json b/data/json/player_activities.json index 3ced2d6de6b7b..f628c3d20b141 100644 --- a/data/json/player_activities.json +++ b/data/json/player_activities.json @@ -942,5 +942,27 @@ "suspendable": false, "based_on": "time", "no_resume": true + }, + { + "id": "ACT_TENT_PLACE", + "type": "activity_type", + "activity_level": "LIGHT_EXERCISE", + "verb": "pitching a tent", + "rooted": true, + "based_on": "time", + "no_resume": true, + "refuel_fires": false, + "auto_needs": false + }, + { + "id": "ACT_TENT_DECONSTRUCT", + "type": "activity_type", + "activity_level": "LIGHT_EXERCISE", + "verb": "packing up a tent", + "rooted": true, + "based_on": "time", + "no_resume": true, + "refuel_fires": false, + "auto_needs": false } ] diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index 0eccffdce5ed1..2eac2dfad7912 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -2852,6 +2852,110 @@ std::unique_ptr disassemble_activity_actor::deserialize( JsonIn return actor.clone(); } +void tent_placement_activity_actor::start( player_activity &act, Character & ) +{ + act.moves_total = moves_total; + act.moves_left = moves_total; +} + +void tent_placement_activity_actor::finish( player_activity &act, Character &p ) +{ + map &here = get_map(); + const tripoint center = p.pos() + tripoint( ( radius + 1 ) * target.x, ( radius + 1 ) * target.y, + 0 ); + + // Make a square of floor surrounded by wall. + for( const tripoint &dest : here.points_in_radius( center, radius ) ) { + here.furn_set( dest, wall ); + } + for( const tripoint &dest : here.points_in_radius( center, radius - 1 ) ) { + here.furn_set( dest, floor ); + } + // Place the center floor and the door. + if( floor_center ) { + here.furn_set( center, *floor_center ); + } + here.furn_set( p.pos() + target, door_closed ); + + add_msg( m_info, _( "You set up the %s on the ground." ), it.tname() ); + add_msg( m_info, _( "Examine the center square to pack it up again." ) ); + act.set_to_null(); +} + +void tent_placement_activity_actor::canceled( player_activity &, Character &p ) +{ + map &here = get_map(); + here.add_item_or_charges( p.pos() + target, it, true ); +} + +void tent_placement_activity_actor::serialize( JsonOut &jsout ) const +{ + jsout.start_object(); + jsout.member( "moves_total", moves_total ); + jsout.member( "wall", wall ); + jsout.member( "floor", floor ); + jsout.member( "floor_center", floor_center ); + jsout.member( "door_closed", door_closed ); + jsout.member( "radius", radius ); + jsout.member( "it", it ); + jsout.member( "target", target ); + jsout.end_object(); +} + +std::unique_ptr tent_placement_activity_actor::deserialize( JsonIn &jsin ) +{ + item it; + tent_placement_activity_actor actor( 0, {}, 0, it, {}, {}, {}, {} ); + JsonObject data = jsin.get_object(); + data.read( "moves_total", actor.moves_total ); + data.read( "wall", actor.wall ); + data.read( "floor", actor.floor ); + data.read( "floor_center", actor.floor_center ); + data.read( "door_closed", actor.door_closed ); + data.read( "radius", actor.radius ); + data.read( "it", actor.it ); + data.read( "target", actor.target ); + return actor.clone(); +} + +void tent_deconstruct_activity_actor::start( player_activity &act, Character & ) +{ + act.moves_total = moves_total; + act.moves_left = moves_total; +} + +void tent_deconstruct_activity_actor::finish( player_activity &act, Character & ) +{ + map &here = get_map(); + for( const tripoint &pt : here.points_in_radius( target, radius ) ) { + here.furn_set( pt, f_null ); + } + here.add_item_or_charges( target, item( tent, calendar::turn ) ); + act.set_to_null(); +} + +void tent_deconstruct_activity_actor::serialize( JsonOut &jsout ) const +{ + jsout.start_object(); + jsout.member( "moves_total", moves_total ); + jsout.member( "radius", radius ); + jsout.member( "target", target ); + jsout.member( "tent", tent ); + jsout.end_object(); +} + +std::unique_ptr tent_deconstruct_activity_actor::deserialize( JsonIn &jsin ) +{ + tent_deconstruct_activity_actor actor( 0, 0, {}, {} ); + JsonObject data = jsin.get_object(); + data.read( "moves_total", actor.moves_total ); + data.read( "radius", actor.radius ); + data.read( "target", actor.target ); + data.read( "tent", actor.tent ); + + return actor.clone(); +} + void meditate_activity_actor::start( player_activity &act, Character & ) { act.moves_total = to_moves( 20_minutes ); @@ -2905,7 +3009,6 @@ std::unique_ptr play_with_pet_activity_actor::deserialize( JsonI JsonObject data = jsin.get_object(); data.read( "pet_name", actor.pet_name ); - return actor.clone(); } @@ -2987,6 +3090,8 @@ deserialize_functions = { { activity_id( "ACT_RELOAD" ), &reload_activity_actor::deserialize }, { activity_id( "ACT_SHAVE" ), &shave_activity_actor::deserialize }, { activity_id( "ACT_STASH" ), &stash_activity_actor::deserialize }, + { activity_id( "ACT_TENT_DECONSTRUCT" ), &tent_deconstruct_activity_actor::deserialize }, + { activity_id( "ACT_TENT_PLACE" ), &tent_placement_activity_actor::deserialize }, { activity_id( "ACT_TRY_SLEEP" ), &try_sleep_activity_actor::deserialize }, { activity_id( "ACT_UNLOAD" ), &unload_activity_actor::deserialize }, { activity_id( "ACT_WORKOUT_HARD" ), &workout_activity_actor::deserialize }, diff --git a/src/activity_actor_definitions.h b/src/activity_actor_definitions.h index a245d29180781..378e508babe7b 100644 --- a/src/activity_actor_definitions.h +++ b/src/activity_actor_definitions.h @@ -1011,6 +1011,41 @@ class insert_item_activity_actor : public activity_actor static std::unique_ptr deserialize( JsonIn &jsin ); }; +class tent_placement_activity_actor : public activity_actor +{ + private: + int moves_total; + tripoint target; + int radius = 1; + item it; + string_id wall; + string_id floor; + cata::optional> floor_center; + string_id door_closed; + + public: + tent_placement_activity_actor( int moves_total, tripoint target, int radius, item it, + string_id wall, string_id floor, cata::optional> floor_center, + string_id door_closed ) : moves_total( moves_total ), target( target ), radius( radius ), + it( it ), wall( wall ), floor( floor ), floor_center( floor_center ), door_closed( door_closed ) {} + + activity_id get_type() const override { + return activity_id( "ACT_TENT_PLACE" ); + } + + void start( player_activity &act, Character & ) override; + void do_turn( player_activity &, Character & ) override {} + void finish( player_activity &act, Character &p ) override; + void canceled( player_activity &, Character &p ) override; + + std::unique_ptr clone() const override { + return std::make_unique( *this ); + } + + void serialize( JsonOut &jsout ) const override; + static std::unique_ptr deserialize( JsonIn &jsin ); +}; + class meditate_activity_actor : public activity_actor { public: @@ -1055,6 +1090,34 @@ class play_with_pet_activity_actor : public activity_actor static std::unique_ptr deserialize( JsonIn &jsin ); }; +class tent_deconstruct_activity_actor : public activity_actor +{ + private: + int moves_total; + int radius; + tripoint target; + itype_id tent; + + public: + tent_deconstruct_activity_actor( int moves_total, int radius, tripoint target, + itype_id tent ) : moves_total( moves_total ), radius( radius ), target( target ), tent( tent ) {} + + activity_id get_type() const override { + return activity_id( "ACT_TENT_DECONSTRUCT" ); + } + + void start( player_activity &act, Character & ) override; + void do_turn( player_activity &, Character & ) override {} + void finish( player_activity &act, Character & ) override; + + std::unique_ptr clone() const override { + return std::make_unique( *this ); + } + + void serialize( JsonOut &jsout ) const override; + static std::unique_ptr deserialize( JsonIn &jsin ); +}; + class shave_activity_actor : public activity_actor { public: diff --git a/src/iexamine.cpp b/src/iexamine.cpp index b50785a19a991..43a7835752a05 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -1308,7 +1308,6 @@ void iexamine::portable_structure( player &p, const tripoint &examp ) name = string_format( _( "damaged %s" ), name ); } radius = actor.radius; - } else { radius = std::max( 1, fid->bash.collapse_radius ); } @@ -1318,12 +1317,9 @@ void iexamine::portable_structure( player &p, const tripoint &examp ) return; } - p.moves -= to_moves( 2_seconds ); - for( const tripoint &pt : here.points_in_radius( examp, radius ) ) { - here.furn_set( pt, f_null ); - } - - here.add_item_or_charges( examp, item( dropped, calendar::turn ) ); + player_activity new_act = player_activity( tent_deconstruct_activity_actor( to_moves + ( 20_minutes ), radius, examp, dropped ) ); + p.assign_activity( new_act, false ); } /** diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 2448d5e8faa8c..60108382e2c24 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -4164,20 +4164,12 @@ cata::optional deploy_tent_actor::use( player &p, item &it, bool, const tri return cata::nullopt; } } - // Make a square of floor surrounded by wall. - for( const tripoint &dest : here.points_in_radius( center, radius ) ) { - here.furn_set( dest, wall ); - } - for( const tripoint &dest : here.points_in_radius( center, radius - 1 ) ) { - here.furn_set( dest, floor ); - } - // Place the center floor and the door. - if( floor_center ) { - here.furn_set( center, *floor_center ); - } - here.furn_set( p.pos() + direction, door_closed ); - add_msg( m_info, _( "You set up the %s on the ground." ), it.tname() ); - add_msg( m_info, _( "Examine the center square to pack it up again." ) ); + + //checks done start activity: + player_activity new_act = player_activity( tent_placement_activity_actor( to_moves + ( 20_minutes ), direction, radius, it, wall, floor, floor_center, door_closed ) ); + get_player_character().assign_activity( new_act, false ); + return 1; } From bb0e1ffdc6b1828365bea835f3531dd24335984f Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Wed, 7 Jul 2021 17:50:50 -0700 Subject: [PATCH 058/116] Add z=-1 soil layer (#49658) * Allow specifying default terrain per z-level Allow regional_settings to specify the default overmap terrain for each level, and add a solid_earth overmap terrain (and soil terrain to fill it), representing a soil layer on z-1. * Fix hardcoded overmap terrain generation Overmap terrain features like sewers and ants needed some changes made to the overmap generation code to work with the new z-1 soil layer. * Replace rock with earth on z-1 JSON mapgens Replace rock floors with concrete floors in artifical structures, and with dirt ones in natural structures. Wall in (and shift rooms a bit to fit) the missile silo with metal walls on z=-1 - bare earth walls don't feel correct for a missile silo. * Move hardcoded slimepit generation down 1 z level Add a new JSON-ized top of the special - an open-topped slime pit leading down into the hardcoded special on z-2. * Adjust overmap terrains for z-1 soil level Some terrains are meant to look like solid rock, but that doesn't make sense anymore on z-1. Make them look like solid earth instead. * Update hardcoded mapgen for soil on z-1 Sewers could probably use some proper walls, but I'll leave that for someone else to update. --- .../furniture_and_terrain/terrain-walls.json | 21 + .../terrain-zlevel-transitions.json | 42 ++ .../json/mapgen/basement/basement_bionic.json | 4 +- data/json/mapgen/basement/basement_chem.json | 4 +- data/json/mapgen/basement/basement_game.json | 10 +- data/json/mapgen/basement/basement_guns.json | 14 +- .../mapgen/basement/basement_lab_stairs.json | 6 +- .../json/mapgen/basement/basement_messed.json | 2 +- data/json/mapgen/basement/basement_meth.json | 6 +- .../mapgen/basement/basement_survival.json | 34 +- data/json/mapgen/basement/basement_weed.json | 2 +- data/json/mapgen/bunker.json | 2 +- data/json/mapgen/cabin.json | 2 +- data/json/mapgen/cathedral.json | 2 +- data/json/mapgen/cave.json | 124 ++--- data/json/mapgen/earth.json | 37 ++ .../isherwood_farms/farm_isherwood.json | 4 +- data/json/mapgen/lab/lab_central.json | 2 +- .../lab/lab_surface/lab_surface_big_z-1.json | 2 +- data/json/mapgen/lab_subway_vent_shaft.json | 49 +- data/json/mapgen/lmoe.json | 2 +- data/json/mapgen/mall/mall_basement.json | 4 +- data/json/mapgen/mansion.json | 38 +- data/json/mapgen/mine/mine_shaft.json | 2 +- data/json/mapgen/missile_silo.json | 49 +- data/json/mapgen/necropolis/necropolisB1.json | 30 +- data/json/mapgen/pawn_shop.json | 2 +- data/json/mapgen/prison_1.json | 4 +- .../mapgen/railroad/railroad_station.json | 2 +- .../mapgen/refugee_center/rc_grounds_e.json | 2 +- .../mapgen/refugee_center/rc_grounds_n.json | 2 +- .../mapgen/refugee_center/rc_grounds_ne.json | 2 +- .../mapgen/refugee_center/rc_grounds_nw.json | 8 +- .../mapgen/refugee_center/rc_grounds_s.json | 2 +- .../mapgen/refugee_center/rc_grounds_se.json | 2 +- .../mapgen/refugee_center/rc_grounds_sw.json | 2 +- .../mapgen/refugee_center/rc_grounds_w.json | 2 +- .../refugee_center/z-1_refugee_center.json | 2 +- data/json/mapgen/river_shipwreck.json | 4 +- data/json/mapgen/sewage_treatment.json | 10 +- data/json/mapgen/slime_pit.json | 83 ++++ data/json/mapgen/sub_station.json | 12 +- data/json/mapgen/ws_survivor_bunker.json | 28 +- .../mapgen_palettes/airliner_palette.json | 2 +- data/json/mapgen_palettes/basement.json | 56 +-- .../json/mapgen_palettes/collapsed_tower.json | 2 +- .../mapgen_palettes/hotel_tower_palette.json | 2 +- .../house_general_palette.json | 2 +- data/json/mapgen_palettes/lmoe.json | 6 +- data/json/mapgen_palettes/mall_palette.json | 2 +- .../necropolis/necropolis_b1.json | 4 +- data/json/mapgen_palettes/office.json | 2 +- data/json/mapgen_palettes/prison.json | 2 +- data/json/mapgen_palettes/railroad.json | 2 +- data/json/mapgen_palettes/sewers_palette.json | 2 +- data/json/mapgen_palettes/shelter.json | 2 +- data/json/mapgen_palettes/subway.json | 3 +- .../overmap/overmap_special/specials.json | 2 +- .../overmap_terrain/overmap_terrain.json | 20 +- .../overmap_terrain_alien.json | 11 + .../overmap_terrain_evac_center.json | 462 +++++++++--------- .../overmap_terrain/overmap_terrain_lab.json | 6 +- .../overmap_terrain_necropolis.json | 12 +- data/json/overmap/special_locations.json | 2 +- data/json/regional_map_settings.json | 24 +- data/json/test_regions.json | 49 +- .../aftershock_exoplanet/region_settings.json | 24 +- .../desert_regional_map_settings.json | 24 +- .../rural_regional_map_settings.json | 24 +- src/map.cpp | 4 + src/mapgen.cpp | 5 +- src/mapgen_functions.cpp | 67 +-- src/overmap.cpp | 43 +- src/regional_settings.cpp | 7 +- src/regional_settings.h | 4 +- 75 files changed, 968 insertions(+), 574 deletions(-) create mode 100644 data/json/mapgen/earth.json create mode 100644 data/json/mapgen/slime_pit.json create mode 100644 data/json/overmap/overmap_terrain/overmap_terrain_alien.json diff --git a/data/json/furniture_and_terrain/terrain-walls.json b/data/json/furniture_and_terrain/terrain-walls.json index bdbc377be1f88..2175a346682f6 100644 --- a/data/json/furniture_and_terrain/terrain-walls.json +++ b/data/json/furniture_and_terrain/terrain-walls.json @@ -1241,6 +1241,27 @@ "items": [ { "item": "wax", "count": [ 3, 5 ] } ] } }, + { + "type": "terrain", + "id": "t_soil", + "name": "solid earth", + "description": "A wall of solid earth.", + "symbol": "#", + "color": "brown", + "move_cost": 0, + "coverage": 100, + "flags": [ "NOITEM", "SUPPORTS_ROOF", "WALL", "NO_SCENT", "MINEABLE", "BLOCK_WIND" ], + "roof": "t_dirt", + "bash": { + "str_min": 100, + "str_max": 400, + "sound": "wham!", + "sound_fail": "whump!", + "ter_set": "t_dirt", + "ter_set_bashed_from_above": "t_dirt", + "items": [ { "group": "digging_soil_loam_50L", "count": 20 } ] + } + }, { "type": "terrain", "id": "t_rock", diff --git a/data/json/furniture_and_terrain/terrain-zlevel-transitions.json b/data/json/furniture_and_terrain/terrain-zlevel-transitions.json index 9b9908772a021..a876c30bb4f8d 100644 --- a/data/json/furniture_and_terrain/terrain-zlevel-transitions.json +++ b/data/json/furniture_and_terrain/terrain-zlevel-transitions.json @@ -209,6 +209,48 @@ "move_cost": 2, "flags": [ "TRANSPARENT", "ROAD" ] }, + { + "type": "terrain", + "id": "t_earth_ramp_down_high", + "name": "earth ramp down (high end)", + "description": "The upper end of an earth ramp leading down.", + "symbol": ">", + "color": "brown", + "move_cost": 2, + "flags": [ "TRANSPARENT", "Z_TRANSPARENT" ] + }, + { + "type": "terrain", + "id": "t_earth_ramp_down_low", + "name": "earth ramp down (low end)", + "description": "The lower end of an earth ramp leading down.", + "connects_to": "WALL", + "symbol": ">", + "color": "brown", + "move_cost": 2, + "flags": [ "TRANSPARENT", "RAMP_DOWN", "Z_TRANSPARENT" ] + }, + { + "type": "terrain", + "id": "t_earth_ramp_up_high", + "name": "earth ramp up (high end)", + "connects_to": "WALL", + "description": "The upper end of an earth ramp leading up.", + "symbol": "<", + "color": "brown", + "move_cost": 2, + "flags": [ "RAMP_UP" ] + }, + { + "type": "terrain", + "id": "t_earth_ramp_up_low", + "name": "road ramp up (low end)", + "description": "The lower end of an earth ramp leading up.", + "symbol": "<", + "color": "brown", + "move_cost": 2, + "flags": [ "TRANSPARENT" ] + }, { "type": "terrain", "id": "t_sidewalk_ramp_down_high", diff --git a/data/json/mapgen/basement/basement_bionic.json b/data/json/mapgen/basement/basement_bionic.json index 431de1d917051..ffe8851916e2f 100644 --- a/data/json/mapgen/basement/basement_bionic.json +++ b/data/json/mapgen/basement/basement_bionic.json @@ -5,7 +5,7 @@ "om_terrain": [ "basement_bionic" ], "weight": 100, "object": { - "fill_ter": "t_rock_floor", + "fill_ter": "t_thconc_floor", "rows": [ " ", " |----------| ", @@ -81,7 +81,7 @@ "om_terrain": [ "basement_bionic_decoy" ], "weight": 100, "object": { - "fill_ter": "t_rock_floor", + "fill_ter": "t_thconc_floor", "rows": [ " ", " |----------| ", diff --git a/data/json/mapgen/basement/basement_chem.json b/data/json/mapgen/basement/basement_chem.json index f92fe66b0c711..01963a0801bda 100644 --- a/data/json/mapgen/basement/basement_chem.json +++ b/data/json/mapgen/basement/basement_chem.json @@ -6,7 +6,7 @@ "//": "matches house_29", "weight": 250, "object": { - "fill_ter": "t_rock", + "fill_ter": "t_soil", "rows": [ " ", " ", @@ -93,7 +93,7 @@ "//": "matches house_30", "weight": 200, "object": { - "fill_ter": "t_rock", + "fill_ter": "t_soil", "rows": [ " ", " ", diff --git a/data/json/mapgen/basement/basement_game.json b/data/json/mapgen/basement/basement_game.json index d3bd59b03c20c..445c72442aea0 100644 --- a/data/json/mapgen/basement/basement_game.json +++ b/data/json/mapgen/basement/basement_game.json @@ -7,7 +7,7 @@ "weight": 250, "object": { "rotation": [ 0, 3 ], - "fill_ter": "t_rock_floor", + "fill_ter": "t_thconc_floor", "rows": [ "|----| ", "|...i| ", @@ -59,7 +59,7 @@ "weight": 250, "object": { "rotation": [ 0, 3 ], - "fill_ter": "t_rock_floor", + "fill_ter": "t_thconc_floor", "rows": [ "|----| ", "|...i| ", @@ -111,7 +111,7 @@ "weight": 250, "object": { "rotation": [ 0, 3 ], - "fill_ter": "t_rock_floor", + "fill_ter": "t_thconc_floor", "rows": [ "|----| ", "|...i| ", @@ -161,7 +161,7 @@ "weight": 250, "object": { "rotation": [ 0, 3 ], - "fill_ter": "t_rock_floor", + "fill_ter": "t_thconc_floor", "rows": [ "|----| ", "|...i| ", @@ -211,7 +211,7 @@ "weight": 250, "object": { "rotation": [ 0, 3 ], - "fill_ter": "t_rock_floor", + "fill_ter": "t_thconc_floor", "rows": [ "111111 ", "1...i1 ", diff --git a/data/json/mapgen/basement/basement_guns.json b/data/json/mapgen/basement/basement_guns.json index 81728a6c98aa6..5e919bbe58d7b 100644 --- a/data/json/mapgen/basement/basement_guns.json +++ b/data/json/mapgen/basement/basement_guns.json @@ -6,7 +6,7 @@ "//": "used by house_31 and house_32", "weight": 250, "object": { - "fill_ter": "t_rock", + "fill_ter": "t_soil", "rotation": [ 0, 3 ], "rows": [ " -------------------- ", @@ -35,15 +35,15 @@ " " ], "terrain": { - "#": "t_rock_floor", + "#": "t_thconc_floor", "+": "t_door_c", "-": "t_wall", - ".": "t_rock_floor", + ".": "t_thconc_floor", "<": "t_stairs_up", - "]": "t_rock_floor", - "h": "t_rock_floor", - "s": "t_rock_floor", - "{": "t_rock_floor", + "]": "t_thconc_floor", + "h": "t_thconc_floor", + "s": "t_thconc_floor", + "{": "t_thconc_floor", "|": "t_wall" }, "furniture": { "#": "f_counter", "]": "f_bookcase", "h": "f_chair", "s": "f_gunsafe_ml", "{": "f_rack" }, diff --git a/data/json/mapgen/basement/basement_lab_stairs.json b/data/json/mapgen/basement/basement_lab_stairs.json index 95ba303d29da1..6c252c050fba6 100644 --- a/data/json/mapgen/basement/basement_lab_stairs.json +++ b/data/json/mapgen/basement/basement_lab_stairs.json @@ -37,7 +37,7 @@ "palettes": [ "lab_palette" ], "terrain": { "=": "t_wall", - ",": "t_rock_floor", + ",": "t_thconc_floor", "!": "t_card_science", "7": "t_thconc_floor", "<": "t_stairs_up", @@ -90,11 +90,11 @@ "furniture": { "X": "f_crate_c" }, "terrain": { "=": "t_concrete_wall", - "7": "t_rock_floor", + "7": "t_thconc_floor", "D": "t_door_metal_locked", ">": "t_stairs_down", "6": "t_card_science", - "X": "t_rock_floor" + "X": "t_thconc_floor" }, "place_loot": [ { "group": "alcohol", "x": [ 16, 20 ], "y": 6, "chance": 96 }, diff --git a/data/json/mapgen/basement/basement_messed.json b/data/json/mapgen/basement/basement_messed.json index 94bd53953ea19..1bd67e96c3780 100644 --- a/data/json/mapgen/basement/basement_messed.json +++ b/data/json/mapgen/basement/basement_messed.json @@ -6,7 +6,7 @@ "//": "used for house_crack1, house_crack2", "weight": 250, "object": { - "fill_ter": "t_rock", + "fill_ter": "t_soil", "rows": [ " ", " ", diff --git a/data/json/mapgen/basement/basement_meth.json b/data/json/mapgen/basement/basement_meth.json index 74124ce556469..d518fb8507640 100644 --- a/data/json/mapgen/basement/basement_meth.json +++ b/data/json/mapgen/basement/basement_meth.json @@ -6,7 +6,7 @@ "//": "linked to house_27.", "weight": 20, "object": { - "fill_ter": "t_rock", + "fill_ter": "t_soil", "rows": [ " ", " ", @@ -118,7 +118,7 @@ "//": "linked to house_27.", "weight": 250, "object": { - "fill_ter": "t_rock", + "fill_ter": "t_soil", "rows": [ " ", " ", @@ -176,7 +176,7 @@ "//": "linked to house_27.", "weight": 250, "object": { - "fill_ter": "t_rock", + "fill_ter": "t_soil", "rows": [ " ", " ", diff --git a/data/json/mapgen/basement/basement_survival.json b/data/json/mapgen/basement/basement_survival.json index 145cb64b24ff7..1924dbda2b532 100644 --- a/data/json/mapgen/basement/basement_survival.json +++ b/data/json/mapgen/basement/basement_survival.json @@ -20,7 +20,7 @@ "om_terrain": [ "basement_survival" ], "//": "matches house_26", "object": { - "fill_ter": "t_rock", + "fill_ter": "t_soil", "rows": [ " ", " ", @@ -48,25 +48,25 @@ " " ], "terrain": { - "#": "t_rock_floor", + "#": "t_thconc_floor", "+": "t_door_c", "-": "t_wall", - ".": "t_rock_floor", + ".": "t_thconc_floor", "<": "t_stairs_up", - "X": "t_rock_floor", - "]": "t_rock_floor", - "b": "t_rock_floor", - "c": "t_rock_floor", - "d": "t_rock_floor", - "f": "t_rock_floor", - "g": "t_rock_floor", - "h": "t_rock_floor", - "k": "t_rock_floor", - "s": "t_rock_floor", - "t": "t_rock_floor", - "x": "t_rock_floor", - "y": "t_rock_floor", - "{": "t_rock_floor", + "X": "t_thconc_floor", + "]": "t_thconc_floor", + "b": "t_thconc_floor", + "c": "t_thconc_floor", + "d": "t_thconc_floor", + "f": "t_thconc_floor", + "g": "t_thconc_floor", + "h": "t_thconc_floor", + "k": "t_thconc_floor", + "s": "t_thconc_floor", + "t": "t_thconc_floor", + "x": "t_thconc_floor", + "y": "t_thconc_floor", + "{": "t_thconc_floor", "|": "t_wall" }, "furniture": { diff --git a/data/json/mapgen/basement/basement_weed.json b/data/json/mapgen/basement/basement_weed.json index 80e52254b9411..c5c61a3032328 100644 --- a/data/json/mapgen/basement/basement_weed.json +++ b/data/json/mapgen/basement/basement_weed.json @@ -15,7 +15,7 @@ "om_terrain": [ "basement_weed" ], "//": "matches house_28", "object": { - "fill_ter": "t_rock", + "fill_ter": "t_soil", "rows": [ " ", " ", diff --git a/data/json/mapgen/bunker.json b/data/json/mapgen/bunker.json index 75bbb4a50dea6..2e1f0bbdf4a4a 100644 --- a/data/json/mapgen/bunker.json +++ b/data/json/mapgen/bunker.json @@ -93,7 +93,7 @@ "terrain": { " ": "t_floor", "r": "t_floor", - "#": "t_rock", + "#": "t_soil", "+": "t_door_metal_locked", "6": "t_card_military", "<": "t_stairs_up", diff --git a/data/json/mapgen/cabin.json b/data/json/mapgen/cabin.json index 1aeae9038575f..3f04847738e89 100644 --- a/data/json/mapgen/cabin.json +++ b/data/json/mapgen/cabin.json @@ -786,7 +786,7 @@ "r": { "furniture": "f_rack", "items": { "item": "cannedfood", "chance": 30 } } }, "terrain": { - "#": "t_rock", + "#": "t_soil", "+": "t_door_c", "-": "t_wall", "<": "t_stairs_up", diff --git a/data/json/mapgen/cathedral.json b/data/json/mapgen/cathedral.json index cab83defac573..04e1b8a96cc8f 100644 --- a/data/json/mapgen/cathedral.json +++ b/data/json/mapgen/cathedral.json @@ -111,7 +111,7 @@ ], "terrain": { " ": [ "t_grass", "t_grass", "t_grass", "t_dirt" ], - "#": "t_rock", + "#": "t_soil", "+": "t_door_c", "-": "t_wall", ".": "t_floor", diff --git a/data/json/mapgen/cave.json b/data/json/mapgen/cave.json index fe2edb477c030..7b64580e3501a 100644 --- a/data/json/mapgen/cave.json +++ b/data/json/mapgen/cave.json @@ -34,9 +34,9 @@ ], "terrain": { ".": [ [ "t_region_groundcover_forest", 4 ], [ "t_region_tree", 1 ] ], - "|": "t_rock", - ",": "t_rock_roof", - "%": [ "t_rock", "t_region_groundcover_forest" ], + "|": "t_soil", + ",": "t_dirt_underground", + "%": [ "t_soil", "t_region_groundcover_forest" ], ";": "t_dirt", "<": "t_slope_down" }, @@ -85,10 +85,10 @@ ], "terrain": { ".": [ [ "t_region_groundcover_forest", 4 ], [ "t_region_tree", 1 ] ], - "|": "t_rock", - "%": [ "t_rock", "t_region_groundcover_forest" ], + "|": "t_soil", + "%": [ "t_soil", "t_region_groundcover_forest" ], ";": "t_dirt", - ",": "t_rock_roof", + ",": "t_dirt_underground", "<": "t_slope_down" }, "furniture": { } @@ -129,11 +129,11 @@ ], "terrain": { ".": [ [ "t_region_groundcover_forest", 4 ], [ "t_region_tree", 1 ] ], - "|": "t_rock", - "%": [ "t_rock", "t_region_groundcover_forest" ], + "|": "t_soil", + "%": [ "t_soil", "t_region_groundcover_forest" ], ";": "t_dirt", - ",": "t_rock_roof", - "W": "t_rock_roof", + ",": "t_dirt_underground", + "W": "t_dirt_underground", "<": "t_slope_down" }, "furniture": { }, @@ -176,11 +176,11 @@ ], "terrain": { ".": [ [ "t_region_groundcover_forest", 4 ], [ "t_region_tree", 1 ] ], - "|": "t_rock", - "%": [ "t_rock", "t_region_groundcover_forest" ], + "|": "t_soil", + "%": [ "t_soil", "t_region_groundcover_forest" ], ";": "t_dirt", - ",": "t_rock_roof", - "W": "t_rock_roof", + ",": "t_dirt_underground", + "W": "t_dirt_underground", "<": "t_slope_down" }, "fields": { "W": { "field": "fd_web", "intensity": 1, "age": 10 } }, @@ -222,11 +222,11 @@ ], "terrain": { ".": [ [ "t_region_groundcover_forest", 4 ], [ "t_region_tree", 1 ] ], - "|": "t_rock", - "%": [ "t_rock", "t_region_groundcover_forest" ], + "|": "t_soil", + "%": [ "t_soil", "t_region_groundcover_forest" ], ";": "t_dirt", - ",": "t_rock_roof", - "B": "t_rock_roof", + ",": "t_dirt_underground", + "B": "t_dirt_underground", "<": "t_slope_down" }, "furniture": { }, @@ -268,12 +268,12 @@ ], "terrain": { ".": [ [ "t_region_groundcover_forest", 4 ], [ "t_region_tree", 1 ] ], - "|": "t_rock", - "%": [ "t_rock", "t_region_groundcover_forest" ], + "|": "t_soil", + "%": [ "t_soil", "t_region_groundcover_forest" ], ";": "t_dirt", - ",": "t_rock_roof", - "B": "t_rock_roof", - "W": "t_rock_roof", + ",": "t_dirt_underground", + "B": "t_dirt_underground", + "W": "t_dirt_underground", "<": "t_slope_down" }, "furniture": { }, @@ -316,12 +316,12 @@ ], "terrain": { ".": [ [ "t_region_groundcover_forest", 4 ], [ "t_region_tree", 1 ] ], - "|": "t_rock", - "%": [ "t_rock", "t_region_groundcover_forest" ], + "|": "t_soil", + "%": [ "t_soil", "t_region_groundcover_forest" ], ";": "t_dirt", - ",": "t_rock_roof", - "B": "t_rock_roof", - "W": "t_rock_roof", + ",": "t_dirt_underground", + "B": "t_dirt_underground", + "W": "t_dirt_underground", "<": "t_slope_down" }, "fields": { "W": { "field": "fd_web", "intensity": 1, "age": 10 } }, @@ -363,12 +363,12 @@ ], "terrain": { ".": [ [ "t_region_groundcover_forest", 4 ], [ "t_region_tree", 1 ] ], - "|": "t_rock", - "%": [ "t_rock", "t_region_groundcover_forest" ], + "|": "t_soil", + "%": [ "t_soil", "t_region_groundcover_forest" ], ";": "t_dirt", - ",": "t_rock_roof", - "B": "t_rock_roof", - "W": "t_rock_roof", + ",": "t_dirt_underground", + "B": "t_dirt_underground", + "W": "t_dirt_underground", "<": "t_slope_down" }, "furniture": { }, @@ -411,17 +411,17 @@ ], "terrain": { ".": [ [ "t_region_groundcover_forest", 4 ], [ "t_region_tree", 1 ] ], - "|": "t_rock", - "%": [ "t_rock", "t_region_groundcover_forest" ], - ";": "t_rock_floor_no_roof", - "!": "t_rock_floor_no_roof", - "?": "t_rock_floor_no_roof", - "#": "t_rock_floor_no_roof", - "~": "t_rock_floor_no_roof", - "@": "t_rock_roof", - ",": "t_rock_roof", - "q": "t_rock_roof", - "R": "t_rock_floor_no_roof" + "|": "t_soil", + "%": [ "t_soil", "t_region_groundcover_forest" ], + ";": "t_dirt", + "!": "t_dirt", + "?": "t_dirt", + "#": "t_dirt", + "~": "t_dirt", + "@": "t_dirt_underground", + ",": "t_dirt_underground", + "q": "t_dirt_underground", + "R": "t_dirt" }, "furniture": { "R": [ [ "f_boulder_small", 1 ], [ "f_null", 10 ] ] }, "item": { @@ -479,7 +479,7 @@ "............,...........", "............>..........." ], - "terrain": { ".": "t_rock", ",": "t_rock_floor", "W": "t_rock_floor", ">": "t_slope_up", "~": "t_water_dp" }, + "terrain": { ".": "t_soil", ",": "t_dirt", "W": "t_dirt", ">": "t_slope_up", "~": "t_water_dp" }, "furniture": { "W": "f_boulder_small" }, "item": { "W": { "item": "longsword", "chance": 100 } }, "monster": { @@ -497,7 +497,7 @@ "om_terrain": [ "cave_underground" ], "weight": 1000, "object": { - "fill_ter": "t_rock_floor", + "fill_ter": "t_dirt", "rotation": [ 0, 3 ], "rows": [ "........................", @@ -525,7 +525,7 @@ "............,...........", "............>..........." ], - "terrain": { ".": "t_rock", ",": "t_rock_floor", ">": "t_slope_up" }, + "terrain": { ".": "t_soil", ",": "t_dirt", ">": "t_slope_up" }, "furniture": { }, "items": { "~": [ { "item": "monparts", "chance": 2 }, { "item": "trash_forest", "chance": 2 } ] } } @@ -536,7 +536,7 @@ "om_terrain": [ "cave_underground" ], "weight": 800, "object": { - "fill_ter": "t_rock_floor", + "fill_ter": "t_dirt", "rotation": [ 0, 3 ], "rows": [ "........................", @@ -564,7 +564,7 @@ "............ ...........", "............>..........." ], - "terrain": { ".": "t_rock", " ": "t_rock_floor", ">": "t_slope_up" }, + "terrain": { ".": "t_soil", " ": "t_dirt", ">": "t_slope_up" }, "furniture": { }, "monster": { "M": { "monster": "mon_nakedmolerat_giant" }, " ": { "monster": "mon_nakedmolerat_giant", "chance": 2 } } } @@ -575,7 +575,7 @@ "om_terrain": [ "cave_underground" ], "weight": 500, "object": { - "fill_ter": "t_rock_floor", + "fill_ter": "t_dirt", "rotation": [ 0, 3 ], "rows": [ "........................", @@ -603,7 +603,7 @@ "...........,,,..........", "............>..........." ], - "terrain": { ".": "t_rock", ",": "t_rock_floor", "!": "t_rock_floor", ">": "t_slope_up" }, + "terrain": { ".": "t_soil", ",": "t_dirt", "!": "t_dirt", ">": "t_slope_up" }, "furniture": { "C": "f_crate_c", "S": "f_utility_shelf", "G": [ "f_grave_stone_old", "f_grave_head", "f_grave_monument" ] }, "item": { "!": { "item": "material_soil", "chance": 40, "amount": [ 5, 10 ] }, @@ -618,7 +618,7 @@ "om_terrain": [ "cave_underground" ], "weight": 250, "object": { - "fill_ter": "t_rock_floor", + "fill_ter": "t_dirt", "rotation": [ 0, 3 ], "rows": [ "........................", @@ -646,7 +646,7 @@ "............ ....F.7J G.", "............>..........." ], - "terrain": { ".": "t_rock", " ": "t_rock_floor", ">": "t_slope_up" }, + "terrain": { ".": "t_soil", " ": "t_dirt", ">": "t_slope_up" }, "furniture": { "f": "f_firering", "c": "f_camp_chair", @@ -688,7 +688,7 @@ "om_terrain": [ "cave_underground" ], "weight": 700, "object": { - "fill_ter": "t_rock_floor", + "fill_ter": "t_dirt", "rotation": [ 0, 3 ], "rows": [ "........................", @@ -716,7 +716,7 @@ "........... 2 ..........", "............>..........." ], - "terrain": { ".": "t_rock", " ": "t_rock_floor", ">": "t_slope_up", "2": "t_railroad_track_small" }, + "terrain": { ".": "t_soil", " ": "t_dirt", ">": "t_slope_up", "2": "t_railroad_track_small" }, "furniture": { }, "item": { "1": { "item": "broken_molebot", "chance": 2 } }, "items": { "1": { "item": "cave_minerals", "chance": 40, "repeat": [ 1, 3 ] } }, @@ -728,7 +728,7 @@ "method": "json", "om_terrain": [ "cave_rat_underground" ], "object": { - "fill_ter": "t_rock_floor", + "fill_ter": "t_dirt", "rotation": [ 0, 3 ], "rows": [ "1...........2...........", @@ -756,7 +756,7 @@ "...................... ", "...................... <" ], - "terrain": { ".": "t_rock", " ": "t_rock_floor", ">": "t_slope_up", "<": "t_slope_down" }, + "terrain": { ".": "t_soil", " ": "t_dirt", ">": "t_slope_up", "<": "t_slope_down" }, "furniture": { }, "nested": { "1": { "chunks": [ "cave_nw" ] }, @@ -771,7 +771,7 @@ "method": "json", "om_terrain": [ "cave_rat" ], "object": { - "fill_ter": "t_rock_floor", + "fill_ter": "t_dirt", "rotation": [ 0, 3 ], "rows": [ "........................", @@ -800,10 +800,10 @@ "........................" ], "terrain": { - " ": "t_rock_floor", - ".": "t_rock", - "|": [ [ "t_rock", 20 ], [ "t_rock_floor", 80 ] ], - "%": [ "t_rock", "t_rock_floor" ], + " ": "t_dirt", + ".": "t_soil", + "|": [ [ "t_soil", 20 ], [ "t_dirt", 80 ] ], + "%": [ "t_soil", "t_dirt" ], "<": "t_slope_up" }, "furniture": { }, diff --git a/data/json/mapgen/earth.json b/data/json/mapgen/earth.json new file mode 100644 index 0000000000000..df055df398fce --- /dev/null +++ b/data/json/mapgen/earth.json @@ -0,0 +1,37 @@ +[ + { + "method": "json", + "object": { + "rows": [ + "........................", + "........................", + "........................", + "........................", + "........................", + "........................", + "........................", + "........................", + "........................", + "........................", + "........................", + "........................", + "........................", + "........................", + "........................", + "........................", + "........................", + "........................", + "........................", + "........................", + "........................", + "........................", + "........................", + "........................" + ], + "terrain": { ".": "t_soil" } + }, + "om_terrain": "solid_earth", + "type": "mapgen", + "weight": 100 + } +] diff --git a/data/json/mapgen/isherwood_farms/farm_isherwood.json b/data/json/mapgen/isherwood_farms/farm_isherwood.json index 38b63d7da9e0e..30ac9d706880d 100644 --- a/data/json/mapgen/isherwood_farms/farm_isherwood.json +++ b/data/json/mapgen/isherwood_farms/farm_isherwood.json @@ -262,7 +262,7 @@ "om_terrain": "farm_isherwood_2_cellar", "object": { "faction_owner": [ { "id": "isherwood_family", "x": [ 0, 23 ], "y": [ 0, 23 ] } ], - "fill_ter": "t_rock_floor", + "fill_ter": "t_dirt", "rows": [ " ", " ", @@ -289,7 +289,7 @@ " ", " " ], - "terrain": { "<": "t_stairs_up", "#": "t_rock_wall", ".": "t_rock_floor", " ": "t_rock" }, + "terrain": { "<": "t_stairs_up", "#": "t_rock_wall", ".": "t_dirt", " ": "t_soil" }, "furniture": { "a": "f_rack", "r": "f_rack", diff --git a/data/json/mapgen/lab/lab_central.json b/data/json/mapgen/lab/lab_central.json index 7caf731dbfa81..7a5d1f77562da 100644 --- a/data/json/mapgen/lab/lab_central.json +++ b/data/json/mapgen/lab/lab_central.json @@ -63,7 +63,7 @@ "om_terrain": [ "central_lab_shaft" ], "weight": 100, "object": { - "fill_ter": "t_rock", + "fill_ter": "t_soil", "rows": [ " ", " ", diff --git a/data/json/mapgen/lab/lab_surface/lab_surface_big_z-1.json b/data/json/mapgen/lab/lab_surface/lab_surface_big_z-1.json index 1114307de4eaf..fd03649a1d0c2 100644 --- a/data/json/mapgen/lab/lab_surface/lab_surface_big_z-1.json +++ b/data/json/mapgen/lab/lab_surface/lab_surface_big_z-1.json @@ -165,7 +165,7 @@ ], "terrain": { "|": "t_strconc_wall", - "#": "t_rock", + "#": "t_soil", "<": "t_stairs_up", ">": "t_stairs_down", "@": "t_elevator_control_off", diff --git a/data/json/mapgen/lab_subway_vent_shaft.json b/data/json/mapgen/lab_subway_vent_shaft.json index 548e622f1546a..6592e9c8b78f3 100644 --- a/data/json/mapgen/lab_subway_vent_shaft.json +++ b/data/json/mapgen/lab_subway_vent_shaft.json @@ -17,6 +17,7 @@ ">": "t_ladder_down", "u": "t_chainfence", "U": "t_chainfence", + "0": "t_soil", "#": "t_rock" }, "furniture": { "%": "f_machinery_heavy" } @@ -100,30 +101,30 @@ "weight": 1000, "object": { "rows": [ - "########################", - "########################", - "########################", - "########################", - "########################", - "########################", - "########################", - "########################", - "########-------#########", - "########-``%``-#########", - "########-``w``-#########", - "########-``<``-#########", - "########-``w``-#########", - "########-`>w``-#########", - "########-------#########", - "########################", - "########################", - "########################", - "########################", - "########################", - "########################", - "########################", - "########################", - "########################" + "000000000000000000000000", + "000000000000000000000000", + "000000000000000000000000", + "000000000000000000000000", + "000000000000000000000000", + "000000000000000000000000", + "000000000000000000000000", + "000000000000000000000000", + "00000000-------000000000", + "00000000-``%``-000000000", + "00000000-``w``-000000000", + "00000000-``<``-000000000", + "00000000-``w``-000000000", + "00000000-`>w``-000000000", + "00000000-------000000000", + "000000000000000000000000", + "000000000000000000000000", + "000000000000000000000000", + "000000000000000000000000", + "000000000000000000000000", + "000000000000000000000000", + "000000000000000000000000", + "000000000000000000000000", + "000000000000000000000000" ], "palettes": [ "lab_subway_vent_shaft" ] } diff --git a/data/json/mapgen/lmoe.json b/data/json/mapgen/lmoe.json index 6eb5181a128ce..f90e7672acd5d 100644 --- a/data/json/mapgen/lmoe.json +++ b/data/json/mapgen/lmoe.json @@ -117,7 +117,7 @@ "//2": "This particular 4-bed shelter is definitely homemade, mostly carved out of bare rock, and seems to be incomplete.", "weight": 100, "object": { - "fill_ter": "t_rock_floor", + "fill_ter": "t_dirt", "rows": [ "########################", "########################", diff --git a/data/json/mapgen/mall/mall_basement.json b/data/json/mapgen/mall/mall_basement.json index 3894a522ec0e4..434fc0b7e5a46 100644 --- a/data/json/mapgen/mall/mall_basement.json +++ b/data/json/mapgen/mall/mall_basement.json @@ -47,7 +47,7 @@ "*": "t_linoleum_gray", ",": "t_linoleum_white", "6": "t_carpet_concrete_red", - ".": "t_rock", + ".": "t_soil", "{": "t_linoleum_gray", "Y": "t_linoleum_gray", "}": "t_linoleum_white", @@ -107,7 +107,7 @@ "#": "t_brick_wall", "*": "t_linoleum_gray", ",": "t_linoleum_white", - ".": "t_rock", + ".": "t_soil", "{": "t_linoleum_gray", "Y": "t_linoleum_gray", "}": "t_linoleum_white" diff --git a/data/json/mapgen/mansion.json b/data/json/mapgen/mansion.json index e04c172b7f8b9..f69d7dce5292b 100644 --- a/data/json/mapgen/mansion.json +++ b/data/json/mapgen/mansion.json @@ -34,7 +34,7 @@ "###++##############++###" ], "palettes": [ "standard_domestic_palette" ], - "terrain": { " ": "t_rock", ".": "t_thconc_floor", "]": "t_sewage_pipe", ")": "t_sewage_pump" }, + "terrain": { " ": "t_soil", ".": "t_thconc_floor", "]": "t_sewage_pipe", ")": "t_sewage_pump" }, "furniture": { "?": "f_generator_broken", "!": [ "f_crate_c", "f_cardboard_box" ] }, "items": { ".": { "item": "clutter_basement" }, @@ -171,7 +171,7 @@ ], "palettes": [ "standard_domestic_palette" ], "terrain": { - " ": "t_rock", + " ": "t_soil", ".": "t_thconc_floor", "0": "t_thconc_floor", "-": "t_carpet_concrete_red", @@ -324,7 +324,7 @@ " " ], "palettes": [ "standard_domestic_palette" ], - "terrain": { " ": "t_rock", ".": "t_thconc_floor" } + "terrain": { " ": "t_soil", ".": "t_thconc_floor" } } }, { @@ -453,7 +453,7 @@ ], "palettes": [ "standard_domestic_palette" ], "terrain": { - " ": "t_rock", + " ": "t_soil", ".": "t_thconc_floor", "]": "t_sewage_pipe", ")": "t_sewage_pump", @@ -707,7 +707,7 @@ ], "palettes": [ "standard_domestic_palette" ], "terrain": { - " ": "t_rock", + " ": "t_soil", ".": "t_thconc_floor", "]": "t_sewage_pipe", ")": "t_sewage_pump", @@ -814,7 +814,7 @@ ], "palettes": [ "standard_domestic_palette" ], "terrain": { - " ": "t_rock", + " ": "t_soil", ".": "t_thconc_floor", "]": "t_sewage_pipe", ")": "t_sewage_pump", @@ -962,7 +962,7 @@ ], "palettes": [ "standard_domestic_palette", "standard_domestic_lino_bathroom" ], "terrain": { - " ": "t_rock", + " ": "t_soil", ".": "t_thconc_floor", "]": "t_door_glass_c", "-": "t_carpet_concrete_purple", @@ -1133,7 +1133,7 @@ ], "palettes": [ "standard_domestic_palette", "standard_domestic_lino_bathroom" ], "terrain": { - " ": "t_rock", + " ": "t_soil", ".": "t_thconc_floor", "]": "t_sewage_pipe", ")": "t_sewage_pump", @@ -1325,7 +1325,7 @@ ], "palettes": [ "standard_domestic_palette", "standard_domestic_lino_bathroom" ], "terrain": { - " ": "t_rock", + " ": "t_soil", ".": "t_thconc_floor", "x": "t_carpet_concrete_yellow", "-": "t_carpet_concrete_yellow", @@ -1461,7 +1461,7 @@ "om_terrain": [ "mansion_+_dn", "mansion_+1d" ], "weight": 1000, "object": { - "fill_ter": "t_rock_floor", + "fill_ter": "t_dirt", "rows": [ "#......................#", "#......................#", @@ -1489,7 +1489,7 @@ "# #" ], "palettes": [ "standard_domestic_palette" ], - "terrain": { " ": "t_rock", ".": "t_thconc_floor" }, + "terrain": { " ": "t_soil", ".": "t_thconc_floor" }, "items": { ".": { "item": "clutter_basement" } } } }, @@ -1612,7 +1612,7 @@ ], "palettes": [ "standard_domestic_palette" ], "terrain": { - " ": "t_rock", + " ": "t_soil", ".": "t_thconc_floor", "]": "t_sewage_pipe", ")": "t_sewage_pump", @@ -1762,7 +1762,7 @@ "###########++###########" ], "palettes": [ "standard_domestic_palette" ], - "terrain": { " ": "t_rock", ".": "t_thconc_floor", "]": "t_sewage_pipe", ")": "t_sewage_pump" }, + "terrain": { " ": "t_soil", ".": "t_thconc_floor", "]": "t_sewage_pipe", ")": "t_sewage_pump" }, "furniture": { "&": "f_table", "=": "f_machinery_old", @@ -1920,7 +1920,7 @@ ], "palettes": [ "standard_domestic_palette", "standard_domestic_lino_bathroom" ], "terrain": { - " ": "t_rock", + " ": "t_soil", ".": "t_thconc_floor", "`": "t_linoleum_gray", "-": "t_carpet_concrete_yellow", @@ -2103,7 +2103,7 @@ " ##########++#####" ], "palettes": [ "standard_domestic_palette" ], - "terrain": { " ": "t_rock", ".": "t_thconc_floor", "]": "t_sewage_pipe", ")": "t_sewage_pump" }, + "terrain": { " ": "t_soil", ".": "t_thconc_floor", "]": "t_sewage_pipe", ")": "t_sewage_pump" }, "furniture": { "=": "f_machinery_old", "!": [ "f_crate_c", "f_cardboard_box" ] }, "items": { ".": { "item": "clutter_basement" }, @@ -2252,7 +2252,7 @@ " ##########++#####" ], "palettes": [ "standard_domestic_palette" ], - "terrain": { " ": "t_rock", ".": "t_thconc_floor", "]": "t_sewage_pipe", ")": "t_sewage_pump" }, + "terrain": { " ": "t_soil", ".": "t_thconc_floor", "]": "t_sewage_pipe", ")": "t_sewage_pump" }, "furniture": { "=": "f_machinery_old", "&": "f_table", "?": "f_generator_broken", "!": [ "f_crate_c", "f_cardboard_box" ] }, "items": { ".": { "item": "clutter_basement" }, "!": { "item": "crate_stack", "chance": 100 } }, "place_monsters": [ { "monster": "GROUP_MANSION", "x": [ 8, 21 ], "y": [ 8, 21 ], "density": 0.1 } ] @@ -2409,7 +2409,7 @@ " ##########++#####" ], "palettes": [ "standard_domestic_palette" ], - "terrain": { " ": "t_rock", ".": "t_thconc_floor" }, + "terrain": { " ": "t_soil", ".": "t_thconc_floor" }, "furniture": { "=": "f_table", "!": [ "f_crate_c", "f_cardboard_box" ] }, "items": { ".": { "item": "clutter_basement" }, @@ -2568,7 +2568,7 @@ ], "palettes": [ "standard_domestic_palette", "standard_domestic_lino_bathroom" ], "terrain": { - " ": "t_rock", + " ": "t_soil", ".": "t_thconc_floor", "]": "t_sewage_pipe", ")": "t_sewage_pump", @@ -2728,7 +2728,7 @@ " ###########++#####" ], "palettes": [ "standard_domestic_palette" ], - "terrain": { " ": "t_rock", ".": "t_thconc_floor", "]": "t_sewage_pipe", ")": "t_sewage_pump", "/": "t_door_locked_interior" }, + "terrain": { " ": "t_soil", ".": "t_thconc_floor", "]": "t_sewage_pipe", ")": "t_sewage_pump", "/": "t_door_locked_interior" }, "furniture": { "%": "f_rack_wood", "!": "f_wood_keg", diff --git a/data/json/mapgen/mine/mine_shaft.json b/data/json/mapgen/mine/mine_shaft.json index 8fee0022eb3de..d242ed7b520e8 100644 --- a/data/json/mapgen/mine/mine_shaft.json +++ b/data/json/mapgen/mine/mine_shaft.json @@ -4,7 +4,7 @@ "method": "json", "om_terrain": "mine_shaft_middle", "object": { - "fill_ter": "t_rock", + "fill_ter": "t_soil", "rows": [ " <#", " #", diff --git a/data/json/mapgen/missile_silo.json b/data/json/mapgen/missile_silo.json index 864376dcf1e16..4512d7e9b02de 100644 --- a/data/json/mapgen/missile_silo.json +++ b/data/json/mapgen/missile_silo.json @@ -72,32 +72,33 @@ "fill_ter": "t_floor", "rows": [ " ", - " ", - " ......W tc...W ", - " .cTTc..X tc...s & 6", - " .cTTc..+... e....s r..", - " .cTTc.. . f...ba S.a", - " ....... . +X = ", - " CCCrxxa ............ ", - " a. 1 . ", - " ~~~~~~~~~ . . ", - " ~~|-----|~~ . . ", - " ~~|-`````-|~~ . . ", - " ~|-`*****`-|~ . X+ ", - " ~|`*******`|~ . B...a", - " ~|`*******`|~ . l...W", - " ~|`*******`|~?. B...l", - " ~|`*******`|~ . l...B", - " ~|`*******`|~ . B...l", - " ~|-`*****`-|~ . l...B", - " ~~|-`````-|~~ . ", - " ~~|-----|~~ . < ^ ", - " ~~~~~~~~~ ....?..$ ", - " > $ ", - " " + "@@@@@@@@@ @@@@@@@@ ", + "@......W@@ @tc...W@@@@@", + "@.cTTc..X@@@@tc...s@& 6@", + "@.cTTc..+...@e....s@r..@", + "@.cTTc..@@@.@f...ba@S.a@", + "@.......@ @.@@@+X@@@@=@@", + "@CCCrxxa@ @............@", + "@@@@@@@@@@@@@@a.@@1@@.@@", + " @@~~~~~~~~~@@@.@@@@@.@ ", + "@@~~|-----|~~@@.@ @.@ ", + "@~~|-`````-|~~@.@ @@.@ ", + "@~|-`*****`-|~@.@@@@X+@@", + "@~|`*******`|~@.@@B...a@", + "@~|`*******`|~@.@@l...W@", + "@~|`*******`|~?.@@B...l@", + "@~|`*******`|~@.@@l...B@", + "@~|`*******`|~@.@@B...l@", + "@~|-`*****`-|~@.@@l...B@", + "@~~|-`````-|~~@.@@@@@@@@", + "@@~~|-----|~~@@.@@@@<@^@", + " @@~~~~~~~~~@@@....?..$@", + " @@@@@@@@@@@ @@@@@@>@$@", + " @@@@@" ], "terrain": { - " ": "t_rock", + " ": "t_soil", + "@": "t_wall_metal", "*": "t_missile", "`": "t_hole", "|": "t_metal_railing", diff --git a/data/json/mapgen/necropolis/necropolisB1.json b/data/json/mapgen/necropolis/necropolisB1.json index 4a92701c41273..746856705358f 100644 --- a/data/json/mapgen/necropolis/necropolisB1.json +++ b/data/json/mapgen/necropolis/necropolisB1.json @@ -241,7 +241,7 @@ ".....................2x33..............................................." ], "palettes": [ "necropolis_b1" ], - "terrain": { "@": "t_rock_floor", "r": "t_rock_floor", "L": "t_rock_floor", "c": "t_rock_floor" }, + "terrain": { "@": "t_dirt", "r": "t_dirt", "L": "t_dirt", "c": "t_dirt" }, "place_monsters": [ { "monster": "GROUP_NECROPOLIS_SEWERS", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.05 }, { "monster": "GROUP_NECROPOLIS_SEWERS", "x": [ 25, 46 ], "y": [ 1, 22 ], "density": 0.05 }, @@ -322,8 +322,8 @@ "c": "t_metal_floor", "r": "t_metal_floor", "6": "t_metal_floor", - "z": "t_rock_floor", - "L": "t_rock_floor" + "z": "t_dirt", + "L": "t_dirt" }, "place_items": [ { "item": "vault_survival", "x": [ 21, 21 ], "y": [ 20, 23 ], "chance": 85 }, @@ -406,7 +406,7 @@ "33 .....233x......... ........ 3333X3333333333333333333 ........." ], "palettes": [ "necropolis_b1" ], - "terrain": { "n": "t_rock_floor", "h": "t_rock_floor", "@": "t_rock_floor", "o": "t_rock_floor" }, + "terrain": { "n": "t_dirt", "h": "t_dirt", "@": "t_dirt", "o": "t_dirt" }, "place_monsters": [ { "monster": "GROUP_NECROPOLIS_SEWERS", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.05 }, { "monster": "GROUP_NECROPOLIS_SEWERS", "x": [ 25, 46 ], "y": [ 1, 22 ], "density": 0.05 }, @@ -479,7 +479,7 @@ "................{......................................................." ], "palettes": [ "necropolis_b1" ], - "terrain": { "r": "t_rock_floor" }, + "terrain": { "r": "t_dirt" }, "place_monsters": [ { "monster": "GROUP_NECROPOLIS_SEWERS", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.05 }, { "monster": "GROUP_NECROPOLIS_SEWERS", "x": [ 25, 46 ], "y": [ 1, 22 ], "density": 0.05 }, @@ -555,7 +555,7 @@ "...............33....... ........33x..............................33..." ], "palettes": [ "necropolis_b1" ], - "terrain": { "z": "t_rock_floor" }, + "terrain": { "z": "t_dirt" }, "place_items": [ { "item": "cannedfood", "x": [ 6, 7 ], "y": [ 15, 16 ], "chance": 90 }, { "item": "cannedfood", "x": [ 7, 8 ], "y": [ 18, 19 ], "chance": 90 } @@ -704,14 +704,14 @@ ], "palettes": [ "necropolis_b1" ], "terrain": { - "d": "t_rock_floor", - "A": "t_rock_floor", - "z": "t_rock_floor", - "h": "t_rock_floor", - "n": "t_rock_floor", - "?": "t_rock_floor", - "f": "t_rock_floor", - "@": "t_rock_floor" + "d": "t_dirt", + "A": "t_dirt", + "z": "t_dirt", + "h": "t_dirt", + "n": "t_dirt", + "?": "t_dirt", + "f": "t_dirt", + "@": "t_dirt" }, "place_monsters": [ { "monster": "GROUP_NECROPOLIS_SEWERS", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.05 }, @@ -784,7 +784,7 @@ "................................3..............................33......." ], "palettes": [ "necropolis_b1" ], - "terrain": { "r": "t_rock_floor" }, + "terrain": { "r": "t_dirt" }, "place_monsters": [ { "monster": "GROUP_NECROPOLIS_SEWERS", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.05 }, { "monster": "GROUP_NECROPOLIS_SEWERS", "x": [ 25, 46 ], "y": [ 1, 22 ], "density": 0.05 }, diff --git a/data/json/mapgen/pawn_shop.json b/data/json/mapgen/pawn_shop.json index d2b486fc7478c..9fff2d4ed4bde 100644 --- a/data/json/mapgen/pawn_shop.json +++ b/data/json/mapgen/pawn_shop.json @@ -398,7 +398,7 @@ "........................" ], "terrain": { - ".": "t_rock", + ".": "t_soil", " ": "t_floor", "b": "t_floor", "c": "t_floor", diff --git a/data/json/mapgen/prison_1.json b/data/json/mapgen/prison_1.json index a817df4088914..c72fc6c417d35 100644 --- a/data/json/mapgen/prison_1.json +++ b/data/json/mapgen/prison_1.json @@ -1442,8 +1442,8 @@ ], "palettes": [ "prison_palette" ], "terrain": { - " ": [ "t_rock" ], - "^": [ "t_rock_floor" ], + " ": [ "t_soil" ], + "^": [ "t_thconc_floor" ], "_": [ "t_grate" ], "~": [ "t_sewage" ], "'": [ "t_water_sh_murky_underground" ], diff --git a/data/json/mapgen/railroad/railroad_station.json b/data/json/mapgen/railroad/railroad_station.json index dc6aeda1987d4..c39aa02e06e96 100644 --- a/data/json/mapgen/railroad/railroad_station.json +++ b/data/json/mapgen/railroad/railroad_station.json @@ -142,7 +142,7 @@ ], "weight": 100, "object": { - "fill_ter": "t_rock", + "fill_ter": "t_soil", "rows": [ " ", " ", diff --git a/data/json/mapgen/refugee_center/rc_grounds_e.json b/data/json/mapgen/refugee_center/rc_grounds_e.json index 37d213cee93d7..ebf3d21732b75 100644 --- a/data/json/mapgen/refugee_center/rc_grounds_e.json +++ b/data/json/mapgen/refugee_center/rc_grounds_e.json @@ -216,7 +216,7 @@ [ "refctr_E1e_z-1", "refctr_E2e_z-1", "refctr_E3e_z-1", "refctr_E4e_z-1", "refctr_E5e_z-1" ] ], "weight": 100, - "object": { "fill_ter": "t_rock" } + "object": { "fill_ter": "t_soil" } }, { "type": "mapgen", diff --git a/data/json/mapgen/refugee_center/rc_grounds_n.json b/data/json/mapgen/refugee_center/rc_grounds_n.json index 3b3c840969095..c7d00616d5465 100644 --- a/data/json/mapgen/refugee_center/rc_grounds_n.json +++ b/data/json/mapgen/refugee_center/rc_grounds_n.json @@ -216,7 +216,7 @@ [ "refctr_N1e_z-1", "refctr_N2e_z-1", "refctr_N3e_z-1", "refctr_N4e_z-1", "refctr_N5e_z-1" ] ], "weight": 100, - "object": { "fill_ter": "t_rock" } + "object": { "fill_ter": "t_soil" } }, { "type": "mapgen", diff --git a/data/json/mapgen/refugee_center/rc_grounds_ne.json b/data/json/mapgen/refugee_center/rc_grounds_ne.json index 206600739fef9..a11813118e7f2 100644 --- a/data/json/mapgen/refugee_center/rc_grounds_ne.json +++ b/data/json/mapgen/refugee_center/rc_grounds_ne.json @@ -216,7 +216,7 @@ [ "refctr_NE1e_z-1", "refctr_NE2e_z-1", "refctr_NE3e_z-1", "refctr_NE4e_z-1", "refctr_NE5e_z-1" ] ], "weight": 100, - "object": { "fill_ter": "t_rock" } + "object": { "fill_ter": "t_soil" } }, { "type": "mapgen", diff --git a/data/json/mapgen/refugee_center/rc_grounds_nw.json b/data/json/mapgen/refugee_center/rc_grounds_nw.json index f2f1cd4c1003d..2cb4f21d628ef 100644 --- a/data/json/mapgen/refugee_center/rc_grounds_nw.json +++ b/data/json/mapgen/refugee_center/rc_grounds_nw.json @@ -216,7 +216,7 @@ [ "refctr_NW1e_z-1", "refctr_NW2e_z-1", "refctr_NW3e_z-1", "refctr_NW4e_z-1", "refctr_NW5e_z-1" ] ], "weight": 100, - "object": { "fill_ter": "t_rock" } + "object": { "fill_ter": "t_soil" } }, { "type": "mapgen", @@ -229,7 +229,7 @@ [ "refctr_NW1e_z-2", "refctr_NW2e_z-2", "refctr_NW3e_z-2", "refctr_NW4e_z-2", "refctr_NW5e_z-2" ] ], "weight": 100, - "object": { "fill_ter": "t_rock" } + "object": { "fill_ter": "t_soil" } }, { "type": "mapgen", @@ -242,7 +242,7 @@ [ "refctr_NW1e_z-3", "refctr_NW2e_z-3", "refctr_NW3e_z-3", "refctr_NW4e_z-3", "refctr_NW5e_z-3" ] ], "weight": 100, - "object": { "fill_ter": "t_rock" } + "object": { "fill_ter": "t_soil" } }, { "type": "mapgen", @@ -255,6 +255,6 @@ [ "refctr_NW1e_z-4", "refctr_NW2e_z-4", "refctr_NW3e_z-4", "refctr_NW4e_z-4", "refctr_NW5e_z-4" ] ], "weight": 100, - "object": { "fill_ter": "t_rock" } + "object": { "fill_ter": "t_soil" } } ] diff --git a/data/json/mapgen/refugee_center/rc_grounds_s.json b/data/json/mapgen/refugee_center/rc_grounds_s.json index 3383fd936d8f3..7b37fee336659 100644 --- a/data/json/mapgen/refugee_center/rc_grounds_s.json +++ b/data/json/mapgen/refugee_center/rc_grounds_s.json @@ -216,7 +216,7 @@ [ "refctr_S1e_z-1", "refctr_S2e_z-1", "refctr_S3e_z-1", "refctr_S4e_z-1", "refctr_S5e_z-1" ] ], "weight": 100, - "object": { "fill_ter": "t_rock" } + "object": { "fill_ter": "t_soil" } }, { "type": "mapgen", diff --git a/data/json/mapgen/refugee_center/rc_grounds_se.json b/data/json/mapgen/refugee_center/rc_grounds_se.json index b95f136ff8c22..0cfcb537367e4 100644 --- a/data/json/mapgen/refugee_center/rc_grounds_se.json +++ b/data/json/mapgen/refugee_center/rc_grounds_se.json @@ -216,7 +216,7 @@ [ "refctr_SE1e_z-1", "refctr_SE2e_z-1", "refctr_SE3e_z-1", "refctr_SE4e_z-1", "refctr_SE5e_z-1" ] ], "weight": 100, - "object": { "fill_ter": "t_rock" } + "object": { "fill_ter": "t_soil" } }, { "type": "mapgen", diff --git a/data/json/mapgen/refugee_center/rc_grounds_sw.json b/data/json/mapgen/refugee_center/rc_grounds_sw.json index 6dcadb1fceb22..dffcb405ff2af 100644 --- a/data/json/mapgen/refugee_center/rc_grounds_sw.json +++ b/data/json/mapgen/refugee_center/rc_grounds_sw.json @@ -216,7 +216,7 @@ [ "refctr_SW1e_z-1", "refctr_SW2e_z-1", "refctr_SW3e_z-1", "refctr_SW4e_z-1", "refctr_SW5e_z-1" ] ], "weight": 100, - "object": { "fill_ter": "t_rock" } + "object": { "fill_ter": "t_soil" } }, { "type": "mapgen", diff --git a/data/json/mapgen/refugee_center/rc_grounds_w.json b/data/json/mapgen/refugee_center/rc_grounds_w.json index c51c9c9b1ae40..ac7c4bd8b30e8 100644 --- a/data/json/mapgen/refugee_center/rc_grounds_w.json +++ b/data/json/mapgen/refugee_center/rc_grounds_w.json @@ -216,7 +216,7 @@ [ "refctr_W1e_z-1", "refctr_W2e_z-1", "refctr_W3e_z-1", "refctr_W4e_z-1", "refctr_W5e_z-1" ] ], "weight": 100, - "object": { "fill_ter": "t_rock" } + "object": { "fill_ter": "t_soil" } }, { "type": "mapgen", diff --git a/data/json/mapgen/refugee_center/z-1_refugee_center.json b/data/json/mapgen/refugee_center/z-1_refugee_center.json index 4f579205def81..8dbf1b0ff53ee 100644 --- a/data/json/mapgen/refugee_center/z-1_refugee_center.json +++ b/data/json/mapgen/refugee_center/z-1_refugee_center.json @@ -10,6 +10,6 @@ [ "evac_center_21_z-1", "evac_center_22_z-1", "evac_center_23_z-1", "evac_center_24_z-1", "evac_center_25_z-1" ] ], "weight": 100, - "object": { "fill_ter": "t_rock" } + "object": { "fill_ter": "t_soil" } } ] diff --git a/data/json/mapgen/river_shipwreck.json b/data/json/mapgen/river_shipwreck.json index 2d455053ffeb2..31dc0e464b2b8 100644 --- a/data/json/mapgen/river_shipwreck.json +++ b/data/json/mapgen/river_shipwreck.json @@ -130,7 +130,7 @@ " ": "t_metal_floor", "+": "t_door_metal_c", "-": "t_wall_metal", - ".": "t_rock", + ".": "t_soil", "C": "t_dirtmound", "~": "t_water_sh" }, @@ -182,7 +182,7 @@ " ": "t_metal_floor", "+": "t_door_metal_c", "-": "t_wall_metal", - ".": "t_rock", + ".": "t_soil", "<": "t_stairs_up", "C": "t_dirtmound", "~": "t_water_sh" diff --git a/data/json/mapgen/sewage_treatment.json b/data/json/mapgen/sewage_treatment.json index a2005d3540720..5fa8348caaaa7 100644 --- a/data/json/mapgen/sewage_treatment.json +++ b/data/json/mapgen/sewage_treatment.json @@ -72,12 +72,12 @@ "h": "t_thconc_floor", "D": "t_thconc_floor", "1": "t_thconc_floor", - "=": "t_rock_floor", + "=": "t_dirt", ">": "t_stairs_up", "!": "t_bars", "~": "t_sewage", "`": "t_sewage", - "%": "t_rock", + "%": "t_soil", ".": "t_thconc_floor", "^": "t_ladder_up", "*": "t_door_bar_locked", @@ -354,7 +354,7 @@ ], "weight": 250, "object": { - "fill_ter": "t_rock_floor", + "fill_ter": "t_dirt", "rows": [ "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%~~~~%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%", "%%%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%%%%", @@ -471,7 +471,7 @@ "//": "10% chance of a hidden CHUD lair", "weight": 25, "object": { - "fill_ter": "t_rock_floor", + "fill_ter": "t_dirt", "rows": [ "%%%%%~#2%%%%%%%%HHHHHHHH", "%%%%%~#2%%%HHHHHHww.....", @@ -520,7 +520,7 @@ "//": "Easter egg - TMNT reference", "weight": 1, "object": { - "fill_ter": "t_rock_floor", + "fill_ter": "t_dirt", "rows": [ "%%%%%~#2%%%%%%%%HHHHHHHH", "%%%%%~#2%%%HHHHHHww.....", diff --git a/data/json/mapgen/slime_pit.json b/data/json/mapgen/slime_pit.json new file mode 100644 index 0000000000000..bd79c83f02e59 --- /dev/null +++ b/data/json/mapgen/slime_pit.json @@ -0,0 +1,83 @@ +[ + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "slimepit_bottom" ], + "weight": 100, + "object": { + "fill_ter": "t_dirt", + "rows": [ + "########################", + "########################", + "######222222############", + "#####2#1111#2###########", + "####221 12222########", + "####2#1 111#22#######", + "###221 12########", + "###211 122#######", + "##221 1122######", + "##211 > 112######", + "##21 #2#####", + "##21 122####", + "##21 11222##", + "##21 1112##", + "##21 122##", + "##211 12###", + "##221 11#2###", + "###211 11122####", + "##22#11 11111222#####", + "####221111 #22222#######", + "#####22#2#112#22########", + "#########2222###########", + "########################", + "########################" + ], + "terrain": { + "#": "t_soil", + " ": [ "t_dirt", "t_slime" ], + ">": "t_slope_down", + "1": "t_earth_ramp_up_low", + "2": "t_earth_ramp_up_high" + }, + "furniture": { " ": "f_null" }, + "place_monsters": [ { "monster": "GROUP_SLIME", "x": [ 2, 7 ], "y": [ 10, 17 ], "chance": 2, "repeat": 12 } ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "slimepit_top" ], + "weight": 100, + "object": { + "fill_ter": "t_open_air", + "rows": [ + "########################", + "########################", + "######222222############", + "#####2#1111#2###########", + "####221 12222########", + "####2#1 111#22#######", + "###221 12########", + "###211 122#######", + "##221 1122######", + "##211 112######", + "##21 #2#####", + "##21 122####", + "##21 11222##", + "##21 1112##", + "##21 122##", + "##211 12###", + "##221 11#2###", + "###211 11122####", + "##22#11 11111222#####", + "####221111 #22222#######", + "#####22#2#112#22########", + "#########2222###########", + "########################", + "########################" + ], + "terrain": { "#": "t_region_groundcover", " ": "t_open_air", "1": "t_earth_ramp_down_low", "2": "t_earth_ramp_down_high" }, + "furniture": { " ": "f_null" } + } + } +] diff --git a/data/json/mapgen/sub_station.json b/data/json/mapgen/sub_station.json index a3f5f893b94d2..7a1c2ae116854 100644 --- a/data/json/mapgen/sub_station.json +++ b/data/json/mapgen/sub_station.json @@ -118,9 +118,9 @@ "object": { "fill_ter": "t_thconc_floor", "rows": [ - "#^^^X^^^X^^^^^^X^^^X^^^#", - "#^^-x---x-^^^^-x---x-^^#", - "#^^^X^^^X^IIII^X^^^X^^^#", + "0^^^X^^^X^^^^^^X^^^X^^^0", + "0^^-x---x-^^^^-x---x-^^0", + "0^^^X^^^X^IIII^X^^^X^^^0", "R^^^X^^^X^<<<<^X^^^X^^^R", "R^^-x---x-____-x---x-^^R", "G^^^X^^^X^____^X^^^X^^^G", @@ -139,9 +139,9 @@ "G^^^X^^^X^_MM_^X^^^X^^^G", "R^^-x---x-____-x---x-^^R", "R^^^X^^^X^____^X^^^X^^^R", - "#^^^X^^^X^____^X^^^X^^^#", - "#^^-x---x-IIII-x---x-^^#", - "#^^^X^^^X^^^^^^X^^^X^^^#" + "0^^^X^^^X^____^X^^^X^^^0", + "0^^-x---x-IIII-x---x-^^0", + "0^^^X^^^X^^^^^^X^^^X^^^0" ], "palettes": [ "subway_underground" ] } diff --git a/data/json/mapgen/ws_survivor_bunker.json b/data/json/mapgen/ws_survivor_bunker.json index 184c22ae3a002..3155fcdfe2b11 100644 --- a/data/json/mapgen/ws_survivor_bunker.json +++ b/data/json/mapgen/ws_survivor_bunker.json @@ -194,25 +194,25 @@ "######R#########R#######" ], "terrain": { - "#": "t_rock", + "#": "t_soil", "<": "t_ladder_up", "-": "t_wall_wood", "|": "t_wall_wood", - ".": "t_rock_floor", + ".": "t_dirt", "D": "t_door_locked_interior", "R": "t_root_wall", - "S": "t_rock_floor", - "s": "t_rock_floor", - "r": "t_rock_floor", - "1": "t_rock_floor", - "2": "t_rock_floor", - "k": "t_rock_floor", - "b": "t_rock_floor", - "t": "t_rock_floor", - "C": "t_rock_floor", - "B": "t_rock_floor", - "W": "t_rock_floor", - "h": "t_rock_floor" + "S": "t_dirt", + "s": "t_dirt", + "r": "t_dirt", + "1": "t_dirt", + "2": "t_dirt", + "k": "t_dirt", + "b": "t_dirt", + "t": "t_dirt", + "C": "t_dirt", + "B": "t_dirt", + "W": "t_dirt", + "h": "t_dirt" }, "furniture": { "r": "f_rubble_rock", diff --git a/data/json/mapgen_palettes/airliner_palette.json b/data/json/mapgen_palettes/airliner_palette.json index c9b9428afdd08..acb5e6fe590d9 100644 --- a/data/json/mapgen_palettes/airliner_palette.json +++ b/data/json/mapgen_palettes/airliner_palette.json @@ -5,7 +5,7 @@ "terrain": { " ": "t_region_groundcover_urban", "A": "t_open_air", - ",": "t_rock", + ",": "t_soil", "d": "t_dirtmound", "M": "t_wall_metal", "m": "t_scrap_wall_halfway", diff --git a/data/json/mapgen_palettes/basement.json b/data/json/mapgen_palettes/basement.json index 50cf5b977b3d7..1df5f9878553c 100644 --- a/data/json/mapgen_palettes/basement.json +++ b/data/json/mapgen_palettes/basement.json @@ -60,35 +60,35 @@ "type": "palette", "id": "basement_game", "terrain": { - " ": "t_rock", + " ": "t_soil", "+": "t_door_c", "-": "t_wall_w", - ".": "t_rock_floor", + ".": "t_thconc_floor", "<": "t_wood_stairs_up", - "&": "t_rock_floor", - "*": "t_rock_floor", - "%": "t_rock_floor", - "}": "t_rock_floor", - "@": "t_rock_floor", - "!": "t_rock_floor", - "^": "t_rock_floor", - "{": "t_rock_floor", - "_": "t_rock_floor", - "?": "t_rock_floor", - "/": "t_rock_floor", - "a": "t_rock_floor", - "b": "t_rock_floor", - "c": "t_rock_floor", - "d": "t_rock_floor", - "f": "t_rock_floor", - "i": "t_rock_floor", - "p": "t_rock_floor", - "r": "t_rock_floor", - "s": "t_rock_floor", - "t": "t_rock_floor", - "w": "t_rock_floor", - "C": "t_rock_floor", - "L": "t_rock_floor", + "&": "t_thconc_floor", + "*": "t_thconc_floor", + "%": "t_thconc_floor", + "}": "t_thconc_floor", + "@": "t_thconc_floor", + "!": "t_thconc_floor", + "^": "t_thconc_floor", + "{": "t_thconc_floor", + "_": "t_thconc_floor", + "?": "t_thconc_floor", + "/": "t_thconc_floor", + "a": "t_thconc_floor", + "b": "t_thconc_floor", + "c": "t_thconc_floor", + "d": "t_thconc_floor", + "f": "t_thconc_floor", + "i": "t_thconc_floor", + "p": "t_thconc_floor", + "r": "t_thconc_floor", + "s": "t_thconc_floor", + "t": "t_thconc_floor", + "w": "t_thconc_floor", + "C": "t_thconc_floor", + "L": "t_thconc_floor", ",": "t_floor", "T": "t_floor", "A": "t_floor", @@ -131,7 +131,7 @@ "type": "palette", "id": "basement_bunker", "terrain": { - "#": "t_rock", + "#": "t_soil", "+": "t_door_metal_locked", "*": "t_door_c", "^": "t_door_locked_interior", @@ -149,7 +149,7 @@ "type": "palette", "id": "basement_empty", "terrain": { - " ": "t_rock", + " ": "t_soil", "+": "t_door_c", ".": "t_thconc_floor", "|": "t_concrete_wall", diff --git a/data/json/mapgen_palettes/collapsed_tower.json b/data/json/mapgen_palettes/collapsed_tower.json index a31f5b11e171a..fb299354f7c01 100644 --- a/data/json/mapgen_palettes/collapsed_tower.json +++ b/data/json/mapgen_palettes/collapsed_tower.json @@ -3,7 +3,7 @@ "type": "palette", "id": "collapsed_tower", "terrain": { - "#": "t_rock", + "#": "t_soil", "+": "t_door_c", "-": "t_wall", ".": "t_region_groundcover_urban", diff --git a/data/json/mapgen_palettes/hotel_tower_palette.json b/data/json/mapgen_palettes/hotel_tower_palette.json index 2a55e64166211..53130129ca2c3 100644 --- a/data/json/mapgen_palettes/hotel_tower_palette.json +++ b/data/json/mapgen_palettes/hotel_tower_palette.json @@ -55,7 +55,7 @@ "~": "t_thconc_floor", "<": "t_stairs_up", ">": "t_stairs_down", - "#": "t_rock", + "#": "t_soil", "$": "t_sewage_pipe", "4": "t_gutter_downspout", "P": "t_sewage_pump" diff --git a/data/json/mapgen_palettes/house_general_palette.json b/data/json/mapgen_palettes/house_general_palette.json index cc74d9a46ebf3..8535dc5133150 100644 --- a/data/json/mapgen_palettes/house_general_palette.json +++ b/data/json/mapgen_palettes/house_general_palette.json @@ -214,7 +214,7 @@ "id": "standard_domestic_basement_palette", "//": "Intended to be used in conjunction with standard_domestic_palette. Load the domestic palette first, then this one to overwrite certain common symbols with ones more appropriate for basements. Symbols still open for use: ! $ % & _ = ~ - ? / , and more", "terrain": { - "^": "t_rock", + "^": "t_soil", "#": "t_concrete_wall", ".": "t_thconc_floor", "c": "t_thconc_floor", diff --git a/data/json/mapgen_palettes/lmoe.json b/data/json/mapgen_palettes/lmoe.json index 6a48164868480..189bc41a14f69 100644 --- a/data/json/mapgen_palettes/lmoe.json +++ b/data/json/mapgen_palettes/lmoe.json @@ -3,7 +3,7 @@ "type": "palette", "id": "bunker", "terrain": { - "#": "t_rock", + "#": "t_soil", "*": "t_chaingate_c", "+": "t_door_metal_c", "-": "t_scrap_wall", @@ -91,7 +91,7 @@ "terrain": { " ": [ [ "t_region_groundcover", 60 ], [ "t_region_shrub", 2 ], "t_region_tree" ], "_": [ "t_region_groundcover", [ "t_region_groundcover_barren", 9 ] ], - "#": "t_rock", + "#": "t_soil", "$": [ "t_region_tree_fruit", "t_region_tree_nut", "t_region_shrub_fruit", "t_region_shrub" ], "S": [ [ "t_region_groundcover", 5 ], @@ -103,7 +103,7 @@ ], "v": "t_open_air", "+": "t_door_metal_c", - ".": "t_rock_floor", + ".": "t_dirt", ">": "t_stairs_down", ")": "t_slope_up", "(": "t_slope_down", diff --git a/data/json/mapgen_palettes/mall_palette.json b/data/json/mapgen_palettes/mall_palette.json index fe628abd119b6..26c6e462b9794 100644 --- a/data/json/mapgen_palettes/mall_palette.json +++ b/data/json/mapgen_palettes/mall_palette.json @@ -111,7 +111,7 @@ "1": "t_door_metal_locked", "=": [ "t_door_c", "t_door_locked" ], "|": "t_concrete_wall", - " ": "t_rock", + " ": "t_soil", "3": "t_gates_control_brick", "E": "t_elevator", "<": "t_stairs_up", diff --git a/data/json/mapgen_palettes/necropolis/necropolis_b1.json b/data/json/mapgen_palettes/necropolis/necropolis_b1.json index e26983d1de3fc..fb92e373838bb 100644 --- a/data/json/mapgen_palettes/necropolis/necropolis_b1.json +++ b/data/json/mapgen_palettes/necropolis/necropolis_b1.json @@ -25,7 +25,7 @@ "{": "f_rubble" }, "terrain": { - " ": "t_rock_floor", + " ": "t_dirt", "!": "t_bars", "#": "t_ladder_up", ")": "t_floor", @@ -33,7 +33,7 @@ "+": "t_door_metal_c", ",": "t_pavement_y", "-": "t_wall", - ".": "t_rock", + ".": "t_soil", "2": "t_sewage_pipe", "3": "t_sewage", "4": "t_water_pump", diff --git a/data/json/mapgen_palettes/office.json b/data/json/mapgen_palettes/office.json index cde7b097ebdfc..295993de255bc 100644 --- a/data/json/mapgen_palettes/office.json +++ b/data/json/mapgen_palettes/office.json @@ -5,7 +5,7 @@ "terrain": { "*": "t_null", "/": "t_open_air", - "~": "t_rock", + "~": "t_soil", "#": "t_concrete_wall", ">": "t_stairs_down", "<": "t_stairs_up", diff --git a/data/json/mapgen_palettes/prison.json b/data/json/mapgen_palettes/prison.json index 447d1bdd88b1b..48f6b55e18d63 100644 --- a/data/json/mapgen_palettes/prison.json +++ b/data/json/mapgen_palettes/prison.json @@ -4,7 +4,7 @@ "id": "prison_palette", "terrain": { " ": [ "t_region_groundcover_urban", "t_region_groundcover_barren" ], - "#": "t_rock", + "#": "t_soil", "%": "t_fence_barbed", "+": "t_door_locked_interior", ",": "t_floor", diff --git a/data/json/mapgen_palettes/railroad.json b/data/json/mapgen_palettes/railroad.json index d8325b40b02e0..4ec915b597f78 100644 --- a/data/json/mapgen_palettes/railroad.json +++ b/data/json/mapgen_palettes/railroad.json @@ -90,6 +90,6 @@ { "type": "palette", "id": "railroad_station_under", - "terrain": { " ": "t_rock", ">": "t_stairs_down", "<": "t_stairs_up", "#": "t_concrete_wall", "_": "t_concrete", "I": "t_column" } + "terrain": { " ": "t_soil", ">": "t_stairs_down", "<": "t_stairs_up", "#": "t_concrete_wall", "_": "t_concrete", "I": "t_column" } } ] diff --git a/data/json/mapgen_palettes/sewers_palette.json b/data/json/mapgen_palettes/sewers_palette.json index f2c4788460a82..5a9c089b409dd 100644 --- a/data/json/mapgen_palettes/sewers_palette.json +++ b/data/json/mapgen_palettes/sewers_palette.json @@ -12,7 +12,7 @@ "_": [ [ "t_moss", 2 ], [ "t_dirt", 3 ], [ "t_dirtmound", 1 ], [ "t_sewage", 10 ] ], "|": [ "t_concrete_wall" ], "I": [ "t_wall_metal" ], - "W": [ "t_rock" ], + "W": [ "t_soil" ], "r": [ "t_metal_floor" ], "L": [ [ "t_door_bar_o", 1 ], [ "t_door_bar_locked", 5 ] ], "D": [ "t_door_metal_c" ], diff --git a/data/json/mapgen_palettes/shelter.json b/data/json/mapgen_palettes/shelter.json index d0790f5f21591..cdfdb5a84a1f1 100644 --- a/data/json/mapgen_palettes/shelter.json +++ b/data/json/mapgen_palettes/shelter.json @@ -7,7 +7,7 @@ "!": "t_pavement", "`": "t_pavement_y", "&": "t_sidewalk", - "#": "t_rock", + "#": "t_soil", "+": "t_door_c", "-": "t_wall_w", "_": "t_linoleum_white", diff --git a/data/json/mapgen_palettes/subway.json b/data/json/mapgen_palettes/subway.json index 7c7ec2270d7f6..154462ebcc2a4 100644 --- a/data/json/mapgen_palettes/subway.json +++ b/data/json/mapgen_palettes/subway.json @@ -21,7 +21,8 @@ "type": "palette", "id": "subway_underground", "terrain": { - "#": "t_rock", + "#": "t_soil", + "0": "t_rock", "R": "t_rock_red", "G": "t_rock_green", "B": "t_rock_blue", diff --git a/data/json/overmap/overmap_special/specials.json b/data/json/overmap/overmap_special/specials.json index ad0f2fbb22245..19841ac6f844a 100644 --- a/data/json/overmap/overmap_special/specials.json +++ b/data/json/overmap/overmap_special/specials.json @@ -1244,7 +1244,7 @@ { "type": "overmap_special", "id": "Slime Pit", - "overmaps": [ { "point": [ 0, 0, 0 ], "overmap": "slimepit_down" } ], + "overmaps": [ { "point": [ 0, 0, 0 ], "overmap": "slimepit_top" }, { "point": [ 0, 0, -1 ], "overmap": "slimepit_bottom" } ], "locations": [ "wilderness" ], "city_distance": [ 3, 30 ], "occurrences": [ 0, 3 ], diff --git a/data/json/overmap/overmap_terrain/overmap_terrain.json b/data/json/overmap/overmap_terrain/overmap_terrain.json index 6338ba751a437..383f4bda69ee5 100644 --- a/data/json/overmap/overmap_terrain/overmap_terrain.json +++ b/data/json/overmap/overmap_terrain/overmap_terrain.json @@ -22,6 +22,15 @@ "copy-from": "generic_city_building_no_sidewalk", "extend": { "flags": [ "SIDEWALK" ] } }, + { + "type": "overmap_terrain", + "id": "solid_earth", + "name": "solid earth", + "sym": "#", + "color": "brown", + "see_cost": 5, + "flags": [ "NO_ROTATE" ] + }, { "type": "overmap_terrain", "id": "park", @@ -653,7 +662,16 @@ }, { "type": "overmap_terrain", - "id": [ "lab_subway_vent_shaft-1", "lab_subway_vent_shaft-2", "lab_subway_vent_shaft-3", "lab_subway_vent_shaft-4" ], + "id": "lab_subway_vent_shaft-1", + "name": "ventilation shaft", + "sym": "#", + "color": "brown", + "see_cost": 5, + "flags": [ "NO_ROTATE", "RISK_HIGH" ] + }, + { + "type": "overmap_terrain", + "id": [ "lab_subway_vent_shaft-2", "lab_subway_vent_shaft-3", "lab_subway_vent_shaft-4" ], "name": "ventilation shaft", "sym": "%", "color": "dark_gray", diff --git a/data/json/overmap/overmap_terrain/overmap_terrain_alien.json b/data/json/overmap/overmap_terrain/overmap_terrain_alien.json new file mode 100644 index 0000000000000..e5178718e09d2 --- /dev/null +++ b/data/json/overmap/overmap_terrain/overmap_terrain_alien.json @@ -0,0 +1,11 @@ +[ + { + "type": "overmap_terrain", + "id": [ "slimepit_bottom", "slimepit_top" ], + "name": "slime pit", + "sym": "~", + "color": "light_green", + "see_cost": 2, + "flags": [ "KNOWN_DOWN", "NO_ROTATE" ] + } +] diff --git a/data/json/overmap/overmap_terrain/overmap_terrain_evac_center.json b/data/json/overmap/overmap_terrain/overmap_terrain_evac_center.json index 02bfcfe4eaa2c..c9f05abc1ad63 100644 --- a/data/json/overmap/overmap_terrain/overmap_terrain_evac_center.json +++ b/data/json/overmap/overmap_terrain/overmap_terrain_evac_center.json @@ -757,6 +757,14 @@ ], "copy-from": "generic_rc_air" }, + { + "type": "overmap_terrain", + "abstract": "generic_rc_earth", + "name": "solid earth", + "sym": "#", + "color": "brown", + "see_cost": 5 + }, { "type": "overmap_terrain", "abstract": "generic_rc_underground", @@ -769,902 +777,908 @@ "type": "overmap_terrain", "id": [ "evac_center_10_z-1", + "evac_center_11_z-1", + "evac_center_12_z-1", + "evac_center_13_z-1", + "evac_center_14_z-1", + "evac_center_15_z-1", + "evac_center_16_z-1", + "evac_center_17_z-1", + "evac_center_18_z-1", + "evac_center_19_z-1", + "evac_center_1_z-1", + "evac_center_20_z-1", + "evac_center_21_z-1", + "evac_center_22_z-1", + "evac_center_23_z-1", + "evac_center_24_z-1", + "evac_center_25_z-1", + "evac_center_2_z-1", + "evac_center_3_z-1", + "evac_center_4_z-1", + "evac_center_5_z-1", + "evac_center_6_z-1", + "evac_center_7_z-1", + "evac_center_8_z-1", + "evac_center_9_z-1", + "refctr_E1a_z-1", + "refctr_E1b_z-1", + "refctr_E1c_z-1", + "refctr_E1d_z-1", + "refctr_E1e_z-1", + "refctr_E2a_z-1", + "refctr_E2b_z-1", + "refctr_E2c_z-1", + "refctr_E2d_z-1", + "refctr_E2e_z-1", + "refctr_E3a_z-1", + "refctr_E3b_z-1", + "refctr_E3c_z-1", + "refctr_E3d_z-1", + "refctr_E3e_z-1", + "refctr_E4a_z-1", + "refctr_E4b_z-1", + "refctr_E4c_z-1", + "refctr_E4d_z-1", + "refctr_E4e_z-1", + "refctr_E5a_z-1", + "refctr_E5b_z-1", + "refctr_E5c_z-1", + "refctr_E5d_z-1", + "refctr_E5e_z-1", + "refctr_N1a_z-1", + "refctr_N1b_z-1", + "refctr_N1c_z-1", + "refctr_N1d_z-1", + "refctr_N1e_z-1", + "refctr_N2a_z-1", + "refctr_N2b_z-1", + "refctr_N2c_z-1", + "refctr_N2d_z-1", + "refctr_N2e_z-1", + "refctr_N3a_z-1", + "refctr_N3b_z-1", + "refctr_N3c_z-1", + "refctr_N3d_z-1", + "refctr_N3e_z-1", + "refctr_N4a_z-1", + "refctr_N4b_z-1", + "refctr_N4c_z-1", + "refctr_N4d_z-1", + "refctr_N4e_z-1", + "refctr_N5a_z-1", + "refctr_N5b_z-1", + "refctr_N5c_z-1", + "refctr_N5d_z-1", + "refctr_N5e_z-1", + "refctr_NE1a_z-1", + "refctr_NE1b_z-1", + "refctr_NE1c_z-1", + "refctr_NE1d_z-1", + "refctr_NE1e_z-1", + "refctr_NE2a_z-1", + "refctr_NE2b_z-1", + "refctr_NE2c_z-1", + "refctr_NE2d_z-1", + "refctr_NE2e_z-1", + "refctr_NE3a_z-1", + "refctr_NE3b_z-1", + "refctr_NE3c_z-1", + "refctr_NE3d_z-1", + "refctr_NE3e_z-1", + "refctr_NE4a_z-1", + "refctr_NE4b_z-1", + "refctr_NE4c_z-1", + "refctr_NE4d_z-1", + "refctr_NE4e_z-1", + "refctr_NE5a_z-1", + "refctr_NE5b_z-1", + "refctr_NE5c_z-1", + "refctr_NE5d_z-1", + "refctr_NE5e_z-1", + "refctr_NW1a_z-1", + "refctr_NW1b_z-1", + "refctr_NW1c_z-1", + "refctr_NW1d_z-1", + "refctr_NW1e_z-1", + "refctr_NW2a_z-1", + "refctr_NW2b_z-1", + "refctr_NW2c_z-1", + "refctr_NW2d_z-1", + "refctr_NW2e_z-1", + "refctr_NW3a_z-1", + "refctr_NW3b_z-1", + "refctr_NW3c_z-1", + "refctr_NW3d_z-1", + "refctr_NW3e_z-1", + "refctr_NW4a_z-1", + "refctr_NW4b_z-1", + "refctr_NW4c_z-1", + "refctr_NW4d_z-1", + "refctr_NW4e_z-1", + "refctr_NW5a_z-1", + "refctr_NW5b_z-1", + "refctr_NW5c_z-1", + "refctr_NW5d_z-1", + "refctr_NW5e_z-1", + "refctr_S1a_z-1", + "refctr_S1b_z-1", + "refctr_S1c_z-1", + "refctr_S1d_z-1", + "refctr_S1e_z-1", + "refctr_S2a_z-1", + "refctr_S2b_z-1", + "refctr_S2c_z-1", + "refctr_S2d_z-1", + "refctr_S2e_z-1", + "refctr_S3a_z-1", + "refctr_S3b_z-1", + "refctr_S3c_z-1", + "refctr_S3d_z-1", + "refctr_S3e_z-1", + "refctr_S4a_z-1", + "refctr_S4b_z-1", + "refctr_S4c_z-1", + "refctr_S4d_z-1", + "refctr_S4e_z-1", + "refctr_S5a_z-1", + "refctr_S5b_z-1", + "refctr_S5c_z-1", + "refctr_S5d_z-1", + "refctr_S5e_z-1", + "refctr_SE1a_z-1", + "refctr_SE1b_z-1", + "refctr_SE1c_z-1", + "refctr_SE1d_z-1", + "refctr_SE1e_z-1", + "refctr_SE2a_z-1", + "refctr_SE2b_z-1", + "refctr_SE2c_z-1", + "refctr_SE2d_z-1", + "refctr_SE2e_z-1", + "refctr_SE3a_z-1", + "refctr_SE3b_z-1", + "refctr_SE3c_z-1", + "refctr_SE3d_z-1", + "refctr_SE3e_z-1", + "refctr_SE4a_z-1", + "refctr_SE4b_z-1", + "refctr_SE4c_z-1", + "refctr_SE4d_z-1", + "refctr_SE4e_z-1", + "refctr_SE5a_z-1", + "refctr_SE5b_z-1", + "refctr_SE5c_z-1", + "refctr_SE5d_z-1", + "refctr_SE5e_z-1", + "refctr_SW1a_z-1", + "refctr_SW1b_z-1", + "refctr_SW1c_z-1", + "refctr_SW1d_z-1", + "refctr_SW1e_z-1", + "refctr_SW2a_z-1", + "refctr_SW2b_z-1", + "refctr_SW2c_z-1", + "refctr_SW2d_z-1", + "refctr_SW2e_z-1", + "refctr_SW3a_z-1", + "refctr_SW3b_z-1", + "refctr_SW3c_z-1", + "refctr_SW3d_z-1", + "refctr_SW3e_z-1", + "refctr_SW4a_z-1", + "refctr_SW4b_z-1", + "refctr_SW4c_z-1", + "refctr_SW4d_z-1", + "refctr_SW4e_z-1", + "refctr_SW5a_z-1", + "refctr_SW5b_z-1", + "refctr_SW5c_z-1", + "refctr_SW5d_z-1", + "refctr_SW5e_z-1", + "refctr_W1a_z-1", + "refctr_W1b_z-1", + "refctr_W1c_z-1", + "refctr_W1d_z-1", + "refctr_W1e_z-1", + "refctr_W2a_z-1", + "refctr_W2b_z-1", + "refctr_W2c_z-1", + "refctr_W2d_z-1", + "refctr_W2e_z-1", + "refctr_W3a_z-1", + "refctr_W3b_z-1", + "refctr_W3c_z-1", + "refctr_W3d_z-1", + "refctr_W3e_z-1", + "refctr_W4a_z-1", + "refctr_W4b_z-1", + "refctr_W4c_z-1", + "refctr_W4d_z-1", + "refctr_W4e_z-1", + "refctr_W5a_z-1", + "refctr_W5b_z-1", + "refctr_W5c_z-1", + "refctr_W5d_z-1", + "refctr_W5e_z-1" + ], + "copy-from": "generic_rc_earth" + }, + { + "type": "overmap_terrain", + "id": [ "evac_center_10_z-2", "evac_center_10_z-3", "evac_center_10_z-4", - "evac_center_11_z-1", "evac_center_11_z-2", "evac_center_11_z-3", "evac_center_11_z-4", - "evac_center_12_z-1", "evac_center_12_z-2", "evac_center_12_z-3", "evac_center_12_z-4", - "evac_center_13_z-1", "evac_center_13_z-2", "evac_center_13_z-3", "evac_center_13_z-4", - "evac_center_14_z-1", "evac_center_14_z-2", "evac_center_14_z-3", "evac_center_14_z-4", - "evac_center_15_z-1", "evac_center_15_z-2", "evac_center_15_z-3", "evac_center_15_z-4", - "evac_center_16_z-1", "evac_center_16_z-2", "evac_center_16_z-3", "evac_center_16_z-4", - "evac_center_17_z-1", "evac_center_17_z-2", "evac_center_17_z-3", "evac_center_17_z-4", - "evac_center_18_z-1", "evac_center_18_z-2", "evac_center_18_z-3", "evac_center_18_z-4", - "evac_center_19_z-1", "evac_center_19_z-2", "evac_center_19_z-3", "evac_center_19_z-4", - "evac_center_1_z-1", "evac_center_1_z-2", "evac_center_1_z-3", "evac_center_1_z-4", - "evac_center_20_z-1", "evac_center_20_z-2", "evac_center_20_z-3", "evac_center_20_z-4", - "evac_center_21_z-1", "evac_center_21_z-2", "evac_center_21_z-3", "evac_center_21_z-4", - "evac_center_22_z-1", "evac_center_22_z-2", "evac_center_22_z-3", "evac_center_22_z-4", - "evac_center_23_z-1", "evac_center_23_z-2", "evac_center_23_z-3", "evac_center_23_z-4", - "evac_center_24_z-1", "evac_center_24_z-2", "evac_center_24_z-3", "evac_center_24_z-4", - "evac_center_25_z-1", "evac_center_25_z-2", "evac_center_25_z-3", "evac_center_25_z-4", - "evac_center_2_z-1", "evac_center_2_z-2", "evac_center_2_z-3", "evac_center_2_z-4", - "evac_center_3_z-1", "evac_center_3_z-2", "evac_center_3_z-3", "evac_center_3_z-4", - "evac_center_4_z-1", "evac_center_4_z-2", "evac_center_4_z-3", "evac_center_4_z-4", - "evac_center_5_z-1", "evac_center_5_z-2", "evac_center_5_z-3", "evac_center_5_z-4", - "evac_center_6_z-1", "evac_center_6_z-2", "evac_center_6_z-3", "evac_center_6_z-4", - "evac_center_7_z-1", "evac_center_7_z-2", "evac_center_7_z-3", "evac_center_7_z-4", - "evac_center_8_z-1", "evac_center_8_z-2", "evac_center_8_z-3", "evac_center_8_z-4", - "evac_center_9_z-1", "evac_center_9_z-2", "evac_center_9_z-3", "evac_center_9_z-4", - "refctr_E1a_z-1", "refctr_E1a_z-2", "refctr_E1a_z-3", "refctr_E1a_z-4", - "refctr_E1b_z-1", "refctr_E1b_z-2", "refctr_E1b_z-3", "refctr_E1b_z-4", - "refctr_E1c_z-1", "refctr_E1c_z-2", "refctr_E1c_z-3", "refctr_E1c_z-4", - "refctr_E1d_z-1", "refctr_E1d_z-2", "refctr_E1d_z-3", "refctr_E1d_z-4", - "refctr_E1e_z-1", "refctr_E1e_z-2", "refctr_E1e_z-3", "refctr_E1e_z-4", - "refctr_E2a_z-1", "refctr_E2a_z-2", "refctr_E2a_z-3", "refctr_E2a_z-4", - "refctr_E2b_z-1", "refctr_E2b_z-2", "refctr_E2b_z-3", "refctr_E2b_z-4", - "refctr_E2c_z-1", "refctr_E2c_z-2", "refctr_E2c_z-3", "refctr_E2c_z-4", - "refctr_E2d_z-1", "refctr_E2d_z-2", "refctr_E2d_z-3", "refctr_E2d_z-4", - "refctr_E2e_z-1", "refctr_E2e_z-2", "refctr_E2e_z-3", "refctr_E2e_z-4", - "refctr_E3a_z-1", "refctr_E3a_z-2", "refctr_E3a_z-3", "refctr_E3a_z-4", - "refctr_E3b_z-1", "refctr_E3b_z-2", "refctr_E3b_z-3", "refctr_E3b_z-4", - "refctr_E3c_z-1", "refctr_E3c_z-2", "refctr_E3c_z-3", "refctr_E3c_z-4", - "refctr_E3d_z-1", "refctr_E3d_z-2", "refctr_E3d_z-3", "refctr_E3d_z-4", - "refctr_E3e_z-1", "refctr_E3e_z-2", "refctr_E3e_z-3", "refctr_E3e_z-4", - "refctr_E4a_z-1", "refctr_E4a_z-2", "refctr_E4a_z-3", "refctr_E4a_z-4", - "refctr_E4b_z-1", "refctr_E4b_z-2", "refctr_E4b_z-3", "refctr_E4b_z-4", - "refctr_E4c_z-1", "refctr_E4c_z-2", "refctr_E4c_z-3", "refctr_E4c_z-4", - "refctr_E4d_z-1", "refctr_E4d_z-2", "refctr_E4d_z-3", "refctr_E4d_z-4", - "refctr_E4e_z-1", "refctr_E4e_z-2", "refctr_E4e_z-3", "refctr_E4e_z-4", - "refctr_E5a_z-1", "refctr_E5a_z-2", "refctr_E5a_z-3", "refctr_E5a_z-4", - "refctr_E5b_z-1", "refctr_E5b_z-2", "refctr_E5b_z-3", "refctr_E5b_z-4", - "refctr_E5c_z-1", "refctr_E5c_z-2", "refctr_E5c_z-3", "refctr_E5c_z-4", - "refctr_E5d_z-1", "refctr_E5d_z-2", "refctr_E5d_z-3", "refctr_E5d_z-4", - "refctr_E5e_z-1", "refctr_E5e_z-2", "refctr_E5e_z-3", "refctr_E5e_z-4", - "refctr_N1a_z-1", "refctr_N1a_z-2", "refctr_N1a_z-3", "refctr_N1a_z-4", - "refctr_N1b_z-1", "refctr_N1b_z-2", "refctr_N1b_z-3", "refctr_N1b_z-4", - "refctr_N1c_z-1", "refctr_N1c_z-2", "refctr_N1c_z-3", "refctr_N1c_z-4", - "refctr_N1d_z-1", "refctr_N1d_z-2", "refctr_N1d_z-3", "refctr_N1d_z-4", - "refctr_N1e_z-1", "refctr_N1e_z-2", "refctr_N1e_z-3", "refctr_N1e_z-4", - "refctr_N2a_z-1", "refctr_N2a_z-2", "refctr_N2a_z-3", "refctr_N2a_z-4", - "refctr_N2b_z-1", "refctr_N2b_z-2", "refctr_N2b_z-3", "refctr_N2b_z-4", - "refctr_N2c_z-1", "refctr_N2c_z-2", "refctr_N2c_z-3", "refctr_N2c_z-4", - "refctr_N2d_z-1", "refctr_N2d_z-2", "refctr_N2d_z-3", "refctr_N2d_z-4", - "refctr_N2e_z-1", "refctr_N2e_z-2", "refctr_N2e_z-3", "refctr_N2e_z-4", - "refctr_N3a_z-1", "refctr_N3a_z-2", "refctr_N3a_z-3", "refctr_N3a_z-4", - "refctr_N3b_z-1", "refctr_N3b_z-2", "refctr_N3b_z-3", "refctr_N3b_z-4", - "refctr_N3c_z-1", "refctr_N3c_z-2", "refctr_N3c_z-3", "refctr_N3c_z-4", - "refctr_N3d_z-1", "refctr_N3d_z-2", "refctr_N3d_z-3", "refctr_N3d_z-4", - "refctr_N3e_z-1", "refctr_N3e_z-2", "refctr_N3e_z-3", "refctr_N3e_z-4", - "refctr_N4a_z-1", "refctr_N4a_z-2", "refctr_N4a_z-3", "refctr_N4a_z-4", - "refctr_N4b_z-1", "refctr_N4b_z-2", "refctr_N4b_z-3", "refctr_N4b_z-4", - "refctr_N4c_z-1", "refctr_N4c_z-2", "refctr_N4c_z-3", "refctr_N4c_z-4", - "refctr_N4d_z-1", "refctr_N4d_z-2", "refctr_N4d_z-3", "refctr_N4d_z-4", - "refctr_N4e_z-1", "refctr_N4e_z-2", "refctr_N4e_z-3", "refctr_N4e_z-4", - "refctr_N5a_z-1", "refctr_N5a_z-2", "refctr_N5a_z-3", "refctr_N5a_z-4", - "refctr_N5b_z-1", "refctr_N5b_z-2", "refctr_N5b_z-3", "refctr_N5b_z-4", - "refctr_N5c_z-1", "refctr_N5c_z-2", "refctr_N5c_z-3", "refctr_N5c_z-4", - "refctr_N5d_z-1", "refctr_N5d_z-2", "refctr_N5d_z-3", "refctr_N5d_z-4", - "refctr_N5e_z-1", "refctr_N5e_z-2", "refctr_N5e_z-3", "refctr_N5e_z-4", - "refctr_NE1a_z-1", "refctr_NE1a_z-2", "refctr_NE1a_z-3", "refctr_NE1a_z-4", - "refctr_NE1b_z-1", "refctr_NE1b_z-2", "refctr_NE1b_z-3", "refctr_NE1b_z-4", - "refctr_NE1c_z-1", "refctr_NE1c_z-2", "refctr_NE1c_z-3", "refctr_NE1c_z-4", - "refctr_NE1d_z-1", "refctr_NE1d_z-2", "refctr_NE1d_z-3", "refctr_NE1d_z-4", - "refctr_NE1e_z-1", "refctr_NE1e_z-2", "refctr_NE1e_z-3", "refctr_NE1e_z-4", - "refctr_NE2a_z-1", "refctr_NE2a_z-2", "refctr_NE2a_z-3", "refctr_NE2a_z-4", - "refctr_NE2b_z-1", "refctr_NE2b_z-2", "refctr_NE2b_z-3", "refctr_NE2b_z-4", - "refctr_NE2c_z-1", "refctr_NE2c_z-2", "refctr_NE2c_z-3", "refctr_NE2c_z-4", - "refctr_NE2d_z-1", "refctr_NE2d_z-2", "refctr_NE2d_z-3", "refctr_NE2d_z-4", - "refctr_NE2e_z-1", "refctr_NE2e_z-2", "refctr_NE2e_z-3", "refctr_NE2e_z-4", - "refctr_NE3a_z-1", "refctr_NE3a_z-2", "refctr_NE3a_z-3", "refctr_NE3a_z-4", - "refctr_NE3b_z-1", "refctr_NE3b_z-2", "refctr_NE3b_z-3", "refctr_NE3b_z-4", - "refctr_NE3c_z-1", "refctr_NE3c_z-2", "refctr_NE3c_z-3", "refctr_NE3c_z-4", - "refctr_NE3d_z-1", "refctr_NE3d_z-2", "refctr_NE3d_z-3", "refctr_NE3d_z-4", - "refctr_NE3e_z-1", "refctr_NE3e_z-2", "refctr_NE3e_z-3", "refctr_NE3e_z-4", - "refctr_NE4a_z-1", "refctr_NE4a_z-2", "refctr_NE4a_z-3", "refctr_NE4a_z-4", - "refctr_NE4b_z-1", "refctr_NE4b_z-2", "refctr_NE4b_z-3", "refctr_NE4b_z-4", - "refctr_NE4c_z-1", "refctr_NE4c_z-2", "refctr_NE4c_z-3", "refctr_NE4c_z-4", - "refctr_NE4d_z-1", "refctr_NE4d_z-2", "refctr_NE4d_z-3", "refctr_NE4d_z-4", - "refctr_NE4e_z-1", "refctr_NE4e_z-2", "refctr_NE4e_z-3", "refctr_NE4e_z-4", - "refctr_NE5a_z-1", "refctr_NE5a_z-2", "refctr_NE5a_z-3", "refctr_NE5a_z-4", - "refctr_NE5b_z-1", "refctr_NE5b_z-2", "refctr_NE5b_z-3", "refctr_NE5b_z-4", - "refctr_NE5c_z-1", "refctr_NE5c_z-2", "refctr_NE5c_z-3", "refctr_NE5c_z-4", - "refctr_NE5d_z-1", "refctr_NE5d_z-2", "refctr_NE5d_z-3", "refctr_NE5d_z-4", - "refctr_NE5e_z-1", "refctr_NE5e_z-2", "refctr_NE5e_z-3", "refctr_NE5e_z-4", - "refctr_NW1a_z-1", "refctr_NW1a_z-2", "refctr_NW1a_z-3", "refctr_NW1a_z-4", - "refctr_NW1b_z-1", "refctr_NW1b_z-2", "refctr_NW1b_z-3", "refctr_NW1b_z-4", - "refctr_NW1c_z-1", "refctr_NW1c_z-2", "refctr_NW1c_z-3", "refctr_NW1c_z-4", - "refctr_NW1d_z-1", "refctr_NW1d_z-2", "refctr_NW1d_z-3", "refctr_NW1d_z-4", - "refctr_NW1e_z-1", "refctr_NW1e_z-2", "refctr_NW1e_z-3", "refctr_NW1e_z-4", - "refctr_NW2a_z-1", "refctr_NW2a_z-2", "refctr_NW2a_z-3", "refctr_NW2a_z-4", - "refctr_NW2b_z-1", "refctr_NW2b_z-2", "refctr_NW2b_z-3", "refctr_NW2b_z-4", - "refctr_NW2c_z-1", "refctr_NW2c_z-2", "refctr_NW2c_z-3", "refctr_NW2c_z-4", - "refctr_NW2d_z-1", "refctr_NW2d_z-2", "refctr_NW2d_z-3", "refctr_NW2d_z-4", - "refctr_NW2e_z-1", "refctr_NW2e_z-2", "refctr_NW2e_z-3", "refctr_NW2e_z-4", - "refctr_NW3a_z-1", "refctr_NW3a_z-2", "refctr_NW3a_z-3", "refctr_NW3a_z-4", - "refctr_NW3b_z-1", "refctr_NW3b_z-2", "refctr_NW3b_z-3", "refctr_NW3b_z-4", - "refctr_NW3c_z-1", "refctr_NW3c_z-2", "refctr_NW3c_z-3", "refctr_NW3c_z-4", - "refctr_NW3d_z-1", "refctr_NW3d_z-2", "refctr_NW3d_z-3", "refctr_NW3d_z-4", - "refctr_NW3e_z-1", "refctr_NW3e_z-2", "refctr_NW3e_z-3", "refctr_NW3e_z-4", - "refctr_NW4a_z-1", "refctr_NW4a_z-2", "refctr_NW4a_z-3", "refctr_NW4a_z-4", - "refctr_NW4b_z-1", "refctr_NW4b_z-2", "refctr_NW4b_z-3", "refctr_NW4b_z-4", - "refctr_NW4c_z-1", "refctr_NW4c_z-2", "refctr_NW4c_z-3", "refctr_NW4c_z-4", - "refctr_NW4d_z-1", "refctr_NW4d_z-2", "refctr_NW4d_z-3", "refctr_NW4d_z-4", - "refctr_NW4e_z-1", "refctr_NW4e_z-2", "refctr_NW4e_z-3", "refctr_NW4e_z-4", - "refctr_NW5a_z-1", "refctr_NW5a_z-2", "refctr_NW5a_z-3", "refctr_NW5a_z-4", - "refctr_NW5b_z-1", "refctr_NW5b_z-2", "refctr_NW5b_z-3", "refctr_NW5b_z-4", - "refctr_NW5c_z-1", "refctr_NW5c_z-2", "refctr_NW5c_z-3", "refctr_NW5c_z-4", - "refctr_NW5d_z-1", "refctr_NW5d_z-2", "refctr_NW5d_z-3", "refctr_NW5d_z-4", - "refctr_NW5e_z-1", "refctr_NW5e_z-2", "refctr_NW5e_z-3", "refctr_NW5e_z-4", - "refctr_S1a_z-1", "refctr_S1a_z-2", "refctr_S1a_z-3", "refctr_S1a_z-4", - "refctr_S1b_z-1", "refctr_S1b_z-2", "refctr_S1b_z-3", "refctr_S1b_z-4", - "refctr_S1c_z-1", "refctr_S1c_z-2", "refctr_S1c_z-3", "refctr_S1c_z-4", - "refctr_S1d_z-1", "refctr_S1d_z-2", "refctr_S1d_z-3", "refctr_S1d_z-4", - "refctr_S1e_z-1", "refctr_S1e_z-2", "refctr_S1e_z-3", "refctr_S1e_z-4", - "refctr_S2a_z-1", "refctr_S2a_z-2", "refctr_S2a_z-3", "refctr_S2a_z-4", - "refctr_S2b_z-1", "refctr_S2b_z-2", "refctr_S2b_z-3", "refctr_S2b_z-4", - "refctr_S2c_z-1", "refctr_S2c_z-2", "refctr_S2c_z-3", "refctr_S2c_z-4", - "refctr_S2d_z-1", "refctr_S2d_z-2", "refctr_S2d_z-3", "refctr_S2d_z-4", - "refctr_S2e_z-1", "refctr_S2e_z-2", "refctr_S2e_z-3", "refctr_S2e_z-4", - "refctr_S3a_z-1", "refctr_S3a_z-2", "refctr_S3a_z-3", "refctr_S3a_z-4", - "refctr_S3b_z-1", "refctr_S3b_z-2", "refctr_S3b_z-3", "refctr_S3b_z-4", - "refctr_S3c_z-1", "refctr_S3c_z-2", "refctr_S3c_z-3", "refctr_S3c_z-4", - "refctr_S3d_z-1", "refctr_S3d_z-2", "refctr_S3d_z-3", "refctr_S3d_z-4", - "refctr_S3e_z-1", "refctr_S3e_z-2", "refctr_S3e_z-3", "refctr_S3e_z-4", - "refctr_S4a_z-1", "refctr_S4a_z-2", "refctr_S4a_z-3", "refctr_S4a_z-4", - "refctr_S4b_z-1", "refctr_S4b_z-2", "refctr_S4b_z-3", "refctr_S4b_z-4", - "refctr_S4c_z-1", "refctr_S4c_z-2", "refctr_S4c_z-3", "refctr_S4c_z-4", - "refctr_S4d_z-1", "refctr_S4d_z-2", "refctr_S4d_z-3", "refctr_S4d_z-4", - "refctr_S4e_z-1", "refctr_S4e_z-2", "refctr_S4e_z-3", "refctr_S4e_z-4", - "refctr_S5a_z-1", "refctr_S5a_z-2", "refctr_S5a_z-3", "refctr_S5a_z-4", - "refctr_S5b_z-1", "refctr_S5b_z-2", "refctr_S5b_z-3", "refctr_S5b_z-4", - "refctr_S5c_z-1", "refctr_S5c_z-2", "refctr_S5c_z-3", "refctr_S5c_z-4", - "refctr_S5d_z-1", "refctr_S5d_z-2", "refctr_S5d_z-3", "refctr_S5d_z-4", - "refctr_S5e_z-1", "refctr_S5e_z-2", "refctr_S5e_z-3", "refctr_S5e_z-4", - "refctr_SE1a_z-1", "refctr_SE1a_z-2", "refctr_SE1a_z-3", "refctr_SE1a_z-4", - "refctr_SE1b_z-1", "refctr_SE1b_z-2", "refctr_SE1b_z-3", "refctr_SE1b_z-4", - "refctr_SE1c_z-1", "refctr_SE1c_z-2", "refctr_SE1c_z-3", "refctr_SE1c_z-4", - "refctr_SE1d_z-1", "refctr_SE1d_z-2", "refctr_SE1d_z-3", "refctr_SE1d_z-4", - "refctr_SE1e_z-1", "refctr_SE1e_z-2", "refctr_SE1e_z-3", "refctr_SE1e_z-4", - "refctr_SE2a_z-1", "refctr_SE2a_z-2", "refctr_SE2a_z-3", "refctr_SE2a_z-4", - "refctr_SE2b_z-1", "refctr_SE2b_z-2", "refctr_SE2b_z-3", "refctr_SE2b_z-4", - "refctr_SE2c_z-1", "refctr_SE2c_z-2", "refctr_SE2c_z-3", "refctr_SE2c_z-4", - "refctr_SE2d_z-1", "refctr_SE2d_z-2", "refctr_SE2d_z-3", "refctr_SE2d_z-4", - "refctr_SE2e_z-1", "refctr_SE2e_z-2", "refctr_SE2e_z-3", "refctr_SE2e_z-4", - "refctr_SE3a_z-1", "refctr_SE3a_z-2", "refctr_SE3a_z-3", "refctr_SE3a_z-4", - "refctr_SE3b_z-1", "refctr_SE3b_z-2", "refctr_SE3b_z-3", "refctr_SE3b_z-4", - "refctr_SE3c_z-1", "refctr_SE3c_z-2", "refctr_SE3c_z-3", "refctr_SE3c_z-4", - "refctr_SE3d_z-1", "refctr_SE3d_z-2", "refctr_SE3d_z-3", "refctr_SE3d_z-4", - "refctr_SE3e_z-1", "refctr_SE3e_z-2", "refctr_SE3e_z-3", "refctr_SE3e_z-4", - "refctr_SE4a_z-1", "refctr_SE4a_z-2", "refctr_SE4a_z-3", "refctr_SE4a_z-4", - "refctr_SE4b_z-1", "refctr_SE4b_z-2", "refctr_SE4b_z-3", "refctr_SE4b_z-4", - "refctr_SE4c_z-1", "refctr_SE4c_z-2", "refctr_SE4c_z-3", "refctr_SE4c_z-4", - "refctr_SE4d_z-1", "refctr_SE4d_z-2", "refctr_SE4d_z-3", "refctr_SE4d_z-4", - "refctr_SE4e_z-1", "refctr_SE4e_z-2", "refctr_SE4e_z-3", "refctr_SE4e_z-4", - "refctr_SE5a_z-1", "refctr_SE5a_z-2", "refctr_SE5a_z-3", "refctr_SE5a_z-4", - "refctr_SE5b_z-1", "refctr_SE5b_z-2", "refctr_SE5b_z-3", "refctr_SE5b_z-4", - "refctr_SE5c_z-1", "refctr_SE5c_z-2", "refctr_SE5c_z-3", "refctr_SE5c_z-4", - "refctr_SE5d_z-1", "refctr_SE5d_z-2", "refctr_SE5d_z-3", "refctr_SE5d_z-4", - "refctr_SE5e_z-1", "refctr_SE5e_z-2", "refctr_SE5e_z-3", "refctr_SE5e_z-4", - "refctr_SW1a_z-1", "refctr_SW1a_z-2", "refctr_SW1a_z-3", "refctr_SW1a_z-4", - "refctr_SW1b_z-1", "refctr_SW1b_z-2", "refctr_SW1b_z-3", "refctr_SW1b_z-4", - "refctr_SW1c_z-1", "refctr_SW1c_z-2", "refctr_SW1c_z-3", "refctr_SW1c_z-4", - "refctr_SW1d_z-1", "refctr_SW1d_z-2", "refctr_SW1d_z-3", "refctr_SW1d_z-4", - "refctr_SW1e_z-1", "refctr_SW1e_z-2", "refctr_SW1e_z-3", "refctr_SW1e_z-4", - "refctr_SW2a_z-1", "refctr_SW2a_z-2", "refctr_SW2a_z-3", "refctr_SW2a_z-4", - "refctr_SW2b_z-1", "refctr_SW2b_z-2", "refctr_SW2b_z-3", "refctr_SW2b_z-4", - "refctr_SW2c_z-1", "refctr_SW2c_z-2", "refctr_SW2c_z-3", "refctr_SW2c_z-4", - "refctr_SW2d_z-1", "refctr_SW2d_z-2", "refctr_SW2d_z-3", "refctr_SW2d_z-4", - "refctr_SW2e_z-1", "refctr_SW2e_z-2", "refctr_SW2e_z-3", "refctr_SW2e_z-4", - "refctr_SW3a_z-1", "refctr_SW3a_z-2", "refctr_SW3a_z-3", "refctr_SW3a_z-4", - "refctr_SW3b_z-1", "refctr_SW3b_z-2", "refctr_SW3b_z-3", "refctr_SW3b_z-4", - "refctr_SW3c_z-1", "refctr_SW3c_z-2", "refctr_SW3c_z-3", "refctr_SW3c_z-4", - "refctr_SW3d_z-1", "refctr_SW3d_z-2", "refctr_SW3d_z-3", "refctr_SW3d_z-4", - "refctr_SW3e_z-1", "refctr_SW3e_z-2", "refctr_SW3e_z-3", "refctr_SW3e_z-4", - "refctr_SW4a_z-1", "refctr_SW4a_z-2", "refctr_SW4a_z-3", "refctr_SW4a_z-4", - "refctr_SW4b_z-1", "refctr_SW4b_z-2", "refctr_SW4b_z-3", "refctr_SW4b_z-4", - "refctr_SW4c_z-1", "refctr_SW4c_z-2", "refctr_SW4c_z-3", "refctr_SW4c_z-4", - "refctr_SW4d_z-1", "refctr_SW4d_z-2", "refctr_SW4d_z-3", "refctr_SW4d_z-4", - "refctr_SW4e_z-1", "refctr_SW4e_z-2", "refctr_SW4e_z-3", "refctr_SW4e_z-4", - "refctr_SW5a_z-1", "refctr_SW5a_z-2", "refctr_SW5a_z-3", "refctr_SW5a_z-4", - "refctr_SW5b_z-1", "refctr_SW5b_z-2", "refctr_SW5b_z-3", "refctr_SW5b_z-4", - "refctr_SW5c_z-1", "refctr_SW5c_z-2", "refctr_SW5c_z-3", "refctr_SW5c_z-4", - "refctr_SW5d_z-1", "refctr_SW5d_z-2", "refctr_SW5d_z-3", "refctr_SW5d_z-4", - "refctr_SW5e_z-1", "refctr_SW5e_z-2", "refctr_SW5e_z-3", "refctr_SW5e_z-4", - "refctr_W1a_z-1", "refctr_W1a_z-2", "refctr_W1a_z-3", "refctr_W1a_z-4", - "refctr_W1b_z-1", "refctr_W1b_z-2", "refctr_W1b_z-3", "refctr_W1b_z-4", - "refctr_W1c_z-1", "refctr_W1c_z-2", "refctr_W1c_z-3", "refctr_W1c_z-4", - "refctr_W1d_z-1", "refctr_W1d_z-2", "refctr_W1d_z-3", "refctr_W1d_z-4", - "refctr_W1e_z-1", "refctr_W1e_z-2", "refctr_W1e_z-3", "refctr_W1e_z-4", - "refctr_W2a_z-1", "refctr_W2a_z-2", "refctr_W2a_z-3", "refctr_W2a_z-4", - "refctr_W2b_z-1", "refctr_W2b_z-2", "refctr_W2b_z-3", "refctr_W2b_z-4", - "refctr_W2c_z-1", "refctr_W2c_z-2", "refctr_W2c_z-3", "refctr_W2c_z-4", - "refctr_W2d_z-1", "refctr_W2d_z-2", "refctr_W2d_z-3", "refctr_W2d_z-4", - "refctr_W2e_z-1", "refctr_W2e_z-2", "refctr_W2e_z-3", "refctr_W2e_z-4", - "refctr_W3a_z-1", "refctr_W3a_z-2", "refctr_W3a_z-3", "refctr_W3a_z-4", - "refctr_W3b_z-1", "refctr_W3b_z-2", "refctr_W3b_z-3", "refctr_W3b_z-4", - "refctr_W3c_z-1", "refctr_W3c_z-2", "refctr_W3c_z-3", "refctr_W3c_z-4", - "refctr_W3d_z-1", "refctr_W3d_z-2", "refctr_W3d_z-3", "refctr_W3d_z-4", - "refctr_W3e_z-1", "refctr_W3e_z-2", "refctr_W3e_z-3", "refctr_W3e_z-4", - "refctr_W4a_z-1", "refctr_W4a_z-2", "refctr_W4a_z-3", "refctr_W4a_z-4", - "refctr_W4b_z-1", "refctr_W4b_z-2", "refctr_W4b_z-3", "refctr_W4b_z-4", - "refctr_W4c_z-1", "refctr_W4c_z-2", "refctr_W4c_z-3", "refctr_W4c_z-4", - "refctr_W4d_z-1", "refctr_W4d_z-2", "refctr_W4d_z-3", "refctr_W4d_z-4", - "refctr_W4e_z-1", "refctr_W4e_z-2", "refctr_W4e_z-3", "refctr_W4e_z-4", - "refctr_W5a_z-1", "refctr_W5a_z-2", "refctr_W5a_z-3", "refctr_W5a_z-4", - "refctr_W5b_z-1", "refctr_W5b_z-2", "refctr_W5b_z-3", "refctr_W5b_z-4", - "refctr_W5c_z-1", "refctr_W5c_z-2", "refctr_W5c_z-3", "refctr_W5c_z-4", - "refctr_W5d_z-1", "refctr_W5d_z-2", "refctr_W5d_z-3", "refctr_W5d_z-4", - "refctr_W5e_z-1", "refctr_W5e_z-2", "refctr_W5e_z-3", "refctr_W5e_z-4" diff --git a/data/json/overmap/overmap_terrain/overmap_terrain_lab.json b/data/json/overmap/overmap_terrain/overmap_terrain_lab.json index b0ff4dde7a1ad..57d9b86574c61 100644 --- a/data/json/overmap/overmap_terrain/overmap_terrain_lab.json +++ b/data/json/overmap/overmap_terrain/overmap_terrain_lab.json @@ -276,9 +276,9 @@ "lab_surface_brick_basementE3", "lab_surface_brick_basementE4" ], - "name": "solid rock", - "sym": "%", - "color": "dark_gray", + "name": "solid earth", + "sym": "#", + "color": "brown", "see_cost": 5 }, { diff --git a/data/json/overmap/overmap_terrain/overmap_terrain_necropolis.json b/data/json/overmap/overmap_terrain/overmap_terrain_necropolis.json index a35ab83f79ca7..acbaaccb2315e 100644 --- a/data/json/overmap/overmap_terrain/overmap_terrain_necropolis.json +++ b/data/json/overmap/overmap_terrain/overmap_terrain_necropolis.json @@ -352,7 +352,17 @@ "necropolis_b_76", "necropolis_b_80", "necropolis_b_81", - "necropolis_b_9", + "necropolis_b_9" + ], + "copy-from": "generic_necropolis_underground", + "name": "solid earth", + "sym": "#", + "color": "brown" + }, + { + "//": "xxx Bookmark for necropolis sewers", + "type": "overmap_terrain", + "id": [ "necropolis_c_19", "necropolis_c_46", "necropolis_c_55", diff --git a/data/json/overmap/special_locations.json b/data/json/overmap/special_locations.json index 39efb21801aea..9d9bfecd9ed08 100644 --- a/data/json/overmap/special_locations.json +++ b/data/json/overmap/special_locations.json @@ -63,7 +63,7 @@ { "type": "overmap_location", "id": "subterranean", - "terrains": [ "cavern", "empty_rock", "rock", "slimepit", "sewer" ] + "terrains": [ "cavern", "empty_rock", "rock", "slimepit", "sewer", "solid_earth" ] }, { "type": "overmap_location", diff --git a/data/json/regional_map_settings.json b/data/json/regional_map_settings.json index 645c78f69b909..8f76f1e4ecf9a 100644 --- a/data/json/regional_map_settings.json +++ b/data/json/regional_map_settings.json @@ -2,7 +2,29 @@ { "type": "region_settings", "id": "default", - "default_oter": "field", + "default_oter": [ + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "field", + "solid_earth", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock" + ], "default_groundcover": [ [ "t_region_groundcover", 1 ] ], "region_terrain_and_furniture": { "terrain": { diff --git a/data/json/test_regions.json b/data/json/test_regions.json index f2b9e756918a1..ecf4fbfda8bca 100644 --- a/data/json/test_regions.json +++ b/data/json/test_regions.json @@ -2,7 +2,29 @@ { "type": "region_settings", "id": "desert_test", - "default_oter": "field", + "default_oter": [ + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "field", + "solid_earth", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock" + ], "default_groundcover": [ [ "t_region_groundcover", 1 ] ], "region_terrain_and_furniture": { "terrain": { @@ -260,6 +282,29 @@ }, { "type": "region_settings", - "id": "river" + "id": "river", + "default_oter": [ + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "field", + "solid_earth", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock" + ] } ] diff --git a/data/mods/aftershock_exoplanet/region_settings.json b/data/mods/aftershock_exoplanet/region_settings.json index 0bdd0d4dab127..9e5ab9838a179 100644 --- a/data/mods/aftershock_exoplanet/region_settings.json +++ b/data/mods/aftershock_exoplanet/region_settings.json @@ -8,7 +8,29 @@ "clear_whitelist": false, "whitelist": [ ] }, - "default_oter": "field", + "default_oter": [ + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "field", + "solid_earth", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock" + ], "default_groundcover": [ [ "t_region_groundcover", 1 ] ], "river_scale": 0, "city": { diff --git a/data/mods/desert_region/desert_regional_map_settings.json b/data/mods/desert_region/desert_regional_map_settings.json index 3a054d8fc46ee..86f57f60acb44 100644 --- a/data/mods/desert_region/desert_regional_map_settings.json +++ b/data/mods/desert_region/desert_regional_map_settings.json @@ -2,7 +2,29 @@ { "type": "region_settings", "id": "default", - "default_oter": "desert", + "default_oter": [ + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "field", + "solid_earth", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock" + ], "default_groundcover": [ [ "t_region_groundcover", 1 ] ], "region_terrain_and_furniture": { "terrain": { diff --git a/data/mods/rural_biome/rural_regional_map_settings.json b/data/mods/rural_biome/rural_regional_map_settings.json index c2492070f9be1..6f35908615b8a 100644 --- a/data/mods/rural_biome/rural_regional_map_settings.json +++ b/data/mods/rural_biome/rural_regional_map_settings.json @@ -2,7 +2,29 @@ { "type": "region_settings", "id": "default", - "default_oter": "field", + "default_oter": [ + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "open_air", + "field", + "solid_earth", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock", + "empty_rock" + ], "default_groundcover": [ [ "t_region_groundcover", 1 ] ], "region_terrain_and_furniture": { "terrain": { diff --git a/src/map.cpp b/src/map.cpp index 75646f0290f21..bc5a0ebd02c84 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -6884,6 +6884,8 @@ void map::loadn( const tripoint &grid, const bool update_vehicles, bool _actuali // Cache empty overmap types static const oter_str_id rock( "empty_rock" ); static const oter_str_id air( "open_air" ); + static const oter_str_id earth( "solid_earth" ); + static const ter_str_id t_soil( "t_soil" ); dbg( D_INFO ) << "map::loadn(game[" << g.get() << "], worldx[" << abs_sub.x << "], worldy[" << abs_sub.y << "], grid " << grid << ")"; @@ -6915,6 +6917,8 @@ void map::loadn( const tripoint &grid, const bool update_vehicles, bool _actuali generate_uniform( grid_abs_sub_rounded, t_open_air ); } else if( terrain_type == rock ) { generate_uniform( grid_abs_sub_rounded, t_rock ); + } else if( terrain_type == earth ) { + generate_uniform( grid_abs_sub_rounded, t_soil ); } else { tinymap tmp_map; tmp_map.generate( grid_abs_sub_rounded, calendar::turn ); diff --git a/src/mapgen.cpp b/src/mapgen.cpp index ea4de782eddf7..22a2f854dabd0 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -4622,6 +4622,9 @@ void map::draw_slimepit( const mapgendata &dat ) case 4: ter_set( point( SEEX * 2 - rng( 1, 3 ), SEEY * 2 - rng( 1, 3 ) ), t_slope_up ); } + } else if( dat.above() == "slimepit_bottom" ) { + // Align the stairs + ter_set( point( 7, 9 ), t_slope_up ); } place_spawns( GROUP_SLIME, 1, point( SEEX, SEEY ), point( SEEX, SEEY ), 0.15 ); place_items( item_group_id( "sewer" ), 40, point_zero, point( EAST_EDGE, SOUTH_EDGE ), true, @@ -4745,7 +4748,7 @@ void map::draw_connections( const mapgendata &dat ) } else if( is_ot_match( "ants", terrain_type, ot_match_type::type ) ) { if( dat.above() == "anthill" ) { if( const auto p = random_point( *this, [this]( const tripoint & n ) { - return ter( n ) == t_rock_floor; + return ter( n ) == t_dirt; } ) ) { ter_set( *p, t_slope_up ); } diff --git a/src/mapgen_functions.cpp b/src/mapgen_functions.cpp index a2fc728ac5a8d..f6390f6226c2e 100644 --- a/src/mapgen_functions.cpp +++ b/src/mapgen_functions.cpp @@ -1395,11 +1395,12 @@ void mapgen_subway( mapgendata &dat ) void mapgen_sewer_straight( mapgendata &dat ) { + static const ter_str_id t_soil( "t_soil" ); map *const m = &dat.m; for( int i = 0; i < SEEX * 2; i++ ) { for( int j = 0; j < SEEY * 2; j++ ) { if( i < SEEX - 2 || i > SEEX + 1 ) { - m->ter_set( point( i, j ), t_rock ); + m->ter_set( point( i, j ), t_soil ); } else { m->ter_set( point( i, j ), t_sewage ); } @@ -1414,11 +1415,12 @@ void mapgen_sewer_straight( mapgendata &dat ) void mapgen_sewer_curved( mapgendata &dat ) { + static const ter_str_id t_soil( "t_soil" ); map *const m = &dat.m; for( int i = 0; i < SEEX * 2; i++ ) { for( int j = 0; j < SEEY * 2; j++ ) { if( ( i > SEEX + 1 && j < SEEY - 2 ) || i < SEEX - 2 || j > SEEY + 1 ) { - m->ter_set( point( i, j ), t_rock ); + m->ter_set( point( i, j ), t_soil ); } else { m->ter_set( point( i, j ), t_sewage ); } @@ -1439,11 +1441,12 @@ void mapgen_sewer_curved( mapgendata &dat ) void mapgen_sewer_tee( mapgendata &dat ) { + static const ter_str_id t_soil( "t_soil" ); map *const m = &dat.m; for( int i = 0; i < SEEX * 2; i++ ) { for( int j = 0; j < SEEY * 2; j++ ) { if( i < SEEX - 2 || ( i > SEEX + 1 && ( j < SEEY - 2 || j > SEEY + 1 ) ) ) { - m->ter_set( point( i, j ), t_rock ); + m->ter_set( point( i, j ), t_soil ); } else { m->ter_set( point( i, j ), t_sewage ); } @@ -1464,12 +1467,13 @@ void mapgen_sewer_tee( mapgendata &dat ) void mapgen_sewer_four_way( mapgendata &dat ) { + static const ter_str_id t_soil( "t_soil" ); map *const m = &dat.m; int rn = rng( 0, 3 ); for( int i = 0; i < SEEX * 2; i++ ) { for( int j = 0; j < SEEY * 2; j++ ) { if( ( i < SEEX - 2 || i > SEEX + 1 ) && ( j < SEEY - 2 || j > SEEY + 1 ) ) { - m->ter_set( point( i, j ), t_rock ); + m->ter_set( point( i, j ), t_soil ); } else { m->ter_set( point( i, j ), t_sewage ); } @@ -2248,25 +2252,26 @@ void mapgen_hellmouth( mapgendata &dat ) void mapgen_ants_curved( mapgendata &dat ) { + static const ter_str_id t_soil( "t_soil" ); map *const m = &dat.m; point p( SEEX, 1 ); int rn = 0; // First, set it all to rock - fill_background( m, t_rock ); + fill_background( m, t_soil ); for( int i = SEEX - 2; i <= SEEX + 3; i++ ) { - m->ter_set( point( i, 0 ), t_rock_floor ); - m->ter_set( point( i, 1 ), t_rock_floor ); - m->ter_set( point( i, 2 ), t_rock_floor ); - m->ter_set( point( SEEX * 2 - 1, i ), t_rock_floor ); - m->ter_set( point( SEEX * 2 - 2, i ), t_rock_floor ); - m->ter_set( point( SEEX * 2 - 3, i ), t_rock_floor ); + m->ter_set( point( i, 0 ), t_dirt ); + m->ter_set( point( i, 1 ), t_dirt ); + m->ter_set( point( i, 2 ), t_dirt ); + m->ter_set( point( SEEX * 2 - 1, i ), t_dirt ); + m->ter_set( point( SEEX * 2 - 2, i ), t_dirt ); + m->ter_set( point( SEEX * 2 - 3, i ), t_dirt ); } do { for( int i = p.x - 2; i <= p.x + 3; i++ ) { for( int j = p.y - 2; j <= p.y + 3; j++ ) { if( i > 0 && i < SEEX * 2 - 1 && j > 0 && j < SEEY * 2 - 1 ) { - m->ter_set( point( i, j ), t_rock_floor ); + m->ter_set( point( i, j ), t_dirt ); } } } @@ -2288,7 +2293,7 @@ void mapgen_ants_curved( mapgendata &dat ) for( int i = p.x - 2; i <= p.x + 3; i++ ) { for( int j = p.y - 2; j <= p.y + 3; j++ ) { if( i > 0 && i < SEEX * 2 - 1 && j > 0 && j < SEEY * 2 - 1 ) { - m->ter_set( point( i, j ), t_rock_floor ); + m->ter_set( point( i, j ), t_dirt ); } } } @@ -2306,13 +2311,14 @@ void mapgen_ants_curved( mapgendata &dat ) void mapgen_ants_four_way( mapgendata &dat ) { + static const ter_str_id t_soil( "t_soil" ); map *const m = &dat.m; - fill_background( m, t_rock ); + fill_background( m, t_soil ); int x = SEEX; for( int j = 0; j < SEEY * 2; j++ ) { for( int i = x - 2; i <= x + 3; i++ ) { if( i >= 1 && i < SEEX * 2 - 1 ) { - m->ter_set( point( i, j ), t_rock_floor ); + m->ter_set( point( i, j ), t_dirt ); } } x += rng( -1, 1 ); @@ -2330,7 +2336,7 @@ void mapgen_ants_four_way( mapgendata &dat ) for( int i = 0; i < SEEX * 2; i++ ) { for( int j = y - 2; j <= y + 3; j++ ) { if( j >= 1 && j < SEEY * 2 - 1 ) { - m->ter_set( point( i, j ), t_rock_floor ); + m->ter_set( point( i, j ), t_dirt ); } } y += rng( -1, 1 ); @@ -2348,13 +2354,14 @@ void mapgen_ants_four_way( mapgendata &dat ) void mapgen_ants_straight( mapgendata &dat ) { + static const ter_str_id t_soil( "t_soil" ); map *const m = &dat.m; int x = SEEX; - fill_background( m, t_rock ); + fill_background( m, t_soil ); for( int j = 0; j < SEEY * 2; j++ ) { for( int i = x - 2; i <= x + 3; i++ ) { if( i >= 1 && i < SEEX * 2 - 1 ) { - m->ter_set( point( i, j ), t_rock_floor ); + m->ter_set( point( i, j ), t_dirt ); } } x += rng( -1, 1 ); @@ -2375,13 +2382,14 @@ void mapgen_ants_straight( mapgendata &dat ) void mapgen_ants_tee( mapgendata &dat ) { + static const ter_str_id t_soil( "t_soil" ); map *const m = &dat.m; - fill_background( m, t_rock ); + fill_background( m, t_soil ); int x = SEEX; for( int j = 0; j < SEEY * 2; j++ ) { for( int i = x - 2; i <= x + 3; i++ ) { if( i >= 1 && i < SEEX * 2 - 1 ) { - m->ter_set( point( i, j ), t_rock_floor ); + m->ter_set( point( i, j ), t_dirt ); } } x += rng( -1, 1 ); @@ -2398,7 +2406,7 @@ void mapgen_ants_tee( mapgendata &dat ) for( int i = SEEX; i < SEEX * 2; i++ ) { for( int j = y - 2; j <= y + 3; j++ ) { if( j >= 1 && j < SEEY * 2 - 1 ) { - m->ter_set( point( i, j ), t_rock_floor ); + m->ter_set( point( i, j ), t_dirt ); } } y += rng( -1, 1 ); @@ -2425,14 +2433,15 @@ void mapgen_ants_tee( mapgendata &dat ) static void mapgen_ants_generic( mapgendata &dat ) { + static const ter_str_id t_soil( "t_soil" ); map *const m = &dat.m; for( int i = 0; i < SEEX * 2; i++ ) { for( int j = 0; j < SEEY * 2; j++ ) { if( i < SEEX - 4 || i > SEEX + 5 || j < SEEY - 4 || j > SEEY + 5 ) { - m->ter_set( point( i, j ), t_rock ); + m->ter_set( point( i, j ), t_soil ); } else { - m->ter_set( point( i, j ), t_rock_floor ); + m->ter_set( point( i, j ), t_dirt ); } } } @@ -2443,11 +2452,11 @@ static void mapgen_ants_generic( mapgendata &dat ) do { p.x = rng( 1 + cw, SEEX * 2 - 2 - cw ); p.y = rng( 1 + cw, SEEY * 2 - 2 - cw ); - } while( m->ter( p ) == t_rock ); + } while( m->ter( p ) == t_soil ); for( int i = p.x - cw; i <= p.x + cw; i++ ) { for( int j = p.y - cw; j <= p.y + cw; j++ ) { if( trig_dist( p, point( i, j ) ) <= cw ) { - m->ter_set( point( i, j ), t_rock_floor ); + m->ter_set( point( i, j ), t_dirt ); } } } @@ -2456,7 +2465,7 @@ static void mapgen_ants_generic( mapgendata &dat ) is_ot_match( "ants_lab", dat.north(), ot_match_type::contains ) ) { for( int i = SEEX - 2; i <= SEEX + 3; i++ ) { for( int j = 0; j <= SEEY; j++ ) { - m->ter_set( point( i, j ), t_rock_floor ); + m->ter_set( point( i, j ), t_dirt ); } } } @@ -2464,7 +2473,7 @@ static void mapgen_ants_generic( mapgendata &dat ) is_ot_match( "ants_lab", dat.east(), ot_match_type::contains ) ) { for( int i = SEEX; i <= SEEX * 2 - 1; i++ ) { for( int j = SEEY - 2; j <= SEEY + 3; j++ ) { - m->ter_set( point( i, j ), t_rock_floor ); + m->ter_set( point( i, j ), t_dirt ); } } } @@ -2472,7 +2481,7 @@ static void mapgen_ants_generic( mapgendata &dat ) is_ot_match( "ants_lab", dat.south(), ot_match_type::contains ) ) { for( int i = SEEX - 2; i <= SEEX + 3; i++ ) { for( int j = SEEY; j <= SEEY * 2 - 1; j++ ) { - m->ter_set( point( i, j ), t_rock_floor ); + m->ter_set( point( i, j ), t_dirt ); } } } @@ -2480,7 +2489,7 @@ static void mapgen_ants_generic( mapgendata &dat ) is_ot_match( "ants_lab", dat.west(), ot_match_type::contains ) ) { for( int i = 0; i <= SEEX; i++ ) { for( int j = SEEY - 2; j <= SEEY + 3; j++ ) { - m->ter_set( point( i, j ), t_rock_floor ); + m->ter_set( point( i, j ), t_dirt ); } } } diff --git a/src/overmap.cpp b/src/overmap.cpp index c8c4b8c2aeb67..2c55fc4a85765 100644 --- a/src/overmap.cpp +++ b/src/overmap.cpp @@ -1091,15 +1091,7 @@ void overmap::populate() oter_id overmap::get_default_terrain( int z ) const { - if( z == 0 ) { - return settings.default_oter.id(); - } else { - // // TODO: Get rid of the hard-coded ids. - static const oter_str_id open_air( "open_air" ); - static const oter_str_id empty_rock( "empty_rock" ); - - return z > 0 ? open_air.id() : empty_rock.id(); - } + return settings.default_oter[OVERMAP_DEPTH + z].id(); } void overmap::init_layers() @@ -1499,9 +1491,9 @@ bool overmap::generate_sub( const int z ) std::vector central_lab_train_points; std::vector mine_points; // These are so common that it's worth checking first as int. - const oter_id skip_above[5] = { + const oter_id skip_above[6] = { oter_id( "empty_rock" ), oter_id( "forest" ), oter_id( "field" ), - oter_id( "forest_thick" ), oter_id( "forest_water" ) + oter_id( "forest_thick" ), oter_id( "forest_water" ), oter_id( "solid_earth" ) }; for( int i = 0; i < OMAPX; i++ ) { @@ -1544,7 +1536,7 @@ bool overmap::generate_sub( const int z ) } else if( oter_above == "anthill" || oter_above == "acid_anthill" ) { const int size = rng( MIN_ANT_SIZE, MAX_ANT_SIZE ); ant_points.emplace_back( p.xy(), size ); - } else if( oter_above == "slimepit_down" ) { + } else if( oter_above == "slimepit_down" || oter_above == "slimepit_bottom" ) { const int size = rng( MIN_GOO_SIZE, MAX_GOO_SIZE ); goo_points.emplace_back( p.xy(), size ); } else if( oter_above == "forest_water" ) { @@ -1638,12 +1630,19 @@ bool overmap::generate_sub( const int z ) // mark tile to prevent subway gen ter_set( nearby_loc, oter_id( "open_air" ) ); } + if( is_ot_match( "solid_earth", ter( nearby_loc ), ot_match_type::contains ) ) { + // mark tile to prevent subway gen + ter_set( nearby_loc, oter_id( "field" ) ); + } } } else { // change train connection point back to rock to allow gen if( is_ot_match( "open_air", ter( i ), ot_match_type::contains ) ) { ter_set( i, oter_id( "empty_rock" ) ); } + if( is_ot_match( "field", ter( i ), ot_match_type::contains ) ) { + ter_set( i, oter_id( "solid_earth" ) ); + } real_train_points.push_back( i.xy() ); } is_first_in_pair = !is_first_in_pair; @@ -1695,6 +1694,10 @@ bool overmap::generate_sub( const int z ) ot_match_type::contains ) ) { // clear marked ter_set( subway_loc, oter_id( "empty_rock" ) ); + } else if( is_ot_match( "field", ter( subway_loc ), + ot_match_type::contains ) ) { + // clear marked + ter_set( subway_loc, oter_id( "solid_earth" ) ); } } } @@ -1725,7 +1728,7 @@ bool overmap::generate_sub( const int z ) for( auto &i : ant_points ) { const tripoint_om_omt p_loc( i.pos, z ); - if( ter( p_loc ) != "empty_rock" ) { + if( ter( p_loc ) != "empty_rock" && ter( p_loc ) != "solid_earth" ) { continue; } mongroup_id ant_group( ter( p_loc + tripoint_above ) == "anthill" ? @@ -1747,7 +1750,7 @@ bool overmap::generate_over( const int z ) // These are so common that it's worth checking first as int. const std::set skip_below = { oter_id( "empty_rock" ), oter_id( "forest" ), oter_id( "field" ), - oter_id( "forest_thick" ), oter_id( "forest_water" ) + oter_id( "forest_thick" ), oter_id( "forest_water" ), oter_id( "solid_earth" ) }; if( z == 1 ) { @@ -2337,7 +2340,7 @@ void overmap::place_forest_trailheads() void overmap::place_forests() { - const oter_id default_oter_id( settings.default_oter ); + const oter_id default_oter_id( settings.default_oter[OVERMAP_DEPTH] ); const oter_id forest( "forest" ); const oter_id forest_thick( "forest_thick" ); @@ -2948,7 +2951,7 @@ void overmap::place_cities() point_om_omt c( rng( size - 1, OMAPX - size ), rng( size - 1, OMAPY - size ) ); const tripoint_om_omt p( c, 0 ); - if( ter( p ) == settings.default_oter ) { + if( ter( p ) == settings.default_oter[OVERMAP_DEPTH] ) { placement_attempts = 0; ter_set( p, oter_id( "road_nesw" ) ); // every city starts with an intersection city tmp; @@ -3316,7 +3319,8 @@ void overmap::build_tunnel( const tripoint_om_omt &p, int s, om_direction::type if( check_ot( "ants", ot_match_type::type, p ) ) { return; } - if( !is_ot_match( "empty_rock", ter( p ), ot_match_type::type ) ) { + if( !is_ot_match( "empty_rock", ter( p ), ot_match_type::type ) && + !is_ot_match( "solid_earth", ter( p ), ot_match_type::type ) ) { return; } } @@ -3327,8 +3331,9 @@ void overmap::build_tunnel( const tripoint_om_omt &p, int s, om_direction::type valid.reserve( om_direction::size ); for( om_direction::type r : om_direction::all ) { const tripoint_om_omt cand = p + om_direction::displace( r ); - if( !check_ot( "ants", ot_match_type::type, cand ) && - is_ot_match( "empty_rock", ter( cand ), ot_match_type::type ) ) { + if( !check_ot( "ants", ot_match_type::type, cand ) && ( + is_ot_match( "empty_rock", ter( cand ), ot_match_type::type ) || + is_ot_match( "solid_earth", ter( cand ), ot_match_type::type ) ) ) { valid.push_back( r ); } } diff --git a/src/regional_settings.cpp b/src/regional_settings.cpp index 39a7ad0f6a855..eb7902ae1440c 100644 --- a/src/regional_settings.cpp +++ b/src/regional_settings.cpp @@ -9,6 +9,7 @@ #include "debug.h" #include "enum_conversions.h" +#include "generic_factory.h" #include "json.h" #include "options.h" #include "output.h" @@ -436,9 +437,9 @@ void load_region_settings( const JsonObject &jo ) jo.throw_error( "No 'id' field." ); } bool strict = new_region.id == "default"; - if( !jo.read( "default_oter", new_region.default_oter ) && strict ) { - jo.throw_error( "default_oter required for default ( though it should probably remain 'field' )" ); - } + mandatory( jo, false, "default_oter", new_region.default_oter ); + // So the data definition goes from z = OVERMAP_HEIGHT to z = OVERMAP_DEPTH + std::reverse( new_region.default_oter.begin(), new_region.default_oter.end() ); if( !jo.read( "river_scale", new_region.river_scale ) && strict ) { jo.throw_error( "river_scale required for default" ); } diff --git a/src/regional_settings.h b/src/regional_settings.h index 9335ff13f3760..e3dcd29015d04 100644 --- a/src/regional_settings.h +++ b/src/regional_settings.h @@ -238,7 +238,7 @@ struct region_terrain_and_furniture_settings { */ struct regional_settings { std::string id; // - oter_str_id default_oter; // 'field' + std::array default_oter; double river_scale = 1; weighted_int_list default_groundcover; // i.e., 'grass_or_dirt' shared_ptr_fast> default_groundcover_str; @@ -256,7 +256,7 @@ struct regional_settings { std::unordered_map region_extras; - regional_settings() : id( "null" ), default_oter( "field" ) { + regional_settings() : id( "null" ) { default_groundcover.add( t_null, 0 ); } void finalize(); From 76e3b05be0b409412760dc77653c8da43399c602 Mon Sep 17 00:00:00 2001 From: UmbralReaper <67179462+UmbralReaper@users.noreply.github.com> Date: Thu, 8 Jul 2021 10:56:45 +1000 Subject: [PATCH 059/116] Change copper wire to a standard size, and add wire drawing. (#48127) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Increase weight and decrease volume of copper wire. * Add manual wire drawing as an option. * Change scrap_copper and copper to more appropriate values and handle the fallout. * scrap_copper is now 50ml instead of 62. Drop rates have been increased to accommodate. * scrap_copper now requires 50 copper instead of 25. * copper_wire, copper_rod, and cable weight and volume fine-tuned. * Obsolete previous cable recipe. Co-authored-by: Jianxiang Wang (王健翔) Co-authored-by: Kevin Granade --- .../furniture-alien.json | 22 +++--- .../furniture-industrial.json | 2 +- .../Locations_MapExtras/locations.json | 2 +- data/json/itemgroups/supplies.json | 4 +- data/json/itemgroups/trash_and_debris.json | 2 +- data/json/items/ammo.json | 25 ++++++- data/json/items/resources/metal.json | 23 ++++++- data/json/items/tool/metalworking.json | 15 ++++ data/json/items/tool/workshop.json | 25 +++++++ data/json/obsolete.json | 21 ++++++ data/json/proficiencies/metalwork.json | 11 +++ data/json/recipes/other/materials.json | 2 +- data/json/recipes/other/parts.json | 68 ++++++++++++++++--- .../recipes/other/parts_construction.json | 2 +- data/json/recipes/recipe_deconstruction.json | 6 +- data/json/recipes/recipe_others.json | 4 +- data/json/recipes/tools/tool.json | 2 +- data/json/recipes/tools/tools_electronic.json | 23 +++++++ data/json/recipes/tools/tools_hand.json | 13 ++++ data/json/recipes/tools/tools_primitive.json | 2 +- data/json/recipes/weapon/piercing.json | 6 +- data/json/requirements/materials.json | 2 +- 22 files changed, 237 insertions(+), 45 deletions(-) diff --git a/data/json/furniture_and_terrain/furniture-alien.json b/data/json/furniture_and_terrain/furniture-alien.json index 6a011c4bee988..318fde46c74ae 100644 --- a/data/json/furniture_and_terrain/furniture-alien.json +++ b/data/json/furniture_and_terrain/furniture-alien.json @@ -187,7 +187,7 @@ { "item": "exodii_module", "count": [ 0, 1 ] }, { "item": "exodii_motor", "count": [ 0, 1 ] }, { "item": "cable", "charges": [ 0, 2 ] }, - { "item": "scrap_copper", "count": [ 2, 10 ] } + { "item": "scrap_copper", "count": [ 2, 12 ] } ] } }, @@ -216,7 +216,7 @@ { "item": "sheet_metal_small", "count": [ 20, 30 ] }, { "item": "exodii_chassis", "count": [ 0, 1 ] }, { "item": "exodii_drone_chassis", "count": [ 0, 1 ] }, - { "item": "scrap_copper", "count": [ 5, 20 ] }, + { "item": "scrap_copper", "count": [ 6, 25 ] }, { "item": "e_scrap", "count": [ 5, 20 ] } ] } @@ -241,7 +241,7 @@ { "item": "scrap", "count": [ 8, 12 ] }, { "item": "pipe", "count": [ 0, 3 ] }, { "item": "sheet_metal_small", "count": [ 2, 10 ] }, - { "item": "scrap_copper", "count": [ 2, 10 ] }, + { "item": "scrap_copper", "count": [ 2, 12 ] }, { "item": "exodii_computer", "count": [ 0, 1 ] }, { "item": "exodii_motor", "count": [ 0, 1 ] }, { "item": "cable", "charges": [ 0, 3 ] }, @@ -270,7 +270,7 @@ { "item": "scrap", "count": [ 8, 12 ] }, { "item": "pipe", "count": [ 0, 3 ] }, { "item": "sheet_metal_small", "count": [ 2, 10 ] }, - { "item": "scrap_copper", "count": [ 2, 10 ] }, + { "item": "scrap_copper", "count": [ 2, 12 ] }, { "item": "amplifier", "count": [ 0, 5 ] }, { "item": "power_supply", "count": [ 0, 1 ] }, { "item": "cable", "charges": [ 0, 5 ] } @@ -298,7 +298,7 @@ { "item": "pipe", "count": [ 2, 4 ] }, { "item": "55gal_drum", "count": [ 0, 1 ] }, { "item": "sheet_metal_small", "count": [ 2, 10 ] }, - { "item": "scrap_copper", "count": [ 5, 10 ] }, + { "item": "scrap_copper", "count": [ 5, 12 ] }, { "item": "exodii_module", "count": [ 0, 1 ] }, { "item": "exodii_motor", "count": [ 0, 2 ] }, { "item": "pipe_fittings", "count": [ 2, 6 ] } @@ -325,7 +325,7 @@ { "item": "scrap", "count": [ 20, 120 ] }, { "item": "pipe", "count": [ 20, 40 ] }, { "item": "sheet_metal_small", "count": [ 20, 100 ] }, - { "item": "scrap_copper", "count": [ 50, 100 ] }, + { "item": "scrap_copper", "count": [ 62, 124 ] }, { "item": "pipe_fittings", "count": [ 2, 6 ] }, { "item": "exodii_module", "count": [ 0, 6 ] }, { "item": "exodii_motor", "count": [ 0, 8 ] }, @@ -354,7 +354,7 @@ { "item": "pipe", "count": [ 10, 20 ] }, { "item": "pipe_fittings", "count": [ 2, 4 ] }, { "item": "sheet_metal_small", "count": [ 10, 30 ] }, - { "item": "scrap_copper", "count": [ 20, 40 ] }, + { "item": "scrap_copper", "count": [ 25, 62 ] }, { "item": "e_scrap", "count": [ 20, 40 ] }, { "item": "exodii_module", "count": [ 0, 5 ] }, { "item": "exodii_motor", "count": [ 0, 6 ] }, @@ -385,7 +385,7 @@ { "item": "plutonium", "charges": [ 0, 3 ] }, { "item": "lead", "charges": [ 12, 18 ] }, { "item": "sheet_metal_small", "count": [ 10, 30 ] }, - { "item": "scrap_copper", "count": [ 20, 40 ] }, + { "item": "scrap_copper", "count": [ 25, 50 ] }, { "item": "e_scrap", "count": [ 20, 40 ] }, { "item": "circuit", "count": [ 6, 10 ] }, { "item": "power_supply", "count": [ 4, 8 ] }, @@ -419,7 +419,7 @@ { "item": "plutonium", "charges": [ 0, 3 ] }, { "item": "lead", "charges": [ 12, 18 ] }, { "item": "sheet_metal_small", "count": [ 10, 30 ] }, - { "item": "scrap_copper", "count": [ 20, 40 ] }, + { "item": "scrap_copper", "count": [ 25, 50 ] }, { "item": "e_scrap", "count": [ 20, 40 ] }, { "item": "circuit", "count": [ 6, 10 ] }, { "item": "power_supply", "count": [ 4, 8 ] }, @@ -455,7 +455,7 @@ { "item": "plutonium", "charges": [ 0, 3 ] }, { "item": "lead", "charges": [ 12, 18 ] }, { "item": "sheet_metal_small", "count": [ 10, 30 ] }, - { "item": "scrap_copper", "count": [ 10, 30 ] }, + { "item": "scrap_copper", "count": [ 12, 37 ] }, { "item": "e_scrap", "count": [ 10, 20 ] }, { "item": "circuit", "count": [ 2, 5 ] }, { "item": "power_supply", "count": [ 4, 8 ] }, @@ -489,7 +489,7 @@ { "item": "plutonium", "charges": [ 0, 3 ] }, { "item": "lead", "charges": [ 12, 18 ] }, { "item": "sheet_metal_small", "count": [ 10, 30 ] }, - { "item": "scrap_copper", "count": [ 10, 30 ] }, + { "item": "scrap_copper", "count": [ 12, 37 ] }, { "item": "e_scrap", "count": [ 15, 30 ] }, { "item": "circuit", "count": [ 2, 5 ] }, { "item": "power_supply", "count": [ 2, 8 ] }, diff --git a/data/json/furniture_and_terrain/furniture-industrial.json b/data/json/furniture_and_terrain/furniture-industrial.json index 3105557b6c242..12b0c39272053 100644 --- a/data/json/furniture_and_terrain/furniture-industrial.json +++ b/data/json/furniture_and_terrain/furniture-industrial.json @@ -457,7 +457,7 @@ "str_max": 100, "sound": "shred!", "sound_fail": "thud!", - "items": [ { "item": "scrap_copper", "count": [ 1, 4 ] }, { "item": "cable", "charges": [ 1, 4 ] } ] + "items": [ { "item": "scrap_copper", "count": [ 1, 5 ] }, { "item": "cable", "charges": [ 1, 4 ] } ] }, "deconstruct": { "items": [ { "item": "cable", "charges": [ 3, 4 ] } ] } }, diff --git a/data/json/itemgroups/Locations_MapExtras/locations.json b/data/json/itemgroups/Locations_MapExtras/locations.json index b255b6fa67157..277f463f73160 100644 --- a/data/json/itemgroups/Locations_MapExtras/locations.json +++ b/data/json/itemgroups/Locations_MapExtras/locations.json @@ -449,7 +449,7 @@ [ "frame", 20 ], [ "hdframe", 20 ], [ "cu_pipe", 25 ], - [ "scrap_copper", 50 ] + [ "scrap_copper", 62 ] ] }, { diff --git a/data/json/itemgroups/supplies.json b/data/json/itemgroups/supplies.json index c661f38ef0ad3..79c14f01ab9b7 100644 --- a/data/json/itemgroups/supplies.json +++ b/data/json/itemgroups/supplies.json @@ -147,7 +147,7 @@ [ "jerrycan", 10 ], [ "pump_complex", 10 ], [ "well_pump", 10 ], - { "item": "scrap_copper", "prob": 15, "count": [ 1, 10 ] }, + { "item": "scrap_copper", "prob": 15, "count": [ 1, 12 ] }, { "item": "plunger_toilet", "prob": 90, "count": [ 1, 2 ] }, [ "plunger_futuristic", 50 ] ] @@ -364,7 +364,7 @@ { "item": "copper", "prob": 10, "count": [ 1, 5 ] }, { "item": "tin", "prob": 10, "count": [ 1, 5 ] }, { "item": "material_aluminium_ingot", "prob": 10, "count": [ 1, 5 ] }, - { "item": "scrap_copper", "prob": 5, "count": [ 1, 10 ] }, + { "item": "scrap_copper", "prob": 5, "count": [ 1, 12 ] }, { "item": "wire", "prob": 5 }, { "item": "scrap", "prob": 70, "count": [ 1, 10 ] } ] diff --git a/data/json/itemgroups/trash_and_debris.json b/data/json/itemgroups/trash_and_debris.json index 7525c74127128..a270b7bba7ba8 100644 --- a/data/json/itemgroups/trash_and_debris.json +++ b/data/json/itemgroups/trash_and_debris.json @@ -10,7 +10,7 @@ [ "frame", 20 ], [ "hdframe", 20 ], [ "cu_pipe", 25 ], - [ "scrap_copper", 50 ], + [ "scrap_copper", 62 ], [ "rock", 40 ], [ "survnote", 1 ] ] diff --git a/data/json/items/ammo.json b/data/json/items/ammo.json index 4a29bca1d172a..54f02cd749a28 100644 --- a/data/json/items/ammo.json +++ b/data/json/items/ammo.json @@ -298,8 +298,26 @@ "color": "dark_gray", "description": "Plastic jacketed copper cable of the type used in small electronics.", "material": [ "plastic", "copper" ], - "volume": "750 ml", - "weight": "2 g", + "//": "Calculated off of copper wire with an extra 0.5mm of diameter and 0.66g.", + "volume": "155 ml", + "weight": "5413 mg", + "ammo_type": "components", + "count": 200 + }, + { + "type": "AMMO", + "id": "copper_wire", + "category": "spare_parts", + "price": 2000, + "price_postapoc": 100, + "name": { "str": "raw copper wire" }, + "symbol": "=", + "color": "dark_gray", + "description": "Copper wire ready to be covered with plastic.", + "material": [ "copper" ], + "//": "Calculated off of 12 AWG, at 10cm length, using http://www.mtlexs.com/technical-specifications-details/40/weight-of-copper-wire.", + "volume": "110 ml", + "weight": "4747 mg", "ammo_type": "components", "count": 200 }, @@ -792,8 +810,9 @@ "color": "yellow", "description": "Copper bits. Could be used to craft something, for example makeshift shotgun shells.", "material": [ "copper" ], + "//": "80% of 8.63g/ml is 6.904g/ml.", "volume": "250 ml", - "weight": "2 g", + "weight": "8630 mg", "ammo_type": "components", "count": 200 }, diff --git a/data/json/items/resources/metal.json b/data/json/items/resources/metal.json index a1496900e4f17..90d264cbc2e5c 100644 --- a/data/json/items/resources/metal.json +++ b/data/json/items/resources/metal.json @@ -304,8 +304,9 @@ "price": 1000, "price_postapoc": 10, "material": [ "copper" ], - "weight": "50 g", - "volume": "62 ml", + "//": "Density of 8.63g/cm³ = 431.5g/50ml ~ 432g", + "volume": "50 ml", + "weight": "432 g", "bashing": 1, "to_hit": -2 }, @@ -343,5 +344,23 @@ "//": "Density ~ 8g/cm³ ~ 2000kg/250ml @ stack 1000 = 2g/unit", "ammo_type": "components", "count": 200 + }, + { + "type": "AMMO", + "id": "copper_rod", + "category": "spare_parts", + "price": 2000, + "price_postapoc": 20, + "name": { "str": "copper rod" }, + "symbol": "=", + "color": "light_gray", + "description": "A thin copper rod, ready to be made into copper wire.", + "material": [ "copper" ], + "//": "9mm in diameter and 1.572m long.", + "volume": "100 ml", + "weight": "863 g", + "longest_side": "1572 mm", + "ammo_type": "components", + "count": 1 } ] diff --git a/data/json/items/tool/metalworking.json b/data/json/items/tool/metalworking.json index ecce3299045f6..94d1fe05522d4 100644 --- a/data/json/items/tool/metalworking.json +++ b/data/json/items/tool/metalworking.json @@ -294,5 +294,20 @@ "symbol": "`", "color": "brown", "qualities": [ [ "FILE", 1 ] ] + }, + { + "id": "draw_plate", + "type": "TOOL", + "name": { "str": "draw plate" }, + "description": "A piece of metal with holes of varying size drilled into it. Used as part of wire drawing.", + "weight": "200 g", + "volume": "250 ml", + "price": 1000, + "price_postapoc": 10, + "bashing": 5, + "to_hit": -3, + "material": [ "steel" ], + "symbol": "]", + "color": "light_cyan" } ] diff --git a/data/json/items/tool/workshop.json b/data/json/items/tool/workshop.json index ab57bf3547f9e..886538ce7ae0e 100644 --- a/data/json/items/tool/workshop.json +++ b/data/json/items/tool/workshop.json @@ -1267,5 +1267,30 @@ "color": "light_gray", "looks_like": "hand_drill", "qualities": [ [ "DRILL", 1 ] ] + }, + { + "id": "wire_draw_machine", + "type": "TOOL", + "name": { "str": "wire draw machine" }, + "description": "A machine designed specifically for turning metal rods into wire.", + "weight": "26 kg", + "volume": "20 L", + "price": 1000, + "price_postapoc": 10, + "to_hit": -3, + "bashing": 7, + "material": [ "steel" ], + "symbol": ";", + "color": "light_gray", + "pocket_data": [ + { + "pocket_type": "MAGAZINE_WELL", + "holster": true, + "magazine_well": "200 ml", + "max_contains_volume": "20 L", + "max_contains_weight": "20 kg", + "item_restriction": [ "medium_battery_cell", "medium_plus_battery_cell", "medium_atomic_battery_cell", "medium_disposable_cell" ] + } + ] } ] diff --git a/data/json/obsolete.json b/data/json/obsolete.json index b48c2ae8ed950..82c8646ae6964 100644 --- a/data/json/obsolete.json +++ b/data/json/obsolete.json @@ -1526,5 +1526,26 @@ "price": 10000, "weight": "3000 g", "difficulty": 4 + }, + { + "type": "recipe", + "activity_level": "MODERATE_EXERCISE", + "result": "cable", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_COMPONENTS", + "skill_used": "fabrication", + "skills_required": [ "electronics", 2 ], + "difficulty": 5, + "time": "3 m", + "autolearn": true, + "charges": 1, + "qualities": [ + { "id": "ANVIL", "level": 1 }, + { "id": "HAMMER", "level": 2 }, + { "id": "CHISEL", "level": 3 }, + { "id": "CUT", "level": 1 } + ], + "tools": [ [ [ "tongs", -1 ] ], [ [ "swage", -1 ] ], [ [ "surface_heat", 1, "LIST" ], [ "forge", 1 ], [ "oxy_torch", 1 ] ] ], + "components": [ [ [ "copper", 1 ] ], [ [ "duct_tape", 1 ] ] ] } ] diff --git a/data/json/proficiencies/metalwork.json b/data/json/proficiencies/metalwork.json index e4f191756a178..1706c23d2a1ef 100644 --- a/data/json/proficiencies/metalwork.json +++ b/data/json/proficiencies/metalwork.json @@ -95,5 +95,16 @@ "default_fail_multiplier": 1.15, "time_to_learn": "10 h", "required_proficiencies": [ "prof_blacksmithing" ] + }, + { + "type": "proficiency", + "id": "prof_wiremaking", + "name": { "str": "Wire Making" }, + "description": "How to turn raw ingots and metals into usable wire. Includes both drawing and extruding.", + "can_learn": true, + "default_time_multiplier": 2, + "default_fail_multiplier": 1.5, + "time_to_learn": "10 h", + "required_proficiencies": [ "prof_metalworking" ] } ] diff --git a/data/json/recipes/other/materials.json b/data/json/recipes/other/materials.json index 122dcebce58b4..698c70b13c16b 100644 --- a/data/json/recipes/other/materials.json +++ b/data/json/recipes/other/materials.json @@ -88,7 +88,7 @@ "autolearn": true, "qualities": [ { "id": "HAMMER", "level": 1 } ], "tools": [ [ [ "surface_heat", 10, "LIST" ] ] ], - "components": [ [ [ "copper", 25 ] ] ] + "components": [ [ [ "copper", 50 ] ] ] }, { "type": "recipe", diff --git a/data/json/recipes/other/parts.json b/data/json/recipes/other/parts.json index e7e65b5de1f41..4379a003382f8 100644 --- a/data/json/recipes/other/parts.json +++ b/data/json/recipes/other/parts.json @@ -402,26 +402,72 @@ "qualities": [ { "id": "HAMMER", "level": 1 }, { "id": "SCREW", "level": 1 } ], "components": [ [ [ "e_scrap", 5 ] ], [ [ "cable", 6 ] ] ] }, + { + "type": "recipe", + "activity_level": "LIGHT_EXERCISE", + "result": "copper_rod", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_COMPONENTS", + "skill_used": "fabrication", + "difficulty": 4, + "time": "10 m", + "autolearn": true, + "charges": 1, + "qualities": [ { "id": "ANVIL", "level": 1 }, { "id": "HAMMER", "level": 2 }, { "id": "CHISEL", "level": 3 } ], + "proficiencies": [ { "proficiency": "prof_metalworking" }, { "proficiency": "prof_redsmithing" } ], + "tools": [ [ [ "tongs", -1 ] ], [ [ "swage", -1 ] ], [ [ "forge", 10 ], [ "oxy_torch", 10 ] ] ], + "components": [ [ [ "copper_scrap_equivalent", 2, "LIST" ] ] ] + }, { "type": "recipe", "activity_level": "MODERATE_EXERCISE", + "result": "copper_wire", + "id_suffix": "draw_plate", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_COMPONENTS", + "skill_used": "fabrication", + "difficulty": 3, + "time": "32 m", + "autolearn": true, + "charges": 182, + "qualities": [ { "id": "ANVIL", "level": 1 }, { "id": "HAMMER", "level": 2 } ], + "proficiencies": [ { "proficiency": "prof_metalworking" }, { "proficiency": "prof_wiremaking" } ], + "//": "Requires annealing 4 times from the copper rod.", + "tools": [ [ [ "tongs", -1 ] ], [ [ "swage", -1 ] ], [ [ "forge", 40 ], [ "oxy_torch", 40 ] ], [ [ "draw_plate", -1 ] ] ], + "components": [ [ [ "copper_rod", 1 ] ] ] + }, + { + "type": "recipe", + "activity_level": "LIGHT_EXERCISE", + "result": "copper_wire", + "id_suffix": "wire_draw_machine", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_COMPONENTS", + "skill_used": "fabrication", + "difficulty": 3, + "time": "20 m", + "autolearn": true, + "charges": 182, + "qualities": [ { "id": "ANVIL", "level": 1 }, { "id": "HAMMER", "level": 2 } ], + "proficiencies": [ { "proficiency": "prof_metalworking" } ], + "//": "Requires annealing 4 times from the copper rod.", + "tools": [ [ [ "tongs", -1 ] ], [ [ "swage", -1 ] ], [ [ "forge", 40 ], [ "oxy_torch", 40 ] ], [ [ "wire_draw_machine", 100 ] ] ], + "components": [ [ [ "copper_rod", 1 ] ] ] + }, + { + "type": "recipe", + "activity_level": "LIGHT_EXERCISE", "result": "cable", "category": "CC_ELECTRONIC", "subcategory": "CSC_ELECTRONIC_COMPONENTS", "skill_used": "fabrication", "skills_required": [ "electronics", 2 ], - "difficulty": 5, - "time": "3 m", + "difficulty": 2, + "time": "1 m", "autolearn": true, - "charges": 1, - "qualities": [ - { "id": "ANVIL", "level": 1 }, - { "id": "HAMMER", "level": 2 }, - { "id": "CHISEL", "level": 3 }, - { "id": "CUT", "level": 1 } - ], - "tools": [ [ [ "tongs", -1 ] ], [ [ "swage", -1 ] ], [ [ "surface_heat", 1, "LIST" ], [ "forge", 1 ], [ "oxy_torch", 1 ] ] ], - "components": [ [ [ "copper", 1 ] ], [ [ "duct_tape", 1 ] ] ] + "charges": 6, + "qualities": [ { "id": "CUT", "level": 1 } ], + "components": [ [ [ "copper_wire", 6 ] ], [ [ "duct_tape", 1 ] ] ] }, { "type": "recipe", diff --git a/data/json/recipes/other/parts_construction.json b/data/json/recipes/other/parts_construction.json index 4e3317164f099..ddc19c6c2f2d7 100644 --- a/data/json/recipes/other/parts_construction.json +++ b/data/json/recipes/other/parts_construction.json @@ -271,7 +271,7 @@ "qualities": [ { "id": "ANVIL", "level": 3 }, { "id": "HAMMER", "level": 3 }, { "id": "CHISEL", "level": 3 } ], "proficiencies": [ { "proficiency": "prof_metalworking" }, { "proficiency": "prof_redsmithing" } ], "tools": [ [ [ "tongs", -1 ] ], [ [ "swage", -1 ] ], [ [ "forge", 50 ], [ "oxy_torch", 10 ] ] ], - "components": [ [ [ "copper_scrap_equivalent", 7, "LIST" ] ] ] + "components": [ [ [ "copper_scrap_equivalent", 8, "LIST" ] ] ] }, { "type": "recipe", diff --git a/data/json/recipes/recipe_deconstruction.json b/data/json/recipes/recipe_deconstruction.json index ccd9c70416174..b49f8927b0b37 100644 --- a/data/json/recipes/recipe_deconstruction.json +++ b/data/json/recipes/recipe_deconstruction.json @@ -119,7 +119,7 @@ "difficulty": 1, "time": "2 m", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "scrap_copper", 10 ] ], [ [ "scrap", 3 ] ] ] + "components": [ [ [ "scrap_copper", 12 ] ], [ [ "scrap", 3 ] ] ] }, { "result": "copper_ring", @@ -3068,7 +3068,7 @@ "activity_level": "MODERATE_EXERCISE", "time": "5 m", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "copper_scrap_equivalent", 16, "LIST" ] ] ] + "components": [ [ [ "copper_scrap_equivalent", 20, "LIST" ] ] ] }, { "result": "potato_masher", @@ -3122,7 +3122,7 @@ "difficulty": 1, "time": "3 m", "qualities": [ { "id": "SAW_M", "level": 1 } ], - "components": [ [ [ "scrap_copper", 5 ] ], [ [ "scrap", 1 ] ] ] + "components": [ [ [ "scrap_copper", 6 ] ], [ [ "scrap", 1 ] ] ] }, { "result": "power_armor_basic", diff --git a/data/json/recipes/recipe_others.json b/data/json/recipes/recipe_others.json index 63ed887a8b44d..7686291b5158f 100644 --- a/data/json/recipes/recipe_others.json +++ b/data/json/recipes/recipe_others.json @@ -923,7 +923,7 @@ "autolearn": true, "qualities": [ { "id": "HAMMER", "level": 3 } ], "tools": [ [ [ "press", -1 ] ], [ [ "surface_heat", 10, "LIST" ] ] ], - "components": [ [ [ "copper_scrap_equivalent", 20, "LIST" ] ], [ [ "tin", 30 ] ] ] + "components": [ [ [ "copper_scrap_equivalent", 25, "LIST" ] ], [ [ "tin", 30 ] ] ] }, { "type": "recipe", @@ -940,7 +940,7 @@ "qualities": [ { "id": "HAMMER", "level": 3 } ], "tools": [ [ [ "electrolysis_kit", 10 ] ], [ [ "surface_heat", 10, "LIST" ] ] ], "components": [ - [ [ "copper_scrap_equivalent", 20, "LIST" ] ], + [ [ "copper_scrap_equivalent", 25, "LIST" ] ], [ [ "tin", 30 ] ], [ [ "water", 3 ], [ "water_clean", 3 ] ], [ [ "any_strong_acid", 1, "LIST" ] ] diff --git a/data/json/recipes/tools/tool.json b/data/json/recipes/tools/tool.json index c2868ae0620c0..bb9a5d2f7e290 100644 --- a/data/json/recipes/tools/tool.json +++ b/data/json/recipes/tools/tool.json @@ -646,7 +646,7 @@ "autolearn": true, "qualities": [ { "id": "HAMMER", "level": 2 } ], "tools": [ [ [ "surface_heat", 10, "LIST" ], [ "forge", 10 ], [ "oxy_torch", 2 ] ] ], - "components": [ [ [ "copper_scrap_equivalent", 16, "LIST" ] ] ] + "components": [ [ [ "copper_scrap_equivalent", 20, "LIST" ] ] ] }, { "type": "recipe", diff --git a/data/json/recipes/tools/tools_electronic.json b/data/json/recipes/tools/tools_electronic.json index a07d1367ad6ab..b5540559d46d5 100644 --- a/data/json/recipes/tools/tools_electronic.json +++ b/data/json/recipes/tools/tools_electronic.json @@ -736,5 +736,28 @@ [ [ "spring", 2 ] ], [ [ "radio_car_wheel", 1 ] ] ] + }, + { + "type": "recipe", + "activity_level": "LIGHT_EXERCISE", + "result": "wire_draw_machine", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_TOOLS", + "skill_used": "fabrication", + "skills_required": [ [ "mechanics", 2 ], [ "electronics", 1 ] ], + "difficulty": 4, + "time": "1 h", + "autolearn": true, + "using": [ [ "welding_standard", 10 ] ], + "qualities": [ { "id": "SAW_M", "level": 1 } ], + "proficiencies": [ { "proficiency": "prof_welding_basic" } ], + "components": [ + [ [ "motor_small", 1 ] ], + [ [ "jerrycan", 1 ] ], + [ [ "sheet_metal_small", 4 ] ], + [ [ "scrap", 5 ] ], + [ [ "draw_plate", 1 ] ], + [ [ "cable", 10 ] ] + ] } ] diff --git a/data/json/recipes/tools/tools_hand.json b/data/json/recipes/tools/tools_hand.json index a45caf4df5388..4ae6760552340 100644 --- a/data/json/recipes/tools/tools_hand.json +++ b/data/json/recipes/tools/tools_hand.json @@ -1101,5 +1101,18 @@ "proficiencies": [ { "proficiency": "prof_carving" } ], "qualities": [ { "id": "CUT", "level": 1 } ], "components": [ [ [ "2x4", 1 ] ] ] + }, + { + "type": "recipe", + "activity_level": "LIGHT_EXERCISE", + "result": "draw_plate", + "category": "CC_OTHER", + "subcategory": "CSC_OTHER_TOOLS", + "skill_used": "fabrication", + "difficulty": 2, + "time": "5 m", + "autolearn": true, + "tools": [ [ [ "cordless_drill", 20 ] ] ], + "components": [ [ [ "sheet_metal_small", 1 ] ] ] } ] diff --git a/data/json/recipes/tools/tools_primitive.json b/data/json/recipes/tools/tools_primitive.json index c1774b7b84c37..bfa3732aadfee 100644 --- a/data/json/recipes/tools/tools_primitive.json +++ b/data/json/recipes/tools/tools_primitive.json @@ -97,7 +97,7 @@ "proficiencies": [ { "proficiency": "prof_metalworking" }, { "proficiency": "prof_redsmithing" } ], "components": [ [ [ "stick", 1 ], [ "2x4", 1 ] ], - [ [ "copper_scrap_equivalent", 40, "LIST" ] ], + [ [ "copper_scrap_equivalent", 50, "LIST" ] ], [ [ "cordage_short", 2, "LIST" ], [ "filament", 100, "LIST" ], [ "duct_tape", 40 ] ] ] }, diff --git a/data/json/recipes/weapon/piercing.json b/data/json/recipes/weapon/piercing.json index e2f4d6d649448..d7349b8f74f86 100644 --- a/data/json/recipes/weapon/piercing.json +++ b/data/json/recipes/weapon/piercing.json @@ -363,7 +363,7 @@ "proficiencies": [ { "proficiency": "prof_metalworking" }, { "proficiency": "prof_redsmithing" } ], "components": [ [ [ "rag", 1 ], [ "felt_patch", 1 ], [ "duct_tape", 50 ], [ "cordage_short", 2, "LIST" ], [ "filament", 100, "LIST" ] ], - [ [ "copper_scrap_equivalent", 8, "LIST" ] ] + [ [ "copper_scrap_equivalent", 12, "LIST" ] ] ] }, { @@ -469,7 +469,7 @@ [ [ "long_pole", 1 ] ], [ [ "rag", 1 ], [ "felt_patch", 1 ], [ "leather", 1 ], [ "fur", 1 ] ], [ [ "duct_tape", 20 ], [ "cordage_short", 1, "LIST" ], [ "filament", 50, "LIST" ] ], - [ [ "copper_scrap_equivalent", 12, "LIST" ] ] + [ [ "copper_scrap_equivalent", 15, "LIST" ] ] ] }, { @@ -506,7 +506,7 @@ { "proficiency": "prof_redsmithing" }, { "proficiency": "prof_carving", "fail_multiplier": 1 } ], - "components": [ [ [ "stick_long", 1 ] ], [ [ "copper_scrap_equivalent", 12, "LIST" ] ] ] + "components": [ [ [ "stick_long", 1 ] ], [ [ "copper_scrap_equivalent", 15, "LIST" ] ] ] }, { "type": "recipe", diff --git a/data/json/requirements/materials.json b/data/json/requirements/materials.json index 312a6fee77092..67b63603d1ac7 100644 --- a/data/json/requirements/materials.json +++ b/data/json/requirements/materials.json @@ -39,7 +39,7 @@ "id": "copper_scrap_equivalent", "type": "requirement", "//": "Material used for equivalence between one unit of scrap copper and corresponding amount of elemental copper.", - "components": [ [ [ "scrap_copper", 1 ], [ "copper", 25 ] ] ] + "components": [ [ [ "scrap_copper", 1 ], [ "copper", 50 ] ] ] }, { "id": "plant_cordage", From 6d38a07780aa19cbef2bbc5a42461a80ab718dd2 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Wed, 7 Jul 2021 20:57:16 -0700 Subject: [PATCH 060/116] Stop copy-from modifying individual armor portions (#49726) Drop support for copy_from modifying elements of armor_portion_data within islot_armor::data. I can't figure out a way that copy-from as a behavior is a better thing to have than being forced to explicitly enter all the data when it should be different for an armor. There's no way to tell: 1. If the child object wants to modify the armor portion data when it specifies it's own armor portion data (instead of write it's own) 2. If the child does want to modify the data, which portion it is trying to modify. And if we allow it to modify the data, it's impossible to say you don't want a portion. It's just not something that can be handled without creating all sorts of non-obvious traps, and I think it's better to avoid it entirely. --- src/item_factory.cpp | 38 +------------------------------------- 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/src/item_factory.cpp b/src/item_factory.cpp index 2c0a9bb8c66c4..26806acef2786 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -1909,45 +1909,9 @@ void islot_armor::load( const JsonObject &jo ) if( jo.has_array( "armor_portion_data" ) || jo.has_array( "armor" ) ) { const JsonArray &arr = jo.has_array( "armor" ) ? jo.get_array( "armor" ) : jo.get_array( "armor_portion_data" ); - bool dont_add_first = false; - if( !data.empty() ) { // Uses copy-from - dont_add_first = true; - const JsonObject &obj = *arr.begin(); - armor_portion_data tempData; - - if( obj.has_array( "encumbrance" ) ) { - tempData.encumber = obj.get_array( "encumbrance" ).get_int( 0 ); - tempData.max_encumber = obj.get_array( "encumbrance" ).get_int( 1 ); - } else if( obj.has_int( "encumbrance" ) ) { - tempData.encumber = obj.get_int( "encumbrance" ); - tempData.max_encumber = -1; - } - if( obj.has_int( "coverage" ) ) { - tempData.coverage = obj.get_int( "coverage" ); - } - if( tempData.encumber != data[0].encumber ) { - data[0].encumber = tempData.encumber; - } - if( tempData.max_encumber != data[0].max_encumber ) { - data[0].max_encumber = tempData.max_encumber; - } - if( tempData.coverage != data[0].coverage ) { - data[0].coverage = tempData.coverage; - } - body_part_set temp_cover_data; - assign_coverage_from_json( obj, "covers", temp_cover_data ); - if( temp_cover_data.any() ) { - data[0].covers = temp_cover_data; - } - } + data.clear(); for( const JsonObject obj : arr ) { - // If this item used copy-from, data[0] is already set, so skip adding first data - if( dont_add_first ) { - obj.allow_omitted_members(); - dont_add_first = false; - continue; - } armor_portion_data tempData; body_part_set temp_cover_data; assign_coverage_from_json( obj, "covers", temp_cover_data ); From a49dcc865ebdad4df9f5b175706f6da691095d3e Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Wed, 7 Jul 2021 21:31:07 -0700 Subject: [PATCH 061/116] Fix color & installing power bionics (#49731) This restores the coloring and installation behaviour to what it was previously. --- src/bionics.cpp | 2 +- src/item.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bionics.cpp b/src/bionics.cpp index 1187c9cd1b862..10de31657dc62 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -2340,7 +2340,7 @@ ret_val Character::is_installable( const item_location &loc, const bool by return ret_val::make_failure( msg ); } else if( it->has_fault( fault_id( "fault_bionic_salvaged" ) ) ) { return ret_val::make_failure( _( "CBM already deployed. Please reset to factory state." ) ); - } else if( has_bionic( bid ) ) { + } else if( has_bionic( bid ) && !bid->dupes_allowed ) { return ret_val::make_failure( _( "CBM is already installed." ) ); } else if( !can_install_cbm_on_bp( get_occupied_bodyparts( bid ) ) ) { return ret_val::make_failure( _( "CBM not compatible with patient's body." ) ); diff --git a/src/item.cpp b/src/item.cpp index e8d0c4a71baab..8c7d56881b6b5 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -4428,7 +4428,7 @@ nc_color item::color_in_inventory() const } else if( is_filthy() || has_own_flag( flag_DIRTY ) ) { ret = c_brown; } else if( is_bionic() ) { - if( !player_character.has_bionic( type->bionic->id ) ) { + if( !player_character.has_bionic( type->bionic->id ) || type->bionic->id->dupes_allowed ) { ret = player_character.bionic_installation_issues( type->bionic->id ).empty() ? c_green : c_red; } else if( !has_flag( flag_NO_STERILE ) ) { ret = c_dark_gray; From ef6a2f27814ec7393ad5034f0b552eae1f29559b Mon Sep 17 00:00:00 2001 From: Trioct Date: Wed, 7 Jul 2021 23:31:42 -0500 Subject: [PATCH 062/116] fix hollow cane pocket size (#49729) --- data/json/items/melee/swords_and_blades.json | 1 + 1 file changed, 1 insertion(+) diff --git a/data/json/items/melee/swords_and_blades.json b/data/json/items/melee/swords_and_blades.json index 6137c9fa15c56..e185acb8dfde3 100644 --- a/data/json/items/melee/swords_and_blades.json +++ b/data/json/items/melee/swords_and_blades.json @@ -1228,6 +1228,7 @@ "pocket_type": "CONTAINER", "max_contains_volume": "1531 ml", "max_contains_weight": "2 kg", + "max_item_length": "80 cm", "moves": 80, "flag_restriction": [ "SHEATH_SWORD" ] } From a1703f47400c3c7c1f6dc0c500262db0826e91b0 Mon Sep 17 00:00:00 2001 From: Eric <52087122+Ramza13@users.noreply.github.com> Date: Thu, 8 Jul 2021 02:28:04 -0400 Subject: [PATCH 063/116] Unhardcode bio_flashlight and bio_tattoo_led (#47714) * Unhardcode bio_flashlight and bio_tattoo_led * Clean up * Fix * clean up * Revert "clean up" This reverts commit 8eaab1ae22ab754a322a8d7a7b051f39435c4c89. * Fix merge issues --- data/json/bionics.json | 6 ++++-- doc/MAGIC.md | 1 + src/character.cpp | 10 ++++------ src/magic_enchantment.cpp | 1 + src/magic_enchantment.h | 1 + 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/data/json/bionics.json b/data/json/bionics.json index c141498481765..e589504acd1a7 100644 --- a/data/json/bionics.json +++ b/data/json/bionics.json @@ -790,7 +790,8 @@ "act_cost": "3 J", "react_cost": "3 J", "time": 1, - "flags": [ "BIONIC_TOGGLED" ] + "flags": [ "BIONIC_TOGGLED" ], + "enchantments": [ { "condition": "ACTIVE", "values": [ { "value": "LUMINATION", "add": 60 } ] } ] }, { "id": "bio_tattoo_led", @@ -800,7 +801,8 @@ "act_cost": "1 J", "react_cost": "1 J", "time": 1, - "flags": [ "BIONIC_TOGGLED" ] + "flags": [ "BIONIC_TOGGLED" ], + "enchantments": [ { "condition": "ACTIVE", "values": [ { "value": "LUMINATION", "add": 5 } ] } ] }, { "id": "bio_glowy", diff --git a/doc/MAGIC.md b/doc/MAGIC.md index d444fd769b22a..5574e8abab8c0 100644 --- a/doc/MAGIC.md +++ b/doc/MAGIC.md @@ -495,6 +495,7 @@ Effects for the character that has the enchantment: * SOCIAL_PERSUADE * SOCIAL_INTIMIDATE * SLEEPY : The higher this is the more easily you fall asleep. +* LUMINATION : The character produces light * ARMOR_BASH * ARMOR_CUT * ARMOR_STAB diff --git a/src/character.cpp b/src/character.cpp index 0b475725eb348..f9d9d2b8df52d 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -274,7 +274,6 @@ static const trait_id trait_WOOLALLERGY( "WOOLALLERGY" ); static const bionic_id bio_ads( "bio_ads" ); static const bionic_id bio_blaster( "bio_blaster" ); static const bionic_id bio_voice( "bio_voice" ); -static const bionic_id bio_flashlight( "bio_flashlight" ); static const bionic_id bio_gills( "bio_gills" ); static const bionic_id bio_ground_sonar( "bio_ground_sonar" ); static const bionic_id bio_hydraulics( "bio_hydraulics" ); @@ -7731,11 +7730,10 @@ float Character::active_light() const lumination = std::max( lumination, mut_lum ); - if( lumination < 60 && has_active_bionic( bio_flashlight ) ) { - lumination = 60; - } else if( lumination < 5 && ( has_effect( effect_glowing ) || - ( has_active_bionic( bio_tattoo_led ) || - has_effect( effect_glowy_led ) ) ) ) { + lumination = std::max( lumination, + static_cast( enchantment_cache->modify_value( enchant_vals::mod::LUMINATION, 0 ) ) ); + + if( lumination < 5 && ( has_effect( effect_glowing ) || has_effect( effect_glowy_led ) ) ) { lumination = 5; } return lumination; diff --git a/src/magic_enchantment.cpp b/src/magic_enchantment.cpp index 3c7df4924e11e..fdb04bd9d2ed2 100644 --- a/src/magic_enchantment.cpp +++ b/src/magic_enchantment.cpp @@ -83,6 +83,7 @@ namespace io case enchant_vals::mod::SOCIAL_PERSUADE: return "SOCIAL_PERSUADE"; case enchant_vals::mod::SOCIAL_INTIMIDATE: return "SOCIAL_INTIMIDATE"; case enchant_vals::mod::SLEEPY: return "SLEEPY"; + case enchant_vals::mod::LUMINATION: return "LUMINATION"; case enchant_vals::mod::ARMOR_ACID: return "ARMOR_ACID"; case enchant_vals::mod::ARMOR_BASH: return "ARMOR_BASH"; case enchant_vals::mod::ARMOR_BIO: return "ARMOR_BIO"; diff --git a/src/magic_enchantment.h b/src/magic_enchantment.h index f731fcef204e6..5892ec4521df9 100644 --- a/src/magic_enchantment.h +++ b/src/magic_enchantment.h @@ -59,6 +59,7 @@ enum class mod : int { SOCIAL_PERSUADE, SOCIAL_INTIMIDATE, SLEEPY, + LUMINATION, ARMOR_BASH, ARMOR_CUT, ARMOR_STAB, From 39248f580a2afbb6e326b48cd0e87b27699358d2 Mon Sep 17 00:00:00 2001 From: Eric <52087122+Ramza13@users.noreply.github.com> Date: Thu, 8 Jul 2021 02:31:00 -0400 Subject: [PATCH 064/116] Unhardcode joint servo, add INACTIVE enchantment option (#47274) * Unhardcode joint servo * Clean up * comma comma comma comma comma chameleon Co-authored-by: I-am-Erk <45136638+I-am-Erk@users.noreply.github.com> --- data/json/bionics.json | 6 +++++- doc/MAGIC.md | 2 +- src/character.cpp | 10 ---------- src/magic_enchantment.cpp | 5 +++++ src/magic_enchantment.h | 1 + 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/data/json/bionics.json b/data/json/bionics.json index e589504acd1a7..81919afe18d24 100644 --- a/data/json/bionics.json +++ b/data/json/bionics.json @@ -1444,10 +1444,14 @@ "id": "bio_jointservo", "type": "bionic", "name": { "str": "Joint Servo" }, - "description": "Your leg joints have been equipped with servomotors that provide power-assisted movement. They are optimized for running, but walking also requires less effort when this bionic is online. However, when it's offline it will hamper your movement, as you struggle against its moving parts.", + "description": "Your leg joints have been equipped with servomotors that provide power-assisted movement. Movement takes less effort when this bionic is online. However, when it's offline it will hamper your movement, as you struggle against its moving parts.", "occupied_bodyparts": [ [ "leg_l", 12 ], [ "leg_r", 12 ] ], "flags": [ "BIONIC_TOGGLED" ], "mutation_conflicts": [ "LEG_TENTACLES", "LEG_TENT_BRACE" ], + "enchantments": [ + { "condition": "ACTIVE", "values": [ { "value": "MOVE_COST", "multiply": -0.1 } ] }, + { "condition": "INACTIVE", "values": [ { "value": "MOVE_COST", "multiply": 0.1 } ] } + ], "trigger_cost": "35 J" }, { diff --git a/doc/MAGIC.md b/doc/MAGIC.md index 5574e8abab8c0..d05c20c077b1c 100644 --- a/doc/MAGIC.md +++ b/doc/MAGIC.md @@ -411,7 +411,7 @@ You can assign a spell as a special attack for a monster. |--- |--- | `id` | Unique ID. Must be one continuous word, use underscores if necessary. | `has` | How an enchantment determines if it is in the right location in order to qualify for being active. "WIELD" - when wielded in your hand * "WORN" - when worn as armor * "HELD" - when in your inventory -| `condition` | How an enchantment determines if you are in the right environments in order for the enchantment to qualify for being active. * "ALWAYS" - Always and forevermore * "UNDERGROUND" - When the owner of the item is below Z-level 0 * "UNDERWATER" - When the owner is in swimmable terrain * "ACTIVE" - whenever the item, mutation, bionic, or whatever the enchantment is attached to is active. +| `condition` | How an enchantment determines if you are in the right environments in order for the enchantment to qualify for being active. * "ALWAYS" - Always and forevermore * "UNDERGROUND" - When the owner of the item is below Z-level 0 * "UNDERWATER" - When the owner is in swimmable terrain * "ACTIVE" - whenever the item, mutation, bionic, or whatever the enchantment is attached to is active. * "INACTIVE" - whenever the item, mutation, bionic, or whatever the enchantment is attached to is inactive. | `hit_you_effect` | A spell that activates when you melee_attack a creature. The spell is centered on the location of the creature unless self = true, then it is centered on your location. Follows the template for defining "fake_spell" | `hit_me_effect` | A spell that activates when you are hit by a creature. The spell is centered on your location. Follows the template for defining "fake_spell" | `intermittent_activation` | Spells that activate centered on you depending on the duration. The spells follow the "fake_spell" template. diff --git a/src/character.cpp b/src/character.cpp index f9d9d2b8df52d..a82ee99840e16 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -277,7 +277,6 @@ static const bionic_id bio_voice( "bio_voice" ); static const bionic_id bio_gills( "bio_gills" ); static const bionic_id bio_ground_sonar( "bio_ground_sonar" ); static const bionic_id bio_hydraulics( "bio_hydraulics" ); -static const bionic_id bio_jointservo( "bio_jointservo" ); static const bionic_id bio_leukocyte( "bio_leukocyte" ); static const bionic_id bio_memory( "bio_memory" ); static const bionic_id bio_railgun( "bio_railgun" ); @@ -11847,15 +11846,6 @@ int Character::run_cost( int base_cost, bool diag ) const if( has_trait( trait_PADDED_FEET ) && !footwear_factor() ) { movecost *= .9f; } - if( has_active_bionic( bio_jointservo ) ) { - if( is_running() ) { - movecost *= 0.85f; - } else { - movecost *= 0.95f; - } - } else if( has_bionic( bio_jointservo ) ) { - movecost *= 1.1f; - } if( worn_with_flag( flag_SLOWS_MOVEMENT ) ) { movecost *= 1.1f; diff --git a/src/magic_enchantment.cpp b/src/magic_enchantment.cpp index fdb04bd9d2ed2..b21eeb74fa42c 100644 --- a/src/magic_enchantment.cpp +++ b/src/magic_enchantment.cpp @@ -41,6 +41,7 @@ namespace io case enchantment::condition::UNDERGROUND: return "UNDERGROUND"; case enchantment::condition::UNDERWATER: return "UNDERWATER"; case enchantment::condition::ACTIVE: return "ACTIVE"; + case enchantment::condition::INACTIVE: return "INACTIVE"; case enchantment::condition::NUM_CONDITION: break; } debugmsg( "Invalid enchantment::condition" ); @@ -203,6 +204,10 @@ bool enchantment::is_active( const Character &guy, const bool active ) const return active; } + if( active_conditions.second == condition::INACTIVE ) { + return !active; + } + if( active_conditions.second == condition::ALWAYS ) { return true; } diff --git a/src/magic_enchantment.h b/src/magic_enchantment.h index 5892ec4521df9..4a414f2a88ceb 100644 --- a/src/magic_enchantment.h +++ b/src/magic_enchantment.h @@ -118,6 +118,7 @@ class enchantment UNDERGROUND, UNDERWATER, ACTIVE, // the item, mutation, etc. is active + INACTIVE, // the item, mutation, etc. is inactive NUM_CONDITION }; From b09bbfe49de20ace76b95045bab0a3729dbff9c6 Mon Sep 17 00:00:00 2001 From: Eric <52087122+Ramza13@users.noreply.github.com> Date: Thu, 8 Jul 2021 02:34:16 -0400 Subject: [PATCH 065/116] Unhardcode more bionics, add weapon dispersion enchantment (#47288) * Unhardcode more bionics * Update src/bionics.h Co-authored-by: anothersimulacrum * Change dipersion to use enchantment * Update ranged.cpp * Clean up Co-authored-by: anothersimulacrum --- data/json/bionics.json | 6 ++++-- doc/JSON_FLAGS.md | 2 ++ doc/JSON_INFO.md | 1 + doc/MAGIC.md | 1 + src/bionics.cpp | 1 + src/magic_enchantment.cpp | 1 + src/magic_enchantment.h | 1 + src/panels.cpp | 7 ++++--- src/ranged.cpp | 7 ++++--- 9 files changed, 19 insertions(+), 8 deletions(-) diff --git a/data/json/bionics.json b/data/json/bionics.json index 81919afe18d24..4270620db2928 100644 --- a/data/json/bionics.json +++ b/data/json/bionics.json @@ -1014,7 +1014,8 @@ "name": { "str": "Weather Reader" }, "description": "A multitude of scientific instruments and sensors collect environmental data. The data is compiled and presented as a simple readout of the current weather. It also passively tells you the local air temperature.", "occupied_bodyparts": [ [ "torso", 1 ], [ "head", 1 ] ], - "act_cost": "10 J" + "act_cost": "10 J", + "flags": [ "THERMOMETER" ] }, { "id": "bio_nanobots", @@ -1372,7 +1373,8 @@ "name": { "str": "Targeting System" }, "description": "Your eyes are surgically equipped with range finders, and their movement is synced with that of your arms, to a degree. Shots you fire will be much more accurate, particularly at long range.", "occupied_bodyparts": [ [ "eyes", 1 ], [ "arm_l", 3 ], [ "arm_r", 3 ], [ "hand_l", 1 ], [ "hand_r", 1 ] ], - "flags": [ "BIONIC_NPC_USABLE" ] + "flags": [ "BIONIC_NPC_USABLE" ], + "enchantments": [ { "condition": "ALWAYS", "values": [ { "value": "WEAPON_DISPERSION", "multiply": -0.25 } ] } ] }, { "id": "bio_teleport", diff --git a/doc/JSON_FLAGS.md b/doc/JSON_FLAGS.md index 125e43a2e4785..441a6dcd4f493 100644 --- a/doc/JSON_FLAGS.md +++ b/doc/JSON_FLAGS.md @@ -1529,3 +1529,5 @@ Gun fault flags: - ```DIMENSIONAL_ANCHOR``` You can't be teleported. - ```CLIMATE_CONTROL``` You are resistant to extreme temperatures. - ```HEATSINK``` You are resistant to extreme heat. +- ```THERMOMETER``` You always know what temperature it is. + diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index 541fe12ae92ff..b120710c2d026 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -681,6 +681,7 @@ For information about tools with option to export ASCII art in format ready to b | dupes_allowed | (_optional_) Boolean to determine if multiple copies of this bionic can be installed. Defaults to false. | cant_remove_reason | (_optional_) String message to be displayed as the reason it can't be uninstalled. Having any value other than `""` as this will prevent unistalling the bionic. Formatting includes two `%s` for example: `The Telescopic Lenses are part of %1$s eyes now. Removing them would leave %2$s blind.` (default: `""`) | social_modifiers | (_optional_) Json object with optional members: persuade, lie, and intimidate which add or subtract that amount from those types of social checks +| dispersion_mod | (_optional_) Modifier to change firearm disperation. ```C++ { diff --git a/doc/MAGIC.md b/doc/MAGIC.md index d05c20c077b1c..afc578c1f1395 100644 --- a/doc/MAGIC.md +++ b/doc/MAGIC.md @@ -491,6 +491,7 @@ Effects for the character that has the enchantment: * SIGHT_RANGE * CARRY_WEIGHT * CARRY_VOLUME +* WEAPON_DISPERSION * SOCIAL_LIE * SOCIAL_PERSUADE * SOCIAL_INTIMIDATE diff --git a/src/bionics.cpp b/src/bionics.cpp index 10de31657dc62..d13b1cedd372a 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -329,6 +329,7 @@ void bionic_data::load( const JsonObject &jsobj, const std::string & ) optional( jsobj, was_loaded, "vitamin_absorb_mod", vitamin_absorb_mod, 1.0f ); optional( jsobj, was_loaded, "dupes_allowed", dupes_allowed, false ); + int enchant_num = 0; for( JsonValue jv : jsobj.get_array( "enchantments" ) ) { std::string enchant_name = "INLINE_ENCH_" + name + "_" + std::to_string( enchant_num++ ); diff --git a/src/magic_enchantment.cpp b/src/magic_enchantment.cpp index b21eeb74fa42c..d1816afa5b14d 100644 --- a/src/magic_enchantment.cpp +++ b/src/magic_enchantment.cpp @@ -80,6 +80,7 @@ namespace io case enchant_vals::mod::FOOTSTEP_NOISE: return "FOOTSTEP_NOISE"; case enchant_vals::mod::SIGHT_RANGE: return "SIGHT_RANGE"; case enchant_vals::mod::CARRY_WEIGHT: return "CARRY_WEIGHT"; + case enchant_vals::mod::WEAPON_DISPERSION: return "WEAPON_DISPERSION"; case enchant_vals::mod::SOCIAL_LIE: return "SOCIAL_LIE"; case enchant_vals::mod::SOCIAL_PERSUADE: return "SOCIAL_PERSUADE"; case enchant_vals::mod::SOCIAL_INTIMIDATE: return "SOCIAL_INTIMIDATE"; diff --git a/src/magic_enchantment.h b/src/magic_enchantment.h index 4a414f2a88ceb..8c02d88d963c2 100644 --- a/src/magic_enchantment.h +++ b/src/magic_enchantment.h @@ -55,6 +55,7 @@ enum class mod : int { FOOTSTEP_NOISE, SIGHT_RANGE, CARRY_WEIGHT, + WEAPON_DISPERSION, SOCIAL_LIE, SOCIAL_PERSUADE, SOCIAL_INTIMIDATE, diff --git a/src/panels.cpp b/src/panels.cpp index 96569b066cf2b..fe62335588d1a 100644 --- a/src/panels.cpp +++ b/src/panels.cpp @@ -34,6 +34,7 @@ #include "input.h" #include "item.h" #include "json.h" +#include "make_static.h" #include "magic.h" #include "map.h" #include "messages.h" @@ -470,7 +471,7 @@ static std::string get_temp( const avatar &u ) { std::string temp; if( u.has_item_with_flag( json_flag_THERMOMETER ) || - u.has_bionic( bionic_id( "bio_meteorologist" ) ) ) { + u.has_flag( STATIC( json_character_flag( "THERMOMETER" ) ) ) ) { temp = print_temperature( get_weather().get_temperature( u.pos() ) ); } if( temp.empty() ) { @@ -1676,7 +1677,7 @@ static void draw_env_compact( avatar &u, const catacurses::window &w ) get_wind_desc( windpower ) + " " + get_wind_arrow( g->weather.winddirection ) ); if( u.has_item_with_flag( json_flag_THERMOMETER ) || - u.has_bionic( bionic_id( "bio_meteorologist" ) ) ) { + u.has_flag( STATIC( json_character_flag( "THERMOMETER" ) ) ) ) { std::string temp = print_temperature( g->weather.get_temperature( u.pos() ) ); mvwprintz( w, point( 31 - utf8_width( temp ), 5 ), c_light_gray, temp ); } @@ -2058,7 +2059,7 @@ static void draw_time_classic( const avatar &u, const catacurses::window &w ) } if( u.has_item_with_flag( json_flag_THERMOMETER ) || - u.has_bionic( bionic_id( "bio_meteorologist" ) ) ) { + u.has_flag( STATIC( json_character_flag( "THERMOMETER" ) ) ) ) { std::string temp = print_temperature( get_weather().get_temperature( u.pos() ) ); mvwprintz( w, point( 31, 0 ), c_light_gray, _( "Temp : " ) + temp ); } diff --git a/src/ranged.cpp b/src/ranged.cpp index f856aa0526b88..765379f92530d 100644 --- a/src/ranged.cpp +++ b/src/ranged.cpp @@ -107,7 +107,6 @@ static const skill_id skill_launcher( "launcher" ); static const skill_id skill_throw( "throw" ); static const bionic_id bio_railgun( "bio_railgun" ); -static const bionic_id bio_targeting( "bio_targeting" ); static const bionic_id bio_ups( "bio_ups" ); static const std::string flag_MOUNTABLE( "MOUNTABLE" ); @@ -1833,8 +1832,10 @@ dispersion_sources Character::get_weapon_dispersion( const item &obj ) const dispersion.add_range( dispersion_from_skill( avgSkill, weapon_dispersion ) ); - if( has_bionic( bio_targeting ) ) { - dispersion.add_multiplier( 0.75 ); + float disperation_mod = enchantment_cache->modify_value( enchant_vals::mod::WEAPON_DISPERSION, + 1.0f ); + if( disperation_mod != 1.0f ) { + dispersion.add_multiplier( disperation_mod ); } // Range is effectively four times longer when shooting unflagged/flagged guns underwater/out of water. From 91b7a14d3cb3763611109b0bdb9ee0b4970f3abf Mon Sep 17 00:00:00 2001 From: AccountAlias <85119255+AccountAlias@users.noreply.github.com> Date: Thu, 8 Jul 2021 16:13:20 -0400 Subject: [PATCH 066/116] Enforce MAX_SKILL cap (#49747) --- src/character.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/character.cpp b/src/character.cpp index a82ee99840e16..6514b599f2bcb 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -2357,8 +2357,8 @@ void Character::practice( const skill_id &id, int amount, int cap, bool suppress static const int INTMAX_SQRT = std::floor( std::sqrt( std::numeric_limits::max() ) ); SkillLevel &level = get_skill_level_object( id ); const Skill &skill = id.obj(); - if( !level.can_train() && !in_sleep_state() ) { - // If leveling is disabled, don't train, don't drain focus, don't print anything + if( !level.can_train() || in_sleep_state() || ( get_skill_level( id ) >= MAX_SKILL ) ) { + // Do not practice if: cannot train, asleep, or at effective skill cap // Leaving as a skill method rather than global for possible future skill cap setting return; } From a068ed0fb0590ce1f9a3fb5aa2a8c989cfba55dd Mon Sep 17 00:00:00 2001 From: Mom-Bun <43492737+Mom-Bun@users.noreply.github.com> Date: Thu, 8 Jul 2021 15:14:56 -0500 Subject: [PATCH 067/116] Fix Triffid Grove Error (#49744) --- data/json/obsolete_terrains.json | 3 +++ src/savegame.cpp | 29 ++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/data/json/obsolete_terrains.json b/data/json/obsolete_terrains.json index dc517d80da30e..3660ac84d28f3 100644 --- a/data/json/obsolete_terrains.json +++ b/data/json/obsolete_terrains.json @@ -10,6 +10,9 @@ "bridge_east", "bridge_south", "bridge_west", + "triffid_grove", + "triffid_roots", + "triffid_finale", "fema", "fema_entrance", "fema_1_3", diff --git a/src/savegame.cpp b/src/savegame.cpp index 86d99ff82e023..b62647049deab 100644 --- a/src/savegame.cpp +++ b/src/savegame.cpp @@ -386,7 +386,7 @@ void overmap::convert_terrain( if( old == "fema" || old == "fema_entrance" || old == "fema_1_3" || old == "fema_2_1" || old == "fema_2_2" || old == "fema_2_3" || old == "fema_3_1" || old == "fema_3_2" || old == "fema_3_3" || - old == "s_lot" || old == "mine_entrance" ) { + old == "s_lot" || old == "mine_entrance" || old == "triffid_finale" ) { ter_set( pos, oter_id( old + "_north" ) ); } else if( old.compare( 0, 6, "bridge" ) == 0 ) { ter_set( pos, oter_id( old ) ); @@ -397,6 +397,33 @@ void overmap::convert_terrain( ter_set( pos + tripoint_above, oter_id( "bridge_road" + oter_get_rotation_string( oter_ground ) ) ); bridge_points.emplace_back( pos.xy() ); } + } else if( old == "triffid_grove" ) { + { + ter_set( pos, oter_id( "triffid_grove_north" ) ); + ter_set( pos + point_north, oter_id( "triffid_field_north" ) ); + ter_set( pos + point_north_east, oter_id( "triffid_field_north" ) ); + ter_set( pos + point_east, oter_id( "triffid_field_north" ) ); + ter_set( pos + point_south_east, oter_id( "triffid_field_north" ) ); + ter_set( pos + point_south, oter_id( "triffid_field_north" ) ); + ter_set( pos + point_south_west, oter_id( "triffid_field_north" ) ); + ter_set( pos + point_west, oter_id( "triffid_field_north" ) ); + ter_set( pos + point_north_west, oter_id( "triffid_field_north" ) ); + ter_set( pos + tripoint_above, oter_id( "triffid_grove_z2_north" ) ); + ter_set( pos + tripoint( 0, 0, 2 ), oter_id( "triffid_grove_z3_north" ) ); + ter_set( pos + tripoint( 0, 0, 3 ), oter_id( "triffid_grove_roof_north" ) ); + } + } else if( old == "triffid_roots" ) { + { + ter_set( pos, oter_id( "triffid_roots_north" ) ); + ter_set( pos + point_south, oter_id( "triffid_rootsn_north" ) ); + ter_set( pos + point_south_east, oter_id( "triffid_rootsen_north" ) ); + ter_set( pos + point_east, oter_id( "triffid_rootse_north" ) ); + ter_set( pos + point_north_east, oter_id( "triffid_rootsse_north" ) ); + ter_set( pos + point_north, oter_id( "triffid_rootss_north" ) ); + ter_set( pos + point_north_west, oter_id( "triffid_rootssw_north" ) ); + ter_set( pos + point_west, oter_id( "triffid_rootsw_north" ) ); + ter_set( pos + point_south_west, oter_id( "triffid_rootsnw_north" ) ); + } } else if( old.compare( 0, 10, "mass_grave" ) == 0 ) { ter_set( pos, oter_id( "field" ) ); } else if( old == "mine_shaft" ) { From d659ef9fbf541040209aad4f8fe59ce7c659961f Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Thu, 8 Jul 2021 13:15:15 -0700 Subject: [PATCH 068/116] Remove unused static variable (#49742) --- src/character.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/character.cpp b/src/character.cpp index 6514b599f2bcb..c86224f6f1e71 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -281,7 +281,6 @@ static const bionic_id bio_leukocyte( "bio_leukocyte" ); static const bionic_id bio_memory( "bio_memory" ); static const bionic_id bio_railgun( "bio_railgun" ); static const bionic_id bio_shock_absorber( "bio_shock_absorber" ); -static const bionic_id bio_tattoo_led( "bio_tattoo_led" ); static const bionic_id bio_ups( "bio_ups" ); // Aftershock stuff! static const bionic_id afs_bio_linguistic_coprocessor( "afs_bio_linguistic_coprocessor" ); From 782d8b97450f4fc7a3c7ff371db6ea32982afb72 Mon Sep 17 00:00:00 2001 From: Pankaj Patil Date: Fri, 9 Jul 2021 01:46:39 +0530 Subject: [PATCH 069/116] Fix:Ninjutsu martial art does incorrect damage due to multiplicative calculation (#49741) --- data/json/martialarts.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/json/martialarts.json b/data/json/martialarts.json index 8a49e33a015b5..75dd4b28637a0 100644 --- a/data/json/martialarts.json +++ b/data/json/martialarts.json @@ -887,9 +887,9 @@ "melee_allowed": true, "buff_duration": 3, "mult_bonuses": [ - { "stat": "damage", "type": "bash", "scale": 0.5 }, - { "stat": "damage", "type": "cut", "scale": 0.5 }, - { "stat": "damage", "type": "stab", "scale": 0.5 } + { "stat": "damage", "type": "bash", "scale": 0.67 }, + { "stat": "damage", "type": "cut", "scale": 0.67 }, + { "stat": "damage", "type": "stab", "scale": 0.67 } ] } ], From 86738f2bc96384939f843206e94f33d69a0b22d5 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Thu, 8 Jul 2021 13:16:54 -0700 Subject: [PATCH 070/116] Fix typo 'road ramp' > 'earth ramp' (#49740) --- data/json/furniture_and_terrain/terrain-zlevel-transitions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/furniture_and_terrain/terrain-zlevel-transitions.json b/data/json/furniture_and_terrain/terrain-zlevel-transitions.json index a876c30bb4f8d..475760bdf85cd 100644 --- a/data/json/furniture_and_terrain/terrain-zlevel-transitions.json +++ b/data/json/furniture_and_terrain/terrain-zlevel-transitions.json @@ -244,7 +244,7 @@ { "type": "terrain", "id": "t_earth_ramp_up_low", - "name": "road ramp up (low end)", + "name": "earth ramp up (low end)", "description": "The lower end of an earth ramp leading up.", "symbol": "<", "color": "brown", From 3329aa260002d3c9a1621eef53d23d0796fa5175 Mon Sep 17 00:00:00 2001 From: eltank <8000047+eltank@users.noreply.github.com> Date: Thu, 8 Jul 2021 13:33:47 -0700 Subject: [PATCH 071/116] Reduce crafting proficiency penalties based on partial proficiency level (#49198) * Make most of the crafting timing tests ignore missing prof These tests are too brittle and will break any time there's a change in the proficiency penalty formulas or proficiency progression. This causes excessive maintenance burden. A single such test should suffice. * Partial proficiency mitigation * Rename get_proficiency_level * Use 1 decimal for missing prof penalties in crafting UI --- src/character.cpp | 5 ++ src/character.h | 1 + src/recipe.cpp | 128 ++++++++++++++++++++++++---------------- src/recipe.h | 4 +- tests/crafting_test.cpp | 67 +++++++++++---------- 5 files changed, 119 insertions(+), 86 deletions(-) diff --git a/src/character.cpp b/src/character.cpp index c86224f6f1e71..e0f4cb6f7507f 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -12739,6 +12739,11 @@ bool Character::has_proficiency( const proficiency_id &prof ) const return _proficiencies->has_learned( prof ); } +float Character::get_proficiency_practice( const proficiency_id &prof ) const +{ + return _proficiencies->pct_practiced( prof ); +} + bool Character::has_prof_prereqs( const proficiency_id &prof ) const { return _proficiencies->has_prereqs( prof ); diff --git a/src/character.h b/src/character.h index d4b156053968f..250f85bc16b98 100644 --- a/src/character.h +++ b/src/character.h @@ -1831,6 +1831,7 @@ class Character : public Creature, public visitable // --------------- Proficiency Stuff ---------------- bool has_proficiency( const proficiency_id &prof ) const; + float get_proficiency_practice( const proficiency_id &prof ) const; bool has_prof_prereqs( const proficiency_id &prof ) const; void add_proficiency( const proficiency_id &prof, bool ignore_requirements = false ); void lose_proficiency( const proficiency_id &prof, bool ignore_requirements = false ); diff --git a/src/recipe.cpp b/src/recipe.cpp index 12d05a400c797..a589b3b2cd5ae 100644 --- a/src/recipe.cpp +++ b/src/recipe.cpp @@ -614,15 +614,15 @@ static std::string profstring( const prof_penalty &prof, } if( prof.time_mult == 1.0f ) { - return string_format( _( "%s (%gx\u00a0failure%s)" ), + return string_format( _( "%s (%.1fx\u00a0failure%s)" ), name_color, prof.id->name(), color, prof.failure_mult, mitigated_str ); } else if( prof.failure_mult == 1.0f ) { - return string_format( _( "%s (%gx\u00a0time%s)" ), + return string_format( _( "%s (%.1fx\u00a0time%s)" ), name_color, prof.id->name(), color, prof.time_mult, mitigated_str ); } return string_format( - _( "%s (%gx\u00a0time, %gx\u00a0failure%s)" ), + _( "%s (%.1fx\u00a0time, %.1fx\u00a0failure%s)" ), name_color, prof.id->name(), color, prof.time_mult, prof.failure_mult, mitigated_str ); } @@ -650,39 +650,6 @@ std::string recipe::used_proficiencies_string( const Character *c ) const return used; } -std::string recipe::missing_proficiencies_string( const Character *c ) const -{ - if( c == nullptr ) { - return { }; - } - std::vector missing_profs; - - const book_proficiency_bonuses book_bonuses = - c->crafting_inventory().get_book_proficiency_bonuses(); - for( const recipe_proficiency &rec : proficiencies ) { - if( !rec.required ) { - if( !( c->has_proficiency( rec.id ) || helpers_have_proficiencies( *c, rec.id ) ) ) { - prof_penalty pen = { rec.id, rec.time_multiplier, rec.fail_multiplier }; - if( book_bonuses.time_factor( pen.id ) != 0.0f || book_bonuses.fail_factor( pen.id ) != 0.0f ) { - pen.time_mult = 1.0f + ( pen.time_mult - 1.0f ) * ( 1.0f - book_bonuses.time_factor( pen.id ) ); - pen.failure_mult = 1.0f + ( pen.failure_mult - 1.0f ) * ( 1.0f - book_bonuses.fail_factor( - pen.id ) ); - pen.mitigated = true; - } - missing_profs.push_back( pen ); - } - } - } - - std::string color = "yellow"; - std::string missing = enumerate_as_string( missing_profs.begin(), - missing_profs.end(), [&]( const prof_penalty & prof ) { - return profstring( prof, color, c->has_prof_prereqs( prof.id ) ? "cyan" : "red" ); - } ); - - return missing; -} - std::string recipe::recipe_proficiencies_string() const { std::vector profs; @@ -730,34 +697,95 @@ std::set recipe::assist_proficiencies() const return ret; } -float recipe::proficiency_time_maluses( const Character &guy ) const +static float get_aided_proficiency_level( const Character &crafter, proficiency_id prof ) +{ + float max_prof = crafter.get_proficiency_practice( prof ); + for( const npc *helper : crafter.get_crafting_helpers() ) { + max_prof = std::max( max_prof, helper->get_proficiency_practice( prof ) ); + } + return max_prof; +} + +static float proficiency_time_malus( const Character &crafter, const recipe_proficiency &prof ) +{ + if( !crafter.has_proficiency( prof.id ) && + !helpers_have_proficiencies( crafter, prof.id ) && prof.time_multiplier > 1.0f ) { + double malus = prof.time_multiplier - 1.0; + malus *= 1.0 - crafter.crafting_inventory().get_book_proficiency_bonuses().time_factor( prof.id ); + double pl = get_aided_proficiency_level( crafter, prof.id ); + // Sigmoid function that mitigates 100% of the time malus as pl approaches 1.0 + // but has little effect at pl < 0.5. See #49198 + malus *= 1.0 - std::pow( 0.5 - 0.5 * std::cos( pl * M_PI ), 2 ); + return static_cast( 1.0 + malus ); + } + return 1.0f; +} + +float recipe::proficiency_time_maluses( const Character &crafter ) const { float total_malus = 1.0f; for( const recipe_proficiency &prof : proficiencies ) { - if( !guy.has_proficiency( prof.id ) && - !helpers_have_proficiencies( guy, prof.id ) && prof.time_multiplier > 1.0f ) { - float malus = 1.0f + ( prof.time_multiplier - 1.0f ) * - ( 1.0f - guy.crafting_inventory().get_book_proficiency_bonuses().time_factor( prof.id ) ); - total_malus *= malus; - } + total_malus *= proficiency_time_malus( crafter, prof ); } return total_malus; } -float recipe::proficiency_failure_maluses( const Character &guy ) const +static float proficiency_failure_malus( const Character &crafter, const recipe_proficiency &prof ) +{ + if( !crafter.has_proficiency( prof.id ) && + !helpers_have_proficiencies( crafter, prof.id ) && prof.fail_multiplier > 1.0f ) { + double malus = prof.fail_multiplier - 1.0f; + malus *= 1.0 - crafter.crafting_inventory().get_book_proficiency_bonuses().fail_factor( prof.id ); + double pl = get_aided_proficiency_level( crafter, prof.id ); + // The failure malus is not completely eliminated until the proficiency is mastered. + // Most of the mitigation happens at higher pl. See #49198 + malus *= 1.0 - ( 0.75 * std::pow( pl, 3 ) ); + return static_cast( 1.0 + malus ); + } + return 1.0f; +} + +float recipe::proficiency_failure_maluses( const Character &crafter ) const { float total_malus = 1.0f; for( const recipe_proficiency &prof : proficiencies ) { - if( !guy.has_proficiency( prof.id ) && - !helpers_have_proficiencies( guy, prof.id ) && prof.fail_multiplier > 1.0f ) { - float malus = 1.0f + ( prof.fail_multiplier - 1.0f ) * - ( 1.0f - guy.crafting_inventory().get_book_proficiency_bonuses().fail_factor( prof.id ) ); - total_malus *= malus; - } + total_malus *= proficiency_failure_malus( crafter, prof ); } return total_malus; } +std::string recipe::missing_proficiencies_string( const Character *crafter ) const +{ + if( crafter == nullptr ) { + return { }; + } + std::vector missing_profs; + + const book_proficiency_bonuses book_bonuses = + crafter->crafting_inventory().get_book_proficiency_bonuses(); + for( const recipe_proficiency &prof : proficiencies ) { + if( !prof.required ) { + if( !( crafter->has_proficiency( prof.id ) || helpers_have_proficiencies( *crafter, prof.id ) ) ) { + prof_penalty pen = { prof.id, + proficiency_time_malus( *crafter, prof ), + proficiency_failure_malus( *crafter, prof ) + }; + pen.mitigated = book_bonuses.time_factor( pen.id ) != 0.0f || + book_bonuses.fail_factor( pen.id ) != 0.0f; + missing_profs.push_back( pen ); + } + } + } + + std::string color = "yellow"; + std::string missing = enumerate_as_string( missing_profs.begin(), + missing_profs.end(), [&]( const prof_penalty & prof ) { + return profstring( prof, color, crafter->has_prof_prereqs( prof.id ) ? "cyan" : "red" ); + } ); + + return missing; +} + float recipe::exertion_level() const { return exertion; diff --git a/src/recipe.h b/src/recipe.h index 5799fe6d27a20..0624bd160af05 100644 --- a/src/recipe.h +++ b/src/recipe.h @@ -184,9 +184,9 @@ class recipe // Helpful proficiencies std::set assist_proficiencies() const; // The time malus due to proficiencies lacking - float proficiency_time_maluses( const Character &guy ) const; + float proficiency_time_maluses( const Character &crafter ) const; // The failure malus due to proficiencies lacking - float proficiency_failure_maluses( const Character &guy ) const; + float proficiency_failure_maluses( const Character &crafter ) const; // How active of exercise this recipe is float exertion_level() const; diff --git a/tests/crafting_test.cpp b/tests/crafting_test.cpp index aa9287dbe7024..a3bc92f8a17ac 100644 --- a/tests/crafting_test.cpp +++ b/tests/crafting_test.cpp @@ -761,141 +761,111 @@ TEST_CASE( "crafting_skill_gain", "[skill],[crafting],[slow]" ) { SECTION( "lvl 0 -> 1" ) { GIVEN( "nominal morale" ) { - test_skill_progression( recipe_id( "blanket" ), 175, 0, false ); test_skill_progression( recipe_id( "blanket" ), 175, 0, true ); } GIVEN( "high morale" ) { - test_skill_progression( recipe_id( "blanket" ), 173, 50, false ); test_skill_progression( recipe_id( "blanket" ), 173, 50, true ); } GIVEN( "very high morale" ) { - test_skill_progression( recipe_id( "blanket" ), 173, 100, false ); test_skill_progression( recipe_id( "blanket" ), 173, 100, true ); } } SECTION( "lvl 1 -> 2" ) { GIVEN( "nominal morale" ) { - test_skill_progression( recipe_id( "2byarm_guard" ), 2140, 0, false ); test_skill_progression( recipe_id( "2byarm_guard" ), 2140, 0, true ); } GIVEN( "high morale" ) { - test_skill_progression( recipe_id( "2byarm_guard" ), 1842, 50, false ); test_skill_progression( recipe_id( "2byarm_guard" ), 1842, 50, true ); } GIVEN( "very high morale" ) { - test_skill_progression( recipe_id( "2byarm_guard" ), 1737, 100, false ); test_skill_progression( recipe_id( "2byarm_guard" ), 1737, 100, true ); } } SECTION( "lvl 2 -> lvl 3" ) { GIVEN( "nominal morale" ) { - test_skill_progression( recipe_id( "vambrace_larmor" ), 12127, 0, false ); test_skill_progression( recipe_id( "vambrace_larmor" ), 6291, 0, true ); } GIVEN( "high morale" ) { - test_skill_progression( recipe_id( "vambrace_larmor" ), 9919, 50, false ); test_skill_progression( recipe_id( "vambrace_larmor" ), 5230, 50, true ); } GIVEN( "very high morale" ) { - test_skill_progression( recipe_id( "vambrace_larmor" ), 9160, 100, false ); test_skill_progression( recipe_id( "vambrace_larmor" ), 4836, 100, true ); } } SECTION( "lvl 3 -> lvl 4" ) { GIVEN( "nominal morale" ) { - test_skill_progression( recipe_id( "armguard_larmor" ), 22711, 0, false ); test_skill_progression( recipe_id( "armguard_larmor" ), 12138, 0, true ); } GIVEN( "high morale" ) { - test_skill_progression( recipe_id( "armguard_larmor" ), 18436, 50, false ); test_skill_progression( recipe_id( "armguard_larmor" ), 10003, 50, true ); } GIVEN( "very high morale" ) { - test_skill_progression( recipe_id( "armguard_larmor" ), 16951, 100, false ); test_skill_progression( recipe_id( "armguard_larmor" ), 9203, 100, true ); } } SECTION( "lvl 4 -> 5" ) { GIVEN( "nominal morale" ) { - test_skill_progression( recipe_id( "armguard_metal" ), 37537, 0, false ); test_skill_progression( recipe_id( "armguard_metal" ), 19638, 0, true ); } GIVEN( "high morale" ) { - test_skill_progression( recipe_id( "armguard_metal" ), 29872, 50, false ); test_skill_progression( recipe_id( "armguard_metal" ), 16125, 50, true ); } GIVEN( "very high morale" ) { - test_skill_progression( recipe_id( "armguard_metal" ), 27472, 100, false ); test_skill_progression( recipe_id( "armguard_metal" ), 14805, 100, true ); } } SECTION( "lvl 5 -> 6" ) { GIVEN( "nominal morale" ) { - test_skill_progression( recipe_id( "armguard_chitin" ), 100755, 0, false ); test_skill_progression( recipe_id( "armguard_chitin" ), 28817, 0, true ); } GIVEN( "high morale" ) { - test_skill_progression( recipe_id( "armguard_chitin" ), 79969, 50, false ); test_skill_progression( recipe_id( "armguard_chitin" ), 23613, 50, true ); } GIVEN( "very high morale" ) { - test_skill_progression( recipe_id( "armguard_chitin" ), 73091, 100, false ); test_skill_progression( recipe_id( "armguard_chitin" ), 21651, 100, true ); } } SECTION( "lvl 6 -> 7" ) { GIVEN( "nominal morale" ) { - test_skill_progression( recipe_id( "armguard_acidchitin" ), 137741, 0, false ); test_skill_progression( recipe_id( "armguard_acidchitin" ), 39651, 0, true ); } GIVEN( "high morale" ) { - test_skill_progression( recipe_id( "armguard_acidchitin" ), 109241, 50, false ); test_skill_progression( recipe_id( "armguard_acidchitin" ), 32470, 50, true ); } GIVEN( "very high morale" ) { - test_skill_progression( recipe_id( "armguard_acidchitin" ), 99810, 100, false ); test_skill_progression( recipe_id( "armguard_acidchitin" ), 29755, 100, true ); } } SECTION( "lvl 7 -> 8" ) { GIVEN( "nominal morale" ) { - test_skill_progression( recipe_id( "armguard_lightplate" ), 227023, 0, false ); test_skill_progression( recipe_id( "armguard_lightplate" ), 52138, 0, true ); } GIVEN( "high morale" ) { - test_skill_progression( recipe_id( "armguard_lightplate" ), 178077, 50, false ); test_skill_progression( recipe_id( "armguard_lightplate" ), 42656, 50, true ); } GIVEN( "very high morale" ) { - test_skill_progression( recipe_id( "armguard_lightplate" ), 162603, 100, false ); test_skill_progression( recipe_id( "armguard_lightplate" ), 39078, 100, true ); } } SECTION( "lvl 8 -> 9" ) { GIVEN( "nominal morale" ) { - test_skill_progression( recipe_id( "helmet_scavenger" ), 143457, 0, false ); test_skill_progression( recipe_id( "helmet_scavenger" ), 66243, 0, true ); } GIVEN( "high morale" ) { - test_skill_progression( recipe_id( "helmet_scavenger" ), 114137, 50, false ); test_skill_progression( recipe_id( "helmet_scavenger" ), 54170, 50, true ); } GIVEN( "very high morale" ) { - test_skill_progression( recipe_id( "helmet_scavenger" ), 105128, 100, false ); test_skill_progression( recipe_id( "helmet_scavenger" ), 49609, 100, true ); } } SECTION( "lvl 9 -> 10" ) { GIVEN( "nominal morale" ) { - test_skill_progression( recipe_id( "helmet_kabuto" ), 280299, 0, false ); test_skill_progression( recipe_id( "helmet_kabuto" ), 82489, 0, true ); } GIVEN( "high morale" ) { - test_skill_progression( recipe_id( "helmet_kabuto" ), 221512, 50, false ); test_skill_progression( recipe_id( "helmet_kabuto" ), 67364, 50, true ); } GIVEN( "very high morale" ) { - test_skill_progression( recipe_id( "helmet_kabuto" ), 202846, 100, false ); test_skill_progression( recipe_id( "helmet_kabuto" ), 61584, 100, true ); } } @@ -915,15 +885,12 @@ TEST_CASE( "crafting_skill_gain", "[skill],[crafting],[slow]" ) } SECTION( "extremely short craft" ) { GIVEN( "nominal morale" ) { - test_skill_progression( recipe_id( "fishing_hook_basic" ), 174, 0, false ); test_skill_progression( recipe_id( "fishing_hook_basic" ), 174, 0, true ); } GIVEN( "high morale" ) { - test_skill_progression( recipe_id( "fishing_hook_basic" ), 172, 50, false ); test_skill_progression( recipe_id( "fishing_hook_basic" ), 172, 50, true ); } GIVEN( "very high morale" ) { - test_skill_progression( recipe_id( "fishing_hook_basic" ), 172, 100, false ); test_skill_progression( recipe_id( "fishing_hook_basic" ), 172, 100, true ); } } @@ -941,7 +908,7 @@ TEST_CASE( "book_proficiency_mitigation", "[crafting][proficiency]" ) GIVEN( "a recipe with required proficiencies" ) { clear_avatar(); clear_map(); - const recipe &test_recipe = recipe_id( "leather_belt" ).obj(); + const recipe &test_recipe = *recipe_id( "leather_belt" ); grant_skills_to_character( get_player_character(), test_recipe ); int unmitigated_time_taken = test_recipe.batch_time( get_player_character(), 1, 1, 0 ); @@ -965,3 +932,35 @@ TEST_CASE( "book_proficiency_mitigation", "[crafting][proficiency]" ) } } } + +TEST_CASE( "partial_proficiency_mitigation", "[crafting][proficiency]" ) +{ + GIVEN( "a recipe with required proficiencies" ) { + clear_avatar(); + clear_map(); + const recipe &test_recipe = *recipe_id( "leather_belt" ); + + grant_skills_to_character( get_player_character(), test_recipe ); + int unmitigated_time_taken = test_recipe.batch_time( get_player_character(), 1, 1, 0 ); + + WHEN( "player acquires partial proficiency" ) { + int np = 0; + for( const proficiency_id &prof : test_recipe.assist_proficiencies() ) { + np++; + get_player_character().practice_proficiency( prof, + get_player_character().proficiency_training_needed( prof ) / 2 ); + } + int mitigated_time_taken = test_recipe.batch_time( get_player_character(), 1, 1, 0 ); + THEN( "it takes less time to craft the recipe" ) { + CHECK( mitigated_time_taken < unmitigated_time_taken ); + } + AND_WHEN( "player acquires missing proficiencies" ) { + grant_proficiencies_to_character( get_player_character(), test_recipe, true ); + int proficient_time_taken = test_recipe.batch_time( get_player_character(), 1, 1, 0 ); + THEN( "it takes even less time to craft the recipe" ) { + CHECK( proficient_time_taken < mitigated_time_taken ); + } + } + } + } +} From 31be9a376b3809612629e69d603e9d9603d03508 Mon Sep 17 00:00:00 2001 From: SenpaiSlime <83998268+SenpaiSlime@users.noreply.github.com> Date: Thu, 8 Jul 2021 13:34:46 -0700 Subject: [PATCH 072/116] uniformed soldier zombies for military bases (#49255) * uniformed soldier zombies for military bases * Fixing mistakes, changing up the monsterdrops to be better * Update zed-classic.json * Update zombie_milbase_personnel.json * Now with hats! * whoops * Changed them to zed soldier folder, now copy from pilot instead of regular zeds * Updated drop list * Update data/json/monstergroups/military.json Co-authored-by: LaVeyanFiend <51099123+LaVeyanFiend@users.noreply.github.com> * Update data/json/itemgroups/Clothing_Gear/clothing.json Co-authored-by: LaVeyanFiend <51099123+LaVeyanFiend@users.noreply.github.com> * Update clothing.json * whoops, again * Linting files * Update data/json/monsters/zed_soldiers.json Co-authored-by: LaVeyanFiend <51099123+LaVeyanFiend@users.noreply.github.com> Co-authored-by: LaVeyanFiend <51099123+LaVeyanFiend@users.noreply.github.com> --- .../itemgroups/Clothing_Gear/clothing.json | 14 ++++++++++++- .../zombie_milbase_personnel.json | 20 +++++++++++++++++++ data/json/monstergroups/military.json | 11 ++++++---- data/json/monsters/zed_soldiers.json | 11 ++++++++++ 4 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 data/json/monsterdrops/zombie_milbase_personnel.json diff --git a/data/json/itemgroups/Clothing_Gear/clothing.json b/data/json/itemgroups/Clothing_Gear/clothing.json index 38006e9cecf33..f15a55da93cb9 100644 --- a/data/json/itemgroups/Clothing_Gear/clothing.json +++ b/data/json/itemgroups/Clothing_Gear/clothing.json @@ -248,6 +248,18 @@ "subtype": "distribution", "entries": [ { "item": "tshirt" } ] }, + { + "id": "clothing_military_headwear", + "type": "item_group", + "subtype": "distribution", + "//": "add in field caps when they are added to the game.", + "items": [ + { "item": "beret", "prob": 60 }, + { "item": "hat_boonie", "prob": 38 }, + { "item": "turban", "prob": 1 }, + { "item": "headscarf", "prob": 1 } + ] + }, { "id": "clothing_outdoor_pants", "type": "item_group", @@ -544,7 +556,7 @@ "id": "boxing_clothes", "type": "item_group", "subtype": "distribution", - "entries": [ + "items": [ { "item": "tank_top", "prob": 40 }, { "item": "shorts", "prob": 40 }, { "item": "boxing_gloves", "prob": 50 }, diff --git a/data/json/monsterdrops/zombie_milbase_personnel.json b/data/json/monsterdrops/zombie_milbase_personnel.json new file mode 100644 index 0000000000000..144261abbb259 --- /dev/null +++ b/data/json/monsterdrops/zombie_milbase_personnel.json @@ -0,0 +1,20 @@ +[ + { + "id": "mon_zombie_milbase_personnel_death_drops", + "type": "item_group", + "subtype": "collection", + "magazine": 100, + "ammo": 60, + "entries": [ + { "group": "clothing_military", "damage": [ 0, 4 ] }, + { "group": "clothing_military_headwear", "prob": 40, "damage": [ 0, 4 ] }, + { "group": "gear_soldier_sidearm", "prob": 10 }, + { "item": "two_way_radio", "charges": [ 0, 300 ], "prob": 25 }, + { "group": "wallets_military", "prob": 5 }, + { "group": "clothing_glasses", "damage": [ 0, 4 ], "prob": 5 }, + { "item": "wristwatch", "damage": [ 0, 4 ], "prob": 33 }, + { "group": "mil_food_nodrugs", "prob": 15 }, + { "group": "misc_smoking", "prob": 10 } + ] + } +] diff --git a/data/json/monstergroups/military.json b/data/json/monstergroups/military.json index 235912d435406..d2315df385800 100644 --- a/data/json/monstergroups/military.json +++ b/data/json/monstergroups/military.json @@ -47,12 +47,13 @@ { "monster": "mon_zombie_kevlar_1", "freq": 50, "cost_multiplier": 10 }, { "monster": "mon_zombie_flamer", "freq": 50, "cost_multiplier": 5 }, { "monster": "mon_zombie_military_pilot", "freq": 5, "cost_multiplier": 1 }, + { "monster": "mon_zombie_milbase_personnel", "freq": 40, "cost_multiplier": 1 }, { "monster": "mon_zombie_bio_op", "freq": 30, "cost_multiplier": 5 }, { "monster": "mon_zombie_soldier_blackops_1", "freq": 15, "cost_multiplier": 10 }, { "monster": "mon_zombie_armored", "freq": 5, "cost_multiplier": 5 }, { "monster": "mon_zombie_scorched", "freq": 25, "cost_multiplier": 1 }, { "monster": "mon_zombie_hazmat", "freq": 25, "cost_multiplier": 1 }, - { "monster": "mon_zombie", "freq": 50, "cost_multiplier": 1 } + { "monster": "mon_zombie", "freq": 10, "cost_multiplier": 1 } ] }, { @@ -61,8 +62,8 @@ "//": "Civilians with soldiers and burned ones.", "default": "mon_zombie", "monsters": [ - { "monster": "mon_zombie_fat", "freq": 100, "cost_multiplier": 2 }, - { "monster": "mon_zombie_child", "freq": 40, "cost_multiplier": 1 }, + { "monster": "mon_zombie_fat", "freq": 60, "cost_multiplier": 2 }, + { "monster": "mon_zombie_child", "freq": 30, "cost_multiplier": 1 }, { "monster": "mon_zombie_tough", "freq": 40, "cost_multiplier": 3 }, { "monster": "mon_zombie_rot", "freq": 20, "cost_multiplier": 2 }, { "monster": "mon_zombie_crawler", "freq": 10, "cost_multiplier": 2 }, @@ -80,6 +81,7 @@ { "monster": "mon_zombie_survivor_elite", "freq": 1, "cost_multiplier": 25, "starts": 1440 }, { "monster": "mon_zombie_scorched", "freq": 25, "cost_multiplier": 2 }, { "monster": "mon_zombie_soldier", "freq": 200, "cost_multiplier": 2 }, + { "monster": "mon_zombie_milbase_personnel", "freq": 50, "cost_multiplier": 1 }, { "monster": "mon_zombie_military_pilot", "freq": 5, "cost_multiplier": 1 }, { "monster": "mon_zombie_flamer", "freq": 1, "cost_multiplier": 30 } ] @@ -90,7 +92,7 @@ "//": "Civilians with soldiers, doctors and burned ones. More hazmat.", "default": "mon_zombie_soldier", "monsters": [ - { "monster": "mon_zombie", "freq": 100, "cost_multiplier": 2 }, + { "monster": "mon_zombie", "freq": 50, "cost_multiplier": 2 }, { "monster": "mon_zombie_fat", "freq": 60, "cost_multiplier": 2 }, { "monster": "mon_zombie_child", "freq": 40, "cost_multiplier": 1 }, { "monster": "mon_zombie_tough", "freq": 40, "cost_multiplier": 3 }, @@ -110,6 +112,7 @@ { "monster": "mon_zombie_survivor_elite", "freq": 1, "cost_multiplier": 25, "starts": 1440 }, { "monster": "mon_zombie_scorched", "freq": 25, "cost_multiplier": 1 }, { "monster": "mon_zombie_soldier", "freq": 200, "cost_multiplier": 2 }, + { "monster": "mon_zombie_milbase_personnel", "freq": 50, "cost_multiplier": 1 }, { "monster": "mon_zombie_military_pilot", "freq": 20, "cost_multiplier": 1 }, { "monster": "mon_zombie_flamer", "freq": 1, "cost_multiplier": 30 }, { "monster": "mon_zombie_scientist", "freq": 100, "cost_multiplier": 1 } diff --git a/data/json/monsters/zed_soldiers.json b/data/json/monsters/zed_soldiers.json index b4b9e30c3a5d3..f6054fd132d03 100644 --- a/data/json/monsters/zed_soldiers.json +++ b/data/json/monsters/zed_soldiers.json @@ -305,6 +305,17 @@ "FILTHY" ] }, + { + "id": "mon_zombie_milbase_personnel", + "type": "MONSTER", + "name": { "str": "uniformed zombie" }, + "description": "This undead soldier is adorned in standard military fatigues. It carries itself rather steadily for a zombie.", + "copy-from": "mon_zombie_military_pilot", + "looks_like": "mon_zombie", + "delete": { "flags": [ "NOHEAD" ] }, + "upgrades": { "half_life": 18, "into_group": "GROUP_ZOMBIE_UPGRADE" }, + "death_drops": "mon_zombie_milbase_personnel_death_drops" + }, { "id": "mon_zombie_flamer", "type": "MONSTER", From 8ce3dc53a7453df6b2589e2b52103ba11a5aedd2 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Thu, 8 Jul 2021 15:17:12 -0700 Subject: [PATCH 073/116] Implement mod tracking for items and furn/terrain (#49723) Track which mods the items are modified in, and in what order, display it in the descriptions. --- src/descriptions.cpp | 13 +++++++++-- src/generic_factory.h | 5 +++++ src/item.cpp | 9 ++++++++ src/item_factory.cpp | 5 +++++ src/iteminfo_query.h | 1 + src/itype.h | 2 ++ src/mapdata.h | 6 +++++ src/mod_tracker.h | 51 +++++++++++++++++++++++++++++++++++++++++++ src/output.h | 16 ++++++++++++-- 9 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 src/mod_tracker.h diff --git a/src/descriptions.cpp b/src/descriptions.cpp index 4e82010dc3a21..bd99641573f83 100644 --- a/src/descriptions.cpp +++ b/src/descriptions.cpp @@ -14,6 +14,7 @@ #include "input.h" #include "map.h" #include "mapdata.h" +#include "mod_manager.h" #include "output.h" #include "string_formatter.h" #include "translations.h" @@ -108,7 +109,11 @@ void game::extended_description( const tripoint &p ) desc = _( "You do not see any furniture here." ); } else { const furn_id fid = m.furn( p ); - desc = fid.obj().extended_description(); + const std::string mod_src = enumerate_as_string( fid->src.begin(), + fid->src.end(), []( const std::pair &source ) { + return string_format( "'%s'", source.second->name() ); + }, enumeration_conjunction::arrow ); + desc = string_format( _( "Origin: %s\n%s" ), mod_src, fid->extended_description() ); } break; case description_target::terrain: @@ -116,7 +121,11 @@ void game::extended_description( const tripoint &p ) desc = _( "You can't see the terrain here." ); } else { const ter_id tid = m.ter( p ); - desc = tid.obj().extended_description(); + const std::string mod_src = enumerate_as_string( tid->src.begin(), + tid->src.end(), []( const std::pair &source ) { + return string_format( "'%s'", source.second->name() ); + }, enumeration_conjunction::arrow ); + desc = string_format( _( "Origin: %s\n%s" ), mod_src, tid->extended_description() ); } break; } diff --git a/src/generic_factory.h b/src/generic_factory.h index 8fdf757e52186..b5c6a4be49bbb 100644 --- a/src/generic_factory.h +++ b/src/generic_factory.h @@ -16,6 +16,7 @@ #include "init.h" #include "int_id.h" #include "json.h" +#include "mod_tracker.h" #include "output.h" #include "string_id.h" #include "units.h" @@ -264,6 +265,7 @@ class generic_factory } if( jo.has_string( id_member_name ) ) { def.id = string_id( jo.get_string( id_member_name ) ); + assign_src( def, src ); def.load( jo, src ); insert( def ); @@ -284,6 +286,7 @@ class generic_factory break; } def.id = string_id( e ); + assign_src( def, src ); def.load( jo, src ); insert( def ); } @@ -294,6 +297,7 @@ class generic_factory } else if( jo.has_string( legacy_id_member_name ) ) { def.id = string_id( jo.get_string( legacy_id_member_name ) ); + assign_src( def, src ); def.load( jo, src ); insert( def ); @@ -314,6 +318,7 @@ class generic_factory break; } def.id = string_id( e ); + assign_src( def, src ); def.load( jo, src ); insert( def ); } diff --git a/src/item.cpp b/src/item.cpp index c2ac84f50b927..151f45191a439 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -68,6 +68,7 @@ #include "martialarts.h" #include "material.h" #include "messages.h" +#include "mod_manager.h" #include "monster.h" #include "mtype.h" #include "npc.h" @@ -1697,6 +1698,14 @@ double item::average_dps( const Character &guy ) const void item::basic_info( std::vector &info, const iteminfo_query *parts, int batch, bool /* debug */ ) const { + if( parts->test( iteminfo_parts::BASE_MOD_SRC ) ) { + info.emplace_back( "BASE", string_format( _( "Origin: %s" ), enumerate_as_string( type->src.begin(), + type->src.end(), []( const std::pair &source ) { + return string_format( "'%s'", source.second->name() ); + }, enumeration_conjunction::arrow ) ) ); + insert_separation_line( info ); + } + const std::string space = " "; if( parts->test( iteminfo_parts::BASE_MATERIAL ) ) { const std::vector mat_types = made_of_types(); diff --git a/src/item_factory.cpp b/src/item_factory.cpp index 26806acef2786..0ddabf179e39d 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -3079,6 +3079,11 @@ void Item_factory::load_basic_info( const JsonObject &jo, itype &def, const std: jo.read( "id", def.id, true ); } + if( !def.src.empty() && def.src.back().first != def.id ) { + def.src.clear(); + } + def.src.emplace_back( def.id, mod_id( src ) ); + if( def.magazines.empty() ) { migrate_mag_from_pockets( def ); } diff --git a/src/iteminfo_query.h b/src/iteminfo_query.h index 895527ad29d59..15de86340f66b 100644 --- a/src/iteminfo_query.h +++ b/src/iteminfo_query.h @@ -9,6 +9,7 @@ enum class iteminfo_parts : size_t { BASE_CATEGORY = 0, + BASE_MOD_SRC, BASE_PRICE, BASE_BARTER, BASE_OWNER, diff --git a/src/itype.h b/src/itype.h index a39feaead0cf3..c6e67c0251678 100644 --- a/src/itype.h +++ b/src/itype.h @@ -849,6 +849,8 @@ struct itype { using FlagsSetType = std::set; + std::vector> src; + /** * Slots for various item type properties. Each slot may contain a valid pointer or null, check * this before using it. diff --git a/src/mapdata.h b/src/mapdata.h index ade8b739e37a1..b355717e544dd 100644 --- a/src/mapdata.h +++ b/src/mapdata.h @@ -367,6 +367,9 @@ struct map_data_common_t { * Short for terrain type. This struct defines all of the metadata for a given terrain id (an enum below). */ struct ter_t : map_data_common_t { + + std::vector> src; + ter_str_id id; // The terrain's ID. Must be set, must be unique. ter_str_id open; // Open action: transform into terrain with matching id ter_str_id close; // Close action: transform into terrain with matching id @@ -397,6 +400,9 @@ void reset_furn_ter(); */ struct furn_t : map_data_common_t { + + std::vector> src; + furn_str_id id; furn_str_id open; // Open action: transform into furniture with matching id furn_str_id close; // Close action: transform into furniture with matching id diff --git a/src/mod_tracker.h b/src/mod_tracker.h new file mode 100644 index 0000000000000..ef7671730641d --- /dev/null +++ b/src/mod_tracker.h @@ -0,0 +1,51 @@ +#pragma once +#ifndef CATA_SRC_MOD_TRACKER_H +#define CATA_SRC_MOD_TRACKER_H + +#include + +#include "cata_void.h" +#include "type_id.h" + +/** + * Mod Tracking: + * + * These functions live here to provide various JSON-loaded entities + * with the ids of the mods that they are from. + * + * To subscribe, a JSON-loaded entity simply needs to have a + * 'std::vector, mod_id> src;' member. + * (As well as storing their id in an 'id' member of either string or int id type) + * + * If the entity is loaded with generic_factory, no further changes are needed. + * If the entity is not loaded with generic_factory, 'assign_src()' must be called sometime + * after the 'id' member has been assigned. + */ + +/** Template magic to determine if the conditions above are satisfied */ +template> +struct has_src_member : std::false_type {}; + +template +struct has_src_member().src.emplace_back( std::declval().id, mod_id() ) )>> : +std::true_type {}; + +/** Dummy function, for if those conditions are not satisfied */ +template < typename T, typename std::enable_if_t < !has_src_member::value > * = nullptr > +void assign_src( T &, const std::string & ) +{ +} + +/** If those conditions are satisfied, keep track of where this item has been modified */ +template::value > * = nullptr> +void assign_src( T &def, const std::string &src ) +{ + // We need to make sure we're keeping where this entity has been loaded + // If the id this was last loaded with is not this one, discard the history and start again + if( !def.src.empty() && def.src.back().first != def.id ) { + def.src.clear(); + } + def.src.emplace_back( def.id, mod_id( src ) ); +} + +#endif // CATA_SRC_MOD_TRACKER_H diff --git a/src/output.h b/src/output.h index f4732ae2cc447..131fc5d75ce92 100644 --- a/src/output.h +++ b/src/output.h @@ -672,7 +672,8 @@ inline std::string get_labeled_bar( const double val, const int width, const std enum class enumeration_conjunction : int { none, and_, - or_ + or_, + arrow }; /** @@ -692,18 +693,29 @@ std::string enumerate_as_string( const _Container &values, return ( values.size() > 2 ? _( ", and " ) : _( " and " ) ); case enumeration_conjunction::or_: return ( values.size() > 2 ? _( ", or " ) : _( " or " ) ); + case enumeration_conjunction::arrow: + return _( " > " ); } debugmsg( "Unexpected conjunction" ); return _( ", " ); } (); + const std::string separator = [&conj]() { + switch( conj ) { + case enumeration_conjunction::arrow: + return _( " > " ); + default: + return _( ", " ); + } + } + (); std::string res; for( auto iter = values.begin(); iter != values.end(); ++iter ) { if( iter != values.begin() ) { if( std::next( iter ) == values.end() ) { res += final_separator; } else { - res += _( ", " ); + res += separator; } } res += *iter; From 6b84b0a9ee3a6a87d0461e4ed2819e6f4f35d83e Mon Sep 17 00:00:00 2001 From: Eric <52087122+Ramza13@users.noreply.github.com> Date: Thu, 8 Jul 2021 21:23:35 -0400 Subject: [PATCH 074/116] Unhardcode bionics in item action menu (#47909) * Unhardcode bionics in item action menu Co-authored-by: Kevin Granade --- src/character.cpp | 12 ++++++++++++ src/character.h | 3 +++ src/item_action.cpp | 18 ++++-------------- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/character.cpp b/src/character.cpp index e0f4cb6f7507f..d6061bf4fd2c1 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -2260,6 +2260,18 @@ bool Character::has_any_bionic() const return !get_bionics().empty(); } +std::vector Character::get_pseudo_items() const +{ + std::vector result; + for( const bionic &bio : *my_bionics ) { + const bionic_data &bid = bio.info(); + if( bid.fake_item && ( !bid.activated || bio.powered ) ) { + result.emplace_back( item( bid.fake_item ) ); + } + } + return result; +} + bionic_id Character::get_remote_fueled_bionic() const { for( const bionic_id &bid : get_bionics() ) { diff --git a/src/character.h b/src/character.h index 250f85bc16b98..f934faf72571a 100644 --- a/src/character.h +++ b/src/character.h @@ -1234,6 +1234,9 @@ class Character : public Creature, public visitable /** Handles bionic activation effects of the entered bionic, returns if anything activated */ bool activate_bionic( int b, bool eff_only = false, bool *close_bionics_ui = nullptr ); std::vector get_bionics() const; + std::vector get_pseudo_items() const; + /** Returns amount of Storage CBMs in the corpse **/ + std::pair amount_of_storage_bionics() const; /** Returns true if the player has the entered bionic id */ bool has_bionic( const bionic_id &b ) const; /** Returns true if the player has the entered bionic id and it is powered on */ diff --git a/src/item_action.cpp b/src/item_action.cpp index 14bdf91ef9eb7..2e332be0888de 100644 --- a/src/item_action.cpp +++ b/src/item_action.cpp @@ -40,10 +40,6 @@ class Character; static const std::string errstring( "ERROR" ); -static const bionic_id bio_tools( "bio_tools" ); -static const bionic_id bio_claws( "bio_claws" ); -static const bionic_id bio_claws_weapon( "bio_claws_weapon" ); - static const itype_id itype_UPS( "UPS" ); struct tripoint; @@ -254,17 +250,11 @@ void game::item_action_menu() const auto &gen = item_action_generator::generator(); const action_map &item_actions = gen.get_item_action_map(); - // HACK: A bit of a hack for now. If more pseudos get implemented, this should be un-hacked - std::vector pseudos; - item toolset( "toolset", calendar::turn ); - if( u.has_active_bionic( bio_tools ) ) { - pseudos.push_back( &toolset ); - } - item bio_claws_item( static_cast( bio_claws_weapon ), calendar::turn ); - if( u.has_active_bionic( bio_claws ) ) { - pseudos.push_back( &bio_claws_item ); + std::vector pseudo_items = get_player_character().get_pseudo_items(); + std::vector pseudos( pseudo_items.size() ); + for( item &pseudo : pseudo_items ) { + pseudos.push_back( &pseudo ); } - item_action_map iactions = gen.map_actions_to_items( u, pseudos ); if( iactions.empty() ) { popup( _( "You don't have any items with registered uses" ) ); From c3c98c52406ba60b04cfd99360878bc885152764 Mon Sep 17 00:00:00 2001 From: AccountAlias <85119255+AccountAlias@users.noreply.github.com> Date: Thu, 8 Jul 2021 22:43:22 -0400 Subject: [PATCH 075/116] Make cooking oil unhealthy (#49758) --- data/json/items/comestibles/drink_other.json | 1 + 1 file changed, 1 insertion(+) diff --git a/data/json/items/comestibles/drink_other.json b/data/json/items/comestibles/drink_other.json index e5cb02f33e9f8..a23d6bd7a82d4 100644 --- a/data/json/items/comestibles/drink_other.json +++ b/data/json/items/comestibles/drink_other.json @@ -168,6 +168,7 @@ "comestible_type": "DRINK", "symbol": "~", "quench": -1, + "healthy": -2, "calories": 127, "description": "Thin yellow vegetable oil used for cooking.", "price": 40, From c0e047a9a37cd725b1bcf676d91b52b4addb3adf Mon Sep 17 00:00:00 2001 From: casswedson <58050969+casswedson@users.noreply.github.com> Date: Thu, 8 Jul 2021 21:46:25 -0500 Subject: [PATCH 076/116] More professions with vehicles (#49343) * More professions with vehicles from https://github.com/GMC-Modding-Team/Community-Mod-Compilation-redux/tree/master/data/Unleash_The_Mods/Working_mods/Eirs_road_rage + minor edits * Feedback and two more professions from Eirenex Co-authored-by: @EirenexTheDragon * Apply suggestions from code review Co-authored-by: LaVeyanFiend <51099123+LaVeyanFiend@users.noreply.github.com> * change the descriptions a bit Co-authored-by: LaVeyanFiend <51099123+LaVeyanFiend@users.noreply.github.com> --- data/json/professions.json | 234 +++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) diff --git a/data/json/professions.json b/data/json/professions.json index e60fc867d5c37..7b1e2f501c5e5 100644 --- a/data/json/professions.json +++ b/data/json/professions.json @@ -11,6 +11,15 @@ "id": "army_mags_mp5", "entries": [ { "item": "mp5mag", "ammo-item": "9mm", "charges": 30 }, { "item": "mp5mag", "ammo-item": "9mm", "charges": 30 } ] }, + { + "type": "item_group", + "subtype": "collection", + "id": "ranger_mags", + "entries": [ + { "item": "p320mag_13rd_357sig", "ammo-item": "357sig_fmj", "charges": 13 }, + { "item": "p320mag_13rd_357sig", "ammo-item": "357sig_fmj", "charges": 13 } + ] + }, { "type": "item_group", "subtype": "collection", @@ -1814,6 +1823,231 @@ "female": [ "bra", "panties" ] } }, + { + "id": "car_survivor", + "type": "profession", + "name": "Day Driver", + "description": "You love driving and making a living with it. On your way to pick up someone with your car, you start to notice all the chaos happening around you. Not wanting to be a part of it, you took a long detour to safety, only to find yourself in a different place. All that's left is your car.", + "points": 4, + "skills": [ { "level": 1, "name": "barter" }, { "level": 4, "name": "driving" } ], + "vehicle": "car", + "items": { + "both": { + "items": [ "sneakers", "socks", "jeans", "tshirt", "wristwatch", "jacket_light", "water_clean" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, + "male": [ "boxer_shorts" ], + "female": [ "panties", "bra" ] + } + }, + { + "id": "emt_firefighter", + "type": "profession", + "name": "EMT Firefighter", + "description": "You love driving as much as you love extinguishing fire and helping the wounded, where every second counts. On your way to respond to an emergency call with your firetruck, you encounter chaos in the city, recklessness and violence are plentiful. Not wanting to use of the streets covered in burning trash and debris, you took a long detour to your fire station, only to find yourself unsure of the route back. Looks like the only emergency you will respond to will be your own.", + "points": 5, + "skills": [ { "level": 3, "name": "firstaid" }, { "level": 3, "name": "driving" }, { "level": 1, "name": "electronics" } ], + "vehicle": "fire_engine", + "items": { + "both": { + "items": [ + "boots_bunker", + "bunker_coat", + "bunker_pants", + "dress_shirt", + "fire_gauntlets", + "firehelmet", + "glasses_safety", + "mbag", + "nomex_socks", + "water_clean", + "wristwatch" + ], + "entries": [ + { "group": "full_1st_aid" }, + { "group": "charged_cell_phone" }, + { "item": "ear_plugs", "custom-flags": [ "no_auto_equip" ] }, + { "item": "halligan", "container-item": "fireman_belt" } + ] + }, + "male": [ "boxer_shorts" ], + "female": [ "panties", "bra" ] + } + }, + { + "id": "handymanservice", + "type": "profession", + "name": "Serviceman", + "description": "Employed by a large company, you performed services directly at annoying customer's homes and also troubleshoot problems with their devices. After you finally finished replacing the 'wifi-cable' you finally were able to go back to your company, along the road back you notice all the chaos happening around you. Not wanting to get in the way of angry looking protesters, you took an old neglected side road, only to find yourself low on gas in a truly deserted place. Couldn't this all just happen before you finished your work?", + "points": 4, + "skills": [ { "level": 3, "name": "electronics" }, { "level": 2, "name": "driving" }, { "level": 1, "name": "mechanics" } ], + "vehicle": "cube_van_cheap", + "items": { + "both": { + "items": [ + "dress_shirt", + "socks", + "boots", + "pants", + "multitool", + "wristwatch", + "mbag", + "water_clean", + "gloves_work", + "hammer", + "hat_ball" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, + "male": [ "boxer_shorts" ], + "female": [ "panties", "bra" ] + } + }, + { + "id": "bus_driver", + "type": "profession", + "name": "Bus Driver", + "description": "You are making a living with delivering noisy brats to their schools, where you wish with every delivery, that they don't break a seat or window for you. On your way to pick up the first row of brats, you start to notice all the chaos happening around you. By the time you arrive at the station, all the brats look like zombies, so you took a long detour to safety, only to find yourself in a different place. At last you have been freed of the hellish noises they release, but new ones are on the merge.", + "points": 4, + "skills": [ { "level": 1, "name": "barter" }, { "level": 3, "name": "driving" } ], + "vehicle": "schoolbus", + "items": { + "both": { + "items": [ "sneakers", "socks", "jeans", "tshirt", "wristwatch", "jacket_light", "water_clean", "hat_ball" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, + "male": [ "boxer_shorts" ], + "female": [ "panties", "bra" ] + } + }, + { + "id": "cop_car", + "type": "profession", + "name": "Police Interceptor", + "description": "As on-duty officer, you received the call and got ready to respond to the robbery with your patrol car. After arriving at the scene, it was soon you who needed rescuing, and you were lucky to escape with your life and car. No one responds on the radio anymore either. Who's going to respect your authority when the government this badge represents might not even exist anymore?", + "points": 6, + "skills": [ { "level": 3, "name": "gun" }, { "level": 3, "name": "pistol" }, { "level": 3, "name": "driving" } ], + "vehicle": "policecar", + "traits": [ "PROF_POLICE" ], + "items": { + "both": { + "items": [ "pants_army", "socks", "badge_deputy", "sheriffshirt", "police_belt", "boots", "whistle", "kevlar", "wristwatch" ], + "entries": [ + { "group": "charged_cell_phone" }, + { "group": "charged_two_way_radio" }, + { "item": "ear_plugs", "custom-flags": [ "no_auto_equip" ] }, + { "item": "usp_45", "ammo-item": "45_acp", "charges": 12, "container-item": "holster" }, + { "item": "legpouch_large", "contents-group": "army_mags_usp45" } + ] + }, + "male": [ "boxer_shorts" ], + "female": [ "bra", "boy_shorts" ] + } + }, + { + "type": "profession", + "id": "militia_car", + "name": "Militia", + "description": "You’ve long since prepared yourself for this outcome. You, alongside a band of compatriots, started a hideout in the woods from which to launch looting raids on a jury-rigged pickup. The last run went poorly, leaving you last alive amongst your former comrades. Every breath you take now is an act of rebellion against the cruelty of this doomed world. Do not let that flame of hope perish inside you.", + "points": 8, + "skills": [ + { "level": 2, "name": "gun" }, + { "level": 2, "name": "rifle" }, + { "level": 3, "name": "driving" }, + { "level": 1, "name": "mechanics" } + ], + "vehicle": "pickup_technical", + "items": { + "both": { + "items": [ + "pants_army", + "jacket_army", + "socks", + "sweatshirt", + "boots", + "cig", + "elbow_pads", + "slingpack", + "kevlar", + "balclava", + "knee_pads", + "beret", + "wristwatch", + "water_clean" + ], + "entries": [ + { "group": "charged_cell_phone" }, + { "item": "ear_plugs", "custom-flags": [ "no_auto_equip" ] }, + { "item": "knife_combat", "container-item": "sheath" }, + { "item": "m9", "ammo-item": "9mm", "charges": 15, "container-item": "holster" }, + { "item": "chestrig", "contents-group": "army_mags_m4" }, + { "item": "lighter", "charges": 100 }, + { "item": "ar15", "ammo-item": "556", "charges": 30, "contents-item": [ "shoulder_strap" ] } + ] + }, + "male": [ "boxer_shorts" ], + "female": [ "bra", "boy_shorts" ] + } + }, + { + "type": "profession", + "id": "park_ranger", + "name": "Park Ranger", + "description": "As a park ranger, most things you usually do is maintain the park, teach people how to not start a fire in the forest, patrol, and check out stuff on your daily to-do list. After arriving at a deserted camp with notes left from survivors, you took upon heeding their warning, and packed at your station with some supplies alongside your pickup, just before the station was overrun as well.", + "points": 9, + "skills": [ + { "level": 1, "name": "gun" }, + { "level": 1, "name": "pistol" }, + { "level": 3, "name": "driving" }, + { "level": 2, "name": "firstaid" }, + { "level": 1, "name": "fabrication" }, + { "level": 2, "name": "swimming" }, + { "level": 2, "name": "survival" } + ], + "vehicle": "pickup", + "items": { + "both": { + "items": [ + "boots_hiking", + "cowboy_hat", + "diving_watch", + "e_tool", + "hammer", + "knife_folding", + "multitool", + "pants_army", + "police_belt", + "rollmat", + "sheriffshirt", + "socks", + "travelpack", + "vest", + "water_clean", + "whistle_multitool" + ], + "entries": [ + { "group": "charged_cell_phone" }, + { "group": "charged_flashlight" }, + { "group": "charged_two_way_radio" }, + { "group": "full_1st_aid" }, + { "item": "black_pen", "charges": 100 }, + { "item": "coat_rain", "custom-flags": [ "no_auto_equip" ] }, + { "item": "ear_plugs", "custom-flags": [ "no_auto_equip" ] }, + { "item": "file" }, + { "item": "legpouch_large", "contents-group": "ranger_mags" }, + { "item": "lighter", "charges": 100 }, + { "item": "p320_357sig", "ammo-item": "357sig_fmj", "charges": 13, "container-item": "holster" }, + { "item": "paper", "charges": 20, "container-item": "leather_journal" }, + { "item": "permanent_marker", "charges": 500 }, + { "item": "roadmap" }, + { "item": "sm_extinguisher", "charges": 10 }, + { "item": "trailmap" } + ] + }, + "male": [ "boxer_shorts" ], + "female": [ "bra", "boy_shorts" ] + } + }, { "type": "profession", "id": "lumberjack", From 29b322ebc81da588609094f6e6407035585549db Mon Sep 17 00:00:00 2001 From: Salty Panda Date: Fri, 9 Jul 2021 04:56:32 +0200 Subject: [PATCH 077/116] Balance quarterstaff and sling staff (#49082) * Balance quarterstaves Remove durable melee, reduce discrepancies between quarterstaff and staff sling, add staff sling to quarterstaff martial arts, adjust quarterstaves according to wood density and recipe components' weight/vol * Update dps tests for quarterstaves, add tests for sling staff * Update data/json/items/ranged/slings.json --- data/json/items/melee/bludgeons.json | 18 +++++++++--------- data/json/items/ranged/slings.json | 9 ++++----- data/json/martialarts.json | 2 ++ tests/effective_dps_test.cpp | 7 ++++--- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/data/json/items/melee/bludgeons.json b/data/json/items/melee/bludgeons.json index a3d0085ad66f1..7d6f391c00a16 100644 --- a/data/json/items/melee/bludgeons.json +++ b/data/json/items/melee/bludgeons.json @@ -541,9 +541,9 @@ "price_postapoc": 1500, "material": [ "wood", "iron" ], "techniques": [ "WBLOCK_2", "RAPID", "SWEEP" ], - "flags": [ "DURABLE_MELEE", "NONCONDUCTIVE", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ], - "weight": "2200 g", - "volume": "3 L", + "flags": [ "NONCONDUCTIVE", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ], + "weight": "1750 g", + "volume": "1550 ml", "longest_side": "180 cm", "bashing": 32, "category": "weapons", @@ -905,9 +905,9 @@ "price": 4000, "material": [ "wood" ], "techniques": [ "WBLOCK_2", "RAPID", "SWEEP" ], - "flags": [ "DURABLE_MELEE", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ], - "weight": "1400 g", - "volume": "3 L", + "flags": [ "SHEATH_SPEAR", "ALWAYS_TWOHAND" ], + "weight": "1500 g", + "volume": "1500 ml", "longest_side": "180 cm", "bashing": 26, "category": "weapons", @@ -1013,8 +1013,8 @@ "category": "weapons", "name": { "str": "powered quarterstaff", "str_pl": "powered quarterstaves" }, "description": "This is an ironshod quarterstaff that has a high-voltage stun gun built into the handle. The stun gun is wired to the metal caps at either end of the staff, allowing you to zap a dangerous opponent should beating them senseless with it prove too hazardous.", - "weight": "2351 g", - "volume": "3250 ml", + "weight": "1910 g", + "volume": "1800 ml", "longest_side": "180 cm", "price": 8000, "to_hit": 3, @@ -1028,7 +1028,7 @@ "qualities": [ [ "HAMMER", 1 ] ], "techniques": [ "WBLOCK_2", "RAPID", "SWEEP" ], "use_action": [ "TAZER" ], - "flags": [ "DURABLE_MELEE", "NONCONDUCTIVE", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ], + "flags": [ "NONCONDUCTIVE", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ], "pocket_data": [ { "pocket_type": "MAGAZINE_WELL", diff --git a/data/json/items/ranged/slings.json b/data/json/items/ranged/slings.json index 64c185dbb10e3..aa587fa1243fb 100644 --- a/data/json/items/ranged/slings.json +++ b/data/json/items/ranged/slings.json @@ -53,7 +53,7 @@ }, { "id": "staff_sling", - "looks_like": "slingshot", + "looks_like": "quarterstaff", "type": "GUN", "symbol": "(", "color": "brown", @@ -67,7 +67,6 @@ "NEVER_JAMS", "PRIMITIVE_RANGED_WEAPON", "BELTED", - "DURABLE_MELEE", "NONCONDUCTIVE", "SHEATH_SPEAR", "ALWAYS_TWOHAND", @@ -77,13 +76,13 @@ "techniques": [ "WBLOCK_2", "RAPID", "SWEEP" ], "skill": "throw", "ammo": [ "rock" ], - "weight": "2000 g", - "volume": "3 L", + "weight": "1600 g", + "volume": "1650 ml", "longest_side": "180 cm", "price_postapoc": 250, "to_hit": 1, "ranged_damage": { "damage_type": "bullet", "amount": 10 }, - "bashing": 18, + "bashing": 23, "range": 10, "dispersion": 200, "durability": 8, diff --git a/data/json/martialarts.json b/data/json/martialarts.json index 75dd4b28637a0..399773d10c9d2 100644 --- a/data/json/martialarts.json +++ b/data/json/martialarts.json @@ -972,6 +972,7 @@ "nodachi_inferior", "nodachi_fake", "q_staff", + "staff_sling", "scimitar", "scimitar_fake", "scimitar_inferior", @@ -1200,6 +1201,7 @@ "PR24-extended", "primitive_knife", "q_staff", + "staff_sling", "rebar", "scimitar", "scimitar_inferior", diff --git a/tests/effective_dps_test.cpp b/tests/effective_dps_test.cpp index 6050f1713a318..75e4df3b1fee7 100644 --- a/tests/effective_dps_test.cpp +++ b/tests/effective_dps_test.cpp @@ -267,11 +267,12 @@ TEST_CASE( "expected weapon dps", "[expected][dps]" ) make_experienced_tester( test_guy ); SECTION( "staves" ) { // typical value around 18 - calc_expected_dps( test_guy, "i_staff", 18.0 ); - calc_expected_dps( test_guy, "q_staff", 17.0 ); + calc_expected_dps( test_guy, "i_staff", 22.75 ); + calc_expected_dps( test_guy, "staff_sling", 17 ); + calc_expected_dps( test_guy, "q_staff", 20.75 ); calc_expected_dps( test_guy, "l-stick_on", 17.5 ); calc_expected_dps( test_guy, "l-stick", 17.5 ); - calc_expected_dps( test_guy, "shock_staff", 17.0 ); + calc_expected_dps( test_guy, "shock_staff", 21.75 ); calc_expected_dps( test_guy, "hockey_stick", 13.75 ); calc_expected_dps( test_guy, "pool_cue", 10.0 ); calc_expected_dps( test_guy, "broom", 3.25 ); From 8e53629c441a3eccc098ca693f77972980e8d8de Mon Sep 17 00:00:00 2001 From: Jonathan Lane Date: Thu, 8 Jul 2021 23:00:54 -0400 Subject: [PATCH 078/116] Changed thawb material thickness to fix protection value (#49763) Co-authored-by: Jon Titor --- data/json/items/armor/coats.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/items/armor/coats.json b/data/json/items/armor/coats.json index 7d21ef80c0f28..6e2f18489afdf 100644 --- a/data/json/items/armor/coats.json +++ b/data/json/items/armor/coats.json @@ -2009,7 +2009,7 @@ "looks_like": "robe", "color": "white", "warmth": 20, - "material_thickness": 2, + "material_thickness": 0.2, "flags": [ "VARSIZE" ], "armor": [ { "encumbrance": 7, "coverage": 90, "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r" ] } ] }, From 789c7a468973a01d8960be4566c78193228c772a Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Thu, 8 Jul 2021 20:08:30 -0700 Subject: [PATCH 079/116] Unlimited map memory (#47253) * Encapsulate map::drawsq() arguments and clarify their meaning * Split map memory into submap-sized chunks Note: this naive implementation significantly lowers FPS * Optimize map memory access Move memorized submaps that would be affected during drawing into a 2d array. * Save/load memorized submaps; migrate old mm file * Remove leftovers from map memory limit * Some map memory cleanup * Don't save empty mm submaps * Deallocate far-away mm submaps on save; report save failure * Rework tests for map memory * Don't re-allocate region if old region contains required submaps * Remove map_memory.h from avatar.h * Rename memorized_submap -> mm_submap * Rename mm_submap::clean -> mm_submap::empty, add comments. * Improve drawsq_params interface * Remove map_memory.h from lru_cache.cpp * Add function for rectangle overlapping * Save mm_submaps in regions * Fix save/load not using avatar's global pos, improve docs. * When saving, compress mm_submaps using RLE * Simplify map rendering in ascii mode Collect map::draw code in one place, simplify indexing/bound checks. Remove the "batch drawing" optimization: it doesn't help with drawing, but harms code clarity. Instead, convert all relevant draw methods to use 'wputch' and rely on caller to position the cursor properly. * Memorize off-screen tiles in ascii mode * Fix copypasted code * Fix tile memory saving code, minor cleanup. * Add debug logging for tile memory operations * Fix broken saving for tile memory submaps with z != 0 * Lazy allocation for tile memory submaps Co-authored-by: olanti-p --- src/action.cpp | 3 +- src/animation.cpp | 9 +- src/avatar.cpp | 46 ++--- src/avatar.h | 22 +- src/cata_tiles.cpp | 16 ++ src/construction.cpp | 3 +- src/coordinate_conversions.cpp | 10 + src/coordinate_conversions.h | 6 + src/cuboid_rectangle.h | 14 ++ src/debug.cpp | 3 + src/debug.h | 2 + src/editmap.cpp | 19 +- src/game.cpp | 14 +- src/game_constants.h | 3 + src/lru_cache.cpp | 2 - src/map.cpp | 329 +++++++++++++++--------------- src/map.h | 157 ++++++++++++--- src/map_memory.cpp | 358 ++++++++++++++++++++++++++++++++- src/map_memory.h | 178 +++++++++++++++- src/options.cpp | 1 - src/point.h | 1 + src/ranged.cpp | 4 +- src/savegame_json.cpp | 220 +++++++++++++------- tests/map_memory_test.cpp | 83 +++----- tests/point_test.cpp | 72 +++++++ 25 files changed, 1170 insertions(+), 405 deletions(-) diff --git a/src/action.cpp b/src/action.cpp index 578618cb65c7b..f6c85050680d3 100644 --- a/src/action.cpp +++ b/src/action.cpp @@ -1114,8 +1114,7 @@ cata::optional choose_adjacent_highlight( const std::string &message, if( !valid.empty() ) { hilite_cb = make_shared_fast( [&]() { for( const tripoint &pos : valid ) { - here.drawsq( g->w_terrain, player_character, pos, - true, true, player_character.pos() + player_character.view_offset ); + here.drawsq( g->w_terrain, pos, drawsq_params().highlight( true ) ); } } ); g->add_draw_callback( hilite_cb ); diff --git a/src/animation.cpp b/src/animation.cpp index e4b59766446ed..20458301bc2ee 100644 --- a/src/animation.cpp +++ b/src/animation.cpp @@ -459,7 +459,7 @@ void draw_bullet_curses( map &m, const tripoint &t, const char bullet, const tri shared_ptr_fast bullet_cb = make_shared_fast( [&]() { if( p != nullptr && p->z == vp.z ) { - m.drawsq( g->w_terrain, player_character, *p, false, true, vp ); + m.drawsq( g->w_terrain, *p, drawsq_params().center( vp ) ); } mvwputch( g->w_terrain, t.xy() - vp.xy() + point( POSX, POSY ), c_red, bullet ); } ); @@ -628,7 +628,10 @@ namespace void draw_line_curses( game &g, const tripoint ¢er, const std::vector &ret, bool noreveal ) { + avatar &player_character = get_avatar(); + map &here = get_map(); + drawsq_params params = drawsq_params().highlight( true ).center( center ); for( const tripoint &p : ret ) { const Creature *critter = g.critter_at( p, true ); @@ -645,7 +648,7 @@ void draw_line_curses( game &g, const tripoint ¢er, const std::vector &points ) avatar &player_character = get_avatar(); map &here = get_map(); for( const tripoint &p : points ) { - here.drawsq( g.w_terrain, player_character, p, true, true ); + here.drawsq( g.w_terrain, p, drawsq_params().highlight( true ) ); } const tripoint p = points.empty() ? tripoint {POSX, POSY, 0} : diff --git a/src/avatar.cpp b/src/avatar.cpp index a3e5fc1738786..18e37d326911b 100644 --- a/src/avatar.cpp +++ b/src/avatar.cpp @@ -42,6 +42,7 @@ #include "kill_tracker.h" #include "make_static.h" #include "map.h" +#include "map_memory.h" #include "martialarts.h" #include "messages.h" #include "mission.h" @@ -117,12 +118,17 @@ static const json_character_flag json_flag_ALARMCLOCK( "ALARMCLOCK" ); avatar::avatar() { + player_map_memory = std::make_unique(); show_map_memory = true; active_mission = nullptr; grab_type = object_type::NONE; calorie_diary.push_front( daily_calories{} ); } +avatar::~avatar() = default; +avatar::avatar( avatar && ) = default; +avatar &avatar::operator=( avatar && ) = default; + void avatar::toggle_map_memory() { show_map_memory = !show_map_memory; @@ -133,55 +139,45 @@ bool avatar::should_show_map_memory() return show_map_memory; } -void avatar::serialize_map_memory( JsonOut &jsout ) const +bool avatar::save_map_memory() { - player_map_memory.store( jsout ); + return player_map_memory->save( get_map().getabs( pos() ) ); } -void avatar::deserialize_map_memory( JsonIn &jsin ) +void avatar::load_map_memory() { - player_map_memory.load( jsin ); + player_map_memory->load( get_map().getabs( pos() ) ); } -memorized_terrain_tile avatar::get_memorized_tile( const tripoint &pos ) const +void avatar::prepare_map_memory_region( const tripoint &p1, const tripoint &p2 ) { - return player_map_memory.get_tile( pos ); + player_map_memory->prepare_region( p1, p2 ); +} + +const memorized_terrain_tile &avatar::get_memorized_tile( const tripoint &pos ) const +{ + return player_map_memory->get_tile( pos ); } void avatar::memorize_tile( const tripoint &pos, const std::string &ter, const int subtile, const int rotation ) { - player_map_memory.memorize_tile( max_memorized_tiles(), pos, ter, subtile, rotation ); + player_map_memory->memorize_tile( pos, ter, subtile, rotation ); } void avatar::memorize_symbol( const tripoint &pos, const int symbol ) { - player_map_memory.memorize_symbol( max_memorized_tiles(), pos, symbol ); + player_map_memory->memorize_symbol( pos, symbol ); } int avatar::get_memorized_symbol( const tripoint &p ) const { - return player_map_memory.get_symbol( p ); -} - -size_t avatar::max_memorized_tiles() const -{ - // Only check traits once a turn since this is called a huge number of times. - if( current_map_memory_turn != calendar::turn ) { - current_map_memory_turn = calendar::turn; - float map_memory_capacity_multiplier = - mutation_value( "map_memory_capacity_multiplier" ); - if( has_active_bionic( bio_memory ) ) { - map_memory_capacity_multiplier = 50; - } - current_map_memory_capacity = 2 * SEEX * 2 * SEEY * 100 * map_memory_capacity_multiplier; - } - return current_map_memory_capacity; + return player_map_memory->get_symbol( p ); } void avatar::clear_memorized_tile( const tripoint &pos ) { - player_map_memory.clear_memorized_tile( pos ); + player_map_memory->clear_memorized_tile( pos ); } std::vector avatar::get_active_missions() const diff --git a/src/avatar.h b/src/avatar.h index c0fc49681fe76..28cc50322767e 100644 --- a/src/avatar.h +++ b/src/avatar.h @@ -18,7 +18,6 @@ #include "game_constants.h" #include "json.h" #include "magic_teleporter_list.h" -#include "map_memory.h" #include "memory_fast.h" #include "player.h" #include "point.h" @@ -42,6 +41,8 @@ namespace catacurses class window; } // namespace catacurses enum class character_type : int; +class map_memory; +struct memorized_terrain_tile; namespace debug_menu { @@ -70,13 +71,18 @@ class avatar : public player { public: avatar(); + avatar( const avatar & ) = delete; + avatar( avatar && ); + ~avatar(); + avatar &operator=( const avatar & ) = delete; + avatar &operator=( avatar && ); void store( JsonOut &json ) const; void load( const JsonObject &data ); void serialize( JsonOut &json ) const override; void deserialize( JsonIn &jsin ) override; - void serialize_map_memory( JsonOut &jsout ) const; - void deserialize_map_memory( JsonIn &jsin ); + bool save_map_memory(); + void load_map_memory(); // newcharacter.cpp bool create( character_type type, const std::string &tempname = "" ); @@ -97,17 +103,16 @@ class avatar : public player void toggle_map_memory(); bool should_show_map_memory(); + void prepare_map_memory_region( const tripoint &p1, const tripoint &p2 ); /** Memorizes a given tile in tiles mode; finalize_tile_memory needs to be called after it */ void memorize_tile( const tripoint &pos, const std::string &ter, int subtile, int rotation ); /** Returns last stored map tile in given location in tiles mode */ - memorized_terrain_tile get_memorized_tile( const tripoint &p ) const; + const memorized_terrain_tile &get_memorized_tile( const tripoint &p ) const; /** Memorizes a given tile in curses mode; finalize_terrain_memory_curses needs to be called after it */ void memorize_symbol( const tripoint &pos, int symbol ); /** Returns last stored map tile in given location in curses mode */ int get_memorized_symbol( const tripoint &p ) const; - /** Returns the amount of tiles survivor can remember. */ - size_t max_memorized_tiles() const; void clear_memorized_tile( const tripoint &pos ); nc_color basic_symbol_color() const override; @@ -290,11 +295,8 @@ class avatar : public player std::string total_daily_calories_string() const; private: - map_memory player_map_memory; + std::unique_ptr player_map_memory; bool show_map_memory; - /** Used in max_memorized_tiles to cache memory capacity. **/ - mutable time_point current_map_memory_turn = calendar::before_time_starts; - mutable size_t current_map_memory_capacity = 0; friend class debug_menu::mission_debug; /** diff --git a/src/cata_tiles.cpp b/src/cata_tiles.cpp index d7dfe88f295ff..cc74debf624ab 100644 --- a/src/cata_tiles.cpp +++ b/src/cata_tiles.cpp @@ -1110,6 +1110,22 @@ void cata_tiles::draw( const point &dest, const tripoint ¢er, int width, int const level_cache &ch = here.access_cache( center.z ); + // Map memory should be at least the size of the view range + // so that new tiles can be memorized, and at least the size of the display + // since at farthest zoom displayed area may be bigger than view range. + const point min_mm_reg = point( + std::min( o.x, min_visible.x ), + std::min( o.y, min_visible.y ) + ); + const point max_mm_reg = point( + std::max( s.x + o.x, max_visible.x ), + std::max( s.y + o.y, max_visible.y ) + ); + you.prepare_map_memory_region( + here.getabs( tripoint( min_mm_reg, center.z ) ), + here.getabs( tripoint( max_mm_reg, center.z ) ) + ); + //set up a default tile for the edges outside the render area visibility_type offscreen_type = visibility_type::DARK; if( cache.u_is_boomered ) { diff --git a/src/construction.cpp b/src/construction.cpp index 1da0ae0440230..4bffe44e529c7 100644 --- a/src/construction.cpp +++ b/src/construction.cpp @@ -949,8 +949,7 @@ void place_construction( const construction_group_str_id &group ) shared_ptr_fast draw_valid = make_shared_fast( [&]() { map &here = get_map(); for( auto &elem : valid ) { - here.drawsq( g->w_terrain, player_character, elem.first, true, false, - player_character.pos() + player_character.view_offset ); + here.drawsq( g->w_terrain, elem.first, drawsq_params().highlight( true ).show_items( true ) ); } } ); g->add_draw_callback( draw_valid ); diff --git a/src/coordinate_conversions.cpp b/src/coordinate_conversions.cpp index 04227c08a9466..1a46a16ccb9e7 100644 --- a/src/coordinate_conversions.cpp +++ b/src/coordinate_conversions.cpp @@ -184,3 +184,13 @@ tripoint omt_to_seg_copy( const tripoint &p ) { return tripoint( divide( p.x, SEG_SIZE ), divide( p.y, SEG_SIZE ), p.z ); } + +point sm_to_mmr_remain( int &x, int &y ) +{ + return point( divide( x, MM_REG_SIZE, x ), divide( y, MM_REG_SIZE, y ) ); +} + +tripoint mmr_to_sm_copy( const tripoint &p ) +{ + return tripoint( p.x * MM_REG_SIZE, p.y * MM_REG_SIZE, p.z ); +} diff --git a/src/coordinate_conversions.h b/src/coordinate_conversions.h index ffd55c898871c..5dc3bc3a56f4e 100644 --- a/src/coordinate_conversions.h +++ b/src/coordinate_conversions.h @@ -11,6 +11,7 @@ * For documentation on coordinate systems in general see * doc/POINTS_COORDINATES.md. * + * This file provides static translation functions, named like this: @code static point _to__copy(int x, int y); @@ -165,5 +166,10 @@ inline point ms_to_omt_remain( point &p ) } // overmap terrain to map segment. tripoint omt_to_seg_copy( const tripoint &p ); +// Submap to memory map region. +point sm_to_mmr_remain( int &x, int &y ); +// Memory map region to submap. +// Note: this produces sm coords of top-left corner of the region. +tripoint mmr_to_sm_copy( const tripoint &p ); #endif // CATA_SRC_COORDINATE_CONVERSIONS_H diff --git a/src/cuboid_rectangle.h b/src/cuboid_rectangle.h index 5179333c0d104..507059aad2fdc 100644 --- a/src/cuboid_rectangle.h +++ b/src/cuboid_rectangle.h @@ -33,6 +33,13 @@ struct half_open_rectangle : rectangle { return Traits::x( p ) >= Traits::x( p_min ) && Traits::x( p ) < Traits::x( p_max ) && Traits::y( p ) >= Traits::y( p_min ) && Traits::y( p ) < Traits::y( p_max ); } + constexpr bool overlaps( const rectangle &r ) const { + using Traits = point_traits; + return !( Traits::x( r.p_min ) >= Traits::x( p_max ) || + Traits::y( r.p_min ) >= Traits::y( p_max ) || + Traits::x( p_min ) >= Traits::x( r.p_max ) || + Traits::y( p_min ) >= Traits::y( r.p_max ) ); + } }; template>(), int() ) = 0> @@ -47,6 +54,13 @@ struct inclusive_rectangle : rectangle { return Traits::x( p ) >= Traits::x( p_min ) && Traits::x( p ) <= Traits::x( p_max ) && Traits::y( p ) >= Traits::y( p_min ) && Traits::y( p ) <= Traits::y( p_max ); } + constexpr bool overlaps( const rectangle &r ) const { + using Traits = point_traits; + return !( Traits::x( r.p_min ) > Traits::x( p_max ) || + Traits::y( r.p_min ) > Traits::y( p_max ) || + Traits::x( p_min ) > Traits::x( r.p_max ) || + Traits::y( p_min ) > Traits::y( r.p_max ) ); + } }; // Clamp p to the rectangle r. diff --git a/src/debug.cpp b/src/debug.cpp index 173e6ceaf2129..4742e8a7b6ed7 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -643,6 +643,9 @@ static std::ostream &operator<<( std::ostream &out, DebugClass cl ) if( cl & D_SDL ) { out << "SDL "; } + if( cl & D_MMAP ) { + out << "MMAP "; + } } return out; } diff --git a/src/debug.h b/src/debug.h index b5cc4bfb5cca6..0736c4ea13f92 100644 --- a/src/debug.h +++ b/src/debug.h @@ -162,6 +162,8 @@ enum DebugClass { D_NPC = 1 << 5, /** SDL & tiles & anything graphical */ D_SDL = 1 << 6, + /** Related to tile memory (map_memory.cpp) */ + D_MMAP = 1 << 7, DC_ALL = ( 1 << 30 ) - 1 }; diff --git a/src/editmap.cpp b/src/editmap.cpp index 8c420e6a0bc32..57dd5b5cf4471 100644 --- a/src/editmap.cpp +++ b/src/editmap.cpp @@ -461,13 +461,13 @@ void editmap::uber_draw_ter( const catacurses::window &w, map *m ) bool draw_fld=true; bool draw_veh=true; */ - bool draw_itm = true; + bool game_map = m == &get_map() || w == g->w_terrain; const int msize = MAPSIZE_X; if( refresh_mplans ) { hilights["mplan"].points.clear(); } - avatar &player_character = get_avatar(); + drawsq_params params = drawsq_params().center( center ); for( const tripoint &p : tripoint_range( start, end ) ) { int sym = game_map ? '%' : ' '; if( p.x >= 0 && p.x < msize && p.y >= 0 && p.y < msize ) { @@ -476,7 +476,7 @@ void editmap::uber_draw_ter( const catacurses::window &w, map *m ) if( critter != nullptr ) { critter->draw( w, center.xy(), false ); } else { - m->drawsq( w, player_character, p, false, draw_itm, center, false, true ); + m->drawsq( w, p, params ); } if( refresh_mplans ) { monster *mon = dynamic_cast( critter ); @@ -487,7 +487,7 @@ void editmap::uber_draw_ter( const catacurses::window &w, map *m ) } } } else { - m->drawsq( w, player_character, p, false, draw_itm, center, false, true ); + m->drawsq( w, p, params ); } } else { mvwputch( w, p.xy() - start.xy(), c_dark_gray, sym ); @@ -509,8 +509,6 @@ void editmap::do_ui_invalidation() void editmap::draw_main_ui_overlay() { const Creature *critter = g->critter_at( target ); - - avatar &player_character = get_avatar(); map &here = get_map(); #if !defined( TILES ) if( uberdraw ) { @@ -522,7 +520,7 @@ void editmap::draw_main_ui_overlay() if( critter != nullptr ) { critter->draw( g->w_terrain, target, true ); } else { - here.drawsq( g->w_terrain, player_character, target, true, true, target ); + here.drawsq( g->w_terrain, target, drawsq_params().highlight( true ).center( target ) ); } #ifdef TILES // give some visual indication of different cursor moving modes @@ -616,6 +614,7 @@ void editmap::draw_main_ui_overlay() tinymap &tmpmap = *tmpmap_ptr; #ifdef TILES if( use_tiles ) { + const tripoint &player_location = get_player_location().pos(); const point origin_p = target.xy() + point( 1 - SEEX, 1 - SEEY ); for( int x = 0; x < SEEX * 2; x++ ) { for( int y = 0; y < SEEY * 2; y++ ) { @@ -632,7 +631,7 @@ void editmap::draw_main_ui_overlay() g->draw_trap_override( map_p, tmpmap.tr_at( tmp_p ).loadid ); g->draw_field_override( map_p, tmpmap.field_at( tmp_p ).displayed_field_type() ); const maptile &tile = tmpmap.maptile_at( tmp_p ); - if( tmpmap.sees_some_items( tmp_p, player_character.pos() - origin_p ) ) { + if( tmpmap.sees_some_items( tmp_p, player_location - origin_p ) ) { const item &itm = tile.get_uppermost_item(); const mtype *const mon = itm.get_mtype(); g->draw_item_override( map_p, itm.typeId(), mon ? mon->id : mtype_id::NULL_ID(), @@ -687,9 +686,9 @@ void editmap::draw_main_ui_overlay() } else { #endif hilights["mapgentgt"].draw( *this, true ); - const tripoint center( SEEX - 1, SEEY - 1, target.z ); + drawsq_params params = drawsq_params().center( tripoint( SEEX - 1, SEEY - 1, target.z ) ); for( const tripoint &p : tmpmap.points_on_zlevel() ) { - tmpmap.drawsq( g->w_terrain, player_character, p, false, true, center, false, true ); + tmpmap.drawsq( g->w_terrain, p, params ); } tmpmap.rebuild_vehicle_level_caches(); #ifdef TILES diff --git a/src/game.cpp b/src/game.cpp index 2af02c0750b47..34d04379884d2 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2957,9 +2957,7 @@ bool game::load( const save_t &name ) return false; } - read_from_file_optional_json( playerpath + SAVE_EXTENSION_MAP_MEMORY, [&]( JsonIn & jsin ) { - u.deserialize_map_memory( jsin ); - } ); + u.load_map_memory(); const std::string log_filename = worldpath + name.base_path() + SAVE_EXTENSION_LOG; read_from_file_optional( log_filename, @@ -3157,11 +3155,7 @@ bool game::save_player_data() const bool saved_data = write_to_file( playerfile + SAVE_EXTENSION, [&]( std::ostream & fout ) { serialize( fout ); }, _( "player data" ) ); - const bool saved_map_memory = write_to_file( playerfile + SAVE_EXTENSION_MAP_MEMORY, [&]( - std::ostream & fout ) { - JsonOut jsout( fout ); - u.serialize_map_memory( jsout ); - }, _( "player map memory" ) ); + const bool saved_map_memory = u.save_map_memory(); const bool saved_log = write_to_file( playerfile + SAVE_EXTENSION_LOG, [&]( std::ostream & fout ) { memorial().save( fout ); @@ -6118,7 +6112,7 @@ void game::pickup( const tripoint &p ) { // Highlight target shared_ptr_fast hilite_cb = make_shared_fast( [&]() { - m.drawsq( w_terrain, u, p, true, true, u.pos() + u.view_offset ); + m.drawsq( w_terrain, p, drawsq_params().highlight( true ) ); } ); add_draw_callback( hilite_cb ); @@ -6212,7 +6206,7 @@ void game::draw_look_around_cursor( const tripoint &lp, const visibility_variabl if( creature != nullptr && u.sees( *creature ) ) { creature->draw( w_terrain, view_center, true ); } else { - m.drawsq( w_terrain, u, lp, true, true, view_center ); + m.drawsq( w_terrain, lp, drawsq_params().highlight( true ).center( view_center ) ); } } else { std::string visibility_indicator; diff --git a/src/game_constants.h b/src/game_constants.h index 7f9469ebc5281..825d2081fda82 100644 --- a/src/game_constants.h +++ b/src/game_constants.h @@ -55,6 +55,9 @@ static constexpr int OMAPY = OMAPX; // Size of a square unit of terrain saved to a directory. static constexpr int SEG_SIZE = 32; +// Size of a square unit of tile memory saved in a single file, in mm_submaps. +static constexpr int MM_REG_SIZE = 8; + /** * Items on the map with at most this distance to the player are considered available for crafting, * see inventory::form_from_map diff --git a/src/lru_cache.cpp b/src/lru_cache.cpp index 6038ca7ba3cd2..112eeaad841cc 100644 --- a/src/lru_cache.cpp +++ b/src/lru_cache.cpp @@ -6,7 +6,6 @@ #include #include -#include "map_memory.h" #include "memory_fast.h" #include "point.h" @@ -73,7 +72,6 @@ const std::list::Pair> &lru_cache::li } // explicit template initialization for lru_cache of all types -template class lru_cache; template class lru_cache; template class lru_cache; template class lru_cache>; diff --git a/src/map.cpp b/src/map.cpp index bc5a0ebd02c84..affca4289a7ef 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -59,6 +59,7 @@ #include "line.h" #include "location.h" #include "map_iterator.h" +#include "map_memory.h" #include "map_selector.h" #include "mapbuffer.h" #include "mapgen.h" @@ -5700,53 +5701,23 @@ visibility_type map::get_visibility( const lit_level ll, return visibility_type::HIDDEN; } -bool map::apply_vision_effects( const catacurses::window &w, const visibility_type vis ) const +static bool has_memory_at( const tripoint &p ) { - int symbol = ' '; - nc_color color = c_black; - - switch( vis ) { - case visibility_type::CLEAR: - // Drew the tile, so bail out now. - return false; - case visibility_type::LIT: - // can only tell that this square is bright - symbol = '#'; - color = c_light_gray; - break; - case visibility_type::BOOMER: - symbol = '#'; - color = c_pink; - break; - case visibility_type::BOOMER_DARK: - symbol = '#'; - color = c_magenta; - break; - case visibility_type::DARK: - // can't see this square at all - case visibility_type::HIDDEN: - break; + avatar &you = get_avatar(); + if( you.should_show_map_memory() ) { + int t = you.get_memorized_symbol( get_map().getabs( p ) ); + return t != 0; } - wputch( w, color, symbol ); - return true; + return false; } -bool map::draw_maptile_from_memory( const catacurses::window &w, const tripoint &p, - const tripoint &view_center, bool move_cursor ) const +static int get_memory_at( const tripoint &p ) { - int sym = get_avatar().get_memorized_symbol( getabs( p ) ); - if( sym == 0 ) { - return true; + avatar &you = get_avatar(); + if( you.should_show_map_memory() ) { + return you.get_memorized_symbol( get_map().getabs( p ) ); } - if( move_cursor ) { - const int k = p.x + getmaxx( w ) / 2 - view_center.x; - const int j = p.y + getmaxy( w ) / 2 - view_center.y; - - mvwputch( w, point( k, j ), c_brown, sym ); - } else { - wputch( w, c_brown, sym ); - } - return false; + return ' '; } void map::draw( const catacurses::window &w, const tripoint ¢er ) @@ -5763,100 +5734,127 @@ void map::draw( const catacurses::window &w, const tripoint ¢er ) const auto &visibility_cache = get_cache_ref( center.z ).visibility_cache; - // X and y are in map coordinates, but might be out of range of the map. - // When they are out of range, we just draw '#'s. - tripoint p; - p.z = center.z; - int &x = p.x; - int &y = p.y; + int wnd_h = getmaxy( w ); + int wnd_w = getmaxx( w ); + const tripoint offs = center - tripoint( wnd_w / 2, wnd_h / 2, 0 ); + + // Map memory should be at least the size of the view range + // so that new tiles can be memorized, and at least the size of the terminal + // since displayed area may be bigger than view range. + const point min_mm_reg = point( + std::min( 0, offs.x ), + std::min( 0, offs.y ) + ); + const point max_mm_reg = point( + std::max( MAPSIZE_X, offs.x + wnd_w ), + std::max( MAPSIZE_Y, offs.y + wnd_h ) + ); avatar &player_character = get_avatar(); - const bool do_map_memory = player_character.should_show_map_memory(); - for( y = center.y - getmaxy( w ) / 2; y <= center.y + getmaxy( w ) / 2; y++ ) { - if( y - center.y + getmaxy( w ) / 2 >= getmaxy( w ) ) { - continue; + player_character.prepare_map_memory_region( + getabs( tripoint( min_mm_reg, center.z ) ), + getabs( tripoint( max_mm_reg, center.z ) ) + ); + + const auto draw_background = [&]( const tripoint & p ) { + int sym = ' '; + nc_color col = c_black; + if( has_memory_at( p ) ) { + sym = get_memory_at( p ); + col = c_brown; } + wputch( w, col, sym ); + }; - wmove( w, point( 0, y - center.y + getmaxy( w ) / 2 ) ); + const auto draw_vision_effect = [&]( const visibility_type vis ) -> bool { + int sym = '#'; + nc_color col; + switch( vis ) + { + case visibility_type::LIT: + // can only tell that this square is bright + col = c_light_gray; + break; + case visibility_type::BOOMER: + col = c_pink; + break; + case visibility_type::BOOMER_DARK: + col = c_magenta; + break; + default: + return false; + } + wputch( w, col, sym ); + return true; + }; - const int maxxrender = center.x - getmaxx( w ) / 2 + getmaxx( w ); - x = center.x - getmaxx( w ) / 2; - if( y < 0 || y >= MAPSIZE_Y ) { - for( ; x < maxxrender; x++ ) { - if( !do_map_memory || draw_maptile_from_memory( w, p, center, false ) ) { - wputch( w, c_black, ' ' ); - } + drawsq_params params = drawsq_params().memorize( true ); + for( int wy = 0; wy < wnd_h; wy++ ) { + for( int wx = 0; wx < wnd_w; wx++ ) { + wmove( w, point( wx, wy ) ); + const tripoint p = offs + tripoint( wx, wy, 0 ); + if( !inbounds( p ) ) { + draw_background( p ); + continue; } - continue; - } - while( x < 0 ) { - if( !do_map_memory || draw_maptile_from_memory( w, p, center, false ) ) { - wputch( w, c_black, ' ' ); + const lit_level lighting = visibility_cache[p.x][p.y]; + const visibility_type vis = get_visibility( lighting, cache ); + + if( draw_vision_effect( vis ) ) { + continue; } - x++; - } - point l; - const int maxx = std::min( MAPSIZE_X, maxxrender ); - while( x < maxx ) { - submap *cur_submap = get_submap_at( p, l ); - submap *sm_below = p.z > -OVERMAP_DEPTH ? - get_submap_at( {p.xy(), p.z - 1}, l ) : cur_submap; - if( cur_submap == nullptr || sm_below == nullptr ) { - debugmsg( "Tried to draw map at (%d,%d) but the submap is not loaded", l.x, l.y ); - x++; + if( vis == visibility_type::HIDDEN || vis == visibility_type::DARK ) { + draw_background( p ); continue; } - while( l.x < SEEX && x < maxx ) { - const lit_level lighting = visibility_cache[x][y]; - const visibility_type vis = get_visibility( lighting, cache ); - if( !apply_vision_effects( w, vis ) ) { - const maptile curr_maptile = maptile( cur_submap, l ); - const bool draw_lower_zlevel = - draw_maptile( w, player_character, p, curr_maptile, - false, true, center, - lighting == lit_level::LOW, - lighting == lit_level::BRIGHT, true ); - if( draw_lower_zlevel ) { - p.z--; - const maptile tile_below = maptile( sm_below, l ); - draw_from_above( w, player_character, p, tile_below, false, center, - lighting == lit_level::LOW, - lighting == lit_level::BRIGHT, false ); - p.z++; - } - } else if( do_map_memory && ( vis == visibility_type::HIDDEN || vis == visibility_type::DARK ) ) { - draw_maptile_from_memory( w, p, center ); - } - l.x++; - x++; + const maptile curr_maptile = maptile_at_internal( p ); + params + .low_light( lighting == lit_level::LOW ) + .bright_light( lighting == lit_level::BRIGHT ); + if( draw_maptile( w, p, curr_maptile, params ) ) { + continue; } + const maptile tile_below = maptile_at_internal( p - tripoint( 0, 0, 1 ) ); + draw_from_above( w, tripoint( p.xy(), p.z - 1 ), tile_below, params ); } + } - while( x < maxxrender ) { - if( !do_map_memory || draw_maptile_from_memory( w, p, center, false ) ) { - wputch( w, c_black, ' ' ); + // Memorize off-screen tiles + half_open_rectangle display( offs.xy(), offs.xy() + point( wnd_w, wnd_h ) ); + drawsq_params mm_params = drawsq_params().memorize( true ).output( false ); + for( int y = 0; y < MAPSIZE_Y; y++ ) { + for( int x = 0; x < MAPSIZE_X; x++ ) { + const tripoint p( x, y, center.z ); + if( display.contains( p.xy() ) ) { + // Have been memorized during display loop + continue; + } + + const lit_level lighting = visibility_cache[p.x][p.y]; + const visibility_type vis = get_visibility( lighting, cache ); + + if( vis != visibility_type::CLEAR ) { + continue; } - x++; + + const maptile curr_maptile = maptile_at_internal( p ); + mm_params + .low_light( lighting == lit_level::LOW ) + .bright_light( lighting == lit_level::BRIGHT ); + + draw_maptile( w, p, curr_maptile, mm_params ); } } } -void map::drawsq( const catacurses::window &w, player &u, const tripoint &p, - bool invert, bool show_items ) const -{ - drawsq( w, u, p, invert, show_items, u.pos() + u.view_offset, false, false, false ); -} - -void map::drawsq( const catacurses::window &w, player &u, const tripoint &p, - const bool invert_arg, - const bool show_items_arg, const tripoint &view_center, - const bool low_light, const bool bright_light, const bool inorder ) const +void map::drawsq( const catacurses::window &w, const tripoint &p, + const drawsq_params ¶ms ) const { // If we are in tiles mode, the only thing we want to potentially draw is a highlight if( is_draw_tiles_mode() ) { - if( invert_arg ) { + if( params.highlight() ) { g->draw_highlight( p ); } return; @@ -5866,16 +5864,19 @@ void map::drawsq( const catacurses::window &w, player &u, const tripoint &p, return; } + const tripoint view_center = params.center(); + const int k = p.x + getmaxx( w ) / 2 - view_center.x; + const int j = p.y + getmaxy( w ) / 2 - view_center.y; + wmove( w, point( k, j ) ); + const maptile tile = maptile_at( p ); - const bool more = draw_maptile( w, u, p, tile, invert_arg, show_items_arg, - view_center, low_light, bright_light, inorder ); - if( more ) { - tripoint below( p.xy(), p.z - 1 ); - const maptile tile_below = maptile_at( below ); - draw_from_above( w, u, below, tile_below, - invert_arg, view_center, - low_light, bright_light, false ); + if( draw_maptile( w, p, tile, params ) ) { + return; } + + tripoint below( p.xy(), p.z - 1 ); + const maptile tile_below = maptile_at( below ); + draw_from_above( w, below, tile_below, params ); } // a check to see if the lower floor needs to be rendered in tiles @@ -5885,13 +5886,10 @@ bool map::dont_draw_lower_floor( const tripoint &p ) !( has_flag( TFLAG_NO_FLOOR, p ) || has_flag( TFLAG_Z_TRANSPARENT, p ) ); } -// returns true if lower z-level needs to be drawn, false otherwise -bool map::draw_maptile( const catacurses::window &w, const player &u, const tripoint &p, - const maptile &curr_maptile, - bool invert, bool show_items, - const tripoint &view_center, - const bool low_light, const bool bright_light, const bool inorder ) const +bool map::draw_maptile( const catacurses::window &w, const tripoint &p, + const maptile &curr_maptile, const drawsq_params ¶ms ) const { + drawsq_params param = params; nc_color tercol; const ter_t &curr_ter = curr_maptile.get_ter_t(); const furn_t &curr_furn = curr_maptile.get_furn_t(); @@ -5921,8 +5919,8 @@ bool map::draw_maptile( const catacurses::window &w, const player &u, const trip } } if( curr_ter.has_flag( TFLAG_SWIMMABLE ) && curr_ter.has_flag( TFLAG_DEEP_WATER ) && - !u.is_underwater() ) { - show_items = false; // Can only see underwater items if WE are underwater + !player_character.is_underwater() ) { + param.show_items( false ); // Can only see underwater items if WE are underwater } // If there's a trap here, and we have sufficient perception, draw that instead if( curr_trap.can_see( p, player_character ) ) { @@ -6004,7 +6002,7 @@ bool map::draw_maptile( const catacurses::window &w, const player &u, const trip std::string item_sym; // If there are items here, draw those instead - if( show_items && curr_maptile.get_item_count() > 0 && + if( param.show_items() && curr_maptile.get_item_count() > 0 && sees_some_items( p, player_character ) ) { // if there's furniture/terrain/trap/fields (sym!='.') // and we should not override it, then only highlight the square @@ -6017,7 +6015,7 @@ bool map::draw_maptile( const catacurses::window &w, const player &u, const trip tercol = curr_maptile.get_uppermost_item().color(); } if( curr_maptile.get_item_count() > 1 ) { - invert = !invert; + param.highlight( !param.highlight() ); } } } @@ -6036,7 +6034,7 @@ bool map::draw_maptile( const catacurses::window &w, const player &u, const trip } } - if( check_and_set_seen_cache( p ) ) { + if( param.memorize() && check_and_set_seen_cache( p ) ) { player_character.memorize_symbol( getabs( p ), memory_sym ); } @@ -6045,18 +6043,18 @@ bool map::draw_maptile( const catacurses::window &w, const player &u, const trip graf = true; } - const auto u_vision = u.get_vision_modes(); + const auto u_vision = player_character.get_vision_modes(); if( u_vision[BOOMERED] ) { tercol = c_magenta; } else if( u_vision[NV_GOGGLES] ) { - tercol = ( bright_light ) ? c_white : c_light_green; - } else if( low_light ) { + tercol = param.bright_light() ? c_white : c_light_green; + } else if( param.low_light() ) { tercol = c_dark_gray; } else if( u_vision[DARKNESS] ) { tercol = c_dark_gray; } - if( invert ) { + if( param.highlight() ) { tercol = invert_color( tercol ); } else if( hi ) { tercol = hilite( tercol ); @@ -6064,34 +6062,29 @@ bool map::draw_maptile( const catacurses::window &w, const player &u, const trip tercol = red_background( tercol ); } - if( inorder ) { - // Rastering the whole map, take advantage of automatically moving the cursor. - if( item_sym.empty() ) { - wputch( w, tercol, sym ); + if( item_sym.empty() && sym == ' ' ) { + if( !zlevels || p.z <= -OVERMAP_DEPTH || !curr_ter.has_flag( TFLAG_NO_FLOOR ) ) { + // Print filler symbol + sym = ' '; + tercol = c_black; } else { - wprintz( w, tercol, item_sym ); + // Draw tile underneath this one instead + return false; } - } else { - // Otherwise move the cursor before drawing. - const int k = p.x + getmaxx( w ) / 2 - view_center.x; - const int j = p.y + getmaxy( w ) / 2 - view_center.y; + } + + if( params.output() ) { if( item_sym.empty() ) { - mvwputch( w, point( k, j ), tercol, sym ); + wputch( w, tercol, sym ); } else { - mvwprintz( w, point( k, j ), tercol, item_sym ); + wprintz( w, tercol, item_sym ); } } - - return zlevels && item_sym.empty() && p.z > -OVERMAP_DEPTH && - ( curr_ter.has_flag( TFLAG_Z_TRANSPARENT ) || - ( sym == ' ' && curr_ter.has_flag( TFLAG_NO_FLOOR ) ) ); + return true; } -void map::draw_from_above( const catacurses::window &w, const player &u, const tripoint &p, - const maptile &curr_tile, - const bool invert, - const tripoint &view_center, - bool low_light, bool bright_light, bool inorder ) const +void map::draw_from_above( const catacurses::window &w, const tripoint &p, + const maptile &curr_tile, const drawsq_params ¶ms ) const { static const int AUTO_WALL_PLACEHOLDER = 2; // this should never appear as a real symbol! @@ -6144,27 +6137,23 @@ void map::draw_from_above( const catacurses::window &w, const player &u, const t sym = determine_wall_corner( p ); } - const auto u_vision = u.get_vision_modes(); + const std::bitset &u_vision = get_player_character().get_vision_modes(); if( u_vision[BOOMERED] ) { tercol = c_magenta; } else if( u_vision[NV_GOGGLES] ) { - tercol = ( bright_light ) ? c_white : c_light_green; - } else if( low_light ) { + tercol = params.bright_light() ? c_white : c_light_green; + } else if( params.low_light() ) { tercol = c_dark_gray; } else if( u_vision[DARKNESS] ) { tercol = c_dark_gray; } - if( invert ) { + if( params.highlight() ) { tercol = invert_color( tercol ); } - if( inorder ) { + if( params.output() ) { wputch( w, tercol, sym ); - } else { - const int k = p.x + getmaxx( w ) / 2 - view_center.x; - const int j = p.y + getmaxy( w ) / 2 - view_center.y; - mvwputch( w, point( k, j ), tercol, sym ); } } @@ -8909,3 +8898,13 @@ std::vector map::get_haulable_items( const tripoint &pos ) } return target_items; } + +tripoint drawsq_params::center() const +{ + if( view_center == tripoint_min ) { + avatar &player_character = get_avatar(); + return player_character.pos() + player_character.view_offset; + } else { + return view_center; + } +} diff --git a/src/map.h b/src/map.h index 48f4a358ae055..2b65f3f6b5d72 100644 --- a/src/map.h +++ b/src/map.h @@ -157,6 +157,122 @@ struct bash_params { bool bashing_from_above = false; }; +/** Draw parameters used by map::drawsq() and similar methods. */ +struct drawsq_params { + private: + tripoint view_center = tripoint_min; + bool do_highlight = false; + bool do_show_items = true; + bool do_low_light = false; + bool do_bright_light = false; + bool do_memorize = false; + bool do_output = true; + + public: + constexpr drawsq_params() = default; + + /** + * Highlight the tile. On TILES, draws an overlay; on CURSES, inverts color. + * Default: false. + */ + //@{ + constexpr drawsq_params &highlight( bool v ) { + do_highlight = v; + return *this; + } + constexpr bool highlight() const { + return do_highlight; + } + //@} + + /** + * Whether to draw items on the tile. + * Default: true. + */ + //@{ + constexpr drawsq_params &show_items( bool v ) { + do_show_items = v; + return *this; + } + constexpr bool show_items() const { + return do_show_items; + } + //@} + + /** + * Whether tile is low light, and should be drawn with muted color. + * Default: false. + */ + //@{ + constexpr drawsq_params &low_light( bool v ) { + do_low_light = v; + return *this; + } + constexpr bool low_light() const { + return do_low_light; + } + //@} + + /** + * Whether tile is in bright light. Affects NV overlay, and nothing else. + * Default: false; + */ + //@{ + constexpr drawsq_params &bright_light( bool v ) { + do_bright_light = v; + return *this; + } + constexpr bool bright_light() const { + return do_bright_light; + } + //@} + + /** + * Whether the tile should be memorized. Used only in map::draw(). + * Default: false. + */ + //@{ + constexpr drawsq_params &memorize( bool v ) { + do_memorize = v; + return *this; + } + constexpr bool memorize() const { + return do_memorize; + } + //@} + + /** + * HACK: Whether the tile should be printed. Used only in map::draw() + * as a hack for memorizing off-screen tiles. + * Default: true. + */ + //@{ + constexpr drawsq_params &output( bool v ) { + do_output = v; + return *this; + } + constexpr bool output() const { + return do_output; + } + //@} + + /** + * Set view center. + * Default: uses avatar's current view center. + */ + //@{ + constexpr drawsq_params ¢er( const tripoint &p ) { + view_center = p; + return *this; + } + constexpr drawsq_params ¢er_at_avatar() { + view_center = tripoint_min; + return *this; + } + tripoint center() const; + //@} +}; + /** * Manage and cache data about a part of the map. * @@ -362,8 +478,6 @@ class map visibility_type get_visibility( lit_level ll, const visibility_variables &cache ) const; - bool apply_vision_effects( const catacurses::window &w, visibility_type vis ) const; - // See field.cpp std::tuple get_wind_blockers( const int &winddirection, const tripoint &pos ); @@ -381,21 +495,14 @@ class map */ void draw( const catacurses::window &w, const tripoint ¢er ); - /** Draw the map tile at the given coordinate. Called by `map::draw()`. - * - * @param w The window we are drawing in - * @param u The player - * @param p The tile on this map to draw. - * @param invert Invert colors if this flag is true - * @param show_items Draw items in tile if this flag is true see `center` in `map::draw()` - */ - void drawsq( const catacurses::window &w, player &u, const tripoint &p, - bool invert, bool show_items, - const tripoint &view_center, - bool low_light = false, bool bright_light = false, - bool inorder = false ) const; - void drawsq( const catacurses::window &w, player &u, const tripoint &p, - bool invert = false, bool show_items = true ) const; + /** + * Draw the map tile at the given coordinate. Called by `map::draw()`. + * + * @param w The window we are drawing in + * @param p The tile on this map to draw. + * @param params Draw parameters. + */ + void drawsq( const catacurses::window &w, const tripoint &p, const drawsq_params ¶ms ) const; /** * Add currently loaded submaps (in @ref grid) to the @ref mapbuffer. @@ -1780,21 +1887,13 @@ class map * Internal version of the drawsq. Keeps a cached maptile for less re-getting. * Returns false if it has drawn all it should, true if `draw_from_above` should be called after. */ - bool draw_maptile( const catacurses::window &w, const player &u, const tripoint &p, - const maptile &tile, - bool invert, bool show_items, - const tripoint &view_center, - bool low_light, bool bright_light, bool inorder ) const; - bool draw_maptile_from_memory( const catacurses::window &w, const tripoint &p, - const tripoint &view_center, - bool move_cursor = true ) const; + bool draw_maptile( const catacurses::window &w, const tripoint &p, + const maptile &tile, const drawsq_params ¶ms ) const; /** * Draws the tile as seen from above. */ - void draw_from_above( const catacurses::window &w, const player &u, const tripoint &p, - const maptile &tile, bool invert, - const tripoint &view_center, - bool low_light, bool bright_light, bool inorder ) const; + void draw_from_above( const catacurses::window &w, const tripoint &p, + const maptile &tile, const drawsq_params ¶ms ) const; int determine_wall_corner( const tripoint &p ) const; // apply a circular light pattern immediately, however it's best to use... diff --git a/src/map_memory.cpp b/src/map_memory.cpp index ce5f1a1c65ad6..afe54a4ae84df 100644 --- a/src/map_memory.cpp +++ b/src/map_memory.cpp @@ -1,30 +1,368 @@ +#include "cata_assert.h" +#include "cached_options.h" +#include "cata_utility.h" +#include "coordinate_conversions.h" +#include "cuboid_rectangle.h" +#include "filesystem.h" +#include "game.h" +#include "line.h" #include "map_memory.h" +#include "path_info.h" -static const memorized_terrain_tile default_tile{ "", 0, 0 }; +const memorized_terrain_tile mm_submap::default_tile{ "", 0, 0 }; +const int mm_submap::default_symbol = 0; -memorized_terrain_tile map_memory::get_tile( const tripoint &pos ) const +#define MM_SIZE (MAPSIZE * 2) + +#define dbg(x) DebugLog((x),D_MMAP) << __FILE__ << ":" << __LINE__ << ": " + +static std::string find_legacy_mm_file() +{ + return PATH_INFO::player_base_save_path() + SAVE_EXTENSION_MAP_MEMORY; +} + +static std::string find_mm_dir() +{ + return string_format( "%s.mm1", PATH_INFO::player_base_save_path() ); +} + +static std::string find_region_path( const std::string &dirname, const tripoint &p ) +{ + return string_format( "%s/%d.%d.%d.mmr", dirname, p.x, p.y, p.z ); +} + +/** + * Helper class for converting global sm coord into + * global mm_region coord + sm coord within the region. + */ +struct reg_coord_pair { + tripoint reg; + point sm_loc; + + reg_coord_pair( const tripoint &p ) : sm_loc( p.xy() ) { + reg = tripoint( sm_to_mmr_remain( sm_loc.x, sm_loc.y ), p.z ); + } +}; + +mm_submap::mm_submap() {} + +mm_region::mm_region() : submaps {{ nullptr }} {} + +bool mm_region::is_empty() const { - return tile_cache.get( pos, default_tile ); + for( size_t y = 0; y < MM_REG_SIZE; y++ ) { + for( size_t x = 0; x < MM_REG_SIZE; x++ ) { + if( !submaps[x][y]->is_empty() ) { + return false; + } + } + } + return true; } -void map_memory::memorize_tile( int limit, const tripoint &pos, const std::string &ter, +map_memory::coord_pair::coord_pair( const tripoint &p ) : loc( p.xy() ) +{ + sm = tripoint( ms_to_sm_remain( loc.x, loc.y ), p.z ); +} + +map_memory::map_memory() +{ + clear_cache(); +} + +const memorized_terrain_tile &map_memory::get_tile( const tripoint &pos ) const +{ + coord_pair p( pos ); + const mm_submap &sm = get_submap( p.sm ); + return sm.tile( p.loc ); +} + +void map_memory::memorize_tile( const tripoint &pos, const std::string &ter, const int subtile, const int rotation ) { - tile_cache.insert( limit, pos, memorized_terrain_tile{ ter, subtile, rotation } ); + coord_pair p( pos ); + mm_submap &sm = get_submap( p.sm ); + sm.set_tile( p.loc, memorized_terrain_tile{ ter, subtile, rotation } ); } int map_memory::get_symbol( const tripoint &pos ) const { - return symbol_cache.get( pos, 0 ); + coord_pair p( pos ); + const mm_submap &sm = get_submap( p.sm ); + return sm.symbol( p.loc ); } -void map_memory::memorize_symbol( int limit, const tripoint &pos, const int symbol ) +void map_memory::memorize_symbol( const tripoint &pos, const int symbol ) { - symbol_cache.insert( limit, pos, symbol ); + coord_pair p( pos ); + mm_submap &sm = get_submap( p.sm ); + sm.set_symbol( p.loc, symbol ); } void map_memory::clear_memorized_tile( const tripoint &pos ) { - tile_cache.remove( pos ); - symbol_cache.remove( pos ); + coord_pair p( pos ); + mm_submap &sm = get_submap( p.sm ); + sm.set_symbol( p.loc, mm_submap::default_symbol ); + sm.set_tile( p.loc, mm_submap::default_tile ); +} + +bool map_memory::prepare_region( const tripoint &p1, const tripoint &p2 ) +{ + cata_assert( p1.z == p2.z ); + cata_assert( p1.x <= p2.x && p1.y <= p2.y ); + + tripoint sm_p1 = coord_pair( p1 ).sm - point( 1, 1 ); + tripoint sm_p2 = coord_pair( p2 ).sm + point( 1, 1 ); + + tripoint sm_pos = sm_p1; + point sm_size = sm_p2.xy() - sm_p1.xy(); + + if( sm_pos.z == cache_pos.z ) { + inclusive_rectangle rect( cache_pos.xy(), cache_pos.xy() + cache_size ); + if( rect.contains( sm_p1.xy() ) && rect.contains( sm_p2.xy() ) ) { + return false; + } + } + + dbg( D_INFO ) << "Preparing memory map for area: pos: " << sm_pos << " size: " << sm_size; + + cache_pos = sm_pos; + cache_size = sm_size; + cached.clear(); + cached.reserve( static_cast( cache_size.x ) * cache_size.y ); + for( int dy = 0; dy < cache_size.y; dy++ ) { + for( int dx = 0; dx < cache_size.x; dx++ ) { + cached.push_back( fetch_submap( cache_pos + point( dx, dy ) ) ); + } + } + return true; +} + +shared_ptr_fast map_memory::fetch_submap( const tripoint &sm_pos ) +{ + shared_ptr_fast sm = find_submap( sm_pos ); + if( sm ) { + return sm; + } + sm = load_submap( sm_pos ); + if( sm ) { + return sm; + } + return allocate_submap( sm_pos ); +} + +shared_ptr_fast map_memory::allocate_submap( const tripoint &sm_pos ) +{ + // Since all save/load operations are done on regions of submaps, + // we need to allocate the whole region at once. + shared_ptr_fast ret; + tripoint reg = reg_coord_pair( sm_pos ).reg; + + dbg( D_INFO ) << "Allocated mm_region " << reg << " [" << mmr_to_sm_copy( reg ) << "]"; + + for( size_t y = 0; y < MM_REG_SIZE; y++ ) { + for( size_t x = 0; x < MM_REG_SIZE; x++ ) { + tripoint pos = mmr_to_sm_copy( reg ) + tripoint( x, y, 0 ); + shared_ptr_fast sm = make_shared_fast(); + if( pos == sm_pos ) { + ret = sm; + } + submaps.insert( std::make_pair( pos, sm ) ); + } + } + + return ret; +} + +shared_ptr_fast map_memory::find_submap( const tripoint &sm_pos ) +{ + auto sm = submaps.find( sm_pos ); + if( sm == submaps.end() ) { + return nullptr; + } else { + return sm->second; + } +} + +shared_ptr_fast map_memory::load_submap( const tripoint &sm_pos ) +{ + if( test_mode ) { + return nullptr; + } + + const std::string dirname = find_mm_dir(); + reg_coord_pair p( sm_pos ); + const std::string path = find_region_path( dirname, p.reg ); + + if( !dir_exist( dirname ) ) { + // Old saves don't have [plname].mm1 folder + return nullptr; + } + + mm_region mmr; + const auto loader = [&]( JsonIn & jsin ) { + mmr.deserialize( jsin ); + }; + + try { + if( !read_from_file_optional_json( path, loader ) ) { + // Region not found + return nullptr; + } + } catch( const std::exception &err ) { + debugmsg( "Failed to load memory map region (%d,%d,%d): %s", + p.reg.x, p.reg.y, p.reg.z, err.what() ); + return nullptr; + } + + dbg( D_INFO ) << "Loaded mm_region " << p.reg << " [" << mmr_to_sm_copy( p.reg ) << "]"; + + shared_ptr_fast ret; + + for( size_t y = 0; y < MM_REG_SIZE; y++ ) { + for( size_t x = 0; x < MM_REG_SIZE; x++ ) { + tripoint pos = mmr_to_sm_copy( p.reg ) + tripoint( x, y, 0 ); + shared_ptr_fast &sm = mmr.submaps[x][y]; + if( pos == sm_pos ) { + ret = sm; + } + submaps.insert( std::make_pair( pos, sm ) ); + } + } + + return ret; +} + +static mm_submap null_mz_submap; + +const mm_submap &map_memory::get_submap( const tripoint &sm_pos ) const +{ + point idx = ( sm_pos - cache_pos ).xy(); + if( idx.x > 0 && idx.y > 0 && idx.x < cache_size.x && idx.y < cache_size.y ) { + return *cached[idx.y * cache_size.x + idx.x]; + } else { + return null_mz_submap; + } +} + +mm_submap &map_memory::get_submap( const tripoint &sm_pos ) +{ + point idx = ( sm_pos - cache_pos ).xy(); + if( idx.x > 0 && idx.y > 0 && idx.x < cache_size.x && idx.y < cache_size.y ) { + return *cached[idx.y * cache_size.x + idx.x]; + } else { + return null_mz_submap; + } +} + +void map_memory::load( const tripoint &pos ) +{ + const std::string dirname = find_mm_dir(); + + clear_cache(); + + if( !dir_exist( dirname ) ) { + // Old saves have [plname].mm file and no [plname].mm1 folder + const std::string legacy_file = find_legacy_mm_file(); + if( file_exist( legacy_file ) ) { + try { + read_from_file_optional_json( legacy_file, [&]( JsonIn & jsin ) { + this->load_legacy( jsin ); + } ); + } catch( const std::exception &err ) { + debugmsg( "Failed to load legacy memory map file: %s", err.what() ); + } + } + return; + } + + coord_pair p( pos ); + tripoint start = p.sm - tripoint( MM_SIZE / 2, MM_SIZE / 2, 0 ); + dbg( D_INFO ) << "[LOAD] Loading memory map around " << p.sm << ". Loading submaps within " << start + << "->" << start + tripoint( MM_SIZE, MM_SIZE, 0 ); + for( int dy = 0; dy < MM_SIZE; dy++ ) { + for( int dx = 0; dx < MM_SIZE; dx++ ) { + fetch_submap( start + tripoint( dx, dy, 0 ) ); + } + } + dbg( D_INFO ) << "[LOAD] Done."; +} + +bool map_memory::save( const tripoint &pos ) +{ + tripoint sm_center = coord_pair( pos ).sm; + const std::string dirname = find_mm_dir(); + assure_dir_exist( dirname ); + + clear_cache(); + + dbg( D_INFO ) << "N submaps before save: " << submaps.size(); + + // Since mm_submaps are always allocated in regions, + // we are certain that each region will be filled. + std::map regions; + for( auto &it : submaps ) { + const reg_coord_pair p( it.first ); + regions[p.reg].submaps[p.sm_loc.x][p.sm_loc.y] = it.second; + } + submaps.clear(); + + constexpr point MM_HSIZE_P = point( MM_SIZE / 2, MM_SIZE / 2 ); + rectangle rect_keep( sm_center.xy() - MM_HSIZE_P, sm_center.xy() + MM_HSIZE_P ); + + dbg( D_INFO ) << "[SAVE] Saving memory map around " << sm_center << ". Keeping submaps within " << + rect_keep.p_min << "->" << rect_keep.p_max; + + bool result = true; + + for( auto &it : regions ) { + const tripoint ®p = it.first; + mm_region ® = it.second; + if( !reg.is_empty() ) { + const std::string path = find_region_path( dirname, regp ); + const std::string descr = string_format( + _( "memory map region for (%d,%d,%d)" ), + regp.x, regp.y, regp.z + ); + + const auto writer = [&]( std::ostream & fout ) -> void { + fout << serialize_wrapper( [&]( JsonOut & jsout ) + { + reg.serialize( jsout ); + } ); + }; + + const bool res = write_to_file( path, writer, descr.c_str() ); + result = result & res; + } + tripoint regp_sm = mmr_to_sm_copy( regp ); + half_open_rectangle rect_reg( regp_sm.xy(), regp_sm.xy() + point( MM_REG_SIZE, + MM_REG_SIZE ) ); + if( rect_reg.overlaps( rect_keep ) ) { + dbg( D_INFO ) << "Keeping mm_region " << regp << " [" << regp_sm << "]"; + // Put submaps back + for( size_t y = 0; y < MM_REG_SIZE; y++ ) { + for( size_t x = 0; x < MM_REG_SIZE; x++ ) { + tripoint p = regp_sm + tripoint( x, y, 0 ); + shared_ptr_fast &sm = reg.submaps[x][y]; + submaps.insert( std::make_pair( p, sm ) ); + } + } + } else { + dbg( D_INFO ) << "Dropping mm_region " << regp << " [" << regp_sm << "]"; + } + } + + dbg( D_INFO ) << "[SAVE] Done."; + dbg( D_INFO ) << "N submaps after save: " << submaps.size(); + + return result; +} + +void map_memory::clear_cache() +{ + cached.clear(); + cache_pos = tripoint_min; + cache_size = point_zero; } diff --git a/src/map_memory.h b/src/map_memory.h index d5912169a1e19..406d653f45aed 100644 --- a/src/map_memory.h +++ b/src/map_memory.h @@ -4,9 +4,11 @@ #include -#include "lru_cache.h" +#include "game_constants.h" +#include "memory_fast.h" #include "point.h" // IWYU pragma: keep +class JsonOut; class JsonIn; class JsonObject; class JsonOut; @@ -15,28 +17,182 @@ struct memorized_terrain_tile { std::string tile; int subtile; int rotation; + + inline bool operator==( const memorized_terrain_tile &rhs ) const { + return ( rotation == rhs.rotation ) && ( subtile == rhs.subtile ) && ( tile == rhs.tile ); + } + + inline bool operator!=( const memorized_terrain_tile &rhs ) const { + return !( *this == rhs ); + } }; +/** Represent a submap-sized chunk of tile memory. */ +struct mm_submap { + public: + static const memorized_terrain_tile default_tile; + static const int default_symbol; + + mm_submap(); + + /** Whether this mm_submap is empty. Empty submaps are skipped during saving. */ + bool is_empty() const { + return tiles.empty() && symbols.empty(); + } + + inline const memorized_terrain_tile &tile( const point &p ) const { + if( tiles.empty() ) { + return default_tile; + } else { + return tiles[p.y * SEEX + p.x]; + } + } + + inline void set_tile( const point &p, const memorized_terrain_tile &value ) { + if( tiles.empty() ) { + // call 'reserve' first to force allocation of exact size + tiles.reserve( SEEX * SEEY ); + tiles.resize( SEEX * SEEY, default_tile ); + } + tiles[p.y * SEEX + p.x] = value; + } + + inline int symbol( const point &p ) const { + if( symbols.empty() ) { + return default_symbol; + } else { + return symbols[p.y * SEEX + p.x]; + } + } + + inline void set_symbol( const point &p, int value ) { + if( symbols.empty() ) { + // call 'reserve' first to force allocation of exact size + symbols.reserve( SEEX * SEEY ); + symbols.resize( SEEX * SEEY, default_symbol ); + } + symbols[p.y * SEEX + p.x] = value; + } + + void serialize( JsonOut &jsout ) const; + void deserialize( JsonIn &jsin ); + + private: + std::vector tiles; // holds either 0 or SEEX*SEEY elements + std::vector symbols; // holds either 0 or SEEX*SEEY elements +}; + +/** + * Represents a square of mm_submaps. + * For faster save/load, submaps are collected into regions + * and each region is saved in its own file. + */ +struct mm_region { + shared_ptr_fast submaps[MM_REG_SIZE][MM_REG_SIZE]; + + mm_region(); + + bool is_empty() const; + + void serialize( JsonOut &jsout ) const; + void deserialize( JsonIn &jsin ); +}; + +/** + * Manages map tiles memorized by the avatar. + * Note that there are 2 separate memories in here: + * 1. memorized graphic tiles (for TILES with a tileset) + * 2. memorized symbols (for CURSES or TILES in ascii mode) + * TODO: combine tiles and curses. Also, split map memory into layers (terrain/furn/vpart/...)? + */ class map_memory { + private: + /** + * Helper class for converting global ms coord into + * global sm coord + ms coord within the submap. + */ + struct coord_pair { + tripoint sm; + point loc; + + coord_pair( const tripoint &p ); + }; + public: - void store( JsonOut &jsout ) const; - void load( JsonIn &jsin ); - void load( const JsonObject &jsin ); + map_memory(); + + /** Load memorized submaps around given global map square pos. */ + void load( const tripoint &pos ); + + /** Load legacy memory file. TODO: remove after 0.F (or whatever BN will have instead). */ + void load_legacy( JsonIn &jsin ); - /** Memorizes a given tile; finalize_tile_memory needs to be called after it */ - void memorize_tile( int limit, const tripoint &pos, const std::string &ter, + /** Save memorized submaps to disk, drop ones far from given global map square pos. */ + bool save( const tripoint &pos ); + + /** + * Prepares map memory for rendering and/or memorization of given region. + * @param p1 top-left corner of the region, in global ms coords + * @param p2 bottom-right corner of the region, in global ms coords + * Both coords are inclusive and should be on the same Z level. + * @return whether the region was re-cached + */ + bool prepare_region( const tripoint &p1, const tripoint &p2 ); + + /** + * Memorizes given tile, overwriting old value. + * @param pos tile position, in global ms coords. + */ + void memorize_tile( const tripoint &pos, const std::string &ter, int subtile, int rotation ); - /** Returns last stored map tile in given location */ - memorized_terrain_tile get_tile( const tripoint &pos ) const; + /** + * Returns memorized tile. + * @param pos tile position, in global ms coords. + */ + const memorized_terrain_tile &get_tile( const tripoint &pos ) const; - void memorize_symbol( int limit, const tripoint &pos, int symbol ); + /** + * Memorizes given symbol, overwriting old value. + * @param pos tile position, in global ms coords. + */ + void memorize_symbol( const tripoint &pos, int symbol ); + + /** + * Returns memorized symbol. + * @param pos tile position, in global ms coords. + */ int get_symbol( const tripoint &pos ) const; + /** + * Clears memorized tile and symbol. + * @param pos tile position, in global ms coords. + */ void clear_memorized_tile( const tripoint &pos ); + private: - lru_cache tile_cache; - lru_cache symbol_cache; + std::map> submaps; + + std::vector> cached; + tripoint cache_pos; + point cache_size; + + /** Find, load or allocate a submap. @returns the submap. */ + shared_ptr_fast fetch_submap( const tripoint &sm_pos ); + /** Find submap amongst the loaded submaps. @returns nullptr if failed. */ + shared_ptr_fast find_submap( const tripoint &sm_pos ); + /** Load submap from disk. @returns nullptr if failed. */ + shared_ptr_fast load_submap( const tripoint &sm_pos ); + /** Allocate empty submap. @returns the submap. */ + shared_ptr_fast allocate_submap( const tripoint &sm_pos ); + + /** Get submap from within the cache */ + //@{ + const mm_submap &get_submap( const tripoint &sm_pos ) const; + mm_submap &get_submap( const tripoint &sm_pos ); + //@} + + void clear_cache(); }; #endif // CATA_SRC_MAP_MEMORY_H diff --git a/src/options.cpp b/src/options.cpp index d97edc5182dd2..10da65b59273b 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -3164,7 +3164,6 @@ void options_manager::load() } ); update_global_locale(); - update_options_cache(); #if defined(SDL_SOUND) diff --git a/src/point.h b/src/point.h index dbcb3ec56e82f..4f4d93cc6ddb8 100644 --- a/src/point.h +++ b/src/point.h @@ -244,6 +244,7 @@ struct tripoint { friend inline constexpr bool operator!=( const tripoint &a, const tripoint &b ) { return !( a == b ); } + friend inline bool operator<( const tripoint &a, const tripoint &b ) { if( a.x != b.x ) { return a.x < b.x; diff --git a/src/ranged.cpp b/src/ranged.cpp index 765379f92530d..5379b3539d157 100644 --- a/src/ranged.cpp +++ b/src/ranged.cpp @@ -2080,6 +2080,7 @@ target_handler::trajectory target_ui::run() } } + // Event loop! ExitCode loop_exit_code; std::string timed_out_action; @@ -2998,6 +2999,7 @@ void target_ui::draw_terrain_overlay() // Draw spell AOE if( mode == TargetMode::Spell ) { + drawsq_params params; for( const tripoint &tile : spell_aoe ) { if( tile.z != center.z ) { continue; @@ -3007,7 +3009,7 @@ void target_ui::draw_terrain_overlay() g->draw_highlight( tile ); } else { #endif - get_map().drawsq( g->w_terrain, *you, tile, true, true, center ); + get_map().drawsq( g->w_terrain, tile, params ); #ifdef TILES } #endif diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index a6e9445a02c0c..351ccb459b73e 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -1432,10 +1432,6 @@ void avatar::load( const JsonObject &data ) } } - //Load from legacy map_memory save location (now in its own file .mm) - if( data.has_member( "map_memory_tiles" ) || data.has_member( "map_memory_curses" ) ) { - player_map_memory.load( data ); - } data.read( "show_map_memory", show_map_memory ); for( JsonArray pair : data.get_array( "assigned_invlet" ) ) { @@ -3491,94 +3487,174 @@ void player_morale::load( const JsonObject &jsin ) jsin.read( "morale", points ); } -void map_memory::store( JsonOut &jsout ) const +struct mm_elem { + memorized_terrain_tile tile; + int symbol; + + bool operator==( const mm_elem &rhs ) const { + return symbol == rhs.symbol && tile == rhs.tile; + } +}; + +void mm_submap::serialize( JsonOut &jsout ) const { jsout.start_array(); - jsout.start_array(); - for( const auto &elem : tile_cache.list() ) { + + // Uses RLE for compression. + + mm_elem last; + int num_same = 1; + + const auto write_seq = [&]() { jsout.start_array(); - jsout.write( elem.first.x ); - jsout.write( elem.first.y ); - jsout.write( elem.first.z ); - jsout.write( elem.second.tile ); - jsout.write( elem.second.subtile ); - jsout.write( elem.second.rotation ); + jsout.write( last.tile.tile ); + jsout.write( last.tile.subtile ); + jsout.write( last.tile.rotation ); + jsout.write( last.symbol ); + if( num_same != 1 ) { + jsout.write( num_same ); + } jsout.end_array(); + }; + + for( size_t y = 0; y < SEEY; y++ ) { + for( size_t x = 0; x < SEEX; x++ ) { + point p( x, y ); + const mm_elem elem = { tile( p ), symbol( p ) }; + if( x == 0 && y == 0 ) { + last = elem; + continue; + } + if( last == elem ) { + num_same += 1; + continue; + } + write_seq(); + num_same = 1; + last = elem; + } } + write_seq(); + jsout.end_array(); +} + +void mm_submap::deserialize( JsonIn &jsin ) +{ + jsin.start_array(); + + // Uses RLE for compression. + + mm_elem elem; + size_t remaining = 0; + for( size_t y = 0; y < SEEY; y++ ) { + for( size_t x = 0; x < SEEX; x++ ) { + if( remaining > 0 ) { + remaining -= 1; + } else { + jsin.start_array(); + elem.tile.tile = jsin.get_string(); + elem.tile.subtile = jsin.get_int(); + elem.tile.rotation = jsin.get_int(); + elem.symbol = jsin.get_int(); + if( jsin.test_int() ) { + remaining = jsin.get_int() - 1; + } + jsin.end_array(); + } + point p( x, y ); + // Try to avoid assigning to save up on memory + if( elem.tile != mm_submap::default_tile ) { + set_tile( p, elem.tile ); + } + if( elem.symbol != mm_submap::default_symbol ) { + set_symbol( p, elem.symbol ); + } + } + } + jsin.end_array(); +} + +void mm_region::serialize( JsonOut &jsout ) const +{ jsout.start_array(); - for( const auto &elem : symbol_cache.list() ) { - jsout.start_array(); - jsout.write( elem.first.x ); - jsout.write( elem.first.y ); - jsout.write( elem.first.z ); - jsout.write( elem.second ); - jsout.end_array(); + for( size_t y = 0; y < MM_REG_SIZE; y++ ) { + for( size_t x = 0; x < MM_REG_SIZE; x++ ) { + const shared_ptr_fast &sm = submaps[x][y]; + if( sm->is_empty() ) { + jsout.write_null(); + } else { + sm->serialize( jsout ); + } + } } jsout.end_array(); - jsout.end_array(); } -void map_memory::load( JsonIn &jsin ) +void mm_region::deserialize( JsonIn &jsin ) { - // Legacy loading of object version. - if( jsin.test_object() ) { - JsonObject jsobj = jsin.get_object(); - jsobj.allow_omitted_members(); - load( jsobj ); - } else { - // This file is large enough that it's more than called for to minimize the - // amount of data written and read and make it a bit less "friendly", - // and use the streaming interface. - jsin.start_array(); - tile_cache.clear(); - jsin.start_array(); - while( !jsin.end_array() ) { - jsin.start_array(); - tripoint p; - p.x = jsin.get_int(); - p.y = jsin.get_int(); - p.z = jsin.get_int(); - const std::string tile = jsin.get_string(); - const int subtile = jsin.get_int(); - const int rotation = jsin.get_int(); - memorize_tile( std::numeric_limits::max(), p, - tile, subtile, rotation ); - jsin.end_array(); - } - symbol_cache.clear(); - jsin.start_array(); - while( !jsin.end_array() ) { - jsin.start_array(); - tripoint p; - p.x = jsin.get_int(); - p.y = jsin.get_int(); - p.z = jsin.get_int(); - const int symbol = jsin.get_int(); - memorize_symbol( std::numeric_limits::max(), p, symbol ); - jsin.end_array(); + jsin.start_array(); + for( size_t y = 0; y < MM_REG_SIZE; y++ ) { + for( size_t x = 0; x < MM_REG_SIZE; x++ ) { + shared_ptr_fast &sm = submaps[x][y]; + sm = make_shared_fast(); + if( jsin.test_null() ) { + jsin.skip_null(); + } else { + sm->deserialize( jsin ); + } } - jsin.end_array(); } + jsin.end_array(); } -// Deserializer for legacy object-based memory map. -void map_memory::load( const JsonObject &jsin ) +void map_memory::load_legacy( JsonIn &jsin ) { - tile_cache.clear(); - for( JsonObject pmap : jsin.get_array( "map_memory_tiles" ) ) { - pmap.allow_omitted_members(); - const tripoint p( pmap.get_int( "x" ), pmap.get_int( "y" ), pmap.get_int( "z" ) ); - memorize_tile( std::numeric_limits::max(), p, pmap.get_string( "tile" ), - pmap.get_int( "subtile" ), pmap.get_int( "rotation" ) ); + struct mig_elem { + int symbol; + memorized_terrain_tile tile; + }; + std::map elems; + + jsin.start_array(); + jsin.start_array(); + while( !jsin.end_array() ) { + jsin.start_array(); + tripoint p; + p.x = jsin.get_int(); + p.y = jsin.get_int(); + p.z = jsin.get_int(); + mig_elem &elem = elems[p]; + elem.tile.tile = jsin.get_string(); + elem.tile.subtile = jsin.get_int(); + elem.tile.rotation = jsin.get_int(); + jsin.end_array(); } + jsin.start_array(); + while( !jsin.end_array() ) { + jsin.start_array(); + tripoint p; + p.x = jsin.get_int(); + p.y = jsin.get_int(); + p.z = jsin.get_int(); + elems[p].symbol = jsin.get_int(); + jsin.end_array(); + } + jsin.end_array(); - symbol_cache.clear(); - for( JsonObject pmap : jsin.get_array( "map_memory_curses" ) ) { - pmap.allow_omitted_members(); - const tripoint p( pmap.get_int( "x" ), pmap.get_int( "y" ), pmap.get_int( "z" ) ); - memorize_symbol( std::numeric_limits::max(), p, pmap.get_int( "symbol" ) ); + for( const std::pair &elem : elems ) { + coord_pair cp( elem.first ); + shared_ptr_fast sm = find_submap( cp.sm ); + if( !sm ) { + sm = allocate_submap( cp.sm ); + } + if( elem.second.tile != mm_submap::default_tile ) { + sm->set_tile( cp.loc, elem.second.tile ); + } + if( elem.second.symbol != mm_submap::default_symbol ) { + sm->set_symbol( cp.loc, elem.second.symbol ); + } } } diff --git a/tests/map_memory_test.cpp b/tests/map_memory_test.cpp index fcc28128043ea..c294e0fdf463a 100644 --- a/tests/map_memory_test.cpp +++ b/tests/map_memory_test.cpp @@ -11,13 +11,33 @@ #include "map_memory.h" #include "point.h" -static constexpr tripoint p1{ tripoint_above }; -static constexpr tripoint p2{ 0, 0, 2 }; -static constexpr tripoint p3{ 0, 0, 3 }; +static constexpr tripoint p1{ -SEEX - 2, -SEEY - 3, -1 }; +static constexpr tripoint p2{ 5, 7, -1 }; +static constexpr tripoint p3{ SEEX * 2 + 5, SEEY + 7, -1 }; +static constexpr tripoint p4{ SEEX * 3 + 2, SEEY * 7 + 1, -1 }; + +TEST_CASE( "map_memory_keeps_region", "[map_memory]" ) +{ + map_memory memory; + CHECK( memory.prepare_region( p1, p2 ) ); + CHECK( !memory.prepare_region( p1, p2 ) ); + CHECK( !memory.prepare_region( p1 + tripoint_east, p2 + tripoint_east ) ); + CHECK( memory.prepare_region( p2, p3 ) ); + CHECK( memory.prepare_region( p1, p3 ) ); + CHECK( !memory.prepare_region( p1, p3 ) ); + CHECK( !memory.prepare_region( p2, p3 ) ); + CHECK( memory.prepare_region( p1, p4 ) ); + CHECK( !memory.prepare_region( p2, p3 ) ); + CHECK( memory.prepare_region( + tripoint( p2.x, p2.y, -p2.z ), + tripoint( p3.x, p3.y, -p3.z ) + ) ); +} TEST_CASE( "map_memory_defaults", "[map_memory]" ) { map_memory memory; + memory.prepare_region( p1, p2 ); CHECK( memory.get_symbol( p1 ) == 0 ); memorized_terrain_tile default_tile = memory.get_tile( p1 ); CHECK( default_tile.tile.empty() ); @@ -28,66 +48,25 @@ TEST_CASE( "map_memory_defaults", "[map_memory]" ) TEST_CASE( "map_memory_remembers", "[map_memory]" ) { map_memory memory; - memory.memorize_symbol( 2, p1, 1 ); - memory.memorize_symbol( 2, p2, 2 ); + memory.prepare_region( p1, p2 ); + memory.memorize_symbol( p1, 1 ); + memory.memorize_symbol( p2, 2 ); CHECK( memory.get_symbol( p1 ) == 1 ); CHECK( memory.get_symbol( p2 ) == 2 ); } -TEST_CASE( "map_memory_limited", "[map_memory]" ) -{ - lru_cache symbol_cache; - symbol_cache.insert( 2, p1, 1 ); - symbol_cache.insert( 2, p2, 1 ); - symbol_cache.insert( 2, p3, 1 ); - CHECK( symbol_cache.get( p1, 0 ) == 0 ); -} - TEST_CASE( "map_memory_overwrites", "[map_memory]" ) { map_memory memory; - memory.memorize_symbol( 2, p1, 1 ); - memory.memorize_symbol( 2, p2, 2 ); - memory.memorize_symbol( 2, p2, 3 ); + memory.prepare_region( p1, p2 ); + memory.memorize_symbol( p1, 1 ); + memory.memorize_symbol( p2, 2 ); + memory.memorize_symbol( p2, 3 ); CHECK( memory.get_symbol( p1 ) == 1 ); CHECK( memory.get_symbol( p2 ) == 3 ); } -TEST_CASE( "map_memory_erases_lru", "[map_memory]" ) -{ - lru_cache symbol_cache; - symbol_cache.insert( 2, p1, 1 ); - symbol_cache.insert( 2, p2, 2 ); - symbol_cache.insert( 2, p1, 1 ); - symbol_cache.insert( 2, p3, 3 ); - CHECK( symbol_cache.get( p1, 0 ) == 1 ); - CHECK( symbol_cache.get( p2, 0 ) == 0 ); - CHECK( symbol_cache.get( p3, 0 ) == 3 ); -} - -TEST_CASE( "map_memory_survives_save_lod", "[map_memory]" ) -{ - map_memory memory; - memory.memorize_symbol( 2, p1, 1 ); - memory.memorize_symbol( 2, p2, 2 ); - - // Save and reload - std::ostringstream jsout_s; - JsonOut jsout( jsout_s ); - memory.store( jsout ); - - INFO( "Json was: " << jsout_s.str() ); - std::istringstream jsin_s( jsout_s.str() ); - JsonIn jsin( jsin_s ); - map_memory memory2; - memory2.load( jsin ); - - memory.memorize_symbol( 2, p3, 3 ); - memory2.memorize_symbol( 2, p3, 3 ); - CHECK( memory.get_symbol( p1 ) == memory2.get_symbol( p1 ) ); - CHECK( memory.get_symbol( p2 ) == memory2.get_symbol( p2 ) ); - CHECK( memory.get_symbol( p3 ) == memory2.get_symbol( p3 ) ); -} +// TODO: map memory save / load #include diff --git a/tests/point_test.cpp b/tests/point_test.cpp index 355e0cfa3adf4..10ae9fee70903 100644 --- a/tests/point_test.cpp +++ b/tests/point_test.cpp @@ -26,6 +26,78 @@ TEST_CASE( "rectangle_containment_raw", "[point]" ) CHECK( !r2.contains( point( 0, 3 ) ) ); } +TEST_CASE( "rectangle_overlapping_inclusive", "[point]" ) +{ + inclusive_rectangle r1( point( 0, 0 ), point( 2, + 2 ) ); // NOLINT(cata-use-named-point-constants) + inclusive_rectangle r2( point( 2, 2 ), point( 3, 3 ) ); + inclusive_rectangle r3( point( 0, 0 ), point( 2, + 1 ) ); // NOLINT(cata-use-named-point-constants) + inclusive_rectangle r4( point( -2, -4 ), point( 4, -1 ) ); + inclusive_rectangle r5( point( -1, -3 ), point( 0, -2 ) ); + + CHECK( r1.overlaps( r1 ) ); + CHECK( r1.overlaps( r2 ) ); + CHECK( r1.overlaps( r3 ) ); + CHECK( !r1.overlaps( r4 ) ); + CHECK( !r1.overlaps( r5 ) ); + + CHECK( r2.overlaps( r1 ) ); + CHECK( r2.overlaps( r2 ) ); + CHECK( !r2.overlaps( r3 ) ); + CHECK( !r2.overlaps( r4 ) ); + CHECK( !r2.overlaps( r5 ) ); + + CHECK( r3.overlaps( r1 ) ); + CHECK( !r3.overlaps( r2 ) ); + CHECK( r3.overlaps( r3 ) ); + CHECK( !r3.overlaps( r4 ) ); + CHECK( !r3.overlaps( r5 ) ); + + CHECK( !r4.overlaps( r1 ) ); + CHECK( !r4.overlaps( r2 ) ); + CHECK( !r4.overlaps( r3 ) ); + CHECK( r4.overlaps( r4 ) ); + CHECK( r4.overlaps( r5 ) ); + CHECK( r5.overlaps( r4 ) ); +} + +TEST_CASE( "rectangle_overlapping_half_open", "[point]" ) +{ + half_open_rectangle r1( point( 0, 0 ), point( 2, + 2 ) ); // NOLINT(cata-use-named-point-constants) + half_open_rectangle r2( point( 2, 2 ), point( 3, 3 ) ); + half_open_rectangle r3( point( 0, 0 ), point( 2, + 1 ) ); // NOLINT(cata-use-named-point-constants) + half_open_rectangle r4( point( -2, -4 ), point( 4, -1 ) ); + half_open_rectangle r5( point( -1, -3 ), point( 0, -2 ) ); + + CHECK( r1.overlaps( r1 ) ); + CHECK( !r1.overlaps( r2 ) ); + CHECK( r1.overlaps( r3 ) ); + CHECK( !r1.overlaps( r4 ) ); + CHECK( !r1.overlaps( r5 ) ); + + CHECK( !r2.overlaps( r1 ) ); + CHECK( r2.overlaps( r2 ) ); + CHECK( !r2.overlaps( r3 ) ); + CHECK( !r2.overlaps( r4 ) ); + CHECK( !r2.overlaps( r5 ) ); + + CHECK( r3.overlaps( r1 ) ); + CHECK( !r3.overlaps( r2 ) ); + CHECK( r3.overlaps( r3 ) ); + CHECK( !r3.overlaps( r4 ) ); + CHECK( !r3.overlaps( r5 ) ); + + CHECK( !r4.overlaps( r1 ) ); + CHECK( !r4.overlaps( r2 ) ); + CHECK( !r4.overlaps( r3 ) ); + CHECK( r4.overlaps( r4 ) ); + CHECK( r4.overlaps( r5 ) ); + CHECK( r5.overlaps( r4 ) ); +} + TEST_CASE( "rectangle_containment_coord", "[point]" ) { // NOLINTNEXTLINE(cata-use-named-point-constants) From bd78e45d59124e85aab9d0f77df59f7eb93558d1 Mon Sep 17 00:00:00 2001 From: Paul Fenwick Date: Thu, 8 Jul 2021 20:13:54 -0700 Subject: [PATCH 080/116] Reduce solder in electronics control unit from 150 to 40 (#49734) Closes #49725 --- data/json/recipes/other/parts.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/recipes/other/parts.json b/data/json/recipes/other/parts.json index 4379a003382f8..2558110721855 100644 --- a/data/json/recipes/other/parts.json +++ b/data/json/recipes/other/parts.json @@ -534,7 +534,7 @@ "time": "1 h", "reversible": true, "autolearn": true, - "using": [ [ "soldering_standard", 150 ] ], + "using": [ [ "soldering_standard", 40 ] ], "qualities": [ { "id": "SCREW", "level": 1 } ], "proficiencies": [ { "proficiency": "prof_plasticworking" } ], "components": [ [ [ "e_scrap", 5 ] ], [ [ "amplifier", 1 ] ], [ [ "cable", 5 ] ], [ [ "plastic_chunk", 5 ] ] ] From 957191140c1f625db4f3cd454f2a6ecfb53a545a Mon Sep 17 00:00:00 2001 From: Extension-Driver <85973915+Extension-Driver@users.noreply.github.com> Date: Fri, 9 Jul 2021 15:24:22 +1200 Subject: [PATCH 081/116] Add new location: Safe Light Industry, and link it to the Safe Place scenario (#49320) * Added light industry as possible start location * Corrected spelling of 'Industrial' * Added Light Industry to Safe Place * Add welding googles to tools_mechanic * fix comma, 2x googles chance * googles -> goggles * re-add s_lightindustry_scen.json * re-add overmap defs for LI * diff (scen) * update the defn of LI start location * re-add LI OM special defn * Update chemistry.json * Fix terrian defn --- data/json/itemgroups/tools.json | 3 +- data/json/mapgen/s_lightindustry_scen.json | 289 ++++++++++++++++++ .../overmap/overmap_special/specials.json | 22 ++ .../overmap_terrain_industrial.json | 29 ++ data/json/scenarios.json | 3 +- data/json/start_locations.json | 6 + 6 files changed, 350 insertions(+), 2 deletions(-) create mode 100644 data/json/mapgen/s_lightindustry_scen.json diff --git a/data/json/itemgroups/tools.json b/data/json/itemgroups/tools.json index 993a87bdf287a..d9dc27b428290 100644 --- a/data/json/itemgroups/tools.json +++ b/data/json/itemgroups/tools.json @@ -304,7 +304,8 @@ { "item": "polisher", "prob": 70, "charges": [ 0, 100 ] }, { "item": "angle_grinder", "prob": 5, "charges": [ 0, 500 ] }, { "item": "welder", "prob": 10, "charges": [ 0, 500 ] }, - [ "clamp", 10 ] + [ "clamp", 10 ], + [ "goggles_welding", 80 ] ] }, { diff --git a/data/json/mapgen/s_lightindustry_scen.json b/data/json/mapgen/s_lightindustry_scen.json new file mode 100644 index 0000000000000..02a3342bd637c --- /dev/null +++ b/data/json/mapgen/s_lightindustry_scen.json @@ -0,0 +1,289 @@ +[ + { + "type": "mapgen", + "method": "json", + "om_terrain": [ + [ "s_lightindustry_scen_10", "s_lightindustry_scen_11" ], + [ "s_lightindustry_scen_road_0", "s_lightindustry_scen_road_1" ], + [ "s_lightindustry_scen_00", "s_lightindustry_scen_01" ] + ], + "object": { + "fill_ter": "t_floor", + "rows": [ + "................................................", + "................................................", + "#%%%%#%%%%#%%%%#%%#%%%%#%%%%#%%%%#%%%%#%%%%#....", + "##::###::###::##::#######oo###oo###oo###oo##^%%#", + "#!{!v#rrrP#Prrr#HHHN#jk#U~~UUU~~U#~55~d~88~##o##", + "#!}}!: h h :!!!H#;;#U~~~~~~~U#~~~~d~~~~#ppp#", + "#!!!!: :NN!H#M;#U~~~~~~~U#dd&dd~~~~:;q;o", + "#L!!!:r hrh ) ##+##ddddd&d##~~~~~~6~~:;;;#", + "#L!!L:rh r r: zz #~~~~~~~~~#~~~~~~9~~:;;M#", + "###)##B P#P hr: +~~`````~~~~~45~~5~~);;p#", + "+ u# B #~~`~~~`~~~~~~~~~~~~:;qpo", + "#::):#::):#::):#))#::):#~~`~~~`~~~~~52~~~~~#;;p#", + "# #P u#u # #r #~~`~~~`~~~~~~~~~##+##+##", + "#rr u#r hr#P hr# :rh u#~~`~~~`~~~~~~~~1#;;#.s.#", + "# h P#rh r#P rr# #r P#c~`~~~`~~#5~31~5#kj#.s..", + "##::###::###::##))##::###bbbbbbb###o##o#####.s..", + "#%%%%#%%%%#%%%%#ss#%%%%#c_______s#%%%%%%.^.#.s..", + "sssssssssssssssssssssssss_______ssssssssssssssss", + "s____e____e____e____es%s___________se____e____es", + "s____e____e____e____es%s___________se____e____es", + "s____e____e____e____es%s___________se____e____es", + "s____e____e____e____es%s___________se____e____es", + "s____e____e____e____es%s___________se____e____es", + "s____e____e____e____esss___________se____e____es", + "s______________________________________________s", + "s______________________________________________s", + "s______________________________________________s", + "s______________________________________________s", + "s______________________________________________s", + "s______ssssssssssssssssssssssssssssssssss______s", + "s______s%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%s_______", + "s______ssssssssssssssssssssssssssssssssss_______", + "s_______________________________________________", + "s_______________________________________________", + "s_______________________________________________", + "s_______________________________________________", + "s_______________________________________________", + "s_______________________________________________", + "s_______________________________________________", + "s_______________________________________________", + "s_______________________________________________", + "s_______________________________________________", + "s___________________ssssssss__________ssssssssss", + "s___________________s%%s...s__________s.........", + "s___________________s%%s...s__________s.........", + "s___________________s%%s...s__________s.........", + "s___________________s%%s...s__________s.........", + "s___________________ssssssss__________s.........", + "s____e____e____e____ssss...s__________s.........", + "s____e____e____e____s%%s...s__________s.........", + "s____e____e____e____s%%s...s__________s.........", + "s____e____e____e____s%%s...s__________s.........", + "s____e____e____e____s%%s...s__________s.........", + "s____e____e____e____ssss...s__________s%%%.%%%..", + "ssssssssssssssssssssssss...s__________##o###o##.", + ".##o###o###o##...sss...s...s__________#rrr#Phr#.", + ".#rru#thr#rBt#...sss...sssssc_________# h # r#.", + "^# h # r#rh #...sss...s...##bbbbbbb#+# ##", + "## #%%#o+o#%%s%%%#c~`~~~`~~~# u#", + "#r ####==y#####o##~~`~~~`~~~o hhhh ho", + "orh # h # u# u#===wwx#CCC~~~`~~~`~~~# ZZZZ rr#", + "#r #rru# u#hro=====w#CC~~~~`~~~`~~~o hhhh ###", + "### ##### u# r#=====w#~~~~~~`~~~`~~~# r#", + "#rr #thr# u#+##======+~~~~~~`````~~~+ hro", + "#th # r# B# zz======#~~~~~~~~~57~~~# u#", + "or + #####d&d#~~~~~31~~~#B P ##+##", + "#rh + #Y;j#Q~Q#~~~~~~~~~5##+# #B r#", + "###+##t ####### +;;k#Q~Q#~52~~~~~~2#;;# # hr#", + "#rr B#t #mnlkn# #####Q~Q#~~~~~46~~~#jk# # r#", + "o h u# +;;;;;+ +;;k#Q~Q#~52~~~~~~8####+##o##", + "# u#t #qpq;Y# #Y;j#Q~Q#~~~~~~~~~8#^sssss...", + "###o###+####o########o###o####o####o###.sssss..." + ], + "terrain": { + ".": "t_region_groundcover_urban", + "%": "t_region_shrub_decorative", + "#": "t_brick_wall", + "o": "t_window", + " ": "t_floor", + "s": "t_sidewalk", + "_": "t_pavement", + "e": "t_pavement_y", + ";": "t_linoleum_gray", + "j": "t_linoleum_gray", + "k": "t_linoleum_gray", + "l": "t_linoleum_gray", + "m": "t_linoleum_gray", + "n": "t_linoleum_gray", + "Y": "t_linoleum_gray", + "M": "t_linoleum_gray", + "q": "t_linoleum_gray", + "p": "t_linoleum_gray", + "=": "t_carpet_green", + "w": "t_carpet_green", + "x": "t_carpet_green", + "y": "t_carpet_green", + "!": "t_carpet_red", + "v": "t_carpet_red", + "H": "t_carpet_red", + "}": "t_carpet_red", + "{": "t_carpet_red", + "L": "t_carpet_red", + "N": "t_carpet_red", + "~": "t_thconc_floor", + "C": "t_thconc_floor", + "Q": "t_thconc_floor", + "U": "t_thconc_floor", + "1": "t_thconc_floor", + "2": "t_thconc_floor", + "3": "t_thconc_floor", + "4": "t_thconc_floor", + "9": "t_thconc_floor", + "`": "t_metal_floor", + ":": "t_wall_glass", + ")": "t_door_glass_c", + "+": "t_door_c", + "b": "t_door_metal_locked", + "c": "t_gates_mech_control", + "d": "t_chainfence_h", + "&": "t_chaingate_l", + "5": "t_thconc_floor", + "6": "t_thconc_floor", + "7": "t_thconc_floor", + "8": "t_thconc_floor", + "^": "t_gutter_downspout" + }, + "furniture": { + "5": "f_machinery_electronic", + "6": "f_machinery_light", + "7": "f_machinery_heavy", + "8": "f_machinery_old", + "k": "f_sink", + "l": "f_oven", + "m": "f_fridge", + "n": "f_counter", + "q": "f_chair", + "h": "f_chair", + "{": "f_chair", + "p": "f_table", + "}": "f_desk", + "r": "f_desk", + "x": "f_table", + "Z": "f_table", + "N": "f_table", + "Q": "f_rack", + "t": "f_locker", + "U": "f_locker", + "M": "f_locker", + "P": "f_filing_cabinet", + "u": "f_bookcase", + "L": "f_bookcase", + "w": "f_sofa", + "H": "f_sofa", + "z": "f_vending_c", + "Y": "f_trashcan", + "y": "f_trashcan", + "B": "f_trashcan", + "v": "f_safe_l", + "1": "f_arcfurnace_empty", + "2": "f_hydraulic_press", + "3": "f_air_compressor", + "4": "f_drill_press", + "9": "f_heavy_lathe", + "C": "f_crate_c" + }, + "toilets": { "j": { } }, + "items": { + "y": { "item": "trash", "chance": 30, "repeat": [ 2, 3 ] }, + "B": { "item": "trash", "chance": 30, "repeat": [ 2, 3 ] }, + "Y": { "item": "trash", "chance": 30, "repeat": [ 2, 3 ] }, + "v": { "item": "vault", "chance": 30, "repeat": [ 2, 3 ] }, + "r": { "item": "office", "chance": 30 }, + "Z": { "item": "office", "chance": 30 }, + "t": { "item": "cleaning_bulk", "chance": 30, "repeat": [ 2, 3 ] }, + "n": { "item": "kitchen_nonfood", "chance": 30, "repeat": [ 1, 2 ] }, + "l": { "item": "oven", "chance": 30, "repeat": [ 1, 3 ] }, + "m": { "item": "SUS_fridge_breakroom", "chance": 30 }, + "x": { "item": "magazines", "chance": 30, "repeat": [ 2, 5 ] }, + "N": { "item": "magazines", "chance": 30, "repeat": [ 0, 2 ] }, + "P": { "item": "office_paper", "chance": 30 }, + "H": [ { "item": "jackets", "chance": 10 }, { "item": "bags", "chance": 10 } ], + "u": { "item": "textbooks", "chance": 30, "repeat": [ 1, 2 ] }, + "L": { "item": "textbooks", "chance": 30, "repeat": [ 1, 2 ] }, + "C": { "item": "tools_construction", "chance": 50, "repeat": [ 2, 3 ] }, + " ": { "item": "office_mess", "chance": 5 }, + "~": { "item": "vehicle_scrapped", "chance": 3 } + }, + "place_loot": [ + { "group": "vending_food", "chance": 80, "x": 15, "y": 64 }, + { "group": "vending_drink", "chance": 80, "x": 16, "y": 64 }, + { "group": "vending_food", "chance": 80, "x": 20, "y": 8 }, + { "group": "vending_drink", "chance": 80, "x": 21, "y": 8 }, + { "group": "bar_trash", "chance": 50, "repeat": 2, "x": 11, "y": 70 }, + { "group": "tools_blacksmith", "chance": 60, "repeat": 4, "x": 26, "y": [ 68, 70 ] }, + { "group": "tools_mechanic", "chance": 60, "repeat": 2, "x": 26, "y": [ 66, 67 ] }, + { "group": "tools_home", "chance": 60, "repeat": 4, "x": 24, "y": [ 66, 68 ] }, + { "group": "power_tools", "chance": 60, "repeat": 3, "x": 24, "y": [ 69, 70 ] }, + { "group": "hand_tools", "chance": 75, "repeat": 4, "x": 24, "y": [ 4, 6 ] }, + { "group": "power_tools", "chance": 75, "repeat": 4, "x": [ 27, 29 ], "y": 4 }, + { "group": "tools_mechanic", "chance": 75, "repeat": 4, "x": 32, "y": [ 4, 6 ] }, + { "group": "elecsto_diy", "chance": 60, "repeat": 4, "x": [ 34, 39 ], "y": [ 12, 14 ] }, + { "group": "elecsto_diy", "chance": 60, "repeat": 4, "x": [ 34, 37 ], "y": [ 4, 5 ] } + ], + "place_vehicles": [ { "vehicle": "cube_van", "x": 31, "y": 50, "chance": 100, "status": -1, "rotation": 270 } ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ [ "s_lightindustry_scen_10_roof", "s_lightindustry_scen_11_roof" ] ], + "object": { + "fill_ter": "t_flat_roof", + "rows": [ + " ", + " ", + ". . . . . . . . . . ", + "|2222222222222222222222222222222222222222223 .", + "|..........................................52223", + "|................................=.............3", + "|..............................................3", + "|..............................................3", + "|.........&........................&...........3", + "|..............................................3", + "|..................X........:..................3", + "|..............................................3", + "|..........................................3---3", + "|............=.............................3 .", + "|..........................................3 ", + "|----------------------------------------5-3 ", + ". . . . . . . . ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "roof_palette" ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ [ "s_lightindustry_scen_00_roof", "s_lightindustry_scen_01_roof" ] ], + "object": { + "fill_ter": "t_flat_roof", + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " |22222223 ", + " |222222222223 |.......3 ", + " |...........3 |.......3 ", + " 5...........3 |2222222222|.......33", + "||...........3 |2223 |...................3", + "|............322|...3222222|....X....:.........3", + "|..............................................3", + "|..............................................3", + "|..............................................3", + "|..............................................3", + "|..........&.............................=.....3", + "|.................:............................3", + "|............................&.................3", + "|....X.........................................3", + "|..............................................3", + "|.....................................5--------3", + "|.....................=...............3 ", + "|-------------------------------------3 " + ], + "palettes": [ "roof_palette" ] + } + } +] diff --git a/data/json/overmap/overmap_special/specials.json b/data/json/overmap/overmap_special/specials.json index 19841ac6f844a..45715665471ee 100644 --- a/data/json/overmap/overmap_special/specials.json +++ b/data/json/overmap/overmap_special/specials.json @@ -7445,5 +7445,27 @@ "//": "Low chance to find a matching location, so always try to place it", "occurrences": [ 100, 100 ], "flags": [ "LAB", "UNIQUE" ] + }, + { + "type": "overmap_special", + "id": "o_lightindustry_scen", + "overmaps": [ + { "point": [ 1, 0, 0 ], "overmap": "s_lightindustry_scen_road_0_south" }, + { "point": [ 0, 0, 0 ], "overmap": "s_lightindustry_scen_road_1_south" }, + { "point": [ 1, -1, 0 ], "overmap": "s_lightindustry_scen_00_south" }, + { "point": [ 1, -1, 1 ], "overmap": "s_lightindustry_scen_00_roof_south" }, + { "point": [ 0, -1, 0 ], "overmap": "s_lightindustry_scen_01_south" }, + { "point": [ 0, -1, 1 ], "overmap": "s_lightindustry_scen_01_roof_south" }, + { "point": [ 1, 1, 0 ], "overmap": "s_lightindustry_scen_10_south" }, + { "point": [ 1, 1, 1 ], "overmap": "s_lightindustry_scen_10_roof_south" }, + { "point": [ 0, 1, 0 ], "overmap": "s_lightindustry_scen_11_south" }, + { "point": [ 0, 1, 1 ], "overmap": "s_lightindustry_scen_11_roof_south" } + ], + "connections": [ { "point": [ -1, 0, 0 ], "terrain": "road", "from": [ 0, 0, 0 ] } ], + "locations": [ "wilderness" ], + "city_distance": [ 1, 40 ], + "city_sizes": [ 4, -1 ], + "occurrences": [ 0, 1 ], + "flags": [ "CLASSIC" ] } ] diff --git a/data/json/overmap/overmap_terrain/overmap_terrain_industrial.json b/data/json/overmap/overmap_terrain/overmap_terrain_industrial.json index c57c4e7367a21..0f066501a694e 100644 --- a/data/json/overmap/overmap_terrain/overmap_terrain_industrial.json +++ b/data/json/overmap/overmap_terrain/overmap_terrain_industrial.json @@ -419,5 +419,34 @@ "color": "dark_gray", "see_cost": 5, "flags": [ "KNOWN_UP" ] + }, + { + "type": "overmap_terrain", + "id": [ "s_lightindustry_scen_road_0", "s_lightindustry_scen_road_1" ], + "name": "light industry", + "sym": "─", + "color": "dark_gray", + "see_cost": 5, + "extras": "build", + "mondensity": 2 + }, + { + "type": "overmap_terrain", + "id": [ + "s_lightindustry_scen_00", + "s_lightindustry_scen_00_roof", + "s_lightindustry_scen_01", + "s_lightindustry_scen_01_roof", + "s_lightindustry_scen_10", + "s_lightindustry_scen_10_roof", + "s_lightindustry_scen_11", + "s_lightindustry_scen_11_roof" + ], + "name": "light industry", + "sym": "I", + "color": "light_blue", + "see_cost": 5, + "extras": "build", + "mondensity": 2 } ] diff --git a/data/json/scenarios.json b/data/json/scenarios.json index a639ca8ac13be..c1a4726a2217a 100644 --- a/data/json/scenarios.json +++ b/data/json/scenarios.json @@ -105,7 +105,8 @@ "sloc_lighthouse_ground", "sloc_cabin_lake", "sloc_lodge_ground", - "sloc_freshwater_research_station" + "sloc_freshwater_research_station", + "sloc_light_industry_scen" ], "start_name": "Safe Building", "flags": [ "LONE_START" ] diff --git a/data/json/start_locations.json b/data/json/start_locations.json index cfb4afa3039fc..8148499ea4027 100644 --- a/data/json/start_locations.json +++ b/data/json/start_locations.json @@ -503,5 +503,11 @@ { "om_terrain": "road_curved", "om_terrain_match_type": "PREFIX" }, { "om_terrain": "road_end", "om_terrain_match_type": "PREFIX" } ] + }, + { + "type": "start_location", + "id": "sloc_light_industry_scen", + "name": "Industrial Offices", + "terrain": [ "s_lightindustry_scen_10" ] } ] From cbfdd31aaf539283f0c34b873f8cc8f519e339e9 Mon Sep 17 00:00:00 2001 From: gisaku33 Date: Thu, 8 Jul 2021 23:25:59 -0400 Subject: [PATCH 082/116] Update mutations.json (#49303) --- data/json/mutations/mutations.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/data/json/mutations/mutations.json b/data/json/mutations/mutations.json index b4e1da072d360..694fbdf93e346 100644 --- a/data/json/mutations/mutations.json +++ b/data/json/mutations/mutations.json @@ -3272,10 +3272,9 @@ "id": "BURROW", "name": { "str": "Burrowing" }, "points": 10, - "consume_time_modifier": 2.0, "valid": false, "purifiable": false, - "description": "Between your claws and teeth, you can tunnel through just about anything.", + "description": "Your tough paws allow you to dig through dirt and rubble with ease.", "prereqs": [ "CLAWS_ST", "PAWS", "PAWS_LARGE" ], "threshreq": [ "THRESH_RAT", "THRESH_LUPINE", "THRESH_URSINE" ], "category": [ "RAT", "LUPINE", "URSINE" ], From 6176893913f5456252c2df724be16071a131e325 Mon Sep 17 00:00:00 2001 From: ToxiClay Date: Fri, 9 Jul 2021 01:03:55 -0400 Subject: [PATCH 083/116] Remove CROWS turrets from irradiator overmap special --- data/json/mapgen/irradiator_1.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/data/json/mapgen/irradiator_1.json b/data/json/mapgen/irradiator_1.json index bb22f689dc0a0..c19bb1e14b97d 100644 --- a/data/json/mapgen/irradiator_1.json +++ b/data/json/mapgen/irradiator_1.json @@ -110,7 +110,7 @@ "'f**|MP PPPPP|----==-------XXXXXXXXNXXXXXXXX-----==-----|PPZPPPZPPP|**f'", "'f**|TTTTTTTT| C K KXXXXXXX!Q!!!!!Q!XXXXXX J |TTTTTTTTTT|**f'", "'f**|--------4 C K KKKXCCMMCX!!UUUUU!!XMMCCX J J C 4----------|**f'", - "'f**|( N C K KXCXXXCX!!UUUUU!!XCXXCX J J C N (|**f'", + "'f**| N C K KXCXXXCX!!UUUUU!!XCXXCX J J C N |**f'", "'f**| CCCCCCCMCC C CC1 XXCCCCCC3CCCCCCX 2 M CCMCCCCCCCCC |**f'", "'f**| C N C K CCCC KXXXX!!UUUUU!!XXX CCCCCCM J C N C |**f'", "'f**| C |----4 C K KXXXX!!UUUUU!!XXX M J C 4------| C |**f'", @@ -129,7 +129,7 @@ "'f**| C |M KKKKKKKKKKKK |A AAAAR RAAAA A| JJJJJJJJJJJ | C |**f'", "'f**| CCMCC |A D D A|J CCCMCC |**f'", "'f**| N C KKKKKKKKKKKK |A ^oo^R R^oo^ A|J JJW MMMMMCCCC N |**f'", - "'f**| ( 4 C |-------++-------|J J W MMMMM 4 ( |**f'", + "'f**| 4 C |-------++-------|J J W MMMMM 4 |**f'", "'f**| N C KKKKKKKKKKKK |gggR{{R R{{Rggg|J JJW MMMMMCCCC N |**f'", "'f**| CCMCC |g%%D%%D D%%D%%g|J CCCMCC |**f'", "'f**| C |M KKKKKKKKKKKK |gggR{{R R{{Rggg| WWWWWWWWWWW N C |**f'", @@ -160,9 +160,9 @@ "'f**L_____________________Lss******ss******ssL_____________________L**f'", "'f**L____________________Ls##ssss##ss##ssss##sL____________________L**f'", "'f**L___________________Lss--w=w---DD---w=w--ssL___________________L**f'", - "'fsss__________________Lssswdh ^hx xhA hdwsssL__________________sssf'", - "'fs(s__________________Ls(swxh hd dh hxws(sL__________________s(sf'", - "'fsss__________________Lsss--w-w---DD---w-w--sssL__________________sssf'", + "'f**L__________________Lssswdh ^hx xhA hdwsssL__________________L**f'", + "'f**L__________________Lssswxh hd dh hxwsssL__________________L**f'", + "'f**L__________________Lsss--w-w---DD---w-w--sssL__________________L**f'", "'ffffGGGGGGGGGGGGGGGGGGffffffffffffGGffffffffffffGGGGGGGGGGGGGGGGGGffff'", "[[[[L__________________LssssssssssssssssssssssssL__________________L[[[[", "[[[[L__________________LssssssssssssssssssssssssL__________________L[[[[" @@ -314,7 +314,7 @@ ], "liquids": { "T": { "liquid": "water_clean", "amount": [ 200, 600 ] } }, "fields": { "U": { "field": "fd_nuke_gas", "intensity": 3, "age": 990 }, "/": { "field": "fd_shock_vent" } }, - "monster": { "(": { "monster": "mon_turret_rifle" }, "!": { "monster": "mon_hazmatbot", "chance": 5 } }, + "monster": { "!": { "monster": "mon_hazmatbot", "chance": 5 } }, "monsters": { "h": { "monster": "GROUP_ZOMBIE", "chance": 50 }, "o": { "monster": "GROUP_ZOMBIE", "chance": 50 }, From 43af3901e812bdb37e7b81e71b39c310544d0316 Mon Sep 17 00:00:00 2001 From: chrispikula Date: Thu, 8 Jul 2021 23:39:04 -0600 Subject: [PATCH 084/116] Populated Bone Skewers into recipes, made Skewers millable (#47986) * Populated Bone Skewers into recipes, made Skewers millable Utilized skewer_bone as a 25:1 replacement for bone_tainted or bone_any, in recipies where chemical, rather than physical properties were required, with 200% tainted penalty. Make skewers 25:4 millable tainted bone meal, to match up with normal bones. Added bone skewers to charcoal recipe utilizing kiln. 25:1 to bone. Also, with fertilizer_liquid, added meal_bone_tainted, with 200% penalty. --- data/json/items/comestibles/carnivore.json | 1 + data/json/items/generic.json | 1 + data/json/recipes/chem/other.json | 3 ++- data/json/recipes/recipe_food.json | 6 +++--- data/json/recipes/recipe_medsandchemicals.json | 4 ++-- data/json/recipes/recipe_others.json | 10 +++++++++- 6 files changed, 18 insertions(+), 7 deletions(-) diff --git a/data/json/items/comestibles/carnivore.json b/data/json/items/comestibles/carnivore.json index 2338ef2278536..e9f91a540b875 100644 --- a/data/json/items/comestibles/carnivore.json +++ b/data/json/items/comestibles/carnivore.json @@ -903,6 +903,7 @@ "description": "A rotten and brittle bone from some unnatural creature or other. Could be used to make some stuff, like charcoal or glue. You could eat it, but it will poison you.", "price": 0, "price_postapoc": 5, + "milling": { "into": "meal_bone_tainted", "conversion_rate": 4 }, "//": "Not for use in edible recipes, and should require ~200% as much as normal for applicable inedible recipes except for charcoal.", "material": [ "bone" ], "volume": "250 ml", diff --git a/data/json/items/generic.json b/data/json/items/generic.json index ee1bc83dd173c..cd71b557f1f53 100644 --- a/data/json/items/generic.json +++ b/data/json/items/generic.json @@ -810,6 +810,7 @@ "weight": "10 g", "volume": "25 ml", "to_hit": -5, + "milling": { "into": "meal_bone_tainted", "conversion_rate": 0.16 }, "qualities": [ [ "COOK", 1 ] ] }, { diff --git a/data/json/recipes/chem/other.json b/data/json/recipes/chem/other.json index 2a4b09be3ff22..a8f8403ba7356 100644 --- a/data/json/recipes/chem/other.json +++ b/data/json/recipes/chem/other.json @@ -14,7 +14,7 @@ "book_learn": [ [ "recipe_arrows", 1 ], [ "textbook_survival", 1 ], [ "survival_book", 1 ] ], "qualities": [ { "id": "COOK", "level": 2 } ], "tools": [ [ [ "surface_heat", 3, "LIST" ] ] ], - "components": [ [ [ "water", 1 ], [ "water_clean", 1 ] ], [ [ "bone_any", 10, "LIST" ] ] ] + "components": [ [ [ "water", 1 ], [ "water_clean", 1 ] ], [ [ "bone_any", 10, "LIST" ], [ "skewer_bone", 500 ] ] ] }, { "result": "superglue", @@ -34,6 +34,7 @@ [ "bleach", 1 ], [ "lye_powder", 100 ], [ "bone_any", 20, "LIST" ], + [ "skewer_bone", 1000 ], [ "cured_hide", 2 ], [ "pine_bough", 10 ], [ "raw_dandelion", 20 ], diff --git a/data/json/recipes/recipe_food.json b/data/json/recipes/recipe_food.json index 6d1bc903c3f52..9d3cfcdc256ba 100644 --- a/data/json/recipes/recipe_food.json +++ b/data/json/recipes/recipe_food.json @@ -4780,7 +4780,7 @@ "batch_time_factors": [ 83, 3 ], "flags": [ "BLIND_EASY" ], "tools": [ [ [ "rock_quern", -1 ], [ "clay_quern", -1 ] ] ], - "components": [ [ [ "bone_tainted", 1 ] ] ] + "components": [ [ [ "bone_tainted", 1 ], [ "skewer_bone", 25 ] ] ] }, { "type": "recipe", @@ -6680,7 +6680,7 @@ "autolearn": true, "batch_time_factors": [ 83, 3 ], "tools": [ [ [ "food_processor", 20 ] ] ], - "components": [ [ [ "bone_tainted", 1 ] ] ] + "components": [ [ [ "bone_tainted", 1 ], [ "skewer_bone", 25 ] ] ] }, { "result": "cattlefodder", @@ -6993,7 +6993,7 @@ "batch_time_factors": [ 83, 3 ], "flags": [ "BLIND_EASY" ], "tools": [ [ [ "mortar_pestle", -1 ] ] ], - "components": [ [ [ "bone_tainted", 1 ] ] ] + "components": [ [ [ "bone_tainted", 1 ], [ "skewer_bone", 25 ] ] ] }, { "type": "recipe", diff --git a/data/json/recipes/recipe_medsandchemicals.json b/data/json/recipes/recipe_medsandchemicals.json index a8b59c7310f77..81b82c994a9ee 100644 --- a/data/json/recipes/recipe_medsandchemicals.json +++ b/data/json/recipes/recipe_medsandchemicals.json @@ -634,7 +634,7 @@ "tools": [ [ [ "surface_heat", 10, "LIST" ] ] ], "components": [ [ [ "water", 4 ], [ "water_clean", 4 ] ], - [ [ "meal_bone", 2 ] ], + [ [ "meal_bone", 2 ], [ "meal_bone_tainted", 4 ] ], [ [ "meal_chitin_piece", 1 ] ], [ [ "feces_bird", 10 ], [ "feces_cow", 4 ], [ "feces_manure", 6 ] ] ] @@ -668,7 +668,7 @@ "tools": [ [ [ "surface_heat", 5, "LIST" ] ] ], "components": [ [ [ "water", 4 ], [ "water_clean", 4 ] ], - [ [ "meal_bone", 2 ] ], + [ [ "meal_bone", 2 ], [ "meal_bone_tainted", 4 ] ], [ [ "meal_chitin_piece", 1 ] ], [ [ "ammonia", 1 ], [ "lye_powder", 100 ], [ "chem_saltpetre", 50 ] ] ] diff --git a/data/json/recipes/recipe_others.json b/data/json/recipes/recipe_others.json index 7686291b5158f..7b2d5c3aae944 100644 --- a/data/json/recipes/recipe_others.json +++ b/data/json/recipes/recipe_others.json @@ -1238,7 +1238,15 @@ "time": "1 m", "autolearn": true, "components": [ - [ [ "splinter", 40 ], [ "2x4", 6 ], [ "stick", 8 ], [ "bone_any", 40, "LIST" ], [ "pine_bough", 20 ], [ "log", 1 ] ], + [ + [ "splinter", 40 ], + [ "2x4", 6 ], + [ "stick", 8 ], + [ "bone_any", 40, "LIST" ], + [ "skewer_bone", 1000 ], + [ "pine_bough", 20 ], + [ "log", 1 ] + ], [ [ "char_kiln", 1 ] ] ] }, From 8993df11c82f0162d22b59665df967a40a5f5222 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Thu, 8 Jul 2021 23:04:58 -0700 Subject: [PATCH 085/116] Obsolete ANBC and AEP suits (#49733) These items, and their recipes are pretty nonsense. We should have NBC gear, but the ANBC gear is nothing close to representing that. --- .../itemgroups/Clothing_Gear/clothing.json | 6 +- data/json/items/armor/coats.json | 2 +- data/json/items/armor/suits_protection.json | 86 +------------------ data/json/items/obsolete.json | 80 +++++++++++++++++ .../mapgen/military/mil_base/mil_base_z0.json | 2 +- data/json/recipes/armor/suit.json | 50 ----------- .../recipe_modular_outpost_cross.json | 2 +- .../recipe_modular_outpost_normal.json | 2 +- data/json/recipes/recipe_obsolete.json | 10 +++ data/mods/Fuji_Mil_Prof/prof/spc.json | 2 +- data/mods/TEST_DATA/items.json | 2 +- src/map_extras.cpp | 4 +- tests/item_test.cpp | 2 +- 13 files changed, 104 insertions(+), 146 deletions(-) diff --git a/data/json/itemgroups/Clothing_Gear/clothing.json b/data/json/itemgroups/Clothing_Gear/clothing.json index f15a55da93cb9..467f3896bc397 100644 --- a/data/json/itemgroups/Clothing_Gear/clothing.json +++ b/data/json/itemgroups/Clothing_Gear/clothing.json @@ -539,8 +539,7 @@ "//": "Various types of hazmat suits, without masks", "items": [ { "collection": [ { "item": "cleansuit" }, { "item": "gloves_rubber" }, { "item": "boots_rubber" } ], "prob": 40 }, - [ "hazmat_suit", 55 ], - [ "anbc_suit", 5 ] + [ "hazmat_suit", 60 ] ] }, { @@ -2237,7 +2236,7 @@ { "type": "item_group", "id": "hazmat_full", - "items": [ [ "hazmat_suit", 80 ], [ "anbc_suit", 20 ] ] + "items": [ [ "hazmat_suit", 100 ] ] }, { "type": "item_group", @@ -2270,7 +2269,6 @@ [ "armor_plarmor", 2 ], [ "armor_riot", 10 ], [ "swat_armor", 6 ], - [ "aep_suit", 4 ], [ "armor_scrapsuit", 12 ], [ "armor_chitin", 2 ], [ "armor_lightplate", 1 ], diff --git a/data/json/items/armor/coats.json b/data/json/items/armor/coats.json index 6e2f18489afdf..5684cb22222a1 100644 --- a/data/json/items/armor/coats.json +++ b/data/json/items/armor/coats.json @@ -1,7 +1,7 @@ [ { "id": "bunker_coat", - "repairs_like": "aep_suit", + "repairs_like": "fsurvivor_suit", "type": "ARMOR", "category": "armor", "name": { "str": "turnout coat" }, diff --git a/data/json/items/armor/suits_protection.json b/data/json/items/armor/suits_protection.json index 0ea12e2b90030..82ace8bd9b634 100644 --- a/data/json/items/armor/suits_protection.json +++ b/data/json/items/armor/suits_protection.json @@ -1,84 +1,4 @@ [ - { - "id": "aep_suit", - "type": "ARMOR", - "category": "armor", - "name": { "str": "AEP suit" }, - "description": "An armored environmental protection suit. Custom-built from a cleansuit and body armor, it provides excellent protection against both physical harm and ambient radiation.", - "weight": "7200 g", - "volume": "9 L", - "price": 140000, - "price_postapoc": 6000, - "material": [ "kevlar_layered", "plastic" ], - "symbol": "[", - "looks_like": "hazmat_suit", - "color": "light_red", - "armor": [ - { "covers": [ "torso" ], "coverage": 100, "encumbrance": [ 10, 15 ] }, - { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": [ 10, 15 ] }, - { "covers": [ "arm_l", "arm_r" ], "coverage": 100, "encumbrance": [ 10, 10 ] } - ], - "pocket_data": [ - { - "pocket_type": "CONTAINER", - "max_contains_volume": "1 L", - "max_contains_weight": "3 kg", - "max_item_length": "18 cm", - "moves": 80 - }, - { - "pocket_type": "CONTAINER", - "max_contains_volume": "1 L", - "max_contains_weight": "3 kg", - "max_item_length": "18 cm", - "moves": 80 - }, - { - "pocket_type": "CONTAINER", - "max_contains_volume": "1 L", - "max_contains_weight": "3 kg", - "max_item_length": "18 cm", - "moves": 80 - }, - { - "pocket_type": "CONTAINER", - "max_contains_volume": "1 L", - "max_contains_weight": "3 kg", - "max_item_length": "18 cm", - "moves": 80 - } - ], - "warmth": 35, - "material_thickness": 7, - "environmental_protection": 9, - "flags": [ "VARSIZE", "WATERPROOF", "HOOD", "RAINPROOF", "STURDY", "RAD_RESIST", "OUTER" ] - }, - { - "id": "anbc_suit", - "type": "ARMOR", - "category": "armor", - "name": { "str": "ANBC suit" }, - "description": "An armored, impermeable full-body suit that functions as body armor, as well as protecting from nuclear, biological, and chemical hazards. It requires a separate gas mask for full protection.", - "weight": "8700 g", - "volume": "20 L", - "price": 400000, - "price_postapoc": 9000, - "material": [ "kevlar_layered", "plastic" ], - "symbol": "[", - "looks_like": "hazmat_suit", - "color": "light_red", - "warmth": 50, - "material_thickness": 7, - "environmental_protection": 20, - "flags": [ "VARSIZE", "WATERPROOF", "RAINPROOF", "GAS_PROOF", "STURDY", "RAD_PROOF", "ELECTRIC_IMMUNE", "OUTER" ], - "armor": [ - { - "encumbrance": 35, - "coverage": 100, - "covers": [ "head", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] - } - ] - }, { "id": "armor_blarmor", "type": "ARMOR", @@ -681,7 +601,7 @@ }, { "id": "cleansuit", - "repairs_like": "aep_suit", + "repairs_like": "fsurvivor_suit", "type": "ARMOR", "name": { "str": "cleansuit" }, "description": "A simple hazardous materials handling suit. Though somewhat restrictive and fragile, wearing it will provide excellent protection against ambient radiation.", @@ -835,7 +755,7 @@ }, { "id": "hazmat_suit", - "repairs_like": "aep_suit", + "repairs_like": "fsurvivor_suit", "type": "ARMOR", "name": { "str": "hazmat suit" }, "description": "An impermeable whole-body garment worn as protection against hazardous materials. Though very restrictive and fragile, wearing it will provide complete protection against ambient radiation. It requires a separate gas mask for full protection.", @@ -959,7 +879,7 @@ }, { "id": "robofac_enviro_suit", - "repairs_like": "aep_suit", + "repairs_like": "fsurvivor_suit", "type": "ARMOR", "name": { "str": "Hub 01 environmental suit" }, "description": "A lightweight environmental suit worn by Hub personnel in their rare forays aboveground. Colored brown and blue, the white seal of Hub 01 is embroidered on both of its upper arms. It requires a separate gas mask for full protection.", diff --git a/data/json/items/obsolete.json b/data/json/items/obsolete.json index 21f11659f77c0..f01fc571db757 100644 --- a/data/json/items/obsolete.json +++ b/data/json/items/obsolete.json @@ -522,6 +522,86 @@ "ammo_effects": [ "LASER", "INCENDIARY" ], "flags": [ "NO_UNLOAD" ] }, + { + "id": "aep_suit", + "type": "ARMOR", + "category": "armor", + "name": { "str": "AEP suit" }, + "description": "An armored environmental protection suit. Custom-built from a cleansuit and body armor, it provides excellent protection against both physical harm and ambient radiation.", + "weight": "7200 g", + "volume": "9 L", + "price": 140000, + "price_postapoc": 6000, + "material": [ "kevlar_layered", "plastic" ], + "symbol": "[", + "looks_like": "hazmat_suit", + "color": "light_red", + "armor": [ + { "covers": [ "torso" ], "coverage": 100, "encumbrance": [ 10, 15 ] }, + { "covers": [ "leg_l", "leg_r" ], "coverage": 100, "encumbrance": [ 10, 15 ] }, + { "covers": [ "arm_l", "arm_r" ], "coverage": 100, "encumbrance": [ 10, 10 ] } + ], + "pocket_data": [ + { + "pocket_type": "CONTAINER", + "max_contains_volume": "1 L", + "max_contains_weight": "3 kg", + "max_item_length": "18 cm", + "moves": 80 + }, + { + "pocket_type": "CONTAINER", + "max_contains_volume": "1 L", + "max_contains_weight": "3 kg", + "max_item_length": "18 cm", + "moves": 80 + }, + { + "pocket_type": "CONTAINER", + "max_contains_volume": "1 L", + "max_contains_weight": "3 kg", + "max_item_length": "18 cm", + "moves": 80 + }, + { + "pocket_type": "CONTAINER", + "max_contains_volume": "1 L", + "max_contains_weight": "3 kg", + "max_item_length": "18 cm", + "moves": 80 + } + ], + "warmth": 35, + "material_thickness": 7, + "environmental_protection": 9, + "flags": [ "VARSIZE", "WATERPROOF", "HOOD", "RAINPROOF", "STURDY", "RAD_RESIST", "OUTER" ] + }, + { + "id": "anbc_suit", + "type": "ARMOR", + "category": "armor", + "name": { "str": "ANBC suit" }, + "description": "An armored, impermeable full-body suit that functions as body armor, as well as protecting from nuclear, biological, and chemical hazards. It requires a separate gas mask for full protection.", + "weight": "8700 g", + "volume": "20 L", + "price": 400000, + "price_postapoc": 9000, + "material": [ "kevlar_layered", "plastic" ], + "symbol": "[", + "looks_like": "hazmat_suit", + "color": "light_red", + "warmth": 50, + "material_thickness": 7, + "environmental_protection": 20, + "flags": [ "VARSIZE", "WATERPROOF", "RAINPROOF", "GAS_PROOF", "STURDY", "RAD_PROOF", "ELECTRIC_IMMUNE", "OUTER" ], + "armor": [ + { + "encumbrance": 35, + "coverage": 100, + "covers": [ "head", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r" ] + } + ] + }, { "id": "armguard_bone", "type": "ARMOR", diff --git a/data/json/mapgen/military/mil_base/mil_base_z0.json b/data/json/mapgen/military/mil_base/mil_base_z0.json index 782f5b5ee8ef9..1b0031302de86 100644 --- a/data/json/mapgen/military/mil_base/mil_base_z0.json +++ b/data/json/mapgen/military/mil_base/mil_base_z0.json @@ -1182,7 +1182,7 @@ { "item": "geiger_off", "x": 32, "y": 25, "chance": 50, "repeat": [ 10, 20 ] }, { "item": "rad_monitor", "x": 32, "y": 25, "chance": 50, "repeat": [ 10, 20 ] }, { "item": "cleansuit", "x": 32, "y": 25, "chance": 50, "repeat": [ 10, 20 ] }, - { "item": "aep_suit", "x": 32, "y": 25, "chance": 50, "repeat": [ 5, 10 ] }, + { "item": "hazmat_suit", "x": 32, "y": 25, "chance": 50, "repeat": [ 5, 10 ] }, { "item": "oxygen_tank", "x": 32, "y": 25, "chance": 50, "repeat": [ 10, 20 ] }, { "item": "wrapped_rad_badge", "x": 32, "y": 25, "chance": 50, "repeat": [ 20, 60 ] }, { "item": "prussian_blue", "x": 32, "y": 25, "chance": 50, "repeat": [ 20, 60 ] }, diff --git a/data/json/recipes/armor/suit.json b/data/json/recipes/armor/suit.json index 9f13daebc1c39..13418543dfa37 100644 --- a/data/json/recipes/armor/suit.json +++ b/data/json/recipes/armor/suit.json @@ -1,54 +1,4 @@ [ - { - "result": "aep_suit", - "type": "recipe", - "activity_level": "LIGHT_EXERCISE", - "category": "CC_ARMOR", - "subcategory": "CSC_ARMOR_SUIT", - "skill_used": "fabrication", - "difficulty": 6, - "skills_required": [ "tailor", 5 ], - "time": "12 h", - "book_learn": [ [ "tailor_portfolio", 7 ], [ "textbook_tailor", 8 ], [ "textbook_fireman", 6 ] ], - "qualities": [ { "id": "CUT", "level": 1 } ], - "tools": [ [ [ "welder", 112 ], [ "welder_crude", 168 ], [ "soldering_iron", 168 ], [ "toolset", 168 ] ] ], - "proficiencies": [ - { "proficiency": "prof_closures" }, - { "proficiency": "prof_polymerworking" }, - { "proficiency": "prof_closures_waterproofing" } - ], - "components": [ - [ [ "cleansuit", 1 ] ], - [ [ "duct_tape", 600 ] ], - [ [ "kevlar", 1 ], [ "ballistic_vest_empty", 1 ], [ "swat_armor", 1 ], [ "sheet_kevlar_layered", 24 ] ], - [ [ "plastic_sheet", 1 ] ] - ] - }, - { - "result": "anbc_suit", - "type": "recipe", - "activity_level": "LIGHT_EXERCISE", - "category": "CC_ARMOR", - "subcategory": "CSC_ARMOR_SUIT", - "skill_used": "fabrication", - "difficulty": 8, - "skills_required": [ "tailor", 7 ], - "time": "12 h 40 m", - "book_learn": [ [ "tailor_portfolio", 7 ], [ "textbook_fireman", 7 ] ], - "qualities": [ { "id": "CUT", "level": 1 } ], - "tools": [ [ [ "welder", 112 ], [ "welder_crude", 168 ], [ "soldering_iron", 168 ], [ "toolset", 168 ] ] ], - "proficiencies": [ - { "proficiency": "prof_closures" }, - { "proficiency": "prof_polymerworking" }, - { "proficiency": "prof_closures_waterproofing" } - ], - "components": [ - [ [ "hazmat_suit", 1 ] ], - [ [ "duct_tape", 800 ] ], - [ [ "swat_armor", 1 ], [ "sheet_kevlar_layered", 48 ] ], - [ [ "plastic_sheet", 1 ] ] - ] - }, { "result": "armor_blarmor", "type": "recipe", diff --git a/data/json/recipes/basecamps/fbmc_outpost/recipe_modular_outpost_cross.json b/data/json/recipes/basecamps/fbmc_outpost/recipe_modular_outpost_cross.json index 3d06cc9462373..b8500a41d8c6f 100644 --- a/data/json/recipes/basecamps/fbmc_outpost/recipe_modular_outpost_cross.json +++ b/data/json/recipes/basecamps/fbmc_outpost/recipe_modular_outpost_cross.json @@ -130,7 +130,7 @@ "time": "1 d", "skills": [ [ "electronics", 8 ] ], "inline": { - "tools": [ [ [ "hazmat_suit", -1 ], [ "anbc_suit", -1 ] ], [ [ "mask_gas", 50 ] ], [ [ "soldering_iron", 50 ] ] ], + "tools": [ [ [ "hazmat_suit", -1 ] ], [ [ "mask_gas", 50 ] ], [ [ "soldering_iron", 50 ] ] ], "qualities": [ [ { "id": "SCREW" } ], [ { "id": "SCREW_FINE" } ], [ { "id": "WRENCH" } ], [ { "id": "WRENCH_FINE" } ] ], "components": [ [ [ "solder_wire", 50 ] ], diff --git a/data/json/recipes/basecamps/fbmc_outpost/recipe_modular_outpost_normal.json b/data/json/recipes/basecamps/fbmc_outpost/recipe_modular_outpost_normal.json index f978e62a938b1..8227ad233c4c1 100644 --- a/data/json/recipes/basecamps/fbmc_outpost/recipe_modular_outpost_normal.json +++ b/data/json/recipes/basecamps/fbmc_outpost/recipe_modular_outpost_normal.json @@ -116,7 +116,7 @@ "time": "1 d", "skills": [ [ "electronics", 8 ] ], "inline": { - "tools": [ [ [ "hazmat_suit", -1 ], [ "anbc_suit", -1 ] ], [ [ "mask_gas", 50 ] ], [ [ "soldering_iron", 50 ] ] ], + "tools": [ [ [ "hazmat_suit", -1 ] ], [ [ "mask_gas", 50 ] ], [ [ "soldering_iron", 50 ] ] ], "qualities": [ [ { "id": "SCREW" } ], [ { "id": "SCREW_FINE" } ], [ { "id": "WRENCH" } ], [ { "id": "WRENCH_FINE" } ] ], "components": [ [ [ "solder_wire", 50 ] ], diff --git a/data/json/recipes/recipe_obsolete.json b/data/json/recipes/recipe_obsolete.json index 9c56edb33c045..9ecf3c481fae2 100644 --- a/data/json/recipes/recipe_obsolete.json +++ b/data/json/recipes/recipe_obsolete.json @@ -70,6 +70,16 @@ "result": "survivor_belt", "obsolete": true }, + { + "result": "aep_suit", + "type": "recipe", + "obsolete": true + }, + { + "result": "anbc_suit", + "type": "recipe", + "obsolete": true + }, { "type": "recipe", "result": "survival_kit", diff --git a/data/mods/Fuji_Mil_Prof/prof/spc.json b/data/mods/Fuji_Mil_Prof/prof/spc.json index aa296a046d4da..5f41ff5897554 100644 --- a/data/mods/Fuji_Mil_Prof/prof/spc.json +++ b/data/mods/Fuji_Mil_Prof/prof/spc.json @@ -183,7 +183,7 @@ "items": { "both": { "items": [ - "anbc_suit", + "hazmat_suit", "pants_cargo", "longshirt", "dump_pouch", diff --git a/data/mods/TEST_DATA/items.json b/data/mods/TEST_DATA/items.json index 08620df87f192..f16ef6c0011d1 100644 --- a/data/mods/TEST_DATA/items.json +++ b/data/mods/TEST_DATA/items.json @@ -541,7 +541,7 @@ }, { "id": "test_hazmat_suit", - "repairs_like": "aep_suit", + "repairs_like": "fsurvivor_suit", "type": "ARMOR", "name": "TEST hazmat suit", "description": "An impermeable whole-body garment worn as protection against hazardous materials. Though very restrictive and fragile, wearing it will provide complete protection against ambient radiation. It requires a separate gas mask for full protection.", diff --git a/src/map_extras.cpp b/src/map_extras.cpp index ec74562b4fea2..baa301f371463 100644 --- a/src/map_extras.cpp +++ b/src/map_extras.cpp @@ -78,7 +78,7 @@ static const itype_id itype_223_casing( "223_casing" ); static const itype_id itype_762_51_casing( "762_51_casing" ); static const itype_id itype_9mm_casing( "9mm_casing" ); static const itype_id itype_acoustic_guitar( "acoustic_guitar" ); -static const itype_id itype_anbc_suit( "anbc_suit" ); +static const itype_id itype_hazmat_suit( "hazmat_suit" ); static const itype_id itype_ash( "ash" ); static const itype_id itype_bag_canvas( "bag_canvas" ); static const itype_id itype_bottle_glass( "bottle_glass" ); @@ -2867,7 +2867,7 @@ static bool mx_grave( map &m, const tripoint &abs_sub ) case 2: { m.ter_set( point( SEEX, SEEY ), t_grave_new ); m.spawn_item( point( SEEX, SEEY ), itype_glasses_eye ); - m.spawn_item( point( SEEX, SEEY ), itype_anbc_suit ); + m.spawn_item( point( SEEX, SEEY ), itype_hazmat_suit ); m.spawn_item( point( SEEX, SEEY ), itype_crowbar ); m.furn_set( point( SEEX, SEEY - 1 ), f_sign ); m.set_signage( tripoint( SEEX, SEEY - 1, abs_sub.z ), diff --git a/tests/item_test.cpp b/tests/item_test.cpp index 0c7614ebf5308..8aa058395c9aa 100644 --- a/tests/item_test.cpp +++ b/tests/item_test.cpp @@ -45,7 +45,7 @@ TEST_CASE( "simple_item_layers", "[item]" ) CHECK( item( "arm_warmers" ).get_layer() == layer_level::UNDERWEAR ); CHECK( item( "10gal_hat" ).get_layer() == layer_level::REGULAR ); CHECK( item( "baldric" ).get_layer() == layer_level::WAIST ); - CHECK( item( "aep_suit" ).get_layer() == layer_level::OUTER ); + CHECK( item( "armor_lightplate" ).get_layer() == layer_level::OUTER ); CHECK( item( "2byarm_guard" ).get_layer() == layer_level::BELTED ); } From 621a68c23a17a9c5f86c81ad2f3b2751bfc09ab7 Mon Sep 17 00:00:00 2001 From: connorpmartin <55263157+connorpmartin@users.noreply.github.com> Date: Fri, 9 Jul 2021 02:12:32 -0400 Subject: [PATCH 086/116] Make fungal infections less obvious to player (#49101) * Update effects.json * Itchy skin from Sarius's suggestion * Update effects.json * Update effects.json --- data/json/effects.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/json/effects.json b/data/json/effects.json index 056814e222c66..621073d32e779 100644 --- a/data/json/effects.json +++ b/data/json/effects.json @@ -1066,8 +1066,8 @@ "apply_memorial_log": "Contracted a fungal infection.", "remove_memorial_log": "Cured the fungal infection.", "miss_messages": [ [ "You feel sick inside.", 1 ] ], - "speed_name": "Fungal infection", - "remove_message": "Tingling sensation in your skin fades away.", + "speed_name": "Itchy skin", + "remove_message": "The itching in your skin fades away.", "rating": "bad", "max_intensity": 3, "int_dur_factor": "6 h", From afad6359f01d65cb3dd8229ee0805fd738d85eee Mon Sep 17 00:00:00 2001 From: casswedson <58050969+casswedson@users.noreply.github.com> Date: Fri, 9 Jul 2021 01:20:34 -0500 Subject: [PATCH 087/116] Replace MREs with itemgroups (#48827) * Replace mres with itemgroups * fix all the things Not the solution I wanted, but it works Also aluminum foil * Apply suggestions from code review Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> * move mres their own SUS file no remaning/comments SUS itemgroups have Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> --- data/json/itemgroups/Food/food.json | 32 -- data/json/itemgroups/SUS/mre_packages.json | 168 +++++++ data/json/itemgroups/defense_mode.json | 2 +- data/json/itemgroups/military.json | 2 +- data/json/itemgroups/misc.json | 4 +- data/json/itemgroups/roof.json | 6 +- data/json/items/comestibles/mre.json | 244 ---------- data/json/items/containers.json | 84 ++++ data/json/items/obsolete.json | 244 ++++++++++ data/json/mapgen/helipad.json | 2 +- data/json/npcs/NC_SOLDIER.json | 24 +- data/json/npcs/items_generic.json | 24 +- .../NPC_scavenger_mercenary.json | 3 +- .../recipe_deconstruction_package.json | 460 ------------------ data/json/recipes/recipe_obsolete.json | 145 ++++++ data/json/vehicles/helicopters.json | 90 ++-- .../CRT_EXPANSION/scenarios/crt_classes.json | 22 +- 17 files changed, 704 insertions(+), 852 deletions(-) create mode 100644 data/json/itemgroups/SUS/mre_packages.json delete mode 100644 data/json/recipes/recipe_deconstruction_package.json diff --git a/data/json/itemgroups/Food/food.json b/data/json/itemgroups/Food/food.json index 593a5c50e8bef..4b865be0d9d4a 100644 --- a/data/json/itemgroups/Food/food.json +++ b/data/json/itemgroups/Food/food.json @@ -588,38 +588,6 @@ { "item": "pie_maple", "prob": 10 } ] }, - { - "type": "item_group", - "id": "MRE", - "subtype": "distribution", - "entries": [ - { "item": "mre_chilibeans_box" }, - { "item": "mre_bbqbeef_box" }, - { "item": "mre_chickennoodle_box" }, - { "item": "mre_spaghetti_box" }, - { "item": "mre_chicken_box" }, - { "item": "mre_beeftaco_box" }, - { "item": "mre_beef_box" }, - { "item": "mre_meatball_box" }, - { "item": "mre_beefstew_box" }, - { "item": "mre_chilimac_box" }, - { "item": "mre_veggy_box" }, - { "item": "mre_macaronimarinara_box" }, - { "item": "mre_sfettuccine_box" }, - { "item": "mre_ratatouille_box" }, - { "item": "mre_cheesetort_box" }, - { "item": "mre_mushroomfettuccine_box" }, - { "item": "mre_mexicanchickenstew_box" }, - { "item": "mre_maplesausage_box" }, - { "item": "mre_ravioli_box" }, - { "item": "mre_hashbrownbacon_box" }, - { "item": "mre_lemontuna_box" }, - { "item": "mre_asianbeef_box" }, - { "item": "mre_chickenpesto_box" }, - { "item": "mre_southwestbeef_box" }, - { "item": "mre_hotdog_box" } - ] - }, { "type": "item_group", "id": "alcohol", diff --git a/data/json/itemgroups/SUS/mre_packages.json b/data/json/itemgroups/SUS/mre_packages.json new file mode 100644 index 0000000000000..f745089d5a423 --- /dev/null +++ b/data/json/itemgroups/SUS/mre_packages.json @@ -0,0 +1,168 @@ +[ + { + "type": "item_group", + "id": "MRE", + "items": [ { "group": "mre_full_pack" } ] + }, + { + "type": "item_group", + "id": "any_MRE", + "subtype": "distribution", + "entries": [ { "group": "mre_full_pack" }, { "group": "mre_used_pack" } ] + }, + { + "type": "item_group", + "id": "mre_entrees", + "subtype": "distribution", + "entries": [ + { "item": "mre_asianbeef" }, + { "item": "mre_bbqbeef" }, + { "item": "mre_beef" }, + { "item": "mre_beefstew" }, + { "item": "mre_beeftaco" }, + { "item": "mre_cheesetort" }, + { "item": "mre_chicken" }, + { "item": "mre_chickenburritobowl" }, + { "item": "mre_chickennoodle" }, + { "item": "mre_chickenpesto" }, + { "item": "mre_chilibeans" }, + { "item": "mre_chilimac" }, + { "item": "mre_hashbrownbacon" }, + { "item": "mre_hotdog" }, + { "item": "mre_lemontuna" }, + { "item": "mre_macaronimarinara" }, + { "item": "mre_maplesausage" }, + { "item": "mre_meatball" }, + { "item": "mre_mexicanchickenstew" }, + { "item": "mre_mushroomfettuccine" }, + { "item": "mre_pepperjackbeef" }, + { "item": "mre_ratatouille" }, + { "item": "mre_ravioli" }, + { "item": "mre_sfettuccine" }, + { "item": "mre_southwestbeef" }, + { "item": "mre_spaghetti" }, + { "item": "mre_veggy" } + ] + }, + { + "type": "item_group", + "id": "mre_dessert_pack", + "subtype": "collection", + "entries": [ + { "item": "candy2", "container-item": "wrapper" }, + { "item": "chocolate" }, + { "item": "cookies", "container-item": "wrapper" }, + { "item": "dry_fruit", "container-item": "wrapper" } + ] + }, + { + "type": "item_group", + "id": "mre_accessory_pack", + "container-item": "bag_plastic", + "subtype": "collection", + "entries": [ + { "item": "gummy_vitamins", "charges": 1 }, + { "item": "matches", "charges": 20 }, + { "item": "paper", "charges": 8 }, + { "item": "gum", "charges": 2 }, + { "item": "pur_tablets", "charges": 6, "container-item": "beverage_bag" }, + { "item": "spork" }, + { + "distribution": [ + { "item": "instant_coffee", "count": 2, "container-item": "beverage_bag" }, + { "item": "herbal_tea_bag", "count": 2, "container-item": "beverage_bag" }, + { "item": "tea_bag", "count": 2, "container-item": "beverage_bag" }, + { "item": "tea_bag_chamomile", "count": 2, "container-item": "beverage_bag" }, + { "item": "tea_bag_dandelion", "count": 2, "container-item": "beverage_bag" }, + { "item": "tea_fruit_bag", "count": 2, "container-item": "beverage_bag" }, + { "item": "tea_green_bag", "count": 2, "container-item": "beverage_bag" } + ] + } + ] + }, + { + "type": "item_group", + "id": "mre_contents", + "//": "What an MRE in pristine condition should contain.", + "subtype": "collection", + "entries": [ + { "group": "mre_entrees", "container-item": "mre_bag_small" }, + { "item": "heatpack" }, + { + "distribution": [ + { "item": "can_cheese", "container-item": "mre_bag_small", "sealed": true }, + { "item": "spread_peanutbutter", "container-item": "mre_bag_small", "sealed": true } + ] + }, + { "item": "crackers", "charges": 2, "container-item": "mre_bag_small", "sealed": true }, + { "group": "mre_accessory_pack" }, + { "item": "mre_bag", "contents-group": "mre_dessert_pack", "sealed": true } + ] + }, + { + "type": "item_group", + "id": "mre_full_pack", + "subtype": "collection", + "entries": [ { "item": "mre_package", "contents-group": "mre_contents", "sealed": true } ] + }, + { + "type": "item_group", + "id": "mre_used_dessert_pack", + "subtype": "collection", + "entries": [ + { "item": "candy2", "charges": [ 0, 3 ], "container-item": "wrapper" }, + { "item": "chocolate", "charges": [ 0, 3 ] }, + { "item": "cookies", "charges": [ 0, 4 ], "container-item": "wrapper" }, + { "item": "dry_fruit", "container-item": "wrapper" } + ] + }, + { + "type": "item_group", + "id": "mre_used_accessory_pack", + "container-item": "bag_plastic", + "subtype": "collection", + "entries": [ + { "item": "gummy_vitamins", "charges": 1 }, + { "item": "matches", "charges": [ 0, 20 ] }, + { "item": "paper", "charges": [ 0, 8 ] }, + { "item": "gum", "charges": [ 0, 2 ] }, + { "item": "pur_tablets", "charges": [ 0, 6 ], "container-item": "beverage_bag" }, + { "item": "spork" }, + { + "distribution": [ + { "item": "instant_coffee", "count": [ 0, 2 ], "container-item": "beverage_bag" }, + { "item": "herbal_tea_bag", "count": [ 0, 2 ], "container-item": "beverage_bag" }, + { "item": "tea_bag", "count": [ 0, 2 ], "container-item": "beverage_bag" }, + { "item": "tea_bag_chamomile", "count": [ 0, 2 ], "container-item": "beverage_bag" }, + { "item": "tea_bag_dandelion", "count": [ 0, 2 ], "container-item": "beverage_bag" }, + { "item": "tea_fruit_bag", "count": [ 0, 2 ], "container-item": "beverage_bag" }, + { "item": "tea_green_bag", "count": [ 0, 2 ], "container-item": "beverage_bag" } + ] + } + ] + }, + { + "type": "item_group", + "id": "mre_used_contents", + "subtype": "collection", + "entries": [ + { "group": "mre_entrees", "container-item": "mre_bag_small", "sealed": false, "prob": 40 }, + { "item": "heatpack", "prob": 40 }, + { + "distribution": [ + { "item": "can_cheese", "container-item": "mre_bag_small", "prob": 40, "sealed": true }, + { "item": "spread_peanutbutter", "container-item": "mre_bag_small", "prob": 40, "sealed": true } + ] + }, + { "item": "crackers", "charges": [ 0, 2 ], "container-item": "mre_bag_small", "sealed": false }, + { "group": "mre_accessory_pack", "prob": 50 }, + { "item": "mre_bag", "contents-group": "mre_used_dessert_pack", "sealed": false } + ] + }, + { + "type": "item_group", + "id": "mre_used_pack", + "subtype": "collection", + "entries": [ { "item": "mre_package", "contents-group": "mre_used_contents", "sealed": false } ] + } +] diff --git a/data/json/itemgroups/defense_mode.json b/data/json/itemgroups/defense_mode.json index 08ebc50f2080d..2f63487032723 100644 --- a/data/json/itemgroups/defense_mode.json +++ b/data/json/itemgroups/defense_mode.json @@ -99,7 +99,7 @@ { "item": "energy_drink" }, { "item": "whiskey" }, { "item": "can_beans" }, - { "item": "mre_beef" }, + { "group": "MRE" }, { "item": "flour" }, { "item": "inhaler" }, { "item": "codeine" }, diff --git a/data/json/itemgroups/military.json b/data/json/itemgroups/military.json index ef8cf03b9927d..a58d5547f3655 100644 --- a/data/json/itemgroups/military.json +++ b/data/json/itemgroups/military.json @@ -58,7 +58,7 @@ "id": "military_patrol_food", "subtype": "collection", "entries": [ - { "group": "MRE", "count": [ 1, 3 ], "prob": 70 }, + { "group": "any_MRE", "count": [ 1, 3 ], "prob": 70 }, { "item": "chocolate", "prob": 20, "charges": [ 1, 3 ] }, { "item": "neccowafers", "prob": 20 }, { "item": "water_clean", "container-item": "canteen", "prob": 80, "charges": [ 0, 6 ] } diff --git a/data/json/itemgroups/misc.json b/data/json/itemgroups/misc.json index 9865786c76101..8fc8708c8372b 100644 --- a/data/json/itemgroups/misc.json +++ b/data/json/itemgroups/misc.json @@ -149,9 +149,7 @@ { "item": "rollmat" }, { "item": "sleeping_bag_roll" }, { "item": "ear_plugs" }, - { "item": "mre_hashbrownbacon_box" }, - { "item": "mre_macaronimarinara_box" }, - { "item": "mre_meatball_box" }, + { "group": "MRE", "count": 3 }, { "item": "water_clean", "count": 2, "charges": 2, "container-item": "bottle_plastic", "sealed": false } ] }, diff --git a/data/json/itemgroups/roof.json b/data/json/itemgroups/roof.json index 3f316fb6b8d24..1ea3dc5e39cd6 100644 --- a/data/json/itemgroups/roof.json +++ b/data/json/itemgroups/roof.json @@ -5,11 +5,7 @@ "items": [ { "item": "grenade", "prob": 5 }, { "item": "binoculars", "prob": 5 }, - { "item": "mre_maplesausage_box", "prob": 5 }, - { "item": "mre_ravioli_box", "prob": 5 }, - { "item": "mre_hashbrownbacon_box", "prob": 0 }, - { "item": "mre_lemontuna_box", "prob": 5 }, - { "item": "mre_asianbeef_box", "prob": 5 }, + { "group": "any_MRE", "count": [ 1, 5 ] }, { "item": "ak47", "prob": 20, "charges": [ 0, 30 ] }, { "item": "akmag30", "prob": 20, "charges": [ 0, 30 ] }, { "item": "762_m43", "prob": 20, "charges": [ 1, 30 ] }, diff --git a/data/json/items/comestibles/mre.json b/data/json/items/comestibles/mre.json index 26a0f465316c0..5de233670de77 100644 --- a/data/json/items/comestibles/mre.json +++ b/data/json/items/comestibles/mre.json @@ -1,36 +1,4 @@ [ - { - "abstract": "mre_box", - "type": "GENERIC", - "symbol": ")", - "color": "brown", - "name": { "str": "MRE" }, - "category": "food", - "description": "A generic MRE box, you shouldn't see this.", - "price": 1500, - "price_postapoc": 1500, - "weight": "725 g", - "volume": "750 ml", - "material": [ "plastic" ], - "looks_like": "mre_beef_box", - "use_action": [ "DISASSEMBLE" ] - }, - { - "abstract": "mre_smallbox", - "type": "GENERIC", - "symbol": ")", - "color": "brown", - "name": { "str": "MRE small box", "str_pl": "MRE small boxes" }, - "category": "food", - "description": "A generic small MRE box, you shouldn't see this", - "price": 500, - "price_postapoc": 100, - "weight": "300 g", - "volume": "250 ml", - "material": [ "plastic" ], - "looks_like": "mre_beef_box", - "use_action": [ "DISASSEMBLE" ] - }, { "abstract": "mre_entree", "type": "COMESTIBLE", @@ -51,218 +19,6 @@ "looks_like": "mre_beef", "fun": -1 }, - { - "id": "mre_accessory", - "type": "GENERIC", - "copy-from": "mre_smallbox", - "name": { "str": "MRE - Accessory Pack", "str_pl": "MREs - Accessory Packs" }, - "description": "An MRE accessory pack containing a variety of utensils and drinks. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_dessert", - "type": "GENERIC", - "copy-from": "mre_smallbox", - "name": { "str": "MRE - Dessert Pack", "str_pl": "MREs - Dessert Packs" }, - "description": "A sealed plastic bag containing an array of desserts. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_chilibeans_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Chili & Beans", "str_pl": "MREs - Chili & Beans" }, - "description": "A 'Meal Ready to Eat' with a chili & beans entree and everything a vegetarian soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_bbqbeef_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - BBQ Beef", "str_pl": "MREs - BBQ Beef" }, - "description": "A 'Meal Ready to Eat' with a BBQ beef entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_chickennoodle_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Chicken & Noodles", "str_pl": "MREs - Chicken & Noodles" }, - "description": "A 'Meal Ready to Eat' with a chicken & noodles entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_spaghetti_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Spaghetti", "str_pl": "MREs - Spaghetti" }, - "description": "A 'Meal Ready to Eat' with a spaghetti entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents.", - "looks_like": "mre_veggy_box" - }, - { - "id": "mre_chicken_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Chicken Chunks", "str_pl": "MREs - Chicken Chunks" }, - "description": "A 'Meal Ready to Eat' with a chicken chunk entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_beeftaco_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Beef Taco", "str_pl": "MREs - Beef Taco" }, - "description": "A 'Meal Ready to Eat' with a beef taco entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_beef_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Beef Brisket", "str_pl": "MREs - Beef Brisket" }, - "description": "A 'Meal Ready to Eat' with a beef brisket entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_meatball_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Meatballs & Marinara", "str_pl": "MREs - Meatballs & Marinara" }, - "description": "A 'Meal Ready to Eat' with a meatball entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_beefstew_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Beef Stew", "str_pl": "MREs - Beef Stew" }, - "description": "A 'Meal Ready to Eat' with a beef stew entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_chilimac_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Chili & Macaroni", "str_pl": "MREs - Chili & Macaroni" }, - "description": "A 'Meal Ready to Eat' with a chili & macaroni entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents.", - "looks_like": "mre_veggy_box" - }, - { - "id": "mre_veggy_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Vegetarian Taco", "str_pl": "MREs - Vegetarian Taco" }, - "description": "A 'Meal Ready to Eat' with a vegetarian taco entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_macaronimarinara_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Macaroni Marinara", "str_pl": "MREs - Macaroni Marinara" }, - "description": "A 'Meal Ready to Eat' with a macaroni marinara entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents.", - "looks_like": "mre_veggy_box" - }, - { - "id": "mre_sfettuccine_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Spinach Fettuccine", "str_pl": "MREs - Spinach Fettuccine" }, - "description": "A 'Meal Ready to Eat' with a creamy spinach fettuccine entree and everything a vegetarian soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents.", - "looks_like": "mre_veggy_box" - }, - { - "id": "mre_ratatouille_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Ratatouille", "str_pl": "MREs - Ratatouille" }, - "description": "A 'Meal Ready to Eat' with a ratatouille entree and everything a vegetarian soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents.", - "looks_like": "mre_veggy_box" - }, - { - "id": "mre_cheesetort_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Cheese Tortellini", "str_pl": "MREs - Cheese Tortellini" }, - "description": "A 'Meal Ready to Eat' with a cheese tortellini entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents.", - "looks_like": "mre_veggy_box" - }, - { - "id": "mre_mushroomfettuccine_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Mushroom Fettuccine", "str_pl": "MREs - Mushroom Fettuccine" }, - "description": "A 'Meal Ready to Eat' with a mushroom fettuccine entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents.", - "looks_like": "mre_veggy_box" - }, - { - "id": "mre_mexicanchickenstew_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Mexican Chicken Stew", "str_pl": "MREs - Mexican Chicken Stew" }, - "description": "A 'Meal Ready to Eat' with a Mexican chicken stew entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents.", - "looks_like": "mre_beef_box" - }, - { - "id": "mre_chickenburritobowl_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Chicken Burrito Bowl", "str_pl": "MREs - Chicken Burrito Bowl" }, - "description": "A 'Meal Ready to Eat' with a chicken burrito bowl entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_maplesausage_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Maple Sausage", "str_pl": "MREs - Maple Sausage" }, - "description": "A 'Meal Ready to Eat' with a maple sausage entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_ravioli_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Ravioli", "str_pl": "MREs - Ravioli" }, - "description": "A 'Meal Ready to Eat' with a ravioli entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_pepperjackbeef_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Pepper Jack Beef", "str_pl": "MREs - Pepper Jack Beef" }, - "description": "A 'Meal Ready to Eat' with a pepper jack beef entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_hashbrownbacon_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Hash Browns & Bacon", "str_pl": "MREs - Hash Browns & Bacon" }, - "description": "A 'Meal Ready to Eat' with a hash browns & bacon entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_lemontuna_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Lemon Pepper Tuna", "str_pl": "MREs - Lemon Pepper Tuna" }, - "description": "A 'Meal Ready to Eat' with a lemon pepper tuna entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_asianbeef_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Asian Beef & Vegetables", "str_pl": "MREs - Asian Beef & Vegetables" }, - "description": "A 'Meal Ready to Eat' with an asian beef & vegetables entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_chickenpesto_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Chicken Pesto & Pasta", "str_pl": "MREs - Chicken Pesto & Pasta" }, - "description": "A 'Meal Ready to Eat' with a chicken pesto entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_southwestbeef_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Southwest Beef & Beans", "str_pl": "MREs - Southwest Beef & Beans" }, - "description": "A 'Meal Ready to Eat' with a southwest beef & beans entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." - }, - { - "id": "mre_hotdog_box", - "type": "GENERIC", - "copy-from": "mre_box", - "name": { "str": "MRE - Frankfurters & Beans", "str_pl": "MREs - Frankfurters & Beans" }, - "description": "A vintage MRE, still perfectly preserved and edible. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents.", - "price": 1000 - }, { "type": "COMESTIBLE", "id": "mre_chilibeans", diff --git a/data/json/items/containers.json b/data/json/items/containers.json index a089dd655298b..4b74d6f7ee86f 100644 --- a/data/json/items/containers.json +++ b/data/json/items/containers.json @@ -1787,6 +1787,90 @@ "symbol": ")", "color": "red" }, + { + "id": "mre_bag_small", + "type": "GENERIC", + "category": "container", + "name": { "str": "small MRE bag" }, + "looks_like": "mre_beef_box", + "description": "A small, sturdy, plastic and aluminum container of multi-layered construction, with detailed nutritional information about its contents.", + "weight": "70 g", + "volume": "100 ml", + "price": 0, + "price_postapoc": 0, + "to_hit": -1, + "pocket_data": [ + { + "pocket_type": "CONTAINER", + "max_contains_volume": "250 ml", + "max_contains_weight": "1500 g", + "airtight": true, + "moves": 200, + "sealed_data": { "spoil_multiplier": 0.0 }, + "watertight": true + } + ], + "material": [ "plastic", "aluminum" ], + "symbol": ")", + "color": "light_gray", + "flags": [ "TRADER_AVOID" ] + }, + { + "id": "mre_bag", + "type": "GENERIC", + "category": "container", + "name": { "str": "MRE bag" }, + "looks_like": "mre_beef_box", + "description": "A sturdy plastic and aluminum container of multi-layered construction, with detailed nutritional information about its contents.", + "weight": "180 g", + "volume": "250 ml", + "price": 0, + "price_postapoc": 0, + "to_hit": -1, + "pocket_data": [ + { + "pocket_type": "CONTAINER", + "max_contains_volume": "510 ml", + "max_contains_weight": "3 kg", + "airtight": true, + "moves": 200, + "sealed_data": { "spoil_multiplier": 0.0 }, + "watertight": true + } + ], + "material": [ "plastic", "aluminum" ], + "symbol": ")", + "color": "light_gray", + "flags": [ "TRADER_AVOID" ] + }, + { + "id": "mre_package", + "type": "GENERIC", + "category": "container", + "name": { "str": "MRE package" }, + "looks_like": "mre_beef_box", + "description": "The Meal, Ready-to-Eat - also known as the MRE - is an individual field ration. It is in a lightweight yet sturdy multi-layered plastic and aluminum foil container - essentially a flexible can.", + "weight": "320 g", + "volume": "450 ml", + "price": 0, + "price_postapoc": 0, + "to_hit": -1, + "pocket_data": [ + { + "pocket_type": "CONTAINER", + "max_contains_volume": "2831 ml", + "max_contains_weight": "4 kg", + "airtight": true, + "moves": 200, + "sealed_data": { "spoil_multiplier": 0.0 }, + "watertight": true + } + ], + "material": [ "plastic", "aluminum" ], + "symbol": ")", + "color": "light_gray", + "flags": [ "TRADER_AVOID" ] + }, { "id": "beverage_bag", "type": "GENERIC", diff --git a/data/json/items/obsolete.json b/data/json/items/obsolete.json index f01fc571db757..93b89c027ed98 100644 --- a/data/json/items/obsolete.json +++ b/data/json/items/obsolete.json @@ -18,6 +18,250 @@ "type": "recipe", "obsolete": true }, + { + "abstract": "mre_box", + "type": "GENERIC", + "symbol": ")", + "color": "brown", + "name": { "str": "MRE" }, + "category": "food", + "description": "A generic MRE box, you shouldn't see this.", + "price": 1500, + "price_postapoc": 1500, + "weight": "725 g", + "volume": "750 ml", + "material": [ "plastic" ], + "looks_like": "mre_beef_box", + "use_action": [ "DISASSEMBLE" ] + }, + { + "abstract": "mre_smallbox", + "type": "GENERIC", + "symbol": ")", + "color": "brown", + "name": { "str": "MRE small box", "str_pl": "MRE small boxes" }, + "category": "food", + "description": "A generic small MRE box, you shouldn't see this", + "price": 500, + "price_postapoc": 100, + "weight": "300 g", + "volume": "250 ml", + "material": [ "plastic" ], + "looks_like": "mre_beef_box", + "use_action": [ "DISASSEMBLE" ] + }, + { + "id": "mre_accessory", + "type": "GENERIC", + "copy-from": "mre_smallbox", + "name": { "str": "MRE - Accessory Pack", "str_pl": "MREs - Accessory Packs" }, + "description": "An MRE accessory pack containing a variety of utensils and drinks. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_dessert", + "type": "GENERIC", + "copy-from": "mre_smallbox", + "name": { "str": "MRE - Dessert Pack", "str_pl": "MREs - Dessert Packs" }, + "description": "A sealed plastic bag containing an array of desserts. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_chilibeans_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Chili & Beans", "str_pl": "MREs - Chili & Beans" }, + "description": "A 'Meal Ready to Eat' with a chili & beans entree and everything a vegetarian soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_bbqbeef_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - BBQ Beef", "str_pl": "MREs - BBQ Beef" }, + "description": "A 'Meal Ready to Eat' with a BBQ beef entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_chickennoodle_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Chicken & Noodles", "str_pl": "MREs - Chicken & Noodles" }, + "description": "A 'Meal Ready to Eat' with a chicken & noodles entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_spaghetti_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Spaghetti", "str_pl": "MREs - Spaghetti" }, + "description": "A 'Meal Ready to Eat' with a spaghetti entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents.", + "looks_like": "mre_veggy_box" + }, + { + "id": "mre_chicken_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Chicken Chunks", "str_pl": "MREs - Chicken Chunks" }, + "description": "A 'Meal Ready to Eat' with a chicken chunk entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_beeftaco_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Beef Taco", "str_pl": "MREs - Beef Taco" }, + "description": "A 'Meal Ready to Eat' with a beef taco entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_beef_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Beef Brisket", "str_pl": "MREs - Beef Brisket" }, + "description": "A 'Meal Ready to Eat' with a beef brisket entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_meatball_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Meatballs & Marinara", "str_pl": "MREs - Meatballs & Marinara" }, + "description": "A 'Meal Ready to Eat' with a meatball entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_beefstew_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Beef Stew", "str_pl": "MREs - Beef Stew" }, + "description": "A 'Meal Ready to Eat' with a beef stew entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_chilimac_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Chili & Macaroni", "str_pl": "MREs - Chili & Macaroni" }, + "description": "A 'Meal Ready to Eat' with a chili & macaroni entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents.", + "looks_like": "mre_veggy_box" + }, + { + "id": "mre_veggy_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Vegetarian Taco", "str_pl": "MREs - Vegetarian Taco" }, + "description": "A 'Meal Ready to Eat' with a vegetarian taco entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_macaronimarinara_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Macaroni Marinara", "str_pl": "MREs - Macaroni Marinara" }, + "description": "A 'Meal Ready to Eat' with a macaroni marinara entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents.", + "looks_like": "mre_veggy_box" + }, + { + "id": "mre_sfettuccine_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Spinach Fettuccine", "str_pl": "MREs - Spinach Fettuccine" }, + "description": "A 'Meal Ready to Eat' with a creamy spinach fettuccine entree and everything a vegetarian soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents.", + "looks_like": "mre_veggy_box" + }, + { + "id": "mre_ratatouille_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Ratatouille", "str_pl": "MREs - Ratatouille" }, + "description": "A 'Meal Ready to Eat' with a ratatouille entree and everything a vegetarian soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents.", + "looks_like": "mre_veggy_box" + }, + { + "id": "mre_cheesetort_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Cheese Tortellini", "str_pl": "MREs - Cheese Tortellini" }, + "description": "A 'Meal Ready to Eat' with a cheese tortellini entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents.", + "looks_like": "mre_veggy_box" + }, + { + "id": "mre_mushroomfettuccine_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Mushroom Fettuccine", "str_pl": "MREs - Mushroom Fettuccine" }, + "description": "A 'Meal Ready to Eat' with a mushroom fettuccine entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents.", + "looks_like": "mre_veggy_box" + }, + { + "id": "mre_mexicanchickenstew_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Mexican Chicken Stew", "str_pl": "MREs - Mexican Chicken Stew" }, + "description": "A 'Meal Ready to Eat' with a Mexican chicken stew entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents.", + "looks_like": "mre_beef_box" + }, + { + "id": "mre_chickenburritobowl_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Chicken Burrito Bowl", "str_pl": "MREs - Chicken Burrito Bowl" }, + "description": "A 'Meal Ready to Eat' with a chicken burrito bowl entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_maplesausage_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Maple Sausage", "str_pl": "MREs - Maple Sausage" }, + "description": "A 'Meal Ready to Eat' with a maple sausage entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_ravioli_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Ravioli", "str_pl": "MREs - Ravioli" }, + "description": "A 'Meal Ready to Eat' with a ravioli entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_pepperjackbeef_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Pepper Jack Beef", "str_pl": "MREs - Pepper Jack Beef" }, + "description": "A 'Meal Ready to Eat' with a pepper jack beef entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_hashbrownbacon_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Hash Browns & Bacon", "str_pl": "MREs - Hash Browns & Bacon" }, + "description": "A 'Meal Ready to Eat' with a hash browns & bacon entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_lemontuna_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Lemon Pepper Tuna", "str_pl": "MREs - Lemon Pepper Tuna" }, + "description": "A 'Meal Ready to Eat' with a lemon pepper tuna entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_asianbeef_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Asian Beef & Vegetables", "str_pl": "MREs - Asian Beef & Vegetables" }, + "description": "A 'Meal Ready to Eat' with an asian beef & vegetables entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_chickenpesto_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Chicken Pesto & Pasta", "str_pl": "MREs - Chicken Pesto & Pasta" }, + "description": "A 'Meal Ready to Eat' with a chicken pesto entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_southwestbeef_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Southwest Beef & Beans", "str_pl": "MREs - Southwest Beef & Beans" }, + "description": "A 'Meal Ready to Eat' with a southwest beef & beans entree and everything a hungry soldier needs. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents." + }, + { + "id": "mre_hotdog_box", + "type": "GENERIC", + "copy-from": "mre_box", + "name": { "str": "MRE - Frankfurters & Beans", "str_pl": "MREs - Frankfurters & Beans" }, + "description": "A vintage MRE, still perfectly preserved and edible. The contents will begin to rot once they're removed from this sealed bag. Activate or disassemble it to get to its contents.", + "price": 1000 + }, { "id": "survival_kit", "type": "GENERIC", diff --git a/data/json/mapgen/helipad.json b/data/json/mapgen/helipad.json index 95fe689dccd82..21e3471acfeb3 100644 --- a/data/json/mapgen/helipad.json +++ b/data/json/mapgen/helipad.json @@ -71,7 +71,7 @@ "item": { "subtype": "distribution", "entries": [ - { "group": "military_patrol_food", "prob": 50, "count": [ 3, 5 ] }, + { "group": "MRE", "prob": 50, "count": [ 3, 5 ] }, { "group": "infantry_common_gear", "prob": 5, "count": [ 1, 2 ] }, { "group": "mil_food", "prob": 40, "count": [ 1, 5 ] }, { "group": "infantry_medical_gear", "prob": 5, "count": [ 1, 2 ] }, diff --git a/data/json/npcs/NC_SOLDIER.json b/data/json/npcs/NC_SOLDIER.json index d5e6ccb771832..32254860913cf 100644 --- a/data/json/npcs/NC_SOLDIER.json +++ b/data/json/npcs/NC_SOLDIER.json @@ -149,29 +149,7 @@ { "item": "e_tool", "prob": 15 }, { "item": "chocolate", "prob": 30 }, { "item": "can_beans", "prob": 20 }, - { "item": "mre_chilibeans_box", "prob": 45 }, - { "item": "mre_bbqbeef_box", "prob": 45 }, - { "item": "mre_chickennoodle_box", "prob": 45 }, - { "item": "mre_spaghetti_box", "prob": 45 }, - { "item": "mre_chicken_box", "prob": 45 }, - { "item": "mre_beeftaco_box", "prob": 45 }, - { "item": "mre_beef_box", "prob": 45 }, - { "item": "mre_meatball_box", "prob": 45 }, - { "item": "mre_beefstew_box", "prob": 45 }, - { "item": "mre_chilimac_box", "prob": 45 }, - { "item": "mre_veggy_box", "prob": 45 }, - { "item": "mre_macaronimarinara_box", "prob": 45 }, - { "item": "mre_cheesetort_box", "prob": 45 }, - { "item": "mre_mushroomfettuccine_box", "prob": 45 }, - { "item": "mre_mexicanchickenstew_box", "prob": 45 }, - { "item": "mre_maplesausage_box", "prob": 45 }, - { "item": "mre_ravioli_box", "prob": 45 }, - { "item": "mre_hashbrownbacon_box", "prob": 45 }, - { "item": "mre_lemontuna_box", "prob": 45 }, - { "item": "mre_asianbeef_box", "prob": 45 }, - { "item": "mre_chickenpesto_box", "prob": 45 }, - { "item": "mre_southwestbeef_box", "prob": 45 }, - { "item": "mre_hotdog_box", "prob": 45 }, + { "group": "any_MRE", "count": [ 2, 3 ], "prob": 45 }, { "group": "full_ifak", "prob": 35 }, { "item": "saline", "prob": 10 }, { "item": "con_milk", "prob": 10 }, diff --git a/data/json/npcs/items_generic.json b/data/json/npcs/items_generic.json index 3c112bae478e7..64a3fe75c951b 100644 --- a/data/json/npcs/items_generic.json +++ b/data/json/npcs/items_generic.json @@ -799,29 +799,7 @@ [ "money_bundle", 10 ], [ "moonshine", 5 ], [ "mp3", 10 ], - [ "mre_chilibeans_box", 6 ], - [ "mre_bbqbeef_box", 6 ], - [ "mre_chickennoodle_box", 6 ], - [ "mre_spaghetti_box", 6 ], - [ "mre_chicken_box", 6 ], - [ "mre_beeftaco_box", 6 ], - [ "mre_beef_box", 6 ], - [ "mre_meatball_box", 6 ], - [ "mre_beefstew_box", 6 ], - [ "mre_chilimac_box", 6 ], - [ "mre_veggy_box", 6 ], - [ "mre_macaronimarinara_box", 6 ], - [ "mre_cheesetort_box", 6 ], - [ "mre_mushroomfettuccine_box", 6 ], - [ "mre_mexicanchickenstew_box", 6 ], - [ "mre_maplesausage_box", 6 ], - [ "mre_ravioli_box", 6 ], - [ "mre_hashbrownbacon_box", 6 ], - [ "mre_lemontuna_box", 6 ], - [ "mre_asianbeef_box", 6 ], - [ "mre_chickenpesto_box", 6 ], - [ "mre_southwestbeef_box", 6 ], - [ "mre_hotdog_box", 6 ], + { "group": "any_MRE", "count": [ 1, 3 ], "prob": 20 }, [ "mushroom", 5 ], [ "mustard", 3 ], [ "muzzle_brake", 1 ], diff --git a/data/json/npcs/refugee_center/surface_visitors/NPC_scavenger_mercenary.json b/data/json/npcs/refugee_center/surface_visitors/NPC_scavenger_mercenary.json index 4484feb847eae..ac4999a89bc8c 100644 --- a/data/json/npcs/refugee_center/surface_visitors/NPC_scavenger_mercenary.json +++ b/data/json/npcs/refugee_center/surface_visitors/NPC_scavenger_mercenary.json @@ -64,8 +64,7 @@ "items": [ { "item": "ear_plugs", "custom-flags": [ "no_auto_equip" ] }, { "item": "stanag30", "ammo-item": "556", "charges": 30 }, - { "item": "mre_chilibeans_box" }, - { "item": "mre_chickennoodle_box" } + { "group": "any_MRE", "count": 2 } ] }, { diff --git a/data/json/recipes/recipe_deconstruction_package.json b/data/json/recipes/recipe_deconstruction_package.json deleted file mode 100644 index 36fb768f05108..0000000000000 --- a/data/json/recipes/recipe_deconstruction_package.json +++ /dev/null @@ -1,460 +0,0 @@ -[ - { - "result": "mre_accessory", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "3 s", - "components": [ - [ [ "pur_tablets", 6 ] ], - [ [ "gummy_vitamins", 1 ] ], - [ [ "instant_coffee", 1 ] ], - [ [ "lemonade_powder", 1 ] ], - [ [ "matches", 1 ] ], - [ [ "gum", 2 ] ], - [ [ "paper", 8 ] ], - [ [ "spork", 1 ] ], - [ [ "beverage_bag", 1 ] ] - ], - "flags": [ "BLIND_EASY", "FULL_MAGAZINE" ] - }, - { - "result": "mre_dessert", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "3 s", - "components": [ [ [ "dry_fruit", 1 ] ], [ [ "chocolate", 1 ] ], [ [ "candy2", 1 ] ], [ [ "cookies", 1 ] ], [ [ "bag_plastic", 1 ] ] ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_chilibeans_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_chilibeans", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "spread_peanutbutter", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_bbqbeef_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_bbqbeef", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_chickennoodle_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_chickennoodle", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_spaghetti_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_spaghetti", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_chicken_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_chicken", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_beeftaco_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_beeftaco", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_beef_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_beef", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_meatball_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_meatball", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_beefstew_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_beefstew", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_chilimac_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_chilimac", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_veggy_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_veggy", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_macaronimarinara_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_macaronimarinara", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_sfettuccine_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_sfettuccine", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "spread_peanutbutter", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_ratatouille_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_ratatouille", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "spread_peanutbutter", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_cheesetort_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_cheesetort", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_mushroomfettuccine_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_mushroomfettuccine", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_mexicanchickenstew_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_mexicanchickenstew", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_chickenburritobowl_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_chickenburritobowl", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_maplesausage_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_maplesausage", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_ravioli_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_ravioli", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_pepperjackbeef_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_pepperjackbeef", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_hashbrownbacon_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_hashbrownbacon", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_lemontuna_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_lemontuna", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_asianbeef_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_asianbeef", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_chickenpesto_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_chickenpesto", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_southwestbeef_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_southwestbeef", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - }, - { - "result": "mre_hotdog_box", - "type": "uncraft", - "activity_level": "NO_EXERCISE", - "time": "30 s", - "components": [ - [ [ "mre_hotdog", 1 ] ], - [ [ "crackers", 1 ] ], - [ [ "can_cheese", 1 ] ], - [ [ "heatpack", 1 ] ], - [ [ "mre_dessert", 1 ] ], - [ [ "mre_accessory", 1 ] ], - [ [ "bag_plastic", 1 ] ] - ], - "flags": [ "BLIND_EASY" ] - } -] diff --git a/data/json/recipes/recipe_obsolete.json b/data/json/recipes/recipe_obsolete.json index 9ecf3c481fae2..043971409cf66 100644 --- a/data/json/recipes/recipe_obsolete.json +++ b/data/json/recipes/recipe_obsolete.json @@ -4,6 +4,151 @@ "result": "cooked_burrito", "obsolete": true }, + { + "type": "recipe", + "result": "mre_accessory", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_dessert", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_chilibeans_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_bbqbeef_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_chickennoodle_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_spaghetti_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_chicken_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_beeftaco_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_beef_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_meatball_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_beefstew_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_chilimac_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_veggy_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_macaronimarinara_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_sfettuccine_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_ratatouille_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_cheesetort_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_mushroomfettuccine_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_mexicanchickenstew_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_chickenburritobowl_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_maplesausage_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_ravioli_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_pepperjackbeef_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_hashbrownbacon_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_lemontuna_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_asianbeef_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_chickenpesto_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_southwestbeef_box", + "obsolete": true + }, + { + "type": "recipe", + "result": "mre_hotdog_box", + "obsolete": true + }, { "type": "recipe", "result": "jar_3l_glass", diff --git a/data/json/vehicles/helicopters.json b/data/json/vehicles/helicopters.json index 8baddfd6cc55d..dce6e41b824c3 100644 --- a/data/json/vehicles/helicopters.json +++ b/data/json/vehicles/helicopters.json @@ -659,11 +659,11 @@ ], "items": [ { "x": -1, "y": -1, "chance": 7, "items": [ "bandages" ] }, - { "x": -1, "y": -1, "chance": 5, "items": [ "mre_veggy_box" ] }, - { "x": -1, "y": -1, "chance": 5, "items": [ "mre_beef_box" ] }, - { "x": -1, "y": -1, "chance": 5, "items": [ "mre_ravioli_box" ] }, - { "x": -1, "y": -1, "chance": 5, "items": [ "mre_hotdog_box" ] }, - { "x": -1, "y": -1, "chance": 5, "items": [ "mre_chicken_box" ] }, + { "x": -1, "y": -1, "chance": 5, "item_groups": [ "MRE" ] }, + { "x": -1, "y": -1, "chance": 5, "item_groups": [ "MRE" ] }, + { "x": -1, "y": -1, "chance": 5, "item_groups": [ "MRE" ] }, + { "x": -1, "y": -1, "chance": 5, "item_groups": [ "MRE" ] }, + { "x": -1, "y": -1, "chance": 5, "item_groups": [ "MRE" ] }, { "x": -1, "y": -1, "chance": 10, "items": [ "canteen" ] }, { "x": -1, "y": -1, "chance": 10, "items": [ "light_plus_battery_cell" ] }, { "x": -1, "y": -1, "chance": 10, "item_groups": [ "full_ifak" ] }, @@ -741,11 +741,11 @@ ], "items": [ { "x": -1, "y": -1, "chance": 7, "items": [ "bandages" ] }, - { "x": -1, "y": -1, "chance": 7, "items": [ "mre_veggy_box" ] }, - { "x": -1, "y": -1, "chance": 7, "items": [ "mre_beef_box" ] }, - { "x": -1, "y": -1, "chance": 7, "items": [ "mre_ravioli_box" ] }, - { "x": -1, "y": -1, "chance": 7, "items": [ "mre_hotdog_box" ] }, - { "x": -1, "y": -1, "chance": 7, "items": [ "mre_chicken_box" ] }, + { "x": -1, "y": -1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -1, "y": -1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -1, "y": -1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -1, "y": -1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -1, "y": -1, "chance": 7, "item_groups": [ "MRE" ] }, { "x": -1, "y": -1, "chance": 10, "items": [ "canteen" ] }, { "x": -1, "y": -1, "chance": 10, "items": [ "light_plus_battery_cell" ] }, { "x": -1, "y": -1, "chance": 10, "item_groups": [ "full_ifak" ] }, @@ -818,11 +818,11 @@ ], "items": [ { "x": -1, "y": 1, "chance": 7, "items": [ "bandages" ] }, - { "x": -1, "y": 1, "chance": 7, "items": [ "mre_veggy_box" ] }, - { "x": -1, "y": 1, "chance": 7, "items": [ "mre_beef_box" ] }, - { "x": -1, "y": 1, "chance": 7, "items": [ "mre_ravioli_box" ] }, - { "x": -1, "y": 1, "chance": 7, "items": [ "mre_hotdog_box" ] }, - { "x": -1, "y": 1, "chance": 7, "items": [ "mre_chicken_box" ] }, + { "x": -1, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -1, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -1, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -1, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -1, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, { "x": -1, "y": 1, "chance": 10, "items": [ "canteen" ] }, { "x": -1, "y": 1, "chance": 10, "items": [ "light_plus_battery_cell" ] }, { "x": -1, "y": 1, "chance": 10, "item_groups": [ "full_ifak" ] }, @@ -1035,11 +1035,11 @@ { "x": -7, "y": -2, "chance": 15, "items": [ "mask_gas" ] }, { "x": -7, "y": -2, "chance": 7, "items": [ "flashlight" ], "ammo": 100 }, { "x": -7, "y": -2, "chance": 7, "items": [ "large_repairkit" ] }, - { "x": -7, "y": -2, "chance": 5, "items": [ "mre_veggy_box" ] }, - { "x": -7, "y": -2, "chance": 5, "items": [ "mre_ravioli_box" ] }, - { "x": -7, "y": -2, "chance": 5, "items": [ "mre_beef_box" ] }, - { "x": -7, "y": -2, "chance": 5, "items": [ "mre_chicken_box" ] }, - { "x": -7, "y": -2, "chance": 5, "items": [ "mre_hotdog_box" ] }, + { "x": -7, "y": -2, "chance": 5, "item_groups": [ "MRE" ] }, + { "x": -7, "y": -2, "chance": 5, "item_groups": [ "MRE" ] }, + { "x": -7, "y": -2, "chance": 5, "item_groups": [ "MRE" ] }, + { "x": -7, "y": -2, "chance": 5, "item_groups": [ "MRE" ] }, + { "x": -7, "y": -2, "chance": 5, "item_groups": [ "MRE" ] }, { "x": -7, "y": -2, "chance": 10, "items": [ "manual_rifle" ] }, { "x": -7, "y": -2, "chance": 10, "items": [ "manual_stabbing" ] }, { "x": -7, "y": 2, "chance": 10, "ammo": 70, "items": [ "m9mag" ] }, @@ -1226,11 +1226,11 @@ { "x": -7, "y": -2, "chance": 15, "items": [ "mask_gas" ] }, { "x": -7, "y": -2, "chance": 7, "items": [ "flashlight" ], "ammo": 100 }, { "x": -7, "y": -2, "chance": 7, "items": [ "large_repairkit" ] }, - { "x": -7, "y": -2, "chance": 5, "items": [ "mre_veggy_box" ] }, - { "x": -7, "y": -2, "chance": 5, "items": [ "mre_ravioli_box" ] }, - { "x": -7, "y": -2, "chance": 5, "items": [ "mre_beef_box" ] }, - { "x": -7, "y": -2, "chance": 5, "items": [ "mre_chicken_box" ] }, - { "x": -7, "y": -2, "chance": 5, "items": [ "mre_hotdog_box" ] }, + { "x": -7, "y": -2, "chance": 5, "item_groups": [ "MRE" ] }, + { "x": -7, "y": -2, "chance": 5, "item_groups": [ "MRE" ] }, + { "x": -7, "y": -2, "chance": 5, "item_groups": [ "MRE" ] }, + { "x": -7, "y": -2, "chance": 5, "item_groups": [ "MRE" ] }, + { "x": -7, "y": -2, "chance": 5, "item_groups": [ "MRE" ] }, { "x": -7, "y": -2, "chance": 10, "items": [ "manual_rifle" ] }, { "x": -7, "y": -2, "chance": 10, "items": [ "manual_stabbing" ] }, { "x": -7, "y": 1, "chance": 20, "item_groups": [ "remains_soldier" ] }, @@ -1395,11 +1395,11 @@ { "x": -7, "y": -2, "chance": 15, "items": [ "mask_gas" ] }, { "x": -7, "y": -2, "chance": 7, "items": [ "flashlight" ], "ammo": 100 }, { "x": -7, "y": -2, "chance": 7, "items": [ "large_repairkit" ] }, - { "x": -7, "y": -2, "chance": 5, "items": [ "mre_veggy_box" ] }, - { "x": -7, "y": -2, "chance": 5, "items": [ "mre_ravioli_box" ] }, - { "x": -7, "y": -2, "chance": 5, "items": [ "mre_beef_box" ] }, - { "x": -7, "y": -2, "chance": 5, "items": [ "mre_chicken_box" ] }, - { "x": -7, "y": -2, "chance": 5, "items": [ "mre_hotdog_box" ] }, + { "x": -7, "y": -2, "chance": 5, "item_groups": [ "MRE" ] }, + { "x": -7, "y": -2, "chance": 5, "item_groups": [ "MRE" ] }, + { "x": -7, "y": -2, "chance": 5, "item_groups": [ "MRE" ] }, + { "x": -7, "y": -2, "chance": 5, "item_groups": [ "MRE" ] }, + { "x": -7, "y": -2, "chance": 5, "item_groups": [ "MRE" ] }, { "x": -7, "y": -2, "chance": 10, "items": [ "manual_rifle" ] }, { "x": -7, "y": -2, "chance": 10, "items": [ "manual_stabbing" ] }, { "x": -7, "y": 1, "chance": 20, "item_groups": [ "remains_soldier" ] }, @@ -1491,11 +1491,11 @@ { "x": -10, "y": 2, "parts": [ "frame_cover", "halfboard_ne" ] } ], "items": [ - { "x": -6, "y": 1, "chance": 7, "items": [ "mre_veggy_box" ] }, - { "x": -6, "y": 1, "chance": 7, "items": [ "mre_hotdog_box" ] }, - { "x": -6, "y": 1, "chance": 7, "items": [ "mre_ravioli_box" ] }, - { "x": -6, "y": 1, "chance": 7, "items": [ "mre_chicken_box" ] }, - { "x": -6, "y": 1, "chance": 7, "items": [ "mre_beef_box" ] }, + { "x": -6, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -6, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -6, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -6, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -6, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, { "x": -6, "y": 1, "chance": 10, "items": [ "helmet_liner" ] }, { "x": -6, "y": 1, "chance": 5, "magazine": 70, "ammo": 70, "items": [ "9mm" ] }, { "x": -6, "y": 1, "chance": 5, "items": [ "223" ] }, @@ -1597,11 +1597,11 @@ { "x": -8, "y": 1, "parts": [ "frame_vertical" ] } ], "items": [ - { "x": -6, "y": 1, "chance": 7, "items": [ "mre_veggy_box" ] }, - { "x": -6, "y": 1, "chance": 7, "items": [ "mre_hotdog_box" ] }, - { "x": -6, "y": 1, "chance": 7, "items": [ "mre_ravioli_box" ] }, - { "x": -6, "y": 1, "chance": 7, "items": [ "mre_chicken_box" ] }, - { "x": -6, "y": 1, "chance": 7, "items": [ "mre_beef_box" ] }, + { "x": -6, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -6, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -6, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -6, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -6, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, { "x": -6, "y": 1, "chance": 10, "items": [ "helmet_liner" ] }, { "x": -6, "y": 1, "chance": 5, "magazine": 70, "ammo": 70, "items": [ "9mm" ] }, { "x": -6, "y": 1, "chance": 5, "items": [ "223" ] }, @@ -1701,11 +1701,11 @@ { "x": -10, "y": 2, "parts": [ "frame_cover", "halfboard_ne" ] } ], "items": [ - { "x": -6, "y": 1, "chance": 7, "items": [ "mre_veggy_box" ] }, - { "x": -6, "y": 1, "chance": 7, "items": [ "mre_hotdog_box" ] }, - { "x": -6, "y": 1, "chance": 7, "items": [ "mre_ravioli_box" ] }, - { "x": -6, "y": 1, "chance": 7, "items": [ "mre_chicken_box" ] }, - { "x": -6, "y": 1, "chance": 7, "items": [ "mre_beef_box" ] }, + { "x": -6, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -6, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -6, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -6, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, + { "x": -6, "y": 1, "chance": 7, "item_groups": [ "MRE" ] }, { "x": -6, "y": 1, "chance": 10, "items": [ "helmet_liner" ] }, { "x": -6, "y": 1, "chance": 5, "magazine": 70, "ammo": 70, "items": [ "9mm" ] }, { "x": -6, "y": 1, "chance": 5, "items": [ "223" ] }, diff --git a/data/mods/CRT_EXPANSION/scenarios/crt_classes.json b/data/mods/CRT_EXPANSION/scenarios/crt_classes.json index 041172c84f5a0..80478294efd54 100644 --- a/data/mods/CRT_EXPANSION/scenarios/crt_classes.json +++ b/data/mods/CRT_EXPANSION/scenarios/crt_classes.json @@ -88,7 +88,6 @@ "legguard_hard", "pants_army", "armguard_hard", - "mre_veggy_box", "crt_backpack", "two_way_radio", "crt_gloves_liner", @@ -101,6 +100,7 @@ { "item": "ear_plugs", "custom-flags": [ "no_auto_equip" ] }, { "item": "knife_crt", "container-item": "sheath" }, { "item": "m4a1", "ammo-item": "223", "contents-item": [ "grip", "holo_sight" ] }, + { "group": "MRE" }, { "item": "stanag30", "ammo-item": "223", "count": 1 } ] }, @@ -127,7 +127,6 @@ "army_top", "crt_jacket", "armguard_hard", - "mre_veggy_box", "crt_helmet", "glasses_bal", "molle_pack", @@ -141,6 +140,7 @@ { "item": "ear_plugs", "custom-flags": [ "no_auto_equip" ] }, { "item": "knife_rm42", "container-item": "sheath" }, { "item": "scar_h", "ammo-item": "308", "contents-item": "shoulder_strap" }, + { "group": "MRE" }, { "item": "scarhmag", "ammo-item": "308", "count": 2 } ] }, @@ -176,7 +176,6 @@ "crt_canteen", "crt_legrig", "socks", - "mre_veggy_box", "crt_la_boots", "two_way_radio", "bandages", @@ -188,6 +187,7 @@ { "group": "full_ifak" }, { "item": "ear_plugs", "custom-flags": [ "no_auto_equip" ] }, { "item": "sleeping_bag", "custom-flags": [ "no_auto_equip" ] }, + { "group": "MRE" }, { "item": "crt_laser_pistol", "container-item": "holster" } ] }, @@ -215,7 +215,6 @@ "jacket_army", "army_top", "crt_armguard", - "mre_veggy_box", "molle_pack", "two_way_radio", "crt_gloves", @@ -230,6 +229,7 @@ { "item": "l_lmg_223", "ammo-item": "223" }, { "item": "lw223bigmag", "count": 1 }, { "item": "m9", "ammo-item": "9mm", "container-item": "holster" }, + { "group": "MRE" }, { "item": "m9mag", "ammo-item": "9mm", "count": 2 } ] }, @@ -261,7 +261,6 @@ "crt_iduster", "army_top", "crt_pants", - "mre_veggy_box", "heavy_flashlight", "two_way_radio", "socks", @@ -273,6 +272,7 @@ { "item": "ear_plugs", "custom-flags": [ "no_auto_equip" ] }, { "item": "knife_rm42", "container-item": "sheath" }, { "item": "m9", "ammo-item": "9mm", "container-item": "holster" }, + { "group": "MRE" }, { "item": "m9mag", "ammo-item": "9mm", "count": 2 } ] }, @@ -450,7 +450,6 @@ "UPS_off", "geiger_off", "crt_hatchet", - "mre_veggy_box", "crt_mess_kit", "lighter", "badge_marshal", @@ -466,6 +465,7 @@ { "item": "knife_crt", "container-item": "crt_belt" }, { "item": "crt_laser_pistol", "container-item": "holster" }, { "item": "signal_flare", "ammo-item": "signal_flare", "count": 5 }, + { "group": "MRE" }, { "item": "battery", "ammo-item": "battery", "count": 25 } ] }, @@ -514,7 +514,6 @@ "crt_boots", "two_way_radio", "crt_hatchet", - "mre_veggy_box", "lighter", "pellet", "pelletgun", @@ -523,6 +522,7 @@ ], "entries": [ { "item": "water_clean", "ammo-item": "water_clean", "container-item": "crt_canteen" }, + { "group": "MRE" }, { "item": "knife_crt", "container-item": "sheath" } ] }, @@ -561,7 +561,6 @@ "socks", "crt_la_boots", "crt_hatchet", - "mre_veggy_box", "lighter", "crt_mess_kit", "id_military", @@ -569,7 +568,7 @@ "knife_swissarmy", "pellet" ], - "entries": [ { "item": "water_clean", "container-item": "canteen" } ] + "entries": [ { "item": "water_clean", "container-item": "canteen" }, { "group": "MRE" } ] }, "male": [ "boxer_shorts" ], "female": [ "sports_bra", "boxer_shorts" ] @@ -648,13 +647,12 @@ "ds_rivet_gun", "ds_ripper", "toolbox", - "mre_veggy_box", "lighter", "UPS_off", "id_military", "id_science" ], - "entries": [ { "item": "water_clean", "ammo-item": "water_clean", "container-item": "canteen" } ] + "entries": [ { "item": "water_clean", "ammo-item": "water_clean", "container-item": "canteen" }, { "group": "MRE" } ] }, "male": [ "boxer_shorts" ], "female": [ "sports_bra", "boxer_shorts" ] @@ -724,7 +722,6 @@ "socks", "crt_la_boots", "crt_hatchet", - "mre_veggy_box", "crt_mess_kit", "lighter", "knife_swissarmy", @@ -736,6 +733,7 @@ ], "entries": [ { "item": "water_clean", "ammo-item": "water_clean", "container-item": "canteen" }, + { "group": "MRE" }, { "item": "knife_crt", "container-item": "crt_belt" } ] }, From e0724f63f15bef2a8eb9f8cc3825d803f2863777 Mon Sep 17 00:00:00 2001 From: connorpmartin <55263157+connorpmartin@users.noreply.github.com> Date: Fri, 9 Jul 2021 02:22:10 -0400 Subject: [PATCH 088/116] Fix fur/scales loop in Chimera (#48637) * Update mutations.json * Small chimera mutation rework Added "patchwork skin" mutation instead of fur and scales, which combines both mutations at reduced effectiveness. Advanced mutation combines them at full effectiveness to represent thicker fur/scales. Added Large to chimera, since Chimera line is partially based on Lizard and Cattle (horns/hooves), and both of them have Large. Added "valid: false" tag to hyper-metabolism alternate mutation to prevent endless mutation swapping. * made patchwork skin work properly * linted --- data/json/mutations/mutation_ordering.json | 2 + data/json/mutations/mutations.json | 79 ++++++++++++++++++++-- 2 files changed, 75 insertions(+), 6 deletions(-) diff --git a/data/json/mutations/mutation_ordering.json b/data/json/mutations/mutation_ordering.json index ef971db43e08c..1e243ed177ac3 100644 --- a/data/json/mutations/mutation_ordering.json +++ b/data/json/mutations/mutation_ordering.json @@ -64,6 +64,8 @@ "LIGHT_FUR", "LUPINE_FUR", "LYNX_FUR", + "PATCHSKIN1", + "PATCHSKIN2", "PLANTSKIN", "SCALES", "SKIN_ROUGH", diff --git a/data/json/mutations/mutations.json b/data/json/mutations/mutations.json index 694fbdf93e346..38e0b2f54e3d7 100644 --- a/data/json/mutations/mutations.json +++ b/data/json/mutations/mutations.json @@ -1489,7 +1489,7 @@ "ugliness": 1, "description": "Your skin is slightly rough. This has no gameplay effect.", "types": [ "SKIN" ], - "changes_to": [ "SCALES", "FEATHERS", "LIGHTFUR", "CHITIN", "PLANTSKIN" ], + "changes_to": [ "SCALES", "FEATHERS", "LIGHTFUR", "CHITIN", "PLANTSKIN", "PATCHSKIN1" ], "category": [ "LIZARD" ] }, { @@ -1963,7 +1963,7 @@ "ugliness": 3, "description": "A set of flexible green scales has grown to cover your body, acting as natural armor. Somewhat reduces wet effects.", "types": [ "SKIN" ], - "category": [ "CHIMERA", "RAPTOR", "LIZARD" ], + "category": [ "RAPTOR", "LIZARD" ], "prereqs": [ "SKIN_ROUGH" ], "changes_to": [ "THICK_SCALES", "SLEEK_SCALES" ], "movecost_swim_modifier": 0.9, @@ -2108,7 +2108,7 @@ "bodytemp_modifiers": [ 250, 500 ], "bodytemp_sleep": 100, "description": "Light fur has grown to cover your entire body, providing slight protection from cold.", - "category": [ "CHIMERA", "SPIDER", "MOUSE" ], + "category": [ "SPIDER", "MOUSE" ], "types": [ "SKIN" ], "prereqs": [ "SKIN_ROUGH" ], "changes_to": [ "FUR", "FELINE_FUR", "LUPINE_FUR", "URSINE_FUR", "CHITIN_FUR" ] @@ -2203,6 +2203,73 @@ "category": [ "FELINE" ], "armor": [ { "parts": [ "head", "mouth" ], "bash": 1 } ] }, + { + "type": "mutation", + "id": "PATCHSKIN1", + "name": { "str": "Patchwork Skin" }, + "points": 2, + "visibility": 10, + "ugliness": 6, + "bodytemp_modifiers": [ 125, 250 ], + "bodytemp_sleep": 50, + "description": "Your skin has mutated into an amalgamation of fur and scales.", + "movecost_swim_modifier": 0.95, + "wet_protection": [ + { "part": "head", "ignored": 2 }, + { "part": "leg_l", "ignored": 5 }, + { "part": "leg_r", "ignored": 5 }, + { "part": "foot_l", "ignored": 2 }, + { "part": "foot_r", "ignored": 2 }, + { "part": "arm_l", "ignored": 5 }, + { "part": "arm_r", "ignored": 5 }, + { "part": "hand_l", "ignored": 1 }, + { "part": "hand_r", "ignored": 1 }, + { "part": "torso", "ignored": 10 } + ], + "armor": [ + { + "parts": [ "torso", "head", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r", "mouth" ], + "cut": 1 + } + ], + "category": [ "CHIMERA" ], + "types": [ "SKIN" ], + "prereqs": [ "SKIN_ROUGH" ], + "changes_to": [ "PATCHSKIN2" ] + }, + { + "type": "mutation", + "id": "PATCHSKIN2", + "name": { "str": "Thickened Patchwork Skin" }, + "points": 4, + "visibility": 10, + "ugliness": 8, + "bodytemp_modifiers": [ 250, 500 ], + "bodytemp_sleep": 100, + "description": "Your skin has mutated into an amalgamation of thickened fur and scales.", + "movecost_swim_modifier": 0.9, + "wet_protection": [ + { "part": "head", "ignored": 3 }, + { "part": "leg_l", "ignored": 10 }, + { "part": "leg_r", "ignored": 10 }, + { "part": "foot_l", "ignored": 3 }, + { "part": "foot_r", "ignored": 3 }, + { "part": "arm_l", "ignored": 9 }, + { "part": "arm_r", "ignored": 9 }, + { "part": "hand_l", "ignored": 2 }, + { "part": "hand_r", "ignored": 2 }, + { "part": "torso", "ignored": 20 } + ], + "armor": [ + { + "parts": [ "torso", "head", "arm_l", "arm_r", "hand_l", "hand_r", "leg_l", "leg_r", "foot_l", "foot_r", "mouth" ], + "cut": 2 + } + ], + "category": [ "CHIMERA" ], + "types": [ "SKIN" ], + "prereqs": [ "PATCHSKIN1" ] + }, { "type": "mutation", "id": "CHITIN", @@ -4194,7 +4261,7 @@ "prereqs": [ "STR_UP", "STR_UP_2", "STR_UP_3", "STR_UP_4" ], "cancels": [ "SMALL", "SMALL2" ], "changes_to": [ "LARGE_OK", "HUGE" ], - "category": [ "URSINE", "CATTLE", "LIZARD" ], + "category": [ "URSINE", "CATTLE", "LIZARD", "CHIMERA" ], "passive_mods": { "str_mod": 2 }, "stomach_size_multiplier": 1.5, "weight_capacity_modifier": 1.05 @@ -4210,10 +4277,10 @@ "prereqs": [ "LARGE" ], "prereqs2": [ "STR_UP", "STR_UP_2", "STR_UP_3", "STR_UP_4" ], "cancels": [ "SMALL", "SMALL2" ], - "threshreq": [ "THRESH_URSINE", "THRESH_CATTLE", "THRESH_LIZARD" ], + "threshreq": [ "THRESH_URSINE", "THRESH_CATTLE", "THRESH_LIZARD", "THRESH_CHIMERA" ], "changes_to": [ "HUGE" ], "leads_to": [ "MUT_TOUGH" ], - "category": [ "URSINE", "CATTLE", "LIZARD" ], + "category": [ "URSINE", "CATTLE", "LIZARD", "CHIMERA" ], "passive_mods": { "str_mod": 2 }, "stomach_size_multiplier": 1.5, "weight_capacity_modifier": 1.05 From 8d81a7e879398a9202c8eb7468d8ca27787ae592 Mon Sep 17 00:00:00 2001 From: Saicchi <47158232+Saicchi@users.noreply.github.com> Date: Fri, 9 Jul 2021 03:23:04 -0300 Subject: [PATCH 089/116] allow vehicle change shape (#48477) Co-authored-by: Saicchi --- data/raw/keybindings.json | 7 +++ src/veh_interact.cpp | 116 +++++++++++++++++++++++++++++++++++++- src/veh_interact.h | 1 + src/vehicle.h | 2 + 4 files changed, 125 insertions(+), 1 deletion(-) diff --git a/data/raw/keybindings.json b/data/raw/keybindings.json index 6756fa7251fcc..a0e9bec885d4d 100644 --- a/data/raw/keybindings.json +++ b/data/raw/keybindings.json @@ -1399,6 +1399,13 @@ "name": "Change tire", "bindings": [ { "input_method": "keyboard_any", "key": "c" } ] }, + { + "type": "keybinding", + "id": "CHANGE_SHAPE", + "category": "VEH_INTERACT", + "name": "Change part shape", + "bindings": [ { "input_method": "keyboard_any", "key": "p" } ] + }, { "type": "keybinding", "id": "ASSIGN_CREW", diff --git a/src/veh_interact.cpp b/src/veh_interact.cpp index 8c207deaf0172..0d898ab17b410 100644 --- a/src/veh_interact.cpp +++ b/src/veh_interact.cpp @@ -235,6 +235,7 @@ veh_interact::veh_interact( vehicle &veh, const point &p ) main_context.register_action( "RENAME" ); main_context.register_action( "SIPHON" ); main_context.register_action( "UNLOAD" ); + main_context.register_action( "CHANGE_SHAPE" ); main_context.register_action( "ASSIGN_CREW" ); main_context.register_action( "RELABEL" ); main_context.register_action( "PREV_TAB" ); @@ -495,6 +496,9 @@ void veh_interact::do_main_loop() if( veh->handle_potential_theft( dynamic_cast( player_character ) ) ) { finish = do_unload(); } + } else if( action == "CHANGE_SHAPE" ) { + // purely comestic + do_change_shape(); } else if( action == "ASSIGN_CREW" ) { if( owned_by_player ) { do_assign_crew(); @@ -670,6 +674,9 @@ task_reason veh_interact::cant_do( char mode ) return e.part().is_seat(); } ) ? task_reason::CAN_DO : task_reason::INVALID_TARGET; + case 'p': + // change part shape + // intentional fall-through case 'a': // relabel valid_target = cpart >= 0; @@ -1937,6 +1944,110 @@ bool veh_interact::do_unload() return true; } +void veh_interact::do_change_shape() +{ + if( cant_do( 'p' ) == task_reason::INVALID_TARGET ) { + msg = _( "No valid vehicle parts here." ); + return; + } + + restore_on_out_of_scope> prev_title( title ); + title = _( "Choose part to change shape:" ); + + shared_ptr_fast current_ui = create_or_get_ui_adaptor(); + restore_on_out_of_scope prev_hilight_part( highlight_part ); + + int part_selected = 0; + + while( true ) { + vehicle_part &part = veh->part( parts_here[part_selected] ); + sel_vpart_info = &part.info(); + + highlight_part = part_selected; + overview_enable = [this, part_selected]( const vehicle_part & pt ) { + return &pt == &veh->part( part_selected ); + }; + + ui_manager::redraw(); + const std::string action = main_context.handle_input(); + + if( action == "QUIT" ) { + break; + } else if( action == "CONFIRM" || action == "CHANGE_SHAPE" ) { + using v_shapes = std::vector>; + const v_shapes &shapes = vpart_shapes[ sel_vpart_info->name() + sel_vpart_info->base_item.str() ]; + if( shapes.empty() ) { + break; + } + + uilist smenu; + smenu.text = _( "Choose shape:" ); + smenu.w_width_setup = [this]() { + return getmaxx( w_list ); + }; + smenu.w_x_setup = [this]( const int ) { + return getbegx( w_list ); + }; + smenu.w_y_setup = [this]( const int ) { + return getbegy( w_list ); + }; + + int ret_code = 0; + int default_selection = 0; + std::vector variants; + for( const vpart_info *const shape : shapes ) { + uilist_entry entry( shape->name() ); + entry.retval = ret_code++; + entry.extratxt.left = 1; + entry.extratxt.sym = special_symbol( shape->sym ); + entry.extratxt.color = shape->color; + variants.emplace_back( std::string() ); + smenu.entries.emplace_back( entry ); + } + + for( const std::pair &vp_variant : sel_vpart_info->symbols ) { + std::string disp_name = sel_vpart_info->name(); + // getting all the available shape variants from vpart_variants + std::size_t variants_offset = 0; + for( const std::pair &vp_variant_pair : vpart_variants ) { + if( vp_variant_pair.first == vp_variant.first ) { + disp_name += " " + vp_variant_pair.second; + variants.emplace_back( vp_variant.first ); + if( vp_variant.first == part.variant ) { + default_selection = ret_code; + } + break; + } + variants_offset += 1; + } + uilist_entry entry( disp_name ); + entry.retval = ret_code++; + entry.extratxt.left = 1; + entry.extratxt.sym = special_symbol( vp_variant.second ); + entry.extratxt.color = sel_vpart_info->color; + smenu.entries.emplace_back( entry ); + } + sort_uilist_entries_by_line_drawing( smenu.entries ); + + // get default selection after sorting + for( std::size_t i = 0; i < smenu.entries.size(); ++i ) { + if( smenu.entries[i].retval == default_selection ) { + default_selection = i; + break; + } + } + + smenu.selected = default_selection; + smenu.query(); + if( smenu.ret >= 0 ) { + part.variant = variants[smenu.ret]; + } + } else { + move_in_list( part_selected, action, parts_here.size() ); + } + } +} + void veh_interact::do_assign_crew() { if( cant_do( 'w' ) != task_reason::CAN_DO ) { @@ -2629,7 +2740,7 @@ void veh_interact::display_mode() // NOLINTNEXTLINE(cata-use-named-point-constants) print_colored_text( w_mode, point( 1, 0 ), title_col, title_col, title.value() ); } else { - constexpr size_t action_cnt = 11; + constexpr size_t action_cnt = 12; const std::array actions = { { veh_act_desc( main_context, "INSTALL", pgettext( "veh_interact", "install" ), @@ -2655,6 +2766,9 @@ void veh_interact::display_mode() veh_act_desc( main_context, "ASSIGN_CREW", pgettext( "veh_interact", "crew" ), cant_do( 'w' ) ), + veh_act_desc( main_context, "CHANGE_SHAPE", + pgettext( "veh_interact", "shape" ), + cant_do( 'p' ) ), veh_act_desc( main_context, "RENAME", pgettext( "veh_interact", "rename" ), task_reason::CAN_DO ), diff --git a/src/veh_interact.h b/src/veh_interact.h index d1f76d1aad1ef..2c0fc2daf2c88 100644 --- a/src/veh_interact.h +++ b/src/veh_interact.h @@ -162,6 +162,7 @@ class veh_interact void do_siphon(); // Returns true if exiting the screen bool do_unload(); + void do_change_shape(); void do_assign_crew(); void do_relabel(); /*@}*/ diff --git a/src/vehicle.h b/src/vehicle.h index 673db9febd9bf..8e02f878f8d27 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -459,9 +459,11 @@ struct vehicle_part { private: /** What type of part is this? */ vpart_id id; + public: /** If it's a part with variants, which variant it is */ std::string variant; + private: /** As a performance optimization we cache the part information here on first lookup */ mutable const vpart_info *info_cache = nullptr; From 03b07a8be7e8cd07a5ef09e3b75a7efd16cc61b3 Mon Sep 17 00:00:00 2001 From: John Bytheway <52664+jbytheway@users.noreply.github.com> Date: Fri, 9 Jul 2021 02:27:46 -0400 Subject: [PATCH 090/116] Parametric mapgen part 1: global random terrain selection (#48529) * Allow access to JsonArray members as JsonValue * Create load_weighted_list function This is a generic function for loading a weighted_list from json that can be used to reduce code duplication and ensure json consistency. * Remove undefined declaration This function had no definition and no callers. * Implement "parameters" for mapgen This is an initial implementation of parameters for mapgen, which currently has those parameters act more like variables than parameters. Essentially all it currently permits is to choose a terrain at random and use that in a palette. Thus choosing a thing at random which applies to an entire map, rather than choosing at random on a per-tile basis. This is the first step towards true parameters for mapgen; hence the currently-misleading name. * Add docs for new parameters feature. * Minor grammar/style fixes Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> --- data/json/mapgen/house/crack_house.json | 8 +- doc/MAPGEN.md | 55 +++++ src/json.cpp | 6 + src/json.h | 1 + src/magic_ter_fur_transform.cpp | 9 +- src/mapgen.cpp | 313 +++++++++++++++++++----- src/mapgen.h | 29 ++- src/mapgendata.cpp | 7 + src/mapgendata.h | 19 ++ src/weighted_list.h | 19 +- 10 files changed, 392 insertions(+), 74 deletions(-) diff --git a/data/json/mapgen/house/crack_house.json b/data/json/mapgen/house/crack_house.json index e68ebdc45a20f..6620f98553c1f 100644 --- a/data/json/mapgen/house/crack_house.json +++ b/data/json/mapgen/house/crack_house.json @@ -106,8 +106,14 @@ " ", " " ], + "parameters": { + "roof_type": { + "type": "ter_str_id", + "default": { "distribution": [ [ "t_flat_roof", 2 ], [ "t_tar_flat_roof", 1 ], [ "t_shingle_flat_roof", 1 ] ] } + } + }, "palettes": [ "roof_palette" ], - "terrain": { ".": "t_shingle_flat_roof" } + "terrain": { ".": { "param": "roof_type" } } } }, { diff --git a/doc/MAPGEN.md b/doc/MAPGEN.md index 999ae42e5c12c..d2706f0718e35 100644 --- a/doc/MAPGEN.md +++ b/doc/MAPGEN.md @@ -49,6 +49,8 @@ * [Place a zone for an NPC faction with "zones"](#place-a-zone-for-an-npc-faction-with-zones) * [Translate terrain type with "translate_ter"](#translate-terrain-type-with-translate_ter) * [Apply mapgen transformation with "ter_furn_transforms"](#apply-mapgen-transformation-with-ter_furn_transforms) + * [Mapgen values](#mapgen-values) + * [Mapgen parameters](#mapgen-parameters) * [Rotate the map with "rotation"](#rotate-the-map-with-rotation) * [Pre-load a base mapgen with "predecessor_mapgen"](#pre-load-a-base-mapgen-with-predecessor_mapgen) * [Using update_mapgen](#using-update_mapgen) @@ -1037,6 +1039,59 @@ an `update_mapgen`, as normal mapgen can just specify the terrain directly. - "transform": (required, string) the id of the `ter_furn_transform` to run. +## Mapgen values + +A *mapgen value* can be used in various places where a specific id is expected. +For example, the default value of a parameter, or a terrain id in the +`"terrain"` object. A mapgen value can take one of three forms: + +* A simple string, which should be a literal id. For example, `"t_flat_roof"`. +* A JSON object containing the key `"distribution"`, whose corresponding value + is a list of lists, each a pair of a string id and an integer weight. For + example: +``` +{ "distribution": [ [ "t_flat_roof", 2 ], [ "t_tar_flat_roof", 1 ], [ "t_shingle_flat_roof", 1 ] ] } +``` +* A JSON object containing the key `"param"`, whose corresponding value is the + string name of a parameter as discussed in [Mapgen + parameters](#mapgen-parameters). For example, `{ "param": "roof_type" }`. + + +## Mapgen parameters + +(Note that this feature is under development and functionality may not line up exactly +with the documentation.) + +Another entry within a mapgen definition can be a `"parameters"` key. For +example: +``` +"parameters": { + "roof_type": { + "type": "ter_str_id", + "default": { "distribution": [ [ "t_flat_roof", 2 ], [ "t_tar_flat_roof", 1 ], [ "t_shingle_flat_roof", 1 ] ] } + } +}, +``` + +Each entry in the `"parameters"` JSON object defines a parameter. The key is +the parameter name. Each such key should have an associated JSON object. That +object must provide its type (which should be a type string as for a +`cata_variant`) and may optionally provide a default value. The default value +should be a [mapgen value](#mapgen-value) as defined above. + +At time of writing, the only way for a parameter to get a value is via the +`"default"`, so you probably want to always have one. + +The primary application of parameters is that you can use a `"distribution"` +mapgen value to select a value at random, and then apply that value to every +use of that parameter. In the above example, a random roof terrain is picked. +By using the parameter with some `"terrain"` key, via a `"param"` mapgen value, +you can use a random but consistent choice of roof terrain across your map. +In contrast, placing the `"distribution"` directly in the `"terrain"` object would +cause mapgen to choose a terrain at random for each roof tile, leading to a +mishmash of roof terrains. + + ## Rotate the map with "rotation" Rotates the generated map after all the other mapgen stuff has been done. The value can be a single integer or a range diff --git a/src/json.cpp b/src/json.cpp index b6657d2301cc6..335e59c97d35a 100644 --- a/src/json.cpp +++ b/src/json.cpp @@ -539,6 +539,12 @@ void JsonArray::verify_index( const size_t i ) const /* iterative access */ +JsonValue JsonArray::next() +{ + verify_index( index ); + return JsonValue( *jsin, positions[index++] ); +} + bool JsonArray::next_bool() { verify_index( index ); diff --git a/src/json.h b/src/json.h index f192a81828c87..72b43490c1c4c 100644 --- a/src/json.h +++ b/src/json.h @@ -1172,6 +1172,7 @@ class JsonArray [[noreturn]] void string_error( const std::string &err, int idx, int offset ); // iterative access + JsonValue next(); bool next_bool(); int next_int(); double next_float(); diff --git a/src/magic_ter_fur_transform.cpp b/src/magic_ter_fur_transform.cpp index bcba357af1724..fede13ce565a1 100644 --- a/src/magic_ter_fur_transform.cpp +++ b/src/magic_ter_fur_transform.cpp @@ -64,14 +64,7 @@ static void load_transform_results( const JsonObject &jsi, const std::string &js list.add( T( jsi.get_string( json_key ) ), 1 ); return; } - for( const JsonValue entry : jsi.get_array( json_key ) ) { - if( entry.test_array() ) { - JsonArray inner = entry.get_array(); - list.add( T( inner.get_string( 0 ) ), inner.get_int( 1 ) ); - } else { - list.add( T( entry.get_string() ), 1 ); - } - } + load_weighted_list( jsi.get_member( json_key ), list, 1 ); } template diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 22a2f854dabd0..b0faf9718836b 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -67,6 +67,7 @@ #include "submap.h" #include "text_snippets.h" #include "tileray.h" +#include "to_string_id.h" #include "translations.h" #include "trap.h" #include "units.h" @@ -779,6 +780,16 @@ void mapgen_function_json_base::setup_setmap( const JsonArray &parray ) } +std::unordered_map +mapgen_function_json_base::get_param_values( const mapgendata &md ) const +{ + std::unordered_map result; + for( const std::pair ¶m : parameters ) { + result.emplace( param.first, param.second.get( md ) ); + } + return result; +} + jmapgen_place::jmapgen_place( const JsonObject &jsi ) : x( jsi, "x" ) , y( jsi, "y" ) @@ -808,6 +819,168 @@ map_key::map_key( const JsonMember &member ) : str( member.name() ) } } +template +static bool is_null_helper( const string_id &id ) +{ + return id.is_null(); +} + +template +static bool is_null_helper( const int_id &id ) +{ + return id.id().is_null(); +} + +static bool is_null_helper( const std::string & ) +{ + return false; +} + +template +static bool is_valid_helper( const string_id &id ) +{ + return id.is_valid(); +} + +static bool is_valid_helper( const std::string & ) +{ + return true; +} + +// Mapgen often uses various id values. Usually these are specified verbatim +// as strings, but they can also be parameterized. This class encapsulates +// such a value. It records how the value was specified so that it can be +// calculated later based on the parameters chosen for a particular instance of +// the mapgen. +template +class mapgen_value +{ + public: + using StringId = to_string_id_t; + + struct value_source { + virtual ~value_source() = default; + virtual Id get( const mapgendata & ) const = 0; + virtual void check( const std::string &/*oter_name*/, + const std::unordered_map & + ) const {}; + }; + + struct id_source : value_source { + Id id; + + explicit id_source( const std::string &s ) : + id( s ) { + } + + Id get( const mapgendata & ) const override { + return id; + } + }; + + struct param_source : value_source { + std::string param_name; + + explicit param_source( const JsonObject &jo ) : + param_name( jo.get_string( "param" ) ) { + } + + Id get( const mapgendata &dat ) const override { + return Id( dat.get_param( param_name ) ); + } + + void check( const std::string &oter_name, + const std::unordered_map ¶meters + ) const override { + auto param = parameters.find( param_name ); + if( param == parameters.end() ) { + debugmsg( "mapgen '%s' uses undefined parameter '%s'", oter_name, param_name ); + } else { + constexpr cata_variant_type req_type = cata_variant_type_for(); + cata_variant_type param_type = param->second.type(); + if( param_type != req_type ) { + debugmsg( "mapgen '%s' uses parameter '%s' of type '%s' in a context " + "expecting type '%s'", oter_name, param_name, + io::enum_to_string( param_type ), + io::enum_to_string( req_type ) ); + } + } + } + }; + + struct distribution_source : value_source { + weighted_int_list list; + + explicit distribution_source( const JsonObject &jo ) { + load_weighted_list( jo.get_member( "distribution" ), list, 1 ); + } + + Id get( const mapgendata & ) const override { + return *list.pick(); + } + + void check( const std::string &oter_name, + const std::unordered_map & ) const override { + for( const weighted_object &wo : list ) { + if( !is_valid_helper( wo.obj ) ) { + debugmsg( "mapgen '%s' uses invalid entry '%s' in weighted list", + oter_name, cata_variant( wo.obj ).get_string() ); + } + } + } + }; + + explicit mapgen_value( const JsonValue &jv ) { + if( jv.test_string() ) { + std::string id = jv.get_string(); + source_ = make_shared_fast( id ); + is_null_ = is_null_helper( id ); + } else { + JsonObject jo = jv.get_object(); + if( jo.has_member( "param" ) ) { + source_ = make_shared_fast( jo ); + } else if( jo.has_member( "distribution" ) ) { + source_ = make_shared_fast( jo ); + } else { + jo.throw_error( R"(Expected member "param" or "distribution" in object)" ); + } + } + } + + bool is_null() const { + return is_null_; + } + + void check( const std::string &oter_name, + const std::unordered_map ¶ms ) const { + source_->check( oter_name, params ); + } + + Id get( const mapgendata &dat ) const { + return source_->get( dat ); + } + private: + bool is_null_ = false; + shared_ptr_fast source_; +}; + +void mapgen_parameter::deserialize( JsonIn &jsin ) +{ + JsonObject jo = jsin.get_object(); + jo.read( "type", type_, true ); + default_ = std::make_unique>( jo.get_member( "default" ) ); +} + +cata_variant_type mapgen_parameter::type() const +{ + return type_; +} + +cata_variant mapgen_parameter::get( const mapgendata &md ) const +{ + return cata_variant::from_string( type_, default_->get( md ) ); +} + /** * This is a generic mapgen piece, the template parameter PieceType should be another specific * type of jmapgen_piece. This class contains a vector of those objects and will chose one of @@ -1481,16 +1654,19 @@ class jmapgen_trap : public jmapgen_piece trap_id id; jmapgen_trap( const JsonObject &jsi, const std::string &/*context*/ ) : id( 0 ) { - const trap_str_id sid( jsi.get_string( "trap" ) ); - if( !sid.is_valid() ) { - set_mapgen_defer( jsi, "trap", "no such trap" ); - } - id = sid.id(); + init( jsi ); } - explicit jmapgen_trap( const std::string &tid ) : + explicit jmapgen_trap( const JsonValue &tid ) : id( 0 ) { - const trap_str_id sid( tid ); + if( tid.test_object() ) { + JsonObject jo = tid.get_object(); + if( jo.has_member( "trap" ) ) { + init( jo ); + return; + } + } + const trap_str_id sid( tid.get_string() ); if( !sid.is_valid() ) { throw std::runtime_error( "unknown trap type" ); } @@ -1504,6 +1680,14 @@ class jmapgen_trap : public jmapgen_piece bool has_vehicle_collision( const mapgendata &dat, const point &p ) const override { return dat.m.veh_at( tripoint( p, dat.zlevel() ) ).has_value(); } + private: + void init( const JsonObject &jsi ) { + const trap_str_id sid( jsi.get_string( "trap" ) ); + if( !sid.is_valid() ) { + set_mapgen_defer( jsi, "trap", "no such trap" ); + } + id = sid.id(); + } }; /** * Place a furniture. @@ -1514,8 +1698,8 @@ class jmapgen_furniture : public jmapgen_piece public: furn_id id; jmapgen_furniture( const JsonObject &jsi, const std::string &/*context*/ ) : - jmapgen_furniture( jsi.get_string( "furn" ) ) {} - explicit jmapgen_furniture( const std::string &fid ) : id( furn_id( fid ) ) {} + jmapgen_furniture( jsi.get_member( "furn" ) ) {} + explicit jmapgen_furniture( const JsonValue &fid ) : id( furn_id( fid.get_string() ) ) {} void apply( const mapgendata &dat, const jmapgen_int &x, const jmapgen_int &y ) const override { dat.m.furn_set( point( x.get(), y.get() ), id ); @@ -1531,18 +1715,22 @@ class jmapgen_furniture : public jmapgen_piece class jmapgen_terrain : public jmapgen_piece { public: - ter_id id; + mapgen_value id; jmapgen_terrain( const JsonObject &jsi, const std::string &/*context*/ ) : - jmapgen_terrain( jsi.get_string( "ter" ) ) {} - explicit jmapgen_terrain( const std::string &tid ) : id( ter_id( tid ) ) {} + jmapgen_terrain( jsi.get_member( "ter" ) ) {} + explicit jmapgen_terrain( const JsonValue &tid ) : id( mapgen_value( tid ) ) {} bool is_nop() const override { - return id.id().is_null(); + return id.is_null(); } void apply( const mapgendata &dat, const jmapgen_int &x, const jmapgen_int &y ) const override { - dat.m.ter_set( point( x.get(), y.get() ), id ); + ter_id chosen_id = id.get( dat ); + if( chosen_id.id().is_null() ) { + return; + } + dat.m.ter_set( point( x.get(), y.get() ), chosen_id ); // Delete furniture if a wall was just placed over it. TODO: need to do anything for fluid, monsters? if( dat.m.has_flag_ter( "WALL", point( x.get(), y.get() ) ) ) { dat.m.furn_set( point( x.get(), y.get() ), f_null ); @@ -1555,6 +1743,12 @@ class jmapgen_terrain : public jmapgen_piece bool has_vehicle_collision( const mapgendata &dat, const point &p ) const override { return dat.m.veh_at( tripoint( p, dat.zlevel() ) ).has_value(); } + + void check( const std::string &oter_name, + const std::unordered_map ¶meters + ) const override { + id.check( oter_name, parameters ); + } }; /** * Run a transformation. @@ -1683,7 +1877,8 @@ class jmapgen_sealed_item : public jmapgen_piece } } - void check( const std::string &context ) const override { + void check( const std::string &context, + const std::unordered_map & ) const override { const furn_t &furn = furniture.obj(); std::string summary = string_format( @@ -1834,19 +2029,6 @@ class jmapgen_zone : public jmapgen_piece } }; -static void load_weighted_entries( const JsonObject &jsi, const std::string &json_key, - weighted_int_list &list ) -{ - for( const JsonValue entry : jsi.get_array( json_key ) ) { - if( entry.test_array() ) { - JsonArray inner = entry.get_array(); - list.add( inner.get_string( 0 ), inner.get_int( 1 ) ); - } else { - list.add( entry.get_string(), 100 ); - } - } -} - /** * Calls another mapgen call inside the current one. * Note: can't use regular overmap ids. @@ -1914,8 +2096,12 @@ class jmapgen_nested : public jmapgen_piece neighborhood_check neighbors; jmapgen_nested( const JsonObject &jsi, const std::string &/*context*/ ) : neighbors( jsi.get_object( "neighbors" ) ) { - load_weighted_entries( jsi, "chunks", entries ); - load_weighted_entries( jsi, "else_chunks", else_entries ); + if( jsi.has_member( "chunks" ) ) { + load_weighted_list( jsi.get_member( "chunks" ), entries, 100 ); + } + if( jsi.has_member( "else_chunks" ) ) { + load_weighted_list( jsi.get_member( "else_chunks" ), else_entries, 100 ); + } } void apply( const mapgendata &dat, const jmapgen_int &x, const jmapgen_int &y ) const override { @@ -2074,20 +2260,18 @@ void load_place_mapings_string( const JsonValue &value, mapgen_palette::placing_map::mapped_type &vect, const std::string &context ) { - if( value.test_string() ) { + if( value.test_string() || value.test_object() ) { try { - vect.push_back( make_shared_fast( value.get_string() ) ); + vect.push_back( make_shared_fast( value ) ); } catch( const std::runtime_error &err ) { // Using the json object here adds nice formatting and context information value.throw_error( err.what() ); } - } else if( value.test_object() ) { - load_place_mapings( value.get_object(), vect, context ); } else { for( const JsonValue entry : value.get_array() ) { if( entry.test_string() ) { try { - vect.push_back( make_shared_fast( entry.get_string() ) ); + vect.push_back( make_shared_fast( entry ) ); } catch( const std::runtime_error &err ) { // Using the json object here adds nice formatting and context information entry.throw_error( err.what() ); @@ -2115,7 +2299,7 @@ void load_place_mapings_alternatively( for( const JsonValue entry : value.get_array() ) { if( entry.test_string() ) { try { - alter->alternatives.emplace_back( entry.get_string() ); + alter->alternatives.emplace_back( entry ); } catch( const std::runtime_error &err ) { // Using the json object here adds nice formatting and context information entry.throw_error( err.what() ); @@ -2131,15 +2315,12 @@ void load_place_mapings_alternatively( } // Test if this is a string or object, and then just emplace it. - if( piece_and_count_jarr.test_string() ) { + if( piece_and_count_jarr.test_string() || piece_and_count_jarr.test_object() ) { try { - alter->alternatives.emplace_back( piece_and_count_jarr.next_string() ); + alter->alternatives.emplace_back( piece_and_count_jarr.next() ); } catch( const std::runtime_error &err ) { piece_and_count_jarr.throw_error( err.what() ); } - } else if( piece_and_count_jarr.test_object() ) { - JsonObject jsi = piece_and_count_jarr.next_object(); - alter->alternatives.emplace_back( jsi, context ); } else { piece_and_count_jarr.throw_error( "First entry must be a string or object." ); } @@ -2219,7 +2400,9 @@ void mapgen_palette::check() for( const std::pair>> &p : format_placings ) { for( const shared_ptr_fast &j : p.second ) { - j->check( context ); + // TODO: palettes should have their own parameters, but don't as + // yet + j->check( context, {} ); } } } @@ -2448,6 +2631,8 @@ bool mapgen_function_json_base::setup_common( const JsonObject &jo ) JsonArray sparray; JsonObject pjo; + jo.read( "parameters", parameters ); + // just like mapf::basic_bind("stuff",blargle("foo", etc) ), only json input and faster when applying if( jo.has_array( "rows" ) ) { mapgen_palette palette = mapgen_palette::load_temp( jo, "dda" ); @@ -2600,13 +2785,14 @@ void mapgen_function_json_base::check_common() const } } - objects.check( context_ ); + objects.check( context_, parameters ); } -void jmapgen_objects::check( const std::string &context ) const +void jmapgen_objects::check( const std::string &context, + const std::unordered_map ¶meters ) const { for( const jmapgen_obj &obj : objects ) { - obj.second->check( context ); + obj.second->check( context, parameters ); } } @@ -2767,8 +2953,8 @@ bool jmapgen_setmap::has_vehicle_collision( const mapgendata &dat, const point & return false; } -bool mapgen_function_json_base::has_vehicle_collision( const mapgendata &dat, - const point &offset ) const +bool mapgen_function_json_base::has_vehicle_collision( + const mapgendata &dat, const point &offset ) const { for( const jmapgen_setmap &elem : setmap_points ) { if( elem.has_vehicle_collision( dat, offset ) ) { @@ -2806,13 +2992,16 @@ void mapgen_function_json::generate( mapgendata &md ) m->rotate( ( -static_cast( md.terrain_type()->get_dir() ) + 4 ) % 4 ); } } + + mapgendata md_with_params( md, get_param_values( md ) ); + for( auto &elem : setmap_points ) { - elem.apply( md, point_zero ); + elem.apply( md_with_params, point_zero ); } - objects.apply( md, point_zero ); + objects.apply( md_with_params, point_zero ); - resolve_regional_terrain_and_furniture( md ); + resolve_regional_terrain_and_furniture( md_with_params ); m->rotate( rotation.get() ); @@ -2821,18 +3010,20 @@ void mapgen_function_json::generate( mapgendata &md ) } } -void mapgen_function_json_nested::nest( const mapgendata &dat, const point &offset ) const +void mapgen_function_json_nested::nest( const mapgendata &md, const point &offset ) const { // TODO: Make rotation work for submaps, then pass this value into elem & objects apply. //int chosen_rotation = rotation.get() % 4; + mapgendata md_with_params( md, get_param_values( md ) ); + for( const jmapgen_setmap &elem : setmap_points ) { - elem.apply( dat, offset ); + elem.apply( md, offset ); } - objects.apply( dat, offset ); + objects.apply( md, offset ); - resolve_regional_terrain_and_furniture( dat ); + resolve_regional_terrain_and_furniture( md ); } /* @@ -5996,6 +6187,8 @@ bool update_mapgen_function_json::update_map( const tripoint_abs_omt &omt_pos, c bool update_mapgen_function_json::update_map( const mapgendata &md, const point &offset, const bool verify ) const { + mapgendata md_with_params( md, get_param_values( md ) ); + class rotation_guard { public: @@ -6019,21 +6212,21 @@ bool update_mapgen_function_json::update_map( const mapgendata &md, const point const mapgendata &md; const int rotation; }; - rotation_guard rot( md ); + rotation_guard rot( md_with_params ); for( const jmapgen_setmap &elem : setmap_points ) { - if( verify && elem.has_vehicle_collision( md, offset ) ) { + if( verify && elem.has_vehicle_collision( md_with_params, offset ) ) { return false; } - elem.apply( md, offset ); + elem.apply( md_with_params, offset ); } - if( verify && objects.has_vehicle_collision( md, offset ) ) { + if( verify && objects.has_vehicle_collision( md_with_params, offset ) ) { return false; } - objects.apply( md, offset ); + objects.apply( md_with_params, offset ); - resolve_regional_terrain_and_furniture( md ); + resolve_regional_terrain_and_furniture( md_with_params ); return true; } diff --git a/src/mapgen.h b/src/mapgen.h index 34616459af352..6ee65da7a95ce 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -12,6 +12,7 @@ #include #include +#include "cata_variant.h" #include "coordinates.h" #include "json.h" #include "memory_fast.h" @@ -21,6 +22,7 @@ #include "weighted_list.h" class map; +template class mapgen_value; class mapgendata; class mission; @@ -134,6 +136,20 @@ struct spawn_data { std::vector patrol_points_rel_ms; }; +class mapgen_parameter +{ + public: + void deserialize( JsonIn & ); + + cata_variant_type type() const; + cata_variant get( const mapgendata &md ) const; + private: + cata_variant_type type_; + // Using a pointer here mostly to move the definition of mapgen_value to the + // cpp file + std::shared_ptr> default_; +}; + /** * Basic mapgen object. It is supposed to place or do something on a specific square on the map. * Inherit from this class and implement the @ref apply function. @@ -164,7 +180,8 @@ class jmapgen_piece return false; } /** Sanity-check this piece */ - virtual void check( const std::string &/*context*/ ) const { } + virtual void check( const std::string &/*context*/, + const std::unordered_map & ) const { } /** Place something on the map from mapgendata &dat, at (x,y). */ virtual void apply( const mapgendata &dat, const jmapgen_int &x, const jmapgen_int &y ) const = 0; @@ -222,6 +239,7 @@ class mapgen_palette { public: palette_id id; + /** * The mapping from character (key) to a list of things that should be placed. This is * similar to objects, but it uses key to get the actual position where to place things @@ -296,7 +314,8 @@ struct jmapgen_objects { void load_objects( const JsonObject &jsi, const std::string &member_name, const std::string &context ); - void check( const std::string &context ) const; + void check( const std::string &context, + const std::unordered_map & ) const; void apply( const mapgendata &dat ) const; void apply( const mapgendata &dat, const point &offset ) const; @@ -328,6 +347,7 @@ class mapgen_function_json_base json_source_location jsrcloc; std::string context_; + std::unordered_map parameters; protected: mapgen_function_json_base( const json_source_location &jsrcloc, const std::string &context ); virtual ~mapgen_function_json_base(); @@ -341,6 +361,9 @@ class mapgen_function_json_base void check_common() const; + std::unordered_map + get_param_values( const mapgendata &md ) const; + bool is_ready; point mapgensize; @@ -397,7 +420,7 @@ class mapgen_function_json_nested : public mapgen_function_json_base mapgen_function_json_nested( const json_source_location &jsrcloc, const std::string &context ); ~mapgen_function_json_nested() override = default; - void nest( const mapgendata &dat, const point &offset ) const; + void nest( const mapgendata &md, const point &offset ) const; protected: bool setup_internal( const JsonObject &jo ) override; diff --git a/src/mapgendata.cpp b/src/mapgendata.cpp index 461111506954a..3610e4fa759fe 100644 --- a/src/mapgendata.cpp +++ b/src/mapgendata.cpp @@ -46,6 +46,13 @@ mapgendata::mapgendata( const mapgendata &other, const oter_id &other_id ) : map terrain_type_ = other_id; } +mapgendata::mapgendata( const mapgendata &other, + const std::unordered_map &mapgen_params ) : + mapgendata( other ) +{ + mapgen_params_ = mapgen_params; +} + void mapgendata::set_dir( int dir_in, int val ) { switch( dir_in ) { diff --git a/src/mapgendata.h b/src/mapgendata.h index 19d8973412078..c109aa3228d86 100644 --- a/src/mapgendata.h +++ b/src/mapgendata.h @@ -3,7 +3,9 @@ #define CATA_SRC_MAPGENDATA_H #include "calendar.h" +#include "cata_variant.h" #include "coordinates.h" +#include "json.h" #include "type_id.h" #include "weighted_list.h" @@ -40,6 +42,7 @@ class mapgendata time_point when_; ::mission *mission_; int zlevel_; + std::unordered_map mapgen_params_; public: oter_id t_nesw[8]; @@ -84,6 +87,12 @@ class mapgendata */ mapgendata( const mapgendata &other, const oter_id &other_id ); + /** + * Creates a copy of this mapgendata, but stores new parameter values. + */ + mapgendata( const mapgendata &other, + const std::unordered_map & ); + const oter_id &terrain_type() const { return terrain_type_; } @@ -139,6 +148,16 @@ class mapgendata void square_groundcover( const point &p1, const point &p2 ) const; ter_id groundcover() const; bool is_groundcover( const ter_id &iid ) const; + + template + Result get_param( const std::string &name ) const { + auto it = mapgen_params_.find( name ); + if( it == mapgen_params_.end() ) { + debugmsg( "No such parameter \"%s\"", name ); + return Result(); + } + return it->second.get(); + } }; #endif // CATA_SRC_MAPGENDATA_H diff --git a/src/weighted_list.h b/src/weighted_list.h index 228cf3a519b9b..a8594303a65cf 100644 --- a/src/weighted_list.h +++ b/src/weighted_list.h @@ -2,6 +2,7 @@ #ifndef CATA_SRC_WEIGHTED_LIST_H #define CATA_SRC_WEIGHTED_LIST_H +#include "json.h" #include "rng.h" #include @@ -178,8 +179,6 @@ template struct weighted_list { return objects.empty(); } - void precalc(); - protected: W total_weight; std::vector > objects; @@ -255,4 +254,20 @@ template struct weighted_float_list : public weighted_list +void load_weighted_list( const JsonValue &jsv, weighted_list &list, W default_weight ) +{ + for( const JsonValue entry : jsv.get_array() ) { + if( entry.test_array() ) { + std::pair p; + entry.read( p, true ); + list.add( p.first, p.second ); + } else { + T val; + entry.read( val ); + list.add( val, default_weight ); + } + } +} + #endif // CATA_SRC_WEIGHTED_LIST_H From fb283c6b2266f85212c37ef6daa68eb1c5cc5cd2 Mon Sep 17 00:00:00 2001 From: AccountAlias <85119255+AccountAlias@users.noreply.github.com> Date: Fri, 9 Jul 2021 02:41:23 -0400 Subject: [PATCH 091/116] Allow blocking of some zombie specials (#49703) * Allow blocking of some zombie specials Allow blocking of some zombie specials add dodgeable and blockable flags to monster specials flip dodgeable and blockable defaults * Update data/json/monster_special_attacks/monster_attacks.json Co-authored-by: I-am-Erk <45136638+I-am-Erk@users.noreply.github.com> Co-authored-by: I-am-Erk <45136638+I-am-Erk@users.noreply.github.com> --- .../monster_attacks.json | 16 +- src/mattack_actors.cpp | 39 +++- src/mattack_actors.h | 4 + src/monattack.cpp | 216 ++++++++---------- 4 files changed, 132 insertions(+), 143 deletions(-) diff --git a/data/json/monster_special_attacks/monster_attacks.json b/data/json/monster_special_attacks/monster_attacks.json index 30b1a0a10a571..35642d9c083ea 100644 --- a/data/json/monster_special_attacks/monster_attacks.json +++ b/data/json/monster_special_attacks/monster_attacks.json @@ -11,7 +11,9 @@ "hit_dmg_u": "The %1$s impales your torso!", "hit_dmg_npc": "The %1$s impales 's torso!", "no_dmg_msg_u": "The %1$s tries to impale your torso, but fails to penetrate your armor!", - "no_dmg_msg_npc": "The %1$s tries to impale 's torso, but fails to penetrate their armor!" + "no_dmg_msg_npc": "The %1$s tries to impale 's torso, but fails to penetrate their armor!", + "dodgeable": true, + "blockable": true }, { "type": "monster_attack", @@ -37,7 +39,9 @@ "hit_dmg_u": "The %1$s claws at you!", "hit_dmg_npc": "The %1$s claws at !", "no_dmg_msg_u": "The %1$s claws at your %2$s, but fails to penetrate armor.", - "no_dmg_msg_npc": "The %1$s tries to claw at , but fails to penetrate armor." + "no_dmg_msg_npc": "The %1$s tries to claw at , but fails to penetrate armor.", + "dodgeable": true, + "blockable": true }, { "type": "monster_attack", @@ -63,7 +67,9 @@ "hit_dmg_u": "The %1$s slams into you!", "hit_dmg_npc": "The %1$s slams into !", "no_dmg_msg_u": "The %1$s tries to slam into you, but stumbles aside.", - "no_dmg_msg_npc": "The %1$s tries to slam into , but fails to." + "no_dmg_msg_npc": "The %1$s tries to slam into , but fails to.", + "dodgeable": true, + "blockable": false }, { "type": "monster_attack", @@ -79,7 +85,9 @@ "miss_msg_u": "The %1$s tries to sting you, but you dodge!", "miss_msg_npc": "The %1$s tries to sting , but they dodge!", "no_dmg_msg_u": "The %1$s tries to sting your %2$s, but it fails to penetrate your armor.", - "no_dmg_msg_npc": "The %1$s tries to sting 's %2$s, but it fails to penetrate their armor." + "no_dmg_msg_npc": "The %1$s tries to sting 's %2$s, but it fails to penetrate their armor.", + "dodgeable": true, + "blockable": true }, { "id": "acid_spray", diff --git a/src/mattack_actors.cpp b/src/mattack_actors.cpp index a54ebc7400933..6e4da2281c579 100644 --- a/src/mattack_actors.cpp +++ b/src/mattack_actors.cpp @@ -219,6 +219,8 @@ void melee_actor::load_internal( const JsonObject &obj, const std::string & ) max_mul = obj.get_float( "max_mul", 1.0f ); move_cost = obj.get_int( "move_cost", 100 ); accuracy = obj.get_int( "accuracy", INT_MIN ); + dodgeable = obj.get_bool( "dodgeable", true ); + blockable = obj.get_bool( "blockable", true ); optional( obj, was_loaded, "miss_msg_u", miss_msg_u, to_translation( "The %s lunges at you, but you dodge!" ) ); @@ -274,29 +276,42 @@ bool melee_actor::call( monster &z ) const add_msg_debug( debugmode::DF_MATTACK, "%s attempting to melee_attack %s", z.name(), target->disp_name() ); + // Dodge check const int acc = accuracy >= 0 ? accuracy : z.type->melee_skill; int hitspread = target->deal_melee_attack( &z, dice( acc, 10 ) ); - - if( hitspread < 0 ) { - game_message_type msg_type = target->is_avatar() ? m_warning : m_info; - sfx::play_variant_sound( "mon_bite", "bite_miss", sfx::get_heard_volume( z.pos() ), - sfx::get_heard_angle( z.pos() ) ); - target->add_msg_player_or_npc( msg_type, miss_msg_u, miss_msg_npc, z.name() ); - return true; + if( dodgeable ) { + if( hitspread < 0 ) { + game_message_type msg_type = target->is_avatar() ? m_warning : m_info; + sfx::play_variant_sound( "mon_bite", "bite_miss", sfx::get_heard_volume( z.pos() ), + sfx::get_heard_angle( z.pos() ) ); + target->add_msg_player_or_npc( msg_type, miss_msg_u, miss_msg_npc, z.name() ); + return true; + } } + // Damage instance calculation damage_instance damage = damage_max_instance; - double multiplier = rng_float( min_mul, max_mul ); damage.mult_damage( multiplier ); + // Pick body part bodypart_str_id bp_hit = body_parts.empty() ? target->select_body_part( &z, hitspread ).id() : *body_parts.pick(); - target->on_hit( &z, bp_hit.id() ); - dealt_damage_instance dealt_damage = target->deal_damage( &z, bp_hit.id(), damage ); - dealt_damage.bp_hit = bp_hit.id(); + bodypart_id bp_id = bodypart_id( bp_hit ); + + // Block our hit + if( blockable ) { + target->block_hit( &z, bp_id, damage ); + } + + // Take damage + dealt_damage_instance dealt_damage = target->deal_damage( &z, bp_id, damage ); + dealt_damage.bp_hit = bp_id; + + // On hit effects + target->on_hit( &z, bp_id ); int damage_total = dealt_damage.total_damage(); add_msg_debug( debugmode::DF_MATTACK, "%s's melee_attack did %d damage", z.name(), damage_total ); @@ -306,7 +321,7 @@ bool melee_actor::call( monster &z ) const sfx::play_variant_sound( "mon_bite", "bite_miss", sfx::get_heard_volume( z.pos() ), sfx::get_heard_angle( z.pos() ) ); target->add_msg_player_or_npc( m_neutral, no_dmg_msg_u, no_dmg_msg_npc, z.name(), - body_part_name_accusative( bp_hit.id() ) ); + body_part_name_accusative( bp_id ) ); } return true; diff --git a/src/mattack_actors.h b/src/mattack_actors.h index 575e16cc13aa1..fdb0f09262a97 100644 --- a/src/mattack_actors.h +++ b/src/mattack_actors.h @@ -71,6 +71,10 @@ class melee_actor : public mattack_actor // If non-negative, the attack will use a different accuracy from mon's // regular melee attack. int accuracy = INT_MIN; + // Determines if a special attack can be dodged + bool dodgeable = true; + // Determines if a special attack can be blocked + bool blockable = true; /** * If empty, regular melee roll body part selection is used. diff --git a/src/monattack.cpp b/src/monattack.cpp index 4ea0deadcfa07..8ef440902dcc6 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -630,25 +630,25 @@ bool mattack::acid_barf( monster *z ) z->moves -= 80; // Make sure it happens before uncanny dodge get_map().add_field( target->pos(), fd_acid, 1 ); - bool uncanny = target->uncanny_dodge(); + // Can we dodge the attack? Uses player dodge function % chance (melee.cpp) - if( uncanny || dodge_check( z, target ) ) { + if( dodge_check( z, target ) ) { game_message_type msg_type = target->is_avatar() ? m_warning : m_info; target->add_msg_player_or_npc( msg_type, _( "The %s barfs acid at you, but you dodge!" ), _( "The %s barfs acid at , but they dodge!" ), z->name() ); - if( !uncanny ) { - target->on_dodge( z, z->type->melee_skill ); - } + target->on_dodge( z, z->type->melee_skill ); return true; } - const bodypart_id &hit = target->get_random_body_part(); - int dam = rng( 5, 12 ); - dam = target->deal_damage( z, hit, damage_instance( damage_type::ACID, - dam ) ).total_damage(); + bodypart_id hit = target->get_random_body_part(); + damage_instance dam_inst = damage_instance( damage_type::ACID, rng( 5, 12 ) ); + target->block_hit( z, hit, dam_inst ); + + int dam = target->deal_damage( z, hit, dam_inst ).total_damage(); + target->add_env_effect( effect_corroding, hit, 5, time_duration::from_turns( dam / 2 + 5 ), hit ); if( dam > 0 ) { @@ -1099,15 +1099,12 @@ bool mattack::smash( monster *z ) // Costs lots of moves to give you a little bit of a chance to get away. z->moves -= 400; - if( target->uncanny_dodge() ) { - return true; - } - // Can we dodge the attack? Uses player dodge function % chance (melee.cpp) if( dodge_check( z, target ) ) { target->add_msg_player_or_npc( _( "The %s takes a powerful swing at you, but you dodge it!" ), _( "The %s takes a powerful swing at , who dodges it!" ), z->name() ); + target->on_dodge( z, z->type->melee_skill ); return true; } @@ -1806,10 +1803,6 @@ bool mattack::fungus_inject( monster *z ) add_msg( m_warning, _( "The %s jabs at you with a needlelike point!" ), z->name() ); z->moves -= 150; - if( player_character.uncanny_dodge() ) { - return true; - } - // Can we dodge the attack? Uses player dodge function % chance (melee.cpp) if( dodge_check( z, target ) ) { target->add_msg_player_or_npc( _( "You dodge it!" ), @@ -1818,11 +1811,11 @@ bool mattack::fungus_inject( monster *z ) return true; } - const bodypart_id hit = target->get_random_body_part(); - int dam = rng( 5, 11 ); - dam = player_character.deal_damage( z, hit, damage_instance( damage_type::CUT, - dam ) ).total_damage(); + bodypart_id hit = target->get_random_body_part(); + damage_instance dam_inst = damage_instance( damage_type::CUT, rng( 5, 11 ) ); + target->block_hit( z, hit, dam_inst ); + int dam = player_character.deal_damage( z, hit, dam_inst ).total_damage(); if( dam > 0 ) { //~ 1$s is monster name, 2$s bodypart in accusative add_msg( m_bad, _( "The %1$s sinks its point into your %2$s!" ), z->name(), @@ -1864,10 +1857,6 @@ bool mattack::fungus_bristle( monster *z ) target->disp_name() ); z->moves -= 150; - if( target->uncanny_dodge() ) { - return true; - } - // Can we dodge the attack? Uses player dodge function % chance (melee.cpp) if( dodge_check( z, target ) ) { target->add_msg_player_or_npc( _( "You dodge it!" ), @@ -1876,10 +1865,11 @@ bool mattack::fungus_bristle( monster *z ) return true; } - const bodypart_id hit = target->get_random_body_part(); - int dam = rng( 7, 16 ); - dam = target->deal_damage( z, hit, damage_instance( damage_type::CUT, dam ) ).total_damage(); + bodypart_id hit = target->get_random_body_part(); + damage_instance dam_inst = damage_instance( damage_type::CUT, rng( 7, 16 ) ); + target->block_hit( z, hit, dam_inst ); + int dam = target->deal_damage( z, hit, dam_inst ).total_damage(); if( dam > 0 ) { //~ 1$s is monster name, 2$s bodypart in accusative target->add_msg_if_player( m_bad, _( "The %1$s sinks several needlelike barbs into your %2$s!" ), @@ -2034,9 +2024,6 @@ bool mattack::fungus_fortify( monster *z ) z->name() ); z->moves -= 150; - if( player_character.uncanny_dodge() ) { - return true; - } // Can we dodge the attack? Uses player dodge function % chance (melee.cpp) if( dodge_check( z, target ) ) { target->add_msg_player_or_npc( _( "You dodge it!" ), @@ -2045,12 +2032,11 @@ bool mattack::fungus_fortify( monster *z ) return true; } - // TODO: 21 damage with no chance to critical isn't scary - const bodypart_id hit = target->get_random_body_part(); - int dam = rng( 15, 21 ); - dam = player_character.deal_damage( z, hit, damage_instance( damage_type::STAB, - dam ) ).total_damage(); + bodypart_id hit = target->get_random_body_part(); + damage_instance dam_inst = damage_instance( damage_type::STAB, rng( 15, 21 ) ); + target->block_hit( z, hit, dam_inst ); + int dam = player_character.deal_damage( z, hit, dam_inst ).total_damage(); if( dam > 0 ) { //~ 1$s is monster name, 2$s bodypart in accusative add_msg( m_bad, _( "The %1$s sinks its point into your %2$s!" ), z->name(), @@ -2079,23 +2065,22 @@ bool mattack::impale( monster *z ) } z->moves -= 80; - bool uncanny = target->uncanny_dodge(); - if( uncanny || dodge_check( z, target ) ) { + + if( dodge_check( z, target ) ) { game_message_type msg_type = target->is_avatar() ? m_warning : m_info; target->add_msg_player_or_npc( msg_type, _( "The %s lunges at you, but you dodge!" ), _( "The %s lunges at , but they dodge!" ), z->name() ); - if( !uncanny ) { - target->on_dodge( z, z->type->melee_skill ); - } + target->on_dodge( z, z->type->melee_skill ); return true; } - int dam = target->deal_damage( z, bodypart_id( "torso" ), damage_instance( damage_type::STAB, - rng( 10, 20 ), - rng( 5, 15 ), - .5 ) ).total_damage(); + bodypart_id hit = bodypart_id( "torso" ); + damage_instance dam_inst = damage_instance( damage_type::STAB, rng( 10, 20 ), rng( 5, 15 ), .5 ); + target->block_hit( z, hit, dam_inst ); + + int dam = target->deal_damage( z, hit, dam_inst ).total_damage(); if( dam > 0 ) { game_message_type msg_type = target->is_avatar() ? m_bad : m_info; target->add_msg_player_or_npc( msg_type, @@ -2135,13 +2120,11 @@ bool mattack::dermatik( monster *z ) return false; } - if( target->uncanny_dodge() ) { - return true; - } player *foe = dynamic_cast< player * >( target ); if( foe == nullptr ) { return true; // No implanting monsters for now } + // Can we dodge the attack? Uses player dodge function % chance (melee.cpp) if( dodge_check( z, target ) ) { if( target->is_avatar() ) { @@ -2536,9 +2519,6 @@ bool mattack::tentacle( monster *z ) z->name() ); z->moves -= 100; - if( target->uncanny_dodge() ) { - return true; - } // Can we dodge the attack? Uses player dodge function % chance (melee.cpp) if( dodge_check( z, target ) ) { target->add_msg_player_or_npc( _( "You dodge it!" ), @@ -2547,10 +2527,11 @@ bool mattack::tentacle( monster *z ) return true; } - const bodypart_id hit = target->get_random_body_part(); - int dam = rng( 10, 20 ); - dam = target->deal_damage( z, hit, damage_instance( damage_type::BASH, dam ) ).total_damage(); + bodypart_id hit = target->get_random_body_part(); + damage_instance dam_inst = damage_instance( damage_type::BASH, rng( 10, 20 ) ); + target->block_hit( z, hit, dam_inst ); + int dam = target->deal_damage( z, hit, dam_inst ).total_damage(); if( dam > 0 ) { target->add_msg_player_or_npc( msg_type, //~ 1$s is bodypart name, 2$d is damage value. @@ -2597,18 +2578,14 @@ bool mattack::ranged_pull( monster *z ) z->moves -= 150; - const bool uncanny = target->uncanny_dodge(); - if( uncanny || dodge_check( z, target ) ) { + if( dodge_check( z, target ) ) { z->moves -= 200; game_message_type msg_type = foe && foe->is_avatar() ? m_warning : m_info; target->add_msg_player_or_npc( msg_type, _( "The %s's arms fly out at you, but you dodge!" ), _( "The %s's arms fly out at , but they dodge!" ), z->name() ); - if( !uncanny ) { - target->on_dodge( z, z->type->melee_skill ); - } - + target->on_dodge( z, z->type->melee_skill ); return true; } @@ -2679,17 +2656,14 @@ bool mattack::grab( monster *z ) } z->moves -= 80; - const bool uncanny = target->uncanny_dodge(); + const game_message_type msg_type = target->is_avatar() ? m_warning : m_info; - if( uncanny || dodge_check( z, target ) ) { + if( dodge_check( z, target ) ) { target->add_msg_player_or_npc( msg_type, _( "The %s gropes at you, but you dodge!" ), _( "The %s gropes at , but they dodge!" ), z->name() ); - if( !uncanny ) { - target->on_dodge( z, z->type->melee_skill ); - } - + target->on_dodge( z, z->type->melee_skill ); return true; } @@ -4115,9 +4089,9 @@ bool mattack::stretch_bite( monster *z ) return true; } } - bool uncanny = target->uncanny_dodge(); + // Can we dodge the attack? Uses player dodge function % chance (melee.cpp) - if( uncanny || dodge_check( z, target ) ) { + if( dodge_check( z, target ) ) { z->moves -= 150; z->add_effect( effect_stunned, 3_turns ); game_message_type msg_type = target->is_avatar() ? m_warning : m_info; @@ -4125,17 +4099,16 @@ bool mattack::stretch_bite( monster *z ) _( "The %s's head extends to bite you, but you dodge and the head sails past!" ), _( "The %s's head extends to bite , but they dodge and the head sails past!" ), z->name() ); - if( !uncanny ) { - target->on_dodge( z, z->type->melee_skill ); - } + + target->on_dodge( z, z->type->melee_skill ); return true; } - const bodypart_id hit = target->get_random_body_part(); - // More damage due to the speed of the moving head - int dam = rng( 5, 15 ); - dam = target->deal_damage( z, hit, damage_instance( damage_type::STAB, dam ) ).total_damage(); + bodypart_id hit = target->get_random_body_part(); + damage_instance dam_inst = damage_instance( damage_type::STAB, rng( 5, 15 ) ); + target->block_hit( z, hit, dam_inst ); + int dam = target->deal_damage( z, hit, dam_inst ).total_damage(); if( dam > 0 ) { game_message_type msg_type = target->is_avatar() ? m_bad : m_info; target->add_msg_player_or_npc( msg_type, @@ -4218,10 +4191,6 @@ bool mattack::flesh_golem( monster *z ) z->name(), target->disp_name() ); z->moves -= 100; - if( target->uncanny_dodge() ) { - return true; - } - // Can we dodge the attack? Uses player dodge function % chance (melee.cpp) if( dodge_check( z, target ) ) { target->add_msg_player_or_npc( _( "You dodge it!" ), @@ -4229,10 +4198,12 @@ bool mattack::flesh_golem( monster *z ) target->on_dodge( z, z->type->melee_skill ); return true; } - const bodypart_id hit = target->get_random_body_part(); - // TODO: 10 bashing damage doesn't sound like a "massive claw" but a mediocre punch - int dam = rng( 5, 10 ); - target->deal_damage( z, hit, damage_instance( damage_type::BASH, dam ) ); + + bodypart_id hit = target->get_random_body_part(); + damage_instance dam_inst = damage_instance( damage_type::BASH, rng( 5, 10 ) ); + target->block_hit( z, hit, dam_inst ); + + int dam = target->deal_damage( z, hit, dam_inst ).total_damage(); if( one_in( 6 ) ) { target->add_effect( effect_downed, 3_minutes ); } @@ -4341,10 +4312,6 @@ bool mattack::lunge( monster *z ) z->moves -= 100; - if( target->uncanny_dodge() ) { - return true; - } - // Can we dodge the attack? Uses player dodge function % chance (melee.cpp) if( dodge_check( z, target ) ) { target->add_msg_player_or_npc( _( "The %1$s lunges at you, but you sidestep it!" ), @@ -4352,9 +4319,12 @@ bool mattack::lunge( monster *z ) target->on_dodge( z, z->type->melee_skill ); return true; } - const bodypart_id hit = target->get_random_body_part(); - int dam = rng( 3, 7 ); - dam = target->deal_damage( z, hit, damage_instance( damage_type::BASH, dam ) ).total_damage(); + + bodypart_id hit = target->get_random_body_part(); + damage_instance dam_inst = damage_instance( damage_type::BASH, rng( 3, 7 ) ); + target->block_hit( z, hit, dam_inst ); + + int dam = target->deal_damage( z, hit, dam_inst ).total_damage(); if( dam > 0 ) { game_message_type msg_type = target->is_avatar() ? m_bad : m_warning; target->add_msg_player_or_npc( msg_type, @@ -4415,9 +4385,6 @@ bool mattack::longswipe( monster *z ) z->moves -= 150; - if( target->uncanny_dodge() ) { - return true; - } // Can we dodge the attack? Uses player dodge function % chance (melee.cpp) if( dodge_check( z, target ) ) { target->add_msg_player_or_npc( _( "The %s thrusts a claw at you, but you evade it!" ), @@ -4426,9 +4393,12 @@ bool mattack::longswipe( monster *z ) target->on_dodge( z, z->type->melee_skill ); return true; } - const bodypart_id hit = target->get_random_body_part(); - int dam = rng( 3, 7 ); - dam = target->deal_damage( z, hit, damage_instance( damage_type::CUT, dam ) ).total_damage(); + + bodypart_id hit = target->get_random_body_part(); + damage_instance dam_inst = damage_instance( damage_type::CUT, rng( 3, 7 ) ); + target->block_hit( z, hit, dam_inst ); + + int dam = target->deal_damage( z, hit, dam_inst ).total_damage(); if( dam > 0 ) { game_message_type msg_type = target->is_avatar() ? m_bad : m_warning; target->add_msg_player_or_npc( msg_type, @@ -4451,10 +4421,6 @@ bool mattack::longswipe( monster *z ) } z->moves -= 100; - if( target->uncanny_dodge() ) { - return true; - } - // Can we dodge the attack? Uses player dodge function % chance (melee.cpp) if( dodge_check( z, target ) ) { target->add_msg_player_or_npc( _( "The %s slashes at your neck! You duck!" ), @@ -4463,9 +4429,11 @@ bool mattack::longswipe( monster *z ) return true; } - int dam = rng( 6, 10 ); - dam = target->deal_damage( z, bodypart_id( "head" ), damage_instance( damage_type::CUT, - dam ) ).total_damage(); + bodypart_id hit = bodypart_id( "head" ); + damage_instance dam_inst = damage_instance( damage_type::CUT, rng( 6, 10 ) ); + target->block_hit( z, hit, dam_inst ); + + int dam = target->deal_damage( z, hit, dam_inst ).total_damage(); if( dam > 0 ) { game_message_type msg_type = target->is_avatar() ? m_bad : m_warning; target->add_msg_player_or_npc( msg_type, @@ -4897,18 +4865,17 @@ bool mattack::evolve_kill_strike( monster *z ) } z->moves -= 100; - const bool uncanny = target->uncanny_dodge(); - if( uncanny || dodge_check( z, target ) ) { + + if( dodge_check( z, target ) ) { game_message_type msg_type = target->is_avatar() ? m_warning : m_info; target->add_msg_player_or_npc( msg_type, _( "The %s lunges at you, but you dodge!" ), _( "The %s lunges at , but they dodge!" ), z->name() ); - if( !uncanny ) { - target->on_dodge( z, z->type->melee_skill ); - target->add_msg_player_or_npc( msg_type, _( "The %s lunges at you, but you dodge!" ), - _( "The %s lunges at , but they dodge!" ), - z->name() ); - } + + target->on_dodge( z, z->type->melee_skill ); + target->add_msg_player_or_npc( msg_type, _( "The %s lunges at you, but you dodge!" ), + _( "The %s lunges at , but they dodge!" ), + z->name() ); return true; } tripoint const target_pos = target->pos(); @@ -5167,10 +5134,6 @@ bool mattack::bio_op_takedown( monster *z ) } z->moves -= 100; - if( target->uncanny_dodge() ) { - return true; - } - // Can we dodge the attack? Uses player dodge function % chance (melee.cpp) if( dodge_check( z, target ) ) { target->add_msg_player_or_npc( _( "You dodge it!" ), @@ -5261,10 +5224,6 @@ bool mattack::bio_op_impale( monster *z ) } z->moves -= 100; - if( target->uncanny_dodge() ) { - return true; - } - // Can we dodge the attack? Uses player dodge function % chance (melee.cpp) if( dodge_check( z, target ) ) { target->add_msg_player_or_npc( _( "You dodge it!" ), @@ -5348,10 +5307,6 @@ bool mattack::bio_op_disarm( monster *z ) } z->moves -= 100; - if( target->uncanny_dodge() ) { - return true; - } - // Can we dodge the attack? Uses player dodge function % chance (melee.cpp) if( dodge_check( z, target ) ) { target->add_msg_player_or_npc( _( "You dodge it!" ), @@ -5702,7 +5657,6 @@ bool mattack::stretch_attack( monster *z ) return false; } - int dam = rng( 5, 10 ); z->moves -= 100; map &here = get_map(); for( auto &pnt : here.find_clear_path( z->pos(), target->pos() ) ) { @@ -5719,7 +5673,8 @@ bool mattack::stretch_attack( monster *z ) _( "The %s thrusts its arm at you, stretching to reach you from afar." ), _( "The %s thrusts its arm at ." ), z->name() ); - if( dodge_check( z, target ) || target->uncanny_dodge() ) { + + if( dodge_check( z, target ) ) { target->add_msg_player_or_npc( msg_type, _( "You evade the stretched arm and it sails past you!" ), _( " evades the stretched arm!" ) ); target->on_dodge( z, z->type->melee_skill ); @@ -5728,9 +5683,11 @@ bool mattack::stretch_attack( monster *z ) return true; } - const bodypart_id hit = target->get_random_body_part(); - dam = target->deal_damage( z, hit, damage_instance( damage_type::STAB, dam ) ).total_damage(); + bodypart_id hit = target->get_random_body_part(); + damage_instance dam_inst = damage_instance( damage_type::STAB, rng( 5, 10 ) ); + target->block_hit( z, hit, dam_inst ); + int dam = target->deal_damage( z, hit, dam_inst ).total_damage(); if( dam > 0 ) { game_message_type msg_type = target->is_avatar() ? m_bad : m_info; target->add_msg_player_or_npc( msg_type, @@ -5815,6 +5772,11 @@ bool mattack::doot( monster *z ) bool mattack::dodge_check( monster *z, Creature *target ) { + // If successfully uncanny dodged, no need to calculate dodge chance + if( target->uncanny_dodge() ) { + return true; + } + ///\EFFECT_DODGE increases chance of dodging, vs their melee skill float dodge = std::max( target->get_dodge() - rng( 0, z->get_hit() ), 0.0f ); return dodge > 0.0 && rng( 0, 10000 ) < 10000 / ( 1 + 99 * std::exp( -.6 * dodge ) ); From 8032c52cfc55100fbc1e4f257b29c762c82563a3 Mon Sep 17 00:00:00 2001 From: Eric <52087122+Ramza13@users.noreply.github.com> Date: Fri, 9 Jul 2021 10:43:29 -0400 Subject: [PATCH 092/116] Allow item usage to use effect_on_conditions and move over/rebalance sleep items. (#48360) * Compiles * Add item use eoc and rebalance sleep items * Update JSON_INFO.md * Code review + fix * Update iuse_actor.cpp * Update dialogue.h * Clean up * Update dialogue.h * Update iuse_actor.cpp --- data/json/effect_on_condition.json | 10 +++++++ data/json/item_actions.json | 10 +++---- data/json/items/comestibles/drink.json | 6 +++- data/json/items/comestibles/med.json | 12 ++++++-- doc/JSON_INFO.md | 5 ++++ src/creature.h | 2 +- src/dialogue.h | 1 + src/item_factory.cpp | 2 +- src/iuse.cpp | 7 ----- src/iuse.h | 1 - src/iuse_actor.cpp | 38 ++++++++++++++++++++++++++ src/iuse_actor.h | 19 +++++++++++++ src/npc.h | 2 +- src/npctalk.cpp | 13 +++++++++ src/talker.h | 1 + src/talker_character.cpp | 4 +++ src/talker_character.h | 2 ++ 17 files changed, 116 insertions(+), 19 deletions(-) diff --git a/data/json/effect_on_condition.json b/data/json/effect_on_condition.json index ce8a99fc4ff9d..80f455a8611b3 100644 --- a/data/json/effect_on_condition.json +++ b/data/json/effect_on_condition.json @@ -87,5 +87,15 @@ { "sound_effect": "elec_crackle_low", "id": "bionics", "volume": 100 }, { "u_add_power": "-25kJ" } ] + }, + { + "type": "effect_on_condition", + "id": "EOC_SLEEP", + "effect": [ { "message": "You feel very sleepy…" }, { "u_mod_fatigue": 40 } ] + }, + { + "type": "effect_on_condition", + "id": "EOC_MINOR_SLEEP", + "effect": [ { "message": "You feel sleepy…" }, { "u_mod_fatigue": 20 } ] } ] diff --git a/data/json/item_actions.json b/data/json/item_actions.json index 0428cfb630050..12bddabd5d0ed 100644 --- a/data/json/item_actions.json +++ b/data/json/item_actions.json @@ -844,11 +844,6 @@ "id": "SIPHON", "name": { "str": "Siphon" } }, - { - "type": "item_action", - "id": "SLEEP", - "name": { "str": "Take" } - }, { "type": "item_action", "id": "SMOKING", @@ -1073,5 +1068,10 @@ "type": "item_action", "id": "CRAFT", "name": { "str": "Work on craft" } + }, + { + "type": "item_action", + "id": "effect_on_conditions", + "name": { "str": "Activate item" } } ] diff --git a/data/json/items/comestibles/drink.json b/data/json/items/comestibles/drink.json index 8b18bd6444b2c..e9ae43cacbe22 100644 --- a/data/json/items/comestibles/drink.json +++ b/data/json/items/comestibles/drink.json @@ -158,7 +158,11 @@ "name": { "str_sp": "chamomile tea" }, "copy-from": "tea", "color": "green", - "use_action": [ "SLEEP" ], + "use_action": { + "type": "effect_on_conditions", + "description": "Can be used to treat insomnia.", + "effect_on_conditions": [ "EOC_MINOR_SLEEP" ] + }, "stim": 0, "spoils_in": "10 days", "quench": 34, diff --git a/data/json/items/comestibles/med.json b/data/json/items/comestibles/med.json index be7668321c6fd..3611f2c72db82 100644 --- a/data/json/items/comestibles/med.json +++ b/data/json/items/comestibles/med.json @@ -1336,7 +1336,11 @@ "flags": [ "IRREPLACEABLE_CONSUMABLE" ], "addiction_potential": 40, "addiction_type": "sleeping pill", - "use_action": [ "SLEEP" ] + "use_action": { + "type": "effect_on_conditions", + "description": "Can be used to treat insomnia.", + "effect_on_conditions": [ "EOC_SLEEP" ] + } }, { "id": "poppy_pain", @@ -1379,7 +1383,11 @@ "color": "magenta", "healthy": -2, "addiction_type": "opiate", - "use_action": [ "SLEEP" ] + "use_action": { + "type": "effect_on_conditions", + "description": "Can be used to treat insomnia.", + "effect_on_conditions": [ "EOC_SLEEP" ] + } }, { "id": "poppysyrup", diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index b120710c2d026..0bdecf450d93c 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -3195,6 +3195,11 @@ The contents of use_action fields can either be a string indicating a built-in f "kevlar_padded" ] } +"use_action": { + "type" :"effect_on_conditions", // activate effect_on_conditions + "description" :"This debugs the game", // usage description + "effect_on_conditions" : ["test_cond"] // ids of the effect_on_conditions to activate + } ``` ###random Descriptions diff --git a/src/creature.h b/src/creature.h index 42224344a9c10..c43a2ee6e2c7a 100644 --- a/src/creature.h +++ b/src/creature.h @@ -265,7 +265,7 @@ class Creature : public location, public viewer virtual const avatar *as_avatar() const { return nullptr; } - virtual const npc *as_npc() { + virtual npc *as_npc() { return nullptr; } virtual const npc *as_npc() const { diff --git a/src/dialogue.h b/src/dialogue.h index 0ea3acb49d395..dd9e566180a23 100644 --- a/src/dialogue.h +++ b/src/dialogue.h @@ -104,6 +104,7 @@ struct talk_effect_fun_t { void set_add_wet( const JsonObject &jo, const std::string &member, bool is_npc ); void set_add_power( const JsonObject &jo, const std::string &member, bool is_npc ); void set_sound_effect( const JsonObject &jo, const std::string &member ); + void set_mod_fatigue( const JsonObject &jo, const std::string &member, bool is_npc = false ); void set_add_var( const JsonObject &jo, const std::string &member, bool is_npc = false ); void set_remove_var( const JsonObject &jo, const std::string &member, bool is_npc = false ); void set_adjust_var( const JsonObject &jo, const std::string &member, bool is_npc = false ); diff --git a/src/item_factory.cpp b/src/item_factory.cpp index 0ddabf179e39d..55c5fe59c0771 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -1012,7 +1012,6 @@ void Item_factory::init() add_iuse( "SHOCKTONFA_OFF", &iuse::shocktonfa_off ); add_iuse( "SHOCKTONFA_ON", &iuse::shocktonfa_on ); add_iuse( "SIPHON", &iuse::siphon ); - add_iuse( "SLEEP", &iuse::sleep ); add_iuse( "SMOKING", &iuse::smoking ); add_iuse( "SOLARPACK", &iuse::solarpack ); add_iuse( "SOLARPACK_OFF", &iuse::solarpack_off ); @@ -1080,6 +1079,7 @@ void Item_factory::init() add_actor( std::make_unique() ); add_actor( std::make_unique() ); add_actor( std::make_unique() ); + add_actor( std::make_unique() ); // An empty dummy group, it will not spawn anything. However, it makes that item group // id valid, so it can be used all over the place without need to explicitly check for it. m_template_groups[item_group_id( "EMPTY_GROUP" )] = diff --git a/src/iuse.cpp b/src/iuse.cpp index e79092c6a6a8e..1d77ecc447009 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -999,13 +999,6 @@ cata::optional iuse::prozac( player *p, item *it, bool, const tripoint & ) return it->type->charges_to_use(); } -cata::optional iuse::sleep( player *p, item *it, bool, const tripoint & ) -{ - p->mod_fatigue( 40 ); - p->add_msg_if_player( m_warning, _( "You feel very sleepy…" ) ); - return it->type->charges_to_use(); -} - cata::optional iuse::datura( player *p, item *it, bool, const tripoint & ) { if( p->is_npc() ) { diff --git a/src/iuse.h b/src/iuse.h index 0803ae5071716..c666280836376 100644 --- a/src/iuse.h +++ b/src/iuse.h @@ -63,7 +63,6 @@ cata::optional purifier( player *, item *, bool, const tripoint & ); cata::optional purify_iv( player *, item *, bool, const tripoint & ); cata::optional purify_smart( player *, item *, bool, const tripoint & ); cata::optional sewage( player *, item *, bool, const tripoint & ); -cata::optional sleep( player *, item *, bool, const tripoint & ); cata::optional smoking( player *, item *, bool, const tripoint & ); cata::optional thorazine( player *, item *, bool, const tripoint & ); cata::optional vaccine( player *, item *, bool, const tripoint & ); diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 60108382e2c24..6aa820c3e4466 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -76,6 +76,7 @@ #include "sounds.h" #include "string_formatter.h" #include "string_input_popup.h" +#include "talker.h" #include "translations.h" #include "trap.h" #include "ui.h" @@ -4508,3 +4509,40 @@ std::unique_ptr change_scent_iuse::clone() const { return std::make_unique( *this ); } + +std::unique_ptr effect_on_conditons_actor::clone() const +{ + return std::make_unique( *this ); +} + +void effect_on_conditons_actor::load( const JsonObject &obj ) +{ + description = obj.get_string( "description" ); + for( const std::string &eoc : obj.get_string_array( "effect_on_conditions" ) ) { + eocs.emplace_back( effect_on_condition_id( eoc ) ); + } +} + +void effect_on_conditons_actor::info( const item &, std::vector &dump ) const +{ + dump.emplace_back( "DESCRIPTION", description ); +} + +cata::optional effect_on_conditons_actor::use( player &p, item &it, bool, + const tripoint & ) const +{ + dialogue d; + standard_npc default_npc( "Default" ); + if( avatar *u = p.as_avatar() ) { + d.alpha = get_talker_for( u ); + } else if( npc *n = p.as_npc() ) { + d.alpha = get_talker_for( n ); + } + ///TODO make this talker item + d.beta = get_talker_for( default_npc ); + + for( const effect_on_condition_id &eoc : eocs ) { + eoc->activate( d ); + } + return it.type->charges_to_use(); +} diff --git a/src/iuse_actor.h b/src/iuse_actor.h index 031eee1b704c5..767e215d8c810 100644 --- a/src/iuse_actor.h +++ b/src/iuse_actor.h @@ -1113,4 +1113,23 @@ class sew_advanced_actor : public iuse_actor cata::optional use( player &, item &, bool, const tripoint & ) const override; std::unique_ptr clone() const override; }; + + +/** + * Activate an array of effect_on_conditions + */ +class effect_on_conditons_actor : public iuse_actor +{ + public: + std::vector eocs; + std::string description; + explicit effect_on_conditons_actor( const std::string &type = "effect_on_conditions" ) : iuse_actor( + type ) {} + + ~effect_on_conditons_actor() override = default; + void load( const JsonObject &obj ) override; + cata::optional use( player &p, item &it, bool, const tripoint & ) const override; + std::unique_ptr clone() const override; + void info( const item &, std::vector & ) const override; +}; #endif // CATA_SRC_IUSE_ACTOR_H diff --git a/src/npc.h b/src/npc.h index d613904b8c431..4cc0b216941b6 100644 --- a/src/npc.h +++ b/src/npc.h @@ -773,7 +773,7 @@ class npc : public player bool is_npc() const override { return true; } - const npc *as_npc() override { + npc *as_npc() override { return this; } const npc *as_npc() const override { diff --git a/src/npctalk.cpp b/src/npctalk.cpp index 7a7b671266463..787f17ed4ca3c 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -2192,6 +2192,15 @@ void talk_effect_fun_t::set_add_power( const JsonObject &jo, const std::string & }; } +void talk_effect_fun_t::set_mod_fatigue( const JsonObject &jo, const std::string &member, + bool is_npc ) +{ + int amount = jo.get_int( member ); + function = [is_npc, amount]( const dialogue & d ) { + d.actor( is_npc )->mod_fatigue( amount ); + }; +} + void talk_effect_t::set_effect_consequence( const talk_effect_fun_t &fun, dialogue_consequence con ) { @@ -2445,6 +2454,10 @@ void talk_effect_t::parse_sub_effect( const JsonObject &jo ) subeffect_fun.set_add_power( jo, "u_add_power", false ); } else if( jo.has_member( "npc_add_power" ) ) { subeffect_fun.set_add_power( jo, "npc_add_power", true ); + } else if( jo.has_int( "u_mod_fatigue" ) ) { + subeffect_fun.set_mod_fatigue( jo, "u_mod_fatigue", false ); + } else if( jo.has_int( "npc_mod_fatigue" ) ) { + subeffect_fun.set_mod_fatigue( jo, "npc_mod_fatigue", true ); } else { jo.throw_error( "invalid sub effect syntax: " + jo.str() ); } diff --git a/src/talker.h b/src/talker.h index a548cc95274d7..0fed5ecbdcc8f 100644 --- a/src/talker.h +++ b/src/talker.h @@ -96,6 +96,7 @@ class talker } virtual void set_mutation( const trait_id & ) {} virtual void unset_mutation( const trait_id & ) {} + virtual void mod_fatigue( int ) {} virtual bool has_trait_flag( const json_character_flag & ) const { return false; } diff --git a/src/talker_character.cpp b/src/talker_character.cpp index b233df97b98a0..f28e950db8da6 100644 --- a/src/talker_character.cpp +++ b/src/talker_character.cpp @@ -318,3 +318,7 @@ units::energy talker_character::power_cur() const return me_chr->get_power_level(); } +void talker_character::mod_fatigue( int amount ) +{ + me_chr->mod_fatigue( amount ); +} diff --git a/src/talker_character.h b/src/talker_character.h index 782c0ca41483b..520d967fa4a19 100644 --- a/src/talker_character.h +++ b/src/talker_character.h @@ -113,6 +113,8 @@ class talker_character: public talker bool worn_with_flag( const flag_id &flag ) const override; bool wielded_with_flag( const flag_id &flag ) const override; + void mod_fatigue( int amount ) override; + void mod_pain( int amount ) override; protected: From b3b986d3a0cd25b62268b00ebd854863870c7940 Mon Sep 17 00:00:00 2001 From: Hirmuolio <22011552+Hirmuolio@users.noreply.github.com> Date: Fri, 9 Jul 2021 17:45:26 +0300 Subject: [PATCH 093/116] Make all comestibles rot and have temperature (#49640) * generalize to comestibles * astyle * generalize more foodstuff * revert some irrelevant changes * some tidying up * unused function * reduntant check * freezing F to C * freezing F to C * freezing F to C --- data/json/items/chemicals_and_resources.json | 15 +++++------ src/item.cpp | 27 ++++++++------------ src/item.h | 1 - src/iuse.cpp | 3 +-- src/map.cpp | 2 +- src/player.cpp | 2 +- src/recipe.cpp | 4 +-- src/savegame_json.cpp | 4 ++- 8 files changed, 25 insertions(+), 33 deletions(-) diff --git a/data/json/items/chemicals_and_resources.json b/data/json/items/chemicals_and_resources.json index cd130ad86671e..921149ee74c7b 100644 --- a/data/json/items/chemicals_and_resources.json +++ b/data/json/items/chemicals_and_resources.json @@ -542,7 +542,7 @@ "count": 100 }, { - "type": "AMMO", + "type": "COMESTIBLE", "id": "chem_sulphuric_acid", "category": "chems", "price": 250, @@ -555,14 +555,13 @@ "volume": "250 ml", "weight": "460 g", "bashing": 1, - "ammo_type": "components", "phase": "liquid", "container": "bottle_glass", - "//freezing_point": 25, + "freezing_point": -36, "drop_action": { "type": "emit_actor", "emits": [ "emit_acid_drop" ], "scale_qty": true } }, { - "type": "AMMO", + "type": "COMESTIBLE", "id": "chem_muriatic_acid", "category": "chems", "price": 250, @@ -575,10 +574,9 @@ "volume": "250 ml", "weight": "460 g", "bashing": 1, - "ammo_type": "components", "phase": "liquid", "container": "bottle_glass", - "//freezing_point": 25, + "freezing_point": -50, "drop_action": { "type": "emit_actor", "emits": [ "emit_acid_drop" ], "scale_qty": true } }, { @@ -599,7 +597,7 @@ "container": "bottle_glass" }, { - "type": "AMMO", + "type": "COMESTIBLE", "id": "chem_nitric_acid", "category": "chems", "price": 300, @@ -612,10 +610,9 @@ "volume": "250 ml", "weight": "375 g", "bashing": 1, - "ammo_type": "components", "phase": "liquid", "container": "bottle_glass", - "//freezing_point": -44, + "freezing_point": -42, "drop_action": { "type": "emit_actor", "emits": [ "emit_acid_drop" ], "scale_qty": true } }, { diff --git a/src/item.cpp b/src/item.cpp index 151f45191a439..c061cd34e6a5e 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -309,7 +309,7 @@ item::item( const itype *type, time_point turn, int qty ) : type( type ), bday( item_pocket::pocket_type::MAGAZINE ); } - } else if( has_temperature() || goes_bad() ) { + } else if( has_temperature() ) { active = true; last_temp_check = bday; @@ -378,7 +378,7 @@ item::item( const recipe *rec, int qty, std::list items, std::vectorcomps_used = selections; - if( is_food() ) { + if( has_temperature() ) { active = true; last_temp_check = bday; if( goes_bad() ) { @@ -412,7 +412,7 @@ item::item( const recipe *rec, item &component ) std::listitems( { component } ); components = items; - if( is_food() ) { + if( has_temperature() ) { active = true; last_temp_check = bday; if( goes_bad() ) { @@ -4444,7 +4444,7 @@ nc_color item::color_in_inventory() const } } else if( has_flag( flag_LEAK_DAM ) && has_flag( flag_RADIOACTIVE ) && damage() > 0 ) { ret = c_light_green; - } else if( active && !is_food() && !is_corpse() ) { + } else if( active && !has_temperature() && !is_corpse() ) { // Active items show up as yellow ret = c_yellow; } else if( is_corpse() && can_revive() ) { @@ -4983,7 +4983,7 @@ std::string item::tname( unsigned int quantity, bool with_prefix, unsigned int t tagtext += _( " (lit)" ); } else if( has_flag( flag_IS_UPS ) && get_var( "cable" ) == "plugged_in" ) { tagtext += _( " (plugged in)" ); - } else if( active && !is_food() && !is_corpse() && + } else if( active && !has_temperature() && !is_corpse() && !string_ends_with( typeId().str(), "_on" ) ) { // Usually the items whose ids end in "_on" have the "active" or "on" string already contained // in their name, also food is active while it rots. @@ -5839,13 +5839,13 @@ bool item::goes_bad() const // Corpses rot only if they are made of rotting materials return made_of_any( materials::get_rotting() ); } - return is_food() && get_comestible()->spoils != 0_turns; + return is_comestible() && get_comestible()->spoils != 0_turns; } time_duration item::get_shelf_life() const { if( goes_bad() ) { - if( is_food() ) { + if( is_comestible() ) { return get_comestible()->spoils; } else if( is_corpse() ) { return 24_hours; @@ -6861,11 +6861,6 @@ bool item::reinforceable() const } ); } -bool item::destroyed_at_zero_charges() const -{ - return ( is_ammo() || is_food() ); -} - bool item::is_gun() const { return !!type->gun; @@ -7042,7 +7037,7 @@ bool item::is_food_container() const bool item::has_temperature() const { - return is_food() || is_corpse(); + return is_comestible() || is_corpse(); } bool item::is_corpse() const @@ -9425,7 +9420,7 @@ bool item::has_rotten_away() const if( is_corpse() && !can_revive() ) { return get_rot() > 10_days; } else { - return is_food() && get_relative_rot() > 2.0; + return get_relative_rot() > 2.0; } } @@ -9535,7 +9530,7 @@ bool item::needs_processing() const bool need_process = false; visit_items( [&need_process]( const item * it, item * ) { if( it->active || it->ethereal || it->has_flag( flag_RADIO_ACTIVATION ) || - it->is_food() || it->has_relic_recharge() ) { + it->has_relic_recharge() ) { need_process = true; return VisitResponse::ABORT; } @@ -9546,7 +9541,7 @@ bool item::needs_processing() const int item::processing_speed() const { - if( is_corpse() || is_food() ) { + if( is_corpse() || is_comestible() ) { return to_turns( 10_minutes ); } // Unless otherwise indicated, update every turn. diff --git a/src/item.h b/src/item.h index d956610995d97..dc14fb9725bc9 100644 --- a/src/item.h +++ b/src/item.h @@ -1194,7 +1194,6 @@ class item : public visitable void overwrite_relic( const relic &nrelic ); - bool destroyed_at_zero_charges() const; // Most of the is_whatever() functions call the same function in our itype bool is_null() const; // True if type is NULL, or points to the null item (id == 0) bool is_comestible() const; diff --git a/src/iuse.cpp b/src/iuse.cpp index 1d77ecc447009..865e6d310599a 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -4753,8 +4753,7 @@ cata::optional iuse::blood_draw( player *p, item *it, bool, const tripoint if( acid_blood ) { item acid( "chem_sulphuric_acid", calendar::turn ); - // Acid should have temperature. But it currently does not. So trying to set it crashes the game. - // When acid gets temperature just add acid.set_item_temperature( blood_temp ); here + acid.set_item_temperature( blood_temp ); it->put_in( acid, item_pocket::pocket_type::CONTAINER ); if( one_in( 3 ) ) { if( it->inc_damage( damage_type::ACID ) ) { diff --git a/src/map.cpp b/src/map.cpp index affca4289a7ef..cffa18ff5a79a 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -4461,7 +4461,7 @@ item &map::add_item( const tripoint &p, item new_item ) // Process foods and temperature tracked items when they are added to the map, here instead of add_item_at() // to avoid double processing food and corpses during active item processing. - if( new_item.is_food() || new_item.has_temperature() ) { + if( new_item.has_temperature() ) { new_item.process( nullptr, p ); } diff --git a/src/player.cpp b/src/player.cpp index 5cfb1b2184525..56fedd5b84d7b 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -1092,7 +1092,7 @@ void player::siphon( vehicle &veh, const itype_id &desired_liquid ) } item liquid( desired_liquid, calendar::turn, qty ); - if( liquid.is_food() ) { + if( liquid.has_temperature() ) { liquid.set_item_specific_energy( veh.fuel_specific_energy( desired_liquid ) ); } if( liquid_handler::handle_liquid( liquid, nullptr, 1, nullptr, &veh ) ) { diff --git a/src/recipe.cpp b/src/recipe.cpp index a589b3b2cd5ae..deee47ea8fa32 100644 --- a/src/recipe.cpp +++ b/src/recipe.cpp @@ -918,7 +918,7 @@ std::function recipe::get_component_filter( // EDIBLE_FROZEN components ( e.g. flour, chocolate ) are allowed as well // Otherwise forbid them std::function frozen_filter = return_true; - if( result.is_food() && !hot_result() ) { + if( result.has_temperature() && !hot_result() ) { frozen_filter = []( const item & component ) { return !component.has_flag( flag_FROZEN ) || component.has_flag( flag_EDIBLE_FROZEN ); }; @@ -1057,7 +1057,7 @@ bool recipe::hot_result() const // the check includes this tool in addition to the hotplate. // // TODO: Make this less of a hack - if( create_result().is_food() ) { + if( create_result().has_temperature() ) { const requirement_data::alter_tool_comp_vector &tool_lists = simple_requirements().get_tools(); for( const std::vector &tools : tool_lists ) { for( const tool_comp &t : tools ) { diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 351ccb459b73e..ceeeb47ba1b28 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -2544,7 +2544,9 @@ void item::io( Archive &archive ) if( count_by_charges() && charges <= 0 ) { charges = item( type, calendar::turn_zero ).charges; } - if( is_food() ) { + + // Items from old saves before those items were temperature tracked need activating. + if( has_temperature() ) { active = true; } if( !active && ( has_own_flag( flag_HOT ) || has_own_flag( flag_COLD ) || From b4d6f89a9981c90c3ee2423a8233881ca5277c3e Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Fri, 9 Jul 2021 15:46:22 +0100 Subject: [PATCH 094/116] Roof and general improvements for orchard_apple (#49596) * Added a roof along with item spawns and a new forklift spawn. Made two palettes to encompass the buildings and general orchard. Changed the road layout to make it look slightly more natural. * Adjusted vehicle spawn chances from test numbers. * Simplified arrays and removed less accessible nested chunk spawns. * Eventually worked out how to lint. --- .../agriculture.json | 40 +++ data/json/mapgen/orchard_apple.json | 269 +++++++++--------- data/json/mapgen_palettes/orchard_apple.json | 65 +++++ .../overmap/overmap_special/specials.json | 4 +- .../overmap_terrain_agricultural.json | 16 ++ 5 files changed, 265 insertions(+), 129 deletions(-) create mode 100644 data/json/mapgen_palettes/orchard_apple.json diff --git a/data/json/itemgroups/Agriculture_Forage_Excavation/agriculture.json b/data/json/itemgroups/Agriculture_Forage_Excavation/agriculture.json index 2aa922cdb00f3..8b97754f71cc0 100644 --- a/data/json/itemgroups/Agriculture_Forage_Excavation/agriculture.json +++ b/data/json/itemgroups/Agriculture_Forage_Excavation/agriculture.json @@ -146,5 +146,45 @@ [ "straw_pile", 20 ], [ "survnote", 1 ] ] + }, + { + "type": "item_group", + "id": "orchard_supplies", + "subtype": "distribution", + "items": [ + [ "fertilizer_liquid", 10 ], + [ "fertilizer_commercial", 10 ], + [ "insecticide", 10 ], + [ "pot_canning", 5 ], + { "item": "jar_3l_glass_sealed", "prob": 25, "count": [ 2, 10 ] }, + { "item": "wooden_barrel", "prob": 20, "count": [ 2, 4 ] } + ] + }, + { + "type": "item_group", + "id": "orchard_tools", + "subtype": "collection", + "items": [ + [ "shovel", 5 ], + { "item": "trimmer_off", "prob": 5, "charges": [ 0, 600 ] }, + [ "bucket", 5 ], + [ "rake", 15 ], + [ "rake_plastic", 5 ], + [ "stepladder", 15 ], + { "item": "pointy_stick", "prob": 20, "count": [ 3, 10 ] }, + [ "hammer", 10 ], + [ "rope_makeshift_6", 20 ] + ] + }, + { + "type": "item_group", + "id": "stored_pulp", + "ammo": 100, + "magazine": 100, + "subtype": "distribution", + "entries": [ + { "item": "wooden_barrel", "prob": 100, "sealed": true }, + { "item": "juice_pulp", "prob": 100, "charges": [ 7, 77 ], "container-item": "wooden_barrel" } + ] } ] diff --git a/data/json/mapgen/orchard_apple.json b/data/json/mapgen/orchard_apple.json index 1a664397aef46..01cab79230852 100644 --- a/data/json/mapgen/orchard_apple.json +++ b/data/json/mapgen/orchard_apple.json @@ -12,46 +12,33 @@ "q q", "q q", "q $$$$$$$$$$$$$$$$$$$$ q", - "q $------------------$ q", - "q $-,,C-.........OOX-$ q", - "q $-Ck,o.OcccO....OX-$ q", - "q $--ox-.........OXX-$ q", - "q $-.........--++----$ q", - "q $-..O......-T...XX-$ q", - "q $-f.c......+....XX-$ q", - "q $-f.c......+.....X-$ q", - "q $-f.c......-....XX-$ q", - "q $-..O......-.....X-$ q", - "q $-.........-....|X-$ q", - "q $------++---====---$ q", - "q $]]$]''''''] q", - "q 7$$7 $]]$]''''''] q", - "q $]]$]''''''] q", - "'''''''''''''''''''' q", - "'''''''''''''''''''' q", - "'''''''''''''''''''' q", - "'''''''''''''''''''' q" + "q $MMMMMMMMMMMMMMMMMM$ q", + "q $M,,CMmmmmmmmmmOOYM$ q", + "q $MCk,omEcccEmmmmOYM$ q", + "q $MMx+MmmmmmmmmmOYYM$ q", + "q $MmmmmmmmmmMM&&MMMM$ q", + "q $MmmEmmmmmmMzmmmXXM$ q", + "q $Mfmcmmmmmm&mmmmXXM$ q", + "q $Mfmcmmmmmm&mmmmmXM$ q", + "q $MfmcmmmmmmMmmmmXXM$ q", + "q $MmmEmmmmmmMmmmmmXM$ q", + "q $MmmmmmmmmmMmmmmGXM$ q", + "q $MMMMMM&&MMM====MMM$ q", + "q ^$]]$]......] q", + "q 7$$7 $]]$]......] q", + "]]]]]]]]]]]]]......] q", + "]...........]......] q", + "]...........]......] q", + "]...........]......] q", + "]...........]......] q" ], - "terrain": { - " ": [ "t_dirt", "t_grass", "t_grass", "t_grass", "t_grass", "t_grass" ], - "$": [ "t_shrub", "t_shrub", "t_shrub", "t_shrub", "t_shrub", "t_underbrush" ], - "'": "t_pavement", - "+": "t_door_metal_c", - ",": "t_floor", - "-": "t_wall_metal", - ".": "t_metal_floor", - "7": "t_tree", - "=": "t_door_metal_locked", - "C": "t_floor", - "]": "t_sidewalk", - "k": "t_floor", - "o": "t_window", - "x": "t_door_c", - "|": "t_gates_control_metal", - "Q": "t_fence_v", - "q": "t_fence_h" + "palettes": [ "orchard_buildings" ], + "terrain": { " ": [ [ "t_grass", 5 ], "t_dirt" ] }, + "items": { + "O": { "item": "orchard_tools", "chance": 25, "repeat": [ 0, 1 ] }, + "X": { "item": "orchard_tools", "chance": 25, "repeat": [ 0, 1 ] }, + "Y": [ { "item": "orchard_tools", "chance": 50, "repeat": [ 1, 2 ] }, { "item": "orchard_supplies", "chance": 50 } ] }, - "furniture": { "C": "f_chair", "O": "f_crate_o", "T": "f_table", "X": "f_crate_c", "c": "f_counter", "f": "f_rack", "k": "f_desk" }, "place_items": [ { "item": "office", "x": 7, "y": 7, "chance": 75, "repeat": [ 1, 3 ] }, { "item": "office", "x": 16, "y": 10, "chance": 50 }, @@ -63,10 +50,9 @@ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "chance": 45 } ], "place_vehicles": [ - { "vehicle": "suburban_home", "x": 2, "y": 21, "chance": 45, "rotation": -90 }, - { "vehicle": "suburban_home", "x": 7, "y": 21, "chance": 45, "rotation": -90 }, - { "vehicle": "suburban_home", "x": 12, "y": 21, "chance": 45, "rotation": -90 }, - { "vehicle": "highway", "x": 16, "y": 21, "chance": 45 } + { "vehicle": "suburban_home", "x": [ 3, 8 ], "y": 22, "chance": 45, "rotation": 180 }, + { "vehicle": "highway", "x": 15, "y": 20, "chance": 60, "rotation": -90 }, + { "vehicle": "forklift", "x": 16, "y": 12, "chance": 20, "rotation": 90 } ] } }, @@ -78,80 +64,50 @@ "object": { "fill_ter": "t_floor", "rows": [ - ".................... q", - ".................... q", - ".................... q", - ".................... q", - "....................****", - "....................****", - "...................*****", - "...................* q", - "...................* q", - "..................** q", - ".................** q", - "..............**** q", - "q**********************q", - "q******bbb**-------+--$q", - "q******ttt**-cT{xxS,s-$q", - "q******bbb**oc,D,,,,F-$q", - "q***********oc,,,,,,F-$q", - "q***********-POOk,,TF-$q", - "q ********* -----++---$q", - "q7 ****btb 7-XOO,,,ff-$q", - "q ****btb -XO,,,,,|-$q", - "q7 ****btb 7---=====--$q", - "q ********* |*****dd q", + "].y.y.y.y.y.]......] q", + "...................] q", + "...................] q", + "...................] q", + "...................]****", + "..................]]****", + "..................]*****", + "..................]* q", + ".................]]* q", + "................]]** q", + ".............]]]]** q", + "]]]]]]]]]]]]]]**** q", + "q************^*********q", + "q******bbb**WWWWWWW+WW$q", + "q******ttt**WcT{vvS,sW$q", + "q******bbb**oc,D,,,,FW$q", + "q***********oc,,,,,,FW$q", + "q***********WPOOa,,TFW$q", + "q ********* WWWWW++WWW$q", + "q7 ****btb 7WXOO,,,ffW$q", + "q ****btb WXO,,,,,gW$q", + "q7 ****btb 7WWW=====WW$q", + "q ********* g*****dd q", "QQQQ***QQQQQQQQQQ***QQQQ" ], - "terrain": { - " ": [ "t_dirt", "t_grass_long", "t_grass", "t_grass", "t_grass", "t_grass" ], - "$": "t_shrub", - "*": "t_dirt", - "+": "t_door_c", - ",": "t_floor", - "-": "t_wall_wood", - ".": "t_pavement", - "7": "t_tree", - "=": "t_door_metal_locked", - "b": "t_dirt", - "o": "t_window_empty", - "t": "t_dirt", - "|": "t_barndoor", - "Q": "t_fence_v", - "q": "t_fence_h" - }, - "furniture": { - "D": "f_trashcan", - "F": "f_fridge", - "O": "f_crate_o", - "P": "f_sign", - "S": "f_smoking_rack", - "T": "f_table", - "X": "f_crate_c", - "b": "f_bench", - "c": "f_counter", - "d": "f_dumpster", - "f": "f_rack", - "k": "f_wood_keg", - "s": "f_safe_o", - "t": "f_table", - "x": "f_oven", - "{": "f_sink" - }, + "palettes": [ "orchard_buildings" ], + "terrain": { " ": [ [ "t_grass", 4 ], "t_grass_long", "t_dirt" ] }, "place_signs": [ { "signage": "Get Apples n Ciders!", "x": 13, "y": 17 } ], "place_items": [ - { "item": "fridge", "x": 20, "y": [ 15, 17 ], "chance": 75, "repeat": [ 1, 3 ] }, - { "item": "farming_tools", "x": [ 19, 20 ], "y": 19, "chance": 50, "repeat": [ 1, 2 ] }, + { "item": "fridge", "x": 20, "y": [ 15, 17 ], "chance": 25, "repeat": [ 1, 3 ] }, + { "item": "orchard_tools", "x": [ 19, 20 ], "y": 19, "chance": 50, "repeat": [ 1, 2 ] }, { "item": "trash", "x": 22, "y": [ 15, 16 ], "chance": 65, "repeat": [ 1, 2 ] }, - { "item": "trash", "x": 11, "y": 12, "chance": 75 } + { "item": "trash", "x": 11, "y": 12, "chance": 75 }, + { "item": "stored_pulp", "x": [ 13, 14 ], "y": [ 19, 20 ], "chance": 75 } ], + "place_item": [ { "item": "apple", "x": 20, "y": [ 15, 17 ], "chance": 100, "repeat": [ 5, 15 ] } ], + "liquids": { "k": { "liquid": "apple_cider", "amount": [ 10, 100 ] } }, "place_monsters": [ { "monster": "GROUP_PEST", "x": [ 1, 22 ], "y": [ 1, 22 ], "chance": 30 }, { "monster": "GROUP_SAFE", "x": [ 1, 22 ], "y": [ 1, 22 ], "chance": 30 }, { "monster": "GROUP_DOMESTIC", "x": [ 1, 22 ], "y": [ 1, 22 ], "chance": 40 }, { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "chance": 45 } ], - "place_vehicles": [ { "vehicle": "suburban_home", "x": 4, "y": 17, "chance": 50, "rotation": -90 } ] + "place_vehicles": [ { "vehicle": "suburban_home", "x": 5, "y": 10, "chance": 45 } ] } }, { @@ -187,12 +143,7 @@ " $ *** $ *** $$ ", " *** $$ *** $" ], - "terrain": { - " ": [ "t_dirt", "t_grass_long", "t_grass_long", "t_grass", "t_grass", "t_grass", "t_grass" ], - "*": [ "t_dirt", "t_dirt", "t_dirt", "t_dirt", "t_dirt", "t_dirt", "t_grass" ], - "$": [ "t_shrub", "t_shrub", "t_underbrush", "t_grass", "t_dirt" ], - "7": [ "t_tree_apple", "t_tree_apple", "t_tree_dead" ] - }, + "palettes": [ "orchard_tree_apple" ], "place_monsters": [ { "monster": "GROUP_PEST", "x": [ 1, 22 ], "y": [ 1, 22 ], "chance": 60 }, { "monster": "GROUP_DOMESTIC", "x": [ 1, 22 ], "y": [ 1, 22 ], "chance": 40 }, @@ -234,12 +185,7 @@ " $ *** $ *** $$ ", " *** $$ *** $" ], - "terrain": { - " ": [ "t_dirt", "t_grass_long", "t_grass_long", "t_grass", "t_grass", "t_grass", "t_grass" ], - "*": [ "t_dirt", "t_dirt", "t_dirt", "t_dirt", "t_dirt", "t_dirt", "t_grass" ], - "$": [ "t_shrub", "t_shrub", "t_underbrush", "t_grass", "t_dirt" ], - "7": [ "t_tree_apple", "t_tree_apple", "t_tree_dead" ] - }, + "palettes": [ "orchard_tree_apple" ], "place_monsters": [ { "monster": "GROUP_PEST", "x": [ 1, 22 ], "y": [ 1, 22 ], "chance": 60 }, { "monster": "GROUP_DOMESTIC", "x": [ 1, 22 ], "y": [ 1, 22 ], "chance": 40 }, @@ -281,12 +227,7 @@ "$ *** $ *** $$ ", " $*** $$ *** $" ], - "terrain": { - " ": [ "t_dirt", "t_grass_long", "t_grass_long", "t_grass", "t_grass", "t_grass", "t_grass" ], - "*": [ "t_dirt", "t_dirt", "t_dirt", "t_dirt", "t_dirt", "t_dirt", "t_grass" ], - "$": [ "t_shrub", "t_shrub", "t_underbrush", "t_grass", "t_dirt" ], - "7": [ "t_tree_apple", "t_tree_apple", "t_tree_dead" ] - }, + "palettes": [ "orchard_tree_apple" ], "place_monsters": [ { "monster": "GROUP_PEST", "x": [ 1, 22 ], "y": [ 1, 22 ], "chance": 60 }, { "monster": "GROUP_DOMESTIC", "x": [ 1, 22 ], "y": [ 1, 22 ], "chance": 50 }, @@ -328,12 +269,7 @@ "$ *** $ $ $$ ", " $*** $$ $ $" ], - "terrain": { - " ": [ "t_dirt", "t_grass_long", "t_grass_long", "t_grass", "t_grass", "t_grass", "t_grass" ], - "*": [ "t_dirt", "t_dirt", "t_dirt", "t_dirt", "t_dirt", "t_dirt", "t_grass" ], - "$": [ "t_shrub", "t_shrub", "t_underbrush", "t_grass", "t_dirt" ], - "7": [ "t_tree_apple", "t_tree_apple", "t_tree_dead" ] - }, + "palettes": [ "orchard_tree_apple" ], "place_monsters": [ { "monster": "GROUP_PEST", "x": [ 1, 22 ], "y": [ 1, 22 ], "chance": 60 }, { "monster": "GROUP_DOMESTIC", "x": [ 1, 22 ], "y": [ 1, 22 ], "chance": 50 }, @@ -341,5 +277,82 @@ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "chance": 25 } ] } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "orchard_processing_roof" ], + "object": { + "fill_ter": "t_tile_flat_roof", + "rows": [ + " ", + " ", + " ", + " ", + " ", + " |22222222222222223 ", + " |................3 ", + " |.:...........7..3 ", + " |................3 ", + " |..6......###....3 ", + " |.........#z#....3 ", + " |.........###....3 ", + " |................3 ", + " |................3 ", + " |................3 ", + " |................3 ", + " |---5------------3 ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "roof_palette" ], + "terrain": { "z": "t_ladder_down" }, + "nested": { + "6": { "chunks": [ [ "null", 20 ], [ "roof_6x6_garden_3", 80 ] ] }, + "7": { "chunks": [ [ "null", 20 ], [ "roof_2x2_infrastructure", 40 ], [ "roof_2x2_infrastructure_2", 40 ] ] } + } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "orchard_stall_roof" ], + "weight": 500, + "object": { + "fill_ter": "t_tile_flat_roof", + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " |5222222223 ", + " |.........3 ", + " |.......6.3 ", + " |.........3 ", + " |.......6.3 ", + " |.........3 ", + " |.........3 ", + " |.........3 ", + " ----------3 ", + " ", + " " + ], + "palettes": [ "roof_palette" ], + "nested": { "6": { "chunks": [ [ "null", 30 ], [ "roof_2x2_utilities", 30 ], [ "roof_2x2_utilities_c", 40 ] ] } } + } } ] diff --git a/data/json/mapgen_palettes/orchard_apple.json b/data/json/mapgen_palettes/orchard_apple.json new file mode 100644 index 0000000000000..8c28ab2c713c5 --- /dev/null +++ b/data/json/mapgen_palettes/orchard_apple.json @@ -0,0 +1,65 @@ +[ + { + "type": "palette", + "id": "orchard_buildings", + "terrain": { + "*": "t_dirt", + "$": [ [ "t_shrub", 5 ], "t_underbrush" ], + "+": "t_door_c", + "=": "t_door_metal_locked", + "&": "t_door_metal_c", + ".": "t_pavement", + ",": "t_floor", + "^": "t_gutter_downspout", + "7": "t_tree", + "b": "t_dirt", + "M": "t_wall_metal", + "m": "t_metal_floor", + "C": "t_floor", + "]": "t_sidewalk", + "k": "t_floor", + "o": "t_window_empty", + "x": "t_window", + "G": "t_gates_control_metal", + "g": "t_barndoor", + "W": "t_wall_wood", + "z": "t_ladder_up", + "t": "t_dirt", + "Q": "t_fence_v", + "q": "t_fence_h", + "y": "t_pavement_y" + }, + "furniture": { + "C": "f_chair", + "E": "f_crate_o", + "O": "f_crate_o", + "X": "f_crate_c", + "Y": "f_crate_c", + "c": "f_counter", + "f": "f_rack", + "k": "f_desk", + "D": "f_trashcan", + "F": "f_fridge", + "P": "f_sign", + "S": "f_smoking_rack", + "T": "f_table", + "b": "f_bench", + "d": "f_dumpster", + "a": "f_wood_keg", + "s": "f_safe_o", + "t": "f_table", + "v": "f_oven", + "{": "f_sink" + } + }, + { + "type": "palette", + "id": "orchard_tree_apple", + "terrain": { + " ": [ [ "t_grass", 3 ], [ "t_grass_long", 2 ], "t_dirt" ], + "*": [ [ "t_dirt", 5 ], "t_grass" ], + "$": [ [ "t_shrub", 2 ], "t_underbrush", "t_grass", "t_dirt" ], + "7": [ [ "t_tree_apple", 4 ], [ "t_tree_young", 2 ], "t_tree_dead" ] + } + } +] diff --git a/data/json/overmap/overmap_special/specials.json b/data/json/overmap/overmap_special/specials.json index 45715665471ee..85468692ae508 100644 --- a/data/json/overmap/overmap_special/specials.json +++ b/data/json/overmap/overmap_special/specials.json @@ -3796,7 +3796,9 @@ { "point": [ 0, 3, 0 ], "overmap": "pond_field_north" }, { "point": [ 1, 3, 0 ], "overmap": "orchard_tree_apple_north" }, { "point": [ 2, 3, 0 ], "overmap": "orchard_tree_apple_north" }, - { "point": [ 3, 3, 0 ], "overmap": "orchard_tree_apple_north" } + { "point": [ 3, 3, 0 ], "overmap": "orchard_tree_apple_north" }, + { "point": [ 0, 0, 1 ], "overmap": "orchard_processing_roof_north" }, + { "point": [ 0, 1, 1 ], "overmap": "orchard_stall_roof_north" } ], "connections": [ { "point": [ -1, 1, 0 ], "terrain": "road", "connection": "local_road", "from": [ 0, 1, 0 ] } ], "locations": [ "wilderness" ], diff --git a/data/json/overmap/overmap_terrain/overmap_terrain_agricultural.json b/data/json/overmap/overmap_terrain/overmap_terrain_agricultural.json index 5a2e2ccef9845..ce31bf7a15cbe 100644 --- a/data/json/overmap/overmap_terrain/overmap_terrain_agricultural.json +++ b/data/json/overmap/overmap_terrain/overmap_terrain_agricultural.json @@ -317,6 +317,22 @@ "color": "i_light_green", "mondensity": 3 }, + { + "type": "overmap_terrain", + "id": "orchard_processing_roof", + "copy-from": "generic_rural_building", + "name": "orchard processing roof", + "sym": "T", + "color": "i_light_green" + }, + { + "type": "overmap_terrain", + "id": "orchard_stall_roof", + "copy-from": "generic_rural_building", + "name": "orchard stall roof", + "sym": "T", + "color": "i_light_green" + }, { "type": "overmap_terrain", "id": [ From c10ea6aa59bf3e8511d44e0eaee17abca2a2084d Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Fri, 9 Jul 2021 15:47:39 +0100 Subject: [PATCH 095/116] Add Woodwork Craft Shop (#49582) * Added a woodwork variety of craft shop. * Added an extinguisher spawn and a new line to match the style. * Corrected spacing * Toned down item spawns, added items to woodcrafts itemgroup and removed unnecessary rows and terrain from 1x1_woodcrafts_display_canoe. * Removed a naughty comma. * Removed rude comma and linted. --- data/json/itemgroups/Clothing_Gear/gear.json | 7 + data/json/itemgroups/art_antiques_crafts.json | 18 ++ data/json/itemgroups/books.json | 21 ++ data/json/itemgroups/supplies.json | 5 + data/json/mapgen/Woodworker.json | 214 ++++++++++++++++++ data/json/mapgen/nested/retail_nested.json | 89 ++++++++ .../overmap/multitile_city_buildings.json | 10 + .../overmap_terrain_commercial.json | 6 +- 8 files changed, 367 insertions(+), 3 deletions(-) create mode 100644 data/json/mapgen/Woodworker.json diff --git a/data/json/itemgroups/Clothing_Gear/gear.json b/data/json/itemgroups/Clothing_Gear/gear.json index 511091cbaba4d..b0c222207bca6 100644 --- a/data/json/itemgroups/Clothing_Gear/gear.json +++ b/data/json/itemgroups/Clothing_Gear/gear.json @@ -199,5 +199,12 @@ "prob": 20 } ] + }, + { + "id": "SUS_woodcrafts_gear", + "type": "item_group", + "//": "This group is for lockers storing safety gear for woodcrafts. SUS item groups are collections that contain a reasonable realistic distribution of items that might spawn in a given storage furniture.", + "subtype": "collection", + "items": [ [ "glasses_safety", 95 ], [ "mask_dust", 30 ], [ "gloves_work", 30 ], [ "apron_leather", 95 ] ] } ] diff --git a/data/json/itemgroups/art_antiques_crafts.json b/data/json/itemgroups/art_antiques_crafts.json index d1e5a376777c1..734b6c227a3b8 100644 --- a/data/json/itemgroups/art_antiques_crafts.json +++ b/data/json/itemgroups/art_antiques_crafts.json @@ -274,5 +274,23 @@ { "item": "ceramic_cup", "prob": 15 }, { "item": "jug_clay", "prob": 15 } ] + }, + { + "type": "item_group", + "id": "woodcrafts", + "items": [ + [ "holy_symbol_wood", 20 ], + [ "hand_paddles", 10 ], + [ "pipe_tobacco", 10 ], + [ "ukulele", 10 ], + [ "clogs", 20 ], + [ "canteen_wood", 10 ], + [ "pet_carrier_wooden", 10 ], + [ "wooden_barrel", 10 ], + [ "wooden_bead", 5 ], + [ "bead_bracelet", 5 ], + [ "bead_ear", 5 ], + [ "bead_necklace", 5 ] + ] } ] diff --git a/data/json/itemgroups/books.json b/data/json/itemgroups/books.json index 89ce24a5474b4..3dd85e9513e23 100644 --- a/data/json/itemgroups/books.json +++ b/data/json/itemgroups/books.json @@ -694,6 +694,27 @@ { "item": "textbook_tailor", "prob": 30 } ] }, + { + "id": "fabricationbooks", + "type": "item_group", + "subtype": "distribution", + "entries": [ + { "item": "mag_fabrication", "prob": 50 }, + { "item": "manual_fabrication", "prob": 35 }, + { "item": "textbook_fabrication", "prob": 15 } + ] + }, + { + "id": "carpentrybooks", + "type": "item_group", + "subtype": "distribution", + "entries": [ + { "item": "mag_carpentry", "prob": 35 }, + { "item": "101_carpentry", "prob": 30 }, + { "item": "textbook_carpentry", "prob": 20 }, + { "item": "carpentry_book", "prob": 5 } + ] + }, { "id": "magazines", "type": "item_group", diff --git a/data/json/itemgroups/supplies.json b/data/json/itemgroups/supplies.json index 79c14f01ab9b7..c50135c7626b4 100644 --- a/data/json/itemgroups/supplies.json +++ b/data/json/itemgroups/supplies.json @@ -199,6 +199,11 @@ [ "pine_bough", 3 ] ] }, + { + "type": "item_group", + "id": "supplies_woodcrafts", + "items": [ [ "superglue", 40 ], [ "sandpaper", 40 ], [ "screwdriver", 5 ], [ "chisel", 10 ], [ "hammer", 5 ] ] + }, { "id": "supplies_hardware", "type": "item_group", diff --git a/data/json/mapgen/Woodworker.json b/data/json/mapgen/Woodworker.json new file mode 100644 index 0000000000000..d8de8168e8368 --- /dev/null +++ b/data/json/mapgen/Woodworker.json @@ -0,0 +1,214 @@ +[ + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "craft_shop_3" ], + "weight": 200, + "object": { + "fill_ter": "t_floor", + "rows": [ + ",,s,pppyppp,,,,,,,,,ss,,", + ",OmOGGGGGGGOOWWWWWOOddO,", + ",OsMpppypppOf4fffπfOffO,", + ",OsFpppypppOffffffffffO,", + ",OsFpppypppOfnfnfnffffO,", + ",OsFpppypppOfnfnfnffffO,", + ",OsFpppypppOffffffffffO,", + ",OoOpppypppOfπππfkCkffO,", + ",FsspppypppOffffffcOffO,", + ",FsspppypppOOWWWWWOOffO,", + ",FsspppypppOfffffffOffO,", + ",FsspppypppORf3ffffdffO,", + ",FsspppypppOBffffffOffO,", + ",FsspppypppORffffffO<>O ", + " wpfdfffffffO ", + " OOOOoOOOOOOO ", + " OfffffO66F6O ", + " wsffffofff6O ", + " ORssbfOfff6O ", + " OOwOOOOOwwOO ", + " |..........4 ", + " |..........3 ", + " |----------5 ", + " " + ], + "terrain": { + " ": "t_open_air", + ".": "t_tile_flat_roof", + ">": "t_stairs_down", + "-": "t_gutter_south", + "|": "t_gutter_east", + "3": "t_gutter_west", + "4": "t_gutter_downspout", + "5": "t_gutter_drop", + "d": "t_door_c", + "f": "t_floor", + "g": "t_door_glass_c", + "H": "t_water_dispenser", + "o": "t_door_o", + "O": "t_wall_g", + "r": "t_glass_railing", + "w": "t_window_no_curtains", + "W": "t_wall_glass" + }, + "furniture": { + "6": "f_counter", + "b": "f_trashcan", + "B": "f_bookcase", + "c": "f_chair", + "C": "f_console_broken", + "F": "f_fridge", + "k": "f_desk", + "l": "f_stool", + "M": "f_machinery_light", + "R": "f_locker", + "s": "f_sink", + "t": "f_table" + }, + "toilets": { "p": { } }, + "items": { + "b": { "item": "trash", "chance": 80 }, + "F": { "item": "fridge", "chance": 50, "repeat": [ 2, 4 ] }, + "k": [ { "item": "file_room", "chance": 40, "repeat": [ 1, 3 ] }, { "item": "writing_utensils", "chance": 30 } ], + "s": [ { "item": "SUS_kitchen_sink", "chance": 20 }, { "item": "cleaning", "chance": 20, "repeat": [ 2, 4 ] } ], + "t": { "item": "dinnerware", "chance": 20, "repeat": [ 1, 5 ] }, + "p": { "item": "SUS_toilet", "chance": 30 }, + "R": { "item": "SUS_woodcrafts_gear", "chance": 95 }, + "B": [ + { "item": "carpentrybooks", "chance": 50, "repeat": [ 1, 3 ] }, + { "item": "fabricationbooks", "chance": 10, "repeat": [ 1, 3 ] } + ], + "6": [ { "item": "SUS_junk_drawer", "chance": 20 } ] + }, + "place_item": [ { "item": "coffeemaker", "x": 14, "y": 8, "chance": 100 }, { "item": "toaster", "x": 21, "y": 16, "chance": 70 } ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "craft_shop_roof_3", + "object": { + "fill_ter": "t_tile_flat_roof", + "rows": [ + " ", + " |222222222222222222223 ", + " |.........ooo...ooo..3 ", + " |.A.......ooo...ooo..3 ", + " |.........ooo...ooo..3 ", + " |....................3 ", + " |....................3 ", + " |---------|..........3 ", + " |..........3 ", + " |..........3 ", + " |..........3 ", + " |..........3 ", + " |..........3 ", + " |..........3 ", + " |..........3 ", + " |..........3 ", + " |..........3 ", + " |......=.=.3 ", + " |..........3 ", + " |----------5 ", + " ", + " ", + " ", + " " + ], + "palettes": [ "roof_palette" ] + } + } +] diff --git a/data/json/mapgen/nested/retail_nested.json b/data/json/mapgen/nested/retail_nested.json index 659a09c1baa5c..7fefcb8f93272 100644 --- a/data/json/mapgen/nested/retail_nested.json +++ b/data/json/mapgen/nested/retail_nested.json @@ -1500,5 +1500,94 @@ "Y": { "item": "trash", "chance": 30, "repeat": [ 1, 4 ] } } } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "3x3_woodcrafts_crates", + "//": "designed for the back of the woodwork craftshop", + "object": { + "mapgensize": [ 3, 3 ], + "rotation": [ 0, 3 ], + "rows": [ + " z", + " zz", + "zzz" + ], + "terrain": { " ": "t_null" }, + "furniture": { "z": [ [ "f_crate_c", 2 ], [ "f_crate_o", 1 ], [ "f_null", 3 ] ] }, + "items": { "z": { "item": "wood_workshop", "chance": 20, "repeat": [ 3, 5 ] } } + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "4x4_woodcrafts_table_vertical", + "//": "designed for the large workbench tables in the woodwork craftshop", + "object": { + "mapgensize": [ 4, 4 ], + "rotation": [ 0, 3 ], + "rows": [ + "ttt ", + "ttt ", + "ttt ", + "ttt " + ], + "terrain": { " ": "t_null" }, + "furniture": { "t": "f_table" }, + "item": { "t": { "item": "sandpaper", "chance": 17 } }, + "place_item": [ { "item": "clamp", "x": 0, "y": [ 0, 3 ], "chance": 80 }, { "item": "clamp", "x": 2, "y": [ 0, 3 ], "chance": 80 } ] + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "4x4_woodcrafts_table_horizontal", + "//": "designed for the large workbench tables in the woodwork craftshop", + "object": { + "mapgensize": [ 4, 4 ], + "rotation": [ 0, 3 ], + "rows": [ + "tttt", + "tttt", + "tttt", + " " + ], + "terrain": { " ": "t_null" }, + "furniture": { "t": "f_table" }, + "item": { "t": { "item": "sandpaper", "chance": 17 } }, + "place_item": [ { "item": "clamp", "x": [ 0, 3 ], "y": 0, "chance": 80 }, { "item": "clamp", "x": [ 0, 3 ], "y": 2, "chance": 80 } ] + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "4x4_woodcrafts_display_nocanoe", + "//": "designed for the window display of the woodwork craftshop", + "object": { + "mapgensize": [ 4, 4 ], + "rotation": [ 0, 3 ], + "rows": [ + "ππππ", + " ", + " ", + " ", + " " + ], + "terrain": { " ": "t_null" }, + "furniture": { "π": "f_displaycase" }, + "items": { "π": { "item": "woodcrafts", "chance": 100, "repeat": [ 1, 3 ] } } + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "1x1_woodcrafts_display_canoe", + "//": "designed for the window display of the woodwork craftshop", + "object": { + "mapgensize": [ 1, 1 ], + "rotation": [ 0, 3 ], + "place_vehicles": [ { "vehicle": "canoe", "x": 2, "y": 0, "chance": 100, "rotation": 180, "fuel": 0, "status": 0 } ] + } } ] diff --git a/data/json/overmap/multitile_city_buildings.json b/data/json/overmap/multitile_city_buildings.json index 7819a4433a62d..1cd34ec73777f 100644 --- a/data/json/overmap/multitile_city_buildings.json +++ b/data/json/overmap/multitile_city_buildings.json @@ -3321,6 +3321,16 @@ { "point": [ 0, 0, 2 ], "overmap": "craft_shop_roof_2_north" } ] }, + { + "type": "city_building", + "id": "craft_shop_3", + "locations": [ "land" ], + "overmaps": [ + { "point": [ 0, 0, 0 ], "overmap": "craft_shop_3_north" }, + { "point": [ 0, 0, 1 ], "overmap": "craft_shop_2ndfloor_3_north" }, + { "point": [ 0, 0, 2 ], "overmap": "craft_shop_roof_3_north" } + ] + }, { "type": "city_building", "id": "pool", diff --git a/data/json/overmap/overmap_terrain/overmap_terrain_commercial.json b/data/json/overmap/overmap_terrain/overmap_terrain_commercial.json index dfba53e9ffe20..6df3392f2db5d 100644 --- a/data/json/overmap/overmap_terrain/overmap_terrain_commercial.json +++ b/data/json/overmap/overmap_terrain/overmap_terrain_commercial.json @@ -1241,7 +1241,7 @@ }, { "type": "overmap_terrain", - "id": [ "craft_shop", "craft_shop_1", "craft_shop_2" ], + "id": [ "craft_shop", "craft_shop_1", "craft_shop_2", "craft_shop_3" ], "copy-from": "generic_city_building", "name": "craft shop", "sym": "s", @@ -1258,7 +1258,7 @@ }, { "type": "overmap_terrain", - "id": [ "craft_shop_roof", "craft_shop_roof_1", "craft_shop_roof_2" ], + "id": [ "craft_shop_roof", "craft_shop_roof_1", "craft_shop_roof_2", "craft_shop_roof_3" ], "copy-from": "generic_city_building", "name": "craft shop roof", "sym": "s", @@ -1266,7 +1266,7 @@ }, { "type": "overmap_terrain", - "id": "craft_shop_2ndfloor_2", + "id": [ "craft_shop_2ndfloor_2", "craft_shop_2ndfloor_3" ], "name": "craft shop 2nd floor", "copy-from": "generic_city_building", "sym": "s", From 62624807415e27b1ad242a3c2f3b0180dfbf3296 Mon Sep 17 00:00:00 2001 From: eltank <8000047+eltank@users.noreply.github.com> Date: Fri, 9 Jul 2021 07:49:20 -0700 Subject: [PATCH 096/116] Implement SAFE_AT_WORLGEN json flag (#49377) --- .../overmap/overmap_special/specials.json | 12 ++--- doc/JSON_FLAGS.md | 1 + src/overmap.cpp | 50 ++++++++++++++----- src/overmap.h | 4 ++ src/overmapbuffer.cpp | 2 +- 5 files changed, 49 insertions(+), 20 deletions(-) diff --git a/data/json/overmap/overmap_special/specials.json b/data/json/overmap/overmap_special/specials.json index 85468692ae508..18de71f1ea0cc 100644 --- a/data/json/overmap/overmap_special/specials.json +++ b/data/json/overmap/overmap_special/specials.json @@ -3386,7 +3386,7 @@ "city_distance": [ 3, -1 ], "city_sizes": [ 4, -1 ], "occurrences": [ 75, 100 ], - "flags": [ "UNIQUE" ] + "flags": [ "UNIQUE", "SAFE_AT_WORLDGEN" ] }, { "type": "overmap_special", @@ -3396,7 +3396,7 @@ "city_distance": [ 20, -1 ], "city_sizes": [ 4, -1 ], "occurrences": [ 80, 100 ], - "flags": [ "CLASSIC", "WILDERNESS", "UNIQUE" ] + "flags": [ "CLASSIC", "WILDERNESS", "UNIQUE", "SAFE_AT_WORLDGEN" ] }, { "type": "overmap_special", @@ -3411,7 +3411,7 @@ "city_distance": [ 20, -1 ], "city_sizes": [ 4, -1 ], "occurrences": [ 50, 100 ], - "flags": [ "CLASSIC", "WILDERNESS", "UNIQUE" ] + "flags": [ "CLASSIC", "WILDERNESS", "UNIQUE", "SAFE_AT_WORLDGEN" ] }, { "type": "overmap_special", @@ -3568,7 +3568,7 @@ "city_distance": [ 3, -1 ], "rotate": false, "occurrences": [ 30, 100 ], - "flags": [ "UNIQUE" ] + "flags": [ "UNIQUE", "SAFE_AT_WORLDGEN" ] }, { "type": "overmap_special", @@ -4517,7 +4517,7 @@ "city_sizes": [ 1, 16 ], "occurrences": [ 33, 100 ], "rotate": false, - "flags": [ "UNIQUE" ] + "flags": [ "UNIQUE", "SAFE_AT_WORLDGEN" ] }, { "type": "overmap_special", @@ -6772,7 +6772,7 @@ "occurrences": [ 35, 100 ], "//": "Inflated chance, effective rate ~19% (n=726)", "connections": [ { "point": [ -1, 15, 0 ], "terrain": "road" } ], - "flags": [ "FARM", "UNIQUE" ] + "flags": [ "FARM", "UNIQUE", "SAFE_AT_WORLDGEN" ] }, { "id": "airliner_crashed", diff --git a/doc/JSON_FLAGS.md b/doc/JSON_FLAGS.md index 441a6dcd4f493..cb2dbffed4c55 100644 --- a/doc/JSON_FLAGS.md +++ b/doc/JSON_FLAGS.md @@ -1145,6 +1145,7 @@ These branches are also the valid entries for the categories of `dreams` in `dre - ```FUNGAL``` Location is related to fungi. Used to classify location. - ```LAKE``` Location is is placed on a lake and will be ignored for placement if the overmap doesn't contain any lake terrain. - ```MI-GO``` Location is related to mi-go. +- ```SAFE_AT_WORLDGEN``` Location will not spawn overmap monster groups during worldgen (does not affect monsters spawned by mapgen). - ```TRIFFID``` Location is related to triffids. Used to classify location. - ```UNIQUE``` Location is unique and will only occur once per overmap. `occurrences` is overridden to define a percent chance (e.g. `"occurrences" : [75, 100]` is 75%) - ```URBAN``` diff --git a/src/overmap.cpp b/src/overmap.cpp index 2c55fc4a85765..1b500ee86ad0c 100644 --- a/src/overmap.cpp +++ b/src/overmap.cpp @@ -1712,13 +1712,13 @@ bool overmap::generate_sub( const int z ) tripoint_om_sm sm_pos = project_to( omt_pos ); // Sewers and city subways are present at z == -1 and z == -2. Don't spawn CHUD on other z-levels. if( ( z == -1 || z == -2 ) && one_in( 3 ) ) { - add_mon_group( mongroup( GROUP_CHUD, - sm_pos, i.size, i.size * 20 ) ); + spawn_mon_group( mongroup( GROUP_CHUD, + sm_pos, i.size, i.size * 20 ) ); } // Sewers are present at z == -1. Don't spawn sewer monsters on other z-levels. if( z == -1 && !one_in( 8 ) ) { - add_mon_group( mongroup( GROUP_SEWER, - sm_pos, ( i.size * 7 ) / 2, i.size * 70 ) ); + spawn_mon_group( mongroup( GROUP_SEWER, + sm_pos, ( i.size * 7 ) / 2, i.size * 70 ) ); } } @@ -1733,7 +1733,7 @@ bool overmap::generate_sub( const int z ) } mongroup_id ant_group( ter( p_loc + tripoint_above ) == "anthill" ? "GROUP_ANT" : "GROUP_ANT_ACID" ); - add_mon_group( + spawn_mon_group( mongroup( ant_group, tripoint_om_sm( project_to( i.pos ), z ), ( i.size * 3 ) / 2, rng( 6000, 8000 ) ) ); build_anthill( p_loc, i.size, ter( p_loc + tripoint_above ) == "anthill" ); @@ -4077,6 +4077,7 @@ void overmap::place_special( } const bool blob = special.flags.count( "BLOB" ) > 0; + const bool is_safe_zone = special.flags.count( "SAFE_AT_WORLDGEN" ) > 0; for( const auto &elem : special.terrains ) { const tripoint_om_omt location = p + om_direction::rotate( elem.p, dir ); @@ -4084,6 +4085,9 @@ void overmap::place_special( overmap_special_placements[location] = special.id; ter_set( location, tid ); + if( is_safe_zone ) { + safe_at_worldgen.emplace( location ); + } if( blob ) { for( int x = -2; x <= 2; x++ ) { @@ -4128,7 +4132,18 @@ void overmap::place_special( const overmap_special_spawns &spawns = special.spawns; const int pop = rng( spawns.population.min, spawns.population.max ); const int rad = rng( spawns.radius.min, spawns.radius.max ); - add_mon_group( mongroup( spawns.group, project_to( p ), rad, pop ) ); + spawn_mon_group( mongroup( spawns.group, project_to( p ), rad, pop ) ); + } + // If it's a safe zone, remove existing spawns + if( is_safe_zone ) { + for( auto it = zg.begin(); it != zg.end(); ) { + tripoint_om_omt pos = project_to( it->second.pos ); + if( safe_at_worldgen.find( pos ) != safe_at_worldgen.end() ) { + zg.erase( it++ ); + } else { + ++it; + } + } } } @@ -4364,8 +4379,8 @@ void overmap::place_mongroups() } } if( swamp_count >= 25 ) { - add_mon_group( mongroup( GROUP_SWAMP, tripoint( x * 2, y * 2, 0 ), 3, - rng( swamp_count * 8, swamp_count * 25 ) ) ); + spawn_mon_group( mongroup( GROUP_SWAMP, tripoint( x * 2, y * 2, 0 ), 3, + rng( swamp_count * 8, swamp_count * 25 ) ) ); } } } @@ -4383,8 +4398,8 @@ void overmap::place_mongroups() } } if( river_count >= 25 ) { - add_mon_group( mongroup( GROUP_RIVER, tripoint( x * 2, y * 2, 0 ), 3, - rng( river_count * 8, river_count * 25 ) ) ); + spawn_mon_group( mongroup( GROUP_RIVER, tripoint( x * 2, y * 2, 0 ), 3, + rng( river_count * 8, river_count * 25 ) ) ); } } } @@ -4392,9 +4407,9 @@ void overmap::place_mongroups() // Place the "put me anywhere" groups int numgroups = rng( 0, 3 ); for( int i = 0; i < numgroups; i++ ) { - add_mon_group( mongroup( GROUP_WORM, tripoint( rng( 0, OMAPX * 2 - 1 ), rng( 0, - OMAPY * 2 - 1 ), 0 ), - rng( 20, 40 ), rng( 30, 50 ) ) ); + spawn_mon_group( mongroup( GROUP_WORM, tripoint( rng( 0, OMAPX * 2 - 1 ), rng( 0, + OMAPY * 2 - 1 ), 0 ), + rng( 20, 40 ), rng( 30, 50 ) ) ); } } @@ -4472,6 +4487,15 @@ void overmap::save() const } ); } +void overmap::spawn_mon_group( const mongroup &group ) +{ + tripoint_om_omt pos = project_to( group.pos ); + if( safe_at_worldgen.find( pos ) != safe_at_worldgen.end() ) { + return; + } + add_mon_group( group ); +} + void overmap::add_mon_group( const mongroup &group ) { // Monster groups: the old system had large groups (radius > 1), diff --git a/src/overmap.h b/src/overmap.h index e1b64da5cfb50..7050a3cf3ad97 100644 --- a/src/overmap.h +++ b/src/overmap.h @@ -365,6 +365,8 @@ class overmap // can be used after placement to lookup whether a given location was created // as part of a special. std::unordered_map overmap_special_placements; + // Records location where mongroups are not allowed to spawn during worldgen. + std::unordered_set safe_at_worldgen; regional_settings settings; @@ -509,6 +511,8 @@ class overmap void place_radios(); void add_mon_group( const mongroup &group ); + // Spawns a new mongroup (to be called by worldgen code) + void spawn_mon_group( const mongroup &group ); void load_monster_groups( JsonIn &jsin ); void load_legacy_monstergroups( JsonIn &jsin ); diff --git a/src/overmapbuffer.cpp b/src/overmapbuffer.cpp index e021bbc878cb9..d91439c85466c 100644 --- a/src/overmapbuffer.cpp +++ b/src/overmapbuffer.cpp @@ -136,7 +136,7 @@ void overmapbuffer::fix_mongroups( overmap &new_overmap ) } overmap &om = get( omp ); mg.pos = tripoint_om_sm( sm_rem, mg.pos.z() ); - om.add_mon_group( mg ); + om.spawn_mon_group( mg ); new_overmap.zg.erase( it++ ); } } From d33c60e4ddb95d74c08a4e6a7f4530b9c6a66d4e Mon Sep 17 00:00:00 2001 From: Saicchi <47158232+Saicchi@users.noreply.github.com> Date: Fri, 9 Jul 2021 11:52:41 -0300 Subject: [PATCH 097/116] Jsonize Monster Shearing (#49002) * shearing basic implementation * shearing activity_actor conversion * add shearing activity tests * convert sheep to new shearable * fix quality test error Co-authored-by: Binrui Dong * rename file ending in _tests to _test * rebase jsonizeshearing to cdda-experimental-2021-07-07-1531 Co-authored-by: Saicchi Co-authored-by: Binrui Dong --- data/json/monsters/mammal.json | 14 +- data/json/player_activities.json | 4 +- data/mods/TEST_DATA/items.json | 54 ++++++ data/mods/TEST_DATA/monsters.json | 30 ++++ doc/MONSTERS.md | 28 +++ src/activity_actor.cpp | 160 ++++++++++++++++- src/activity_actor_definitions.h | 35 ++++ src/activity_handlers.cpp | 37 ---- src/debug.cpp | 1 + src/debug.h | 1 + src/monexamine.cpp | 26 +-- src/monster.h | 4 + src/monstergenerator.cpp | 10 ++ src/mtype.h | 2 + src/shearing.cpp | 76 ++++++++ src/shearing.h | 53 ++++++ tests/player_activities_test.cpp | 280 ++++++++++++++++++++++++++++++ 17 files changed, 750 insertions(+), 65 deletions(-) create mode 100644 data/mods/TEST_DATA/monsters.json create mode 100644 src/shearing.cpp create mode 100644 src/shearing.h create mode 100644 tests/player_activities_test.cpp diff --git a/data/json/monsters/mammal.json b/data/json/monsters/mammal.json index dcf74bac048d7..ffefcfb1b68d0 100644 --- a/data/json/monsters/mammal.json +++ b/data/json/monsters/mammal.json @@ -2249,6 +2249,7 @@ "dodge": 2, "starting_ammo": { "milk_raw": 5 }, "anger_triggers": [ ], + "shearing": [ { "result": "wool_staple", "amount": 22 } ], "harvest": "mammal_large_wool", "reproduction": { "baby_monster": "mon_sheep_lamb", "baby_count": 1, "baby_timer": 275 }, "//": "Sheep are seasonal breeders. The natural sexual season is positioned so that lambs will be born in the spring when the weather is warmer and grass is available.", @@ -2258,18 +2259,7 @@ "placate_triggers": [ "PLAYER_WEAK" ], "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_CROP", 120 ] ], - "flags": [ - "SEES", - "HEARS", - "SMELLS", - "ANIMAL", - "SHEARABLE", - "PATH_AVOID_DANGER_1", - "WARM", - "CATTLEFODDER", - "PET_WONT_FOLLOW", - "MILKABLE" - ] + "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "CATTLEFODDER", "PET_WONT_FOLLOW", "MILKABLE" ] }, { "id": "mon_squirrel", diff --git a/data/json/player_activities.json b/data/json/player_activities.json index f628c3d20b141..37a5d65db1003 100644 --- a/data/json/player_activities.json +++ b/data/json/player_activities.json @@ -506,13 +506,13 @@ "no_resume": true }, { - "id": "ACT_SHEAR", + "id": "ACT_SHEARING", "type": "activity_type", "activity_level": "MODERATE_EXERCISE", "verb": "shearing an animal", "suspendable": false, "rooted": true, - "based_on": "time", + "based_on": "speed", "no_resume": true }, { diff --git a/data/mods/TEST_DATA/items.json b/data/mods/TEST_DATA/items.json index f16ef6c0011d1..e78a34a778069 100644 --- a/data/mods/TEST_DATA/items.json +++ b/data/mods/TEST_DATA/items.json @@ -94,6 +94,60 @@ "price": 7500, "price_postapoc": 300 }, + { + "type": "TOOL", + "id": "test_shears", + "name": { "str_sp": "shears" }, + "description": "This is a set of shears designed to obtain wool from sheep.", + "weight": "820 g", + "volume": "750 ml", + "price": 500, + "price_postapoc": 250, + "to_hit": -1, + "cutting": 3, + "material": [ "steel", "plastic" ], + "symbol": ";", + "color": "light_gray", + "qualities": [ [ "SHEAR", 1 ] ], + "flags": [ "STAB" ] + }, + { + "type": "TOOL", + "id": "test_shears_off", + "copy-from": "test_shears", + "name": { "str": "electric shears (off)" }, + "description": "This is a set of electric shears designed to obtain wool from sheep.", + "qualities": [ ], + "use_action": { + "type": "transform", + "msg": "Your %s activates.", + "target": "test_shears_on", + "active": true, + "need_charges": 1, + "need_charges_msg": "The shears batteries are dead." + }, + "pocket_data": [ + { + "pocket_type": "MAGAZINE_WELL", + "holster": true, + "rigid": true, + "max_contains_volume": "20 L", + "max_contains_weight": "20 kg", + "item_restriction": [ "test_battery_disposable" ] + } + ] + }, + { + "type": "TOOL", + "id": "test_shears_on", + "copy-from": "test_shears_off", + "name": { "str": "electric shears (on)" }, + "description": "This is a set of electric shears designed to obtain wool from sheep. These shears have been turned on.", + "power_draw": 10000, + "revert_to": "test_shears_off", + "use_action": { "type": "transform", "msg": "Your %s deactivates.", "target": "test_shears_off" }, + "qualities": [ [ "SHEAR", 3 ] ] + }, { "id": "test_tool_belt", "type": "ARMOR", diff --git a/data/mods/TEST_DATA/monsters.json b/data/mods/TEST_DATA/monsters.json new file mode 100644 index 0000000000000..6db3d5787cc82 --- /dev/null +++ b/data/mods/TEST_DATA/monsters.json @@ -0,0 +1,30 @@ +[ + { + "type": "MONSTER", + "id": "mon_test_non_shearable", + "name": { "str_sp": "non shearable monster" }, + "description": "An 8-legged beast of rugged greenish skin.", + "default_faction": "herbivore", + "material": [ "flesh" ], + "symbol": "S", + "volume": "81500 ml", + "weight": "81500 g", + "hp": 100, + "speed": 50, + "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "CATTLEFODDER", "PET_WONT_FOLLOW" ] + }, + { + "type": "MONSTER", + "id": "mon_test_shearable", + "copy-from": "mon_test_non_shearable", + "name": { "str_sp": "shearable monster" }, + "description": "An 8-legged beast of a surprisingly comfy sanguine fur.", + "//": "A random assortment of items to test shearing", + "shearing": [ + { "result": "test_rock", "amount": 30 }, + { "result": "test_2x4", "amount": [ 5, 10 ] }, + { "result": "test_rag", "ratio_mass": 0.5 }, + { "result": "test_pipe", "ratio_volume": 0.3 } + ] + } +] diff --git a/doc/MONSTERS.md b/doc/MONSTERS.md index 2eedc4a7ef2c4..cd178a3ba2f35 100644 --- a/doc/MONSTERS.md +++ b/doc/MONSTERS.md @@ -90,6 +90,7 @@ Monsters may also have any of these optional properties: | `harvest` | (string) ID of a "harvest" type describing what can be harvested from the corpse | `zombify_into` | (string) mtype_id this monster zombifies into after it's death | `fungalize_into` | (string) mtype_id this monster turns into when fungalized by spores +| `shearing` | (array of objects) Items produced when the monster is sheared Properties in the above tables are explained in more detail in the sections below. @@ -428,6 +429,33 @@ The monster's reproduction cycle, if any. Supports: (Array, optional) Designate seasons during which this monster is capable of reproduction. ie: `[ "SPRING", "SUMMER" ]` +## "shearing +(array of objects, optional) + +A set of items that are given to the player when they shear this monster. These entries can be duplicates and are one of these 4 types: +```json +"shearing": [ + { + "result": "wool", + "amount": 100 // exact amount + }, + { + "result": "rags", + "amount": [10, 100] // random number in range ( inclusive ) + }, + { + "result": "leather", + "ratio_mass": 0.25 // amount from percentage of mass ( kilograms ) + }, + { + "result": "wool", + "ratio_volume": 0.60 // amount from percentage of volume ( liters ) + } +] +``` + +This means that when this monster is sheared, it will give: 100 units of wool, 10 to 100 pieces of rag, 25% of its body mass as leather and 60% of its volume as wool. + ## "special_when_hit" (array, optional) diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index 8d2d7bd9d9ed0..b22bf09ad6d3a 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -65,6 +65,7 @@ #include "requirements.h" #include "ret_val.h" #include "rng.h" +#include "shearing.h" #include "sounds.h" #include "string_formatter.h" #include "timed_event.h" @@ -77,8 +78,8 @@ #include "vpart_position.h" static const efftype_id effect_pet( "pet" ); +static const efftype_id effect_sheared( "sheared" ); static const efftype_id effect_sleep( "sleep" ); - static const efftype_id effect_tied( "tied" ); static const itype_id itype_bone_human( "bone_human" ); @@ -100,6 +101,7 @@ static const mtype_id mon_skeleton( "mon_skeleton" ); static const mtype_id mon_zombie_crawler( "mon_zombie_crawler" ); static const quality_id qual_LOCKPICK( "LOCKPICK" ); +static const quality_id qual_SHEAR( "SHEAR" ); std::string activity_actor::get_progress_message( const player_activity &act ) const { @@ -2764,6 +2766,161 @@ std::unique_ptr milk_activity_actor::deserialize( JsonIn &jsin ) return actor.clone(); } +void shearing_activity_actor::start( player_activity &act, Character &who ) +{ + monster *mon = g->critter_at( mon_coords ); + if( !mon ) { + debugmsg( "shearing lost monster when starting" ); + act.set_to_null(); + return; + } + + std::string pet_name_capitalized = mon->unique_name.empty() ? mon->disp_name( false, + true ) : mon->unique_name; + + if( !mon->shearable() ) { + add_msg( _( "$1%s has nothing %2$s could shear." ), pet_name_capitalized, who.disp_name() ); + if( shearing_tie ) { + mon->remove_effect( effect_tied ); + } + act.set_to_null(); + return; + } + + const int shearing_quality = who.max_quality( qual_SHEAR ); + if( !( shearing_quality > 0 ) ) { + if( who.is_player() ) { + add_msg( m_info, _( "%1$s don't have a shearing tool." ), who.disp_name( false, true ) ); + } else { // who.is_npc + // npcs can't shear monsters yet, this is for when they are able to + add_msg_if_player_sees( who, _( "%1$s doesn't have a shearing tool." ), who.disp_name(), + mon->disp_name() ); + } + if( shearing_tie ) { + mon->remove_effect( effect_tied ); + } + act.set_to_null(); + return; + } + + const time_duration shearing_time = 30_minutes / shearing_quality; + add_msg_debug( debugmode::DF_ACT_SHEARING, "shearing_time time = %s", to_string( shearing_time ) ); + + if( who.is_player() ) { + add_msg( m_info, + _( "%1$s start shearing %2$s." ), who.disp_name( false, true ), mon->disp_name() ); + } else { // who.is_npc + // npcs can't shear monsters yet, this is for when they are able to + add_msg_if_player_sees( who, _( "%1$s starts shearing %2$s." ), who.disp_name(), + mon->disp_name() ); + } + + act.moves_total = to_moves( shearing_time ); + act.moves_left = act.moves_total; +} + +void shearing_activity_actor::do_turn( player_activity &, Character &who ) +{ + if( !who.has_quality( qual_SHEAR ) ) { + if( who.is_player() ) { + add_msg( + m_bad, + _( "%1$s don't have a shearing tool anymore." ), + who.disp_name( false, true ) ); + } else { + add_msg_if_player_sees( + who, + _( "%1$s doesn't have a shearing tool anymore." ), + who.disp_name() ); + } + who.cancel_activity(); + } +} + +void shearing_activity_actor::finish( player_activity &act, Character &who ) +{ + monster *mon = g->critter_at( mon_coords ); + if( !mon ) { + debugmsg( "shearing monster at position disappeared" ); + act.set_to_null(); + return; + } + + const shearing_data &shear_data = mon->type->shearing; + if( !shear_data.valid() ) { + debugmsg( "shearing monster does not have shearing_data" ); + if( shearing_tie ) { + mon->remove_effect( effect_tied ); + } + act.set_to_null(); + return; + } + + map &mp = get_map(); + + add_msg_if_player_sees( who, + string_format( + _( "%1$s finished shearing %2$s and got:" ), + who.disp_name( false, true ), + mon->unique_name.empty() ? mon->disp_name() : mon->unique_name ) ); + + const std::vector shear_roll = shear_data.roll_all( *mon ); + for( const shearing_roll &roll : shear_roll ) { + if( roll.result->count_by_charges() ) { + item shear_item( roll.result, calendar::turn, roll.amount ); + mp.add_item_or_charges( who.pos(), shear_item ); + add_msg_if_player_sees( who, shear_item.display_name() ); + } else { + item shear_item( roll.result, calendar::turn ); + for( int i = 0; i < roll.amount; ++i ) { + mp.add_item_or_charges( who.pos(), shear_item ); + } + add_msg_if_player_sees( who, + //~ %1$s - item, %2$d - amount + string_format( _( "%1$s x%2$d" ), + shear_item.display_name(), roll.amount ) ); + } + } + + mon->add_effect( effect_sheared, calendar::season_length() ); + if( shearing_tie ) { + mon->remove_effect( effect_tied ); + } + + act.set_to_null(); +} + +void shearing_activity_actor::canceled( player_activity &, Character & ) +{ + monster *mon = g->critter_at( mon_coords ); + if( !mon ) { + return; + } + + if( shearing_tie ) { + // free the poor critter + mon->remove_effect( effect_tied ); + } +} + +void shearing_activity_actor::serialize( JsonOut &jsout ) const +{ + jsout.start_object(); + jsout.member( "mon_coords", mon_coords ); + jsout.member( "shearing_tie", shearing_tie ); + jsout.end_object(); +} + +std::unique_ptr shearing_activity_actor::deserialize( JsonIn &jsin ) +{ + shearing_activity_actor actor = shearing_activity_actor( {} ); + + JsonObject data = jsin.get_object(); + data.read( "mon_coords", actor.mon_coords ); + data.read( "shearing_tie", actor.shearing_tie ); + return actor.clone(); +} + static bool check_if_disassemble_okay( item_location target, Character &who ) { item *disassembly = target.get_item(); @@ -3090,6 +3247,7 @@ deserialize_functions = { { activity_id( "ACT_PLAY_WITH_PET" ), &play_with_pet_activity_actor::deserialize }, { activity_id( "ACT_RELOAD" ), &reload_activity_actor::deserialize }, { activity_id( "ACT_SHAVE" ), &shave_activity_actor::deserialize }, + { activity_id( "ACT_SHEARING" ), &shearing_activity_actor::deserialize }, { activity_id( "ACT_STASH" ), &stash_activity_actor::deserialize }, { activity_id( "ACT_TENT_DECONSTRUCT" ), &tent_deconstruct_activity_actor::deserialize }, { activity_id( "ACT_TENT_PLACE" ), &tent_placement_activity_actor::deserialize }, diff --git a/src/activity_actor_definitions.h b/src/activity_actor_definitions.h index 378e508babe7b..15de610521fc3 100644 --- a/src/activity_actor_definitions.h +++ b/src/activity_actor_definitions.h @@ -928,6 +928,41 @@ class milk_activity_actor : public activity_actor std::vector string_values {}; }; +class shearing_activity_actor : public activity_actor +{ + private: + tripoint mon_coords; // monster is tied for the duration + bool shearing_tie; // was the monster tied due to shearing + + public: + explicit shearing_activity_actor( + const tripoint &mon_coords, bool shearing_tie = true ) + : mon_coords( mon_coords ), shearing_tie( shearing_tie ) {}; + + activity_id get_type() const override { + return activity_id( "ACT_SHEARING" ); + } + + void start( player_activity &act, Character &who ) override; + void do_turn( player_activity &/*act*/, Character &who ) override; + void finish( player_activity &act, Character &who ) override; + void canceled( player_activity &/*act*/, Character &/*who*/ ) override; + + bool can_resume_with_internal( const activity_actor &other, + const Character &/*who*/ ) const override { + const shearing_activity_actor &actor = static_cast + ( other ); + return actor.mon_coords == mon_coords; + } + + std::unique_ptr clone() const override { + return std::make_unique( *this ); + } + + void serialize( JsonOut &jsout ) const override; + static std::unique_ptr deserialize( JsonIn &jsin ); +}; + class disassemble_activity_actor : public activity_actor { private: diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 9e701b4b3d9b0..ea387b3622509 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -100,8 +100,6 @@ enum class creature_size : int; -static const efftype_id effect_sheared( "sheared" ); - #define dbg(x) DebugLog((x),D_GAME) << __FILE__ << ":" << __LINE__ << ": " static const activity_id ACT_ADV_INVENTORY( "ACT_ADV_INVENTORY" ); @@ -357,7 +355,6 @@ activity_handlers::finish_functions = { { ACT_HACKSAW, hacksaw_finish }, { ACT_PRY_NAILS, pry_nails_finish }, { ACT_CHOP_TREE, chop_tree_finish }, - { activity_id( "ACT_SHEAR" ), shear_finish }, { ACT_CHOP_LOGS, chop_logs_finish }, { ACT_CHOP_PLANKS, chop_planks_finish }, { ACT_JACKHAMMER, jackhammer_finish }, @@ -1413,40 +1410,6 @@ void activity_handlers::butcher_finish( player_activity *act, player *p ) resume_for_multi_activities( *p ); } -void activity_handlers::shear_finish( player_activity *act, player *p ) -{ - if( act->coords.empty() ) { - debugmsg( "shearing activity with no position of monster stored" ); - return; - } - item_location &loc = act->targets[ 0 ]; - item *shears = loc.get_item(); - if( shears == nullptr ) { - debugmsg( "shearing item location lost" ); - return; - } - map &here = get_map(); - const tripoint source_pos = here.getlocal( act->coords.at( 0 ) ); - monster *source_mon = g->critter_at( source_pos ); - if( source_mon == nullptr ) { - debugmsg( "could not find source creature for shearing" ); - return; - } - // 22 wool staples corresponds to an average wool-producing sheep yield of 10 lbs or so - for( int i = 0; i != 22; ++i ) { - item wool_staple( itype_wool_staple, calendar::turn ); - here.add_item_or_charges( p->pos(), wool_staple ); - } - source_mon->add_effect( effect_sheared, calendar::season_length() ); - if( !act->str_values.empty() && act->str_values[0] == "temp_tie" ) { - source_mon->remove_effect( effect_tied ); - } - act->set_to_null(); - if( shears->type->can_have_charges() ) { - p->consume_charges( *shears, shears->type->charges_to_use() ); - } -} - void activity_handlers::fill_liquid_do_turn( player_activity *act, player *p ) { player_activity &act_ref = *act; diff --git a/src/debug.cpp b/src/debug.cpp index 4742e8a7b6ed7..712b316df5d9c 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -164,6 +164,7 @@ std::string filter_name( debug_filter value ) // *INDENT-OFF* case DF_ACT_BUTCHER: return "DF_ACT_BUTCHER"; case DF_ACT_LOCKPICK: return "DF_ACT_LOCKPICK"; + case DF_ACT_SHEARING: return "DF_ACT_SHEARING"; case DF_ACT_WORKOUT: return "DF_ACT_WORKOUT"; case DF_ANATOMY_BP: return "DF_ANATOMY_BP"; case DF_AVATAR: return "DF_AVATAR"; diff --git a/src/debug.h b/src/debug.h index 0736c4ea13f92..cf40d076d4c83 100644 --- a/src/debug.h +++ b/src/debug.h @@ -230,6 +230,7 @@ namespace debugmode enum debug_filter : int { DF_ACT_BUTCHER = 0, // butcher activity handler DF_ACT_LOCKPICK, // lockpicking activity actor + DF_ACT_SHEARING, // shearing activity actor DF_ACT_WORKOUT, // workout activity actor DF_ANATOMY_BP, // anatomy::select_body_part() DF_AVATAR, // avatar generic diff --git a/src/monexamine.cpp b/src/monexamine.cpp index 29aa3a909ef21..4067d7a4ee665 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -143,7 +143,7 @@ bool monexamine::pet_menu( monster &z ) if( z.has_flag( MF_MILKABLE ) ) { amenu.addentry( milk, true, 'm', _( "Milk %s" ), pet_name ); } - if( z.has_flag( MF_SHEARABLE ) ) { + if( z.shearable() ) { bool available = true; if( season_of_year( calendar::turn ) == WINTER ) { amenu.addentry( shear, false, 'S', @@ -157,7 +157,7 @@ bool monexamine::pet_menu( monster &z ) if( player_character.has_quality( qual_SHEAR, 1 ) ) { amenu.addentry( shear, true, 'S', _( "Shear %s." ), pet_name ); } else { - amenu.addentry( shear, false, 'S', _( "You cannot shear this animal without shears." ) ); + amenu.addentry( shear, false, 'S', _( "You cannot shear this animal without a shearing tool." ) ); } } } @@ -293,20 +293,20 @@ bool monexamine::pet_menu( monster &z ) void monexamine::shear_animal( monster &z ) { - Character &player_character = get_player_character(); - const int moves = to_moves( time_duration::from_minutes( 30 / player_character.max_quality( - qual_SHEAR ) ) ); + Character &guy = get_player_character(); + if( !guy.has_quality( qual_SHEAR ) ) { + add_msg( _( "You don't have a shearing tool." ) ); + } - player_character.assign_activity( activity_id( "ACT_SHEAR" ), moves, -1 ); - player_character.activity.coords.push_back( get_map().getabs( z.pos() ) ); - // pin the sheep in place if it isn't already - if( !z.has_effect( effect_tied ) ) { + // was monster already tied before shearing + const bool monster_tied = z.has_effect( effect_tied ); + + // tie the critter so it doesn't move while being sheared + if( !monster_tied ) { z.add_effect( effect_tied, 1_turns, true ); - player_character.activity.str_values.emplace_back( "temp_tie" ); } - player_character.activity.targets.emplace_back( player_character, - player_character.best_quality_item( qual_SHEAR ) ); - add_msg( _( "You start shearing the %s." ), z.get_name() ); + + guy.assign_activity( player_activity( shearing_activity_actor( z.pos(), !monster_tied ) ) ); } static item_location pet_armor_loc( monster &z ) diff --git a/src/monster.h b/src/monster.h index d497b57d393c9..3975feb0b08a0 100644 --- a/src/monster.h +++ b/src/monster.h @@ -168,6 +168,10 @@ class monster : public Creature bool made_of_any( const std::set &ms ) const override; bool made_of( phase_id p ) const; // Returns true if its phase is p + bool shearable() const { + return type->shearing.valid(); + } + bool avoid_trap( const tripoint &pos, const trap &tr ) const override; void serialize( JsonOut &json ) const; diff --git a/src/monstergenerator.cpp b/src/monstergenerator.cpp index b03cb280673fd..40242e8cfc74a 100644 --- a/src/monstergenerator.cpp +++ b/src/monstergenerator.cpp @@ -834,6 +834,16 @@ void mtype::load( const JsonObject &jo, const std::string &src ) assign( jo, "harvest", harvest ); + if( jo.has_array( "shearing" ) ) { + std::vector entries; + for( JsonObject shearing_entry : jo.get_array( "shearing" ) ) { + struct shearing_entry entry {}; + entry.load( shearing_entry ); + entries.emplace_back( entry ); + } + shearing = shearing_data( entries ); + } + const auto death_reader = make_flag_reader( gen.death_map, "monster death function" ); optional( jo, was_loaded, "death_function", dies, death_reader ); if( dies.empty() ) { diff --git a/src/mtype.h b/src/mtype.h index c7b28b576b3f9..d9da09e98e6ae 100644 --- a/src/mtype.h +++ b/src/mtype.h @@ -17,6 +17,7 @@ #include "mattack_common.h" #include "optional.h" #include "pathfinding.h" +#include "shearing.h" #include "translations.h" #include "type_id.h" #include "units.h" // IWYU pragma: keep @@ -299,6 +300,7 @@ struct mtype { damage_instance melee_damage; // Basic melee attack damage harvest_id harvest; + shearing_data shearing; float luminance; // 0 is default, >0 gives luminance to lightmap unsigned int def_chance; // How likely a special "defensive" move is to trigger (0-100%, default 0) diff --git a/src/shearing.cpp b/src/shearing.cpp new file mode 100644 index 0000000000000..4bf5ecdfe0abc --- /dev/null +++ b/src/shearing.cpp @@ -0,0 +1,76 @@ +#include "shearing.h" + +#include + +#include "generic_factory.h" +#include "monster.h" +#include "rng.h" +#include "units.h" + + +shearing_roll shearing_entry::roll( const monster &mon ) const +{ + shearing_roll roll; + roll.result = result; + + roll.amount += amount; + + if( random_max ) { + roll.amount += rng( random_min, random_max ); + } + + if( ratio_mass ) { + float weight = units::to_kilogram( mon.get_weight() ); + roll.amount += static_cast( ratio_mass * weight ); + } + + if( ratio_volume ) { + float volume = units::to_liter( mon.get_volume() ); + roll.amount += static_cast( ratio_volume * volume ); + } + + return roll; +} + +void shearing_entry::load( const JsonObject &jo ) +{ + mandatory( jo, was_loaded, "result", result ); + + optional( jo, was_loaded, "ratio_mass", ratio_mass ); + ratio_mass = std::max( 0.00f, ratio_mass ); + + optional( jo, was_loaded, "ratio_volume", ratio_volume ); + ratio_volume = std::max( 0.00f, ratio_volume ); + + if( jo.has_int( "amount" ) ) { + mandatory( jo, was_loaded, "amount", amount ); + amount = std::max( 0, amount ); + } else if( jo.has_array( "amount" ) ) { + std::vector amount_random = jo.get_int_array( "amount" ); + random_min = std::max( 0, amount_random[0] ); + random_max = std::max( 0, amount_random[1] ); + if( random_min > random_max ) { + std::swap( random_min, random_max ); + } + } +} + +shearing_data::shearing_data( std::vector &shearing_entries ) +{ + if( !shearing_entries.empty() ) { + entries_ = shearing_entries; + valid_ = true; + } +} + +std::vector shearing_data::roll_all( const monster &mon ) const +{ + std::vector rolls; + rolls.reserve( entries_.size() ); + + for( const shearing_entry &entry : entries_ ) { + rolls.push_back( entry.roll( mon ) ); + } + + return rolls; +} diff --git a/src/shearing.h b/src/shearing.h new file mode 100644 index 0000000000000..b0e93ee82852a --- /dev/null +++ b/src/shearing.h @@ -0,0 +1,53 @@ +#pragma once +#include "damage.h" +#ifndef CATA_SRC_SHEARING_H +#define CATA_SRC_SHEARING_H + +#include + +#include "itype.h" + +class monster; + +struct shearing_roll { + itype_id result; + int amount = 0; +}; + +struct shearing_entry { + itype_id result; + int amount = 0; + int random_min = 0; + int random_max = 0; + float ratio_mass = 0.0f; + float ratio_volume = 0.0f; + + shearing_roll roll( const monster &mon ) const; + + bool was_loaded = false; + void load( const JsonObject &jo ); + //void deserialize( JsonIn &jsin ); +}; + +class shearing_data +{ + public: + shearing_data() = default; + explicit shearing_data( std::vector &shearing_entries ); + + bool valid() const { + return valid_; + } + + const std::vector &entries() const { + return entries_; + } + + std::vector roll_all( const monster &mon ) const; + + private: + bool valid_ = false; + std::vector entries_; +}; + +#endif // CATA_SRC_SHEARING_H diff --git a/tests/player_activities_test.cpp b/tests/player_activities_test.cpp new file mode 100644 index 0000000000000..c089104c9c7da --- /dev/null +++ b/tests/player_activities_test.cpp @@ -0,0 +1,280 @@ +#include "catch/catch.hpp" +#include "map_helpers.h" +#include "player_helpers.h" +#include "activity_scheduling_helper.h" + +#include "map.h" +#include "character.h" +#include "monster.h" +#include "avatar.h" +#include "calendar.h" +#include "iuse_actor.h" +#include "game.h" +#include "flag.h" +#include "point.h" +#include "activity_actor_definitions.h" + +static const activity_id ACT_NULL( "ACT_NULL" ); +static const activity_id ACT_SHEARING( "ACT_SHEARING" ); + +static const efftype_id effect_pet( "pet" ); +static const efftype_id effect_tied( "tied" ); + +static const itype_id itype_test_battery_disposable( "test_battery_disposable" ); +static const itype_id itype_test_shears( "test_shears" ); +static const itype_id itype_test_shears_off( "test_shears_off" ); +static const itype_id itype_test_shears_on( "test_shears_on" ); + +static const mtype_id mon_test_shearable( "mon_test_shearable" ); +static const mtype_id mon_test_non_shearable( "mon_test_non_shearable" ); + +static const quality_id qual_SHEAR( "SHEAR" ); + +TEST_CASE( "shearing", "[activity][shearing][animals]" ) +{ + avatar &dummy = get_avatar(); + clear_avatar(); + clear_map(); + + auto test_monster = [&dummy]( bool mon_shearable ) -> monster & { + monster *mon; + if( mon_shearable ) + { + mon = &spawn_test_monster( mon_test_shearable.str(), dummy.pos() + tripoint_north ); + } else + { + mon = &spawn_test_monster( mon_test_non_shearable.str(), dummy.pos() + tripoint_north ); + } + + mon->friendly = -1; + mon->add_effect( effect_pet, 1_turns, true ); + mon->add_effect( effect_tied, 1_turns, true ); + return *mon; + }; + + + SECTION( "shearing testing time" ) { + + GIVEN( "player without shearing quality" ) { + clear_avatar(); + clear_map(); + monster &mon = test_monster( true ); + + REQUIRE( dummy.max_quality( qual_SHEAR ) <= 0 ); + dummy.activity = player_activity( shearing_activity_actor( mon.pos(), false ) ); + dummy.activity.start_or_resume( dummy, false ); + + THEN( "shearing can't start" ) { + CHECK( dummy.activity.id() == ACT_NULL ); + } + } + + GIVEN( "a tool with shearing quality one" ) { + clear_avatar(); + clear_map(); + monster &mon = test_monster( true ); + + dummy.i_add( item( itype_test_shears ) ); + REQUIRE( dummy.max_quality( qual_SHEAR ) == 1 ); + + dummy.activity = player_activity( shearing_activity_actor( mon.pos(), false ) ); + dummy.activity.start_or_resume( dummy, false ); + REQUIRE( dummy.activity.id() == ACT_SHEARING ); + + THEN( "shearing time is 30 minutes" ) { + CHECK( dummy.activity.moves_total == to_moves( 30_minutes ) ); + } + } + + GIVEN( "an electric tool with shearing quality three" ) { + clear_avatar(); + clear_map(); + monster &mon = test_monster( true ); + + item battery( itype_test_battery_disposable ); + battery.ammo_set( battery.ammo_default(), 300 ); + + item elec_shears( itype_test_shears_off ); + elec_shears.put_in( battery, item_pocket::pocket_type::MAGAZINE_WELL ); + + const use_function *use = elec_shears.type->get_use( "transform" ); + REQUIRE( use != nullptr ); + const iuse_transform *actor = dynamic_cast( use->get_actor_ptr() ); + actor->use( dummy, elec_shears, false, dummy.pos() ); + + dummy.i_add( elec_shears ); + REQUIRE( dummy.max_quality( qual_SHEAR ) == 3 ); + + dummy.activity = player_activity( shearing_activity_actor( mon.pos(), false ) ); + dummy.activity.start_or_resume( dummy, false ); + REQUIRE( dummy.activity.id() == ACT_SHEARING ); + + THEN( "shearing time is 10 minutes" ) { + CHECK( dummy.activity.moves_total == to_moves( 10_minutes ) ); + } + } + + GIVEN( "a non shearable animal" ) { + clear_avatar(); + clear_map(); + monster &mon = test_monster( false ); + + dummy.i_add( item( itype_test_shears ) ); + REQUIRE( dummy.max_quality( qual_SHEAR ) == 1 ); + + dummy.activity = player_activity( shearing_activity_actor( mon.pos(), false ) ); + dummy.activity.start_or_resume( dummy, false ); + + THEN( "shearing can't start" ) { + CHECK( dummy.activity.id() == ACT_NULL ); + } + } + } + + SECTION( "shearing losing tool" ) { + GIVEN( "an electric tool with shearing quality three" ) { + clear_avatar(); + clear_map(); + monster &mon = test_monster( true ); + + item battery( itype_test_battery_disposable ); + battery.ammo_set( battery.ammo_default(), 5 ); + + item elec_shears( itype_test_shears_off ); + elec_shears.put_in( battery, item_pocket::pocket_type::MAGAZINE_WELL ); + + const use_function *use = elec_shears.type->get_use( "transform" ); + REQUIRE( use != nullptr ); + const iuse_transform *actor = dynamic_cast( use->get_actor_ptr() ); + actor->use( dummy, elec_shears, false, dummy.pos() ); + + dummy.i_add( elec_shears ); + REQUIRE( dummy.max_quality( qual_SHEAR ) == 3 ); + + dummy.activity = player_activity( shearing_activity_actor( mon.pos(), false ) ); + dummy.activity.start_or_resume( dummy, false ); + REQUIRE( dummy.activity.id() == ACT_SHEARING ); + + dummy.moves += dummy.get_speed(); + for( int i = 0; i < 100; ++i ) { + dummy.activity.do_turn( dummy ); + } + + WHEN( "tool runs out of charges mid activity" ) { + for( int i = 0; i < 10000; ++i ) { + dummy.process_items(); + } + + CHECK( dummy.weapon.ammo_remaining() == 0 ); + REQUIRE( dummy.weapon.typeId().str() == itype_test_shears_off.str() ); + + CHECK( dummy.max_quality( qual_SHEAR ) <= 0 ); + + THEN( "activity stops without completing" ) { + CHECK( dummy.activity.id() == ACT_SHEARING ); + CHECK( dummy.activity.moves_left > 0 ); + dummy.activity.do_turn( dummy ); + CHECK( dummy.activity.id() == ACT_NULL ); + } + } + } + } + + SECTION( "shearing testing result" ) { + + GIVEN( "a shearable monster" ) { + + clear_avatar(); + clear_map(); + monster &mon = test_monster( true ); + + dummy.i_add( item( itype_test_shears ) ); + REQUIRE( dummy.max_quality( qual_SHEAR ) == 1 ); + + dummy.activity = player_activity( shearing_activity_actor( mon.pos(), false ) ); + dummy.activity.start_or_resume( dummy, false ); + REQUIRE( dummy.activity.id() == ACT_SHEARING ); + + const itype_id test_amount( "test_rock" ); + const itype_id test_random( "test_2x4" ); + const itype_id test_mass( "test_rag" ); + const itype_id test_volume( "test_pipe" ); + + process_activity( dummy ); + WHEN( "shearing finishes" ) { + CHECK( dummy.activity.id() == ACT_NULL ); + THEN( "player receives the items" ) { + const map_stack items = get_map().i_at( dummy.pos() ); + int count_amount = 0; + int count_random = 0; + int count_mass = 0; + int count_volume = 0; + for( const item &it : items ) { + // can't use switch here + const itype_id it_id = it.typeId(); + if( it_id == test_amount ) { + count_amount += it.charges; + } else if( it_id == test_random ) { + count_random += 1; + } else if( it_id == test_mass ) { + count_mass += 1; + } else if( it_id == test_volume ) { + count_volume += 1; + } + } + + CHECK( count_amount == 30 ); + CHECK( ( 5 <= count_random && count_random <= 10 ) ); + + float weight = units::to_kilogram( mon.get_weight() ); + CHECK( count_mass == static_cast( 0.5f * weight ) ); + + float volume = units::to_liter( mon.get_volume() ); + CHECK( count_volume == static_cast( 0.3f * volume ) ); + } + } + } + + GIVEN( "an previously tied shearable monster" ) { + clear_avatar(); + clear_map(); + monster &mon = test_monster( true ); + + dummy.i_add( item( itype_test_shears ) ); + REQUIRE( dummy.max_quality( qual_SHEAR ) == 1 ); + + dummy.activity = player_activity( shearing_activity_actor( mon.pos(), false ) ); + dummy.activity.start_or_resume( dummy, false ); + REQUIRE( dummy.activity.id() == ACT_SHEARING ); + + process_activity( dummy ); + WHEN( "player is done shearing" ) { + REQUIRE( dummy.activity.id() == ACT_NULL ); + THEN( "monster is tied" ) { + CHECK( mon.has_effect( effect_tied ) ); + } + } + } + + GIVEN( "a previously untied shearable monster" ) { + clear_avatar(); + clear_map(); + monster &mon = test_monster( true ); + + dummy.i_add( item( itype_test_shears ) ); + REQUIRE( dummy.max_quality( qual_SHEAR ) == 1 ); + + dummy.activity = player_activity( shearing_activity_actor( mon.pos(), true ) ); + dummy.activity.start_or_resume( dummy, false ); + REQUIRE( dummy.activity.id() == ACT_SHEARING ); + + process_activity( dummy ); + WHEN( "player is done shearing" ) { + REQUIRE( dummy.activity.id() == ACT_NULL ); + THEN( "monster is untied" ) { + CHECK_FALSE( mon.has_effect( effect_tied ) ); + } + } + } + } +} From 29b08fdb05849c5fac5b9897d141e7c36304d48f Mon Sep 17 00:00:00 2001 From: LyleSY Date: Fri, 9 Jul 2021 10:56:24 -0400 Subject: [PATCH 098/116] tent pole take 2 (#49492) * tent pole take 2 * activities_hobbies * locations itemgroup * recipe_others * materials requirements * restore mine_materials changes * restore armrig changes * restore welding and bodypillow changes * can build three from one again * use "LIST" for requirements in recipes https://github.com/CleverRaven/Cataclysm-DDA/blob/master/doc/JSON_INFO.md#recipes explains it * lint recipe_others * rebracket requirements * add adhesive to tent requirements * separate recipes * reformat recipes * simpler recipes * simplify tent parts * recipes simpler still * no requirements * uncraft broken tents --- .../Locations_MapExtras/locations.json | 4 +++- data/json/itemgroups/activities_hobbies.json | 1 + data/json/items/tool/shelters.json | 19 ++++++++++++++++++ data/json/recipes/recipe_deconstruction.json | 20 +++++++++++++++++++ data/json/recipes/recipe_others.json | 6 ++++-- 5 files changed, 47 insertions(+), 3 deletions(-) diff --git a/data/json/itemgroups/Locations_MapExtras/locations.json b/data/json/itemgroups/Locations_MapExtras/locations.json index 277f463f73160..a75b0f1186053 100644 --- a/data/json/itemgroups/Locations_MapExtras/locations.json +++ b/data/json/itemgroups/Locations_MapExtras/locations.json @@ -2257,6 +2257,7 @@ [ "rollmat", 40 ], [ "tent_kit", 17 ], [ "large_tent_kit", 17 ], + [ "tent_pole", 17 ], { "distribution": [ { "group": "full_survival_kit" }, { "group": "used_survival_kit" } ], "prob": 10 }, [ "canteen", 15 ], [ "2lcanteen", 10 ], @@ -2453,7 +2454,8 @@ { "item": "rag", "prob": 60, "custom-flags": [ "FILTHY" ] }, { "item": "coat_lab", "prob": 20 }, { "item": "blanket", "prob": 20 }, - { "item": "sheet", "prob": 20 } + { "item": "sheet", "prob": 20 }, + { "item": "tent_pole", "prob": 20 } ] }, { diff --git a/data/json/itemgroups/activities_hobbies.json b/data/json/itemgroups/activities_hobbies.json index f8967629f8a8d..5b005686179cc 100644 --- a/data/json/itemgroups/activities_hobbies.json +++ b/data/json/itemgroups/activities_hobbies.json @@ -269,6 +269,7 @@ [ "rollmat", 40 ], [ "tent_kit", 17 ], [ "large_tent_kit", 17 ], + [ "tent_pole", 17 ], [ "canteen", 15 ], [ "2lcanteen", 10 ], [ "camelbak", 5 ], diff --git a/data/json/items/tool/shelters.json b/data/json/items/tool/shelters.json index 156dd13b968a7..3b529ec9613da 100644 --- a/data/json/items/tool/shelters.json +++ b/data/json/items/tool/shelters.json @@ -6,6 +6,7 @@ "description": "This is a small shelter, made of sticks and skins. Use it to place. This shelter has been damaged, and needs repairs.", "weight": "1360 g", "volume": "7500 ml", + "longest_side": "90 cm", "price": 2000, "price_postapoc": 50, "to_hit": -3, @@ -21,6 +22,7 @@ "description": "This is a family sized tent. It provides a large amount of space, but is very bulky.", "weight": "2266 g", "volume": "10 L", + "longest_side": "90 cm", "price": 50000, "price_postapoc": 1500, "to_hit": -3, @@ -46,6 +48,7 @@ "description": "This is a small shelter, made of sticks and skins. Use it to place.", "weight": "1360 g", "volume": "7500 ml", + "longest_side": "90 cm", "price": 6500, "price_postapoc": 500, "to_hit": -3, @@ -70,6 +73,7 @@ "description": "This is a small personal tent, it's just big enough to fit you comfortably.", "weight": "1133 g", "volume": "2500 ml", + "longest_side": "90 cm", "price": 15000, "price_postapoc": 1000, "to_hit": -3, @@ -86,5 +90,20 @@ "door_opened": "f_canvas_door_o", "door_closed": "f_canvas_door" } + }, + { + "type": "GENERIC", + "id": "tent_pole", + "symbol": "/", + "color": "dark_gray", + "name": { "str": "aluminum tent pole" }, + "description": "A light collapsible tent pole made from aluminum, perfect for pitching a tent.", + "looks_like": "long_pole", + "material": [ "aluminum" ], + "weight": "225 g", + "volume": "100 ml", + "longest_side": "90 cm", + "bashing": 1, + "to_hit": -1 } ] diff --git a/data/json/recipes/recipe_deconstruction.json b/data/json/recipes/recipe_deconstruction.json index b49f8927b0b37..3084f29d925bb 100644 --- a/data/json/recipes/recipe_deconstruction.json +++ b/data/json/recipes/recipe_deconstruction.json @@ -5026,6 +5026,26 @@ "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "material_rocksalt", 10 ] ] ] }, + { + "result": "broketent", + "type": "uncraft", + "activity_level": "LIGHT_EXERCISE", + "skill_used": "tailor", + "time": "10 m", + "difficulty": 1, + "qualities": [ { "id": "CUT", "level": 1 } ], + "components": [ [ [ "tarp", 1 ] ], [ [ "tent_pole", 2 ] ], [ [ "plastic_sheet", 1 ] ], [ [ "bag_plastic", 1 ] ] ] + }, + { + "result": "largebroketent", + "type": "uncraft", + "activity_level": "LIGHT_EXERCISE", + "skill_used": "tailor", + "time": "30 m", + "difficulty": 1, + "qualities": [ { "id": "CUT", "level": 1 } ], + "components": [ [ [ "tarp", 4 ] ], [ [ "tent_pole", 5 ] ], [ [ "plastic_sheet", 3 ] ], [ [ "bag_plastic", 3 ] ] ] + }, { "result": "knife_butter", "type": "uncraft", diff --git a/data/json/recipes/recipe_others.json b/data/json/recipes/recipe_others.json index 7b2d5c3aae944..7f6187329b733 100644 --- a/data/json/recipes/recipe_others.json +++ b/data/json/recipes/recipe_others.json @@ -136,7 +136,8 @@ "qualities": [ { "id": "CUT", "level": 1 }, { "id": "SCREW", "level": 1 } ], "time": "28 m", "autolearn": true, - "components": [ [ [ "largebroketent", 1 ], [ "broketent", 2 ] ], [ [ "superglue", 2 ], [ "duct_tape", 20 ] ] ] + "using": [ [ "adhesive", 1 ] ], + "components": [ [ [ "tarp", 2 ] ], [ [ "tent_pole", 2 ] ], [ [ "plastic_sheet", 1 ] ], [ [ "bag_plastic", 1 ] ] ] }, { "type": "recipe", @@ -152,7 +153,8 @@ "proficiencies": [ { "proficiency": "prof_closures" }, { "proficiency": "prof_closures_waterproofing" } ], "time": "32 m", "autolearn": true, - "components": [ [ [ "largebroketent", 2 ], [ "broketent", 4 ], [ "tent_kit", 3 ] ], [ [ "superglue", 3 ], [ "duct_tape", 40 ] ] ] + "using": [ [ "adhesive", 3 ] ], + "components": [ [ [ "tarp", 6 ] ], [ [ "tent_pole", 6 ] ], [ [ "plastic_sheet", 3 ] ], [ [ "bag_plastic", 3 ] ] ] }, { "type": "recipe", From 74f7e2ff65da7b7af703ed5d1f4995071717e8cf Mon Sep 17 00:00:00 2001 From: pehamm <76401419+pehamm@users.noreply.github.com> Date: Fri, 9 Jul 2021 16:58:54 +0200 Subject: [PATCH 099/116] Added Pack Hunter Mutation (#47031) * Added Pack Hunter Mutation * Linting and astyle * Applied suggestions from code review * Revert "Applied suggestions from code review" This reverts commit 47f04e80b1bec927a691116c1ae871e63b83dac9. * Revert "Linting and astyle" This reverts commit a1b4978eee8f83651902c3c6c05c44cfaabcb20e. * Revert "Added Pack Hunter Mutation" This reverts commit 7e159ad155c95ecc3ef64c957af0e650176f955d. * Based on Code Review, rolled back all changes and redid implementation putely in JSON * Ensure the Pacifist trait cancels Pack Hunter Co-authored-by: Peter Hamm --- data/json/mutations/mutations.json | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/data/json/mutations/mutations.json b/data/json/mutations/mutations.json index 38e0b2f54e3d7..bb7b671f7106c 100644 --- a/data/json/mutations/mutations.json +++ b/data/json/mutations/mutations.json @@ -1352,7 +1352,7 @@ "starting_trait": true, "social_modifiers": { "intimidate": -10 }, "valid": false, - "cancels": [ "PSYCHOPATH", "KILLER", "PRED1", "PRED2", "PRED3", "PRED4" ] + "cancels": [ "PSYCHOPATH", "KILLER", "PRED1", "PRED2", "PRED3", "PRED4", "PACK_HUNTER" ] }, { "type": "mutation", @@ -3906,7 +3906,7 @@ "prereqs": [ "CARNIVORE", "THRESH_URSINE" ], "prereqs2": [ "PRED2" ], "leads_to": [ "SAPIOVORE" ], - "changes_to": [ "PRED4" ], + "changes_to": [ "PRED4", "PACK_HUNTER" ], "threshreq": [ "THRESH_BEAST", "THRESH_RAPTOR", @@ -3955,6 +3955,22 @@ "category": [ "BEAST", "RAPTOR", "CHIMERA", "URSINE", "LIZARD", "SPIDER" ], "flags": [ "CANNIBAL" ] }, + { + "type": "mutation", + "id": "PACK_HUNTER", + "name": { "str": "Pack Hunter" }, + "points": 4, + "description": "Puny as they may seem, a hunter needs a pack, and some of those hairless bipeds may yet prove some worth. You continue to gain combat skills at an elevated rate, and maintain a level of critical thinking that supports cooperation.", + "social_modifiers": { "intimidate": 4 }, + "valid": false, + "purifiable": false, + "prereqs": [ "CARNIVORE" ], + "prereqs2": [ "PRED3" ], + "cancels": [ "PACIFIST" ], + "threshreq": [ "THRESH_LUPINE" ], + "category": [ "LUPINE" ], + "flags": [ "PRED3" ] + }, { "type": "mutation", "id": "M_DEFENDER", From 8d721b4884378d3e659dbb20a582e54202e14554 Mon Sep 17 00:00:00 2001 From: Curtis Merrill Date: Fri, 9 Jul 2021 11:00:16 -0400 Subject: [PATCH 100/116] Npc attack (#47562) * create npc_attack class This implements a class that owns all of the logic for an npc evaluating the best weapon to use in the moment. * Tests for npc_attack * add a debug mode that shows potential values --- data/mods/TEST_DATA/items.json | 35 +++ src/action.cpp | 4 + src/action.h | 1 + src/cata_tiles.cpp | 50 +++- src/debug_menu.cpp | 5 + src/debug_menu.h | 1 + src/npc.h | 11 + src/npc_attack.cpp | 518 +++++++++++++++++++++++++++++++++ src/npc_attack.h | 125 ++++++++ src/npcmove.cpp | 163 ++++------- tests/npc_attack_test.cpp | 286 ++++++++++++++++++ 11 files changed, 1084 insertions(+), 115 deletions(-) create mode 100644 src/npc_attack.cpp create mode 100644 src/npc_attack.h create mode 100644 tests/npc_attack_test.cpp diff --git a/data/mods/TEST_DATA/items.json b/data/mods/TEST_DATA/items.json index e78a34a778069..69bcc5bc5a2e1 100644 --- a/data/mods/TEST_DATA/items.json +++ b/data/mods/TEST_DATA/items.json @@ -1088,6 +1088,41 @@ "price": 7500, "price_postapoc": 300 }, + { + "id": "test_bullwhip", + "type": "GENERIC", + "symbol": "/", + "color": "brown", + "name": { "str": "TEST bullwhip" }, + "description": "A long strip of braided leather with a handle on one end. Originally developed to settle disagreements with cattle, it's better used now for flaying the rotten flesh off of walking corpses. Great for when a problem comes along.", + "weight": "3460 g", + "volume": "2 L", + "price": 3500, + "price_postapoc": 500, + "material": [ "leather" ], + "flags": [ "REACH_ATTACK", "REACH3", "WHIP" ], + "cutting": 3, + "category": "weapons" + }, + { + "id": "test_glaive", + "type": "GENERIC", + "symbol": "/", + "color": "light_gray", + "name": { "str": "TEST glaive" }, + "description": "A sturdy polearm with a sizable, single-edged blade on the end.", + "price": 50000, + "material": [ "steel", "wood" ], + "qualities": [ [ "CUT", 1 ], [ "BUTCHER", -28 ] ], + "flags": [ "DURABLE_MELEE", "REACH_ATTACK", "NONCONDUCTIVE", "POLEARM", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ], + "techniques": [ "WIDE", "WBLOCK_1" ], + "weight": "2100 g", + "volume": "2500 ml", + "longest_side": "180 cm", + "bashing": 17, + "cutting": 40, + "price_postapoc": 8000 + }, { "id": "test_glock", "type": "GUN", diff --git a/src/action.cpp b/src/action.cpp index f6c85050680d3..4e4e5b39e4ca0 100644 --- a/src/action.cpp +++ b/src/action.cpp @@ -336,6 +336,8 @@ std::string action_ident( action_id act ) return "debug_lighting"; case ACTION_DISPLAY_RADIATION: return "debug_radiation"; + case ACTION_DISPLAY_NPC_ATTACK_POTENTIAL: + return "debug_npc_attack_potential"; case ACTION_TOGGLE_HOUR_TIMER: return "debug_hour_timer"; case ACTION_TOGGLE_DEBUG_MODE: @@ -448,6 +450,7 @@ bool can_action_change_worldstate( const action_id act ) case ACTION_DISPLAY_VISIBILITY: case ACTION_DISPLAY_LIGHTING: case ACTION_DISPLAY_RADIATION: + case ACTION_DISPLAY_NPC_ATTACK_POTENTIAL: case ACTION_DISPLAY_TRANSPARENCY: case ACTION_DISPLAY_REACHABILITY_ZONES: case ACTION_ZOOM_OUT: @@ -886,6 +889,7 @@ action_id handle_action_menu() REGISTER_ACTION( ACTION_DISPLAY_TRANSPARENCY ); REGISTER_ACTION( ACTION_DISPLAY_REACHABILITY_ZONES ); REGISTER_ACTION( ACTION_DISPLAY_RADIATION ); + REGISTER_ACTION( ACTION_DISPLAY_NPC_ATTACK_POTENTIAL ); REGISTER_ACTION( ACTION_TOGGLE_DEBUG_MODE ); } else if( category == _( "Interact" ) ) { REGISTER_ACTION( ACTION_EXAMINE ); diff --git a/src/action.h b/src/action.h index 721608c277097..b8db9c42cd158 100644 --- a/src/action.h +++ b/src/action.h @@ -322,6 +322,7 @@ enum action_id : int { ACTION_DISPLAY_TRANSPARENCY, /** Toggle reachability zones map */ ACTION_DISPLAY_REACHABILITY_ZONES, + ACTION_DISPLAY_NPC_ATTACK_POTENTIAL, /** Toggle timing of the game hours */ ACTION_TOGGLE_HOUR_TIMER, /** Not an action, serves as count of enumerated actions */ diff --git a/src/cata_tiles.cpp b/src/cata_tiles.cpp index cc74debf624ab..cb9c45ff1c11a 100644 --- a/src/cata_tiles.cpp +++ b/src/cata_tiles.cpp @@ -1055,6 +1055,30 @@ struct tile_render_info { } }; +static std::map display_npc_attack_potential() +{ + avatar &you = get_avatar(); + npc avatar_as_npc; + std::ostringstream os; + JsonOut jsout( os ); + jsout.write( you ); + std::istringstream is( os.str() ); + JsonIn jsin( is ); + jsin.read( avatar_as_npc ); + avatar_as_npc.regen_ai_cache(); + avatar_as_npc.evaluate_best_weapon( nullptr ); + std::map effectiveness_map; + std::vector effectiveness = + avatar_as_npc.get_current_attack()->all_evaluations( avatar_as_npc, nullptr ); + for( const npc_attack_rating &effectiveness_at_point : effectiveness ) { + if( !effectiveness_at_point.value() ) { + continue; + } + effectiveness_map[effectiveness_at_point.target()] = *effectiveness_at_point.value(); + } + return effectiveness_map; +} + void cata_tiles::draw( const point &dest, const tripoint ¢er, int width, int height, std::multimap &overlay_strings, color_block_overlay_container &color_blocks ) @@ -1181,7 +1205,14 @@ void cata_tiles::draw( const point &dest, const tripoint ¢er, int width, int would_apply_vision_effects( here.get_visibility( ch.visibility_cache[np.x][np.y], cache ) ); }; - + std::map npc_attack_rating_map; + int max_npc_effectiveness = 0; + if( g->display_overlay_state( ACTION_DISPLAY_NPC_ATTACK_POTENTIAL ) ) { + npc_attack_rating_map = display_npc_attack_potential(); + for( const std::pair &pair : npc_attack_rating_map ) { + max_npc_effectiveness = std::max( pair.second, max_npc_effectiveness ); + } + } for( int row = min_row; row < max_row; row ++ ) { std::vector draw_points; draw_points.reserve( max_col ); @@ -1264,6 +1295,23 @@ void cata_tiles::draw( const point &dest, const tripoint ¢er, int width, int } } + if( g->display_overlay_state( ACTION_DISPLAY_NPC_ATTACK_POTENTIAL ) ) { + if( npc_attack_rating_map.count( pos ) ) { + const int val = npc_attack_rating_map.at( pos ); + short color; + if( val <= 0 ) { + color = catacurses::red; + } else if( val == max_npc_effectiveness ) { + color = catacurses::cyan; + } else { + color = catacurses::white; + } + overlay_strings.emplace( player_to_screen( point( x, y ) ) + half_tile, + formatted_text( std::to_string( val ), color, + direction::NORTH ) ); + } + } + // Add temperature value to the overlay_strings list for every visible tile when // displaying temperature if( g->display_overlay_state( ACTION_DISPLAY_TEMPERATURE ) && !invisible[0] ) { diff --git a/src/debug_menu.cpp b/src/debug_menu.cpp index ff26a6bef399e..faf08c216ffea 100644 --- a/src/debug_menu.cpp +++ b/src/debug_menu.cpp @@ -173,6 +173,7 @@ std::string enum_to_string( debug_menu::debug_menu case debug_menu::debug_menu_index::CRASH_GAME: return "CRASH_GAME"; case debug_menu::debug_menu_index::MAP_EXTRA: return "MAP_EXTRA"; case debug_menu::debug_menu_index::DISPLAY_NPC_PATH: return "DISPLAY_NPC_PATH"; + case debug_menu::debug_menu_index::DISPLAY_NPC_ATTACK: return "DISPLAY_NPC_ATTACK"; case debug_menu::debug_menu_index::PRINT_FACTION_INFO: return "PRINT_FACTION_INFO"; case debug_menu::debug_menu_index::PRINT_NPC_MAGIC: return "PRINT_NPC_MAGIC"; case debug_menu::debug_menu_index::QUIT_NOSAVE: return "QUIT_NOSAVE"; @@ -272,6 +273,7 @@ static int info_uilist( bool display_all_entries = true ) { uilist_entry( debug_menu_index::HOUR_TIMER, true, 'E', _( "Toggle hour timer" ) ) }, { uilist_entry( debug_menu_index::TRAIT_GROUP, true, 't', _( "Test trait group" ) ) }, { uilist_entry( debug_menu_index::DISPLAY_NPC_PATH, true, 'n', _( "Toggle NPC pathfinding on map" ) ) }, + { uilist_entry( debug_menu_index::DISPLAY_NPC_ATTACK, true, 'A', _( "Toggle NPC attack potential values on map" ) ) }, { uilist_entry( debug_menu_index::PRINT_FACTION_INFO, true, 'f', _( "Print faction info to console" ) ) }, { uilist_entry( debug_menu_index::PRINT_NPC_MAGIC, true, 'M', _( "Print NPC magic info to console" ) ) }, { uilist_entry( debug_menu_index::TEST_WEATHER, true, 'W', _( "Test weather" ) ) }, @@ -2546,6 +2548,9 @@ void debug() case debug_menu_index::DISPLAY_SCENTS_TYPE_LOCAL: g->display_toggle_overlay( ACTION_DISPLAY_SCENT_TYPE ); break; + case debug_menu_index::DISPLAY_NPC_ATTACK: + g->display_toggle_overlay( ACTION_DISPLAY_NPC_ATTACK_POTENTIAL ); + break; case debug_menu_index::DISPLAY_TEMP: g->display_toggle_overlay( ACTION_DISPLAY_TEMPERATURE ); break; diff --git a/src/debug_menu.h b/src/debug_menu.h index 66498bbd88328..a0088a8ed3435 100644 --- a/src/debug_menu.h +++ b/src/debug_menu.h @@ -65,6 +65,7 @@ enum class debug_menu_index : int { CRASH_GAME, MAP_EXTRA, DISPLAY_NPC_PATH, + DISPLAY_NPC_ATTACK, PRINT_FACTION_INFO, PRINT_NPC_MAGIC, QUIT_NOSAVE, diff --git a/src/npc.h b/src/npc.h index 4cc0b216941b6..19c095946acde 100644 --- a/src/npc.h +++ b/src/npc.h @@ -35,6 +35,7 @@ #include "line.h" #include "lru_cache.h" #include "memory_fast.h" +#include "npc_attack.h" #include "optional.h" #include "pimpl.h" #include "player.h" @@ -573,6 +574,9 @@ struct npc_short_term_cache { cata::optional guard_pos; double my_weapon_value = 0; + npc_attack_rating current_attack_evaluation; + std::shared_ptr current_attack; + // Use weak_ptr to avoid circular references between Creatures // attitude of creatures the npc can see std::vector> hostile_guys; @@ -1068,6 +1072,10 @@ class npc : public player // Functions which choose an action for a particular goal npc_action method_of_fleeing(); npc_action method_of_attack(); + // among the different attack methods the npc has available, what's the best one in the current situation? + // picks among melee, guns, spells, etc. + // updates the ai_cache + void evaluate_best_weapon( const Creature *target ); static std::array, npc_need::num_needs> need_data; @@ -1281,6 +1289,9 @@ class npc : public player npc_short_term_cache ai_cache; public: + const std::shared_ptr &get_current_attack() const { + return ai_cache.current_attack; + } /** * Global position, expressed in map square coordinate system * (the most detailed coordinate system), used by the @ref map. diff --git a/src/npc_attack.cpp b/src/npc_attack.cpp new file mode 100644 index 0000000000000..c7edaf31daa69 --- /dev/null +++ b/src/npc_attack.cpp @@ -0,0 +1,518 @@ +#include "npc_attack.h" + +#include "character.h" +#include "flag.h" +#include "game.h" +#include "item.h" +#include "map.h" +#include "messages.h" +#include "npc.h" +#include "point.h" +#include "projectile.h" +#include "ranged.h" + +namespace npc_attack_constants +{ +const std::map attitude_multiplier = { + { Creature::Attitude::FRIENDLY, -10 }, + { Creature::Attitude::HOSTILE, 3 }, + { Creature::Attitude::NEUTRAL, -1 } +}; +// if you are attacking your target, multiply potential by this number +const int target_modifier = 3; +// if you kill the creature, multiply the potential by this number +const int kill_modifier = 2; +// the amount of penalty if the npc has to change what it's wielding +// update this number and comment when that is no longer a flat -15 moves +const int base_time_penalty = 3; +// we want this out of our hands, pronto. +// give a large buff to the attack value so it prioritizes this +const int base_throw_now = 10'000; +} // namespace npc_attack_constants + +// TODO: make a better, more generic "check if this projectile is blocked" function +// TODO: put this in a namespace for reuse +static bool has_obstruction( const tripoint &from, const tripoint &to ) +{ + std::vector line = line_to( from, to ); + // @to is what we want to hit. we don't need to check for obstruction there. + line.pop_back(); + const map &here = get_map(); + for( const tripoint &line_point : line ) { + if( here.impassable( line_point ) ) { + return true; + } + } + return false; +} + +bool npc_attack_rating::operator>( const npc_attack_rating &rhs ) const +{ + if( !rhs._value ) { + return true; + } + if( !_value ) { + return false; + } + return *_value > *rhs._value; +} + +bool npc_attack_rating::operator>( const int rhs ) const +{ + if( !_value ) { + return false; + } + return *_value > rhs; +} + +bool npc_attack_rating::operator<( const int rhs ) const +{ + if( !_value ) { + return true; + } + return *_value < rhs; +} + +npc_attack_rating npc_attack_rating::operator-=( const int rhs ) +{ + if( _value ) { + *_value -= rhs; + } + return *this; +} + +void npc_attack_melee::use( npc &source, const tripoint &location ) const +{ + if( !source.wield( weapon ) ) { + debugmsg( "ERROR: npc tried to melee monster with weapon it couldn't wield" ); + return; + } + Creature *critter = g->critter_at( location ); + if( !critter ) { + debugmsg( "ERROR: npc tried to attack null critter" ); + return; + } + if( !source.is_adjacent( critter, true ) ) { + add_msg_debug( debugmode::debug_filter::DF_NPC, "%s is attempting a reach attack", + source.disp_name() ); + source.reach_attack( location ); + } else { + add_msg_debug( debugmode::debug_filter::DF_NPC, "%s is attempting a melee attack", + source.disp_name() ); + source.melee_attack( *critter, true ); + } +} + +tripoint_range npc_attack_melee::targetable_points( const npc &source ) const +{ + const int reach_range{ weapon.reach_range( source ) }; + return get_map().points_in_radius( source.pos(), reach_range ); +} + +npc_attack_rating npc_attack_melee::evaluate( const npc &source, + const Creature *target ) const +{ + npc_attack_rating effectiveness( cata::nullopt, source.pos() ); + if( !can_use( source ) ) { + return effectiveness; + } + const int time_penalty = base_time_penalty( source ); + for( const tripoint &targetable_point : targetable_points( source ) ) { + if( Creature *critter = g->critter_at( targetable_point ) ) { + if( source.attitude_to( *critter ) != Creature::Attitude::HOSTILE ) { + // no point in swinging a sword at a friendly! + continue; + } + npc_attack_rating effectiveness_at_point = evaluate_critter( source, target, critter ); + effectiveness_at_point -= time_penalty; + if( effectiveness_at_point > effectiveness ) { + effectiveness = effectiveness_at_point; + } + } + } + return effectiveness; +} + +std::vector npc_attack_melee::all_evaluations( const npc &source, + const Creature *target ) const +{ + std::vector effectiveness; + if( !can_use( source ) ) { + return effectiveness; + } + const int time_penalty = base_time_penalty( source ); + for( const tripoint &targetable_point : targetable_points( source ) ) { + if( Creature *critter = g->critter_at( targetable_point ) ) { + if( source.attitude_to( *critter ) != Creature::Attitude::HOSTILE ) { + // no point in swinging a sword at a friendly! + continue; + } + npc_attack_rating effectiveness_at_point = evaluate_critter( source, target, critter ); + effectiveness_at_point -= time_penalty; + effectiveness.push_back( effectiveness_at_point ); + } + } + return effectiveness; +} + +bool npc_attack_melee::can_use( const npc &source ) const +{ + // can't attack with something you can't wield + return source.can_wield( weapon ).success(); +} + +int npc_attack_melee::base_time_penalty( const npc &source ) const +{ + return source.is_wielding( weapon ) ? 0 : npc_attack_constants::base_time_penalty; +} + +npc_attack_rating npc_attack_melee::evaluate_critter( const npc &source, + const Creature *target, Creature *critter ) const +{ + if( !critter ) { + return npc_attack_rating{}; + } + const int distance_to_me = rl_dist( source.pos(), critter->pos() ); + const double damage{ weapon.effective_dps( source, *critter ) }; + const Creature::Attitude att = source.attitude_to( *critter ); + double potential = damage * npc_attack_constants::attitude_multiplier.at( att ) - + ( distance_to_me - 1 ); + if( damage >= critter->get_hp() ) { + potential *= npc_attack_constants::kill_modifier; + } + if( target && target->pos() == critter->pos() ) { + potential *= npc_attack_constants::target_modifier; + } + return npc_attack_rating( std::round( potential ), critter->pos() ); +} + +void npc_attack_gun::use( npc &source, const tripoint &location ) const +{ + const item &weapon = *gunmode; + if( !weapon.ammo_sufficient() ) { + source.do_reload( weapon ); + add_msg_debug( debugmode::debug_filter::DF_NPC, "%s is reloading %s", source.disp_name(), + weapon.display_name() ); + return; + } + + const int dist = rl_dist( source.pos(), location ); + + if( source.aim_per_move( weapon, source.recoil ) > 0 && + source.confident_shoot_range( weapon, source.get_most_accurate_sight( weapon ) ) >= dist ) { + add_msg_debug( debugmode::debug_filter::DF_NPC, "%s is aiming", source.disp_name() ); + source.aim(); + } else { + source.fire_gun( location ); + add_msg_debug( debugmode::debug_filter::DF_NPC, "%s fires %s", source.disp_name(), + weapon.display_name() ); + } +} + +bool npc_attack_gun::can_use( const npc &source ) const +{ + // can't attack with something you can't wield + return source.can_wield( *gunmode ).success(); +} + +int npc_attack_gun::base_time_penalty( const npc &source ) const +{ + const item &weapon = *gunmode; + int time_penalty = 0; + if( source.is_wielding( weapon ) ) { + time_penalty += npc_attack_constants::base_time_penalty; + } + // we want the need to reload a gun cumulative with needing to wield the gun + if( !weapon.ammo_sufficient() ) { + time_penalty += npc_attack_constants::base_time_penalty; + } + int recoil_penalty = 0; + if( source.is_wielding( weapon ) ) { + recoil_penalty = source.recoil; + } else { + recoil_penalty = MAX_RECOIL; + } + recoil_penalty /= 100; + return time_penalty + recoil_penalty; +} + +tripoint_range npc_attack_gun::targetable_points( const npc &source ) const +{ + const item &weapon = *gunmode; + return get_map().points_in_radius( source.pos(), weapon.gun_range() ); +} + +npc_attack_rating npc_attack_gun::evaluate( + const npc &source, const Creature *target ) const +{ + npc_attack_rating effectiveness( cata::nullopt, source.pos() ); + if( !can_use( source ) ) { + return effectiveness; + } + const int time_penalty = base_time_penalty( source ); + for( const tripoint &targetable_point : targetable_points( source ) ) { + if( g->critter_at( targetable_point ) ) { + npc_attack_rating effectiveness_at_point = evaluate_tripoint( source, target, + targetable_point ); + effectiveness_at_point -= time_penalty; + if( effectiveness_at_point > effectiveness ) { + effectiveness = effectiveness_at_point; + } + } + } + return effectiveness; +} + +std::vector npc_attack_gun::all_evaluations( const npc &source, + const Creature *target ) const +{ + std::vector effectiveness; + if( !can_use( source ) ) { + return effectiveness; + } + const int time_penalty = base_time_penalty( source ); + for( const tripoint &targetable_point : targetable_points( source ) ) { + if( g->critter_at( targetable_point ) ) { + npc_attack_rating effectiveness_at_point = evaluate_tripoint( source, target, + targetable_point ); + effectiveness_at_point -= time_penalty; + effectiveness.push_back( effectiveness_at_point ); + } + } + return effectiveness; +} + +npc_attack_rating npc_attack_gun::evaluate_tripoint( + const npc &source, const Creature *target, const tripoint &location ) const +{ + const item &gun = *gunmode.target; + const int damage = gun.gun_damage().total_damage() * gunmode.qty; + if( has_obstruction( source.pos(), location ) ) { + return npc_attack_rating( cata::nullopt, location ); + } + + const Creature *critter = g->critter_at( location ); + if( !critter ) { + // TODO: AOE ammo effects + return npc_attack_rating( cata::nullopt, location ); + } + const int distance_to_me = rl_dist( location, source.pos() ); + const Creature::Attitude att = source.attitude_to( *critter ); + const bool friendly_fire = att == Creature::Attitude::FRIENDLY && + !source.rules.has_flag( ally_rule::avoid_friendly_fire ); + int attitude_mult = npc_attack_constants::attitude_multiplier.at( att ); + if( friendly_fire ) { + // hitting a neutral creature isn't exactly desired, but it's a lot less than a friendly. + // if friendly fire is on, we don't care too much, though if an available hit doesn't damage them it would be better. + attitude_mult = npc_attack_constants::attitude_multiplier.at( Creature::Attitude::NEUTRAL ); + } + const int distance_penalty = std::max( distance_to_me - 1, + ( source.closest_enemy_to_friendly_distance() - 1 ) * 2 ); + double potential = damage * attitude_mult - distance_penalty; + if( damage >= critter->get_hp() ) { + potential *= npc_attack_constants::kill_modifier; + } + if( target && target->pos() == critter->pos() ) { + potential *= npc_attack_constants::target_modifier; + } + return npc_attack_rating( std::round( potential ), location ); +} + +void npc_attack_activate_item::use( npc &source, const tripoint &/*location*/ ) const +{ + if( !source.wield( activatable_item ) ) { + debugmsg( "%s can't wield %s it tried to activate", source.disp_name(), + activatable_item.display_name() ); + } + source.activate_item( activatable_item ); +} + +bool npc_attack_activate_item::can_use( const npc &source ) const +{ + const bool can_use_grenades = ( source.is_player_ally() && + !source.rules.has_flag( ally_rule::use_grenades ) ) || source.is_hallucination(); + //TODO: make this more complete. only does BOMB type items + return can_use_grenades && activatable_item.has_flag( flag_NPC_ACTIVATE ); +} + +npc_attack_rating npc_attack_activate_item::evaluate( + const npc &source, const Creature * /*target*/ ) const +{ + if( !can_use( source ) ) { + return npc_attack_rating( cata::nullopt, source.pos() ); + } + // until we have better logic for grenades it's better to keep this as a last resort... + const int emergency = source.emergency() ? 1 : 0; + return npc_attack_rating( emergency, source.pos() ); +} + +std::vector npc_attack_activate_item::all_evaluations( const npc &source, + const Creature * /*target*/ ) const +{ + std::vector effectiveness; + if( !can_use( source ) ) { + return effectiveness; + } + // until we have better logic for grenades it's better to keep this as a last resort... + const int emergency = source.emergency() ? 1 : 0; + effectiveness.emplace_back( npc_attack_rating( emergency, source.pos() ) ); + return effectiveness; +} + +void npc_attack_throw::use( npc &source, const tripoint &location ) const +{ + // WARNING! wielding the item invalidates the reference! + if( source.wield( thrown_item ) ) { + add_msg_debug( debugmode::debug_filter::DF_NPC, "%s throws the %s", source.disp_name(), + source.weapon.display_name() ); + item thrown( source.weapon ); + if( source.weapon.count_by_charges() && source.weapon.charges > 1 ) { + source.weapon.mod_charges( -1 ); + thrown.charges = 1; + } else { + source.remove_weapon(); + } + source.throw_item( location, thrown ); + } else { + debugmsg( "%s couldn't wield %s to throw it", source.disp_name(), thrown_item.display_name() ); + } +} + +bool npc_attack_throw::can_use( const npc &source ) const +{ + item single_item( thrown_item ); + if( single_item.count_by_charges() ) { + single_item.charges = 1; + } + // please don't throw your pants... + return !source.is_worn( thrown_item ) && + // we would rather throw than activate this. unless we need to throw it now. + !( thrown_item.has_flag( flag_NPC_THROW_NOW ) || thrown_item.has_flag( flag_NPC_ACTIVATE ) ) && + // i don't trust you as far as i can throw you. + source.throw_range( single_item ) != 0; +} + +int npc_attack_throw::base_penalty( const npc &source ) const +{ + // hot potato! HOT POTATO! + int throw_now = 0; + if( thrown_item.has_flag( flag_NPC_THROW_NOW ) ) { + throw_now = npc_attack_constants::base_throw_now; + } + + item single_item( thrown_item ); + if( single_item.count_by_charges() ) { + single_item.charges = 1; + } + const int time_penalty = source.is_wielding( single_item ) ? 0 : + npc_attack_constants::base_time_penalty; + + return time_penalty - throw_now; +} + +tripoint_range npc_attack_throw::targetable_points( const npc &source ) const +{ + item single_item( thrown_item ); + if( single_item.count_by_charges() ) { + single_item.charges = 1; + } + const int range = source.throw_range( single_item ); + return get_map().points_in_radius( source.pos(), range ); +} + +npc_attack_rating npc_attack_throw::evaluate( + const npc &source, const Creature *target ) const +{ + npc_attack_rating effectiveness( cata::nullopt, source.pos() ); + if( !can_use( source ) ) { + // please don't throw your pants... + return effectiveness; + } + const int penalty = base_penalty( source ); + for( const tripoint &potential : targetable_points( source ) ) { + if( Creature *critter = g->critter_at( potential ) ) { + if( source.attitude_to( *critter ) != Creature::Attitude::HOSTILE ) { + // no point in friendly fire! + continue; + } + npc_attack_rating effectiveness_at_point = evaluate_tripoint( source, target, + potential ); + effectiveness_at_point -= penalty; + if( effectiveness_at_point > effectiveness ) { + effectiveness = effectiveness_at_point; + } + } + } + return effectiveness; +} + +std::vector npc_attack_throw::all_evaluations( const npc &source, + const Creature *target ) const +{ + std::vector effectiveness; + if( !can_use( source ) ) { + // please don't throw your pants... + return effectiveness; + } + const int penalty = base_penalty( source ); + for( const tripoint &potential : targetable_points( source ) ) { + if( Creature *critter = g->critter_at( potential ) ) { + if( source.attitude_to( *critter ) != Creature::Attitude::HOSTILE ) { + // no point in friendly fire! + continue; + } + npc_attack_rating effectiveness_at_point = evaluate_tripoint( source, target, + potential ); + effectiveness_at_point -= penalty; + effectiveness.push_back( effectiveness_at_point ); + } + } + return effectiveness; +} + +npc_attack_rating npc_attack_throw::evaluate_tripoint( + const npc &source, const Creature *target, const tripoint &location ) const +{ + if( has_obstruction( source.pos(), location ) ) { + return npc_attack_rating( cata::nullopt, location ); + } + item single_item( thrown_item ); + if( single_item.count_by_charges() ) { + single_item.charges = 1; + } + + Creature::Attitude att = Creature::Attitude::NEUTRAL; + const Creature *critter = g->critter_at( location ); + if( critter ) { + att = source.attitude_to( *critter ); + } + const bool friendly_fire = att == Creature::Attitude::FRIENDLY && + !source.rules.has_flag( ally_rule::avoid_friendly_fire ); + int attitude_mult = npc_attack_constants::attitude_multiplier.at( att ); + if( friendly_fire ) { + // hitting a neutral creature isn't exactly desired, but it's a lot less than a friendly. + // if friendly fire is on, we don't care too much, though if an available hit doesn't damage them it would be better. + attitude_mult = npc_attack_constants::attitude_multiplier.at( Creature::Attitude::NEUTRAL ); + } + + const float throw_mult = throw_cost( source, single_item ) * source.speed_rating() / 100.0f; + const int damage = source.thrown_item_total_damage_raw( single_item ); + float dps = damage / throw_mult; + const int distance_to_me = rl_dist( location, source.pos() ); + const int distance_penalty = std::max( distance_to_me - 1, + ( source.closest_enemy_to_friendly_distance() - 1 ) * 2 ); + + double potential = dps * attitude_mult - distance_penalty; + if( critter && damage >= critter->get_hp() ) { + potential *= npc_attack_constants::kill_modifier; + } + if( !target || !critter ) { + // not great to throw here but if we have a grenade... + potential = -100; + // ... we'd rather throw it farther away from ourselves. + potential += distance_to_me; + } else if( target->pos() == critter->pos() ) { + potential *= npc_attack_constants::target_modifier; + } + return npc_attack_rating( std::round( potential ), location ); +} diff --git a/src/npc_attack.h b/src/npc_attack.h new file mode 100644 index 0000000000000..cd3ad361dcb6b --- /dev/null +++ b/src/npc_attack.h @@ -0,0 +1,125 @@ +#pragma once +#ifndef CATA_SRC_NPC_ATTACK_H +#define CATA_SRC_NPC_ATTACK_H + +#include + +#include "gun_mode.h" +#include "item.h" +#include "map_iterator.h" +#include "optional.h" +#include "point.h" +#include "type_id.h" + +class Creature; +class item; +class npc; + +class npc_attack_rating +{ + // the total calculated effectiveness of this attack. no value means this attack is not possible. + cata::optional _value = cata::nullopt; + // the target tile of the attack + tripoint _target; + public: + npc_attack_rating() = default; + npc_attack_rating( const cata::optional &_value, + const tripoint &_target ) : _value( _value ), _target( _target ) {} + cata::optional value() const { + return _value; + } + tripoint target() const { + return _target; + } + bool operator>( const npc_attack_rating &rhs ) const; + bool operator>( int rhs ) const; + bool operator<( int rhs ) const; + npc_attack_rating operator-=( int rhs ); +}; + +class npc_attack +{ + public: + /** + * Parameters: + * source - the npc making the attack + * target - the desired target of the npc. valued at 100% + */ + virtual npc_attack_rating evaluate( const npc &source, const Creature *target ) const = 0; + virtual void use( npc &source, const tripoint &location ) const = 0; + /** + * For debug information. returns all evaluated effectivenesses. + * This is abstracted out in evaluate() as it's faster to not use a container + */ + virtual std::vector all_evaluations( const npc &source, + const Creature *target ) const = 0; + + virtual ~npc_attack() = default; +}; + +class npc_attack_melee : public npc_attack +{ + item &weapon; + public: + explicit npc_attack_melee( item &weapon ) : weapon( weapon ) {} + npc_attack_rating evaluate( const npc &source, const Creature *target ) const override; + std::vector all_evaluations( const npc &source, + const Creature *target ) const override; + void use( npc &source, const tripoint &location ) const override; + private: + tripoint_range targetable_points( const npc &source ) const; + bool can_use( const npc &source ) const; + int base_time_penalty( const npc &source ) const; + npc_attack_rating evaluate_critter( const npc &source, const Creature *target, + Creature *critter ) const; +}; + +class npc_attack_gun : public npc_attack +{ + const gun_mode gunmode; + public: + explicit npc_attack_gun( const gun_mode &gunmode ) : gunmode( gunmode ) {} + npc_attack_rating evaluate( const npc &source, const Creature *target ) const override; + std::vector all_evaluations( const npc &source, + const Creature *target ) const override; + void use( npc &source, const tripoint &location ) const override; + private: + tripoint_range targetable_points( const npc &source ) const; + bool can_use( const npc &source ) const; + int base_time_penalty( const npc &source ) const; + npc_attack_rating evaluate_tripoint( + const npc &source, const Creature *target, const tripoint &location ) const; +}; + +class npc_attack_throw : public npc_attack +{ + item &thrown_item; + public: + explicit npc_attack_throw( item &thrown_item ) : thrown_item( thrown_item ) {} + npc_attack_rating evaluate( const npc &source, const Creature *target ) const override; + std::vector all_evaluations( const npc &source, + const Creature *target ) const override; + void use( npc &source, const tripoint &location ) const override; + private: + tripoint_range targetable_points( const npc &source ) const; + bool can_use( const npc &source ) const; + int base_penalty( const npc &source ) const; + npc_attack_rating evaluate_tripoint( + const npc &source, const Creature *target, const tripoint &location ) const; +}; + +class npc_attack_activate_item : public npc_attack +{ + item &activatable_item; + public: + explicit npc_attack_activate_item( item &activatable_item ) : + activatable_item( activatable_item ) {} + npc_attack_rating evaluate( const npc &source, const Creature *target ) const override; + std::vector all_evaluations( const npc &source, + const Creature *target ) const override; + void use( npc &source, const tripoint &location ) const override; + private: + bool can_use( const npc &source ) const; +}; + +#endif // CATA_SRC_NPC_ATTACK_H diff --git a/src/npcmove.cpp b/src/npcmove.cpp index 09b739ef5794f..fee237dd311f0 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -52,6 +52,7 @@ #include "mission.h" #include "monster.h" #include "mtype.h" +#include "npc_attack.h" #include "npctalk.h" #include "omdata.h" #include "options.h" @@ -149,6 +150,7 @@ enum npc_action : int { npc_escape_explosion, npc_noop, npc_reach_attack, + npc_do_attack, npc_aim, npc_investigate_sound, npc_return_to_guard_pos, @@ -770,7 +772,7 @@ void npc::move() } regen_ai_cache(); // NPCs under operation should just stay still - if( activity.id() == ACT_OPERATION ) { + if( activity.id() == ACT_OPERATION || activity.id() == activity_id( "ACT_SPELLCASTING" ) ) { execute_action( npc_player_activity ); return; } @@ -1023,6 +1025,11 @@ void npc::execute_action( npc_action action ) Character &player_character = get_player_character(); map &here = get_map(); switch( action ) { + case npc_do_attack: + ai_cache.current_attack->use( *this, ai_cache.current_attack_evaluation.target() ); + ai_cache.current_attack.reset(); + ai_cache.current_attack_evaluation = npc_attack_rating{}; + break; case npc_pause: move_pause(); break; @@ -1383,131 +1390,59 @@ npc_action npc::method_of_attack() return npc_pause; } - tripoint tar = critter->pos(); - int dist = rl_dist( pos(), tar ); - double danger = evaluate_enemy( *critter ); - const bool has_los = clear_shot_reach( pos(), tar, false ); - const bool same_z = tar.z == pos().z; - - // TODO: Change the in_vehicle check to actual "are we driving" check - const bool dont_move = in_vehicle || rules.engagement == combat_engagement::NO_MOVE || - rules.engagement == combat_engagement::FREE_FIRE; - // NPCs engage in free fire can move to avoid allies, but not if they're in a vehicle - const bool dont_move_ff = in_vehicle || rules.engagement == combat_engagement::NO_MOVE; - // if there's enough of a threat to be here, power up the combat CBMs activate_combat_cbms(); - int ups_charges = charges_of( itype_UPS ); - - // get any suitable modes excluding melee, any forbidden to NPCs and those without ammo - // if we require a silent weapon inappropriate modes are also removed - // except in emergency only fire bursts if danger > 0.5 and don't shoot at all at harmless targets - std::vector> modes; - if( rules.has_flag( ally_rule::use_guns ) || !is_player_ally() ) { - for( const auto &e : weapon.gun_all_modes() ) { - modes.emplace_back( e ); - } - - modes.erase( std::remove_if( modes.begin(), modes.end(), - [&]( const std::pair &e ) { - - const auto &m = e.second; - return m.melee() || m.flags.count( "NPC_AVOID" ) || - !m->ammo_sufficient( m.qty ) || !can_use( *m.target ) || - m->get_gun_ups_drain() > ups_charges || - ( ( danger <= ( m.qty == 1 ? 0.0 : 15 ) ) && !emergency() ) || - ( rules.has_flag( ally_rule::use_silent ) && is_player_ally() && - !m.target->is_silent() ); - - } ), modes.end() ); - } - - // prefer modes that result in more total damage - std::stable_sort( modes.begin(), - modes.end(), [&]( const std::pair &lhs, - const std::pair &rhs ) { - return ( lhs.second->gun_damage().total_damage() * lhs.second.qty ) > - ( rhs.second->gun_damage().total_damage() * rhs.second.qty ); - } ); - - const int cur_recoil = recoil_total(); - // modes outside confident range should always be the last option(s) - std::stable_sort( modes.begin(), - modes.end(), [&]( const std::pair &lhs, - const std::pair &rhs ) { - return ( confident_gun_mode_range( lhs.second, cur_recoil ) >= dist ) > - ( confident_gun_mode_range( rhs.second, cur_recoil ) >= dist ); - } ); - - if( emergency() && alt_attack() ) { - add_msg_debug( debugmode::DF_NPC, "%s is trying an alternate attack", disp_name() ); - return npc_noop; - } + evaluate_best_weapon( critter ); - // reach attacks are silent and consume no ammo so prefer these if available - int reach_range = weapon.reach_range( *this ); - if( !trigdist ) { - if( reach_range > 1 && reach_range >= dist && clear_shot_reach( pos(), tar ) ) { - add_msg_debug( debugmode::DF_NPC, "%s is trying a reach attack", disp_name() ); - return npc_reach_attack; - } + cata::optional potential = ai_cache.current_attack_evaluation.value(); + if( potential && *potential > 0 ) { + return npc_do_attack; } else { - if( reach_range > 1 && reach_range >= std::round( trig_dist( pos(), tar ) ) && - clear_shot_reach( pos(), tar ) ) { - add_msg_debug( debugmode::DF_NPC, "%s is trying a reach attack", disp_name() ); - return npc_reach_attack; - } + add_msg_debug( debugmode::debug_filter::DF_NPC, "%s can't figure out what to do", disp_name() ); + return npc_undecided; } +} - // if the best mode is within the confident range try for a shot - if( !modes.empty() && sees( *critter ) && has_los && - confident_gun_mode_range( modes[ 0 ].second, cur_recoil ) >= dist ) { - if( cbm_weapon_index > 0 && !weapon.ammo_sufficient() && can_reload_current() ) { - add_msg_debug( debugmode::DF_NPC, "%s is reloading", disp_name() ); - return npc_reload; +void npc::evaluate_best_weapon( const Creature *target ) +{ + std::shared_ptr best_attack; + npc_attack_rating best_evaluated_attack; + const auto compare = [&best_attack, &best_evaluated_attack, this, &target] + ( const std::shared_ptr &potential_attack ) { + const npc_attack_rating evaluated = potential_attack->evaluate( *this, target ); + if( evaluated > best_evaluated_attack ) { + best_attack = potential_attack; + best_evaluated_attack = evaluated; } + }; - if( wont_hit_friend( tar, weapon, false ) ) { - weapon.gun_set_mode( modes[ 0 ].first ); - add_msg_debug( debugmode::DF_NPC, "%s is trying to shoot someone", disp_name() ); - return npc_shoot; - - } else { - if( !dont_move_ff ) { - add_msg_debug( debugmode::DF_NPC, "%s is trying to avoid friendly fire", disp_name() ); - return npc_avoid_friendly_fire; + // punching things is always available + compare( std::make_shared( null_item_reference() ) ); + const int ups_charges = charges_of( itype_UPS ); + visit_items( [&compare, &ups_charges, this]( item * it, item * ) { + // you can theoretically melee with anything. + compare( std::make_shared( *it ) ); + // ... you can also throw anything + compare( std::make_shared( *it ) ); + if( !it->type->use_methods.empty() ) { + compare( std::make_shared( *it ) ); + } + if( rules.has_flag( ally_rule::use_guns ) ) { + for( const std::pair &mode : it->gun_all_modes() ) { + if( !( mode.second.melee() || mode.second.flags.count( "NPC_AVOID" ) || + !can_use( *mode.second.target ) || mode.second->get_gun_ups_drain() > ups_charges || + ( rules.has_flag( ally_rule::use_silent ) && is_player_ally() && + !mode.second->is_silent() ) ) ) { + compare( std::make_shared( mode.second ) ); + } } } - } - - if( dist == 1 && same_z ) { - add_msg_debug( debugmode::DF_NPC, "%s is trying a melee attack", disp_name() ); - return npc_melee; - } - - // don't mess with CBM weapons - if( cbm_weapon_index < 0 ) { - // TODO: Add a time check now that wielding takes a lot of time - if( wield_better_weapon() ) { - add_msg_debug( debugmode::DF_NPC, "%s is changing weapons", disp_name() ); - return npc_noop; - } - - if( !weapon.ammo_sufficient() && can_reload_current() ) { - add_msg_debug( debugmode::DF_NPC, "%s is reloading", disp_name() ); - return npc_reload; - } - } + return VisitResponse::NEXT; + } ); - // TODO: Needs a check for transparent but non-passable tiles on the way - if( !modes.empty() && sees( *critter ) && aim_per_move( weapon, recoil ) > 0 && - confident_shoot_range( weapon, get_most_accurate_sight( weapon ) ) >= dist ) { - add_msg_debug( debugmode::DF_NPC, "%s is aiming" ); - return npc_aim; - } - add_msg_debug( debugmode::DF_NPC, "%s can't figure out what to do", disp_name() ); - return ( dont_move || !same_z ) ? npc_undecided : npc_melee; + ai_cache.current_attack = best_attack; + ai_cache.current_attack_evaluation = best_evaluated_attack; } npc_action npc::address_needs() diff --git a/tests/npc_attack_test.cpp b/tests/npc_attack_test.cpp new file mode 100644 index 0000000000000..c092f691a280e --- /dev/null +++ b/tests/npc_attack_test.cpp @@ -0,0 +1,286 @@ +#include "catch/catch.hpp" + +#include "game.h" +#include "map.h" +#include "map_helpers.h" +#include "npc.h" +#include "npc_attack.h" +#include "npc_class.h" +#include "options_helpers.h" +#include "player_helpers.h" + +static const mtype_id mon_zombie( "mon_zombie" ); + +static constexpr point main_npc_start{ 50, 50 }; +static constexpr tripoint main_npc_start_tripoint{ main_npc_start, 0 }; + +namespace npc_attack_setup +{ +static void spawn_main_npc() +{ + const string_id blank_template( "test_talker" ); + const character_id model_id = get_map().place_npc( main_npc_start, blank_template ); + + npc &model_npc = *g->find_npc( model_id ); + clear_character( model_npc ); + model_npc.setpos( main_npc_start_tripoint ); + + g->load_npcs(); +} + +static void respawn_main_npc() +{ + npc *guy = g->critter_at( main_npc_start_tripoint ); + guy->die( nullptr ); + spawn_main_npc(); +} + +// will seg fault if the main npc wasn't spawned yet +static npc &get_main_npc() +{ + return *g->critter_at( main_npc_start_tripoint ); +} + +static void spawn_zombie_at_range( const int range ) +{ + g->place_critter_at( mon_zombie, main_npc_start_tripoint + tripoint( range, 0, 0 ) ); +} +} // namespace npc_attack_setup + +struct npc_attack_melee_test_data { + itype_id weapon_id; + // base effectiveness against the zombie + int base_effectiveness; + // effectiveness skyrockets when the zombie will die in one hit + int deathblow; + // the effectiveness value if the zombie is not the main target + int not_main_target; + // the effectiveness value of a farther zombie if it's the target + int reach_far_target; + // the effectiveness value of a farther zombie if it's not the target but nearly dead + int reach_far_deathblow; + // effectiveness value of a farther zombie if it's nearly dead and is the target + int reach_far_target_deathblow; +}; + +static void test_melee_attacks( const npc_attack_melee_test_data &data ) +{ + CAPTURE( data.weapon_id.c_str() ); + clear_map_and_put_player_underground(); + clear_vehicles(); + scoped_weather_override sunny_weather( weather_type_id( "sunny" ) ); + g->weather.set_nextweather( calendar::turn ); + npc_attack_setup::spawn_main_npc(); + npc_attack_setup::spawn_zombie_at_range( 1 ); + monster *zomble = g->critter_at( main_npc_start_tripoint + tripoint_east ); + npc_attack_setup::respawn_main_npc(); + npc &main_npc = npc_attack_setup::get_main_npc(); + item weapon( data.weapon_id ); + main_npc.weapon = weapon; + const npc_attack_melee wep( main_npc.weapon ); + npc_attack_rating wep_effectiveness = wep.evaluate( main_npc, zomble ); + // base effectiveness against the zombie + CHECK( *wep_effectiveness.value() == data.base_effectiveness ); + zomble->set_hp( 1 ); + wep_effectiveness = wep.evaluate( main_npc, zomble ); + // effectiveness skyrockets when the zombie will die in one hit + CHECK( *wep_effectiveness.value() == data.deathblow ); + + npc_attack_setup::spawn_zombie_at_range( 4 ); + monster *dist_target = g->critter_at( main_npc_start_tripoint + tripoint( 4, 0, 0 ) ); + wep_effectiveness = wep.evaluate( main_npc, dist_target ); + // even if the distant target is the npc's actual target, + // the nearly dead zombie we actually can hit is the (only) choice + CHECK( wep_effectiveness.target() == main_npc_start_tripoint + tripoint_east ); + // but the actual effectiveness value is lower because it is not the main target + CHECK( *wep_effectiveness.value() == data.not_main_target ); + zomble->die( nullptr ); + wep_effectiveness = wep.evaluate( main_npc, dist_target ); + // we can't reach the only alive zombie, so there's no valid attack to make + CHECK( !wep_effectiveness.value() ); + dist_target->die( nullptr ); + +} + +static void test_reach_attacks( const npc_attack_melee_test_data &data ) +{ + test_melee_attacks( data ); + + npc &main_npc = npc_attack_setup::get_main_npc(); + const npc_attack_melee wep( main_npc.weapon ); + CAPTURE( data.weapon_id.c_str() ); + + npc_attack_setup::spawn_zombie_at_range( 1 ); + npc_attack_setup::spawn_zombie_at_range( 2 ); + + monster *mon_close = g->critter_at( main_npc_start_tripoint + tripoint_east ); + monster *mon_far = g->critter_at( main_npc_start_tripoint + tripoint( 2, 0, 0 ) ); + + // if the farther zombie is our target, prefer it + npc_attack_rating wep_effectiveness = wep.evaluate( main_npc, mon_far ); + CHECK( wep_effectiveness.target() == main_npc_start_tripoint + tripoint( 2, 0, 0 ) ); + CHECK( *wep_effectiveness.value() == data.reach_far_target ); + + mon_far->set_hp( 1 ); + wep_effectiveness = wep.evaluate( main_npc, mon_close ); + // if the farther zombie is nearly dead but the close one is our target, we still want to fight the closer one + CHECK( wep_effectiveness.target() == main_npc_start_tripoint + tripoint_east ); + CHECK( *wep_effectiveness.value() == data.reach_far_deathblow ); + + mon_close->set_hp( 1 ); + wep_effectiveness = wep.evaluate( main_npc, mon_far ); + // if both zombies are nearly dead, the far target should still be preferred + CHECK( wep_effectiveness.target() == main_npc_start_tripoint + tripoint( 2, 0, 0 ) ); + CHECK( *wep_effectiveness.value() == data.reach_far_target_deathblow ); +} + +struct npc_attack_gun_test_data { + std::string weapon_id; + // default gunmode against a zombie point-blank at MAX_RECOIL + int point_blank_hip_shot_default; + // default gunmode against a zombie point-blank at full aim + int point_blank_full_aim_default; +}; + +static void test_gun_attacks( const npc_attack_gun_test_data &data ) +{ + + clear_map_and_put_player_underground(); + clear_vehicles(); + scoped_weather_override sunny_weather( weather_type_id( "sunny" ) ); + g->weather.set_nextweather( calendar::turn ); + npc_attack_setup::spawn_main_npc(); + npc &main_npc = npc_attack_setup::get_main_npc(); + arm_shooter( main_npc, data.weapon_id ); + + npc_attack_setup::spawn_zombie_at_range( 1 ); + monster *near_zombie = g->critter_at( main_npc_start_tripoint + tripoint_east ); + + const npc_attack_gun gun_default( main_npc.weapon.gun_get_mode( gun_mode_id( "DEFAULT" ) ) ); + npc_attack_rating gun_effectiveness = gun_default.evaluate( main_npc, near_zombie ); + CHECK( *gun_effectiveness.value() == data.point_blank_hip_shot_default ); + main_npc.recoil = main_npc.aim_cap_from_volume( main_npc.weapon ); + gun_effectiveness = gun_default.evaluate( main_npc, near_zombie ); + CHECK( *gun_effectiveness.value() == data.point_blank_full_aim_default ); +} + +TEST_CASE( "Test NPC attack variants' potential", "[npc_attack]" ) +{ + SECTION( "melee" ) { + SECTION( "2x4" ) { + const npc_attack_melee_test_data twobyfour{ + itype_id( "test_2x4" ), + 35, 71, 24, + -1, -1, -1 + }; + test_melee_attacks( twobyfour ); + } + SECTION( "pipe" ) { + const npc_attack_melee_test_data pipe{ + itype_id( "test_pipe" ), + 68, 136, 45, + -1, -1, -1 + }; + test_melee_attacks( pipe ); + } + SECTION( "fire_ax" ) { + const npc_attack_melee_test_data fire_ax{ + itype_id( "test_fire_ax" ), + 141, 283, 94, + -1, -1, -1 + }; + test_melee_attacks( fire_ax ); + } + SECTION( "clumsy_sword" ) { + const npc_attack_melee_test_data clumsy_sword{ + itype_id( "test_clumsy_sword" ), + 227, 454, 151, + -1, -1, -1 + }; + test_melee_attacks( clumsy_sword ); + } + SECTION( "normal_sword" ) { + const npc_attack_melee_test_data normal_sword{ + itype_id( "test_normal_sword" ), + 291, 582, 194, + -1, -1, -1 + }; + test_melee_attacks( normal_sword ); + } + SECTION( "balanced_sword" ) { + const npc_attack_melee_test_data balanced_sword{ + itype_id( "test_balanced_sword" ), + 346, 692, 231, + -1, -1, -1 + }; + test_melee_attacks( balanced_sword ); + } + SECTION( "whip" ) { + const npc_attack_melee_test_data whip{ + itype_id( "test_bullwhip" ), + 22, 43, 14, + 19, 22, 37 + }; + test_reach_attacks( whip ); + } + SECTION( "glaive" ) { + const npc_attack_melee_test_data glaive{ + itype_id( "test_glaive" ), + 192, 384, 128, + 189, 192, 378 + }; + test_reach_attacks( glaive ); + } + } + SECTION( "ranged" ) { + SECTION( "glock" ) { + const npc_attack_gun_test_data glock{ + "test_glock", + 192, 222 + }; + test_gun_attacks( glock ); + } + SECTION( "longbow" ) { + const npc_attack_gun_test_data bow{ + "test_compbow", + 210, 240 + }; + test_gun_attacks( bow ); + } + SECTION( "m1911" ) { + const npc_attack_gun_test_data gun{ + "m1911", + 210, 240 + }; + test_gun_attacks( gun ); + } + SECTION( "remington_870" ) { + const npc_attack_gun_test_data gun{ + "remington_870", + 471, 501 + }; + test_gun_attacks( gun ); + } + SECTION( "browning_blr" ) { + const npc_attack_gun_test_data gun{ + "browning_blr", + 516, 546 + }; + test_gun_attacks( gun ); + } + SECTION( "shotgun_d" ) { + const npc_attack_gun_test_data gun{ + "shotgun_d", + 417, 447 + }; + test_gun_attacks( gun ); + } + SECTION( "m16a4" ) { + const npc_attack_gun_test_data gun{ + "m16a4", + 345, 375 + }; + test_gun_attacks( gun ); + } + } +} From c8895977a51f64a8549d7f79695c3c5cdc34b09b Mon Sep 17 00:00:00 2001 From: Maleclypse <54345792+Maleclypse@users.noreply.github.com> Date: Fri, 9 Jul 2021 10:15:53 -0500 Subject: [PATCH 101/116] Fixes for Hunting Lodge (#49730) * Fixes for Hunting Lodge * Update lodge_nested.json * Update specials.json * Update specials.json --- data/json/mapgen/hunting_lodge.json | 42 +++++++++---------- data/json/mapgen/nested/lodge_nested.json | 4 +- data/json/mapgen_palettes/lodge_palette.json | 6 ++- .../overmap/overmap_special/specials.json | 2 +- 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/data/json/mapgen/hunting_lodge.json b/data/json/mapgen/hunting_lodge.json index c675c04bebdcd..280177ba6b181 100644 --- a/data/json/mapgen/hunting_lodge.json +++ b/data/json/mapgen/hunting_lodge.json @@ -9,9 +9,9 @@ "rows": [ ".%##W###W###W###W###+##W#################%......", ".*#c B#c B#B c#B c# #h s# >#*......", - ".*Wd B#d B#B d#B d# #h T# W*......", - ".*##=###=###=###=## ##=## #*......", - ".*# #*......", + ".*Wd B#d B#B d#B d# #h T# ZZZ W*......", + ".*##=###=###=###=## ##=## ZZZ #*......", + ".*# ZZZ #*......", ".*W W*......", ".*# YY YY AAAAAAAA a OOO >#*......", ".%########+######################## ###%......", @@ -88,24 +88,24 @@ "fill_ter": "t_rock", "rows": [ " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ", - " % % ", - " % % ", - " % % ", - " % % ", - " % % ", - " % % ", - " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% ", - " % % ", - " %%%%%%%%%%%%%% % ", - " % BB% ", - " % % ", - " % % ", - " % % ", - " % % ", - " % % ", - " %%%%% %%%%%%%% ", - " %<| % ", - " % + % ", + " %______________________________________% ", + " %______________________________________% ", + " %______________________________________% ", + " %______________________________________% ", + " %______________________________________% ", + " %______________________________________% ", + " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%_%%% ", + " %_% ", + " %%%%%%%%%%%%%%_% ", + " %____________BB% ", + " %______________% ", + " %______________% ", + " %______________% ", + " %______________% ", + " %______________% ", + " %%%%%___%%%%%%%% ", + " %<|___% ", + " % +___% ", " %%%%%%% ", " ", " ", diff --git a/data/json/mapgen/nested/lodge_nested.json b/data/json/mapgen/nested/lodge_nested.json index 7f89e90c344b3..1bea57c2cb8c4 100644 --- a/data/json/mapgen/nested/lodge_nested.json +++ b/data/json/mapgen/nested/lodge_nested.json @@ -163,12 +163,12 @@ { "item": "bullwhip", "chance": 100 } ], "c": [ - { "item": "bone", "chance": 80, "repeat": [ 4, 8 ] }, { "item": "pants", "chance": 100 }, { "item": "shirts", "chance": 100 }, { "item": "leather_shop_accessories", "chance": 10 } ] - } + }, + "place_fields": [ { "field": "fd_blood", "x": [ 2, 3 ], "y": [ 0, 1 ] }, { "field": "fd_gibs_flesh", "x": [ 2, 3 ], "y": [ 0, 1 ] } ] } }, { diff --git a/data/json/mapgen_palettes/lodge_palette.json b/data/json/mapgen_palettes/lodge_palette.json index dd7b0b86e68a3..24b4f4af1ea50 100644 --- a/data/json/mapgen_palettes/lodge_palette.json +++ b/data/json/mapgen_palettes/lodge_palette.json @@ -65,7 +65,9 @@ "a": { "item": "livingroom", "chance": 20 }, "A": [ { "item": "homebooks", "chance": 60, "repeat": [ 1, 3 ] }, - { "item": "magazines", "chance": 60, "repeat": [ 1, 8 ] }, + { "item": "magazines", "chance": 30, "repeat": [ 0, 4 ] }, + { "item": "novels", "chance": 60, "repeat": [ 1, 8 ] }, + { "item": "religious_books", "chance": 60, "repeat": [ 0, 3 ] }, { "item": "manuals", "chance": 30 } ], "B": { "item": "bed", "chance": 60 }, @@ -92,7 +94,7 @@ "s": { "item": "SUS_bathroom_sink", "chance": 60 }, "t": { "item": "dining", "chance": 30, "repeat": [ 1, 2 ] }, "U": { "item": "camping", "chance": 30, "repeat": [ 1, 4 ] }, - "u": { "item": "SUS_pantry", "chance": 50 }, + "u": [ { "item": "SUS_breakfast_cupboard", "chance": 30 }, { "item": "SUS_coffee_cupboard", "chance": 50 } ], "V": { "item": "SUS_oven", "chance": 70 }, "Y": { "item": "coat_rack", "chance": 35, "repeat": [ 1, 4 ] }, "1": [ { "item": "SUS_dishes", "chance": 35 }, { "item": "SUS_silverware", "chance": 35 } ], diff --git a/data/json/overmap/overmap_special/specials.json b/data/json/overmap/overmap_special/specials.json index 18de71f1ea0cc..ea573e1302fb5 100644 --- a/data/json/overmap/overmap_special/specials.json +++ b/data/json/overmap/overmap_special/specials.json @@ -263,7 +263,7 @@ "connections": [ { "point": [ 0, -1, 0 ], "terrain": "road", "existing": true } ], "locations": [ "land", "swamp" ], "city_distance": [ 15, -1 ], - "city_sizes": [ 1, 8 ], + "city_sizes": [ 0, 12 ], "occurrences": [ 0, 2 ], "flags": [ "CLASSIC", "WILDERNESS" ] }, From 65d81f7edc1b2647f0ab6d28baf4681a0b34f633 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Fri, 9 Jul 2021 08:16:15 -0700 Subject: [PATCH 102/116] Variantize shotguns (#49732) Collapses 5 shotguns based on skill and ammo-capacity. Name the shotguns by ammo capacity, because otherwise they all have the same name. --- .../Locations_MapExtras/locations.json | 2 +- .../monster_drops_lairs.json | 2 +- .../itemgroups/Weapons_Mods_Ammo/guns.json | 24 +- data/json/itemgroups/military.json | 7 +- data/json/items/gun/shot.json | 337 +++++++++--------- data/json/items/magazine/shot.json | 24 +- data/json/items/migration.json | 30 ++ .../mapgen/military/mil_base/mil_base_z0.json | 2 +- data/json/professions.json | 3 +- data/mods/Aftershock/mobs/robots.json | 2 +- .../vehicleparts/blaze_turrets_vanilla.json | 4 +- .../firearms/gg_firearms_migration.json | 7 +- tests/ranged_balance_test.cpp | 2 +- 13 files changed, 236 insertions(+), 210 deletions(-) diff --git a/data/json/itemgroups/Locations_MapExtras/locations.json b/data/json/itemgroups/Locations_MapExtras/locations.json index a75b0f1186053..23c25fbb3b480 100644 --- a/data/json/itemgroups/Locations_MapExtras/locations.json +++ b/data/json/itemgroups/Locations_MapExtras/locations.json @@ -1409,7 +1409,7 @@ { "item": "3006", "prob": 5, "charges": [ 1, 20 ] }, { "item": "ksg", "prob": 8, "charges": [ 0, 7 ] }, { "item": "remington_870_express", "prob": 8, "charges": [ 0, 7 ] }, - { "item": "mossberg_500_security", "prob": 8, "charges": [ 0, 6 ] }, + { "item": "mossberg_500", "variant": "mossberg_500_security", "prob": 8, "charges": [ 0, 6 ] }, { "item": "shot_beanbag", "prob": 25, "charges": [ 1, 10 ] }, { "item": "rm120c", "prob": 2, "charges": [ 0, 5 ] }, { "item": "rm20", "prob": 1, "charges": [ 0, 20 ] }, diff --git a/data/json/itemgroups/Monsters_Animals_Lairs/monster_drops_lairs.json b/data/json/itemgroups/Monsters_Animals_Lairs/monster_drops_lairs.json index 65683bdea1a6e..c16c6e60b6232 100644 --- a/data/json/itemgroups/Monsters_Animals_Lairs/monster_drops_lairs.json +++ b/data/json/itemgroups/Monsters_Animals_Lairs/monster_drops_lairs.json @@ -220,7 +220,7 @@ { "item": "nato_assault_rifle", "variant": "m4a1", "prob": 7 }, { "item": "m16a4", "prob": 6 }, { "item": "nato_assault_rifle", "variant": "h&k416a5", "prob": 3 }, - { "item": "m1014", "prob": 1 }, + { "item": "mossberg_930", "variant": "m1014", "prob": 1 }, { "item": "steyr_aug", "prob": 6 }, { "item": "v29", "prob": 1 }, { "item": "flamethrower", "prob": 1 }, diff --git a/data/json/itemgroups/Weapons_Mods_Ammo/guns.json b/data/json/itemgroups/Weapons_Mods_Ammo/guns.json index ef13f591fa177..32f369c7b1f71 100644 --- a/data/json/itemgroups/Weapons_Mods_Ammo/guns.json +++ b/data/json/itemgroups/Weapons_Mods_Ammo/guns.json @@ -481,10 +481,10 @@ "items": [ { "item": "mossberg_500", "prob": 33, "charges-min": 0, "charges-max": 6 }, { "item": "remington_870", "prob": 35, "charges-min": 0, "charges-max": 5 }, - { "item": "mossberg_500_security", "prob": 17, "charges-min": 0, "charges-max": 6 }, + { "item": "mossberg_500", "variant": "mossberg_500_security", "prob": 17, "charges-min": 0, "charges-max": 6 }, { "item": "remington_870_express", "prob": 18, "charges-min": 0, "charges-max": 6 }, - { "item": "browning_a5", "prob": 14, "charges-min": 0, "charges-max": 5 }, - { "item": "remington_1100", "prob": 17, "charges-min": 0, "charges-max": 5 }, + { "item": "remington_870", "variant": "browning_a5", "prob": 14, "charges-min": 0, "charges-max": 5 }, + { "item": "remington_870", "variant": "remington_1100", "prob": 17, "charges-min": 0, "charges-max": 5 }, { "item": "mossberg_930", "prob": 15, "charges-min": 0, "charges-max": 6 }, { "item": "shotgun_410", "prob": 30, "charges-min": 0, "charges-max": 1 }, { "item": "shotgun_d", "prob": 30, "charges-min": 0, "charges-max": 2 }, @@ -498,10 +498,10 @@ "items": [ { "item": "mossberg_500", "prob": 33, "charges-min": 0, "charges-max": 0 }, { "item": "remington_870", "prob": 35, "charges-min": 0, "charges-max": 0 }, - { "item": "mossberg_500_security", "prob": 17, "charges-min": 0, "charges-max": 0 }, + { "item": "mossberg_500", "variant": "mossberg_500_security", "prob": 17, "charges-min": 0, "charges-max": 0 }, { "item": "remington_870_express", "prob": 18, "charges-min": 0, "charges-max": 0 }, - { "item": "browning_a5", "prob": 14, "charges-min": 0, "charges-max": 0 }, - { "item": "remington_1100", "prob": 17, "charges-min": 0, "charges-max": 0 }, + { "item": "remington_870", "variant": "browning_a5", "prob": 14, "charges-min": 0, "charges-max": 0 }, + { "item": "remington_870", "variant": "remington_1100", "prob": 17, "charges-min": 0, "charges-max": 0 }, { "item": "mossberg_930", "prob": 15, "charges-min": 0, "charges-max": 0 }, { "item": "shotgun_410", "prob": 30, "charges-min": 0, "charges-max": 0 }, { "item": "shotgun_d", "prob": 30, "charges-min": 0, "charges-max": 0 }, @@ -517,8 +517,8 @@ { "item": "ksg", "prob": 50, "charges-min": 0, "charges-max": 7 }, { "item": "ksg-25", "prob": 8, "charges-min": 0, "charges-max": 12 }, { "item": "tavor_12", "prob": 5, "charges-min": 0, "charges-max": 5 }, - { "item": "m1014", "prob": 10, "charges-min": 0, "charges-max": 8 }, - { "item": "SPAS_12", "prob": 2, "charges-min": 0, "charges-max": 9 }, + { "item": "mossberg_930", "variant": "m1014", "prob": 10, "charges-min": 0, "charges-max": 8 }, + { "item": "mossberg_590", "variant": "SPAS_12", "prob": 2, "charges-min": 0, "charges-max": 9 }, { "item": "rm120c", "prob": 5, "charges-min": 0, "charges-max": 5 }, { "item": "rm228", "prob": 5, "charges-min": 0, "charges-max": 10 } ] @@ -531,8 +531,8 @@ "entries": [ { "item": "ksg", "prob": 50, "charges-min": 0, "charges-max": 0 }, { "item": "tavor_12", "prob": 5, "charges-min": 0, "charges-max": 0 }, - { "item": "m1014", "prob": 10, "charges-min": 0, "charges-max": 0 }, - { "item": "SPAS_12", "prob": 2, "charges-min": 0, "charges-max": 0 }, + { "item": "mossberg_930", "variant": "m1014", "prob": 10, "charges-min": 0, "charges-max": 0 }, + { "item": "mossberg_590", "variant": "SPAS_12", "prob": 2, "charges-min": 0, "charges-max": 0 }, { "item": "rm120c", "prob": 5, "charges-min": 0, "charges-max": 0 }, { "item": "rm228", "prob": 5, "charges-min": 0, "charges-max": 0 } ] @@ -576,7 +576,7 @@ { "item": "remington_870_express", "prob": 50, "charges-min": 0, "charges-max": 6 }, { "item": "remington_870_breacher", "prob": 20, "charges-min": 0, "charges-max": 4 }, { "item": "mossberg_590", "prob": 50, "charges-min": 0, "charges-max": 9 }, - { "item": "m1014", "prob": 100, "charges-min": 0, "charges-max": 8 } + { "item": "mossberg_930", "variant": "m1014", "prob": 100, "charges-min": 0, "charges-max": 8 } ] }, { @@ -791,7 +791,7 @@ { "item": "hk_mp5", "prob": 50, "charges-min": 0, "charges-max": 30 }, { "item": "hk_mp5k", "prob": 10, "charges-min": 0, "charges-max": 30 }, { "item": "hk_mp5sd", "prob": 5, "charges-min": 0, "charges-max": 30 }, - { "item": "m1014", "prob": 10, "charges-min": 0, "charges-max": 8 }, + { "item": "mossberg_930", "variant": "m1014", "prob": 10, "charges-min": 0, "charges-max": 8 }, { "item": "nato_assault_rifle", "variant": "m4a1", "prob": 35, "charges-min": 0, "charges-max": 30 }, { "item": "as50", "prob": 5, "charges-min": 0, "charges-max": 10 }, { "item": "hk417_13", "prob": 30, "charges-min": 0, "charges-max": 20 } diff --git a/data/json/itemgroups/military.json b/data/json/itemgroups/military.json index a58d5547f3655..e1efa1a9a32c4 100644 --- a/data/json/itemgroups/military.json +++ b/data/json/itemgroups/military.json @@ -20,7 +20,10 @@ "type": "item_group", "id": "military_standard_shotguns", "subtype": "distribution", - "entries": [ { "item": "m1014", "prob": 60, "charges": [ 0, 8 ] }, { "item": "mossberg_590", "prob": 40, "charges": [ 0, 9 ] } ] + "entries": [ + { "item": "mossberg_930", "variant": "m1014", "prob": 60, "charges": [ 0, 8 ] }, + { "item": "mossberg_590", "prob": 40, "charges": [ 0, 9 ] } + ] }, { "type": "item_group", @@ -190,7 +193,7 @@ { "item": "p226_9mm", "prob": 1 }, { "item": "sp2022", "prob": 1 }, { "item": "nato_assault_rifle", "variant": "h&k416a5", "prob": 7 }, - { "item": "m1014", "prob": 2 }, + { "item": "mossberg_930", "variant": "m1014", "prob": 2 }, { "item": "nato_assault_rifle", "variant": "scar_l", "prob": 6 }, { "item": "scar_h", "prob": 5 }, { "item": "sig_mcx_rattler_sbr", "prob": 1 }, diff --git a/data/json/items/gun/shot.json b/data/json/items/gun/shot.json index 662fbbcbf64b9..ffbc16ce3f34e 100644 --- a/data/json/items/gun/shot.json +++ b/data/json/items/gun/shot.json @@ -105,36 +105,21 @@ "extend": { "flags": [ "RELOAD_ONE" ] }, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "shot": 6 } } ] }, - { - "id": "browning_a5", - "copy-from": "shotgun_base", - "type": "GUN", - "name": { "str": "Browning Auto 5" }, - "description": "This humble looking shotgun was the earliest successful semi-automatic shotgun, and the second most successful in U.S. history, with over 2.7 million made between 1902 and 1998. The recoil tuning mechanism under the handguard and long dwell time of the action make for pleasant shooting.", - "weight": "3090 g", - "volume": "3525 ml", - "longest_side": "1263 mm", - "looks_like": "remington_870", - "price": 80000, - "price_postapoc": 2000, - "to_hit": -1, - "bashing": 12, - "material": [ "steel", "wood" ], - "ranged_damage": { "damage_type": "bullet", "amount": 1 }, - "dispersion": 425, - "durability": 6, - "min_cycle_recoil": 1250, - "clip_size": 5, - "extend": { "flags": [ "RELOAD_ONE" ] }, - "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "shot": 5 } } ] - }, { "id": "ksg", "copy-from": "shotgun_pump", "looks_like": "remington_870", "type": "GUN", - "name": { "str_sp": "Kel-Tec KSG" }, - "description": "A bullpup pump-action shotgun, the Kel-Tec KSG uses a pair of magazine tubes to increase its capacity. Each tube has to be loaded separately, but this offers the option of loading different ammunition for different situations.", + "name": { "str": "14-round tube shotgun" }, + "description": "This shotgun uses a system of 2 tube magazines to carry 14 rounds of 12 gauge shot. Each tube has to be loaded separately, but this offers the option of loading different ammunition for different situations.", + "variants": [ + { + "id": "ksg", + "name": { "str_sp": "Kel-Tec KSG" }, + "description": "A bullpup pump-action shotgun, the Kel-Tec KSG uses a pair of magazine tubes to increase its capacity. Each tube has to be loaded separately, but this offers the option of loading different ammunition for different situations.", + "weight": 1 + } + ], "ascii_picture": "ksg", "weight": "1550 g", "volume": "3371 ml", @@ -170,8 +155,16 @@ "copy-from": "shotgun_pump", "looks_like": "remington_870", "type": "GUN", - "name": { "str_sp": "Kel-Tec KSG-25" }, - "description": "A bullpup pump-action shotgun, the Kel-Tec KSG-25 uses a pair of magazine tubes to increase its capacity. Each tube has to be loaded separately, but this offers the option of loading different ammunition for different situations. The big brother of the KSG, it has a longer barrel and longer magazine tubes.", + "name": { "str": "24-round tube shotgun" }, + "description": "This shotgun uses a system of 2 tube magazines to carry 24 rounds of 12 gauge shot. Each tube has to be loaded separately, but this offers the option of loading different ammunition for different situations.", + "variants": [ + { + "id": "ksg-25", + "name": { "str_sp": "Kel-Tec KSG-25" }, + "description": "A bullpup pump-action shotgun, the Kel-Tec KSG-25 uses a pair of magazine tubes to increase its capacity. Each tube has to be loaded separately, but this offers the option of loading different ammunition for different situations. The big brother of the KSG, it has a longer barrel and longer magazine tubes.", + "weight": 1 + } + ], "ascii_picture": "ksg-25", "weight": "2100 g", "volume": "4495 ml", @@ -202,47 +195,27 @@ ], "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "shot": 12 } } ] }, - { - "id": "m1014", - "copy-from": "shotgun_base", - "looks_like": "remington_870", - "type": "GUN", - "name": { "str": "M1014 shotgun" }, - "description": "Benelli's first gas-operated shotgun, featuring dual pistons for enhanced reliability with various loads and a collapsible buttstock that reduces length by almost 8 inches. Adopted in 1999 as the M1014 Joint Service Combat Shotgun, the Benelli M4 is one of the finest combat shotguns available.", - "weight": "3629 g", - "volume": "6302 ml", - "longest_side": "1021 mm", - "price": 169900, - "price_postapoc": 3500, - "to_hit": -1, - "bashing": 12, - "material": [ "steel", "plastic" ], - "ranged_damage": { "damage_type": "bullet", "amount": 1 }, - "dispersion": 345, - "durability": 9, - "min_cycle_recoil": 1250, - "clip_size": 8, - "valid_mod_locations": [ - [ "accessories", 2 ], - [ "mechanism", 4 ], - [ "sling", 1 ], - [ "barrel", 1 ], - [ "rail mount", 1 ], - [ "loading port", 1 ], - [ "brass catcher", 1 ], - [ "sights", 1 ], - [ "underbarrel mount", 1 ] - ], - "flags": [ "RELOAD_ONE", "NEEDS_UNFOLD" ], - "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "shot": 8 } } ] - }, { "id": "mossberg_500", "copy-from": "shotgun_pump_3gun", "looks_like": "remington_870", "type": "GUN", - "name": { "str_sp": "Mossberg 500 Field" }, - "description": "The Mossberg 500 is a popular series of pump-action shotguns, often acquired for military use. It is noted for its high durability and low recoil. This one is fitted with a 28 inch barrel with sight rib.", + "name": { "str": "6-round shotgun" }, + "description": "This is a shotgun with capacity for 6 rounds of 12 gauge shot.", + "variants": [ + { + "id": "mossberg_500", + "name": { "str_sp": "Mossberg 500 Field" }, + "description": "The Mossberg 500 is a popular series of pump-action shotguns, often acquired for military use. It is noted for its high durability and low recoil. This one is fitted with a 28 inch barrel with sight rib.", + "weight": 1 + }, + { + "id": "mossberg_500_security", + "name": { "str_sp": "Mossberg 500 Security" }, + "description": "The Mossberg 500 is a popular series of pump-action shotguns, often acquired for military use. It is noted for its high durability and low recoil. This one is fitted with an 18.5 inch barrel.", + "ascii_picture": "mossberg500_sec" + } + ], "ascii_picture": "mossberg500", "weight": "3402 g", "volume": "2450 ml", @@ -259,30 +232,25 @@ "clip_size": 6, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "shot": 6 } } ] }, - { - "id": "mossberg_500_security", - "copy-from": "mossberg_500", - "type": "GUN", - "name": { "str_sp": "Mossberg 500 Security" }, - "description": "The Mossberg 500 is a popular series of pump-action shotguns, often acquired for military use. It is noted for its high durability and low recoil. This one is fitted with an 18.5 inch barrel.", - "ascii_picture": "mossberg500_sec", - "weight": "3062 g", - "volume": "2386 ml", - "longest_side": "1016 mm", - "looks_like": "mossberg_500", - "price": 53800, - "price_postapoc": 2250, - "bashing": 12, - "barrel_volume": "28 ml", - "dispersion": 375, - "ranged_damage": { "damage_type": "bullet", "amount": 1 } - }, { "id": "mossberg_590", - "copy-from": "mossberg_500_security", + "copy-from": "mossberg_500", "type": "GUN", - "name": { "str_sp": "Mossberg 590A1" }, - "description": "The Mossberg 590A1 is a military and police oriented version of the Mossberg 500. It features a heavier barrel, a bayonet lug, and a different magazine tube for easier cleaning and maintenance.", + "name": { "str": "9-round shotgun" }, + "description": "This is a shotgun with capacity for 9 rounds of 12 gauge shot", + "variants": [ + { + "id": "mossberg_590", + "name": { "str_sp": "Mossberg 590A1" }, + "description": "The Mossberg 590A1 is a military and police oriented version of the Mossberg 500. It features a heavier barrel, a bayonet lug, and a different magazine tube for easier cleaning and maintenance.", + "weight": 1 + }, + { + "id": "SPAS_12", + "name": { "str": "Franchi SPAS-12" }, + "description": "Mean and intimidating looking, the SPAS 12 has the dubious honor of being declared a destructive device and being banned from import by name, adding to its already considerable appeal. It is a combination pump-action and semi-automatic firearm, with an arm stabilizing hook for one handed shooting." + } + ], "ascii_picture": "mossberg590", "weight": "3289 g", "volume": "2548 ml", @@ -299,13 +267,26 @@ "id": "mossberg_930", "copy-from": "shotgun_base", "type": "GUN", - "name": { "str": "Mossberg 930 SPX" }, - "description": "This semi-automatic offering from Mossberg features a recoil reducing gas system, rifle style sights and a factory-installed picatinny rail. Affordable pricing and decent ergonomics make this a popular entry-level 3-gun shotgun.", + "name": { "str": "8-round shotgun" }, + "description": "This is a shotgun with capacity for 8 rounds of 12 gauge shot", + "variants": [ + { + "id": "mossberg_930", + "name": { "str": "Mossberg 930 SPX" }, + "description": "This semi-automatic offering from Mossberg features a recoil reducing gas system, rifle style sights and a factory-installed picatinny rail. Affordable pricing and decent ergonomics make this a popular entry-level 3-gun shotgun.", + "weight": 1 + }, + { + "id": "m1014", + "name": { "str": "M1014 shotgun" }, + "description": "Benelli's first gas-operated shotgun, featuring dual pistons for enhanced reliability with various loads and a collapsible buttstock that reduces length by almost 8 inches. Adopted in 1999 as the M1014 Joint Service Combat Shotgun, the Benelli M4 is one of the finest combat shotguns available." + } + ], "ascii_picture": "mossberg930sxp", "weight": "3402 g", "volume": "2623 ml", "longest_side": "994 mm", - "looks_like": "m1014", + "looks_like": "remington_870", "price": 60000, "price_postapoc": 2250, "to_hit": -1, @@ -397,8 +378,27 @@ "copy-from": "shotgun_pump_3gun", "//": "Tileset whitelist for shotguns.", "type": "GUN", - "name": { "str_sp": "Remington 870 Wingmaster" }, - "description": "With over 10 million made, the Remington 870 is one of the most popular shotguns on the market, and finds use with hunters and law enforcement agencies alike thanks to its high accuracy and muzzle velocity. This one is a 28 inch barreled model for hunting fowl and game.", + "name": { "str": "5-round shotgun" }, + "description": "This is a shotgun with capacity for 5 rounds of 12 gauge shot.", + "variants": [ + { + "id": "remington_870", + "name": { "str_sp": "Remington 870 Wingmaster" }, + "description": "With over 10 million made, the Remington 870 is one of the most popular shotguns on the market, and finds use with hunters and law enforcement agencies alike thanks to its high accuracy and muzzle velocity. This one is a 28 inch barreled model for hunting fowl and game.", + "weight": 1 + }, + { + "id": "remington_1100", + "name": { "str": "Remington 1100 competition" }, + "description": "This semi-automatic shotgun features a self compensating gas system that will feed a wide array of shells while also reducing recoil. Introduced in 1963, it is favored by law enforcement, hunters and competition shooters, and has been the best-selling autoloading shotgun in U.S. history. This is the nickel finished, teflon coated competition model, with a full length magazine tube and 30 inch barrel.", + "ascii_picture": "remington1100" + }, + { + "id": "browning_a5", + "name": { "str": "Browning Auto 5" }, + "description": "This humble looking shotgun was the earliest successful semi-automatic shotgun, and the second most successful in U.S. history, with over 2.7 million made between 1902 and 1998. The recoil tuning mechanism under the handguard and long dwell time of the action make for pleasant shooting." + } + ], "ascii_picture": "remington870", "weight": "3400 g", "volume": "2487 ml", @@ -419,8 +419,16 @@ "id": "remington_870_breacher", "copy-from": "remington_870", "type": "GUN", - "name": { "str": "Remington 870 MCS" }, - "description": "This Remington 870 Modular Combat System shotgun is currently setup for breaching operations, with a 10 inch barrel and no stock. It is small enough to carry as a secondary weapon, specifically to pop open any pesky doors you might come across. The grip's design makes for controllable yet unpleasant recoil, and the barrel lacks any sights.", + "name": { "str": "breaching shotgun" }, + "description": "This shotgun has a short barrel and no stock, and is set up for breaching doors. It is small enough to carry as a secondary weapon, but has fairly unpleasant recoil and no sights.", + "variants": [ + { + "id": "remington_870_breacher", + "name": { "str": "Remington 870 MCS" }, + "description": "This Remington 870 Modular Combat System shotgun is currently setup for breaching operations, with a 10 inch barrel and no stock. It is small enough to carry as a secondary weapon, specifically to pop open any pesky doors you might come across. The grip's design makes for controllable yet unpleasant recoil, and the barrel lacks any sights.", + "weight": 1 + } + ], "ascii_picture": "remington870mcs", "weight": "2812 g", "volume": "1284 ml", @@ -456,8 +464,16 @@ "id": "remington_870_express", "copy-from": "remington_870", "type": "GUN", - "name": { "str": "Remington 870 express", "str_pl": "Remington 870 expresses" }, - "description": "With over 10 million made, the Remington 870 is one of the most popular shotguns on the market, and finds use with hunters and law enforcement agencies alike thanks to its high accuracy and muzzle velocity. This one is an 18.5 inch barreled defensive model.", + "name": { "str": "7-round shotgun" }, + "description": "This is a shotgun with capacity for 7 rounds of 12 gauge shot.", + "variants": [ + { + "id": "remington_870_express", + "name": { "str": "Remington 870 express", "str_pl": "Remington 870 expresses" }, + "description": "With over 10 million made, the Remington 870 is one of the most popular shotguns on the market, and finds use with hunters and law enforcement agencies alike thanks to its high accuracy and muzzle velocity. This one is an 18.5 inch barreled defensive model.", + "weight": 1 + } + ], "ascii_picture": "remington870xpress", "weight": "3402 g", "volume": "2365 ml", @@ -471,45 +487,6 @@ "price_postapoc": 2750, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "shot": 7 } } ] }, - { - "id": "remington_1100", - "copy-from": "shotgun_base", - "type": "GUN", - "name": { "str": "Remington 1100 competition" }, - "description": "This semi-automatic shotgun features a self compensating gas system that will feed a wide array of shells while also reducing recoil. Introduced in 1963, it is favored by law enforcement, hunters and competition shooters, and has been the best-selling autoloading shotgun in U.S. history. This is the nickel finished, teflon coated competition model, with a full length magazine tube and 30 inch barrel.", - "ascii_picture": "remington1100", - "weight": "3742 g", - "volume": "2626 ml", - "longest_side": "1288 mm", - "price_postapoc": 3250, - "looks_like": "remington_870", - "price": 130000, - "to_hit": -1, - "bashing": 13, - "material": [ "steel", "plastic" ], - "dispersion": 315, - "ranged_damage": { "damage_type": "bullet", "amount": 6 }, - "durability": 8, - "min_cycle_recoil": 1250, - "clip_size": 10, - "barrel_volume": "299 ml", - "built_in_mods": [ "match_trigger" ], - "default_mods": [ "recoil_stock" ], - "valid_mod_locations": [ - [ "accessories", 2 ], - [ "sling", 1 ], - [ "brass catcher", 1 ], - [ "barrel", 1 ], - [ "stock", 1 ], - [ "mechanism", 4 ], - [ "rail mount", 1 ], - [ "loading port", 1 ], - [ "sights mount", 1 ], - [ "underbarrel mount", 1 ] - ], - "extend": { "flags": [ "RELOAD_ONE" ] }, - "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "shot": 5 } } ] - }, { "id": "revolver_shotgun", "copy-from": "shotgun_base", @@ -549,8 +526,16 @@ "copy-from": "shotgun_base", "looks_like": "remington_870", "type": "GUN", - "name": { "str": "Saiga-12" }, - "description": "The Saiga-12 is a semi-automatic shotgun designed on the same Kalashnikov pattern as the AK47 rifle. It reloads with a magazine, rather than one shell at a time like most shotguns. It is one of the last designs of Mikhail Kalashnikov, and was popular in open division shotgun competitions prior to its ban from import via executive order.", + "name": { "str": "Saiga shotgun" }, + "description": "This shotgun is chambered in 12 gauge, and accepting Saiga magazines.", + "variants": [ + { + "id": "saiga_12", + "name": { "str": "Saiga-12" }, + "description": "The Saiga-12 is a semi-automatic shotgun designed on the same Kalashnikov pattern as the AK47 rifle. It reloads with a magazine, rather than one shell at a time like most shotguns. It is one of the last designs of Mikhail Kalashnikov, and was popular in open division shotgun competitions prior to its ban from import via executive order.", + "weight": 1 + } + ], "weight": "3225 g", "volume": "3064 ml", "longest_side": "1068 mm", @@ -653,8 +638,16 @@ "id": "streetsweeper", "copy-from": "shotgun_base", "type": "GUN", - "name": { "str": "Cobray Streetsweeper" }, - "description": "Less shotgun and more comically oversized revolver, the Cobray Streetsweeper sold poorly before it was deemed a destructive device. The cylinder is driven by a clockspring, cannot be indexed by hand, and must be ejected with an ejector rod. Its unique design allows for all 12 shells to be fired in under 3 seconds, as demonstrated by the ATF technical branch.", + "name": { "str": "automatic shotgun" }, + "description": "This shotgun, deemed a destructive device, resembles a comically oversized revolver. It can hold 12 rounds of 12 gauge shot, and fire all of them in under 3 seconds", + "variants": [ + { + "id": "streetsweeper", + "name": { "str": "Cobray Streetsweeper" }, + "description": "Less shotgun and more comically oversized revolver, the Cobray Streetsweeper sold poorly before it was deemed a destructive device. The cylinder is driven by a clockspring, cannot be indexed by hand, and must be ejected with an ejector rod. Its unique design allows for all 12 shells to be fired in under 3 seconds, as demonstrated by the ATF technical branch.", + "weight": 1 + } + ], "weight": "4200 g", "volume": "3193 ml", "longest_side": "592 mm", @@ -688,48 +681,20 @@ "flags": [ "RELOAD_ONE", "RELOAD_EJECT", "NEVER_JAMS" ], "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "shot": 12 } } ] }, - { - "id": "SPAS_12", - "copy-from": "shotgun_base", - "type": "GUN", - "name": { "str": "Franchi SPAS-12" }, - "description": "Mean and intimidating looking, the SPAS 12 has the dubious honor of being declared a destructive device and being banned from import by name, adding to its already considerable appeal. It is a combination pump-action and semi-automatic firearm, with an arm stabilizing hook for one handed shooting.", - "weight": "4400 g", - "volume": "2768 ml", - "longest_side": "835 mm", - "looks_like": "m1014", - "price": 180000, - "price_postapoc": 4750, - "to_hit": -1, - "bashing": 12, - "material": [ "steel", "wood" ], - "dispersion": 380, - "durability": 6, - "clip_size": 9, - "ranged_damage": { "damage_type": "bullet", "amount": 1 }, - "built_in_mods": [ "wire_stock" ], - "valid_mod_locations": [ - [ "accessories", 4 ], - [ "bore", 1 ], - [ "brass catcher", 1 ], - [ "grip mount", 1 ], - [ "mechanism", 2 ], - [ "muzzle", 1 ], - [ "rail mount", 1 ], - [ "sights mount", 1 ], - [ "sling", 1 ], - [ "stock", 1 ], - [ "underbarrel mount", 1 ] - ], - "flags": [ "RELOAD_ONE" ], - "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "shot": 9 } } ] - }, { "id": "tavor_12", "copy-from": "shotgun_base", "type": "GUN", - "name": { "str": "Tavor TS12" }, - "description": "This is a triple tube magazine fed, gas-operated bullpup shotgun of Israeli Weapon Industries make. It is capable of loading 15 shells, all in a relatively small package. Like many other modern IWI designs, this looks more like a sci-fi prop gun than a firearm. An integral top rail is provided for mounting sights.", + "name": { "str": "15-round tube fed shotgun" }, + "description": "This shotgun uses a system of 3 tube magazines to hold 15 rounds of 12 gauge shots, in a relatively small firearm. Each tube has to be loaded separately, but this offers the option of loading different ammunition for different situations.", + "variants": [ + { + "id": "tavor_12", + "name": { "str": "Tavor TS12" }, + "description": "This is a triple tube magazine fed, gas-operated bullpup shotgun of Israeli Weapon Industries make. It is capable of loading 15 shells, all in a relatively small package. Like many other modern IWI designs, this looks more like a sci-fi prop gun than a firearm. An integral top rail is provided for mounting sights.", + "weight": 1 + } + ], "weight": "3429 g", "volume": "4040 ml", "longest_side": "725 mm", @@ -765,8 +730,16 @@ "id": "winchester_1887", "copy-from": "shotgun_base", "type": "GUN", - "name": { "str": "1887 bootleg shotgun" }, - "description": "One of the first commercially successful repeating shotguns, the Winchester 1887 was specifically made lever-action at Winchester's request. Though later overshadowed in success by pump designs, the 1887 remains popular today. This one has a very short barrel, no stock, and would pair nicely with a motorcycle jacket and a Harley Davidson.", + "name": { "str": "6-round lever-action shotgun" }, + "description": "This is a lever-action shotgun with a very short barrel, and no stock, accepting 6 rounds of 12 gauge shot. It would pair nicely with a motorcycle jacket and a Harley Davidson.", + "variants": [ + { + "id": "winchester_1887", + "name": { "str": "1887 bootleg shotgun" }, + "description": "One of the first commercially successful repeating shotguns, the Winchester 1887 was specifically made lever-action at Winchester's request. Though later overshadowed in success by pump designs, the 1887 remains popular today. This one has a very short barrel, no stock, and would pair nicely with a motorcycle jacket and a Harley Davidson.", + "weight": 1 + } + ], "weight": "2994 g", "volume": "1127 ml", "longest_side": "708 mm", @@ -801,8 +774,16 @@ "id": "winchester_1897", "copy-from": "shotgun_base", "type": "GUN", - "name": { "str": "M1897 Trench Gun" }, - "description": "The Winchester 1897 was one of the first commercially-successful pump-action shotguns. In its 'trench' configuration it has become a heavily-romanticized American icon of World War 1. With its barrel shroud, bayonet lug, and 17 inch bayonet, this shotgun is undeniably fearsome in appearance. There aren't any more trenches to clear, so the next zombie-infested town will have to suffice.", + "name": { "str": "trench shotgun" }, + "description": "This shotgun comes attached with a large bayonet, as though it comes straight from the trenches of World War 1. There aren't any more trenches to clear, so the next zombie-infested town will have to suffice.", + "variants": [ + { + "id": "winchester_1897", + "name": { "str": "M1897 Trench Gun" }, + "description": "The Winchester 1897 was one of the first commercially-successful pump-action shotguns. In its 'trench' configuration it has become a heavily-romanticized American icon of World War 1. With its barrel shroud, bayonet lug, and 17 inch bayonet, this shotgun is undeniably fearsome in appearance. There aren't any more trenches to clear, so the next zombie-infested town will have to suffice.", + "weight": 1 + } + ], "weight": "3629 g", "volume": "2564 ml", "longest_side": "989 mm", diff --git a/data/json/items/magazine/shot.json b/data/json/items/magazine/shot.json index 7a0e3f8cea87f..53830d13363bb 100644 --- a/data/json/items/magazine/shot.json +++ b/data/json/items/magazine/shot.json @@ -3,8 +3,16 @@ "id": "saiga10mag", "looks_like": "shotbelt_20", "type": "MAGAZINE", - "name": { "str": "Saiga-12 10-round magazine" }, - "description": "A removable plastic magazine for the Saiga-12 shotgun. Holds 10 rounds.", + "name": { "str": "Saiga shotgun 10-round magazine" }, + "description": "A removable plastic magazine for the Saiga shotgun. Holds 10 rounds.", + "variants": [ + { + "id": "saiga10mag", + "name": { "str": "Saiga-12 10-round magazine" }, + "description": "A removable plastic magazine for the Saiga-12 shotgun. Holds 10 rounds.", + "weight": 1 + } + ], "weight": "210 g", "volume": "500 ml", "price": 4500, @@ -20,8 +28,16 @@ "id": "saiga30mag", "looks_like": "shotbelt_20", "type": "MAGAZINE", - "name": { "str": "Saiga-12 30-round drum magazine" }, - "description": "A removable plastic magazine for the Saiga-12 shotgun. Holds 30 rounds.", + "name": { "str": "Saiga shotgun 30-round drum magazine" }, + "description": "A removable plastic magazine for the Saiga shotgun. Holds 30 rounds.", + "variants": [ + { + "id": "saiga30mag", + "name": { "str": "Saiga-12 30-round drum magazine" }, + "description": "A removable plastic magazine for the Saiga-12 shotgun. Holds 30 rounds.", + "weight": 1 + } + ], "weight": "460 g", "volume": "1 L", "price": 11000, diff --git a/data/json/items/migration.json b/data/json/items/migration.json index 6629d0ab6622b..eaa03579f6da4 100644 --- a/data/json/items/migration.json +++ b/data/json/items/migration.json @@ -1148,6 +1148,36 @@ "type": "MIGRATION", "replace": "nato_assault_rifle" }, + { + "id": "browning_a5", + "type": "MIGRATION", + "replace": "remington_870", + "variant": "browning_a5" + }, + { + "id": "remington_1100", + "type": "MIGRATION", + "replace": "remington_870", + "variant": "remington_1100" + }, + { + "id": "mossberg_500_security", + "type": "MIGRATION", + "replace": "mossberg_500", + "variant": "mossberg_500_security" + }, + { + "id": "m1014", + "type": "MIGRATION", + "replace": "mossberg_930", + "variant": "m1014" + }, + { + "id": "SPAS_12", + "type": "MIGRATION", + "replace": "mossberg_590", + "variant": "SPAS_12" + }, { "id": "acr", "type": "MIGRATION", diff --git a/data/json/mapgen/military/mil_base/mil_base_z0.json b/data/json/mapgen/military/mil_base/mil_base_z0.json index 1b0031302de86..664631853d50b 100644 --- a/data/json/mapgen/military/mil_base/mil_base_z0.json +++ b/data/json/mapgen/military/mil_base/mil_base_z0.json @@ -787,7 +787,7 @@ { "item": "556", "x": 18, "y": [ 9, 12 ], "chance": 75, "repeat": 150 }, { "item": "m249", "x": 20, "y": 9, "chance": 75, "repeat": 6 }, { "item": "m240", "x": 20, "y": 9, "chance": 75, "repeat": 4 }, - { "item": "m1014", "x": 20, "y": 10, "chance": 75, "repeat": 10 }, + { "item": "mossberg_930", "variant": "m1014", "x": 20, "y": 10, "chance": 75, "repeat": 10 }, { "item": "mossberg_590", "x": 20, "y": 10, "chance": 75, "repeat": 8 }, { "item": "m2010", "x": 20, "y": 11, "magazine": 100, "chance": 75, "repeat": 2 }, { "item": "m110a1", "x": 20, "y": 11, "magazine": 100, "chance": 75, "repeat": 8 }, diff --git a/data/json/professions.json b/data/json/professions.json index 7b1e2f501c5e5..6792e5838fd47 100644 --- a/data/json/professions.json +++ b/data/json/professions.json @@ -961,7 +961,8 @@ { "item": "knife_combat", "container-item": "sheath" }, { "item": "shot_00", "count": 2 }, { - "item": "m1014", + "item": "mossberg_930", + "variant": "m1014", "ammo-item": "shot_00", "charges": 8, "contents-item": [ "shoulder_strap", "holo_sight" ] diff --git a/data/mods/Aftershock/mobs/robots.json b/data/mods/Aftershock/mobs/robots.json index 274754bc4c9c9..c6a4acca00f15 100644 --- a/data/mods/Aftershock/mobs/robots.json +++ b/data/mods/Aftershock/mobs/robots.json @@ -456,7 +456,7 @@ "type": "gun", "move_cost": 150, "cooldown": 2, - "gun_type": "m1014", + "gun_type": "mossberg_930", "ammo_type": "shot", "fake_skills": [ [ "gun", 2 ], [ "shotgun", 2 ] ], "fake_dex": 9, diff --git a/data/mods/BlazeIndustries/vehicleparts/blaze_turrets_vanilla.json b/data/mods/BlazeIndustries/vehicleparts/blaze_turrets_vanilla.json index 4cf46dd686f76..f93f36f6d9602 100644 --- a/data/mods/BlazeIndustries/vehicleparts/blaze_turrets_vanilla.json +++ b/data/mods/BlazeIndustries/vehicleparts/blaze_turrets_vanilla.json @@ -240,8 +240,8 @@ "copy-from": "turret", "type": "vehicle_part", "name": { "str": "mounted M1014 shotgun" }, - "item": "m1014", - "breaks_into": [ { "item": "m1014", "prob": 50 } ], + "item": "mossberg_930", + "breaks_into": [ { "item": "mossberg_930", "prob": 50 } ], "requirements": { "install": { "skills": [ [ "mechanics", 4 ] ] }, "removal": { "skills": [ [ "mechanics", 2 ] ] } } }, { diff --git a/data/mods/Generic_Guns/firearms/gg_firearms_migration.json b/data/mods/Generic_Guns/firearms/gg_firearms_migration.json index 428c44560049f..90db3241b58be 100644 --- a/data/mods/Generic_Guns/firearms/gg_firearms_migration.json +++ b/data/mods/Generic_Guns/firearms/gg_firearms_migration.json @@ -334,20 +334,15 @@ { "id": [ "shotgun_410", - "browning_a5", "ksg", "ksg-25", - "m1014", "mossberg_500", - "mossberg_500_security", "mossberg_590", "mossberg_930", "remington_870", "remington_870_breacher", "remington_870_express", - "remington_1100", - "streetsweeper", - "SPAS_12" + "streetsweeper" ], "type": "MIGRATION", "replace": "shot_pump" diff --git a/tests/ranged_balance_test.cpp b/tests/ranged_balance_test.cpp index bc27c11728a90..e9567914456c7 100644 --- a/tests/ranged_balance_test.cpp +++ b/tests/ranged_balance_test.cpp @@ -327,7 +327,7 @@ TEST_CASE( "expert_shooter_accuracy", "[ranged] [balance]" ) test_fast_shooting( shooter, 50, 0.4 ); } SECTION( "an expert shooter with an excellent shotgun" ) { - arm_shooter( shooter, "m1014", { "holo_sight" } ); + arm_shooter( shooter, "mossberg_930", { "holo_sight" } ); test_shooting_scenario( shooter, 18, 24, 124 ); test_fast_shooting( shooter, 60, 0.5 ); } From 98b6dfbe6fb6a571c7e7d0cd7a08a728433c0d68 Mon Sep 17 00:00:00 2001 From: John Bytheway <52664+jbytheway@users.noreply.github.com> Date: Fri, 9 Jul 2021 11:58:48 -0400 Subject: [PATCH 103/116] Improve fallback rendering for overmap terrain (#49777) * Partial fix of missing fallback in the graphical Overmap * Don't specify zero subtile for overmap terrains This is misleading the rendering code into picking the wrong subtile. The correct value for "I don't think there is a subtile" is -1, not 0. Co-authored-by: Fris0uman --- src/cata_tiles.cpp | 19 +++++++++++++++++-- src/omdata.h | 4 ++++ src/sdltiles.cpp | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/cata_tiles.cpp b/src/cata_tiles.cpp index cb9c45ff1c11a..2bf90a6a703e4 100644 --- a/src/cata_tiles.cpp +++ b/src/cata_tiles.cpp @@ -1876,9 +1876,13 @@ bool cata_tiles::draw_from_id_string( const std::string &id, TILE_CATEGORY categ col = tmp.color(); } else if( category == C_OVERMAP_TERRAIN ) { const oter_str_id tmp( id ); + const oter_type_str_id type_tmp( id ); if( tmp.is_valid() ) { - sym = tmp->get_symbol().front(); + sym = tmp->get_uint32_symbol(); col = tmp->get_color(); + } else if( type_tmp.is_valid() ) { + sym = type_tmp->get_symbol().front(); + col = type_tmp->color; } } else if( category == C_OVERMAP_NOTE ) { sym = id[5]; @@ -1887,42 +1891,54 @@ bool cata_tiles::draw_from_id_string( const std::string &id, TILE_CATEGORY categ // Special cases for walls switch( sym ) { case LINE_XOXO: + case LINE_XOXO_UNICODE: sym = LINE_XOXO_C; break; case LINE_OXOX: + case LINE_OXOX_UNICODE: sym = LINE_OXOX_C; break; case LINE_XXOO: + case LINE_XXOO_UNICODE: sym = LINE_XXOO_C; break; case LINE_OXXO: + case LINE_OXXO_UNICODE: sym = LINE_OXXO_C; break; case LINE_OOXX: + case LINE_OOXX_UNICODE: sym = LINE_OOXX_C; break; case LINE_XOOX: + case LINE_XOOX_UNICODE: sym = LINE_XOOX_C; break; case LINE_XXXO: + case LINE_XXXO_UNICODE: sym = LINE_XXXO_C; break; case LINE_XXOX: + case LINE_XXOX_UNICODE: sym = LINE_XXOX_C; break; case LINE_XOXX: + case LINE_XOXX_UNICODE: sym = LINE_XOXX_C; break; case LINE_OXXX: + case LINE_OXXX_UNICODE: sym = LINE_OXXX_C; break; case LINE_XXXX: + case LINE_XXXX_UNICODE: sym = LINE_XXXX_C; break; default: // sym goes unchanged break; } + if( sym != 0 && sym < 256 ) { // see cursesport.cpp, function wattron const int pairNumber = col.to_color_pair_index(); @@ -1936,7 +1952,6 @@ bool cata_tiles::draw_from_id_string( const std::string &id, TILE_CATEGORY categ if( sym != LINE_XOXO_C && sym != LINE_OXOX_C ) { rota = 0; } - if( tileset_ptr->find_tile_type( generic_id ) ) { return draw_from_id_string( generic_id, pos, subtile, rota, ll, apply_night_vision_goggles ); diff --git a/src/omdata.h b/src/omdata.h index 3d1fefe43f0d8..342da3096ef87 100644 --- a/src/omdata.h +++ b/src/omdata.h @@ -281,6 +281,10 @@ struct oter_t { return utf32_to_utf8( from_land_use_code ? symbol_alt : symbol ); } + uint32_t get_uint32_symbol() const { + return symbol; + } + nc_color get_color( const bool from_land_use_code = false ) const { return from_land_use_code ? type->land_use_code->color : type->color; } diff --git a/src/sdltiles.cpp b/src/sdltiles.cpp index b0452d5d0241e..72fe41e46a538 100644 --- a/src/sdltiles.cpp +++ b/src/sdltiles.cpp @@ -886,7 +886,7 @@ void cata_tiles::draw_om( const point &dest, const tripoint_abs_omt ¢er_abs_ const lit_level ll = overmap_buffer.is_explored( omp ) ? lit_level::LOW : lit_level::LIT; // light level is now used for choosing between grayscale filter and normal lit tiles. - draw_from_id_string( id, TILE_CATEGORY::C_OVERMAP_TERRAIN, "overmap_terrain", pos, 0, rotation, + draw_from_id_string( id, TILE_CATEGORY::C_OVERMAP_TERRAIN, "overmap_terrain", pos, -1, rotation, ll, false, height_3d ); if( see ) { From 0cb39780938e31bbf4fe4b6ae2a2762495259a47 Mon Sep 17 00:00:00 2001 From: John Bytheway <52664+jbytheway@users.noreply.github.com> Date: Fri, 9 Jul 2021 12:17:39 -0400 Subject: [PATCH 104/116] Improve error message re armor portions (#49760) When duplicate bodyparts appear in the armor portion data, it's helpful to know which bodyparts they are. --- src/item_factory.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/item_factory.cpp b/src/item_factory.cpp index 55c5fe59c0771..03d64a5df9b3c 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -1163,7 +1163,9 @@ void Item_factory::check_definitions() const for( const bodypart_str_id &bp : *portion.covers ) { if( portion.covers->test( bp ) ) { if( observed_bps.count( bp ) ) { - msg += "multiple portions with same body_part defined\n"; + msg += string_format( + "multiple portions with same body_part %s defined\n", + bp.str() ); } observed_bps.insert( bp ); } From ca4066a2c03e66ae2c8da3d02d41706bcab92dc9 Mon Sep 17 00:00:00 2001 From: Fris0uman <41293484+Fris0uman@users.noreply.github.com> Date: Fri, 9 Jul 2021 18:38:34 +0200 Subject: [PATCH 105/116] Move refueling CBM to its own menu (#48750) * Refueling menu first pass * Get refueling menu to actually refuel * Desentangle fueling and eating * Add refueling to consume menu * fix error? * Remove unused static * remove unused variable --- data/json/player_activities.json | 9 ++ data/raw/keybindings.json | 7 + src/activity_actor.cpp | 19 ++- src/activity_actor_definitions.h | 5 +- src/activity_handlers.cpp | 9 ++ src/activity_handlers.h | 1 + src/avatar_action.cpp | 8 +- src/avatar_action.h | 4 +- src/bionics_ui.cpp | 11 +- src/character.h | 2 + src/consumption.cpp | 68 +++++---- src/game_inventory.cpp | 228 ++++++++++++++++++++++++++++--- src/game_inventory.h | 2 + src/handle_action.cpp | 4 + src/player.h | 4 +- 15 files changed, 310 insertions(+), 71 deletions(-) diff --git a/data/json/player_activities.json b/data/json/player_activities.json index 37a5d65db1003..947c20723245e 100644 --- a/data/json/player_activities.json +++ b/data/json/player_activities.json @@ -872,6 +872,15 @@ "based_on": "neither", "no_resume": true }, + { + "id": "ACT_CONSUME_FUEL_MENU", + "type": "activity_type", + "activity_level": "NO_EXERCISE", + "verb": "consuming fuel", + "suspendable": false, + "based_on": "neither", + "no_resume": true + }, { "id": "ACT_MIND_SPLICER", "type": "activity_type", diff --git a/data/raw/keybindings.json b/data/raw/keybindings.json index a0e9bec885d4d..ddee7b26850b0 100644 --- a/data/raw/keybindings.json +++ b/data/raw/keybindings.json @@ -1686,6 +1686,13 @@ "name": "Toggle safe fuel mod", "bindings": [ { "input_method": "keyboard_char", "key": "S" }, { "input_method": "keyboard_code", "key": "s", "mod": [ "shift" ] } ] }, + { + "type": "keybinding", + "id": "REFUEL", + "category": "BIONICS", + "name": "Open refuel menu", + "bindings": [ { "input_method": "keyboard_char", "key": "R" }, { "input_method": "keyboard_code", "key": "r", "mod": [ "shift" ] } ] + }, { "type": "keybinding", "id": "TOGGLE_AUTO_START", diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index b22bf09ad6d3a..73bfcad937ebb 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -1466,7 +1466,13 @@ void consume_activity_actor::start( player_activity &act, Character &guy ) int moves; Character &player_character = get_player_character(); if( consume_location ) { - const ret_val ret = player_character.will_eat( *consume_location, true ); + ret_val ret = ret_val::make_success(); + if( refuel ) { + ret = player_character.can_consume_fuel( *consume_location ); + } else { + ret = player_character.will_eat( *consume_location, true ); + } + if( !ret.success() ) { canceled = true; consume_menu_selections = std::vector(); @@ -1476,7 +1482,12 @@ void consume_activity_actor::start( player_activity &act, Character &guy ) } moves = to_moves( guy.get_consume_time( *consume_location ) ); } else if( !consume_item.is_null() ) { - const ret_val ret = player_character.will_eat( consume_item, true ); + ret_val ret = ret_val::make_success(); + if( refuel ) { + ret = player_character.can_consume_fuel( consume_item ); + } else { + ret = player_character.will_eat( consume_item, true ); + } if( !ret.success() ) { canceled = true; consume_menu_selections = std::vector(); @@ -1513,9 +1524,9 @@ void consume_activity_actor::finish( player_activity &act, Character & ) avatar &player_character = get_avatar(); if( !canceled ) { if( consume_loc ) { - player_character.consume( consume_loc, /*force=*/true ); + player_character.consume( consume_loc, /*force=*/true, refuel ); } else if( !consume_item.is_null() ) { - player_character.consume( consume_item, /*force=*/true ); + player_character.consume( consume_item, /*force=*/true, refuel ); } else { debugmsg( "Item location/name to be consumed should not be null." ); } diff --git a/src/activity_actor_definitions.h b/src/activity_actor_definitions.h index 15de610521fc3..6cb0c6fc7502f 100644 --- a/src/activity_actor_definitions.h +++ b/src/activity_actor_definitions.h @@ -583,6 +583,7 @@ class consume_activity_actor : public activity_actor std::string consume_menu_filter; bool canceled = false; activity_id type; + bool refuel = false; /** * @pre @p other is a consume_activity_actor */ @@ -595,11 +596,11 @@ class consume_activity_actor : public activity_actor consume_activity_actor( const item_location &consume_location, std::vector consume_menu_selections, const std::vector &consume_menu_selected_items, - const std::string &consume_menu_filter, activity_id type ) : + const std::string &consume_menu_filter, activity_id type, bool refuel = false ) : consume_location( consume_location ), consume_menu_selections( consume_menu_selections ), consume_menu_selected_items( consume_menu_selected_items ), consume_menu_filter( consume_menu_filter ), - type( type ) {} + type( type ), refuel( refuel ) {} explicit consume_activity_actor( const item_location &consume_location ) : consume_location( consume_location ), consume_menu_selections( std::vector() ) {} diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index ea387b3622509..422f3fe4558fc 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -117,6 +117,7 @@ static const activity_id ACT_CLEAR_RUBBLE( "ACT_CLEAR_RUBBLE" ); static const activity_id ACT_CONSUME_DRINK_MENU( "ACT_CONSUME_DRINK_MENU" ); static const activity_id ACT_CONSUME_FOOD_MENU( "ACT_CONSUME_FOOD_MENU" ); static const activity_id ACT_CONSUME_MEDS_MENU( "ACT_CONSUME_MEDS_MENU" ); +static const activity_id ACT_CONSUME_FUEL_MENU( "ACT_CONSUME_FUEL_MENU" ); static const activity_id ACT_CRACKING( "ACT_CRACKING" ); static const activity_id ACT_DISMEMBER( "ACT_DISMEMBER" ); static const activity_id ACT_DISSECT( "ACT_DISSECT" ); @@ -272,6 +273,7 @@ activity_handlers::do_turn_functions = { { ACT_CONSUME_FOOD_MENU, consume_food_menu_do_turn }, { ACT_CONSUME_DRINK_MENU, consume_drink_menu_do_turn }, { ACT_CONSUME_MEDS_MENU, consume_meds_menu_do_turn }, + { ACT_CONSUME_FUEL_MENU, consume_fuel_menu_do_turn }, { ACT_MOVE_LOOT, move_loot_do_turn }, { ACT_ADV_INVENTORY, adv_inventory_do_turn }, { ACT_ARMOR_LAYERS, armor_layers_do_turn }, @@ -351,6 +353,7 @@ activity_handlers::finish_functions = { { ACT_CONSUME_FOOD_MENU, eat_menu_finish }, { ACT_CONSUME_DRINK_MENU, eat_menu_finish }, { ACT_CONSUME_MEDS_MENU, eat_menu_finish }, + { ACT_CONSUME_FUEL_MENU, eat_menu_finish }, { ACT_WASH, washing_finish }, { ACT_HACKSAW, hacksaw_finish }, { ACT_PRY_NAILS, pry_nails_finish }, @@ -2843,6 +2846,12 @@ void activity_handlers::consume_meds_menu_do_turn( player_activity *, player * ) avatar_action::eat( player_character, game_menus::inv::consume_meds( player_character ) ); } +void activity_handlers::consume_fuel_menu_do_turn( player_activity *, player * ) +{ + avatar &player_character = get_avatar(); + avatar_action::eat( player_character, game_menus::inv::consume_fuel( player_character ), true ); +} + void activity_handlers::move_loot_do_turn( player_activity *act, player *p ) { activity_on_turn_move_loot( *act, *p ); diff --git a/src/activity_handlers.h b/src/activity_handlers.h index bfb9ff44bd3af..2e897e4d0fe93 100644 --- a/src/activity_handlers.h +++ b/src/activity_handlers.h @@ -148,6 +148,7 @@ void eat_menu_do_turn( player_activity *act, player *p ); void consume_food_menu_do_turn( player_activity *act, player *p ); void consume_drink_menu_do_turn( player_activity *act, player *p ); void consume_meds_menu_do_turn( player_activity *act, player *p ); +void consume_fuel_menu_do_turn( player_activity *act, player *p ); void move_items_do_turn( player_activity *act, player *p ); void multiple_farm_do_turn( player_activity *act, player *p ); void multiple_fish_do_turn( player_activity *act, player *p ); diff --git a/src/avatar_action.cpp b/src/avatar_action.cpp index cb9b324efde4c..ccc0986c6ffb7 100644 --- a/src/avatar_action.cpp +++ b/src/avatar_action.cpp @@ -830,21 +830,21 @@ bool avatar_action::eat_here( avatar &you ) return false; } -void avatar_action::eat( avatar &you, const item_location &loc ) +void avatar_action::eat( avatar &you, const item_location &loc, bool refuel ) { std::string filter; if( !you.activity.str_values.empty() ) { filter = you.activity.str_values.back(); } avatar_action::eat( you, loc, you.activity.values, you.activity.targets, filter, - you.activity.id() ); + you.activity.id(), refuel ); } void avatar_action::eat( avatar &you, const item_location &loc, const std::vector &consume_menu_selections, const std::vector &consume_menu_selected_items, const std::string &consume_menu_filter, - activity_id type ) + activity_id type, bool refuel ) { if( !loc ) { you.cancel_activity(); @@ -852,7 +852,7 @@ void avatar_action::eat( avatar &you, const item_location &loc, return; } you.assign_activity( player_activity( consume_activity_actor( loc, consume_menu_selections, - consume_menu_selected_items, consume_menu_filter, type ) ) ); + consume_menu_selected_items, consume_menu_filter, type, refuel ) ) ); } void avatar_action::plthrow( avatar &you, item_location loc, diff --git a/src/avatar_action.h b/src/avatar_action.h index 149f55135d14c..cdc27d95f70d3 100644 --- a/src/avatar_action.h +++ b/src/avatar_action.h @@ -21,11 +21,11 @@ namespace avatar_action { /** Eat food or fuel 'E' (or 'a') */ -void eat( avatar &you, const item_location &loc ); +void eat( avatar &you, const item_location &loc, bool refuel = false ); void eat( avatar &you, const item_location &loc, const std::vector &consume_menu_selections, const std::vector &consume_menu_selected_items, - const std::string &consume_menu_filter, activity_id type ); + const std::string &consume_menu_filter, activity_id type, bool refuel = false ); // special rules for eating: grazing etc // returns false if no rules are needed bool eat_here( avatar &you ); diff --git a/src/bionics_ui.cpp b/src/bionics_ui.cpp index ce7835e5aa08c..5fd87546e2ba1 100644 --- a/src/bionics_ui.cpp +++ b/src/bionics_ui.cpp @@ -7,6 +7,7 @@ #include #include "avatar.h" +#include "avatar_action.h" #include "bionics.h" #include "bodypart.h" #include "calendar.h" @@ -17,6 +18,7 @@ #include "enums.h" #include "flat_set.h" #include "game.h" +#include "game_inventory.h" #include "input.h" #include "inventory.h" #include "material.h" @@ -268,9 +270,10 @@ static void draw_bionics_titlebar( const catacurses::window &window, avatar *p, std::string desc_append = string_format( _( "[%s] Reassign, [%s] Switch tabs, " "[%s] Toggle fuel saving mode, " - "[%s] Toggle auto start mode." ), + "[%s] Toggle auto start mode, " + "[%s] Open refueling menu." ), ctxt.get_desc( "REASSIGN" ), ctxt.get_desc( "NEXT_TAB" ), ctxt.get_desc( "TOGGLE_SAFE_FUEL" ), - ctxt.get_desc( "TOGGLE_AUTO_START" ) ); + ctxt.get_desc( "TOGGLE_AUTO_START" ), ctxt.get_desc( "REFUEL" ) ); desc_append += string_format( _( " [%s] Sort: %s" ), ctxt.get_desc( "SORT" ), sort_mode_str( uistate.bionic_sort_mode ) ); std::string desc; @@ -636,6 +639,7 @@ void avatar::power_bionics() ctxt.register_action( "QUIT" ); ctxt.register_action( "HELP_KEYBINDINGS" ); ctxt.register_action( "TOGGLE_SAFE_FUEL" ); + ctxt.register_action( "REFUEL" ); ctxt.register_action( "TOGGLE_AUTO_START" ); ctxt.register_action( "SORT" ); @@ -835,6 +839,9 @@ void avatar::power_bionics() popup( _( "You can't toggle fuel saving mode on a non-fueled CBM." ) ); } } + } else if( action == "REFUEL" ) { + avatar_action::eat( get_avatar(), game_menus::inv::consume_fuel( get_avatar() ), true ); + break; } else if( action == "TOGGLE_AUTO_START" ) { auto &bio_list = tab_mode == TAB_ACTIVE ? active : passive; if( !current_bionic_list->empty() ) { diff --git a/src/character.h b/src/character.h index f934faf72571a..cbdbf2528fd44 100644 --- a/src/character.h +++ b/src/character.h @@ -2365,6 +2365,8 @@ class Character : public Creature, public visitable int nutrition_for( const item &comest ) const; /** Can the food be [theoretically] eaten no matter the consequences? */ ret_val can_eat( const item &food ) const; + /** Can the fuel be [theoretically] eaten? */ + ret_val can_consume_fuel( const item &fuel ) const; /** * Same as @ref can_eat, but takes consequences into account. * Asks about them if @param interactive is true, refuses otherwise. diff --git a/src/consumption.cpp b/src/consumption.cpp index 430a46e02fb17..55102d8e10f29 100644 --- a/src/consumption.cpp +++ b/src/consumption.cpp @@ -635,22 +635,8 @@ morale_type Character::allergy_type( const item &food ) const ret_val Character::can_eat( const item &food ) const { - bool can_fuel_cbm = can_fuel_bionic_with( food ); - if( !food.is_comestible() && !can_fuel_cbm ) { + if( !food.is_comestible() ) { return ret_val::make_failure( _( "That doesn't look edible." ) ); - } else if( can_fuel_cbm ) { - std::string item_name = food.tname(); - material_id mat_type = food.get_base_material().id; - if( food.type->magazine ) { - const item ammo = item( food.ammo_current() ); - item_name = ammo.tname(); - mat_type = ammo.get_base_material().id; - } - if( get_fuel_capacity( mat_type ) <= 0 ) { - return ret_val::make_failure( _( "No space to store more %s" ), item_name ); - } else { - return ret_val::make_success(); - } } const auto &comest = food.get_comestible(); @@ -768,6 +754,26 @@ ret_val Character::can_eat( const item &food ) const return ret_val::make_success(); } +ret_val Character::can_consume_fuel( const item &fuel ) const +{ + if( !can_fuel_bionic_with( fuel ) ) { + return ret_val::make_failure( _( "That doesn't look useable as fuel." ) ); + } else { + std::string item_name = fuel.tname(); + material_id mat_type = fuel.get_base_material().id; + if( fuel.type->magazine ) { + const item ammo = item( fuel.ammo_current() ); + item_name = ammo.tname(); + mat_type = ammo.get_base_material().id; + } + if( get_fuel_capacity( mat_type ) <= 0 ) { + return ret_val::make_failure( _( "No space to store more %s" ), item_name ); + } + + } + return ret_val::make_success(); +} + ret_val Character::will_eat( const item &food, bool interactive ) const { const auto ret = can_eat( food ); @@ -778,7 +784,7 @@ ret_val Character::will_eat( const item &food, bool interactive ) return ret; } - // exit early for cbm fuel as we've already tested everything in can_eat + // exit early as we've already tested everything in can_eat if( !food.is_comestible() ) { return ret_val::make_success(); } @@ -1528,7 +1534,7 @@ bool Character::fuel_bionic_with( item &it ) ngettext( " load %1$i charge of %2$s in their %3$s.", " load %1$i charges of %2$s in their %3$s.", loadable ), loadable, mat->name(), bio->name ); - mod_moves( -250 ); + // Return false for magazines because only their ammo is consumed return !is_magazine; } @@ -1730,18 +1736,7 @@ static bool consume_med( item &target, player &you ) return true; } -static bool cbm_is_full( const player &guy, const item &fuel ) -{ - material_id fuel_mat; - if( fuel.is_magazine() ) { - fuel_mat = item( fuel.ammo_current() ).get_base_material().id; - } else { - fuel_mat = fuel.get_base_material().id; - } - return guy.get_fuel_capacity( fuel_mat ) > 0; -} - -trinary player::consume( item &target, bool force ) +trinary player::consume( item &target, bool force, bool refuel ) { if( target.is_null() ) { add_msg_if_player( m_info, _( "You do not have that item." ) ); @@ -1762,10 +1757,13 @@ trinary player::consume( item &target, bool force ) if( is_player() && !query_consume_ownership( target, *this ) ) { return trinary::NONE; } - if( consume_med( target, *this ) || - ( has_max_power() && get_power_level() < get_max_power_level() && - cbm_is_full( *this, target ) && fuel_bionic_with( target ) ) || - eat( target, *this, force ) ) { + + if( refuel ) { + fuel_bionic_with( target ); + return target.charges <= 0 ? trinary::ALL : trinary::SOME; + } + + if( consume_med( target, *this ) || eat( target, *this, force ) ) { get_event_bus().send( getID(), target.typeId() ); @@ -1776,7 +1774,7 @@ trinary player::consume( item &target, bool force ) return trinary::NONE; } -trinary player::consume( item_location loc, bool force ) +trinary player::consume( item_location loc, bool force, bool refuel ) { if( !loc ) { debugmsg( "Null loc to consume." ); @@ -1784,7 +1782,7 @@ trinary player::consume( item_location loc, bool force ) } contents_change_handler handler; item &target = *loc; - trinary result = consume( target, force ); + trinary result = consume( target, force, refuel ); if( result != trinary::NONE ) { handler.unseal_pocket_containing( loc ); } diff --git a/src/game_inventory.cpp b/src/game_inventory.cpp index 87c47ebe5fba9..934ebd1536a35 100644 --- a/src/game_inventory.cpp +++ b/src/game_inventory.cpp @@ -62,6 +62,7 @@ static const activity_id ACT_EAT_MENU( "ACT_EAT_MENU" ); static const activity_id ACT_CONSUME_FOOD_MENU( "ACT_CONSUME_FOOD_MENU" ); static const activity_id ACT_CONSUME_DRINK_MENU( "ACT_CONSUME_DRINK_MENU" ); static const activity_id ACT_CONSUME_MEDS_MENU( "ACT_CONSUME_MEDS_MENU" ); +static const activity_id ACT_CONSUME_FUEL_MENU( "ACT_CONSUME_FUEL_MENU" ); static const quality_id qual_ANESTHESIA( "ANESTHESIA" ); @@ -131,7 +132,8 @@ static item_location inv_internal( Character &u, const inventory_selector_preset ACT_EAT_MENU, ACT_CONSUME_FOOD_MENU, ACT_CONSUME_DRINK_MENU, - ACT_CONSUME_MEDS_MENU }; + ACT_CONSUME_MEDS_MENU, + ACT_CONSUME_FUEL_MENU }; u.inv->restack( u ); @@ -655,26 +657,7 @@ class comestible_inventory_preset : public inventory_selector_preset } return std::string(); }, _( "SPOILS IN" ) ); - append_cell( [&p]( const item_location & loc ) { - std::string cbm_name; - if( p.can_fuel_bionic_with( *loc ) ) { - std::vector bids = p.get_bionic_fueled_with( *loc ); - if( !bids.empty() ) { - bionic_id bid = p.get_most_efficient_bionic( bids ); - cbm_name = bid->name.translated(); - } - } - if( !cbm_name.empty() ) { - return string_format( "%s", cbm_name ); - } - - return std::string(); - }, _( "CBM" ) ); - - append_cell( [&p]( const item_location & loc ) { - return good_bad_none( p.get_acquirable_energy( *loc ) ); - }, _( "ENERGY (kJ)" ) ); } bool is_shown( const item_location &loc ) const override { @@ -791,6 +774,181 @@ class comestible_inventory_preset : public inventory_selector_preset const player &p; }; +class fuel_inventory_preset : public inventory_selector_preset +{ + public: + explicit fuel_inventory_preset( const player &p ) : p( p ) { + + _indent_entries = false; + + append_cell( []( const item_location & loc ) { + const time_duration spoils = loc->is_comestible() ? loc->get_comestible()->spoils : + calendar::INDEFINITELY_LONG_DURATION; + if( spoils > 0_turns ) { + return to_string_clipped( spoils ); + } + //~ Used for permafood shelf life in the Eat menu + return std::string( _( "indefinite" ) ); + }, _( "SHELF LIFE" ) ); + + append_cell( []( const item_location & loc ) { + const item &it = *loc; + + int converted_volume_scale = 0; + const int charges = std::max( it.charges, 1 ); + const double converted_volume = round_up( convert_volume( it.volume().value() / charges, + &converted_volume_scale ), 2 ); + + //~ Eat menu Volume: + return string_format( _( "%.2f%s" ), converted_volume, volume_units_abbr() ); + }, _( "VOLUME" ) ); + + Character &player_character = get_player_character(); + append_cell( [&player_character]( const item_location & loc ) { + time_duration time = player_character.get_consume_time( *loc ); + return string_format( "%s", to_string( time, true ) ); + }, _( "CONSUME TIME" ) ); + + append_cell( [this, &player_character]( const item_location & loc ) { + std::string sealed; + if( loc.has_parent() ) { + item_pocket *pocket = loc.parent_item()->contained_where( *loc.get_item() ); + sealed = pocket->sealed() ? _( "sealed" ) : std::string(); + } + if( player_character.can_estimate_rot() ) { + if( loc->is_comestible() && loc->get_comestible()->spoils > 0_turns ) { + return sealed + ( sealed.empty() ? "" : " " ) + get_freshness( loc ); + } + return std::string( "---" ); + } + return sealed; + }, _( "FRESHNESS" ) ); + + append_cell( [this, &player_character]( const item_location & loc ) { + if( player_character.can_estimate_rot() ) { + if( loc->is_comestible() && loc->get_comestible()->spoils > 0_turns ) { + if( !loc->rotten() ) { + return get_time_left_rounded( loc ); + } + } + return std::string( "---" ); + } + return std::string(); + }, _( "SPOILS IN" ) ); + append_cell( [&p]( const item_location & loc ) { + std::string cbm_name; + + std::vector bids = p.get_bionic_fueled_with( *loc ); + if( !bids.empty() ) { + bionic_id bid = p.get_most_efficient_bionic( bids ); + cbm_name = bid->name.translated(); + } + + if( !cbm_name.empty() ) { + return string_format( "%s", cbm_name ); + } + + return std::string(); + }, _( "CBM" ) ); + + append_cell( [&p]( const item_location & loc ) { + return good_bad_none( p.get_acquirable_energy( *loc ) ); + }, _( "ENERGY (kJ)" ) ); + } + + bool is_shown( const item_location &loc ) const override { + return p.can_fuel_bionic_with( *loc ); + } + + std::string get_denial( const item_location &loc ) const override { + + if( loc->made_of_from_type( phase_id::LIQUID ) && loc.where() != item_location::type::container ) { + return _( "Can't use spilt liquids." ); + } + + if( p.get_fuel_capacity( loc->get_base_material().id ) <= 0 ) { + return ( _( "No space to store more" ) ); + } + + return inventory_selector_preset::get_denial( loc ); + } + + bool sort_compare( const inventory_entry &lhs, const inventory_entry &rhs ) const override { + time_duration time_a = get_time_left( lhs.any_item() ); + time_duration time_b = get_time_left( rhs.any_item() ); + int order_a = get_order( lhs.any_item(), time_a ); + int order_b = get_order( rhs.any_item(), time_b ); + + return order_a < order_b + || ( order_a == order_b && time_a < time_b ) + || ( order_a == order_b && time_a == time_b && + inventory_selector_preset::sort_compare( lhs, rhs ) ); + } + + protected: + int get_order( const item_location &loc, const time_duration &time ) const { + if( loc->rotten() ) { + return 2; + } else if( time == 0_turns ) { + return 2; + } else { + return 1; + } + } + + time_duration get_time_left( const item_location &loc ) const { + time_duration time_left = 0_turns; + const time_duration shelf_life = loc->is_comestible() ? loc->get_comestible()->spoils : + calendar::INDEFINITELY_LONG_DURATION; + if( shelf_life > 0_turns ) { + const item &it = *loc; + const double relative_rot = it.get_relative_rot(); + time_left = shelf_life - shelf_life * relative_rot; + + // Correct for an estimate that exceeds shelf life -- this happens especially with + // fresh items. + if( time_left > shelf_life ) { + time_left = shelf_life; + } + } + + return time_left; + } + + std::string get_time_left_rounded( const item_location &loc ) const { + const item &it = *loc; + if( it.is_going_bad() ) { + return _( "soon!" ); + } + + time_duration time_left = get_time_left( loc ); + return to_string_approx( time_left ); + } + + std::string get_freshness( const item_location &loc ) { + const item &it = *loc; + const double rot_progress = it.get_relative_rot(); + if( it.is_fresh() ) { + return _( "fresh" ); + } else if( rot_progress < 0.3 ) { + return _( "quite fresh" ); + } else if( rot_progress < 0.5 ) { + return _( "near midlife" ); + } else if( rot_progress < 0.7 ) { + return _( "past midlife" ); + } else if( rot_progress < 0.9 ) { + return _( "getting older" ); + } else if( !it.rotten() ) { + return _( "old" ); + } else { + return _( "rotten" ); + } + } + + private: + const player &p; +}; + static std::string get_consume_needs_hint( player &p ) { auto hint = std::string(); @@ -839,6 +997,21 @@ class comestible_filtered_inventory_preset : public comestible_inventory_preset bool( *predicate )( const item &it ); }; +class fuel_filtered_inventory_preset : public fuel_inventory_preset +{ + public: + fuel_filtered_inventory_preset( const player &p, bool( *predicate )( const item &it ) ) : + fuel_inventory_preset( p ), predicate( predicate ) {} + + bool is_shown( const item_location &loc ) const override { + return fuel_inventory_preset::is_shown( loc ) && + predicate( *loc ); + } + + private: + bool( *predicate )( const item &it ); +}; + item_location game_menus::inv::consume_food( player &p ) { Character &player_character = get_player_character(); @@ -889,6 +1062,21 @@ item_location game_menus::inv::consume_meds( player &p ) get_consume_needs_hint( p ) ); } +item_location game_menus::inv::consume_fuel( player &p ) +{ + Character &player_character = get_player_character(); + if( !player_character.has_activity( ACT_CONSUME_FUEL_MENU ) ) { + player_character.assign_activity( ACT_CONSUME_FUEL_MENU ); + } + std::string none_message = player_character.activity.str_values.size() == 2 ? + _( "You have no more fuel to consume." ) : _( "You have no fuel to consume." ); + return inv_internal( p, fuel_filtered_inventory_preset( p, []( const item & it ) { + return it.is_fuel(); + } ), + _( "Consume fuel" ), 1, + none_message ); +} + class activatable_inventory_preset : public pickup_inventory_preset { public: diff --git a/src/game_inventory.h b/src/game_inventory.h index 765150402e419..e8d37cc5305a9 100644 --- a/src/game_inventory.h +++ b/src/game_inventory.h @@ -94,6 +94,8 @@ item_location consume_food( player &p ); item_location consume_drink( player &p ); /** Consuming a medication item via a custom menu. */ item_location consume_meds( player &p ); +/** Consuming fuel item via a custom menu. */ +item_location consume_fuel( player &p ); /** Choosing a container for liquid. */ item_location container_for( Character &you, const item &liquid, int radius = 0, const item *avoid = nullptr ); diff --git a/src/handle_action.cpp b/src/handle_action.cpp index bd65064e72558..f609b34df6f88 100644 --- a/src/handle_action.cpp +++ b/src/handle_action.cpp @@ -1545,6 +1545,7 @@ void game::open_consume_item_menu() as_m.entries.emplace_back( 0, true, 'f', _( "Food" ) ); as_m.entries.emplace_back( 1, true, 'd', _( "Drink" ) ); as_m.entries.emplace_back( 2, true, 'm', _( "Medication" ) ); + as_m.entries.emplace_back( 3, true, 'u', _( "Fuel" ) ); as_m.query(); avatar &player_character = get_avatar(); @@ -1558,6 +1559,9 @@ void game::open_consume_item_menu() case 2: avatar_action::eat( player_character, game_menus::inv::consume_meds( player_character ) ); break; + case 3: + avatar_action::eat( player_character, game_menus::inv::consume_fuel( get_avatar() ), true ); + break; default: break; } diff --git a/src/player.h b/src/player.h index 1fae5446fed47..240cc74650761 100644 --- a/src/player.h +++ b/src/player.h @@ -213,12 +213,12 @@ class player : public Character /** Used for eating object at a location. Removes item if all of it was consumed. * @returns trinary enum NONE, SOME or ALL amount consumed. */ - trinary consume( item_location loc, bool force = false ); + trinary consume( item_location loc, bool force = false, bool refuel = false ); /** Used for eating a particular item that doesn't need to be in inventory. * @returns trinary enum NONE, SOME or ALL (doesn't remove). */ - trinary consume( item &target, bool force = false ); + trinary consume( item &target, bool force = false, bool refuel = false ); int get_lift_assist() const; From 798cc32a6acaeb1c0d58642b86584c05eb87596a Mon Sep 17 00:00:00 2001 From: Eric <52087122+Ramza13@users.noreply.github.com> Date: Fri, 9 Jul 2021 12:42:55 -0400 Subject: [PATCH 106/116] Add unnatural night time sky activity (#48244) * Add new effect_on_conditions * Update data/json/snippets/effect_on_conditions.json Co-authored-by: anothersimulacrum * Update data/json/snippets/effect_on_conditions.json Co-authored-by: anothersimulacrum * Apply suggestions from code review Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Anton Burmistrov * Formatting * Update talker_character.h * Update effect_on_conditions.json * Apply suggestions from code review Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> Co-authored-by: ToxiClay * Update data/json/snippets/effect_on_conditions.json Co-authored-by: ToxiClay * Update data/json/snippets/effect_on_conditions.json Co-authored-by: ToxiClay * Update data/json/snippets/effect_on_conditions.json Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> * Astyle * Update condition.cpp * Update data/json/snippets/effect_on_conditions.json Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> * Update doc/NPCs.md Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> Co-authored-by: anothersimulacrum Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> Co-authored-by: Anton Burmistrov Co-authored-by: ToxiClay Co-authored-by: I-am-Erk <45136638+I-am-Erk@users.noreply.github.com> --- data/json/effect_on_condition.json | 54 ++++++++++++++++++++ data/json/snippets/effect_on_conditions.json | 40 +++++++++++++++ doc/NPCs.md | 1 + src/condition.cpp | 10 ++++ src/condition.h | 1 + src/talker.h | 3 ++ src/talker_character.cpp | 6 +++ src/talker_character.h | 2 +- 8 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 data/json/snippets/effect_on_conditions.json diff --git a/data/json/effect_on_condition.json b/data/json/effect_on_condition.json index 80f455a8611b3..f09601fd3ca28 100644 --- a/data/json/effect_on_condition.json +++ b/data/json/effect_on_condition.json @@ -98,4 +98,58 @@ "id": "EOC_MINOR_SLEEP", "effect": [ { "message": "You feel sleepy…" }, { "u_mod_fatigue": 20 } ] } + { + "type": "effect_on_condition", + "id": "night_messages", + "recurrence_min": "4 hours", + "recurrence_max": "8 hours", + "condition": { + "and": [ + { "one_in_chance": 3 }, + { "not": "is_day" }, + "u_can_see", + { "is_weather": "clear" }, + { "not": { "days_since_cataclysm": 14 } }, + "u_is_outside" + ] + }, + "deactivate_condition": { "days_since_cataclysm": 14 }, + "effect": [ { "message": "NIGHT_MESSAGES_1", "snippet": true } ] + }, + { + "type": "effect_on_condition", + "id": "night_messages2", + "recurrence_min": "4 hours", + "recurrence_max": "8 hours", + "condition": { + "and": [ + { "one_in_chance": 3 }, + { "not": "is_day" }, + "u_can_see", + { "is_weather": "clear" }, + { "days_since_cataclysm": 14 }, + { "not": { "days_since_cataclysm": 50 } }, + "u_is_outside" + ] + }, + "deactivate_condition": { "days_since_cataclysm": 50 }, + "effect": [ { "message": "NIGHT_MESSAGES_2", "snippet": true } ] + }, + { + "type": "effect_on_condition", + "id": "night_messages3", + "recurrence_min": "4 hours", + "recurrence_max": "8 hours", + "condition": { + "and": [ + { "one_in_chance": 3 }, + { "not": "is_day" }, + "u_can_see", + { "is_weather": "clear" }, + { "days_since_cataclysm": 50 }, + "u_is_outside" + ] + }, + "effect": [ { "message": "NIGHT_MESSAGES_3", "snippet": true } ] + } ] diff --git a/data/json/snippets/effect_on_conditions.json b/data/json/snippets/effect_on_conditions.json new file mode 100644 index 0000000000000..81489bbbe0691 --- /dev/null +++ b/data/json/snippets/effect_on_conditions.json @@ -0,0 +1,40 @@ +[ + { + "type": "snippet", + "category": "NIGHT_MESSAGES_1", + "text": [ + "You see what seems to be a new constellation in the sky. The stars are quite dense and are precisely aligned in several regular polyhedrons next to each other.", + "You see what seems to be a new constellation in the sky. The stars are in a precise spiral, with the central star constantly shifting color.", + "You see several shooting stars. They seem larger than normal, and are all a deep purple.", + "You see a shooting star. It is bright red and does not fall in a straight line.", + "For a brief moment you see a shape in the sky roughly the size of the moon, but square and green.", + "For a brief moment, the stars and moon all disappear. When they come back, you're not sure if they're in the same places as they were." + ] + }, + { + "type": "snippet", + "category": "NIGHT_MESSAGES_2", + "text": [ + "You see what seems to be a new constellation in the sky. It changes shape as you look from a triangle to a pentagon.", + "You see what seems to be a new constellation in the sky, in the shape of a hexagon. It's easy to pick out - there are glowing lines between the stars.", + "You see several shooting stars. After they go below the horizon a bright glow briefly appears.", + "You see a shooting star. It is bright red and stops falling after a second to hover there ominously.", + "For a brief moment you see a shape in the sky roughly the size of the moon. It had almost looked like a blinking eye.", + "You see a moving object in the sky with a blinking red light coming from it." + ] + }, + { + "type": "snippet", + "category": "NIGHT_MESSAGES_3", + "text": [ + "You see a once-familiar constellation and watch as several of its stars move.", + "You see what seems to be a new constellation in the sky. It reminds you of a serpent - it moves like one.", + "You see a shooting star. It seems to be heading straight for you before vanishing suddenly.", + "For a brief moment, you see a pentagonal shape in the sky, roughly twice the size of the moon. It splits into several triangles and then reforms before vanishing.", + "As you look at the stars, they wink out for an instant, reappearing just slightly out of place, as if the night sky had been rotated ever so slightly. This occurs twice more, in rapid succession.", + "A strange cloud seems to float in the sky, at the very edge of your peripheral vision. Just as you shift your gaze to it, it evaporates, boiling away into a stream of shooting stars.", + "For a brief moment, you feel like you've been jerked to the side. You haven't moved, though - the stars have.", + "As you look at the stars, a broad swath of them are plunged into darkness, then come back to life in ragged succession." + ] + } +] diff --git a/doc/NPCs.md b/doc/NPCs.md index 0062c4628488a..cd43be2e8c942 100644 --- a/doc/NPCs.md +++ b/doc/NPCs.md @@ -638,6 +638,7 @@ Condition | Type | Description `"u_has_worn_with_flag"`
`"npc_has_worn_with_flag"` | string | `true` if the player character or NPC is wearing something with the `u_has_worn_with_flag` or `npc_has_worn_with_flag` flag. `"u_has_wielded_with_flag"`
`"npc_has_wielded_with_flag"` | string | `true` if the player character or NPC is wielding something with the `u_has_wielded_with_flag` or `npc_has_wielded_with_flag` flag. `"u_has_power"`
`"npc_has_power"` | int | `true` if the player character's or NPC's bionic power is at least the value of `u_has_power` or `npc_has_power`. +`"u_can_see"`
`"npc_can_see"` | simple string | `true` if the player character or NPC is not blind and is either not sleeping or has the see_sleep trait. #### Player Only conditions diff --git a/src/condition.cpp b/src/condition.cpp index e454446372227..2d96ca862cd39 100644 --- a/src/condition.cpp +++ b/src/condition.cpp @@ -929,6 +929,14 @@ void conditional_t::set_has_power( const JsonObject &jo, const std::string &m }; } +template +void conditional_t::set_can_see( bool is_npc ) +{ + condition = [is_npc]( const T & d ) { + return d.actor( is_npc )->can_see(); + }; +} + template conditional_t::conditional_t( const JsonObject &jo ) { @@ -1234,6 +1242,8 @@ conditional_t::conditional_t( const std::string &type ) set_has_reason(); } else if( type == "mission_has_generic_rewards" ) { set_mission_has_generic_rewards(); + } else if( type == "u_can_see" || type == "npc_can_see" ) { + set_can_see( is_npc ); } else { condition = []( const T & ) { return false; diff --git a/src/condition.h b/src/condition.h index 6c72715de9b9c..0751b667f30d2 100644 --- a/src/condition.h +++ b/src/condition.h @@ -154,6 +154,7 @@ struct conditional_t { void set_has_skill( const JsonObject &jo, const std::string &member, bool is_npc = false ); void set_u_know_recipe( const JsonObject &jo, const std::string &member ); void set_mission_has_generic_rewards(); + void set_can_see( bool is_npc = false ); bool operator()( const T &d ) const { if( !condition ) { diff --git a/src/talker.h b/src/talker.h index 0fed5ecbdcc8f..3aac08c43e2c4 100644 --- a/src/talker.h +++ b/src/talker.h @@ -153,6 +153,9 @@ class talker virtual bool is_deaf() const { return false; } + virtual bool can_see() const { + return false; + } virtual bool is_mute() const { return false; } diff --git a/src/talker_character.cpp b/src/talker_character.cpp index f28e950db8da6..d57de16fc17f4 100644 --- a/src/talker_character.cpp +++ b/src/talker_character.cpp @@ -12,6 +12,7 @@ #include "vehicle.h" class time_duration; +static const trait_id trait_SEESLEEP( "SEESLEEP" ); std::string talker_character::disp_name() const { @@ -318,6 +319,11 @@ units::energy talker_character::power_cur() const return me_chr->get_power_level(); } +bool talker_character::can_see() const +{ + return !me_chr->is_blind() && ( !me_chr->in_sleep_state() || me_chr->has_trait( trait_SEESLEEP ) ); +} + void talker_character::mod_fatigue( int amount ) { me_chr->mod_fatigue( amount ); diff --git a/src/talker_character.h b/src/talker_character.h index 520d967fa4a19..a81ccca1c3a6d 100644 --- a/src/talker_character.h +++ b/src/talker_character.h @@ -116,7 +116,7 @@ class talker_character: public talker void mod_fatigue( int amount ) override; void mod_pain( int amount ) override; - + bool can_see() const override; protected: talker_character() = default; player *me_chr; From 9ac7bd0f5e23c64b3abb496c2aa1b6fc831c3641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jianxiang=20Wang=20=28=E7=8E=8B=E5=81=A5=E7=BF=94=29?= Date: Sat, 10 Jul 2021 00:46:37 +0800 Subject: [PATCH 107/116] Show number of monsters in sidebar compass (#49737) --- src/avatar.h | 2 +- src/game.cpp | 54 +++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/avatar.h b/src/avatar.h index 28cc50322767e..0bc9de8946a7b 100644 --- a/src/avatar.h +++ b/src/avatar.h @@ -61,7 +61,7 @@ struct monster_visible_info { // 6 8 2 0-7 are provide by direction_from() // 5 4 3 8 is used for local monsters (for when we explain them below) std::vector unique_types[9]; - std::vector unique_mons[9]; + std::vector> unique_mons[9]; // If the monster visible in this direction is dangerous bool dangerous[8] = {}; diff --git a/src/game.cpp b/src/game.cpp index 34d04379884d2..fe7cd75125a95 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -4280,7 +4280,7 @@ void game::mon_info( const catacurses::window &w, int hor_padding ) } sym = "@"; } else { - const mtype &mt = *unique_mons[i][j - typeshere_npc]; + const mtype &mt = *unique_mons[i][j - typeshere_npc].first; c = mt.color; sym = mt.sym; } @@ -4291,8 +4291,27 @@ void game::mon_info( const catacurses::window &w, int hor_padding ) } // Now we print their full names! - - std::set listed_mons; + struct nearest_loc_and_cnt { + int nearest_loc; + int cnt; + }; + std::map all_mons; + for( int loc = 0; loc < 9; loc++ ) { + for( const std::pair &mon : unique_mons[loc] ) { + const auto mon_it = all_mons.find( mon.first ); + if( mon_it == all_mons.end() ) { + all_mons.emplace( mon.first, nearest_loc_and_cnt{ loc, mon.second } ); + } else { + // 8 being the nearest location (local monsters) + mon_it->second.nearest_loc = std::max( mon_it->second.nearest_loc, loc ); + mon_it->second.cnt += mon.second; + } + } + } + std::vector> mons_at[9]; + for( const std::pair &mon : all_mons ) { + mons_at[mon.second.nearest_loc].emplace_back( mon.first, mon.second.cnt ); + } // Start printing monster names on row 4. Rows 0-2 are for labels, and row 3 // is blank. @@ -4302,19 +4321,22 @@ void game::mon_info( const catacurses::window &w, int hor_padding ) for( int j = 8; j >= 0 && pr.y < maxheight; j-- ) { // Separate names by some number of spaces (more for local monsters). int namesep = ( j == 8 ? 2 : 1 ); - for( const mtype *type : unique_mons[j] ) { + for( const std::pair &mon : mons_at[j] ) { + const mtype *const type = mon.first; + const int count = mon.second; if( pr.y >= maxheight ) { // no space to print to anyway break; } - if( listed_mons.count( type ) > 0 ) { - // this type is already printed. - continue; - } - listed_mons.insert( type ); const mtype &mt = *type; - const std::string name = mt.nname(); + std::string name = mt.nname( count ); + // Some languages don't have plural forms, but we want to always + // omit 1. + if( count != 1 ) { + name = string_format( pgettext( "monster count and name", "%1$d %2$s" ), + count, name ); + } // Move to the next row if necessary. (The +2 is for the "Z "). if( pr.x + 2 + utf8_width( name ) >= width ) { @@ -4474,9 +4496,15 @@ void game::mon_info_update( ) } } - std::vector &vec = unique_mons[index]; - if( std::find( vec.begin(), vec.end(), critter.type ) == vec.end() ) { - vec.push_back( critter.type ); + std::vector> &vec = unique_mons[index]; + const auto mon_it = std::find_if( vec.begin(), vec.end(), + [&]( const std::pair &elem ) { + return elem.first == critter.type; + } ); + if( mon_it == vec.end() ) { + vec.emplace_back( critter.type, 1 ); + } else { + mon_it->second++; } } else if( p != nullptr ) { //Safe mode NPC check From 04caeb43db3c8ceccfe200f4aa2ca90950c24cf6 Mon Sep 17 00:00:00 2001 From: Paul Fenwick Date: Fri, 9 Jul 2021 09:49:17 -0700 Subject: [PATCH 108/116] Reworked brewing, now with merge conflicts resolved (#49512) * Rework brewing for greater realism * brewing.json: Don't create mass out of nothing for fruit wine must. Previously we used 1 juice (125ml) and ended up with 750ml of must. We now use 2 juice (250ml) and 2 water (500ml) for 750ml of must. Co-authored-by: Korhaka --- data/json/items/comestibles/brewing.json | 124 +++++++++++++++-- data/json/recipes/food/brewing.json | 162 +++++++++++++---------- 2 files changed, 204 insertions(+), 82 deletions(-) diff --git a/data/json/items/comestibles/brewing.json b/data/json/items/comestibles/brewing.json index add3d845d3d67..6d46deaaf0f29 100644 --- a/data/json/items/comestibles/brewing.json +++ b/data/json/items/comestibles/brewing.json @@ -18,7 +18,7 @@ "charges": 5, "phase": "liquid", "comestible_type": "DRINK", - "brewable": { "time": "15 hours", "results": [ "wine_mycus", "yeast" ] } + "brewable": { "time": "7 days", "results": [ "wine_mycus", "yeast" ] } }, { "type": "COMESTIBLE", @@ -39,7 +39,7 @@ "charges": 7, "phase": "liquid", "comestible_type": "DRINK", - "brewable": { "time": "12 hours", "results": [ "wash_whiskey", "yeast" ] } + "brewable": { "time": "7 days", "results": [ "wash_whiskey", "yeast" ] } }, { "type": "COMESTIBLE", @@ -86,7 +86,7 @@ "charges": 7, "phase": "liquid", "comestible_type": "DRINK", - "brewable": { "time": "24 hours", "results": [ "gin_mash" ] } + "brewable": { "time": "7 days", "results": [ "gin_mash" ] } }, { "type": "COMESTIBLE", @@ -133,7 +133,7 @@ "phase": "liquid", "comestible_type": "DRINK", "flags": [ "NUTRIENT_OVERRIDE" ], - "brewable": { "time": "6 hours", "results": [ "wash_vodka", "yeast" ] } + "brewable": { "time": "7 days", "results": [ "wash_vodka", "yeast" ] } }, { "type": "COMESTIBLE", @@ -180,7 +180,7 @@ "charges": 7, "phase": "liquid", "comestible_type": "DRINK", - "brewable": { "time": "12 hours", "results": [ "wash_rum", "yeast" ] } + "brewable": { "time": "7 days", "results": [ "wash_rum", "yeast" ] } }, { "type": "COMESTIBLE", @@ -228,7 +228,7 @@ "charges": 7, "phase": "liquid", "comestible_type": "DRINK", - "brewable": { "time": "12 hours", "results": [ "fruit_wine", "yeast" ] } + "brewable": { "time": "7 days", "results": [ "fruit_wine", "yeast" ] } }, { "type": "COMESTIBLE", @@ -251,7 +251,7 @@ "charges": 7, "phase": "liquid", "comestible_type": "DRINK", - "brewable": { "time": "5 days", "results": [ "mead", "yeast" ] } + "brewable": { "time": "14 days", "results": [ "mead", "yeast" ] } }, { "type": "COMESTIBLE", @@ -272,7 +272,7 @@ "phase": "liquid", "comestible_type": "DRINK", "flags": [ "NUTRIENT_OVERRIDE" ], - "brewable": { "time": "1 day 12 hours 40 minutes", "results": [ "dandelion_wine", "yeast" ] } + "brewable": { "time": "7 days", "results": [ "dandelion_wine", "yeast" ] } }, { "type": "COMESTIBLE", @@ -293,7 +293,7 @@ "phase": "liquid", "comestible_type": "DRINK", "flags": [ "NUTRIENT_OVERRIDE" ], - "brewable": { "time": "1 day 12 hours 40 minutes", "results": [ "burdock_wine", "yeast" ] } + "brewable": { "time": "7 days", "results": [ "burdock_wine", "yeast" ] } }, { "type": "COMESTIBLE", @@ -314,7 +314,7 @@ "phase": "liquid", "comestible_type": "DRINK", "flags": [ "NUTRIENT_OVERRIDE" ], - "brewable": { "time": "1 day 16 hours 50 minutes", "results": [ "pine_wine", "yeast" ] } + "brewable": { "time": "7 days", "results": [ "pine_wine", "yeast" ] } }, { "type": "COMESTIBLE", @@ -335,7 +335,7 @@ "price_postapoc": 10, "phase": "liquid", "comestible_type": "DRINK", - "brewable": { "time": "9 hours", "results": [ "hb_beer", "yeast" ] } + "brewable": { "time": "7 days", "results": [ "hb_beer", "yeast" ] } }, { "type": "COMESTIBLE", @@ -357,7 +357,7 @@ "charges": 7, "phase": "liquid", "comestible_type": "DRINK", - "brewable": { "time": "6 hours", "results": [ "wash_moonshine", "yeast" ] } + "brewable": { "time": "5 days", "results": [ "wash_moonshine", "yeast" ] } }, { "type": "COMESTIBLE", @@ -427,7 +427,7 @@ "phase": "liquid", "comestible_type": "DRINK", "flags": [ "NUTRIENT_OVERRIDE" ], - "brewable": { "time": "7 hours", "results": [ "vinegar" ] } + "brewable": { "time": "14 days", "results": [ "vinegar" ] } }, { "type": "COMESTIBLE", @@ -450,5 +450,103 @@ "comestible_type": "DRINK", "flags": [ "NUTRIENT_OVERRIDE" ], "brewable": { "time": "3 days", "results": [ "yeast" ] } + }, + { + "type": "COMESTIBLE", + "id": "malting_grain", + "name": { "str_sp": "malting grain" }, + "weight": "211 g", + "color": "brown", + "comestible_type": "FOOD", + "symbol": ",", + "quench": -10, + "healthy": 1, + "calories": 743, + "description": "Malting grain that can be used for brewing.", + "price": 20, + "price_postapoc": 250, + "material": [ "veggy" ], + "volume": "1 L", + "flags": [ "EDIBLE_FROZEN", "RAW" ], + "vitamins": [ [ "calcium", 6 ], [ "iron", 29 ] ], + "fun": -15, + "use_action": { + "target": "malted_grain", + "msg": "After soaking the grain and waiting, it has finished malting.", + "moves": 50, + "type": "delayed_transform", + "transform_age": 345600, + "not_ready_msg": "The grain has not malted yet." + } + }, + { + "type": "COMESTIBLE", + "id": "malted_grain", + "name": { "str_sp": "malted grain" }, + "weight": "211 g", + "color": "brown", + "spoils_in": "7 days", + "comestible_type": "FOOD", + "symbol": ",", + "quench": -10, + "healthy": 1, + "calories": 743, + "description": "Grainy cereal used for malting. A staple of brewing everywhere. It can also be ground into flour.", + "price": 20, + "price_postapoc": 250, + "material": [ "veggy" ], + "volume": "1 L", + "flags": [ "EDIBLE_FROZEN", "RAW" ], + "vitamins": [ [ "calcium", 6 ], [ "iron", 29 ] ], + "fun": -15 + }, + { + "type": "COMESTIBLE", + "id": "soaking_dandelion", + "name": { "str_sp": "soaking dandelion" }, + "weight": "308 g", + "color": "brown", + "comestible_type": "FOOD", + "symbol": ",", + "quench": -10, + "healthy": 1, + "calories": 26, + "description": "Malting grain that can be used for brewing.", + "price": 20, + "price_postapoc": 250, + "material": [ "veggy" ], + "volume": "250 ml", + "flags": [ "EDIBLE_FROZEN", "RAW" ], + "vitamins": [ [ "calcium", 6 ], [ "iron", 29 ] ], + "fun": -15, + "use_action": { + "target": "soaked_dandelion", + "msg": "After soaking the dandelions in boiling water, the juice can be used for making wine.", + "moves": 50, + "type": "delayed_transform", + "transform_age": 7200, + "not_ready_msg": "The dandelions need more time." + } + }, + { + "type": "COMESTIBLE", + "id": "soaked_dandelion", + "name": { "str_sp": "soaked dandelion" }, + "weight": "308 g", + "color": "yellow", + "spoils_in": "3 days", + "comestible_type": "FOOD", + "symbol": "~", + "quench": 40, + "healthy": 1, + "calories": 26, + "description": "Dandelions soaked in hot water, used for making dandelion wine.", + "price": 20, + "price_postapoc": 250, + "material": [ "veggy" ], + "volume": "250 ml", + "flags": [ "EDIBLE_FROZEN", "RAW" ], + "vitamins": [ [ "vitA", 33 ], [ "vitC", 23 ], [ "calcium", 11 ], [ "iron", 10 ] ], + "fun": -4 } ] diff --git a/data/json/recipes/food/brewing.json b/data/json/recipes/food/brewing.json index 59701f11055fe..89494b0c430d1 100644 --- a/data/json/recipes/food/brewing.json +++ b/data/json/recipes/food/brewing.json @@ -11,7 +11,7 @@ "autolearn": true, "//": "Should be taught by a flag/mutation rather than autolearned", "batch_time_factors": [ 80, 4 ], - "qualities": [ { "id": "COOK", "level": 2 } ], + "qualities": [ { "id": "BOIL", "level": 2 } ], "tools": [ [ [ "surface_heat", 6, "LIST" ] ] ], "components": [ [ [ "water", 3 ], [ "water_clean", 3 ] ], [ [ "mycus_fruit", 1 ] ], [ [ "yeast", 1 ] ] ] }, @@ -33,66 +33,59 @@ }, { "type": "recipe", - "activity_level": "LIGHT_EXERCISE", + "activity_level": "NO_EXERCISE", "result": "brew_whiskey", "result_mult": 3, "category": "CC_FOOD", "subcategory": "CSC_FOOD_BREW", "skill_used": "cooking", "difficulty": 5, - "time": "25 m", - "batch_time_factors": [ 50, 4 ], + "time": "30 m", + "batch_time_factors": [ 95, 4 ], "book_learn": [ [ "distilling_cookbook", 5 ], [ "scots_cookbook", 5 ] ], - "qualities": [ { "id": "COOK", "level": 2 } ], + "qualities": [ { "id": "BOIL", "level": 2 } ], "tools": [ [ [ "surface_heat", 6, "LIST" ] ] ], - "components": [ - [ [ "water", 3 ], [ "water_clean", 3 ] ], - [ [ "corn", 2 ], [ "irradiated_corn", 2 ], [ "cornmeal", 6 ], [ "barley", 1 ], [ "buckwheat", 1 ] ], - [ [ "sugar", 50 ] ], - [ [ "yeast", 1 ] ] - ] + "components": [ [ [ "water", 3 ], [ "water_clean", 3 ] ], [ [ "malted_grain", 2 ] ], [ [ "sugar", 50 ] ], [ [ "yeast", 1 ] ] ] }, { "type": "recipe", - "activity_level": "LIGHT_EXERCISE", + "activity_level": "NO_EXERCISE", "result": "brew_gin", "result_mult": 3, "category": "CC_FOOD", "subcategory": "CSC_FOOD_BREW", "skill_used": "cooking", "difficulty": 3, - "time": 10000, - "batch_time_factors": [ 50, 4 ], + "time": "30 m", + "batch_time_factors": [ 95, 4 ], "book_learn": [ [ "distilling_cookbook", 3 ] ], - "qualities": [ { "id": "COOK", "level": 2 } ], + "qualities": [ { "id": "BOIL", "level": 2 } ], "tools": [ [ [ "surface_heat", 6, "LIST" ] ] ], "components": [ [ [ "water", 2 ], [ "water_clean", 2 ] ], - [ [ "vodka", 4 ], [ "whiskey", 4 ], [ "hb_beer", 4 ] ], + [ [ "corn", 3 ], [ "cornmeal", 3 ], [ "barley", 3 ], [ "buckwheat", 3 ], [ "oats", 3 ] ], [ [ "juniper", 10 ] ] ] }, { "type": "recipe", - "activity_level": "LIGHT_EXERCISE", + "activity_level": "NO_EXERCISE", "result": "brew_vodka", "result_mult": 3, "category": "CC_FOOD", "subcategory": "CSC_FOOD_BREW", "skill_used": "cooking", "difficulty": 5, - "time": "50 m", + "time": "30 m", "batch_time_factors": [ 50, 4 ], "autolearn": [ [ "cooking", 7 ] ], "book_learn": [ [ "distilling_cookbook", 4 ] ], - "qualities": [ { "id": "COOK", "level": 2 } ], + "qualities": [ { "id": "BOIL", "level": 2 } ], "tools": [ [ [ "surface_heat", 6, "LIST" ] ] ], "components": [ [ [ "water", 3 ], [ "water_clean", 3 ] ], [ [ "molasses", 2 ], - [ "corn", 2 ], - [ "cornmeal", 6 ], [ "wheat", 1 ], [ "barley", 1 ], [ "buckwheat", 1 ], @@ -105,44 +98,44 @@ }, { "type": "recipe", - "activity_level": "LIGHT_EXERCISE", + "activity_level": "NO_EXERCISE", "result": "brew_rum", "result_mult": 3, "category": "CC_FOOD", "subcategory": "CSC_FOOD_BREW", "skill_used": "cooking", "difficulty": 5, - "time": "15 m", - "batch_time_factors": [ 50, 4 ], + "time": "30 m", + "batch_time_factors": [ 95, 4 ], "book_learn": [ [ "distilling_cookbook", 4 ] ], - "qualities": [ { "id": "COOK", "level": 2 } ], + "qualities": [ { "id": "BOIL", "level": 2 } ], "tools": [ [ [ "surface_heat", 6, "LIST" ] ] ], "components": [ [ [ "water", 3 ], [ "water_clean", 3 ] ], [ [ "molasses", 2 ], [ "sugar_beet", 1 ] ], [ [ "yeast", 1 ] ] ] }, { "type": "recipe", - "activity_level": "LIGHT_EXERCISE", + "activity_level": "NO_EXERCISE", "result": "brew_moonshine", "result_mult": 15, "category": "CC_FOOD", "subcategory": "CSC_FOOD_BREW", "skill_used": "cooking", "difficulty": 2, - "time": "40 m", - "batch_time_factors": [ 50, 4 ], + "time": "30 m", + "batch_time_factors": [ 95, 4 ], "book_learn": [ [ "brewing_cookbook", 1 ], [ "family_cookbook", 1 ] ], - "qualities": [ { "id": "COOK", "level": 2 } ], + "qualities": [ { "id": "BOIL", "level": 2 } ], "tools": [ [ [ "surface_heat", 30, "LIST" ] ] ], "components": [ [ [ "water", 15 ], [ "water_clean", 15 ] ], - [ [ "cornmeal", 12 ], [ "buckwheat", 2 ] ], + [ [ "cornmeal", 12 ], [ "corn", 2 ] ], [ [ "sugar", 100 ] ], [ [ "yeast", 2 ] ] ] }, { "type": "recipe", - "activity_level": "LIGHT_EXERCISE", + "activity_level": "NO_EXERCISE", "result": "brew_moonshine", "id_suffix": "pumpkin", "result_mult": 15, @@ -151,79 +144,74 @@ "subcategory": "CSC_FOOD_BREW", "skill_used": "cooking", "difficulty": 2, - "time": "40 m", - "batch_time_factors": [ 50, 4 ], + "time": "30 m", + "batch_time_factors": [ 95, 4 ], "book_learn": [ [ "distilling_cookbook", 1 ], [ "family_cookbook", 1 ] ], - "qualities": [ { "id": "COOK", "level": 2 } ], + "qualities": [ { "id": "BOIL", "level": 2 } ], "tools": [ [ [ "surface_heat", 30, "LIST" ] ] ], "components": [ [ [ "water", 15 ], [ "water_clean", 15 ] ], [ [ "pumpkin", 12 ] ], [ [ "sugar", 50 ] ], [ [ "yeast", 2 ] ] ] }, { "type": "recipe", - "activity_level": "LIGHT_EXERCISE", + "activity_level": "NO_EXERCISE", "result": "brew_fruit_wine", "result_mult": 3, "category": "CC_FOOD", "subcategory": "CSC_FOOD_BREW", "skill_used": "cooking", "difficulty": 3, - "time": "40 m", - "batch_time_factors": [ 50, 4 ], + "time": "30 s", + "batch_time_factors": [ 95, 4 ], "book_learn": [ [ "brewing_cookbook", 2 ], [ "winemaking_beginner", 2 ] ], - "qualities": [ { "id": "COOK", "level": 2 } ], - "tools": [ [ [ "surface_heat", 6, "LIST" ] ] ], - "components": [ [ [ "water", 3 ], [ "water_clean", 3 ] ], [ [ "sweet_fruit", 2, "LIST" ], [ "juice", 1 ] ], [ [ "yeast", 1 ] ] ] + "qualities": [ { "id": "CONTAIN", "level": 1 } ], + "components": [ [ [ "juice", 2 ] ], [ [ "yeast", 1 ] ], [ [ "water", 2 ], [ "water_clean", 2 ] ] ] }, { "type": "recipe", - "activity_level": "LIGHT_EXERCISE", + "activity_level": "NO_EXERCISE", "result": "brew_hb_beer", - "result_mult": 15, + "result_mult": 10, "category": "CC_FOOD", "subcategory": "CSC_FOOD_BREW", "skill_used": "cooking", "difficulty": 4, - "time": "80 m", - "batch_time_factors": [ 50, 4 ], + "time": "60 m", + "batch_time_factors": [ 95, 4 ], "book_learn": [ [ "brewing_cookbook", 4 ] ], - "qualities": [ { "id": "COOK", "level": 2 } ], + "qualities": [ { "id": "BOIL", "level": 2 } ], "tools": [ [ [ "surface_heat", 6, "LIST" ] ] ], - "components": [ - [ [ "water", 15 ], [ "water_clean", 15 ] ], - [ [ "barley", 3 ], [ "buckwheat", 3 ], [ "oats", 3 ] ], - [ [ "hops", 1 ] ], - [ [ "yeast", 1 ] ] - ] + "components": [ [ [ "water", 10 ], [ "water_clean", 10 ] ], [ [ "malted_grain", 2 ] ], [ [ "hops", 1 ] ], [ [ "yeast", 1 ] ] ] }, { "type": "recipe", - "activity_level": "LIGHT_EXERCISE", + "activity_level": "NO_EXERCISE", "result": "brew_mead", "result_mult": 3, "category": "CC_FOOD", "subcategory": "CSC_FOOD_BREW", "skill_used": "cooking", "difficulty": 3, - "time": "80 m", - "batch_time_factors": [ 50, 4 ], + "time": "2 m", + "batch_time_factors": [ 95, 4 ], "book_learn": [ [ "brewing_cookbook", 2 ], [ "winemaking_beginner", 2 ] ], + "qualities": [ { "id": "CONTAIN", "level": 1 } ], "components": [ - [ [ "water", 3 ], [ "water_clean", 3 ] ], + [ [ "water_clean", 3 ] ], [ [ "honey_bottled", 10 ], [ "honeycomb", 2 ], [ "honey_glassed", 10 ] ], [ [ "yeast", 1 ] ] ] }, { "type": "recipe", - "activity_level": "LIGHT_EXERCISE", + "activity_level": "NO_EXERCISE", "result": "brew_dandelion_wine", "result_mult": 3, "category": "CC_FOOD", "subcategory": "CSC_FOOD_BREW", "skill_used": "cooking", "difficulty": 3, - "time": "80 m", - "batch_time_factors": [ 50, 4 ], + "time": "30 s", + "batch_time_factors": [ 95, 4 ], "book_learn": [ [ "brewing_cookbook", 3 ], [ "family_cookbook", 2 ], @@ -231,25 +219,25 @@ [ "textbook_survival", 3 ], [ "manual_survival", 3 ] ], - "qualities": [ { "id": "CUT", "level": 1 }, { "id": "COOK", "level": 2 } ], + "qualities": [ { "id": "CONTAIN", "level": 1 } ], "components": [ - [ [ "water", 3 ], [ "water_clean", 3 ] ], - [ [ "raw_dandelion", 10 ] ], + [ [ "water_clean", 3 ] ], + [ [ "soaked_dandelion", 10 ] ], [ [ "sugar", 10 ], [ "honeycomb", 1 ], [ "honey_bottled", 2 ], [ "honey_glassed", 2 ], [ "syrup", 2 ] ], [ [ "yeast", 1 ] ] ] }, { "type": "recipe", - "activity_level": "LIGHT_EXERCISE", + "activity_level": "NO_EXERCISE", "result": "brew_burdock_wine", "result_mult": 3, "category": "CC_FOOD", "subcategory": "CSC_FOOD_BREW", "skill_used": "cooking", "difficulty": 3, - "time": "80 m", - "batch_time_factors": [ 50, 4 ], + "time": "30 m", + "batch_time_factors": [ 95, 4 ], "book_learn": [ [ "brewing_cookbook", 3 ], [ "family_cookbook", 2 ], @@ -257,7 +245,8 @@ [ "textbook_survival", 3 ], [ "manual_survival", 3 ] ], - "qualities": [ { "id": "CUT", "level": 1 }, { "id": "COOK", "level": 2 } ], + "qualities": [ { "id": "CUT", "level": 1 }, { "id": "BOIL", "level": 2 } ], + "tools": [ [ [ "surface_heat", 6, "LIST" ] ] ], "components": [ [ [ "water", 3 ], [ "water_clean", 3 ] ], [ [ "raw_burdock", 10 ] ], @@ -267,17 +256,18 @@ }, { "type": "recipe", - "activity_level": "LIGHT_EXERCISE", + "activity_level": "NO_EXERCISE", "result": "brew_pine_wine", "result_mult": 3, "category": "CC_FOOD", "subcategory": "CSC_FOOD_BREW", "skill_used": "cooking", "difficulty": 3, - "time": "80 m", - "batch_time_factors": [ 50, 4 ], + "time": "30 m", + "batch_time_factors": [ 95, 4 ], "book_learn": [ [ "survival_book", 3 ], [ "textbook_survival", 3 ], [ "manual_survival", 3 ] ], - "qualities": [ { "id": "CUT", "level": 1 }, { "id": "COOK", "level": 2 } ], + "qualities": [ { "id": "CUT", "level": 1 }, { "id": "BOIL", "level": 2 } ], + "tools": [ [ [ "surface_heat", 6, "LIST" ] ] ], "components": [ [ [ "water", 3 ], [ "water_clean", 3 ] ], [ [ "pine_bough", 5 ] ], @@ -288,6 +278,40 @@ { "type": "recipe", "activity_level": "NO_EXERCISE", + "result": "malting_grain", + "result_mult": 1, + "category": "CC_FOOD", + "subcategory": "CSC_FOOD_BREW", + "skill_used": "cooking", + "difficulty": 3, + "time": "30 s", + "batch_time_factors": [ 95, 4 ], + "book_learn": [ [ "brewing_cookbook", 4 ] ], + "qualities": [ { "id": "CONTAIN", "level": 1 } ], + "components": [ + [ [ "water", 1 ], [ "water_clean", 1 ] ], + [ [ "corn", 1 ], [ "barley", 1 ], [ "buckwheat", 1 ], [ "oats", 1 ], [ "wheat", 1 ] ] + ] + }, + { + "type": "recipe", + "activity_level": "NO_EXERCISE", + "result": "soaking_dandelion", + "result_mult": 1, + "category": "CC_FOOD", + "subcategory": "CSC_FOOD_BREW", + "skill_used": "cooking", + "difficulty": 3, + "time": "30 m", + "batch_time_factors": [ 95, 4 ], + "book_learn": [ [ "brewing_cookbook", 4 ] ], + "qualities": [ { "id": "BOIL", "level": 2 } ], + "tools": [ [ [ "surface_heat", 6, "LIST" ] ] ], + "components": [ [ [ "water", 1 ], [ "water_clean", 1 ] ], [ [ "raw_dandelion", 1 ] ] ] + }, + { + "type": "recipe", + "activity_level": "LIGHT_EXERCISE", "result": "brew_vinegar", "result_mult": 10, "category": "CC_FOOD", From 17f24ad9bcb65841998b636c5d535c2587491c66 Mon Sep 17 00:00:00 2001 From: LohTek Date: Fri, 9 Jul 2021 11:50:58 -0500 Subject: [PATCH 109/116] Add makeshift blindfold made from natural materials (#48886) * Add makeshift blindfold made from natural materials # If commit applied It will provide a way for survivors lost in the woods a means of making a blindfold to sleep when it is still bright outside. # Why change was made Players who wish to play wilderness scenario currently have extreme difficulty making a blindfold. # How this fixes issue Provides a means of making a blindfold from natural materials easily found in the forest. # References #48846 Add a cordage blindfold * Forgot to lint JSON Made changes to correct linting * Text editor causing linting issues This is my first submission so I have to get my tools in line with requirements apologies. * Revert "Forgot to lint JSON" This reverts commit 4f807cb611054b3efdfddf221e6bce09cc802436. * Revert "Revert "Forgot to lint JSON"" This reverts commit c40c047a040a81cffd130109c348273659b54a05. * Changes to fix space in id Fixed ID as requested. * Update head.json * Update data/json/items/tool_armor.json Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> * Update data/json/recipes/armor/head.json Co-authored-by: I-am-Erk <45136638+I-am-Erk@users.noreply.github.com> Co-authored-by: Maleclypse <54345792+Maleclypse@users.noreply.github.com> Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> --- data/json/items/tool_armor.json | 21 +++++++++++++++++++++ data/json/recipes/armor/head.json | 15 +++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/data/json/items/tool_armor.json b/data/json/items/tool_armor.json index ea3e9cd9d9f2e..d83343f5bbd6a 100644 --- a/data/json/items/tool_armor.json +++ b/data/json/items/tool_armor.json @@ -86,6 +86,27 @@ "use_action": { "target": "tourniquet_upper", "msg": "You adjust the tourniquet.", "menu_text": "Adjust", "type": "transform" }, "flags": [ "WATER_FRIENDLY", "OUTER", "TOURNIQUET", "OVERSIZE" ] }, + { + "id": "makeshift_blindfold", + "type": "ARMOR", + "name": { "str": "makeshift blindfold" }, + "description": "A crude eye covering woven from blades of grass with string attached to fasten it. Useful for sleeping in bright areas.", + "weight": "32 g", + "volume": "200 ml", + "price": 5, + "price_postapoc": 1, + "material": [ "dry_plant" ], + "symbol": "[", + "looks_like": "scarf", + "color": "yellow", + "covers": [ "eyes" ], + "coverage": 95, + "encumbrance": 10, + "warmth": 0, + "material_thickness": 0.1, + "environmental_protection": 0, + "flags": [ "BLIND" ] + }, { "id": "blindfold", "type": "ARMOR", diff --git a/data/json/recipes/armor/head.json b/data/json/recipes/armor/head.json index 873b72beb7f40..49c3d4605078b 100644 --- a/data/json/recipes/armor/head.json +++ b/data/json/recipes/armor/head.json @@ -41,6 +41,21 @@ "using": [ [ "sewing_standard", 20 ] ], "components": [ [ [ "felt_patch", 4 ] ] ] }, + { + "result": "makeshift_blindfold", + "type": "recipe", + "activity_level": "LIGHT_EXERCISE", + "category": "CC_ARMOR", + "subcategory": "CSC_ARMOR_HEAD", + "skill_used": "survival", + "difficulty": 2, + "skills_required": [ [ "tailor", 1 ] ], + "time": "20 m", + "autolearn": true, + "reversible": true, + "components": [ [ [ "withered", 10 ] ], [ [ "string_6", 2 ], [ "cordage_6", 2 ] ] ], + "proficiencies": [ { "proficiency": "prof_basketweaving" } ] + }, { "result": "blindfold_duct", "type": "recipe", From 9f628f6f00be4da305f4ca608522ab1b28b5fbdc Mon Sep 17 00:00:00 2001 From: Eric <52087122+Ramza13@users.noreply.github.com> Date: Fri, 9 Jul 2021 12:53:21 -0400 Subject: [PATCH 110/116] Unhardcode bio_leukocycte, add several enchantments (#47659) * Unhardcode bio_leukocycte * Update enchantments.json * Update bionics.json * Update character.cpp * Clean up * Update character.cpp --- data/json/bionics.json | 12 +++++++++++- doc/MAGIC.md | 3 +++ src/character.cpp | 15 ++++++++------- src/handle_action.cpp | 1 - src/magic_enchantment.cpp | 3 +++ src/magic_enchantment.h | 3 +++ 6 files changed, 28 insertions(+), 9 deletions(-) diff --git a/data/json/bionics.json b/data/json/bionics.json index 4270620db2928..3e6830ee543cf 100644 --- a/data/json/bionics.json +++ b/data/json/bionics.json @@ -950,7 +950,17 @@ "flags": [ "BIONIC_TOGGLED", "BIONIC_SLEEP_FRIENDLY", "BIONIC_NPC_USABLE" ], "act_cost": "5 J", "react_cost": "5 J", - "time": 1 + "time": 1, + "enchantments": [ + { + "condition": "ACTIVE", + "values": [ + { "value": "EFFECTIVE_HEALTH_MOD", "add": 100 }, + { "value": "MOD_HEALTH", "add": -50 }, + { "value": "MOD_HEALTH_CAP", "add": -200 } + ] + } + ] }, { "id": "bio_lighter", diff --git a/doc/MAGIC.md b/doc/MAGIC.md index afc578c1f1395..31aaf4875c980 100644 --- a/doc/MAGIC.md +++ b/doc/MAGIC.md @@ -497,6 +497,9 @@ Effects for the character that has the enchantment: * SOCIAL_INTIMIDATE * SLEEPY : The higher this is the more easily you fall asleep. * LUMINATION : The character produces light +* EFFECTIVE_HEALTH_MOD : If this is anything other than zero(which it defaults to) you will use it instead of your actual health mod +* MOD_HEALTH : If this is anything other than zero(which it defaults to) you will to mod your health to a max/min of MOD_HEALTH_CAP every half hour +* MOD_HEALTH_CAP : If this is anything other than zero(which it defaults to) you will cap your MOD_HEALTH gain/loss at this every half hour * ARMOR_BASH * ARMOR_CUT * ARMOR_STAB diff --git a/src/character.cpp b/src/character.cpp index d6061bf4fd2c1..93f5a8d56f8d3 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -277,7 +277,6 @@ static const bionic_id bio_voice( "bio_voice" ); static const bionic_id bio_gills( "bio_gills" ); static const bionic_id bio_ground_sonar( "bio_ground_sonar" ); static const bionic_id bio_hydraulics( "bio_hydraulics" ); -static const bionic_id bio_leukocyte( "bio_leukocyte" ); static const bionic_id bio_memory( "bio_memory" ); static const bionic_id bio_railgun( "bio_railgun" ); static const bionic_id bio_shock_absorber( "bio_shock_absorber" ); @@ -5542,12 +5541,14 @@ void Character::update_health( int external_modifiers ) } // Active leukocyte breeder will keep your health near 100 - int effective_healthy_mod = get_healthy_mod(); - if( has_active_bionic( bio_leukocyte ) ) { - // Side effect: dependency - mod_healthy_mod( -50, -200 ); - effective_healthy_mod = 100; - } + int effective_healthy_mod = enchantment_cache->modify_value( + enchant_vals::mod::EFFECTIVE_HEALTH_MOD, 0 ); + if( effective_healthy_mod == 0 ) { + effective_healthy_mod = get_healthy_mod(); + } + int healthy_mod = enchantment_cache->modify_value( enchant_vals::mod::MOD_HEALTH, 0 ); + int healthy_mod_cap = enchantment_cache->modify_value( enchant_vals::mod::MOD_HEALTH_CAP, 0 ); + mod_healthy_mod( healthy_mod, healthy_mod_cap ); // Health tends toward healthy_mod. // For small differences, it changes 4 points per day diff --git a/src/handle_action.cpp b/src/handle_action.cpp index f609b34df6f88..91c7d1f8f2e8d 100644 --- a/src/handle_action.cpp +++ b/src/handle_action.cpp @@ -1034,7 +1034,6 @@ static void sleep() // some bionics // bio_alarm is useful for waking up during sleeping - // turning off bio_leukocyte has 'unpleasant side effects' if( bio.info().has_flag( STATIC( json_character_flag( "BIONIC_SLEEP_FRIENDLY" ) ) ) ) { continue; } diff --git a/src/magic_enchantment.cpp b/src/magic_enchantment.cpp index d1816afa5b14d..a78c3b4b56ce6 100644 --- a/src/magic_enchantment.cpp +++ b/src/magic_enchantment.cpp @@ -86,6 +86,9 @@ namespace io case enchant_vals::mod::SOCIAL_INTIMIDATE: return "SOCIAL_INTIMIDATE"; case enchant_vals::mod::SLEEPY: return "SLEEPY"; case enchant_vals::mod::LUMINATION: return "LUMINATION"; + case enchant_vals::mod::EFFECTIVE_HEALTH_MOD: return "EFFECTIVE_HEALTH_MOD"; + case enchant_vals::mod::MOD_HEALTH: return "MOD_HEALTH"; + case enchant_vals::mod::MOD_HEALTH_CAP: return "MOD_HEALTH_CAP"; case enchant_vals::mod::ARMOR_ACID: return "ARMOR_ACID"; case enchant_vals::mod::ARMOR_BASH: return "ARMOR_BASH"; case enchant_vals::mod::ARMOR_BIO: return "ARMOR_BIO"; diff --git a/src/magic_enchantment.h b/src/magic_enchantment.h index 8c02d88d963c2..e96e432bb2b9e 100644 --- a/src/magic_enchantment.h +++ b/src/magic_enchantment.h @@ -61,6 +61,9 @@ enum class mod : int { SOCIAL_INTIMIDATE, SLEEPY, LUMINATION, + EFFECTIVE_HEALTH_MOD, + MOD_HEALTH, + MOD_HEALTH_CAP, ARMOR_BASH, ARMOR_CUT, ARMOR_STAB, From 7ede327951096456b58ab3739d0cdb87007ef853 Mon Sep 17 00:00:00 2001 From: Venera3 <72006894+Venera3@users.noreply.github.com> Date: Fri, 9 Jul 2021 19:12:23 +0200 Subject: [PATCH 111/116] [CR] Add CAMOUFLAGE monster flag (#48340) * First * Revert "First" This reverts commit be374044f4069eb553fdc49b7015857d33e29107. * Revert "Revert "First"" This reverts commit f904c037af353ec55b5f4f40108789ab53c63927. * Works! * Astyle * Doc * () * Apply suggestions from code review Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> * Hit msg * Mob 1st Don't look at it too hard, just moving PCs * Monster second pass * Lint Mostly just to get the tests to look at the important bits * Hit messages 2 Hopefully that got all that matter, the hardcoded special attacks will stay a bit weird * Update nether.json * Hunter 2 Mostly fine, ranged todo * Monstergroups Subway's pretty barebones, but that's a followup PR * Final * Update misc.json * Update misc.json Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com> --- data/json/effects.json | 19 +++++++ .../monster_attacks.json | 16 ++++++ data/json/monstergroups/misc.json | 7 +++ data/json/monstergroups/nether.json | 3 ++ data/json/monsters/nether.json | 54 +++++++++++++++++++ .../overmap_terrain_transportation.json | 1 + doc/JSON_FLAGS.md | 1 + src/character.cpp | 8 +++ src/character.h | 1 + src/creature.cpp | 9 ++++ src/creature.h | 1 + src/monster.cpp | 42 ++++++++++----- src/monster.h | 1 + src/monstergenerator.cpp | 1 + src/mtype.h | 1 + 15 files changed, 151 insertions(+), 14 deletions(-) diff --git a/data/json/effects.json b/data/json/effects.json index 621073d32e779..aa31d93272882 100644 --- a/data/json/effects.json +++ b/data/json/effects.json @@ -588,6 +588,25 @@ "speed_mod": [ -0.31, -0.21 ] } }, + { + "type": "effect_type", + "id": "venom_blind", + "name": [ "Distracted", "Inattentive", "Dissociated" ], + "desc": [ + "You find it hard to concentrate on your surroundings properly.", + "You're not even listening, are you?", + "Everything will be fine. Just ignore all you see, and everything will be fine." + ], + "apply_message": "Your vision grows blurry.", + "miss_messages": [ [ "It was right here, wasn't it?", 2 ], [ "Are you sure there's something there?", 1 ] ], + "max_intensity": 3, + "int_add_val": 1, + "int_decay_step": -1, + "int_decay_tick": 90, + "resist_traits": [ "ELFA_NV" ], + "base_mods": { "per_mod": [ -3, 0 ] }, + "scaling_mods": { "per_mod": [ -2, -1 ] } + }, { "type": "effect_type", "id": "foodpoison", diff --git a/data/json/monster_special_attacks/monster_attacks.json b/data/json/monster_special_attacks/monster_attacks.json index 35642d9c083ea..eaf9fff02e731 100644 --- a/data/json/monster_special_attacks/monster_attacks.json +++ b/data/json/monster_special_attacks/monster_attacks.json @@ -15,6 +15,22 @@ "dodgeable": true, "blockable": true }, + { + "type": "monster_attack", + "attack_type": "melee", + "id": "hunter_peck", + "cooldown": 15, + "move_cost": 100, + "damage_max_instance": [ { "damage_type": "stab", "amount": 12, "armor_penetration": 30 } ], + "body_parts": [ [ "head", 1 ], [ "torso", 2 ], [ "leg_r", 1 ], [ "leg_l", 1 ], [ "arm_r", 1 ], [ "arm_l", 1 ] ], + "effects": [ { "id": "venom_blind", "duration": 120 } ], + "hit_dmg_u": "The %1$s buries its beak in your %2$s!", + "hit_dmg_npc": "The %1$s buries its beak in 's %2$s!", + "miss_msg_u": "The %1$s tries to peck you, but you dodge!", + "miss_msg_npc": "The %1$s tries to peck , but they dodge!", + "no_dmg_msg_u": "The %1$s tries to peck your %2$s, but fails to penetrate your armor!", + "no_dmg_msg_npc": "The %1$s tries to peck 's %2$s, but fails to penetrate their armor!" + }, { "type": "monster_attack", "attack_type": "melee", diff --git a/data/json/monstergroups/misc.json b/data/json/monstergroups/misc.json index da1d1e6008307..8278a649d685e 100644 --- a/data/json/monstergroups/misc.json +++ b/data/json/monstergroups/misc.json @@ -53,6 +53,13 @@ { "monster": "mon_crawler", "freq": 35, "cost_multiplier": 0 } ] }, + { + "type": "monstergroup", + "name": "GROUP_SUBWAY", + "//": "Work very much in progress", + "default": "mon_null", + "monsters": [ { "monster": "mon_unseen_hunter", "freq": 100, "cost_multiplier": 1, "starts": 168 } ] + }, { "type": "monstergroup", "name": "GROUP_DOMESTIC", diff --git a/data/json/monstergroups/nether.json b/data/json/monstergroups/nether.json index c89fc03953a4a..c1d1050423eb3 100644 --- a/data/json/monstergroups/nether.json +++ b/data/json/monstergroups/nether.json @@ -35,6 +35,7 @@ { "monster": "mon_flying_polyp", "freq": 100, "cost_multiplier": 0 }, { "monster": "mon_hunting_horror", "freq": 100, "cost_multiplier": 0 }, { "monster": "mon_mi_go", "freq": 100, "cost_multiplier": 0 }, + { "monster": "mon_unseen_hunter", "freq": 100, "cost_multiplier": 1, "starts": 180 }, { "monster": "mon_mi_go_scout", "freq": 100, "cost_multiplier": 0, "starts": 360 }, { "monster": "mon_yugg", "freq": 100, "cost_multiplier": 0 }, { "monster": "mon_gelatin", "freq": 100, "cost_multiplier": 0 }, @@ -51,6 +52,7 @@ "monsters": [ { "monster": "mon_flying_polyp", "freq": 25, "cost_multiplier": 0 }, { "monster": "mon_hunting_horror", "freq": 240, "cost_multiplier": 0 }, + { "monster": "mon_unseen_hunter", "freq": 50, "cost_multiplier": 0, "starts": 720 }, { "monster": "mon_yugg", "freq": 70, "cost_multiplier": 0 }, { "monster": "mon_gelatin", "freq": 120, "cost_multiplier": 0 }, { "monster": "mon_flaming_eye", "freq": 120, "cost_multiplier": 0 }, @@ -80,6 +82,7 @@ { "monster": "mon_flaming_eye", "freq": 200, "cost_multiplier": 0 }, { "monster": "mon_kreck", "freq": 200, "cost_multiplier": 0 }, { "monster": "mon_gracke", "freq": 200, "cost_multiplier": 0 }, + { "monster": "mon_unseen_hunter", "freq": 100, "cost_multiplier": 0, "starts": 720 }, { "monster": "mon_blank", "freq": 200, "cost_multiplier": 0 } ] }, diff --git a/data/json/monsters/nether.json b/data/json/monsters/nether.json index 8071ff1307a89..602f392862d0d 100644 --- a/data/json/monsters/nether.json +++ b/data/json/monsters/nether.json @@ -313,6 +313,60 @@ "NOGIB" ] }, + { + "id": "mon_unseen_hunter", + "type": "MONSTER", + "name": { "str": "unseen hunter" }, + "description": "There was nothing here a moment ago, but now you see the faintest outline of an otherworldly creature approaching you with jittery leaps. Trying to focus on it reveals a pointed beak dripping translucent fluid and rows upon rows of bladed legs grasping the floor, before your eyes begin to burn and your head starts to spin.", + "symbol": " ", + "color": "light_blue", + "default_faction": "nether", + "bodytype": "insect", + "diff": 15, + "volume": "50 L", + "weight": "80 kg", + "hp": 150, + "speed": 100, + "aggression": 30, + "morale": 25, + "regen_morale": true, + "regenerates_in_dark": true, + "melee_skill": 10, + "melee_dice": 4, + "melee_dice_sides": 3, + "melee_damage": [ { "damage_type": "cut", "amount": 5, "armor_penetration": 10 } ], + "dodge": 8, + "vision_day": 20, + "vision_night": 20, + "path_settings": { "allow_open_doors": true, "avoid_traps": true, "avoid_sharp": true }, + "special_attacks": [ + [ "RANGED_PULL", 8 ], + { "type": "leap", "cooldown": 20, "max_range": 6, "allow_no_target": true }, + { "id": "hunter_peck" } + ], + "armor_bash": 5, + "armor_cut": 5, + "armor_stab": 5, + "armor_bullet": 30, + "//": "Reduce bullet armor when things are harder to hit or players miss more", + "anger_triggers": [ "FIRE" ], + "fear_triggers": [ "HURT" ], + "death_function": [ "MELT" ], + "flags": [ + "SEES", + "HEARS", + "GOODHEARING", + "SMELLS", + "DESTROYS", + "WARM", + "CAMOUFLAGE", + "FIREPROOF", + "NIGHT_INVISIBILITY", + "PATH_AVOID_DANGER_1", + "HARDTOSHOOT", + "HIT_AND_RUN" + ] + }, { "id": "mon_gozu", "type": "MONSTER", diff --git a/data/json/overmap/overmap_terrain/overmap_terrain_transportation.json b/data/json/overmap/overmap_terrain/overmap_terrain_transportation.json index 25a58e55cb521..7b0c6a2a99ce2 100644 --- a/data/json/overmap/overmap_terrain/overmap_terrain_transportation.json +++ b/data/json/overmap/overmap_terrain/overmap_terrain_transportation.json @@ -295,6 +295,7 @@ "mapgen_end": [ { "method": "builtin", "name": "subway_end" } ], "mapgen_tee": [ { "method": "builtin", "name": "subway_tee" } ], "mapgen_four_way": [ { "method": "builtin", "name": "subway_four_way" } ], + "spawns": { "group": "GROUP_SUBWAY", "population": [ 1, 2 ], "chance": 50 }, "flags": [ "LINEAR" ] }, { diff --git a/doc/JSON_FLAGS.md b/doc/JSON_FLAGS.md index cb2dbffed4c55..185596d34c406 100644 --- a/doc/JSON_FLAGS.md +++ b/doc/JSON_FLAGS.md @@ -892,6 +892,7 @@ Other monster flags. - ```BORES``` Tunnels through just about anything (15x bash multiplier: dark wyrms' bash skill 12->180) - ```CAN_DIG``` Can dig _and_ walk. - ```CAN_OPEN_DOORS``` Can open doors on its path. +- ```CAMOUFLAGE``` Stays invisible up to (current Perception, + base Perception if the character has the Spotting proficiency) tiles away, even in broad daylight. Monsters see it from the lower of `vision_day` and `vision_night` ranges. - ```CANPLAY``` This creature can be played with if it's a pet. - ```CATFOOD``` Becomes friendly / tamed with cat food. - ```CATTLEFODDER``` Becomes friendly / tamed with cattle fodder. diff --git a/src/character.cpp b/src/character.cpp index 93f5a8d56f8d3..2a3d3ec4456cd 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -237,6 +237,8 @@ static const skill_id skill_smg( "smg" ); static const skill_id skill_swimming( "swimming" ); static const skill_id skill_throw( "throw" ); +static const proficiency_id proficiency_prof_spotting( "prof_spotting" ); + static const species_id species_HUMAN( "HUMAN" ); static const species_id species_ROBOT( "ROBOT" ); @@ -4943,6 +4945,12 @@ int Character::get_speed() const return Creature::get_speed() + get_speedydex_bonus( get_dex() ); } +int Character::get_eff_per() const +{ + return Character::get_per() + int( Character::has_proficiency( proficiency_prof_spotting ) ) * + Character::get_per_base(); +} + int Character::ranged_dex_mod() const { ///\EFFECT_DEX <20 increases ranged penalty diff --git a/src/character.h b/src/character.h index cbdbf2528fd44..0c8c7ed5b922f 100644 --- a/src/character.h +++ b/src/character.h @@ -428,6 +428,7 @@ class Character : public Creature, public visitable virtual int get_int_bonus() const; int get_speed() const override; + int get_eff_per() const override; // Penalty modifiers applied for ranged attacks due to low stats virtual int ranged_dex_mod() const; diff --git a/src/creature.cpp b/src/creature.cpp index 14f2914a23351..85414aefc2863 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -77,6 +77,8 @@ static const efftype_id effect_zapped( "zapped" ); static const species_id species_ROBOT( "ROBOT" ); +static const proficiency_id proficiency_prof_spotting( "prof_spotting" ); + const std::map Creature::size_map = { {"TINY", creature_size::tiny}, {"SMALL", creature_size::small}, @@ -272,6 +274,7 @@ bool Creature::sees( const Creature &critter ) const return visible( ch ); } else if( ( wanted_range > 1 && critter.digging() && here.has_flag( TFLAG_DIGGABLE, critter.pos() ) ) || + ( critter.has_flag( MF_CAMOUFLAGE ) && wanted_range > this->get_eff_per() ) || ( critter.has_flag( MF_NIGHT_INVISIBILITY ) && here.light_at( critter.pos() ) <= lit_level::LOW ) || ( critter.is_underwater() && !is_underwater() && here.is_divable( critter.pos() ) ) || ( here.has_flag_ter_or_furn( TFLAG_HIDE_PLACE, critter.pos() ) && @@ -1648,6 +1651,12 @@ int Creature::get_speed() const { return get_speed_base() + get_speed_bonus(); } + +int Creature::get_eff_per() const +{ + return 0; +} + float Creature::get_dodge() const { return get_dodge_base() + get_dodge_bonus(); diff --git a/src/creature.h b/src/creature.h index c43a2ee6e2c7a..1f0895b25fadf 100644 --- a/src/creature.h +++ b/src/creature.h @@ -636,6 +636,7 @@ class Creature : public location, public viewer virtual float get_hit() const; virtual int get_speed() const; + virtual int get_eff_per() const; virtual creature_size get_size() const = 0; virtual int get_hp( const bodypart_id &bp ) const; virtual int get_hp() const; diff --git a/src/monster.cpp b/src/monster.cpp index 3576e10e1a6e0..9cbe859c40df9 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -1270,6 +1270,11 @@ int monster::hp_percentage() const return get_hp( bodypart_id( "torso" ) ) * 100 / get_hp_max(); } +int monster::get_eff_per() const +{ + return std::min( type->vision_night, type->vision_day ); +} + void monster::process_triggers() { process_trigger( mon_trigger::STALK, [this]() { @@ -1522,6 +1527,8 @@ bool monster::melee_attack( Creature &target, float accuracy ) } const bool u_see_me = player_character.sees( *this ); + const bool u_see_my_spot = player_character.sees( this->pos() ); + const bool u_see_target = player_character.sees( target ); damage_instance damage = !is_hallucination() ? type->melee_damage : damage_instance(); if( !is_hallucination() && type->melee_dice > 0 ) { @@ -1538,32 +1545,32 @@ bool monster::melee_attack( Creature &target, float accuracy ) if( hitspread < 0 ) { bool target_dodging = target.dodge_roll() > 0.0; // Miss - if( u_see_me && !target.in_sleep_state() ) { + if( u_see_my_spot && !target.in_sleep_state() ) { if( target.is_player() ) { if( target_dodging ) { - add_msg( _( "You dodge %s." ), disp_name() ); + add_msg( _( "You dodge %s." ), u_see_me ? disp_name() : "something" ); } else { - add_msg( _( "The %s misses you." ), name() ); + add_msg( _( "%s misses you." ), u_see_me ? disp_name( false, true ) : "Something" ); } } else if( target.is_npc() && target_dodging ) { add_msg( _( "%1$s dodges %2$s attack." ), - target.disp_name(), name() ); + target.disp_name(), u_see_me ? name() : "something" ); } else { - add_msg( _( "The %1$s misses %2$s!" ), - name(), target.disp_name() ); + add_msg( _( "%1$s misses %2$s!" ), + u_see_me ? disp_name( false, true ) : "Something", target.disp_name() ); } } else if( target.is_player() ) { add_msg( _( "You dodge an attack from an unseen source." ) ); } } else if( is_hallucination() || total_dealt > 0 ) { // Hallucinations always produce messages but never actually deal damage - if( u_see_me ) { + if( u_see_my_spot ) { if( target.is_player() ) { sfx::play_variant_sound( "melee_attack", "monster_melee_hit", sfx::get_heard_volume( target.pos() ) ); sfx::do_player_death_hurt( dynamic_cast( target ), false ); //~ 1$s is attacker name, 2$s is bodypart name in accusative. - add_msg( m_bad, _( "The %1$s hits your %2$s." ), name(), + add_msg( m_bad, _( "%1$s hits your %2$s." ), u_see_me ? disp_name( false, true ) : "Something", body_part_name_accusative( dealt_dam.bp_hit ) ); } else if( target.is_npc() ) { if( has_effect( effect_ridden ) && has_flag( MF_RIDEABLE_MECH ) && @@ -1573,7 +1580,7 @@ bool monster::melee_attack( Creature &target, float accuracy ) total_dealt ); } else { //~ %1$s: attacker name, %2$s: target NPC name, %3$s: bodypart name in accusative - add_msg( _( "The %1$s hits %2$s %3$s." ), name(), + add_msg( _( "%1$s hits %2$s %3$s." ), u_see_me ? disp_name( false, true ) : "Something", target.disp_name( true ), body_part_name_accusative( dealt_dam.bp_hit ) ); } @@ -1583,6 +1590,11 @@ bool monster::melee_attack( Creature &target, float accuracy ) //~ %1$s: name of your mount, %2$s: target creature name, %3$d: damage value add_msg( m_good, _( "Your %1$s hits %2$s for %3$d damage!" ), get_name(), target.disp_name(), total_dealt ); + } + if( !u_see_me && u_see_target ) { + add_msg( _( "Something hits the %1$s!" ), target.disp_name() ); + } else if( !u_see_target ) { + add_msg( _( "The %1$s hits something!" ), name() ); } else { //~ %1$s: attacker name, %2$s: target creature name add_msg( _( "The %1$s hits %2$s!" ), name(), target.disp_name() ); @@ -1595,16 +1607,18 @@ bool monster::melee_attack( Creature &target, float accuracy ) } } else { // No damage dealt - if( u_see_me ) { + if( u_see_my_spot ) { if( target.is_player() ) { //~ 1$s is attacker name, 2$s is bodypart name in accusative, 3$s is armor name - add_msg( _( "The %1$s hits your %2$s, but your %3$s protects you." ), name(), + add_msg( _( "%1$s hits your %2$s, but your %3$s protects you." ), u_see_me ? disp_name( false, + true ) : "Something", body_part_name_accusative( dealt_dam.bp_hit ), target.skin_name() ); } else if( target.is_npc() ) { //~ $1s is monster name, %2$s is that monster target name, //~ $3s is target bodypart name in accusative, $4s is the monster target name, //~ 5$s is target armor name. - add_msg( _( "The %1$s hits %2$s %3$s but is stopped by %4$s %5$s." ), name(), + add_msg( _( "%1$s hits %2$s %3$s but is stopped by %4$s %5$s." ), u_see_me ? disp_name( false, + true ) : "Something", target.disp_name( true ), body_part_name_accusative( dealt_dam.bp_hit ), target.disp_name( true ), @@ -1612,8 +1626,8 @@ bool monster::melee_attack( Creature &target, float accuracy ) } else { //~ $1s is monster name, %2$s is that monster target name, //~ $3s is target armor name. - add_msg( _( "The %1$s hits %2$s but is stopped by its %3$s." ), - name(), + add_msg( _( "%1$s hits %2$s but is stopped by its %3$s." ), + u_see_me ? disp_name( false, true ) : "Something", target.disp_name(), target.skin_name() ); } diff --git a/src/monster.h b/src/monster.h index 3975feb0b08a0..df063b58ca7d2 100644 --- a/src/monster.h +++ b/src/monster.h @@ -125,6 +125,7 @@ class monster : public Creature int get_hp_max( const bodypart_id & ) const override; int get_hp_max() const override; int hp_percentage() const override; + int get_eff_per() const override; float get_mountable_weight_ratio() const; diff --git a/src/monstergenerator.cpp b/src/monstergenerator.cpp index 40242e8cfc74a..3b7db5a6d6814 100644 --- a/src/monstergenerator.cpp +++ b/src/monstergenerator.cpp @@ -187,6 +187,7 @@ std::string enum_to_string( m_flag data ) case MF_DROPS_AMMO: return "DROPS_AMMO"; case MF_INSECTICIDEPROOF: return "INSECTICIDEPROOF"; case MF_RANGED_ATTACKER: return "RANGED_ATTACKER"; + case MF_CAMOUFLAGE: return "CAMOUFLAGE"; // *INDENT-ON* case m_flag::MF_MAX: break; diff --git a/src/mtype.h b/src/mtype.h index d9da09e98e6ae..9e1b68c8753bc 100644 --- a/src/mtype.h +++ b/src/mtype.h @@ -178,6 +178,7 @@ enum m_flag : int { MF_DROPS_AMMO, // This monster drops ammo. Should not be set for monsters that use pseudo ammo. MF_INSECTICIDEPROOF, // This monster is immune to insecticide, even though it's made of bug flesh MF_RANGED_ATTACKER, // This monster has any sort of ranged attack + MF_CAMOUFLAGE, // This monster is hard to spot, even in broad daylight MF_MAX // Sets the length of the flags - obviously must be LAST }; From cc9f648c35e9cf4a88b0bf0d02a71c58559ffab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jianxiang=20Wang=20=28=E7=8E=8B=E5=81=A5=E7=BF=94=29?= Date: Sat, 10 Jul 2021 01:13:18 +0800 Subject: [PATCH 112/116] Separate zoom level for overmap (#49776) --- src/game.cpp | 21 +++++++++++++++++++++ src/game.h | 2 ++ src/overmap_ui.cpp | 9 +++++++++ 3 files changed, 32 insertions(+) diff --git a/src/game.cpp b/src/game.cpp index fe7cd75125a95..c009bd26ecc02 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -7593,6 +7593,27 @@ void game::reset_zoom() #endif // TILES } +void game::set_zoom( const int level ) +{ +#if defined(TILES) + if( tileset_zoom != level ) { + tileset_zoom = level; + rescale_tileset( tileset_zoom ); + } +#else + static_cast( level ); +#endif // TILES +} + +int game::get_zoom() const +{ +#if defined(TILES) + return tileset_zoom; +#else + return DEFAULT_TILESET_ZOOM; +#endif +} + int game::get_moves_since_last_save() const { return moves_since_last_save; diff --git a/src/game.h b/src/game.h index 7be7ef04ecda7..331824ef48c27 100644 --- a/src/game.h +++ b/src/game.h @@ -629,6 +629,8 @@ class game void zoom_in(); void zoom_out(); void reset_zoom(); + void set_zoom( int level ); + int get_zoom() const; int get_moves_since_last_save() const; int get_user_action_counter() const; diff --git a/src/overmap_ui.cpp b/src/overmap_ui.cpp index f79fd9e2ce1e7..d40225d3c003b 100644 --- a/src/overmap_ui.cpp +++ b/src/overmap_ui.cpp @@ -1513,9 +1513,18 @@ static void place_ter_or_special( const ui_adaptor &om_ui, tripoint_abs_omt &cur } } +static int overmap_zoom_level = DEFAULT_TILESET_ZOOM; + static tripoint_abs_omt display( const tripoint_abs_omt &orig, const draw_data_t &data = draw_data_t() ) { + const int previous_zoom = g->get_zoom(); + g->set_zoom( overmap_zoom_level ); + on_out_of_scope reset_zoom( [&]() { + overmap_zoom_level = g->get_zoom(); + g->set_zoom( previous_zoom ); + } ); + background_pane bg_pane; ui_adaptor ui; From b434bfcf9fd479a0a1b88da73fd7360d2e4844a6 Mon Sep 17 00:00:00 2001 From: Curtis Merrill Date: Fri, 9 Jul 2021 13:26:55 -0400 Subject: [PATCH 113/116] redo mdeath to use spells (#49439) --- .../monster_deaths.json | 567 +++++++++++++++++ data/json/monsterdrops/misc.json | 36 ++ data/json/monsterdrops/zombie.json | 6 + data/json/monsters/bird.json | 9 - data/json/monsters/cyborgs.json | 8 +- data/json/monsters/defense_bot.json | 18 +- data/json/monsters/drones.json | 6 +- data/json/monsters/feral_humans.json | 3 - data/json/monsters/fish.json | 15 - data/json/monsters/fungus.json | 33 +- data/json/monsters/insect_spider.json | 61 +- data/json/monsters/jabberwock.json | 3 - data/json/monsters/mammal.json | 55 +- data/json/monsters/marloss.json | 2 - data/json/monsters/mechsuits.json | 6 +- data/json/monsters/mi-go.json | 6 - data/json/monsters/misc.json | 18 +- data/json/monsters/mutant.json | 3 - data/json/monsters/mutant_mammal.json | 11 - data/json/monsters/nether.json | 44 +- data/json/monsters/obsolete.json | 18 +- data/json/monsters/power_leech.json | 6 - data/json/monsters/reptile_amphibian.json | 5 - data/json/monsters/robofac_robots.json | 2 +- data/json/monsters/slimes.json | 29 +- data/json/monsters/slugs.json | 3 +- data/json/monsters/triffid.json | 14 +- data/json/monsters/turrets.json | 20 +- data/json/monsters/utility_bot.json | 18 +- data/json/monsters/zanimal_upgrade.json | 6 +- data/json/monsters/zed-animal.json | 16 - data/json/monsters/zed-classic.json | 11 - data/json/monsters/zed-pupating.json | 2 - data/json/monsters/zed-winged.json | 9 +- data/json/monsters/zed_acid.json | 10 +- data/json/monsters/zed_burned.json | 6 +- data/json/monsters/zed_children.json | 8 +- data/json/monsters/zed_electric.json | 4 - data/json/monsters/zed_explosive.json | 12 +- data/json/monsters/zed_ferrous.json | 5 - data/json/monsters/zed_fusion.json | 16 +- data/json/monsters/zed_lab.json | 4 +- data/json/monsters/zed_misc.json | 49 +- data/json/monsters/zed_radiation.json | 10 +- data/json/monsters/zed_skeletal.json | 4 - data/json/monsters/zed_soldiers.json | 21 +- data/json/monsters/zed_survivor.json | 1 - data/mods/Aftershock/mobs/PrepPhyle_mobs.json | 1 - .../Aftershock/mobs/abstract_monsters.json | 4 +- data/mods/Aftershock/mobs/aliens.json | 5 - data/mods/Aftershock/mobs/mutants.json | 1 - data/mods/Aftershock/mobs/robots.json | 16 +- data/mods/Aftershock/mobs/turrets.json | 2 +- .../Aftershock/mobs/uplifted_monsters.json | 3 - data/mods/Aftershock/mobs/water_mobs.json | 2 - data/mods/Aftershock/mobs/zombies.json | 15 +- .../CRT_EXPANSION/monsters/crt_monster.json | 8 +- data/mods/CRT_EXPANSION/monsters/monster.json | 2 - data/mods/CrazyCataclysm/crazy_monsters.json | 5 +- .../monsters/alien_cyborgs.json | 9 +- .../monsters/alien_fauna.json | 7 +- .../monsters/alien_robots.json | 6 +- .../Dark-Skies-Above/monsters/strays.json | 44 +- data/mods/DinoMod/monsters/dinosaur.json | 23 - data/mods/DinoMod/monsters/hatchling.json | 1 - data/mods/DinoMod/monsters/juvenile.json | 1 - data/mods/DinoMod/monsters/zed-dinosaur.json | 9 - .../DinoMod/monsters/zinosaur_upgrade.json | 4 +- data/mods/Magiclysm/monsters.json | 4 +- data/mods/Magiclysm/monsters/Ogre.json | 1 - data/mods/Magiclysm/monsters/Orcs.json | 1 - .../mods/Magiclysm/monsters/demon_spider.json | 2 - data/mods/Magiclysm/monsters/dragon.json | 1 - .../Magiclysm/monsters/forgedwellers.json | 4 +- data/mods/Magiclysm/monsters/goblin.json | 1 - data/mods/Magiclysm/monsters/golems.json | 8 +- .../Magiclysm/monsters/holiday_magiclysm.json | 3 - data/mods/Magiclysm/monsters/lizardfolk.json | 1 - data/mods/Magiclysm/monsters/monsters.json | 14 +- .../monsters/zombified_monsters.json | 2 - .../My_Sweet_Cataclysm/sweet_monsters.json | 13 +- data/mods/National_Guard_Camp/military.json | 2 +- .../desert_region/desert_insect_spider.json | 1 - data/mods/desert_region/desert_mammal.json | 1 - data/mods/desert_region/desert_monsters.json | 3 +- .../desert_reptile_amphibian.json | 1 - doc/MAGIC.md | 13 +- doc/MONSTERS.md | 11 +- src/magic.cpp | 5 + src/magic.h | 15 + src/magic_spell_effect.cpp | 148 +++++ src/mondeath.cpp | 595 +----------------- src/mondeath.h | 71 --- src/monster.cpp | 58 +- src/monstergenerator.cpp | 125 +--- src/monstergenerator.h | 1 - src/mtype.cpp | 1 - src/mtype.h | 27 +- tests/monster_test.cpp | 6 +- 99 files changed, 1151 insertions(+), 1375 deletions(-) create mode 100644 data/json/monster_special_attacks/monster_deaths.json diff --git a/data/json/monster_special_attacks/monster_deaths.json b/data/json/monster_special_attacks/monster_deaths.json new file mode 100644 index 0000000000000..6f0a53489e2ae --- /dev/null +++ b/data/json/monster_special_attacks/monster_deaths.json @@ -0,0 +1,567 @@ +[ + { + "id": "necro_boomer_revive", + "type": "SPELL", + "name": { "str": "Necro Boomer Revive" }, + "description": "Revives zombies in a large AOE", + "valid_targets": [ "ground" ], + "flags": [ "SILENT" ], + "min_aoe": 10, + "max_aoe": 10, + "shape": "blast", + "effect": "revive", + "effect_str": "ZOMBIE" + }, + { + "id": "necro_boomer_upgrade", + "type": "SPELL", + "name": { "str": "Necro Boomer Upgrade" }, + "description": "Upgrades zombies in a large AOE", + "valid_targets": [ "ally" ], + "flags": [ "SILENT" ], + "min_aoe": 10, + "max_aoe": 10, + "min_damage": 1000, + "max_damage": 1000, + "shape": "blast", + "effect": "upgrade" + }, + { + "id": "necro_boomer_death", + "type": "SPELL", + "name": { "str": "Necro Boomer Death" }, + "description": "Revives and then upgrades zombies in a large area", + "valid_targets": [ "ground", "ally" ], + "shape": "blast", + "effect": "noise", + "min_damage": 24, + "max_damage": 24, + "sound_type": "combat", + "sound_id": "explosion", + "sound_variant": "small", + "extra_effects": [ { "id": "necro_boomer_revive", "hit_self": true }, { "id": "necro_boomer_upgrade", "hit_self": true } ] + }, + { + "id": "zombie_child_guilt", + "type": "SPELL", + "name": { "str": "Zombie Child Guilt" }, + "description": "Causes guilt to the target as if the caster was killed by it.", + "valid_targets": [ "hostile" ], + "flags": [ "SILENT" ], + "shape": "blast", + "effect": "guilt", + "effect_str": "ZOMBIE", + "min_damage": 100, + "max_damage": 100, + "min_duration": 180000, + "max_duration": 180000, + "min_range": 5, + "max_range": 5 + }, + { + "id": "death_acid", + "type": "SPELL", + "name": { "str": "Acid Death" }, + "description": "Acid sprays out of a dead acid zombie or some such.", + "valid_targets": [ "ground", "self" ], + "flags": [ "SILENT" ], + "shape": "blast", + "effect": "attack", + "field_id": "fd_acid", + "min_field_intensity": 3, + "max_field_intensity": 3, + "field_chance": 1 + }, + { + "id": "death_halfworm", + "type": "SPELL", + "name": { "str": "Death Halfworm" }, + "description": "Spawns two halfworms.", + "valid_targets": [ "ground", "self" ], + "min_damage": 2, + "max_damage": 2, + "flags": [ "SILENT" ], + "shape": "blast", + "effect": "summon", + "effect_str": "mon_halfworm", + "min_aoe": 1, + "max_aoe": 1 + }, + { + "id": "death_blobsplit_large", + "type": "SPELL", + "name": { "str": "Death Blobsplit Large" }, + "description": "A large blob splits in half", + "valid_targets": [ "ground", "self" ], + "min_damage": 2, + "max_damage": 2, + "flags": [ "SILENT" ], + "shape": "blast", + "effect": "summon", + "effect_str": "mon_blob", + "min_aoe": 1, + "max_aoe": 1 + }, + { + "id": "death_blobsplit", + "type": "SPELL", + "name": { "str": "Death Blobsplit" }, + "description": "A blob splits in half", + "valid_targets": [ "ground", "self" ], + "min_damage": 2, + "max_damage": 2, + "flags": [ "SILENT" ], + "shape": "blast", + "effect": "summon", + "effect_str": "mon_blob_small", + "min_aoe": 1, + "max_aoe": 1 + }, + { + "id": "death_blobsplit_brain", + "type": "SPELL", + "name": { "str": "Death Blobsplit Brain" }, + "description": "A blob brain splits in half", + "valid_targets": [ "ground", "self" ], + "min_damage": 3, + "max_damage": 3, + "flags": [ "SILENT" ], + "shape": "blast", + "effect": "summon", + "effect_str": "mon_blob_large", + "min_aoe": 1, + "max_aoe": 1 + }, + { + "id": "death_blob_brain", + "type": "SPELL", + "name": { "str": "Death Blob Brain" }, + "description": "A blob brain dies", + "valid_targets": [ "ally" ], + "min_aoe": 48, + "max_aoe": 48, + "flags": [ "SILENT" ], + "shape": "blast", + "effect": "remove_effect", + "effect_str": "controlled", + "targeted_monster_ids": [ "blob_small", "blob", "blob_large" ], + "extra_effects": [ { "id": "death_blobsplit_brain", "hit_self": true } ] + }, + { + "id": "death_explosion", + "type": "SPELL", + "name": { "str": "Death Explosion Sound" }, + "description": "boom", + "valid_targets": [ "self" ], + "shape": "blast", + "effect": "noise", + "min_damage": 24, + "max_damage": 24, + "sound_id": "explosion", + "sound_type": "combat", + "sound_variant": "small" + }, + { + "id": "death_gas", + "type": "SPELL", + "name": { "str": "Gas Explosion" }, + "description": "Causes a small explosion of toxic gas.", + "valid_targets": [ "self" ], + "shape": "blast", + "effect": "emit", + "effect_str": "emit_toxic_blast", + "extra_effects": [ { "id": "death_explosion", "hit_self": true } ] + }, + { + "id": "death_smokeburst", + "type": "SPELL", + "name": { "str": "Smoke Explosion" }, + "description": "Causes a small explosion of smoke.", + "valid_targets": [ "self" ], + "shape": "blast", + "effect": "emit", + "effect_str": "emit_smoke_blast", + "extra_effects": [ { "id": "death_explosion", "hit_self": true } ] + }, + { + "id": "death_tearburst", + "type": "SPELL", + "name": { "str": "Teargas Explosion" }, + "description": "Causes a small explosion of teargas.", + "valid_targets": [ "self" ], + "shape": "blast", + "effect": "emit", + "effect_str": "emit_tear_gas_blast", + "extra_effects": [ { "id": "death_explosion", "hit_self": true } ] + }, + { + "id": "death_fungalburst", + "type": "SPELL", + "name": { "str": "Fungal Explosion" }, + "description": "Causes a small explosion of fungus.", + "valid_targets": [ "self" ], + "shape": "blast", + "effect": "emit", + "//": "TODO: Add the ability to check if there's anti-fungal gas here to negate this effect.", + "effect_str": "emit_fungal_blast", + "extra_effects": [ { "id": "death_explosion", "hit_self": true } ] + }, + { + "id": "death_pouf", + "type": "SPELL", + "name": { "str": "Death Pouf Sound" }, + "description": "pouf", + "valid_targets": [ "self" ], + "effect": "noise", + "min_damage": 10, + "max_damage": 10, + "shape": "blast", + "sound_id": "misc", + "sound_variant": "puff", + "sound_type": "combat", + "message": "Pouf!" + }, + { + "id": "death_fungus", + "type": "SPELL", + "name": { "str": "Pouf" }, + "description": "Fungal pouf", + "valid_targets": [ "ground", "self" ], + "effect": "fungalize", + "flags": [ "SILENT" ], + "min_damage": 2500, + "max_damage": 2500, + "min_aoe": 1, + "max_aoe": 1, + "shape": "blast", + "extra_effects": [ { "id": "death_pouf", "hit_self": true } ] + }, + { + "id": "remove_controlled_jackson", + "type": "SPELL", + "name": { "str": "Uncontrol Dancers" }, + "valid_targets": [ "self", "ally" ], + "description": "Removes control effect from polymorphed dancers.", + "targeted_monster_ids": [ "mon_zombie_hulk" ], + "min_aoe": 48, + "max_aoe": 48, + "shape": "blast", + "effect_str": "controlled", + "effect": "remove_effect" + }, + { + "id": "death_jackson", + "type": "SPELL", + "name": { "str": "Jackson Death" }, + "description": "Hee Hee! WOO!", + "valid_targets": [ "self", "ally" ], + "effect": "targeted_polymorph", + "min_aoe": 48, + "max_aoe": 48, + "min_damage": 400, + "max_damage": 400, + "flags": [ "SILENT" ], + "shape": "blast", + "effect_str": "mon_zombie_hulk", + "targeted_monster_ids": [ "mon_zombie_dancer" ], + "extra_effects": [ { "id": "remove_controlled_jackson", "hit_self": true } ] + }, + { + "id": "death_darkman", + "type": "SPELL", + "name": { "str": "Darkman Death" }, + "valid_targets": [ "ally", "hostile" ], + "description": "Removes the darkness effect.", + "min_range": 48, + "max_range": 48, + "shape": "blast", + "effect": "remove_effect", + "effect_str": "darkness" + }, + { + "id": "death_fakespell", + "type": "SPELL", + "name": { "str": "Fake Spell" }, + "description": "A spell that doesn't do anything.", + "valid_targets": [ "hostile", "ally", "ground" ], + "flags": [ "SILENT" ], + "shape": "blast", + "effect": "noise" + }, + { + "id": "death_fireball", + "type": "SPELL", + "name": { "str": "Fireball Death" }, + "valid_targets": [ "ally", "ground", "hostile" ], + "description": "1/10 chance to burst into flames.", + "flags": [ "WONDER" ], + "effect": "none", + "shape": "blast", + "extra_effects": [ + { "id": "death_fakespell" }, + { "id": "death_fakespell" }, + { "id": "death_fakespell" }, + { "id": "death_fakespell" }, + { "id": "death_fakespell" }, + { "id": "death_fakespell" }, + { "id": "death_fakespell" }, + { "id": "death_fakespell" }, + { "id": "death_fakespell" }, + { "id": "death_conflagration", "hit_self": true } + ] + }, + { + "id": "death_conflagration", + "type": "SPELL", + "name": { "str": "Conflagration Death" }, + "valid_targets": [ "self", "ally", "hostile", "ground" ], + "description": "A fireball. Hits with mild shrapnel, but the main effect is fire.", + "effect": "attack", + "field_id": "fd_fire", + "field_chance": 2, + "min_field_intensity": 2, + "max_field_intensity": 2, + "min_aoe": 3, + "max_aoe": 3, + "min_damage": 2, + "max_damage": 2, + "min_duration": 1000, + "max_duration": 1000, + "damage_type": "cut", + "shape": "blast" + }, + { + "id": "death_explosion_mon_spider_jumping_mega", + "type": "SPELL", + "name": { "str": "Death Explosion Huge" }, + "valid_targets": [ "self", "ally", "hostile", "ground" ], + "description": "Big Boom", + "effect": "explosion", + "min_aoe": 8, + "max_aoe": 8, + "min_damage": 26, + "max_damage": 26, + "shape": "blast" + }, + { + "id": "death_explosion_mon_spawn_raptor_unstable", + "type": "SPELL", + "name": { "str": "Death Explosion Tiny" }, + "valid_targets": [ "self", "ally", "hostile", "ground" ], + "description": "tiny boom", + "min_aoe": 8, + "max_aoe": 8, + "min_damage": 4, + "max_damage": 4, + "effect": "explosion", + "shape": "blast" + }, + { + "id": "death_explosion_mon_hazmatbot", + "type": "SPELL", + "name": { "str": "Death Explosion Large" }, + "valid_targets": [ "self", "ally", "hostile", "ground" ], + "description": "tiny boom", + "min_aoe": 8, + "max_aoe": 8, + "min_damage": 20, + "max_damage": 20, + "effect": "explosion", + "shape": "blast" + }, + { + "id": "death_thing", + "type": "SPELL", + "name": { "str": "Death Thing" }, + "description": "Spawns a thing.", + "valid_targets": [ "ground", "self" ], + "min_damage": 1, + "max_damage": 1, + "flags": [ "SILENT" ], + "shape": "blast", + "effect": "summon", + "effect_str": "mon_thing", + "min_aoe": 1, + "max_aoe": 1 + }, + { + "id": "death_preg_roach", + "type": "SPELL", + "name": { "str": "Death Pregnant Roach" }, + "description": "Spawns roach nymph.", + "valid_targets": [ "ground", "self" ], + "min_damage": 1, + "max_damage": 3, + "flags": [ "RANDOM_DAMAGE" ], + "shape": "blast", + "effect": "summon", + "effect_str": "mon_giant_cockroach_nymph", + "min_aoe": 1, + "max_aoe": 1 + }, + { + "id": "death_boomer", + "type": "SPELL", + "name": { "str": "Death Boomer" }, + "description": "Vomitous Explosion", + "valid_targets": [ "ground", "hostile", "ally", "self" ], + "min_aoe": 1, + "max_aoe": 2, + "aoe_increment": 1, + "max_level": 1, + "min_duration": 2400, + "max_duration": 2400, + "shape": "blast", + "effect": "attack", + "effect_str": "boomered", + "field_chance": 1, + "field_id": "fd_bile", + "max_field_intensity": 2, + "min_field_intensity": 2, + "affected_body_parts": [ "EYES" ], + "extra_effects": [ { "id": "death_explosion", "hit_self": true } ] + }, + { + "id": "death_boomer_glow", + "type": "SPELL", + "name": { "str": "Death Boomer Glow" }, + "description": "Boomers and Glow", + "valid_targets": [ "ground", "hostile", "ally", "self" ], + "shape": "blast", + "effect": "attack", + "effect_str": "glowing", + "max_level": 1, + "affected_body_parts": [ "TORSO", "ARM_R", "ARM_L", "LEG_R", "LEG_L" ], + "extra_effects": [ { "id": "death_boomer", "hit_self": true } ], + "min_duration": 24000, + "max_duration": 24000 + }, + { + "id": "ratking_summon_rats", + "type": "SPELL", + "name": { "str": "Death Summon Rats" }, + "description": "makes some rats", + "valid_targets": [ "ground" ], + "shape": "blast", + "effect": "summon", + "effect_str": "mon_sewer_rat", + "min_damage": 7, + "max_damage": 7, + "min_aoe": 1, + "max_aoe": 1 + }, + { + "id": "death_ratking", + "type": "SPELL", + "name": { "str": "Death Ratking" }, + "description": "Death Ratking", + "valid_targets": [ "hostile", "ally" ], + "shape": "blast", + "effect": "remove_effect", + "effect_str": "rat", + "min_range": 48, + "max_range": 48, + "extra_effects": [ { "id": "ratking_summon_rats", "hit_self": true } ] + }, + { + "id": "death_focused_beam_explosion", + "type": "SPELL", + "name": { "str": "Death Focused Beam Explosion" }, + "description": "Give 'em the old flim flam flummox", + "valid_targets": [ "self" ], + "shape": "blast", + "effect": "explosion", + "min_damage": 8, + "max_damage": 8 + }, + { + "id": "death_focused_beam", + "type": "SPELL", + "name": { "str": "Death Focused Beam" }, + "description": "Give 'em the old razzle dazzle", + "valid_targets": [ "hostile", "ally", "ground" ], + "effect": "attack", + "shape": "line", + "field_id": "fd_dazzling", + "field_chance": 1, + "min_field_intensity": 2, + "max_field_intensity": 2, + "extra_effects": [ { "id": "death_focused_beam_explosion", "hit_self": true } ] + }, + { + "id": "death_kill_vines", + "type": "SPELL", + "name": { "str": "Death Kill Vines" }, + "description": "Kill all vines", + "valid_targets": [ "hostile", "ally" ], + "effect": "attack", + "shape": "blast", + "targeted_monster_ids": [ "mon_creeper_vine" ], + "damage_type": "pure", + "min_damage": 1000, + "max_damage": 1000, + "min_aoe": 1, + "max_aoe": 48, + "aoe_increment": 48, + "max_level": 1, + "flags": [ "SILENT" ] + }, + { + "id": "death_kill_breathers", + "type": "SPELL", + "name": { "str": "Death Kill Breathers" }, + "description": "Kill all breathers", + "valid_targets": [ "hostile", "ally" ], + "effect": "attack", + "shape": "blast", + "targeted_monster_ids": [ "mon_breather", "mon_breather_hub" ], + "damage_type": "pure", + "min_damage": 1000, + "max_damage": 1000, + "min_aoe": 48, + "max_aoe": 48, + "aoe_increment": 48, + "flags": [ "SILENT" ] + }, + { + "id": "death_gameover", + "type": "SPELL", + "name": { "str": "Death Gameover" }, + "message": "Game over, man!", + "description": "You Died", + "min_damage": 1000, + "max_damage": 1000, + "min_aoe": 48, + "max_aoe": 48, + "damage_type": "pure", + "effect": "attack", + "shape": "blast", + "valid_targets": [ "ally", "hostile" ] + }, + { + "id": "death_triffid_heart", + "type": "SPELL", + "name": { "str": "Death Triffid Heart" }, + "description": "kills roots", + "effect": "timed_event", + "min_duration": 60000, + "max_duration": 60000, + "min_range": 48, + "max_range": 48, + "effect_str": "ROOTS_DIE", + "shape": "blast", + "valid_targets": [ "ally", "hostile" ] + }, + { + "id": "death_amigara", + "type": "SPELL", + "name": { "str": "Death Amigara" }, + "valid_targets": [ "hostile", "ally", "ground" ], + "description": "removes hypnosis", + "effect": "remove_effect", + "effect_str": "amigara", + "min_range": 48, + "max_range": 48, + "shape": "blast" + } +] diff --git a/data/json/monsterdrops/misc.json b/data/json/monsterdrops/misc.json index 4a21c3695afe7..5b04aa5f4a13f 100644 --- a/data/json/monsterdrops/misc.json +++ b/data/json/monsterdrops/misc.json @@ -22,6 +22,42 @@ { "item": "amplifier", "count": [ 0, 3 ] } ] }, + { + "type": "item_group", + "id": "amigara_items", + "subtype": "distribution", + "items": [ + [ "art_sphere", 100 ], + [ "art_rod", 100 ], + [ "art_teardrop", 100 ], + [ "art_lamp", 100 ], + [ "art_snake", 100 ], + [ "art_disc", 100 ], + [ "art_beads", 100 ], + [ "art_napkin", 100 ], + [ "art_urchin", 100 ], + [ "art_jelly", 100 ], + [ "art_spiral", 100 ], + [ "art_pin", 100 ], + [ "art_tube", 100 ], + [ "art_pyramid", 100 ], + [ "art_crystal", 100 ], + [ "art_knot", 100 ], + [ "art_crescent", 100 ] + ] + }, + { + "type": "item_group", + "id": "amigara_drops", + "subtype": "distribution", + "entries": [ + { + "group": "amigara_items", + "artifact": { "procgen_id": "netherum_tunnels", "rules": { "power_level": 750, "max_attributes": 4, "max_negative_power": -1000 } }, + "prob": 100 + } + ] + }, { "type": "item_group", "subtype": "collection", diff --git a/data/json/monsterdrops/zombie.json b/data/json/monsterdrops/zombie.json index 4421b276c6d3c..e1b0c8fc26c2e 100644 --- a/data/json/monsterdrops/zombie.json +++ b/data/json/monsterdrops/zombie.json @@ -51,6 +51,12 @@ { "group": "wallets", "damage": [ 1, 4 ] } ] }, + { + "type": "item_group", + "subtype": "collection", + "id": "mon_blob_small_deathdrops", + "entries": [ { "item": "slime_scrap", "count": 1 } ] + }, { "type": "item_group", "subtype": "collection", diff --git a/data/json/monsters/bird.json b/data/json/monsters/bird.json index afc64b80d7b73..be66f78153bd8 100644 --- a/data/json/monsters/bird.json +++ b/data/json/monsters/bird.json @@ -27,7 +27,6 @@ "reproduction": { "baby_egg": "egg_chicken", "baby_count": 1, "baby_timer": 2 }, "baby_flags": [ "SPRING", "SUMMER", "AUTUMN", "WINTER" ], "biosignature": { "biosig_item": "feces_bird", "biosig_timer": 3 }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "BIRDFOOD", "SWARMS" ] }, { @@ -69,7 +68,6 @@ "dodge": 4, "harvest": "bird_tiny", "fear_triggers": [ "SOUND", "PLAYER_CLOSE", "FRIEND_ATTACKED", "FRIEND_DIED", "FIRE", "HURT" ], - "death_function": [ "NORMAL" ], "reproduction": { "baby_egg": "egg_crow", "baby_count": 3, "baby_timer": 8 }, "baby_flags": [ "SPRING" ], "biosignature": { "biosig_item": "feces_bird", "biosig_timer": 8 }, @@ -99,7 +97,6 @@ "dodge": 4, "harvest": "bird_small", "fear_triggers": [ "SOUND", "PLAYER_CLOSE", "FRIEND_ATTACKED", "FRIEND_DIED", "FIRE", "HURT" ], - "death_function": [ "NORMAL" ], "reproduction": { "baby_egg": "egg_duck", "baby_count": 3, "baby_timer": 5 }, "baby_flags": [ "SPRING" ], "biosignature": { "biosig_item": "feces_bird", "biosig_timer": 5 }, @@ -149,7 +146,6 @@ "harvest": "bird_small", "vision_day": 50, "fear_triggers": [ "PLAYER_CLOSE", "FRIEND_DIED", "FIRE", "HURT" ], - "death_function": [ "NORMAL" ], "reproduction": { "baby_egg": "egg_turkey", "baby_count": 3, "baby_timer": 12 }, "baby_flags": [ "SPRING", "SUMMER" ], "biosignature": { "biosig_item": "feces_bird", "biosig_timer": 8 }, @@ -200,7 +196,6 @@ "reproduction": { "baby_egg": "egg_cockatrice", "baby_count": 3, "baby_timer": 10 }, "baby_flags": [ "SPRING", "SUMMER", "AUTUMN" ], "biosignature": { "biosig_item": "feces_bird", "biosig_timer": 8 }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "FLIES" ] }, { @@ -228,7 +223,6 @@ "melee_cut": 1, "dodge": 1, "harvest": "bird_tiny", - "death_function": [ "NORMAL" ], "upgrades": { "age_grow": 14, "into": "mon_chicken" }, "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "BIRDFOOD", "SWARMS" ] }, @@ -310,7 +304,6 @@ "harvest": "bird_large", "fear_triggers": [ "PLAYER_CLOSE" ], "special_attacks": [ [ "SHRIEK", 10 ] ], - "death_function": [ "NORMAL" ], "biosignature": { "biosig_item": "feces_bird", "biosig_timer": 8 }, "upgrades": { "half_life": 10, "into_group": "GROUP_CROW_MUTANT" }, "flags": [ "SEES", "HEARS", "SMELLS", "PATH_AVOID_DANGER_1", "WARM", "FLIES" ] @@ -340,7 +333,6 @@ "vision_night": 4, "harvest": "bird_large", "special_attacks": [ [ "SHRIEK", 10 ], [ "LUNGE", 8 ], { "type": "leap", "cooldown": 10, "max_range": 3 } ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "PATH_AVOID_DANGER_1", "STUMBLES", "WARM" ] }, { @@ -367,7 +359,6 @@ "dodge": 4, "harvest": "bird_tiny", "fear_triggers": [ "SOUND", "PLAYER_CLOSE", "FRIEND_ATTACKED", "FRIEND_DIED", "FIRE", "HURT" ], - "death_function": [ "NORMAL" ], "biosignature": { "biosig_item": "feces_bird", "biosig_timer": 4 }, "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "FLIES", "SWARMS", "BIRDFOOD" ] } diff --git a/data/json/monsters/cyborgs.json b/data/json/monsters/cyborgs.json index 26268c190334f..9bdfebbbd05a9 100644 --- a/data/json/monsters/cyborgs.json +++ b/data/json/monsters/cyborgs.json @@ -27,7 +27,6 @@ "vision_day": 50, "revert_to_itype": "bot_broken_cyborg", "special_attacks": [ [ "PARROT", 800 ] ], - "death_function": [ "NORMAL" ], "harvest": "mon_broken_cyborg", "flags": [ "SEES", @@ -72,7 +71,6 @@ "path_settings": { "avoid_traps": true, "avoid_sharp": true }, "revert_to_itype": "bot_prototype_cyborg", "special_attacks": [ [ "PARROT", 800 ] ], - "death_function": [ "NORMAL" ], "harvest": "mon_broken_cyborg", "flags": [ "SEES", @@ -115,7 +113,7 @@ "revert_to_itype": "e_scrap", "anger_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT" ], "death_drops": { "subtype": "collection", "groups": [ [ "robots", 80 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", "GOODHEARING", "NOHEAD", "NO_BREATHE", "PATH_AVOID_DANGER_2", "PRIORITIZE_TARGETS", "HIT_AND_RUN" ] }, { @@ -166,7 +164,7 @@ } ], "death_drops": { "subtype": "collection", "groups": [ [ "robots", 80 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", "GOODHEARING", "NOHEAD", "NO_BREATHE", "PATH_AVOID_DANGER_2", "PRIORITIZE_TARGETS", "HIT_AND_RUN" ] }, { @@ -197,7 +195,7 @@ "vision_night": 3, "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "GRAB", 7 ], [ "scratch", 20 ] ], "death_drops": { "subtype": "collection", "groups": [ [ "robots", 80 ] ] }, - "death_function": [ "FIREBALL" ], + "death_function": { "effect": { "id": "death_fireball", "hit_self": true } }, "harvest": "mon_zomborg", "flags": [ "SEES", diff --git a/data/json/monsters/defense_bot.json b/data/json/monsters/defense_bot.json index e578189b34edd..befeec1d821d2 100644 --- a/data/json/monsters/defense_bot.json +++ b/data/json/monsters/defense_bot.json @@ -29,7 +29,7 @@ "revert_to_itype": "bot_copbot", "special_attacks": [ [ "COPBOT", 3 ] ], "death_drops": { "groups": [ [ "robots", 4 ], [ "copbot", 1 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", "BASHES", "ELECTRONIC", "COLDPROOF", "NO_BREATHE", "PRIORITIZE_TARGETS", "PATH_AVOID_DANGER_1" ] }, { @@ -60,7 +60,7 @@ "special_attacks": [ [ "RIOTBOT", 1 ] ], "special_when_hit": [ "ZAPBACK", 100 ], "death_drops": { "groups": [ [ "robots", 4 ], [ "copbot", 1 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", "GOODHEARING", "ELECTRONIC", "COLDPROOF", "NO_BREATHE", "PRIORITIZE_TARGETS", "PATH_AVOID_DANGER_1" ] }, { @@ -107,7 +107,7 @@ } ], "death_drops": { }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", "ELECTRONIC", "COLDPROOF", "NO_BREATHE", "PATH_AVOID_DANGER_1", "LOUDMOVES", "DROPS_AMMO" ] }, { @@ -154,7 +154,7 @@ } ], "death_drops": { }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", "ELECTRONIC", "COLDPROOF", "NO_BREATHE", "PATH_AVOID_DANGER_1", "LOUDMOVES", "DROPS_AMMO" ] }, { @@ -183,7 +183,7 @@ "path_settings": { "max_dist": 5 }, "special_attacks": [ [ "TAZER", 5 ] ], "death_drops": { "groups": [ [ "robots", 4 ], [ "skitterbot", 1 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", "GOODHEARING", "ELECTRONIC", "COLDPROOF", "NO_BREATHE", "PATH_AVOID_DANGER_1" ] }, { @@ -218,7 +218,7 @@ "path_settings": { "max_dist": 5, "avoid_traps": true, "avoid_sharp": true }, "special_attacks": [ [ "SCIENCE", 16 ], [ "TAZER", 10 ] ], "death_drops": { "groups": [ [ "robots", 4 ], [ "skitterbot", 1 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", @@ -259,7 +259,7 @@ "path_settings": { "max_dist": 5, "avoid_traps": true, "avoid_sharp": true }, "special_attacks": [ [ "SMASH", 20 ], [ "BIO_OP_TAKEDOWN", 20 ] ], "death_drops": "mon_robofac_prototype_drops", - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", @@ -305,7 +305,7 @@ "starting_ammo": { "bot_c4_hack": 2, "bot_flashbang_hack": 3, "bot_gasbomb_hack": 3, "bot_grenade_hack": 10 }, "special_attacks": [ [ "GRENADIER", 10 ] ], "death_drops": { "groups": [ [ "robots", 1 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", @@ -350,7 +350,7 @@ "starting_ammo": { "bot_c4_hack": 10, "bot_flashbang_hack": 10, "bot_gasbomb_hack": 10, "bot_grenade_hack": 20, "bot_mininuke_hack": 1 }, "special_attacks": [ [ "GRENADIER_ELITE", 10 ] ], "death_drops": { "groups": [ [ "robots", 1 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", diff --git a/data/json/monsters/drones.json b/data/json/monsters/drones.json index 550fa09c3f8a3..9e3ff55845cbe 100644 --- a/data/json/monsters/drones.json +++ b/data/json/monsters/drones.json @@ -14,7 +14,7 @@ "morale": 100, "luminance": 5, "death_drops": { "subtype": "collection", "groups": [ [ "robots", 80 ] ], "//": "80% chance of an item from group robots" }, - "death_function": [ "BROKEN_AMMO" ], + "death_function": { "message": "The %s's interior compartment sizzles with destructive energy.", "corpse_type": "BROKEN" }, "flags": [ "SEES", "FLIES", "NOHEAD", "ELECTRONIC", "NO_BREATHE", "INTERIOR_AMMO" ] }, { @@ -110,7 +110,7 @@ "armor_bullet": 6, "revert_to_itype": "bot_manhack", "death_drops": { "groups": [ [ "robots", 4 ], [ "manhack", 1 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "extend": { "flags": [ "HIT_AND_RUN" ] } }, { @@ -172,7 +172,7 @@ } ], "death_drops": { "subtype": "collection", "groups": [ [ "robots", 80 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", diff --git a/data/json/monsters/feral_humans.json b/data/json/monsters/feral_humans.json index 3d3829915f477..8c18b608fa17e 100644 --- a/data/json/monsters/feral_humans.json +++ b/data/json/monsters/feral_humans.json @@ -44,7 +44,6 @@ } ], "death_drops": "feral_humans_death_drops_pipe", - "death_function": [ "NORMAL" ], "zombify_into": "mon_zombie", "anger_triggers": [ "FRIEND_DIED", "FRIEND_ATTACKED", "HURT" ], "flags": [ @@ -107,7 +106,6 @@ "vision_day": 50, "vision_night": 3, "death_drops": "feral_scientists_death_drops_scalpel", - "death_function": [ "NORMAL" ], "zombify_into": "mon_zombie_scientist", "anger_triggers": [ "FRIEND_DIED", "FRIEND_ATTACKED", "HURT", "PLAYER_CLOSE" ], "flags": [ @@ -172,7 +170,6 @@ } ], "death_drops": "feral_security_death_drops_9mm", - "death_function": [ "NORMAL" ], "zombify_into": "mon_zombie_labsecurity", "anger_triggers": [ "FRIEND_DIED", "FRIEND_ATTACKED", "HURT", "PLAYER_WEAK" ], "flags": [ diff --git a/data/json/monsters/fish.json b/data/json/monsters/fish.json index 6060db27211ef..2f51abbb748d8 100644 --- a/data/json/monsters/fish.json +++ b/data/json/monsters/fish.json @@ -33,7 +33,6 @@ "special_attacks": [ [ "SHRIEK_ALERT", 6 ], [ "SHRIEK_STUN", 1 ] ], "anger_triggers": [ "PLAYER_CLOSE", "HURT" ], "fear_triggers": [ "FIRE" ], - "death_function": [ "NORMAL" ], "flags": [ "SMELLS", "HEARS", "SEES", "SWIMS", "GRABS", "ARTHROPOD_BLOOD", "QUEEN", "PATH_AVOID_DANGER_1" ] }, { @@ -63,7 +62,6 @@ "reproduction": { "baby_egg": "egg_fish", "baby_count": 2, "baby_timer": 17 }, "baby_flags": [ "SPRING", "SUMMER" ], "fear_triggers": [ "PLAYER_CLOSE", "SOUND" ], - "death_function": [ "NORMAL" ], "harvest": "fish_tiny", "flags": [ "FISHABLE", "SEES", "SMELLS", "WARM", "SWIMS", "AQUATIC" ] }, @@ -94,7 +92,6 @@ "reproduction": { "baby_egg": "egg_fish", "baby_count": 2, "baby_timer": 17 }, "baby_flags": [ "SPRING", "SUMMER" ], "fear_triggers": [ "PLAYER_CLOSE", "SOUND" ], - "death_function": [ "NORMAL" ], "harvest": "fish_small", "flags": [ "FISHABLE", "SEES", "SMELLS", "WARM", "SWIMS", "AQUATIC" ] }, @@ -125,7 +122,6 @@ "reproduction": { "baby_egg": "egg_fish", "baby_count": 2, "baby_timer": 17 }, "baby_flags": [ "SPRING", "SUMMER" ], "fear_triggers": [ "PLAYER_CLOSE", "SOUND" ], - "death_function": [ "NORMAL" ], "harvest": "fish_small", "flags": [ "FISHABLE", "SEES", "SMELLS", "WARM", "SWIMS", "AQUATIC" ] }, @@ -156,7 +152,6 @@ "reproduction": { "baby_egg": "egg_fish", "baby_count": 2, "baby_timer": 17 }, "baby_flags": [ "SPRING", "SUMMER" ], "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "harvest": "fish_large", "flags": [ "FISHABLE", "SEES", "SMELLS", "WARM", "SWIMS", "AQUATIC" ] }, @@ -187,7 +182,6 @@ "reproduction": { "baby_egg": "egg_fish", "baby_count": 2, "baby_timer": 17 }, "baby_flags": [ "SPRING", "SUMMER" ], "fear_triggers": [ "PLAYER_CLOSE", "SOUND" ], - "death_function": [ "NORMAL" ], "harvest": "fish_large", "flags": [ "FISHABLE", "SEES", "SMELLS", "WARM", "SWIMS", "AQUATIC" ] }, @@ -508,7 +502,6 @@ "reproduction": { "baby_egg": "egg_fish", "baby_count": 2, "baby_timer": 180 }, "baby_flags": [ "SUMMER", "AUTUMN" ], "fear_triggers": [ "PLAYER_CLOSE", "SOUND" ], - "death_function": [ "NORMAL" ], "flags": [ "FISHABLE", "SEES", "SMELLS", "WARM", "SWIMS", "AQUATIC" ] }, { @@ -537,7 +530,6 @@ "reproduction": { "baby_egg": "egg_fish", "baby_count": 2, "baby_timer": 21 }, "baby_flags": [ "AUTUMN" ], "fear_triggers": [ "PLAYER_CLOSE", "SOUND" ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 14, "into": "mon_crayfish_small" }, "flags": [ "FISHABLE", "SEES", "SMELLS", "WARM", "SWIMS", "AQUATIC" ] }, @@ -564,7 +556,6 @@ "melee_cut": 1, "luminance": 5, "fear_triggers": [ "PLAYER_CLOSE", "SOUND" ], - "death_function": [ "NORMAL" ], "harvest": "fish_small", "flags": [ "FISHABLE", "SEES", "SMELLS", "WARM", "SWIMS", "AQUATIC" ] }, @@ -591,7 +582,6 @@ "melee_cut": 1, "luminance": 0, "fear_triggers": [ "PLAYER_CLOSE", "SOUND" ], - "death_function": [ "NORMAL" ], "harvest": "fish_small", "flags": [ "FISHABLE", "SEES", "SMELLS", "WARM", "SWIMS", "AQUATIC" ] }, @@ -633,7 +623,6 @@ "harvest": "shellfish", "anger_triggers": [ "PLAYER_CLOSE", "HURT" ], "fear_triggers": [ "FIRE" ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 21, "into": "mon_crayfish_mega" }, "flags": [ "SMELLS", "HEARS", "SEES", "SWIMS", "GRABS", "ARTHROPOD_BLOOD" ] }, @@ -688,7 +677,6 @@ "special_attacks": [ [ "SHRIEK_ALERT", 6 ], [ "SHRIEK_STUN", 1 ] ], "anger_triggers": [ "PLAYER_CLOSE", "FRIEND_DIED", "FRIEND_ATTACKED", "HURT" ], "fear_triggers": [ "FIRE" ], - "death_function": [ "NORMAL" ], "flags": [ "SMELLS", "HEARS", "SEES", "SWIMS", "GRABS", "ARTHROPOD_BLOOD", "PATH_AVOID_DANGER_1" ] }, { @@ -717,7 +705,6 @@ "harvest": "mutant_fish", "reproduction": { "baby_egg": "egg_fish", "baby_count": 1, "baby_timer": 6 }, "baby_flags": [ "SPRING" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "SWIMS", "AQUATIC" ] }, { @@ -746,7 +733,6 @@ "harvest": "mutant_fish", "reproduction": { "baby_egg": "egg_fish", "baby_count": 2, "baby_timer": 150 }, "baby_flags": [ "AUTUMN" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "SWIMS", "AQUATIC" ] }, { @@ -777,7 +763,6 @@ "reproduction": { "baby_egg": "egg_fish", "baby_count": 2, "baby_timer": 19 }, "baby_flags": [ "SPRING", "SUMMER", "AUTUMN", "WINTER" ], "path_settings": { "max_dist": 5 }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "WARM", "AQUATIC" ] } ] diff --git a/data/json/monsters/fungus.json b/data/json/monsters/fungus.json index 1742844e2f5bc..6c254d7b1d206 100644 --- a/data/json/monsters/fungus.json +++ b/data/json/monsters/fungus.json @@ -28,7 +28,7 @@ "harvest": "zombie", "special_attacks": [ [ "FUNGUS", 100 ], [ "BOOMER", 20 ], [ "scratch", 20 ] ], "death_drops": "default_zombie_items", - "death_function": [ "FUNGUS", "NORMAL" ], + "death_function": { "effect": { "id": "death_fungus", "hit_self": true } }, "burn_into": "mon_zombie_scorched", "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "GROUP_BASH", "POISON", "NO_BREATHE", "PUSH_MON", "FILTHY" ] }, @@ -57,7 +57,7 @@ "luminance": 40, "harvest": "exempt", "special_attacks": [ [ "FUNGUS_HAZE", 25 ] ], - "death_function": [ "FUNGUS" ], + "death_function": { "corpse_type": "NO_CORPSE", "effect": { "id": "death_fungus", "hit_self": true } }, "flags": [ "HEARS", "GOODHEARING", "NOHEAD", "POISON", "IMMOBILE", "NO_BREATHE" ] }, { @@ -87,7 +87,7 @@ "bleed_rate": 0, "harvest": "exempt", "special_attacks": [ [ "FUNGUS_BRISTLE", 10 ] ], - "death_function": [ "DISINTEGRATE" ], + "death_function": { "message": "The %s disintegrates!", "corpse_type": "NO_CORPSE" }, "flags": [ "NOHEAD", "POISON", "NO_BREATHE", "IMMOBILE" ] }, { @@ -118,7 +118,7 @@ "bleed_rate": 0, "harvest": "exempt", "special_attacks": [ [ "FUNGUS_INJECT", 10 ] ], - "death_function": [ "FUNGUS" ], + "death_function": { "corpse_type": "NO_CORPSE", "effect": { "id": "death_fungus", "hit_self": true } }, "flags": [ "HEARS", "GOODHEARING", "NOHEAD", "POISON", "IMMOBILE", "NO_BREATHE", "HARDTOSHOOT" ] }, { @@ -148,7 +148,7 @@ "bleed_rate": 0, "harvest": "exempt", "special_attacks": [ [ "FUNGUS", 10 ] ], - "death_function": [ "DISINTEGRATE" ], + "death_function": { "message": "The %s disintegrates!", "corpse_type": "NO_CORPSE" }, "flags": [ "NOHEAD", "POISON", "NO_BREATHE", "IMMOBILE" ] }, { @@ -177,7 +177,7 @@ "bleed_rate": 0, "harvest": "fungaloid", "special_attacks": [ [ "FUNGUS", 30 ] ], - "death_function": [ "FUNGUS", "NORMAL" ], + "death_function": { "effect": { "id": "death_fungus", "hit_self": true } }, "upgrades": { "half_life": 14, "into": "mon_fungaloid_shambler" }, "flags": [ "STUMBLES", "POISON", "NO_BREATHE", "NOHEAD" ] }, @@ -236,7 +236,7 @@ "armor_cut": 10, "armor_bullet": 8, "special_attacks": [ [ "FUNGUS_SPROUT", 10 ] ], - "death_function": [ "FUNGUS", "NORMAL" ], + "death_function": { "effect": { "id": "death_fungus", "hit_self": true } }, "harvest": "fungaloid_mass", "flags": [ "NOHEAD", "POISON", "IMMOBILE", "NO_BREATHE", "QUEEN" ] }, @@ -263,7 +263,7 @@ "armor_bullet": 8, "luminance": 200, "special_attacks": [ [ "FUNGUS_BIG_BLOSSOM", 10 ] ], - "death_function": [ "FUNGUS", "NORMAL" ], + "death_function": { "effect": { "id": "death_fungus", "hit_self": true } }, "harvest": "fungaloid_mass", "flags": [ "NOHEAD", "POISON", "IMMOBILE", "NO_BREATHE", "QUEEN" ] }, @@ -294,7 +294,7 @@ "armor_bullet": 12, "special_attacks": [ [ "FUNGUS_FORTIFY", 10 ] ], "death_drops": "marloss_yellow_drops", - "death_function": [ "FUNGUS", "NORMAL" ], + "death_function": { "effect": { "id": "death_fungus", "hit_self": true } }, "harvest": "fungaloid_mass", "flags": [ "NOHEAD", "POISON", "IMMOBILE", "HARDTOSHOOT", "NO_BREATHE", "QUEEN" ] }, @@ -326,7 +326,6 @@ "bleed_rate": 0, "harvest": "fungaloid", "special_attacks": [ [ "FUNGUS_GROWTH", 10000 ] ], - "death_function": [ "NORMAL" ], "flags": [ "HEARS", "POISON", "NO_BREATHE", "NOHEAD" ] }, { @@ -351,7 +350,7 @@ "bleed_rate": 0, "harvest": "exempt", "special_attacks": [ [ "PLANT", 100 ] ], - "death_function": [ "DISINTEGRATE" ], + "death_function": { "message": "The %s disintegrates!", "corpse_type": "NO_CORPSE" }, "upgrades": { "half_life": 10, "into": "mon_fungaloid" }, "flags": [ "STUMBLES", "FLIES", "POISON", "NO_BREATHE", "NOHEAD", "NOGIB" ] }, @@ -384,7 +383,6 @@ "harvest": "zombie", "special_attacks": [ [ "FUNGUS", 200 ], { "type": "bite", "cooldown": 5 } ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", "SMELLS", "STUMBLES", "WARM", "BASHES", "GROUP_BASH", "POISON", "NO_BREATHE", "PUSH_MON", "FILTHY" ] }, @@ -418,7 +416,7 @@ "emit_fields": [ { "emit_id": "emit_fungal_leak", "delay": "1 s" } ], "special_attacks": [ [ "SUICIDE", 20 ], [ "scratch", 15 ] ], "death_drops": "default_zombie_items", - "death_function": [ "FUNGALBURST" ], + "death_function": { "effect": { "id": "death_fungalburst", "hit_self": true } }, "flags": [ "SEES", "STUMBLES", "WARM", "POISON", "NO_BREATHE", "FILTHY" ] }, { @@ -452,7 +450,7 @@ "harvest": "zombie", "emit_fields": [ { "emit_id": "emit_fungal_haze_plume", "delay": "1 s" } ], "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "scratch", 15 ] ], - "death_function": [ "FUNGUS" ], + "death_function": { "corpse_type": "NO_CORPSE", "effect": { "id": "death_fungus", "hit_self": true } }, "flags": [ "SEES", "STUMBLES", "WARM", "BASHES", "GROUP_BASH", "POISON", "HARDTOSHOOT", "NO_BREATHE", "PUSH_MON", "FILTHY" ] }, { @@ -487,7 +485,7 @@ "harvest": "mr_bones", "special_attacks": [ [ "SMASH", 20 ] ], "death_drops": "mon_zombie_hulk_death_drops", - "death_function": [ "FUNGUS" ], + "death_function": { "corpse_type": "NO_CORPSE", "effect": { "id": "death_fungus", "hit_self": true } }, "burn_into": "mon_zombie_fiend", "flags": [ "HEARS", @@ -536,7 +534,6 @@ "groups": [ [ "default_zombie_clothes", 100 ], [ "child_items", 65 ] ], "//": "cloth as any other zombie (always), additional items from child_items (sometimes)" }, - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_child_scorched", "flags": [ "SEES", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "GUILT", "NO_BREATHE", "FILTHY" ] }, @@ -571,7 +568,7 @@ "vision_night": 3, "harvest": "arachnid", "special_attacks": [ [ "FUNGUS", 200 ] ], - "death_function": [ "NORMAL", "FUNGUS" ], + "death_function": { "effect": { "id": "death_fungus", "hit_self": true } }, "flags": [ "SEES", "SMELLS", "POISON", "CLIMBS", "PATH_AVOID_FIRE", "PATH_AVOID_FALL" ] }, { @@ -605,7 +602,7 @@ "vision_night": 5, "harvest": "arachnid", "special_attacks": [ [ "FUNGAL_TRAIL", 3 ] ], - "death_function": [ "NORMAL", "FUNGUS" ], + "death_function": { "effect": { "id": "death_fungus", "hit_self": true } }, "flags": [ "SEES", "SMELLS", "VENOM", "WEBWALK", "CLIMBS", "PATH_AVOID_FIRE", "INSECTICIDEPROOF" ] } ] diff --git a/data/json/monsters/insect_spider.json b/data/json/monsters/insect_spider.json index d4524cc36f30d..e8c42d1eafd7e 100644 --- a/data/json/monsters/insect_spider.json +++ b/data/json/monsters/insect_spider.json @@ -24,7 +24,6 @@ "armor_bash": 6, "bleed_rate": 60, "harvest": "arachnid_acid", - "death_function": [ "NORMAL" ], "flags": [ "SMELLS", "HEARS", "GOODHEARING", "BASHES", "BORES", "POISON", "SUNDEATH", "ACIDPROOF", "ACIDTRAIL" ] }, { @@ -53,7 +52,11 @@ "armor_bullet": 6, "bleed_rate": 60, "harvest": "meatslug", - "death_function": [ "WORM" ], + "death_function": { + "message": "The %s splits in two!", + "effect": { "id": "death_halfworm", "hit_self": true }, + "corpse_type": "NO_CORPSE" + }, "flags": [ "DIGS", "HEARS", "POISON", "GOODHEARING", "BASHES", "DESTROYS" ] }, { @@ -79,7 +82,6 @@ "melee_cut": 0, "armor_bash": 2, "harvest": "mutant_meatslug", - "death_function": [ "NORMAL" ], "upgrades": { "age_grow": 10, "into": "mon_worm" }, "flags": [ "DIGS", "HEARS", "GOODHEARING" ] }, @@ -106,7 +108,11 @@ "melee_cut": 3, "armor_bash": 2, "harvest": "mutant_meatslug", - "death_function": [ "WORM" ], + "death_function": { + "message": "The %s splits in two!", + "effect": { "id": "death_halfworm", "hit_self": true }, + "corpse_type": "NO_CORPSE" + }, "upgrades": { "half_life": 20, "into": "mon_graboid" }, "flags": [ "DIGS", "HEARS", "GOODHEARING" ] }, @@ -164,7 +170,6 @@ "biosignature": { "biosig_item": "feces_roach", "biosig_timer": 3 }, "upgrades": { "age_grow": 7, "into": "mon_plague_vector" }, "anger_triggers": [ "FRIEND_ATTACKED", "PLAYER_WEAK" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 60 ] ], "flags": [ "SEES", "HEARS", "SMELLS", "CLIMBS", "POISON", "STUMBLES", "PATH_AVOID_FIRE" ] }, @@ -195,7 +200,6 @@ "vision_night": 3, "harvest": "arachnid_tainted", "upgrades": { "age_grow": 7, "into": "mon_skittering_plague" }, - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 120 ] ], "flags": [ "SEES", "HEARS", "SMELLS", "CLIMBS", "POISON", "LARVA", "STUMBLES", "FILTHY", "PATH_AVOID_FIRE" ] }, @@ -232,7 +236,6 @@ "baby_flags": [ "SPRING", "SUMMER", "AUTUMN" ], "biosignature": { "biosig_item": "feces_roach", "biosig_timer": 3 }, "anger_triggers": [ "FRIEND_ATTACKED", "PLAYER_WEAK" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 40 ] ], "flags": [ "SEES", "HEARS", "SMELLS", "CLIMBS", "POISON", "STUMBLES", "PATH_AVOID_FIRE" ] }, @@ -268,7 +271,6 @@ "baby_flags": [ "SPRING", "SUMMER", "AUTUMN" ], "biosignature": { "biosig_item": "feces_roach", "biosig_timer": 3 }, "upgrades": { "age_grow": 7, "into": "mon_pregnant_giant_cockroach" }, - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 60 ] ], "flags": [ "SEES", "HEARS", "SMELLS", "CLIMBS", "PATH_AVOID_FIRE" ] }, @@ -298,7 +300,6 @@ "vision_night": 3, "harvest": "arachnid", "upgrades": { "age_grow": 7, "into": "mon_giant_cockroach" }, - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 120 ] ], "flags": [ "SEES", "HEARS", "SMELLS", "LARVA", "CLIMBS", "PATH_AVOID_FIRE" ] }, @@ -334,7 +335,7 @@ "reproduction": { "baby_egg": "egg_roach", "baby_count": 3, "baby_timer": 7 }, "baby_flags": [ "SPRING", "SUMMER", "AUTUMN" ], "biosignature": { "biosig_item": "feces_roach", "biosig_timer": 3 }, - "death_function": [ "NORMAL", "PREG_ROACH" ], + "death_function": { "effect": { "id": "death_preg_roach", "hit_self": true } }, "special_attacks": [ [ "EAT_FOOD", 40 ] ], "flags": [ "SEES", "HEARS", "SMELLS", "CLIMBS", "PATH_AVOID_FIRE" ] }, @@ -383,7 +384,6 @@ "harvest": "arachnid_bee", "anger_triggers": [ "HURT", "FRIEND_DIED", "PLAYER_CLOSE" ], "fear_triggers": [ "FIRE" ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 21, "into": "mon_bee_mega" }, "flags": [ "SEES", "SMELLS", "FLIES", "STUMBLES", "SWARMS", "GROUP_MORALE", "CANPLAY", "PATH_AVOID_FIRE" ] }, @@ -485,7 +485,6 @@ "vision_night": 6, "anger_triggers": [ "STALK", "PLAYER_CLOSE" ], "harvest": "arachnid_centipede", - "death_function": [ "NORMAL" ], "upgrades": { "age_grow": 15, "into_group": "GROUP_CENTIPEDE_GIANT" }, "flags": [ "CLIMBS", "SEES", "SMELLS", "KEENNOSE", "HEARS", "GOODHEARING", "PATH_AVOID_FIRE" ] }, @@ -607,7 +606,6 @@ "harvest": "arachnid", "anger_triggers": [ "PLAYER_CLOSE" ], "fear_triggers": [ "HURT" ], - "death_function": [ "NORMAL" ], "flags": [ "AQUATIC", "SEES" ], "upgrades": { "age_grow": 21, "into": "mon_dragonfly_giant" } }, @@ -651,7 +649,6 @@ "harvest": "arachnid_flying", "anger_triggers": [ "PLAYER_WEAK", "STALK" ], "fear_triggers": [ "HURT", "FIRE" ], - "death_function": [ "NORMAL" ], "upgrades": { "age_grow": 40, "into": "mon_dragonfly_mega" }, "flags": [ "SWARMS", "HEARS", "SEES", "FLIES", "PATH_AVOID_FIRE" ] }, @@ -687,7 +684,6 @@ "vision_night": 5, "harvest": "arachnid_dragonfly_mega", "anger_triggers": [ "PLAYER_WEAK", "STALK" ], - "death_function": [ "NORMAL" ], "reproduction": { "baby_egg": "egg_dragonfly", "baby_count": 3, "baby_timer": 1 }, "baby_flags": [ "SPRING", "SUMMER", "AUTUMN" ], "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "SWIMS", "BASHES", "PUSH_MON", "PUSH_VEH" ] @@ -753,7 +749,6 @@ "vision_night": 5, "harvest": "arachnid_flying", "fear_triggers": [ "PLAYER_CLOSE", "HURT", "FIRE" ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 21, "into": "mon_fly_mega" }, "flags": [ "SEES", "SMELLS", "FLIES", "STUMBLES", "HIT_AND_RUN", "CANPLAY", "PATH_AVOID_FIRE" ] }, @@ -810,7 +805,6 @@ "vision_night": 5, "harvest": "arachnid_flying", "fear_triggers": [ "HURT", "FIRE" ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 21, "into": "mon_mosquito_mega" }, "flags": [ "SEES", "SMELLS", "HEARS", "STUMBLES", "VENOM", "FLIES", "HIT_AND_RUN", "PATH_AVOID_FIRE" ] }, @@ -870,7 +864,6 @@ "vision_night": 5, "harvest": "arachnid", "anger_triggers": [ "STALK", "PLAYER_WEAK", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "fungalize_into": "mon_spider_fungus", "upgrades": { "half_life": 21, "into": "mon_spider_cellar_mega" }, "flags": [ "SEES", "SMELLS", "HEARS", "VENOM", "WEBWALK", "CLIMBS", "HARDTOSHOOT", "PUSH_MON", "PATH_AVOID_FIRE" ], @@ -920,7 +913,6 @@ "vision_night": 5, "harvest": "arachnid", "anger_triggers": [ "STALK", "PLAYER_WEAK", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "upgrades": { "age_grow": 40, "into": "mon_spider_cellar_giant" }, "flags": [ "SEES", "SMELLS", "HEARS", "WEBWALK", "CLIMBS", "HARDTOSHOOT", "PATH_AVOID_FIRE" ] }, @@ -967,7 +959,6 @@ "harvest": "arachnid", "special_attacks": [ { "type": "leap", "cooldown": 2, "max_range": 5, "allow_no_target": true } ], "anger_triggers": [ "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "fungalize_into": "mon_spider_fungus", "upgrades": { "half_life": 21, "into": "mon_spider_jumping_mega" }, "flags": [ "SEES", "SMELLS", "HEARS", "HIT_AND_RUN", "CLIMBS", "PATH_AVOID_DANGER_1" ] @@ -982,7 +973,11 @@ "volume": "625 L", "weight": "815 kg", "melee_dice": 2, - "death_function": [ "EXPLODE" ], + "death_function": { + "effect": { "id": "death_explosion_mon_spider_jumping_mega", "hit_self": true }, + "corpse_type": "NO_CORPSE", + "message": "The %s explodes!" + }, "extend": { "flags": [ "DESTROYS", "PUSH_MON", "PUSH_VEH", "FLAMMABLE" ] } }, { @@ -1025,7 +1020,6 @@ "vision_day": 5, "vision_night": 5, "harvest": "arachnid", - "death_function": [ "NORMAL" ], "fungalize_into": "mon_spider_fungus", "upgrades": { "half_life": 21, "into": "mon_spider_trapdoor_mega" }, "flags": [ "SEES", "SMELLS", "HEARS", "VENOM", "GRABS", "CAN_DIG", "WEBWALK", "CLIMBS", "PATH_AVOID_FIRE" ] @@ -1085,7 +1079,6 @@ "vision_day": 5, "vision_night": 5, "harvest": "arachnid", - "death_function": [ "NORMAL" ], "fungalize_into": "mon_spider_fungus", "upgrades": { "half_life": 21, "into": "mon_spider_web_mega" }, "flags": [ "SEES", "SMELLS", "HEARS", "WEBWALK", "CLIMBS", "PATH_AVOID_FIRE", "PATH_AVOID_FALL" ] @@ -1131,7 +1124,6 @@ "vision_day": 5, "vision_night": 5, "harvest": "arachnid", - "death_function": [ "NORMAL" ], "upgrades": { "age_grow": 40, "into": "mon_spider_web" }, "flags": [ "SEES", "SMELLS", "HEARS", "WEBWALK", "STUMBLES", "CLIMBS", "PATH_AVOID_FIRE" ] }, @@ -1176,7 +1168,6 @@ "vision_night": 5, "harvest": "arachnid", "anger_triggers": [ "PLAYER_WEAK", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "fungalize_into": "mon_spider_fungus", "upgrades": { "half_life": 21, "into": "mon_spider_widow_mega" }, "flags": [ "SEES", "SMELLS", "HEARS", "BADVENOM", "WEBWALK", "CLIMBS", "PATH_AVOID_FIRE" ] @@ -1224,7 +1215,6 @@ "vision_night": 5, "harvest": "arachnid", "anger_triggers": [ "PLAYER_WEAK", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "upgrades": { "age_grow": 40, "into": "mon_spider_widow_giant" }, "flags": [ "SEES", "SMELLS", "HEARS", "VENOM", "WEBWALK", "CLIMBS", "PATH_AVOID_FIRE" ] }, @@ -1271,7 +1261,6 @@ "vision_night": 5, "harvest": "arachnid", "anger_triggers": [ "STALK", "PLAYER_WEAK", "HURT", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "fungalize_into": "mon_spider_fungus", "upgrades": { "half_life": 21, "into": "mon_spider_wolf_mega" }, "flags": [ "SEES", "SMELLS", "HEARS", "CLIMBS", "PATH_AVOID_FIRE", "PATH_AVOID_FALL" ] @@ -1373,7 +1362,6 @@ "harvest": "arachnid_wasp", "anger_triggers": [ "FRIEND_ATTACKED", "PLAYER_CLOSE", "PLAYER_WEAK", "HOSTILE_SEEN" ], "fear_triggers": [ "HURT", "FIRE" ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 30, "into": "mon_wasp" }, "flags": [ "SEES", "SMELLS", "HEARS", "FLIES", "SWARMS", "GROUP_MORALE", "CANPLAY", "PATH_AVOID_FIRE", "HARDTOSHOOT" ] }, @@ -1452,7 +1440,6 @@ "harvest": "arachnid_wasp", "anger_triggers": [ "FRIEND_ATTACKED", "PLAYER_CLOSE", "PLAYER_WEAK", "HOSTILE_SEEN" ], "fear_triggers": [ "HURT", "FIRE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "FLIES", "SWARMS", "GROUP_MORALE", "CANPLAY", "HARDTOSHOOT", "PATH_AVOID_FIRE" ] }, { @@ -1539,7 +1526,6 @@ "dodge": 1, "harvest": "arachnid", "upgrades": { "age_grow": 21, "into": "mon_dermatik" }, - "death_function": [ "NORMAL" ], "flags": [ "HEARS", "SMELLS", "POISON", "CAN_DIG", "LARVA" ] }, { @@ -1572,7 +1558,6 @@ "vision_day": 13, "anger_triggers": [ "FRIEND_ATTACKED", "PLAYER_WEAK" ], "fear_triggers": [ "HURT", "FIRE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "FLIES", "PATH_AVOID_FIRE", "CANPLAY" ] }, { @@ -1615,7 +1600,6 @@ } ], "reproduction": { "baby_monster": "mon_dermatik_larva", "baby_count": 2, "baby_timer": 30 }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "IMMOBILE", "PACIFIST" ] }, { @@ -1683,7 +1667,6 @@ "harvest": "arachnid", "upgrades": { "age_grow": 14, "into": "mon_ant_soldier" }, "anger_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT", "PLAYER_WEAK" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 30 ] ], "fungalize_into": "mon_ant_fungus", "flags": [ "SEES", "HEARS", "SMELLS", "CLIMBS", "PATH_AVOID_FIRE", "PATH_AVOID_FALL" ] @@ -1729,7 +1712,7 @@ "upgrades": { "age_grow": 14, "into": "mon_ant_acid_soldier" }, "special_attacks": [ [ "ACID", 23 ], [ "EAT_FOOD", 30 ] ], "anger_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT", "PLAYER_CLOSE" ], - "death_function": [ "ACID", "NORMAL" ], + "death_function": { "message": "The %s's body leaks acid.", "effect": { "id": "death_acid", "hit_self": true } }, "harvest": "arachnid_acid", "flags": [ "ACIDPROOF", "CLIMBS", "HEARS", "POISON", "SEES", "SMELLS", "PATH_AVOID_FIRE", "PATH_AVOID_FALL" ] }, @@ -1755,7 +1738,7 @@ "melee_dice_sides": 3, "melee_cut": 0, "upgrades": { "age_grow": 3, "into": "mon_ant_acid" }, - "death_function": [ "ACID", "NORMAL" ], + "death_function": { "message": "The %s's body leaks acid.", "effect": { "id": "death_acid", "hit_self": true } }, "harvest": "arachnid_acid", "flags": [ "ACIDPROOF", "LARVA", "POISON", "SMELLS" ] }, @@ -1787,7 +1770,6 @@ "armor_bullet": 13, "special_attacks": [ [ "ANTQUEEN", 1 ] ], "anger_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "harvest": "arachnid_acid_queen", "flags": [ "ACIDPROOF", "CLIMBS", "HEARS", "QUEEN", "SEES", "SMELLS", "PATH_AVOID_FIRE", "PATH_AVOID_FALL" ] }, @@ -1822,7 +1804,7 @@ "vision_night": 5, "special_attacks": [ [ "ACID", 15 ] ], "anger_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT", "PLAYER_CLOSE" ], - "death_function": [ "ACID", "NORMAL" ], + "death_function": { "message": "The %s's body leaks acid.", "effect": { "id": "death_acid", "hit_self": true } }, "harvest": "arachnid_acid", "flags": [ "ACIDPROOF", "SHORTACIDTRAIL", "CLIMBS", "HEARS", "POISON", "SEES", "SMELLS", "PATH_AVOID_FIRE", "PATH_AVOID_FALL" ] }, @@ -1849,7 +1831,6 @@ "melee_cut": 0, "harvest": "arachnid", "upgrades": { "age_grow": 3, "into": "mon_ant" }, - "death_function": [ "NORMAL" ], "flags": [ "SMELLS", "LARVA" ] }, { @@ -1879,7 +1860,6 @@ "harvest": "arachnid", "special_attacks": [ [ "ANTQUEEN", 1 ] ], "anger_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT" ], - "death_function": [ "NORMAL" ], "fungalize_into": "mon_ant_fungus", "flags": [ "SMELLS", "QUEEN", "CLIMBS", "PATH_AVOID_FIRE", "PATH_AVOID_FALL" ] }, @@ -1913,7 +1893,6 @@ "vision_night": 5, "harvest": "arachnid", "anger_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "fungalize_into": "mon_ant_fungus", "upgrades": { "half_life": 21, "into": "mon_ant_soldier_mega" }, "flags": [ "SEES", "HEARS", "SMELLS", "CLIMBS", "PATH_AVOID_FIRE", "PATH_AVOID_FALL" ] @@ -1975,7 +1954,6 @@ "biosignature": { "biosig_item": "feces_roach", "biosig_timer": 3 }, "anger_triggers": [ "FRIEND_ATTACKED" ], "fear_triggers": [ "HURT", "FIRE" ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 21, "into": "mon_locust_mega" }, "special_attacks": [ { "type": "leap", "cooldown": 2, "max_range": 8, "allow_no_target": true }, [ "EAT_CROP", 60 ] ], "flags": [ "SEES", "HEARS", "SMELLS", "CLIMBS", "STUMBLES", "PATH_AVOID_FIRE" ] @@ -2018,7 +1996,6 @@ "vision_day": 10, "harvest": "arachnid", "upgrades": { "age_grow": 10, "into": "mon_locust" }, - "death_function": [ "NORMAL" ], "special_attacks": [ { "type": "leap", "cooldown": 4, "max_range": 4, "allow_no_target": true }, [ "EAT_CROP", 120 ] ], "fear_triggers": [ "HURT", "FIRE" ], "flags": [ "SEES", "HEARS", "SMELLS", "CLIMBS", "LARVA", "STUMBLES", "PATH_AVOID_FIRE" ] diff --git a/data/json/monsters/jabberwock.json b/data/json/monsters/jabberwock.json index 02e28e71aad1f..d9d8dd46894d4 100644 --- a/data/json/monsters/jabberwock.json +++ b/data/json/monsters/jabberwock.json @@ -26,7 +26,6 @@ "vision_day": 50, "vision_night": 3, "special_attacks": [ [ "FLESH_GOLEM", 10 ], [ "ABSORB_MEAT", 10 ] ], - "death_function": [ "NORMAL" ], "harvest": "zombie", "upgrades": { "half_life": 15, "into": "mon_flesh_golem" }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "ATTACKMON", "POISON" ] @@ -58,7 +57,6 @@ "vision_day": 50, "vision_night": 3, "special_attacks": [ [ "FLESH_GOLEM", 8 ], [ "ABSORB_MEAT", 1 ] ], - "death_function": [ "NORMAL" ], "harvest": "flesh_golem", "upgrades": { "half_life": 15, "into": "mon_jabberwock" }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "ATTACKMON", "POISON" ] @@ -91,7 +89,6 @@ "vision_day": 50, "vision_night": 3, "special_attacks": [ [ "FLESH_GOLEM", 5 ] ], - "death_function": [ "JABBERWOCKY" ], "harvest": "jabberwock", "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "DESTROYS", "ATTACKMON", "POISON" ] } diff --git a/data/json/monsters/mammal.json b/data/json/monsters/mammal.json index ffefcfb1b68d0..9ebc7fdee0804 100644 --- a/data/json/monsters/mammal.json +++ b/data/json/monsters/mammal.json @@ -37,7 +37,6 @@ "vision_night": 20, "special_attacks": [ { "type": "bite", "cooldown": 15 } ], "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "GOODHEARING", "WARM", "FLIES", "ANIMAL", "PATH_AVOID_DANGER_1" ] }, { @@ -91,7 +90,6 @@ "anger_triggers": [ "HURT", "PLAYER_NEAR_BABY" ], "fear_triggers": [ "SOUND" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "zombify_into": "mon_zombear", "harvest": "mammal_large_fur", "reproduction": { "baby_monster": "mon_bear_cub", "baby_count": 1, "baby_timer": 700 }, @@ -125,7 +123,6 @@ "harvest": "mammal_small_fur", "anger_triggers": [ "PLAYER_CLOSE", "HURT" ], "fear_triggers": [ "SOUND" ], - "death_function": [ "NORMAL" ], "zombify_into": "mon_zombeaver", "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "SWIMS", "WARM" ] }, @@ -158,7 +155,6 @@ "path_settings": { "max_dist": 10 }, "anger_triggers": [ "PLAYER_WEAK" ], "fear_triggers": [ "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 120 ] ], "flags": [ "SEES", "SMELLS", "HEARS", "WARM", "SWIMS", "ANIMAL", "STUMBLES", "PATH_AVOID_DANGER_1" ] }, @@ -190,7 +186,6 @@ "harvest": "mammal_tiny", "path_settings": { "max_dist": 10 }, "fear_triggers": [ "PLAYER_CLOSE", "SOUND" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 120 ] ], "flags": [ "SEES", "SMELLS", "HEARS", "KEENNOSE", "WARM", "SWIMS", "ANIMAL", "PATH_AVOID_DANGER_1" ] }, @@ -222,7 +217,6 @@ "path_settings": { "max_dist": 10 }, "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "upgrades": { "age_grow": 38, "into": "mon_boar_wild" }, "biosignature": { "biosig_item": "feces_manure", "biosig_timer": 7 }, "special_attacks": [ [ "EAT_FOOD", 40 ] ], @@ -262,7 +256,6 @@ "anger_triggers": [ "PLAYER_WEAK", "FRIEND_ATTACKED" ], "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "zombify_into": "mon_zpig_brute", "special_attacks": [ [ "EAT_FOOD", 20 ] ], "flags": [ "SEES", "HEARS", "SMELLS", "PET_MOUNTABLE", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "KEENNOSE" ] @@ -293,7 +286,6 @@ "vision_night": 20, "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "harvest": "mammal_small_fur", "flags": [ "SEES", "HEARS", "GOODHEARING", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "HIT_AND_RUN" ] }, @@ -318,7 +310,6 @@ "special_attacks": [ [ "scratch", 10 ] ], "fear_triggers": [ "SOUND", "PLAYER_CLOSE", "FRIEND_ATTACKED" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "harvest": "mammal_tiny", "flags": [ "SEES", @@ -361,7 +352,6 @@ "special_attacks": [ [ "scratch", 10 ] ], "fear_triggers": [ "SOUND", "PLAYER_CLOSE", "FRIEND_ATTACKED" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "harvest": "mammal_tiny", "reproduction": { "baby_monster": "mon_cat_kitten", "baby_count": 4, "baby_timer": 60 }, "flags": [ @@ -572,7 +562,6 @@ "dodge": 4, "harvest": "mammal_tiny", "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "WARM", "ANIMAL", "PATH_AVOID_DANGER_1" ] }, { @@ -604,7 +593,6 @@ "anger_triggers": [ "STALK", "PLAYER_WEAK", "HURT", "PLAYER_CLOSE", "FRIEND_ATTACKED" ], "fear_triggers": [ "SOUND" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "zombify_into": "mon_zougar", "harvest": "mammal_fur", "flags": [ "SEES", "HEARS", "GOODHEARING", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "HIT_AND_RUN", "KEENNOSE" ] @@ -655,7 +643,6 @@ "fear_triggers": [ "PLAYER_CLOSE" ], "placate_triggers": [ "PLAYER_WEAK" ], "death_drops": { "subtype": "collection", "groups": [ [ "cow", 25 ] ], "//": "25% chance of an item from group cow" }, - "death_function": [ "NORMAL" ], "harvest": "mammal_large_leather", "upgrades": { "age_grow": 180, "into": "mon_cow" }, "biosignature": { "biosig_item": "feces_cow", "biosig_timer": 7 }, @@ -692,7 +679,6 @@ "fear_triggers": [ "PLAYER_CLOSE" ], "placate_triggers": [ "PLAYER_WEAK" ], "death_drops": { "subtype": "collection", "groups": [ [ "cow", 25 ] ], "//": "25% chance of an item from group cow" }, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zow", "harvest": "mammal_large_leather", "reproduction": { "baby_monster": "mon_cow_calf", "baby_count": 1, "baby_timer": 343 }, @@ -740,7 +726,6 @@ "anger_triggers": [ "STALK", "FRIEND_ATTACKED", "PLAYER_WEAK", "HURT" ], "fear_triggers": [ "SOUND" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "harvest": "mammal_fur", "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "HIT_AND_RUN", "KEENNOSE" ] }, @@ -773,7 +758,6 @@ "anger_triggers": [ "FRIEND_ATTACKED", "PLAYER_WEAK" ], "fear_triggers": [ "SOUND" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "KEENNOSE" ] }, { @@ -804,7 +788,6 @@ "harvest": "mammal_small_leather", "path_settings": { "max_dist": 10 }, "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "upgrades": { "age_grow": 330, "into": "mon_deer" }, "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM" ] }, @@ -835,7 +818,6 @@ "harvest": "mammal_large_leather", "path_settings": { "max_dist": 10 }, "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "zombify_into": "mon_zeer", "reproduction": { "baby_monster": "mon_deer_fawn", "baby_count": 1, "baby_timer": 330 }, "//": " 201 days gestation period. The fawn will stay with its mother for approximately one year, suckling for three to four months.", @@ -876,7 +858,6 @@ "biosignature": { "biosig_item": "feces_dog", "biosig_timer": 6 }, "anger_triggers": [ "HURT", "FRIEND_ATTACKED", "FRIEND_DIED" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 100 ], [ "PARROT_AT_DANGER", 0 ] ], "flags": [ "ANIMAL", @@ -1035,7 +1016,6 @@ "upgrades": { "age_grow": 42, "into": "mon_dog_pitbullmix" }, "biosignature": { "biosig_item": "feces_dog", "biosig_timer": 6 }, "fear_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 100 ] ], "flags": [ "ANIMAL", "DOGFOOD", "HEARS", "KEENNOSE", "PATH_AVOID_DANGER_1", "SEES", "SMELLS", "WARM" ] }, @@ -1101,7 +1081,6 @@ "upgrades": { "age_grow": 42, "into": "mon_dog_beagle" }, "biosignature": { "biosig_item": "feces_dog", "biosig_timer": 6 }, "fear_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 100 ] ], "flags": [ "ANIMAL", "DOGFOOD", "GROUP_MORALE", "HEARS", "KEENNOSE", "PATH_AVOID_DANGER_1", "SEES", "SMELLS", "SWARMS", "WARM" ] }, @@ -1164,7 +1143,6 @@ "upgrades": { "age_grow": 42, "into": "mon_dog_bcollie" }, "biosignature": { "biosig_item": "feces_dog", "biosig_timer": 6 }, "fear_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 100 ] ], "flags": [ "ANIMAL", "DOGFOOD", "HEARS", "KEENNOSE", "PATH_AVOID_DANGER_1", "SEES", "SMELLS", "WARM" ] }, @@ -1217,7 +1195,6 @@ "upgrades": { "age_grow": 42, "into": "mon_dog_boxer" }, "biosignature": { "biosig_item": "feces_dog", "biosig_timer": 6 }, "fear_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 100 ] ], "flags": [ "ANIMAL", @@ -1295,7 +1272,6 @@ "upgrades": { "age_grow": 42, "into": "mon_dog_chihuahua" }, "biosignature": { "biosig_item": "feces_dog", "biosig_timer": 6 }, "fear_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 100 ] ], "flags": [ "ANIMAL", "DOGFOOD", "HARDTOSHOOT", "HEARS", "KEENNOSE", "PATH_AVOID_DANGER_1", "SEES", "SMELLS", "WARM" ] }, @@ -1361,7 +1337,6 @@ "upgrades": { "age_grow": 42, "into": "mon_dog_dachshund" }, "biosignature": { "biosig_item": "feces_dog", "biosig_timer": 6 }, "fear_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 100 ] ], "flags": [ "ANIMAL", "DOGFOOD", "HARDTOSHOOT", "HEARS", "KEENNOSE", "PATH_AVOID_DANGER_1", "SEES", "SMELLS", "STUMBLES", "WARM" ] }, @@ -1412,7 +1387,6 @@ "upgrades": { "age_grow": 42, "into": "mon_dog_gshepherd" }, "biosignature": { "biosig_item": "feces_dog", "biosig_timer": 6 }, "fear_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 100 ] ], "flags": [ "ANIMAL", "DOGFOOD", "HEARS", "KEENNOSE", "PATH_AVOID_DANGER_1", "SEES", "SMELLS", "WARM" ] }, @@ -1479,7 +1453,6 @@ "upgrades": { "age_grow": 42, "into": "mon_dog_gpyrenees" }, "biosignature": { "biosig_item": "feces_dog", "biosig_timer": 6 }, "fear_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 100 ] ], "flags": [ "ANIMAL", "DOGFOOD", "HEARS", "KEENNOSE", "PATH_AVOID_DANGER_1", "SEES", "SMELLS", "WARM" ] }, @@ -1546,7 +1519,6 @@ "upgrades": { "age_grow": 42, "into": "mon_dog_rottweiler" }, "biosignature": { "biosig_item": "feces_dog", "biosig_timer": 6 }, "fear_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 100 ] ], "flags": [ "ANIMAL", "DOGFOOD", "HEARS", "KEENNOSE", "PATH_AVOID_DANGER_1", "SEES", "SMELLS", "WARM" ] }, @@ -1611,7 +1583,6 @@ "upgrades": { "age_grow": 42, "into": "mon_dog_auscattle" }, "biosignature": { "biosig_item": "feces_dog", "biosig_timer": 6 }, "fear_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 100 ] ], "flags": [ "ANIMAL", "DOGFOOD", "HEARS", "KEENNOSE", "PATH_AVOID_DANGER_1", "SEES", "SMELLS", "WARM" ] }, @@ -1667,7 +1638,6 @@ "anger_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED" ], "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "HIT_AND_RUN", "KEENNOSE" ] }, { @@ -1698,7 +1668,6 @@ "anger_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED" ], "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "HIT_AND_RUN", "KEENNOSE" ] }, { @@ -1725,7 +1694,6 @@ "dodge": 4, "harvest": "mammal_small_fur", "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "GOODHEARING", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM" ] }, { @@ -1750,7 +1718,6 @@ "dodge": 6, "harvest": "mammal_small_fur", "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "GOODHEARING", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM" ] }, { @@ -1779,7 +1746,6 @@ "anger_triggers": [ "FRIEND_ATTACKED" ], "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], "placate_triggers": [ "PLAYER_WEAK" ], - "death_function": [ "NORMAL" ], "harvest": "mammal_large_leather", "biosignature": { "biosig_item": "feces_manure", "biosig_timer": 2 }, "special_attacks": [ [ "EAT_CROP", 60 ] ], @@ -1819,7 +1785,6 @@ "dodge": 2, "harvest": "mammal_tiny", "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "WARM", "SWIMS", "ANIMAL", "PATH_AVOID_DANGER_1" ] }, { @@ -1848,7 +1813,6 @@ "anger_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED" ], "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "HIT_AND_RUN", "KEENNOSE" ] }, { @@ -1880,7 +1844,6 @@ "vision_night": 7, "path_settings": { "max_dist": 10 }, "anger_triggers": [ "HURT", "MATING_SEASON" ], - "death_function": [ "NORMAL" ], "zombify_into": "mon_zoose", "baby_flags": [ "AUTUMN" ], "//": "Baby moose don't actually exist (yet), but autumn is their mating season so baby_flags is defined so that they get angry then", @@ -1914,7 +1877,6 @@ "dodge": 2, "harvest": "mammal_small_fur", "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "WARM", "SWIMS", "ANIMAL", "PATH_AVOID_DANGER_1" ] }, { @@ -1950,7 +1912,6 @@ "special_attacks": [ [ "SHRIEK_ALERT", 10 ], [ "SHRIEK_STUN", 1 ], { "type": "bite", "cooldown": 6 }, [ "impale", 10 ] ], "anger_triggers": [ "HURT", "SOUND", "STALK" ], "fear_triggers": [ "FIRE" ], - "death_function": [ "NORMAL" ], "regenerates": 10, "regen_morale": true, "flags": [ "PUSH_MON", "BORES", "CAN_DIG", "HEARS", "KEENNOSE", "PATH_AVOID_DANGER_1", "SMELLS", "WARM" ], @@ -1982,7 +1943,6 @@ "harvest": "mammal_small_fur", "anger_triggers": [ "FRIEND_ATTACKED", "HURT" ], "fear_triggers": [ "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "CLIMBS", "PATH_AVOID_DANGER_1", "WARM", "KEENNOSE" ] }, { @@ -2009,7 +1969,6 @@ "dodge": 4, "harvest": "mammal_small_fur", "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "SWIMS", "WARM" ] }, { @@ -2040,7 +1999,6 @@ "path_settings": { "max_dist": 10 }, "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "upgrades": { "age_grow": 38, "into": "mon_pig" }, "biosignature": { "biosig_item": "feces_manure", "biosig_timer": 7 }, "special_attacks": [ [ "EAT_FOOD", 40 ] ], @@ -2078,7 +2036,6 @@ "anger_triggers": [ "PLAYER_WEAK", "FRIEND_ATTACKED" ], "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "zombify_into": "mon_zombie_pig", "special_attacks": [ [ "EAT_FOOD", 20 ] ], "flags": [ "SEES", "HEARS", "SMELLS", "PET_MOUNTABLE", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "KEENNOSE" ] @@ -2106,7 +2063,6 @@ "reproduction": { "baby_monster": "mon_rabbit", "baby_count": 3, "baby_timer": 55 }, "harvest": "mammal_small_fur", "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "CATTLEFODDER", "PET_WONT_FOLLOW", "WARM" ] }, { @@ -2135,7 +2091,6 @@ "harvest": "mammal_small_fur", "vision_night": 5, "anger_triggers": [ "FRIEND_ATTACKED", "HURT" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "CLIMBS", "PATH_AVOID_DANGER_1", "WARM", "KEENNOSE" ] }, { @@ -2161,7 +2116,7 @@ "melee_cut": 1, "harvest": "mammal_tiny", "special_attacks": [ [ "RATKING", 3 ] ], - "death_function": [ "RATKING" ] + "death_function": { "effect": { "id": "death_ratking" }, "message": "Rats suddenly swarm into view." } }, { "id": "mon_sewer_rat", @@ -2191,7 +2146,6 @@ "harvest": "mammal_tiny", "path_settings": { "max_dist": 10 }, "anger_triggers": [ "PLAYER_WEAK", "FRIEND_ATTACKED", "FRIEND_DIED" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "WARM", "SWIMS", "ANIMAL", "PATH_AVOID_DANGER_1", "STUMBLES" ] }, { @@ -2220,7 +2174,6 @@ "harvest": "mammal_small_wool", "fear_triggers": [ "SOUND", "PLAYER_CLOSE", "FRIEND_ATTACKED" ], "placate_triggers": [ "PLAYER_WEAK" ], - "death_function": [ "NORMAL" ], "upgrades": { "age_grow": 240, "into": "mon_sheep" }, "//": "Puberty reached in 6-9 months.", "biosignature": { "biosig_item": "feces_manure", "biosig_timer": 7 }, @@ -2257,7 +2210,6 @@ "biosignature": { "biosig_item": "feces_manure", "biosig_timer": 3 }, "fear_triggers": [ "SOUND", "PLAYER_CLOSE", "FRIEND_ATTACKED" ], "placate_triggers": [ "PLAYER_WEAK" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_CROP", 120 ] ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "CATTLEFODDER", "PET_WONT_FOLLOW", "MILKABLE" ] }, @@ -2285,7 +2237,6 @@ "dodge": 4, "harvest": "mammal_tiny", "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "STUMBLES", "WARM" ] }, { @@ -2312,7 +2263,6 @@ "dodge": 3, "harvest": "mammal_tiny", "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "STUMBLES", "WARM" ] }, { @@ -2339,7 +2289,6 @@ "vision_night": 5, "harvest": "mammal_tiny", "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "SWIMS", "WARM" ] }, { @@ -2370,7 +2319,6 @@ "path_settings": { "max_dist": 10 }, "anger_triggers": [ "STALK", "FRIEND_ATTACKED", "FRIEND_DIED", "PLAYER_WEAK", "PLAYER_CLOSE" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "zombify_into": "mon_zolf", "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "KEENNOSE" ] }, @@ -2402,7 +2350,6 @@ "path_settings": { "max_dist": 14 }, "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], "anger_triggers": [ "HURT", "MATING_SEASON" ], - "death_function": [ "NORMAL" ], "zombify_into": "mon_zeindeer", "reproduction": { "baby_monster": "mon_reindeer_fawn", "baby_count": 5, "baby_timer": 340 }, "biosignature": { "biosig_item": "feces_manure", "biosig_timer": 12 }, diff --git a/data/json/monsters/marloss.json b/data/json/monsters/marloss.json index 8426ec1a6fcc3..38f533a30931c 100644 --- a/data/json/monsters/marloss.json +++ b/data/json/monsters/marloss.json @@ -27,7 +27,6 @@ "vision_night": 3, "special_attacks": [ [ "scratch", 15 ] ], "death_drops": "marloss_zealot_death_drops", - "death_function": [ "NORMAL" ], "anger_triggers": [ "FRIEND_DIED", "FRIEND_ATTACKED", "HURT" ], "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "BASHES", "GROUP_BASH", "HUMAN", "POISON" ] }, @@ -59,7 +58,6 @@ "vision_night": 3, "special_attacks": [ [ "scratch", 15 ] ], "death_drops": "marloss_zealot_death_drops", - "death_function": [ "NORMAL" ], "anger_triggers": [ "FRIEND_DIED", "FRIEND_ATTACKED", "HURT" ], "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "BASHES", "GROUP_BASH", "HUMAN", "POISON" ] } diff --git a/data/json/monsters/mechsuits.json b/data/json/monsters/mechsuits.json index 89fb00a8ca0b9..84cb229ad141d 100644 --- a/data/json/monsters/mechsuits.json +++ b/data/json/monsters/mechsuits.json @@ -28,7 +28,7 @@ "mech_battery": "huge_atomic_battery_cell", "mech_weapon": "recon_mech_laser", "revert_to_itype": "broken_mech_recon", - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "death_drops": { "groups": [ [ "robots", 20 ] ] }, "flags": [ "SEES", @@ -74,7 +74,7 @@ "mech_battery": "huge_atomic_battery_cell", "mech_weapon": "gatling_mech_laser", "revert_to_itype": "broken_mech_combat", - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "death_drops": { "groups": [ [ "robots", 20 ] ] }, "flags": [ "SEES", @@ -121,7 +121,7 @@ "attack_cost": 150, "revert_to_itype": "broken_mech_lifter", "special_attacks": [ [ "SMASH", 40 ] ], - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "death_drops": { "groups": [ [ "robots", 20 ] ] }, "flags": [ "SEES", diff --git a/data/json/monsters/mi-go.json b/data/json/monsters/mi-go.json index 62357c24b73a1..41a4d1bc4f187 100644 --- a/data/json/monsters/mi-go.json +++ b/data/json/monsters/mi-go.json @@ -34,7 +34,6 @@ [ "PARROT", 800 ], { "id": "scratch", "damage_max_instance": [ { "damage_type": "cut", "amount": 23, "armor_multiplier": 0.8 } ] } ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", @@ -86,7 +85,6 @@ { "id": "scratch", "damage_max_instance": [ { "damage_type": "cut", "amount": 23, "armor_multiplier": 0.8 } ] }, { "type": "spell", "spell_data": { "id": "mi-go_slaver_beam", "min_level": 3 }, "cooldown": 100 } ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", @@ -137,7 +135,6 @@ [ "PARROT", 800 ], { "id": "scratch", "damage_max_instance": [ { "damage_type": "cut", "amount": 12, "armor_multiplier": 0.4 } ] } ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", @@ -192,7 +189,6 @@ { "id": "scratch", "damage_max_instance": [ { "damage_type": "cut", "amount": 35, "armor_multiplier": 0.7 } ] }, { "type": "spell", "spell_data": { "id": "mi-go_slaver_beam", "min_level": 1 }, "cooldown": 100 } ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", @@ -246,7 +242,6 @@ { "id": "scratch", "damage_max_instance": [ { "damage_type": "cut", "amount": 30, "armor_multiplier": 0.7 } ] }, { "type": "spell", "spell_data": { "id": "mi-go_slaver_beam", "min_level": 2 }, "cooldown": 100 } ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", @@ -307,7 +302,6 @@ "ranges": [ [ 2, 30, "DEFAULT" ] ] } ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", diff --git a/data/json/monsters/misc.json b/data/json/monsters/misc.json index 14914110b76c6..bed0cc0c3df61 100644 --- a/data/json/monsters/misc.json +++ b/data/json/monsters/misc.json @@ -18,7 +18,7 @@ "melee_cut": 0, "vision_day": 1, "harvest": "exempt", - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "regenerates": 50, "flags": [ "IMMOBILE", "NOT_HALLUCINATION", "FILTHY" ] }, @@ -44,7 +44,7 @@ "vision_day": 50, "vision_night": 50, "harvest": "exempt", - "death_function": [ "DISINTEGRATE" ], + "death_function": { "message": "The %s disintegrates!", "corpse_type": "NO_CORPSE" }, "death_drops": "mon_dragon_dummy_drops", "flags": [ "SEES" ] }, @@ -68,7 +68,7 @@ "armor_bullet": 2, "harvest": "exempt", "special_attacks": [ [ "GENERATOR", 1 ] ], - "death_function": [ "GAMEOVER" ], + "death_function": { "effect": { "id": "death_gameover", "hit_self": true } }, "flags": [ "NOHEAD", "ACIDPROOF", "IMMOBILE" ] }, { @@ -92,7 +92,7 @@ "melee_cut": 0, "harvest": "exempt", "special_attacks": [ [ "DISAPPEAR", 20 ] ], - "death_function": [ "DISAPPEAR" ], + "death_function": { "message": "The %s disappears.", "corpse_type": "NO_CORPSE" }, "flags": [ "SEES", "HEARS", "NO_BREATHE", "SMELLS", "GUILT" ] }, { @@ -115,7 +115,7 @@ "melee_cut": 0, "harvest": "exempt", "special_attacks": [ [ "DISAPPEAR", 20 ] ], - "death_function": [ "DISAPPEAR" ], + "death_function": { "message": "The %s disappears.", "corpse_type": "NO_CORPSE" }, "flags": [ "SEES", "HEARS", "NO_BREATHE" ] }, { @@ -138,7 +138,7 @@ "melee_cut": 0, "harvest": "exempt", "special_attacks": [ [ "DISAPPEAR", 20 ] ], - "death_function": [ "DISAPPEAR" ], + "death_function": { "message": "The %s disappears.", "corpse_type": "NO_CORPSE" }, "flags": [ "SEES", "HEARS", "NO_BREATHE" ] }, { @@ -160,7 +160,7 @@ "dodge": 10, "harvest": "exempt", "fear_triggers": [ "PLAYER_CLOSE" ], - "death_function": [ "DISAPPEAR" ], + "death_function": { "message": "The %s disappears.", "corpse_type": "NO_CORPSE" }, "path_settings": { "max_dist": 30 }, "flags": [ "FLIES", "NO_BREATHE", "HARDTOSHOOT", "PET_WONT_FOLLOW" ] }, @@ -185,7 +185,7 @@ "harvest": "exempt", "fear_triggers": [ "PLAYER_CLOSE" ], "special_attacks": [ [ "DISAPPEAR", 200 ] ], - "death_function": [ "DISAPPEAR" ], + "death_function": { "message": "The %s disappears.", "corpse_type": "NO_CORPSE" }, "flags": [ "FLIES", "NO_BREATHE", "NOT_HALLUCINATION", "HARDTOSHOOT" ] }, { @@ -209,7 +209,7 @@ "harvest": "exempt", "fear_triggers": [ "PLAYER_CLOSE" ], "special_attacks": [ [ "DISAPPEAR", 200 ] ], - "death_function": [ "DISAPPEAR" ], + "death_function": { "message": "The %s disappears.", "corpse_type": "NO_CORPSE" }, "flags": [ "FLIES", "NO_BREATHE", "NOT_HALLUCINATION", "HARDTOSHOOT" ] } ] diff --git a/data/json/monsters/mutant.json b/data/json/monsters/mutant.json index 52b1cfc52c779..94b5e14764a15 100644 --- a/data/json/monsters/mutant.json +++ b/data/json/monsters/mutant.json @@ -28,7 +28,6 @@ "subtype": "collection", "groups": [ [ "subway", 40 ], [ "sewer", 20 ], [ "trash", 5 ], [ "bedroom", 5 ], [ "dresser", 10 ], [ "ammo", 18 ] ] }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "WARM", "BASHES", "GROUP_BASH", "HUMAN", "FILTHY" ] }, { @@ -71,7 +70,6 @@ "anger_triggers": [ "PLAYER_WEAK", "PLAYER_CLOSE", "STALK", "SOUND" ], "fear_triggers": [ "HURT" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "death_drops": "mon_mutant_experimental_death_drops", "upgrades": { "half_life": 50, "into": "mon_mutant_evolved" }, "regenerates": 1, @@ -144,7 +142,6 @@ "subtype": "collection", "groups": [ [ "subway", 40 ], [ "sewer", 20 ], [ "trash", 5 ], [ "bedroom", 1 ], [ "dresser", 5 ], [ "ammo", 18 ] ] }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "WARM", "BASHES", "GROUP_BASH", "HUMAN" ] } ] diff --git a/data/json/monsters/mutant_mammal.json b/data/json/monsters/mutant_mammal.json index b8b573988e929..e11b1fde244d2 100644 --- a/data/json/monsters/mutant_mammal.json +++ b/data/json/monsters/mutant_mammal.json @@ -38,7 +38,6 @@ "anger_triggers": [ "HURT", "PLAYER_CLOSE" ], "fear_triggers": [ "SOUND" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "harvest": "mutant_mammal_large_fur", "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "BASHES", "PUSH_MON", "STUMBLES", "KEENNOSE" ] }, @@ -69,7 +68,6 @@ "harvest": "mutant_mammal_fur", "anger_triggers": [ "PLAYER_CLOSE", "HURT" ], "fear_triggers": [ "SOUND" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "SWIMS", "WARM" ] }, { @@ -98,7 +96,6 @@ "harvest": "bird_large", "anger_triggers": [ "PLAYER_CLOSE", "HURT" ], "fear_triggers": [ "SOUND" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "SWIMS", "WARM" ] }, { @@ -129,7 +126,6 @@ "special_attacks": [ [ "scratch", 10 ] ], "fear_triggers": [ "SOUND", "PLAYER_CLOSE", "FRIEND_ATTACKED" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "harvest": "mammal_tiny", "reproduction": { "baby_monster": "mon_cat_mutant_kitten_prism", "baby_count": 2, "baby_timer": 80 }, "flags": [ @@ -167,7 +163,6 @@ "special_attacks": [ [ "scratch", 10 ] ], "fear_triggers": [ "SOUND", "PLAYER_CLOSE", "FRIEND_ATTACKED" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "harvest": "mammal_tiny", "flags": [ "SEES", "HEARS", "GOODHEARING", "SMELLS", "ANIMAL", "CATFOOD", "PATH_AVOID_DANGER_1", "WARM", "HIT_AND_RUN" ], "upgrades": { "age_grow": 120, "into": "mon_cat_mutant_prism" } @@ -210,7 +205,6 @@ "anger_triggers": [ "FRIEND_ATTACKED", "PLAYER_WEAK" ], "fear_triggers": [ "SOUND" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "KEENNOSE", "GROUP_MORALE" ] }, { @@ -243,7 +237,6 @@ "anger_triggers": [ "STALK", "FRIEND_ATTACKED", "PLAYER_WEAK", "HURT" ], "fear_triggers": [ "SOUND" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "harvest": "mutant_mammal_fur", "flags": [ "SEES", @@ -298,7 +291,6 @@ ], "anger_triggers": [ "STALK", "FRIEND_ATTACKED", "FRIEND_DIED", "PLAYER_WEAK", "PLAYER_CLOSE" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "KEENNOSE" ] }, { @@ -329,7 +321,6 @@ "harvest": "mutant_mammal_large_leather", "path_settings": { "max_dist": 10 }, "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "zombify_into": "mon_zeer", "reproduction": { "baby_monster": "mon_deer_mutant_spider_fawn", "baby_count": 1, "baby_timer": 330 }, "//": " 201 days gestation period. The fawn will stay with its mother for approximately one year, suckling for three to four months.", @@ -366,7 +357,6 @@ "harvest": "mutant_mammal_leather", "path_settings": { "max_dist": 10 }, "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "upgrades": { "age_grow": 330, "into": "mon_deer_mutant_spider" }, "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "STUMBLES" ] }, @@ -403,7 +393,6 @@ "biosignature": { "biosig_item": "feces_dog", "biosig_timer": 6 }, "anger_triggers": [ "HURT", "FRIEND_ATTACKED", "FRIEND_DIED" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 100 ], [ "PARROT_AT_DANGER", 0 ] ], "flags": [ "ANIMAL", diff --git a/data/json/monsters/nether.json b/data/json/monsters/nether.json index 602f392862d0d..c14478e1f75a1 100644 --- a/data/json/monsters/nether.json +++ b/data/json/monsters/nether.json @@ -29,7 +29,6 @@ "path_settings": { "max_dist": 5 }, "special_attacks": [ { "type": "bite", "cooldown": 15 }, [ "impale", 20 ] ], "anger_triggers": [ "HURT", "FRIEND_DIED", "FRIEND_ATTACKED" ], - "death_function": [ "NORMAL" ], "harvest": "bird_large", "flags": [ "HEARS", "KEENNOSE", "GOODHEARING", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "SWIMS", "SUNDEATH" ] }, @@ -59,7 +58,8 @@ "bleed_rate": 50, "harvest": "human", "special_attacks": [ [ "FEAR_PARALYZE", 0 ] ], - "death_function": [ "AMIGARA", "NORMAL" ], + "death_function": { "effect": { "id": "death_amigara" } }, + "death_drops": "amigara_drops", "flags": [ "SMELLS", "HEARS", "SEES", "STUMBLES", "HARDTOSHOOT" ] }, { @@ -86,7 +86,6 @@ "dodge": 1, "harvest": "demihuman", "special_attacks": [ [ "SHRIEK", 10 ] ], - "death_function": [ "NORMAL" ], "flags": [ "SMELLS", "HEARS", "WARM", "ANIMAL", "PATH_AVOID_DANGER_1", "SUNDEATH", "NO_BREATHE", "HUMAN" ] }, { @@ -112,7 +111,6 @@ "harvest": "zombie", "special_attacks": [ [ "FEAR_PARALYZE", 0 ], { "type": "bite", "cooldown": 5 } ], "death_drops": "default_zombie_clothes", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "IMMOBILE", "GUILT", "POISON", "REVIVES", "FILTHY" ] }, { @@ -132,7 +130,7 @@ "melee_cut": 0, "harvest": "exempt", "special_attacks": [ [ "BREATHE", 8 ] ], - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "IMMOBILE", "NOGIB" ] }, { @@ -152,7 +150,7 @@ "melee_cut": 0, "harvest": "exempt", "special_attacks": [ [ "BREATHE", 8 ] ], - "death_function": [ "KILL_BREATHERS" ], + "death_function": { "effect": { "id": "death_kill_breathers", "hit_self": true }, "corpse_type": "NO_CORPSE" }, "flags": [ "ACIDPROOF", "ACID_BLOOD", "IMMOBILE" ] }, { @@ -183,7 +181,7 @@ "luminance": 6, "harvest": "exempt", "special_attacks": [ [ "DARKMAN", 5 ], [ "scratch", 15 ] ], - "death_function": [ "DARKMAN" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away.", "effect": { "id": "death_darkman" } }, "regenerates_in_dark": true, "flags": [ "NOHEAD", "HARDTOSHOOT", "WEBWALK", "FLIES", "PLASTIC", "ELECTRIC", "ACIDPROOF", "SUNDEATH", "NO_BREATHE" ] }, @@ -212,7 +210,6 @@ "harvest": "zombie_leather", "special_attacks": [ [ "scratch", 15 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "BASHES", "GROUP_BASH", "HUMAN", "POISON", "REVIVES", "FILTHY" ] }, { @@ -239,7 +236,7 @@ "dodge": 3, "harvest": "exempt", "special_attacks": [ [ "DOGTHING", 40 ] ], - "death_function": [ "THING" ], + "death_function": { "effect": { "id": "death_thing", "hit_self": true }, "corpse_type": "NO_CORPSE", "message": "The %s emerges!" }, "flags": [ "SEES", "SMELLS", "HEARS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM" ] }, { @@ -268,7 +265,6 @@ "harvest": "zombie_meatslug", "//": "Add a demihuman alien anatomy for things like flaming eye's and Mi-go, polyps and other lovecraftian horrors from other dimensions", "special_attacks": [ [ "STARE", 12 ] ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "WARM", "FLIES", "FIREY", "NO_BREATHE", "NOHEAD" ] }, { @@ -297,7 +293,7 @@ "armor_bash": 8, "bleed_rate": 40, "harvest": "exempt", - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "SMELLS", "HEARS", @@ -394,7 +390,6 @@ "vision_day": 30, "harvest": "gozu", "special_attacks": [ [ "FEAR_PARALYZE", 20 ] ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "WARM", "BASHES", "GROUP_BASH", "ANIMAL", "NO_BREATHE", "PATH_AVOID_DANGER_1" ] }, { @@ -422,7 +417,6 @@ "bleed_rate": 60, "path_settings": { "avoid_traps": true, "avoid_sharp": true }, "harvest": "demihuman", - "death_function": [ "NORMAL" ], "flags": [ "SMELLS", "HEARS", "WARM", "NO_BREATHE", "GRABS", "PRIORITIZE_TARGETS", "PATH_AVOID_DANGER_1" ] }, { @@ -450,7 +444,7 @@ "dodge": 4, "harvest": "exempt", "special_attacks": [ [ "TENTACLE", 5 ] ], - "death_function": [ "THING" ], + "death_function": { "effect": { "id": "death_thing", "hit_self": true }, "corpse_type": "NO_CORPSE", "message": "The %s emerges!" }, "flags": [ "SEES", "SMELLS", "HEARS", "BASHES" ] }, { @@ -484,7 +478,7 @@ "special_attacks": [ [ "TINDALOS_TELEPORT", 5 ] ], "emit_fields": [ { "emit_id": "emit_tindalos_gas_leak", "delay": "1 s" } ], "path_settings": { "max_dist": 10 }, - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "SEES", "SMELLS", @@ -529,7 +523,7 @@ "special_attacks": [ [ "TINDALOS_TELEPORT", 5 ], [ "DISAPPEAR", 25 ] ], "emit_fields": [ { "emit_id": "emit_tindalos_gas_leak", "delay": "1 s" } ], "path_settings": { "max_dist": 10 }, - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "SEES", "SMELLS", @@ -569,7 +563,6 @@ "harvest": "demihuman", "special_attacks": [ [ "ACID", 15 ] ], "anger_triggers": [ "PLAYER_WEAK", "FRIEND_DIED" ], - "death_function": [ "NORMAL" ], "flags": [ "SMELLS", "HEARS", "POISON", "ACIDPROOF", "ACID_BLOOD" ] }, { @@ -594,7 +587,7 @@ "dodge": 8, "harvest": "exempt", "anger_triggers": [ "STALK", "PLAYER_WEAK", "PLAYER_CLOSE", "FRIEND_ATTACKED" ], - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "SEES", "SMELLS", @@ -638,7 +631,7 @@ "//": "a good candidate for an alien anatomy harvest", "harvest": "exempt", "path_settings": { "max_dist": 10 }, - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "SEES", "SMELLS", "HEARS", "WARM", "BASHES", "HIT_AND_RUN", "NO_BREATHE", "NOGIB" ] }, { @@ -671,7 +664,6 @@ "vision_night": 15, "path_settings": { "avoid_traps": true, "avoid_sharp": true }, "harvest": "mammal_small_fur", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "HARDTOSHOOT", "PATH_AVOID_DANGER_1" ] }, { @@ -699,7 +691,7 @@ "harvest": "exempt", "special_attacks": [ [ "DISAPPEAR", 200 ] ], "special_when_hit": [ "ZAPBACK", 100 ], - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "SEES", "HEARS", @@ -743,7 +735,7 @@ "dodge": 1, "harvest": "exempt", "special_attacks": [ [ "DISAPPEAR", 200 ] ], - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "SEES", "SMELLS", "WARM", "SWIMS", "PLASTIC", "SUNDEATH", "NOGIB" ] }, { @@ -773,7 +765,7 @@ "harvest": "exempt", "path_settings": { "max_dist": 5 }, "special_attacks": [ [ "PARROT", 400 ] ], - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "regenerates": 50, "regen_morale": true, "flags": [ "SEES", "SMELLS", "SWIMS", "PLASTIC", "SLUDGEPROOF", "ACID_BLOOD", "ACIDPROOF", "NOHEAD", "ABSORBS_SPLITS", "NOGIB" ] @@ -805,7 +797,7 @@ "bleed_rate": 20, "harvest": "exempt", "special_attacks": [ [ "TENTACLE", 5 ] ], - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "SMELLS", "HEARS", "NOHEAD", "BASHES", "GROUP_BASH", "SWIMS", "ATTACKMON", "PLASTIC", "ACIDPROOF", "NOGIB", "CLIMBS" ] }, { @@ -831,7 +823,6 @@ "melee_cut": 0, "dodge": 6, "harvest": "demihuman", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "GOODHEARING", "POISON", "HUMAN", "CLIMBS" ] }, { @@ -861,7 +852,6 @@ "bleed_rate": 50, "harvest": "meatslug", "special_attacks": [ [ "GENE_STING", 20 ] ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "BASHES", "DESTROYS", "POISON", "VENOM", "NO_BREATHE", "DIGS" ] }, { @@ -883,7 +873,7 @@ "morale": 100, "melee_cut": 0, "harvest": "exempt", - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "HEARS", "GOODHEARING", "STUMBLES", "NOHEAD", "HARDTOSHOOT", "FLIES", "PLASTIC", "NO_BREATHE", "NOGIB" ] } ] diff --git a/data/json/monsters/obsolete.json b/data/json/monsters/obsolete.json index fcac715abb71c..65b61fe0f13f2 100644 --- a/data/json/monsters/obsolete.json +++ b/data/json/monsters/obsolete.json @@ -21,7 +21,6 @@ "dodge": 2, "harvest": "mammal_tiny", "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "WARM", "SWIMS", "ANIMAL", "PATH_AVOID_DANGER_1", "VERMIN" ] }, { @@ -46,7 +45,6 @@ "harvest": "arachnid", "anger_triggers": [ "PLAYER_WEAK" ], "fear_triggers": [ "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "FLIES", "VERMIN" ] }, { @@ -68,7 +66,6 @@ "harvest": "mammal_tiny", "special_attacks": [ { "type": "leap", "cooldown": 10, "max_range": 5 } ], "fear_triggers": [ "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "SWIMS" ] }, { @@ -88,7 +85,6 @@ "melee_cut": 0, "dodge": 6, "harvest": "mammal_tiny", - "death_function": [ "NORMAL" ], "flags": [ "SMELLS", "HEARS", "STUMBLES", "VERMIN", "FLIES" ] }, { @@ -112,7 +108,6 @@ "dodge": 2, "harvest": "mammal_tiny", "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "VERMIN" ] }, { @@ -133,7 +128,6 @@ "dodge": 6, "harvest": "mammal_tiny", "fear_triggers": [ "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "VERMIN", "ACIDPROOF", "ARTHROPOD_BLOOD" ] }, { @@ -154,7 +148,6 @@ "melee_cut": 0, "dodge": 2, "harvest": "mammal_tiny", - "death_function": [ "NORMAL" ], "flags": [ "SMELLS", "HEARS", "VERMIN", "CLIMBS" ] }, { @@ -174,7 +167,6 @@ "melee_cut": 0, "dodge": 2, "harvest": "mammal_tiny", - "death_function": [ "NORMAL" ], "flags": [ "SMELLS", "HEARS", "VERMIN", "WEBWALK", "CLIMBS" ] }, { @@ -194,7 +186,6 @@ "melee_cut": 0, "dodge": 2, "harvest": "arachnid", - "death_function": [ "NORMAL" ], "flags": [ "SMELLS", "HEARS", "VERMIN", "BADVENOM", "CLIMBS" ] }, { @@ -214,7 +205,6 @@ "melee_cut": 0, "dodge": 2, "harvest": "mammal_tiny", - "death_function": [ "NORMAL" ], "flags": [ "SMELLS", "HEARS", "VERMIN", "CLIMBS" ] }, { @@ -245,7 +235,7 @@ "revert_to_itype": "bot_tripod", "special_attacks": [ [ "FLAMETHROWER", 10 ] ], "death_drops": { "groups": [ [ "robots", 4 ], [ "tripod", 1 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", "GOODHEARING", "BASHES", "NO_BREATHE", "ELECTRONIC", "CLIMBS", "PRIORITIZE_TARGETS" ] }, { @@ -277,7 +267,7 @@ "starting_ammo": { "40x46mm_m433": 200, "556": 3000 }, "path_settings": { "max_dist": 20 }, "special_attacks": [ [ "MULTI_ROBOT", 3 ] ], - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", @@ -321,7 +311,7 @@ "starting_ammo": { "40x46mm_m433": 100, "556": 1000 }, "path_settings": { "max_dist": 10 }, "special_attacks": [ [ "CHICKENBOT", 4 ] ], - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", "BASHES", "NO_BREATHE", "ELECTRONIC", "PRIORITIZE_TARGETS", "DROPS_AMMO" ] }, { @@ -358,7 +348,7 @@ ], "special_when_hit": [ "RETURN_FIRE", 100 ], "death_drops": { }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "NOHEAD", "ELECTRONIC", "COLDPROOF", "IMMOBILE", "NO_BREATHE" ] } ] diff --git a/data/json/monsters/power_leech.json b/data/json/monsters/power_leech.json index a93d257256003..f54e9e62cf5f5 100644 --- a/data/json/monsters/power_leech.json +++ b/data/json/monsters/power_leech.json @@ -37,7 +37,6 @@ ], "special_when_hit": [ "ZAPBACK", 100 ], "harvest": "flesh_plant_bloom", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "NOHEAD", "IMMOBILE", "NO_BREATHE", "QUEEN", "HARDTOSHOOT" ] }, { @@ -76,7 +75,6 @@ ], "special_when_hit": [ "ZAPBACK", 100 ], "harvest": "flesh_plant", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "NOHEAD", "IMMOBILE", "NO_BREATHE", "HARDTOSHOOT" ] }, { @@ -104,7 +102,6 @@ "special_when_hit": [ "ZAPBACK", 100 ], "harvest": "flesh_plant", "death_drops": { }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "NOHEAD", "IMMOBILE", "NO_BREATHE", "HARDTOSHOOT" ] }, { @@ -138,7 +135,6 @@ [ "LEECH_SPAWNER", 120 ] ], "harvest": "flesh_plant", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "NOHEAD", "IMMOBILE", "NO_BREATHE" ] }, { @@ -181,7 +177,6 @@ ], "special_when_hit": [ "ZAPBACK", 100 ], "harvest": "flesh_plant", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "NOHEAD", "NO_BREATHE", "HARDTOSHOOT" ] }, { @@ -222,7 +217,6 @@ [ "EVOLVE_KILL_STRIKE", 6 ] ], "harvest": "flesh_plant", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "NOHEAD", "NO_BREATHE", "HARDTOSHOOT" ] } ] diff --git a/data/json/monsters/reptile_amphibian.json b/data/json/monsters/reptile_amphibian.json index d8bcd485bd498..da2e2d079cd3c 100644 --- a/data/json/monsters/reptile_amphibian.json +++ b/data/json/monsters/reptile_amphibian.json @@ -38,7 +38,6 @@ "upgrades": { "half_life": 50, "into": "mon_frog_mother" }, "special_attacks": [ { "type": "leap", "cooldown": 10, "move_cost": 0, "max_range": 10, "min_consider_range": 2 } ], "anger_triggers": [ "STALK", "PLAYER_WEAK", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "SWIMS" ] }, { @@ -87,7 +86,6 @@ "anger_triggers": [ "PLAYER_CLOSE", "PLAYER_WEAK" ], "fear_triggers": [ "FIRE", "HURT" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "GOODHEARING", "SMELLS", "KEENNOSE", "PATH_AVOID_DANGER_1", "ANIMAL", "PUSH_MON", "SWIMS" ] }, { @@ -121,7 +119,6 @@ "anger_triggers": [ "HURT" ], "fear_triggers": [ "PLAYER_CLOSE" ], "placate_triggers": [ "PLAYER_WEAK" ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 14, "into": "mon_rattlesnake_giant" }, "flags": [ "SEES", "HEARS", "SMELLS", "BADVENOM", "HARDTOSHOOT", "SWIMS" ] }, @@ -165,7 +162,6 @@ ], "anger_triggers": [ "HURT", "PLAYER_CLOSE" ], "placate_triggers": [ "PLAYER_WEAK" ], - "death_function": [ "NORMAL" ], "reproduction": { "baby_egg": "egg_reptile", "baby_count": 3, "baby_timer": 10 }, "baby_flags": [ "SPRING" ], "flags": [ "SEES", "HEARS", "SMELLS", "BADVENOM", "HARDTOSHOOT", "SWIMS" ] @@ -197,7 +193,6 @@ "vision_night": 30, "harvest": "mutant_animal_large_noskin", "path_settings": { "max_dist": 5 }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "WARM", "VENOM", "SWIMS" ] } ] diff --git a/data/json/monsters/robofac_robots.json b/data/json/monsters/robofac_robots.json index 941950cf5e131..9472aaf45751c 100644 --- a/data/json/monsters/robofac_robots.json +++ b/data/json/monsters/robofac_robots.json @@ -30,7 +30,7 @@ ], "special_when_hit": [ "RETURN_FIRE", 100 ], "death_drops": { }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "NOHEAD", "ELECTRONIC", "COLDPROOF", "IMMOBILE", "NO_BREATHE" ] } ] diff --git a/data/json/monsters/slimes.json b/data/json/monsters/slimes.json index c32d81d0c4ae4..680d9e788ed73 100644 --- a/data/json/monsters/slimes.json +++ b/data/json/monsters/slimes.json @@ -28,7 +28,11 @@ "bleed_rate": 30, "harvest": "exempt", "special_attacks": [ [ "FORMBLOB", 30 ] ], - "death_function": [ "BLOBSPLIT" ], + "death_function": { + "message": "The %s splits in two!", + "corpse_type": "NO_CORPSE", + "effect": { "id": "death_blobsplit", "hit_self": true } + }, "flags": [ "HEARS", "GOODHEARING", "NOHEAD", "POISON", "NO_BREATHE", "ACIDPROOF" ] }, { @@ -58,7 +62,11 @@ "bleed_rate": 20, "harvest": "exempt", "special_attacks": [ [ "CALLBLOBS", 0 ] ], - "death_function": [ "BRAINBLOB" ], + "death_function": { + "message": "The %s splits in two!", + "corpse_type": "NO_CORPSE", + "effect": { "id": "death_blob_brain", "hit_self": true } + }, "flags": [ "SEES", "HEARS", "GOODHEARING", "NOHEAD", "POISON", "NO_BREATHE", "ACIDPROOF", "QUEEN" ] }, { @@ -92,7 +100,11 @@ "bleed_rate": 30, "harvest": "exempt", "special_attacks": [ [ "FORMBLOB", 20 ] ], - "death_function": [ "BLOBSPLIT" ], + "death_function": { + "message": "The %s splits in two!", + "corpse_type": "NO_CORPSE", + "effect": { "id": "death_blobsplit_large", "hit_self": true } + }, "flags": [ "HEARS", "GOODHEARING", "NOHEAD", "POISON", "NO_BREATHE", "ACIDPROOF" ] }, { @@ -122,7 +134,8 @@ "armor_stab": 10, "armor_acid": 10, "harvest": "exempt", - "death_function": [ "BLOBSPLIT" ], + "death_function": { "message": "The %s's body melts away.", "corpse_type": "NO_CORPSE" }, + "death_drops": "mon_blob_small_deathdrops", "flags": [ "HEARS", "GOODHEARING", "NOHEAD", "POISON", "NO_BREATHE", "ACIDPROOF" ] }, { @@ -150,7 +163,7 @@ "armor_bash": 10, "harvest": "exempt", "special_attacks": [ [ "FORMBLOB", 4 ] ], - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "SMELLS", "HEARS", "PLASTIC", "NO_BREATHE", "NOHEAD", "NOGIB" ] }, { @@ -181,7 +194,11 @@ "vision_night": 5, "harvest": "exempt", "special_attacks": [ [ "SLIMESPRING", 15 ] ], - "death_function": [ "ACID" ], + "death_function": { + "message": "The %s's body dissolves into acid.", + "effect": { "id": "death_acid", "hit_self": true }, + "corpse_type": "NO_CORPSE" + }, "flags": [ "SEES", "HEARS", "SMELLS", "GOODHEARING", "NOHEAD", "POISON", "VENOM", "WARM", "GUILT" ] } ] diff --git a/data/json/monsters/slugs.json b/data/json/monsters/slugs.json index 8f65107620027..ea4b205505b1b 100644 --- a/data/json/monsters/slugs.json +++ b/data/json/monsters/slugs.json @@ -26,7 +26,7 @@ "vision_day": 10, "vision_night": 30, "harvest": "exempt", - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "regenerates": 50, "flags": [ "NOHEAD", "SEES", "POISON", "HEARS", "SMELLS", "SLUDGEPROOF", "SLUDGETRAIL", "SWIMS", "FLAMMABLE", "NOGIB" ] }, @@ -71,7 +71,6 @@ "harvest": "mutant_meatslug", "special_attacks": [ [ "ACID", 10 ] ], "anger_triggers": [ "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "BASHES", "ACIDPROOF", "ACIDTRAIL", "ARTHROPOD_BLOOD" ] } ] diff --git a/data/json/monsters/triffid.json b/data/json/monsters/triffid.json index faf50b8a47e83..cf3d81b2ac195 100644 --- a/data/json/monsters/triffid.json +++ b/data/json/monsters/triffid.json @@ -47,7 +47,6 @@ "harvest": "biollante", "special_attacks": [ [ "SPIT_SAP", 2 ] ], "death_drops": { "subtype": "collection", "groups": [ [ "biollante", 8 ] ], "//": "80% chance of an item from group biollante" }, - "death_function": [ "NORMAL" ], "flags": [ "NOHEAD", "IMMOBILE" ] }, { @@ -71,7 +70,7 @@ "bleed_rate": 50, "harvest": "exempt", "special_attacks": [ [ "GROW_VINE", 60 ] ], - "death_function": [ "KILL_VINES" ], + "death_function": { "effect": { "id": "death_kill_vines", "hit_self": true, "min_level": 1 }, "corpse_type": "NO_CORPSE" }, "flags": [ "NOHEAD", "IMMOBILE" ] }, { @@ -95,7 +94,7 @@ "bleed_rate": 80, "harvest": "exempt", "special_attacks": [ [ "VINE", 100 ] ], - "death_function": [ "VINE_CUT" ], + "death_function": { "effect": { "id": "death_kill_vines", "hit_self": true }, "corpse_type": "NO_CORPSE" }, "flags": [ "NOHEAD", "HARDTOSHOOT", "PLASTIC", "IMMOBILE" ] }, { @@ -120,7 +119,6 @@ "melee_cut": 1, "harvest": "triffid_small", "upgrades": { "age_grow": 14, "into": "mon_triffid_young" }, - "death_function": [ "NORMAL" ], "flags": [ "HEARS", "SMELLS", "NOHEAD", "STUMBLES" ] }, { @@ -146,7 +144,6 @@ "harvest": "triffid_paralytic", "upgrades": { "age_grow": 14, "into": "mon_triffid" }, "special_attacks": [ [ "TRIFFID_GROWTH", 28800 ] ], - "death_function": [ "NORMAL" ], "fungalize_into": "mon_fungaloid", "flags": [ "HEARS", "SMELLS", "NOHEAD", "PARALYZEVENOM" ] }, @@ -175,7 +172,6 @@ "armor_bullet": 3, "bleed_rate": 60, "harvest": "triffid_paralytic", - "death_function": [ "NORMAL" ], "fungalize_into": "mon_fungaloid", "flags": [ "SEES", "SMELLS", "BASHES", "GROUP_BASH", "NOHEAD", "PARALYZEVENOM" ] }, @@ -205,7 +201,6 @@ "bleed_rate": 40, "harvest": "triffid_queen", "special_attacks": [ [ "GROWPLANTS", 20 ] ], - "death_function": [ "NORMAL" ], "fungalize_into": "mon_fungaloid", "flags": [ "HEARS", "SMELLS", "BASHES", "NOHEAD", "PARALYZEVENOM" ] }, @@ -233,7 +228,6 @@ "armor_bash": 18, "bleed_rate": 10, "harvest": "triffid_small", - "death_function": [ "NORMAL" ], "flags": [ "HEARS", "GOODHEARING", "NOHEAD", "HARDTOSHOOT", "GRABS", "SWIMS", "PLASTIC" ] }, { @@ -268,7 +262,6 @@ ], "special_attacks": [ [ "PARA_STING", 10 ] ], "death_drops": { "subtype": "collection", "groups": [ [ "fungal_sting", 80 ] ], "//": "80% chance of an item from group fungal_sting" }, - "death_function": [ "NORMAL" ], "flags": [ "HEARS", "SMELLS", "NOHEAD", "CAN_DIG" ] }, { @@ -293,7 +286,6 @@ "emit_fields": [ { "emit_id": "emit_pollen_stream", "delay": "1 s" } ], "harvest": "triffid_paralytic", "special_attacks": [ [ "SPIT_SAP", 3 ], [ "PARA_STING", 12 ] ], - "death_function": [ "NORMAL" ], "flags": [ "NOHEAD", "IMMOBILE" ] }, { @@ -319,7 +311,7 @@ "armor_bullet": 13, "harvest": "triffid_small", "special_attacks": [ [ "TRIFFID_HEARTBEAT", 50 ] ], - "death_function": [ "TRIFFID_HEART" ], + "death_function": { "effect": { "id": "death_triffid_heart", "hit_self": true } }, "flags": [ "NOHEAD", "IMMOBILE", "QUEEN" ] } ] diff --git a/data/json/monsters/turrets.json b/data/json/monsters/turrets.json index aa1bf09e25515..23df37eaf9feb 100644 --- a/data/json/monsters/turrets.json +++ b/data/json/monsters/turrets.json @@ -44,7 +44,7 @@ ], "special_when_hit": [ "RETURN_FIRE", 100 ], "death_drops": { }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "NOHEAD", "ELECTRONIC", "COLDPROOF", "IMMOBILE", "NO_BREATHE", "DROPS_AMMO" ] }, { @@ -72,7 +72,11 @@ "revert_to_itype": "bot_turret_searchlight", "special_attacks": [ [ "SEARCHLIGHT", 1 ] ], "death_drops": { "groups": [ [ "robots", 1 ], [ "turret_searchlight", 1 ] ] }, - "death_function": [ "FOCUSEDBEAM" ], + "death_function": { + "effect": { "id": "death_focused_beam" }, + "message": "As the final light is destroyed, it erupts in a blinding flare!", + "corpse_type": "NO_CORPSE" + }, "flags": [ "SEES", "NOHEAD", "ELECTRONIC", "COLDPROOF", "IMMOBILE", "NO_BREATHE", "PRIORITIZE_TARGETS" ] }, { @@ -121,7 +125,7 @@ ], "special_when_hit": [ "RETURN_FIRE", 100 ], "death_drops": { }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "NOHEAD", @@ -180,7 +184,7 @@ ], "special_when_hit": [ "RETURN_FIRE", 100 ], "death_drops": { }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "NOHEAD", @@ -239,7 +243,7 @@ ], "special_when_hit": [ "RETURN_FIRE", 100 ], "death_drops": { }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "NOHEAD", @@ -300,7 +304,7 @@ } ], "death_drops": { }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "NOHEAD", "ELECTRONIC", "COLDPROOF", "IMMOBILE", "NO_BREATHE", "DROPS_AMMO" ] }, { @@ -328,7 +332,7 @@ "vision_night": 50, "revert_to_itype": "bot_turret_speaker", "special_attacks": [ [ "SPEAKER", 10 ] ], - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "death_drops": { "groups": [ [ "turret_speaker", 1 ] ] }, "flags": [ "SEES", "NOHEAD", "ELECTRONIC", "IMMOBILE", "NO_BREATHE" ] }, @@ -376,7 +380,7 @@ ], "special_when_hit": [ "RETURN_FIRE", 100 ], "death_drops": { "subtype": "collection", "groups": [ [ "robots", 80 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", "GOODHEARING", "NOHEAD", "IMMOBILE", "NO_BREATHE", "PRIORITIZE_TARGETS", "INTERIOR_AMMO" ] } ] diff --git a/data/json/monsters/utility_bot.json b/data/json/monsters/utility_bot.json index aedfada0b44d8..55b13e60201b7 100644 --- a/data/json/monsters/utility_bot.json +++ b/data/json/monsters/utility_bot.json @@ -23,7 +23,7 @@ "revert_to_itype": "bot_eyebot", "special_attacks": [ [ "PHOTOGRAPH", 30 ] ], "death_drops": { "groups": [ [ "robots", 4 ], [ "eyebot", 1 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "FLIES", "ELECTRONIC", "COLDPROOF", "NO_BREATHE", "NOHEAD", "PRIORITIZE_TARGETS" ] }, { @@ -49,7 +49,7 @@ "revert_to_itype": "bot_grocerybot", "special_attacks": [ [ "PAID_BOT", 1 ] ], "death_drops": { "groups": [ [ "robots", 4 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "ELECTRONIC", @@ -87,7 +87,7 @@ "revert_to_itype": "bot_grocerybot_busted", "special_attacks": [ [ "PAID_BOT", 1 ] ], "death_drops": { "groups": [ [ "robots", 4 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "ELECTRONIC", "COLDPROOF", "NO_BREATHE", "FIREPROOF", "PUSH_MON", "HEARS", "PACIFIST", "PAY_BOT" ] }, { @@ -112,7 +112,11 @@ "armor_bullet": 10, "vision_day": 50, "revert_to_itype": "bot_hazmatbot", - "death_function": [ "EXPLODE" ], + "death_function": { + "corpse_type": "NO_CORPSE", + "effect": { "id": "death_explosion_mon_hazmatbot", "hit_self": true }, + "message": "The %s explodes!" + }, "flags": [ "SEES", "HEARS", "BASHES", "ELECTRONIC", "COLDPROOF", "NO_BREATHE", "PRIORITIZE_TARGETS", "PATH_AVOID_DANGER_1" ] }, { @@ -140,7 +144,7 @@ "armor_bullet": 10, "revert_to_itype": "bot_molebot", "death_drops": { "groups": [ [ "robots", 4 ], [ "molebot", 1 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "HEARS", "GOODHEARING", "DIGS", "NO_BREATHE", "ELECTRONIC", "COLDPROOF", "PATH_AVOID_DANGER_1" ] }, { @@ -170,7 +174,7 @@ "revert_to_itype": "bot_nursebot", "special_attacks": [ [ "ASSIST", 30 ], [ "CHECK_UP", 120 ] ], "death_drops": { "groups": [ [ "robots", 4 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "ELECTRONIC", "COLDPROOF", "NO_BREATHE", "FIREPROOF", "PUSH_MON", "HEARS", "PACIFIST" ] }, { @@ -203,7 +207,7 @@ "revert_to_itype": "bot_nursebot", "special_attacks": [ [ "OPERATE", 30 ], [ "PARROT", 20 ] ], "death_drops": { "groups": [ [ "robots", 4 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "ELECTRONIC", diff --git a/data/json/monsters/zanimal_upgrade.json b/data/json/monsters/zanimal_upgrade.json index 5beff93f879e4..84797b29e8de4 100644 --- a/data/json/monsters/zanimal_upgrade.json +++ b/data/json/monsters/zanimal_upgrade.json @@ -30,7 +30,6 @@ "harvest": "mr_bones", "special_attacks": [ { "type": "bite", "cooldown": 5 } ], "upgrades": { "half_life": 15, "into": "mon_dog_skeleton_brute" }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "NO_BREATHE", "HARDTOSHOOT", "REVIVES", "POISON", "FILTHY" ] }, { @@ -131,7 +130,7 @@ "weight": "150 kg", "harvest": "exempt", "emit_fields": [ { "emit_id": "emit_tear_gas_stream", "delay": "1 s" } ], - "death_function": [ "TEARBURST" ], + "death_function": { "effect": { "id": "death_tearburst", "hit_self": true }, "message": "A %s explode!", "corpse_type": "NO_CORPSE" }, "special_attacks": [ { "id": "impale" } ], "extend": { "flags": [ "HIT_AND_RUN" ] } }, @@ -167,7 +166,6 @@ "harvest": "mr_bones", "special_attacks": [ { "type": "bite", "cooldown": 5 } ], "upgrades": { "half_life": 15, "into": "mon_dog_skeleton_brute" }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "NO_BREATHE", "HARDTOSHOOT", "REVIVES", "POISON", "FILTHY" ] }, { @@ -262,7 +260,7 @@ "dodge": 3, "bleed_rate": 50, "special_attacks": [ [ "ACID_BARF", 10 ] ], - "death_function": [ "ACID", "NORMAL" ], + "death_function": { "message": "The %s's body leaks acid.", "effect": { "id": "death_acid", "hit_self": true } }, "flags": [ "SEES", "HEARS", diff --git a/data/json/monsters/zed-animal.json b/data/json/monsters/zed-animal.json index ed99674f551d9..6e07c5f5923f9 100644 --- a/data/json/monsters/zed-animal.json +++ b/data/json/monsters/zed-animal.json @@ -26,7 +26,6 @@ "armor_bullet": 2, "luminance": 0, "harvest": "zombie_leather", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "SWIMS", "AQUATIC", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ] }, { @@ -56,7 +55,6 @@ "vision_night": 4, "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 5 } ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 28, "into_group": "GROUP_ZOMBIE_DOG_UPGRADE" }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ] }, @@ -91,7 +89,6 @@ "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 5 } ], "death_drops": { "subtype": "collection", "groups": [ [ "dog_cop", 40 ] ], "//": "40% chance of an item from group dog_cop" }, - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 28, "into_group": "GROUP_ZOMBIE_DOG_UPGRADE" }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "PUSH_MON", "FILTHY" ] }, @@ -123,7 +120,6 @@ "vision_night": 4, "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 2, "accuracy": 4, "no_infection_chance": 12 } ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 28, "into": "mon_dog_zombie_brute" }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "PUSH_MON", "FILTHY" ] }, @@ -155,7 +151,6 @@ "special_attacks": [ [ "HOWL", 10 ] ], "anger_triggers": [ "PLAYER_CLOSE", "HURT" ], "fear_triggers": [ "FIRE" ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 28, "into_group": "GROUP_ZOLF_UPGRADE" }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "KEENNOSE", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ] }, @@ -190,7 +185,6 @@ "harvest": "zombie_fur", "anger_triggers": [ "PLAYER_CLOSE", "HURT" ], "fear_triggers": [ "FIRE" ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 14, "into_group": "GROUP_ZOMBEAR_UPGRADE" }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "PUSH_MON", "FILTHY" ] }, @@ -223,7 +217,6 @@ "special_attacks": [ { "type": "bite", "cooldown": 2 } ], "anger_triggers": [ "PLAYER_WEAK", "PLAYER_CLOSE" ], "fear_triggers": [ "FIRE" ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 20, "into_group": "GROUP_ZOMBIE_PIG_UPGRADE" }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "KEENNOSE", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ], "//": "1d8->2d5, minor bonus over 1d9" @@ -256,7 +249,6 @@ "harvest": "zombie_leather", "anger_triggers": [ "PLAYER_CLOSE", "HURT" ], "fear_triggers": [ "FIRE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "FILTHY", "SWIMS" ] }, { @@ -289,7 +281,6 @@ "harvest": "zombie_leather", "anger_triggers": [ "PLAYER_CLOSE", "HURT" ], "fear_triggers": [ "FIRE" ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 14, "into_group": "GROUP_ZOOSE_UPGRADE" }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ] }, @@ -323,7 +314,6 @@ "special_attacks": [ { "type": "leap", "cooldown": 10, "max_range": 5 } ], "anger_triggers": [ "PLAYER_CLOSE", "HURT" ], "fear_triggers": [ "FIRE" ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 14, "into_group": "GROUP_ZOUGAR_UPGRADE" }, "flags": [ "SEES", @@ -369,7 +359,6 @@ "vision_night": 3, "harvest": "zombie_leather", "anger_triggers": [ "PLAYER_CLOSE", "PLAYER_WEAK" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "BASHES", "NO_BREATHE", "REVIVES", "BONES", "FAT" ] }, { @@ -415,7 +404,6 @@ "vision_night": 3, "anger_triggers": [ "PLAYER_CLOSE", "PLAYER_WEAK" ], "death_drops": { "subtype": "collection", "groups": [ [ "cow", 25 ] ], "//": "25% chance of an item from group cow" }, - "death_function": [ "NORMAL" ], "harvest": "zombie_leather", "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ] }, @@ -448,7 +436,6 @@ "vision_night": 3, "anger_triggers": [ "PLAYER_CLOSE", "HURT" ], "fear_triggers": [ "FIRE" ], - "death_function": [ "NORMAL" ], "harvest": "zombie_leather", "special_attacks": [ [ "SMASH", 20 ] ], "flags": [ @@ -493,7 +480,6 @@ "armor_bash": 1, "armor_cut": 3, "vision_night": 15, - "death_function": [ "NORMAL" ], "harvest": "zombie_leather", "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ] }, @@ -526,7 +512,6 @@ "vision_day": 5, "vision_night": 5, "harvest": "arachnid_tainted", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -570,7 +555,6 @@ "armor_bash": 5, "armor_cut": 4, "vision_night": 10, - "death_function": [ "NORMAL" ], "harvest": "zombie_leather", "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ] } diff --git a/data/json/monsters/zed-classic.json b/data/json/monsters/zed-classic.json index a11db87639196..8177826d8318f 100644 --- a/data/json/monsters/zed-classic.json +++ b/data/json/monsters/zed-classic.json @@ -30,7 +30,6 @@ "groups": [ [ "default_zombie_clothes", 100 ], [ "hive", 80 ] ], "//": "cloth as any other zombie (always), additional items from group hive (sometimes)" }, - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "HEARS", @@ -73,7 +72,6 @@ "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "GRAB", 7 ], [ "scratch", 20 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "fungalize_into": "mon_zombie_fungus", "upgrades": { "half_life": 14, "into_group": "GROUP_ZOMBIE_UPGRADE" }, @@ -123,7 +121,6 @@ "harvest": "zombie", "special_attacks": [ [ "GRAB", 7 ], [ "scratch", 20 ] ], "death_drops": "mon_zombie_cop_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "fungalize_into": "mon_zombie_fungus", "flags": [ @@ -167,7 +164,6 @@ "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "scratch", 20 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "upgrades": { "half_life": 14, "into_group": "GROUP_ZOMBIE_CRAWLER_UPGRADE" }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "GRABS", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ] @@ -202,7 +198,6 @@ "special_attacks": [ [ "DANCE", 30 ] ], "death_drops": "mon_zombie_hulk_death_drops", "fungalize_into": "mon_zombie_fungus", - "death_function": [ "NORMAL" ], "regenerates": 50, "flags": [ "WARM", "BASHES", "DESTROYS", "NO_BREATHE", "POISON", "FILTHY" ] }, @@ -235,7 +230,6 @@ "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 5, "min_mul": 0.75, "//": "Fat zombies have stronger jaws" }, [ "scratch", 20 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "fungalize_into": "mon_zombie_fungus", "upgrades": { "half_life": 12, "into_group": "GROUP_ZOMBIE_FAT" }, @@ -285,7 +279,6 @@ "harvest": "zombie", "special_attacks": [ [ "GRAB", 7 ] ], "death_drops": "mon_zombie_fireman_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", @@ -332,7 +325,6 @@ "harvest": "zombie", "special_attacks": [ [ "GRAB", 7 ] ], "death_drops": "mon_zombie_hazmat_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", @@ -376,7 +368,6 @@ "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 2, "accuracy": 3, "no_infection_chance": 10 }, [ "GRAB", 7 ], [ "scratch", 20 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "fungalize_into": "mon_zombie_fungus", "upgrades": { "half_life": 23, "into": "mon_devourer" }, @@ -425,7 +416,6 @@ "harvest": "zombie", "special_attacks": [ [ "GRAB", 7 ], [ "scratch", 15 ] ], "death_drops": "mon_zombie_swat_death_drops", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 28, "into": "mon_zombie_kevlar_1" }, "burn_into": "mon_zombie_scorched", "flags": [ @@ -473,7 +463,6 @@ "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 5, "min_mul": 0.7 }, [ "GRAB", 7 ], [ "scratch", 20 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "fungalize_into": "mon_zombie_fungus", "upgrades": { "half_life": 14, "into_group": "GROUP_ZOMBIE_UPGRADE" }, diff --git a/data/json/monsters/zed-pupating.json b/data/json/monsters/zed-pupating.json index 720b425073b94..f91e5faf54bd4 100644 --- a/data/json/monsters/zed-pupating.json +++ b/data/json/monsters/zed-pupating.json @@ -123,7 +123,6 @@ "harvest": "zombie", "special_attacks": [ [ "SMASH", 30 ] ], "death_drops": "mon_zombie_hulk_death_drops", - "death_function": [ "NORMAL" ], "regenerates": 10, "flags": [ "SEES", @@ -182,7 +181,6 @@ } ], "death_drops": "mon_zombie_hulk_death_drops", - "death_function": [ "NORMAL" ], "regenerates": 10, "flags": [ "SEES", diff --git a/data/json/monsters/zed-winged.json b/data/json/monsters/zed-winged.json index a3486fa0b58dc..bb8f2821c65e3 100644 --- a/data/json/monsters/zed-winged.json +++ b/data/json/monsters/zed-winged.json @@ -30,7 +30,6 @@ { "type": "leap", "cooldown": 10, "max_range": 5 } ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "upgrades": { "half_life": 28, "into": "mon_zombie_brute_winged" }, "flags": [ @@ -86,7 +85,6 @@ } ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_fiend", "flags": [ "SEES", @@ -128,7 +126,6 @@ "vision_night": 5, "harvest": "zombie", "special_attacks": [ { "id": "impale", "damage_max_instance": [ { "damage_type": "stab", "amount": 15, "armor_multiplier": 0.6 } ] } ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 28, "into_group": "GROUP_ZOMBIE_RAPTOR_UPGRADES" }, "flags": [ "SEES", @@ -170,7 +167,11 @@ [ "SUICIDE", 20 ], { "id": "impale", "damage_max_instance": [ { "damage_type": "stab", "amount": 15, "armor_multiplier": 0.6 } ] } ], - "death_function": [ "EXPLODE" ], + "death_function": { + "effect": { "id": "death_explosion_mon_spawn_raptor_unstable", "hit_self": true }, + "corpse_type": "NO_CORPSE", + "message": "The %s explodes!" + }, "upgrades": { } }, { diff --git a/data/json/monsters/zed_acid.json b/data/json/monsters/zed_acid.json index f86a90c6a635d..8a133e42c495c 100644 --- a/data/json/monsters/zed_acid.json +++ b/data/json/monsters/zed_acid.json @@ -26,7 +26,7 @@ "harvest": "zombie", "special_attacks": [ [ "ACID_BARF", 10 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "ACID", "NORMAL" ], + "death_function": { "message": "The %s's body leaks acid.", "effect": { "id": "death_acid", "hit_self": true } }, "burn_into": "mon_zombie_scorched", "upgrades": { "half_life": 10, "into": "mon_zombie_spitter" }, "flags": [ @@ -94,7 +94,7 @@ ], "special_when_hit": [ "ACIDSPLASH", 100 ], "death_drops": "default_zombie_death_drops", - "death_function": [ "ACID", "NORMAL" ], + "death_function": { "message": "The %s's body leaks acid.", "effect": { "id": "death_acid", "hit_self": true } }, "burn_into": "mon_zombie_scorched", "flags": [ "SEES", @@ -141,7 +141,7 @@ "harvest": "zombie", "special_attacks": [ [ "ACID", 20 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "ACID", "NORMAL" ], + "death_function": { "message": "The %s's body leaks acid.", "effect": { "id": "death_acid", "hit_self": true } }, "burn_into": "mon_zombie_scorched", "upgrades": { "half_life": 28, "into": "mon_zombie_corrosive" }, "flags": [ @@ -190,7 +190,7 @@ "harvest": "zombie", "special_attacks": [ [ "ACID_BARF", 22 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "ACID", "NORMAL" ], + "death_function": { "message": "The %s's body leaks acid.", "effect": { "id": "death_acid", "hit_self": true } }, "burn_into": "mon_zombie_scorched", "upgrades": { "half_life": 8, "into": "mon_zombie_acidic" }, "flags": [ @@ -237,7 +237,7 @@ "harvest": "zombie", "melee_damage": [ { "damage_type": "acid", "amount": 4 } ], "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "ACID_BARF", 10 ] ], - "death_function": [ "NORMAL", "ACID" ], + "death_function": { "message": "The %s's body leaks acid.", "effect": { "id": "death_acid", "hit_self": true } }, "upgrades": { "half_life": 12, "into": "mon_zombie_dog_brute_acidic" }, "flags": [ "SEES", diff --git a/data/json/monsters/zed_burned.json b/data/json/monsters/zed_burned.json index 6f94b14a48ae6..544686a927d44 100644 --- a/data/json/monsters/zed_burned.json +++ b/data/json/monsters/zed_burned.json @@ -30,7 +30,7 @@ "vision_day": 10, "vision_night": 3, "harvest": "zombie", - "death_function": [ "SMOKEBURST", "NORMAL" ], + "death_function": { "effect": { "id": "death_smokeburst", "hit_self": true }, "message": "A %s explodes!" }, "upgrades": { "half_life": 14, "into_group": "GROUP_CHILD_ZOMBIE_UPGRADE" }, "flags": [ "SEES", @@ -79,7 +79,7 @@ "vision_night": 3, "harvest": "zombie", "special_attacks": [ [ "SMASH", 30 ], [ "GRAB", 7 ] ], - "death_function": [ "SMOKEBURST", "NORMAL" ], + "death_function": { "effect": { "id": "death_smokeburst", "hit_self": true }, "message": "A %s explodes!" }, "upgrades": { "half_life": 21, "into_group": "GROUP_ZOMBIE_BRUTE" }, "flags": [ "SEES", "HEARS", "STUMBLES", "POISON", "NO_BREATHE", "REVIVES", "REVIVES_HEALTHY", "NO_NECRO", "FILTHY" ] }, @@ -114,7 +114,7 @@ "vision_night": 3, "harvest": "zombie", "special_attacks": [ [ "GRAB", 7 ] ], - "death_function": [ "SMOKEBURST", "NORMAL" ], + "death_function": { "effect": { "id": "death_smokeburst", "hit_self": true }, "message": "A %s explodes!" }, "upgrades": { "half_life": 14, "into_group": "GROUP_ZOMBIE_UPGRADE" }, "flags": [ "SEES", "HEARS", "STUMBLES", "POISON", "NO_BREATHE", "REVIVES", "REVIVES_HEALTHY", "NO_NECRO", "FILTHY" ] } diff --git a/data/json/monsters/zed_children.json b/data/json/monsters/zed_children.json index 575db8b2af31c..1d618888086a7 100644 --- a/data/json/monsters/zed_children.json +++ b/data/json/monsters/zed_children.json @@ -27,7 +27,6 @@ "vision_night": 3, "special_attacks": [ { "type": "bite", "cooldown": 2 } ], "death_drops": { "subtype": "collection", "groups": [ [ "default_zombie_clothes", 100 ], [ "child_items", 65 ] ] }, - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_child_scorched", "fungalize_into": "mon_zombie_child_fungus", "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ], @@ -65,7 +64,6 @@ "groups": [ [ "default_zombie_children_clothes", 100 ], [ "child_items", 65 ] ], "//": "default zombie children clothing (always), additional items from child_items (sometimes)" }, - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_child_scorched", "fungalize_into": "mon_zombie_child_fungus", "upgrades": { "half_life": 14, "into_group": "GROUP_CHILD_ZOMBIE_UPGRADE" }, @@ -99,7 +97,6 @@ "harvest": "zombie", "special_attacks": [ [ "SHRIEK", 5 ] ], "death_drops": { "subtype": "collection", "groups": [ [ "default_zombie_clothes", 100 ], [ "child_items", 65 ] ] }, - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_child_scorched", "fungalize_into": "mon_zombie_child_fungus", "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "CLIMBS", "FILTHY" ], @@ -134,7 +131,6 @@ "harvest": "zombie", "special_attacks": [ [ "SHRIEK", 5 ], [ "scratch", 15 ] ], "death_drops": { "subtype": "collection", "groups": [ [ "default_zombie_clothes", 100 ], [ "child_items", 65 ] ] }, - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_child_scorched", "fungalize_into": "mon_zombie_child_fungus", "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "GUILT", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ], @@ -169,7 +165,7 @@ "harvest": "zombie", "special_attacks": [ [ "GRAB", 5 ] ], "death_drops": { "subtype": "collection", "groups": [ [ "default_zombie_clothes", 100 ], [ "child_items", 65 ] ] }, - "death_function": [ "BOOMER" ], + "death_function": { "effect": { "id": "death_boomer", "hit_self": true }, "message": "A %s explode!", "corpse_type": "NO_CORPSE" }, "burn_into": "mon_zombie_child_scorched", "fungalize_into": "mon_zombie_child_fungus", "flags": [ "SEES", "HEARS", "STUMBLES", "WARM", "GUILT", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ], @@ -203,7 +199,6 @@ "harvest": "zombie", "special_attacks": [ [ "scratch", 10 ], { "type": "leap", "cooldown": 10, "max_range": 5 } ], "death_drops": { "subtype": "collection", "groups": [ [ "default_zombie_clothes", 100 ], [ "child_items", 65 ] ] }, - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_child_scorched", "fungalize_into": "mon_zombie_child_fungus", "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "CLIMBS", "FILTHY" ], @@ -240,7 +235,6 @@ "harvest": "zombie", "special_attacks": [ [ "SHRIEK", 15 ], [ "scratch", 10 ] ], "death_drops": { "subtype": "collection", "groups": [ [ "default_zombie_clothes", 100 ], [ "child_items", 65 ] ] }, - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_child_scorched", "fungalize_into": "mon_zombie_child_fungus", "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "GUILT", "POISON", "NO_BREATHE", "REVIVES", "HARDTOSHOOT", "FILTHY" ], diff --git a/data/json/monsters/zed_electric.json b/data/json/monsters/zed_electric.json index efa0f204ac83e..a5d1aaf2a4ca3 100644 --- a/data/json/monsters/zed_electric.json +++ b/data/json/monsters/zed_electric.json @@ -32,7 +32,6 @@ "special_attacks": [ [ "SHOCKSTORM", 15 ], [ "SMASH", 30 ] ], "special_when_hit": [ "ZAPBACK", 75 ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -79,7 +78,6 @@ "special_attacks": [ [ "SHOCKSTORM", 25 ] ], "special_when_hit": [ "ZAPBACK", 100 ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 28, "into_group": "GROUP_ZOMBIE_ELECTRIC_UPGRADE" }, "flags": [ "SEES", @@ -129,7 +127,6 @@ "emit_fields": [ { "emit_id": "emit_shock_cloud", "delay": "1 s" } ], "special_when_hit": [ "ZAPBACK", 75 ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "WARM", "POISON", "ELECTRIC", "NO_BREATHE", "REVIVES", "ELECTRIC_FIELD", "FILTHY" ] }, { @@ -159,7 +156,6 @@ "harvest": "zombie", "special_when_hit": [ "ZAPBACK", 100 ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 8, "into": "mon_zombie_electric" }, "flags": [ "SEES", diff --git a/data/json/monsters/zed_explosive.json b/data/json/monsters/zed_explosive.json index 766d6b5072e79..5dbd35018104b 100644 --- a/data/json/monsters/zed_explosive.json +++ b/data/json/monsters/zed_explosive.json @@ -25,7 +25,7 @@ "harvest": "exempt", "special_attacks": [ [ "BOOMER", 20 ], [ "scratch", 20 ] ], "death_drops": "default_zombie_items", - "death_function": [ "BOOMER" ], + "death_function": { "effect": { "id": "death_boomer", "hit_self": true }, "message": "A %s explode!", "corpse_type": "NO_CORPSE" }, "upgrades": { "half_life": 14, "into": "mon_boomer_huge" }, "fungalize_into": "mon_boomer_fungus", "flags": [ @@ -76,7 +76,11 @@ "fungalize_into": "mon_boomer_fungus", "special_attacks": [ [ "BOOMER_GLOW", 20 ], [ "scratch", 20 ] ], "death_drops": "default_zombie_items", - "death_function": [ "BOOMER_GLOW" ], + "death_function": { + "effect": { "id": "death_boomer_glow", "hit_self": true, "min_level": 1 }, + "message": "A %s explode!", + "corpse_type": "NO_CORPSE" + }, "flags": [ "SEES", "GOODHEARING", @@ -121,7 +125,7 @@ "harvest": "exempt", "special_attacks": [ [ "scratch", 20 ] ], "death_drops": "default_zombie_items", - "death_function": [ "CONFLAGRATION" ], + "death_function": { "effect": { "id": "death_conflagration", "hit_self": true }, "message": "A %s explodes!", "corpse_type": "NO_CORPSE" }, "flags": [ "SEES", "HEARS", @@ -164,7 +168,7 @@ "emit_fields": [ { "emit_id": "emit_toxic_leak", "delay": "1 s" } ], "special_attacks": [ [ "SUICIDE", 20 ], [ "scratch", 15 ] ], "death_drops": "default_zombie_items", - "death_function": [ "GAS" ], + "death_function": { "message": "A %s explodes!", "effect": { "id": "death_gas", "hit_self": true }, "corpse_type": "NO_CORPSE" }, "fungalize_into": "mon_zombie_gasbag_fungus", "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ] } diff --git a/data/json/monsters/zed_ferrous.json b/data/json/monsters/zed_ferrous.json index 7daa684791f61..e4f32142da0d3 100644 --- a/data/json/monsters/zed_ferrous.json +++ b/data/json/monsters/zed_ferrous.json @@ -26,7 +26,6 @@ "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "GRAB", 7 ], [ "scratch", 20 ] ], "attack_effs": [ { "id": "tetanus", "chance": 10 } ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "upgrades": { "half_life": 15, "into_group": "GROUP_FERROUS_UPGRADE" }, "flags": [ @@ -75,7 +74,6 @@ "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "GRAB", 7 ], [ "scratch", 20 ] ], "attack_effs": [ { "id": "tetanus", "chance": 10 } ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "upgrades": { "half_life": 15, "into_group": "GROUP_FERROUS_UPGRADE" }, "flags": [ @@ -126,7 +124,6 @@ "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "GRAB", 7 ], [ "scratch", 20 ] ], "attack_effs": [ { "id": "tetanus", "chance": 10 } ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", @@ -171,7 +168,6 @@ "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "GRAB", 7 ], [ "scratch", 20 ], [ "impale", 25 ] ], "attack_effs": [ { "id": "tetanus", "chance": 20 } ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", @@ -218,7 +214,6 @@ "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "GRAB", 7 ], [ "scratch", 20 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "attack_effs": [ { "id": "tetanus", "chance": 10 } ], "burn_into": "mon_zombie_scorched", "flags": [ diff --git a/data/json/monsters/zed_fusion.json b/data/json/monsters/zed_fusion.json index c24ca3f68fc9e..62e15403ce9cd 100644 --- a/data/json/monsters/zed_fusion.json +++ b/data/json/monsters/zed_fusion.json @@ -23,7 +23,6 @@ "armor_bash": 8, "harvest": "zombie_leather", "fear_triggers": [ "HURT", "FIRE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "BASHES", "GROUP_BASH", "POISON", "HUMAN" ] }, { @@ -58,7 +57,6 @@ "subtype": "collection", "groups": [ "default_zombie_death_drops", "default_zombie_death_drops", "default_zombie_death_drops" ] }, - "death_function": [ "NORMAL" ], "regenerates": 1, "flags": [ "SEES", @@ -106,7 +104,7 @@ "bleed_rate": 0, "harvest": "exempt", "special_attacks": [ [ "FLESH_TENDRIL", 1 ] ], - "death_function": [ "GAS" ], + "death_function": { "message": "A %s explodes!", "effect": { "id": "death_gas", "hit_self": true }, "corpse_type": "NO_CORPSE" }, "flags": [ "SEES", "HEARS", "SMELLS", "IMMOBILE", "WARM", "POISON", "IMMOBILE", "NO_BREATHE", "FILTHY" ] }, { @@ -136,7 +134,7 @@ "special_attacks": [ [ "SUICIDE", 20 ] ], "death_drops": "default_zombie_items", "upgrades": { "half_life": 8, "into": "mon_zombie_gasbag_crawler" }, - "death_function": [ "GAS" ], + "death_function": { "message": "A %s explodes!", "effect": { "id": "death_gas", "hit_self": true }, "corpse_type": "NO_CORPSE" }, "flags": [ "SEES", "HEARS", "SMELLS", "IMMOBILE", "WARM", "POISON", "NO_BREATHE", "FILTHY" ] }, { @@ -168,7 +166,7 @@ "vision_night": 50, "harvest": "exempt", "special_attacks": [ { "type": "leap", "cooldown": 5, "max_range": 5, "allow_no_target": true }, [ "scratch", 5 ] ], - "death_function": [ "GAS" ], + "death_function": { "message": "A %s explodes!", "effect": { "id": "death_gas", "hit_self": true }, "corpse_type": "NO_CORPSE" }, "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "POISON", "CLIMBS", "NO_BREATHE", "CLIMBS", "HARDTOSHOOT" ] }, { @@ -211,7 +209,7 @@ { "type": "leap", "cooldown": 15, "max_range": 2, "allow_no_target": true }, [ "scratch", 5 ] ], - "death_function": [ "GAS" ], + "death_function": { "message": "A %s explodes!", "effect": { "id": "death_gas", "hit_self": true }, "corpse_type": "NO_CORPSE" }, "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "POISON", "CLIMBS", "NO_BREATHE", "CLIMBS", "HARDTOSHOOT" ] }, { @@ -242,7 +240,7 @@ "bleed_rate": 50, "vision_day": 1, "special_attacks": [ { "type": "leap", "cooldown": 5, "max_range": 3, "allow_no_target": true }, [ "scratch", 5 ] ], - "death_function": [ "GAS" ], + "death_function": { "message": "A %s explodes!", "effect": { "id": "death_gas", "hit_self": true }, "corpse_type": "NO_CORPSE" }, "flags": [ "SEES", "HEARS", "GOODHEARING", "WARM", "POISON", "CLIMBS", "NO_BREATHE", "CLIMBS", "HARDTOSHOOT" ] }, { @@ -274,7 +272,7 @@ "vision_night": 2, "harvest": "exempt", "special_attacks": [ [ "RANGED_PULL", 20 ], [ "SMASH", 20 ] ], - "death_function": [ "GAS" ], + "death_function": { "message": "A %s explodes!", "effect": { "id": "death_gas", "hit_self": true }, "corpse_type": "NO_CORPSE" }, "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "POISON", "CLIMBS", "NO_BREATHE", "IMMOBILE", "RANGED_ATTACKER" ] }, { @@ -300,7 +298,6 @@ "armor_bullet": 20, "bleed_rate": 50, "harvest": "exempt", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "IMMOBILE", "WARM", "POISON", "IMMOBILE", "NO_BREATHE", "FILTHY" ] }, { @@ -326,7 +323,6 @@ "armor_bullet": 10, "bleed_rate": 0, "harvest": "exempt", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "IMMOBILE", "WARM", "POISON", "IMMOBILE", "NO_BREATHE", "FILTHY" ] } ] diff --git a/data/json/monsters/zed_lab.json b/data/json/monsters/zed_lab.json index 2ecba334e2048..6006681666c71 100644 --- a/data/json/monsters/zed_lab.json +++ b/data/json/monsters/zed_lab.json @@ -29,7 +29,6 @@ "path_settings": { "max_dist": 5 }, "special_attacks": [ [ "scratch", 20 ] ], "death_drops": "mon_zombie_scientist_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "upgrades": { "half_life": 28, "into_group": "GROUP_ZOMBIE_UPGRADE" }, "flags": [ @@ -81,7 +80,6 @@ "harvest": "zombie", "special_attacks": [ [ "GRAB", 10 ], [ "scratch", 10 ] ], "death_drops": "mon_zombie_labsecurity_death_drops", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 28, "into_group": "GROUP_SOLDIER_UPGRADE" }, "burn_into": "mon_zombie_scorched", "flags": [ @@ -139,7 +137,7 @@ } ], "death_drops": "phase_zombie_death_drops", - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "GROUP_BASH", "NOGIB", "POISON", "FILTHY", "STUN_IMMUNE" ] }, { diff --git a/data/json/monsters/zed_misc.json b/data/json/monsters/zed_misc.json index 615eb9bd17c66..655ddb00596f0 100644 --- a/data/json/monsters/zed_misc.json +++ b/data/json/monsters/zed_misc.json @@ -37,7 +37,6 @@ "monster_message": "Some of the pustules pop, and the frog mother opens her mouth and vomits tadpoles!" } ], - "death_function": [ "NORMAL" ], "regenerates": 40, "regen_morale": true, "flags": [ @@ -82,7 +81,11 @@ "vision_night": 7, "harvest": "exempt", "special_attacks": [ { "type": "leap", "cooldown": 10, "move_cost": 0, "max_range": 4, "min_consider_range": 2 }, [ "GRAB", 1 ] ], - "death_function": [ "ACID", "MELT" ], + "death_function": { + "message": "The %s's body melts away.", + "effect": { "id": "death_acid", "hit_self": true }, + "corpse_type": "NO_CORPSE" + }, "flags": [ "SEES", "HEARS", "SMELLS", "KEENNOSE", "STUMBLES", "WARM", "POISON", "GRABS", "NO_BREATHE", "FILTHY" ] }, { @@ -127,7 +130,6 @@ [ "GRAB", 4 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", @@ -175,7 +177,6 @@ "special_attacks": [ [ "GRAB", 7 ], [ "scratch", 20 ] ], "//4": "Removed Bite attack to reflect damage to mouth.", "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "upgrades": { "half_life": 8, "into": "mon_zombie_ears" }, "flags": [ @@ -222,7 +223,6 @@ "harvest": "zombie", "special_attacks": [ [ "SMASH", 30 ], [ "GRAB", 7 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_fiend", "upgrades": { "half_life": 21, "into_group": "GROUP_ZOMBIE_BRUTE" }, "fungalize_into": "mon_zombie_fungus", @@ -274,7 +274,6 @@ "harvest": "zombie", "special_attacks": [ [ "SMASH", 30 ], [ "BIO_OP_TAKEDOWN", 20 ], [ "RANGED_PULL", 20 ], [ "GRAB_DRAG", 10 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_fiend", "flags": [ "SEES", @@ -325,7 +324,6 @@ "harvest": "zombie", "special_attacks": [ [ "SMASH", 40 ], [ "STRETCH_ATTACK", 20 ], [ "LONGSWIPE", 20 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_fiend", "flags": [ "SEES", @@ -373,7 +371,6 @@ "special_attacks": [ [ "GRAB", 6 ], [ "scratch", 20 ] ], "//3": "Removed Bite as this creature does not have a 'mouth'.", "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "upgrades": { "half_life": 28, "into": "mon_zombie_skull" }, "flags": [ @@ -420,7 +417,6 @@ "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "scratch", 20 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "upgrades": { "half_life": 14, "into_group": "GROUP_ZOMBIE_GRAB" }, "fungalize_into": "mon_zombie_fungus", @@ -468,7 +464,6 @@ "harvest": "zombie", "special_attacks": [ [ "RANGED_PULL", 20 ], [ "GRAB_DRAG", 3 ], { "type": "bite", "cooldown": 5 } ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "fungalize_into": "mon_zombie_fungus", "flags": [ @@ -518,7 +513,11 @@ "vision_night": 3, "harvest": "zombie", "special_attacks": [ [ "STRETCH_BITE", 10 ], [ "STRETCH_ATTACK", 5 ] ], - "death_function": [ "BLOBSPLIT" ], + "death_function": { + "message": "The %s splits in two!", + "corpse_type": "NO_CORPSE", + "effect": { "id": "death_blobsplit", "hit_self": true } + }, "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "BASHES", "GROUP_BASH", "POISON", "NO_BREATHE", "FILTHY" ] }, { @@ -552,7 +551,6 @@ "harvest": "zombie", "special_attacks": [ [ "SMASH", 20 ] ], "death_drops": "mon_zombie_hulk_death_drops", - "death_function": [ "NORMAL" ], "fungalize_into": "mon_zombie_fungus", "flags": [ "SEES", @@ -605,7 +603,6 @@ } ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "upgrades": { "half_life": 28, "into": "mon_zombie_predator" }, "fungalize_into": "mon_zombie_fungus", @@ -641,7 +638,7 @@ "harvest": "zombie", "special_attacks": [ [ "JACKSON", 0 ] ], "death_drops": "jackson_drops", - "death_function": [ "JACKSON" ], + "death_function": { "message": "The music stops!", "effect": { "id": "death_jackson", "hit_self": true }, "corpse_type": "NO_CORPSE" }, "flags": [ "SEES", "SMELLS", "WARM", "BASHES", "NO_BREATHE", "POISON", "FILTHY" ] }, { @@ -687,7 +684,6 @@ [ "GRAB_DRAG", 10 ] ], "death_drops": "mon_zombie_swimmer_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", @@ -740,7 +736,6 @@ "special_attacks": [ [ "UPGRADE", 10 ] ], "anger_triggers": [ "HURT", "PLAYER_CLOSE", "PLAYER_WEAK" ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", @@ -789,7 +784,6 @@ "special_attacks": [ [ "RESURRECT", 0 ] ], "anger_triggers": [ "HURT", "PLAYER_CLOSE", "PLAYER_WEAK" ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", @@ -815,7 +809,10 @@ "description": "At first this creature looks like nothing more than a grotesque and oleaginous husk, bloated and punctured by jet-black pustules. When approached, its glowing red eyes and an aching grin take form; its skin tears and its guts teem with unmatched fecundity, as its gaze inspires fear of nothing less than cosmic, inhuman ecstasy.", "copy-from": "mon_zombie_necro", "diff": 25, - "death_function": [ "NECRO_BOOMER" ] + "death_function": { + "effect": { "id": "necro_boomer_death", "hit_self": true }, + "message": "The %s lets out an unholy screech, and the corpses around it stir." + } }, { "id": "mon_zombie_runner", @@ -851,7 +848,6 @@ } ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "upgrades": { "half_life": 20, "into": "mon_zombie_hunter" }, "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "PUSH_MON", "FILTHY" ] @@ -896,7 +892,6 @@ { "id": "impale" } ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "PUSH_MON", "FILTHY" ] }, @@ -929,7 +924,6 @@ "harvest": "zombie", "special_attacks": [ [ "SHRIEK_ALERT", 20 ], [ "SHRIEK_STUN", 1 ], [ "scratch", 20 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", "KEENNOSE", "STUMBLES", "WARM", "BASHES", "GROUP_BASH", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ] }, @@ -959,7 +953,6 @@ "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "GRAB", 7 ], [ "scratch", 20 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 28, "into_group": "GROUP_ZOMBIE_SHADY_UPGRADES" }, "burn_into": "mon_zombie_scorched", "flags": [ @@ -1007,7 +1000,6 @@ "anger_triggers": [ "STALK", "PLAYER_WEAK", "HURT", "PLAYER_CLOSE" ], "fear_triggers": [ "FIRE" ], "death_drops": { "groups": [ [ "shia_stuff", 1 ] ] }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "WARM", "BASHES", "POISON", "NO_BREATHE", "PATH_AVOID_DANGER_2", "PRIORITIZE_TARGETS", "FILTHY" ] }, { @@ -1038,7 +1030,6 @@ "harvest": "zombie", "special_attacks": [ [ "SHRIEK", 10 ], [ "GRAB", 7 ], [ "scratch", 20 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "fungalize_into": "mon_zombie_fungus", "upgrades": { "half_life": 10, "into": "mon_zombie_screecher" }, @@ -1088,7 +1079,6 @@ "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 5, "min_mul": 0.7 }, [ "GRAB", 6 ], [ "scratch", 15 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "HEARS", @@ -1135,7 +1125,7 @@ "harvest": "exempt", "emit_fields": [ { "emit_id": "emit_smoke_stream", "delay": "1 s" } ], "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "scratch", 15 ] ], - "death_function": [ "SMOKEBURST" ], + "death_function": { "effect": { "id": "death_smokeburst", "hit_self": true }, "message": "A %s explode!" }, "fungalize_into": "mon_zombie_smoker_fungus", "upgrades": { "half_life": 28, "into": "mon_smoker_brute" }, "flags": [ @@ -1186,7 +1176,7 @@ "harvest": "exempt", "emit_fields": [ { "emit_id": "emit_smoke_stream", "delay": "1 s" } ], "special_attacks": [ [ "SMASH", 30 ], { "type": "bite", "cooldown": 5 }, [ "scratch", 15 ], [ "RANGED_PULL", 20 ], [ "GRAB_DRAG", 10 ] ], - "death_function": [ "SMOKEBURST" ], + "death_function": { "effect": { "id": "death_smokeburst", "hit_self": true }, "message": "A %s explode!" }, "flags": [ "SEES", "HEARS", @@ -1230,7 +1220,6 @@ "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "GRAB", 7 ], [ "scratch", 20 ] ], "death_drops": "mon_zombie_swimmer_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "fungalize_into": "mon_zombie_fungus", "upgrades": { "half_life": 14, "into": "mon_zombie_swimmer" }, @@ -1276,7 +1265,6 @@ "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "GRAB", 7 ], [ "scratch", 20 ] ], "death_drops": "mon_zombie_swimmer_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "fungalize_into": "mon_zombie_fungus", "upgrades": { "half_life": 28, "into": "mon_zombie_mancroc" }, @@ -1328,7 +1316,6 @@ "fungalize_into": "mon_zombie_fungus", "special_attacks": [ [ "PULL_METAL_WEAPON", 25 ], { "type": "bite", "cooldown": 20 } ], "death_drops": "mon_zombie_technician_death_drops", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -1375,7 +1362,6 @@ "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 20 } ], "death_drops": "mon_zombie_miner_death_drops", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "BASHES", "GROUP_BASH", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ] }, { @@ -1408,7 +1394,6 @@ "attack_effs": [ { "id": "paralyzepoison", "duration": 33 } ], "special_attacks": [ [ "GRAB", 7 ], [ "scratch", 20 ], [ "PARA_STING", 30 ] ], "death_drops": "mon_zombie_thorny_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", diff --git a/data/json/monsters/zed_radiation.json b/data/json/monsters/zed_radiation.json index 2e24ba85692d2..1a787a7b9f444 100644 --- a/data/json/monsters/zed_radiation.json +++ b/data/json/monsters/zed_radiation.json @@ -30,7 +30,7 @@ "harvest": "zombie", "special_attacks": [ [ "LONGSWIPE", 8 ], { "id": "scratch", "damage_max_instance": [ { "damage_type": "cut", "amount": 21 } ] } ], "death_drops": { "groups": [ [ "vault_wanderer", 1 ] ] }, - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "GROUP_BASH", "NOGIB", "POISON", "FILTHY" ] }, { @@ -64,7 +64,7 @@ "harvest": "zombie", "special_attacks": [ [ "LUNGE", 20 ] ], "death_drops": { "groups": [ [ "vault_wanderer", 3 ] ] }, - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "GROUP_BASH", "NOGIB", "POISON", "FILTHY" ] }, { @@ -99,7 +99,7 @@ "harvest": "zombie", "special_attacks": [ [ "LUNGE", 15 ] ], "death_drops": { "groups": [ [ "vault_wanderer", 3 ] ] }, - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "GROUP_BASH", "NOGIB", "POISON", "FILTHY" ] }, { @@ -134,7 +134,7 @@ "harvest": "zombie", "special_attacks": [ [ "LUNGE", 10 ] ], "death_drops": { "groups": [ [ "vault_wanderer", 3 ] ] }, - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "GROUP_BASH", "NOGIB", "POISON", "FILTHY" ] }, { @@ -169,7 +169,7 @@ "harvest": "zombie", "special_attacks": [ [ "LUNGE", 5 ] ], "death_drops": { "groups": [ [ "vault_wanderer", 3 ] ] }, - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "GROUP_BASH", "NOGIB", "POISON", "FILTHY" ] } ] diff --git a/data/json/monsters/zed_skeletal.json b/data/json/monsters/zed_skeletal.json index e5a7aaac6c16a..bf8f65955d53a 100644 --- a/data/json/monsters/zed_skeletal.json +++ b/data/json/monsters/zed_skeletal.json @@ -32,7 +32,6 @@ "special_attacks": [ [ "scratch", 10 ], { "type": "bite", "cooldown": 5 } ], "upgrades": { "half_life": 15, "into": "mon_skeleton_brute" }, "death_drops": "default_zombie_clothes", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "HARDTOSHOOT", "REVIVES", "NO_BREATHE", "POISON", "FILTHY" ] }, { @@ -72,7 +71,6 @@ ], "upgrades": { "half_life": 12, "into": "mon_skeleton_hulk" }, "death_drops": "default_zombie_clothes", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "HARDTOSHOOT", "REVIVES", "NO_BREATHE", "POISON", "FILTHY" ] }, { @@ -109,7 +107,6 @@ "harvest": "mr_bones", "special_attacks": [ [ "scratch", 10 ], { "type": "bite", "cooldown": 5 }, [ "SHOCKSTORM", 25 ] ], "death_drops": "default_zombie_clothes", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "ELECTRIC", "REVIVES", "NO_BREATHE", "POISON", "FILTHY" ] }, { @@ -148,7 +145,6 @@ { "id": "scratch", "damage_max_instance": [ { "damage_type": "cut", "amount": 23, "armor_multiplier": 0.8 } ] } ], "death_drops": "mon_zombie_hulk_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_fiend", "flags": [ "SEES", diff --git a/data/json/monsters/zed_soldiers.json b/data/json/monsters/zed_soldiers.json index f6054fd132d03..fb3d16eb90ae9 100644 --- a/data/json/monsters/zed_soldiers.json +++ b/data/json/monsters/zed_soldiers.json @@ -30,7 +30,6 @@ "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 5, "min_mul": 0.8 } ], "death_drops": "mon_zombie_soldier_death_drops", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 28, "into_group": "GROUP_SOLDIER_UPGRADE" }, "burn_into": "mon_zombie_scorched", "fungalize_into": "mon_zombie_fungus", @@ -74,7 +73,6 @@ } ], "death_drops": "mon_zombie_soldier_death_drops", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 38, "into": "mon_zombie_soldier_blackops_2" }, "burn_into": "mon_zombie_scorched", "flags": [ @@ -141,7 +139,11 @@ "ranges": [ [ 2, 20, "DEFAULT" ] ] } ], - "death_function": [ "ACID" ], + "death_function": { + "message": "The %s's body dissolves into acid.", + "effect": { "id": "death_acid", "hit_self": true }, + "corpse_type": "NO_CORPSE" + }, "flags": [ "ACIDPROOF", "ACID_BLOOD" ] } }, @@ -173,7 +175,11 @@ "ranges": [ [ 2, 8, "DEFAULT" ] ] } ], - "death_function": [ "ACID" ], + "death_function": { + "message": "The %s's body dissolves into acid.", + "effect": { "id": "death_acid", "hit_self": true }, + "corpse_type": "NO_CORPSE" + }, "flags": [ "ACIDPROOF", "ACID_BLOOD" ] } }, @@ -212,7 +218,6 @@ [ "SMASH", 30 ] ], "death_drops": "mon_zombie_kevlar_death_drops", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 42, "into": "mon_zombie_kevlar_2" }, "burn_into": "mon_zombie_scorched", "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "BASHES", "GROUP_BASH", "POISON", "NO_BREATHE", "REVIVES", "PUSH_MON", "FILTHY" ] @@ -253,7 +258,6 @@ [ "SMASH", 20 ] ], "death_drops": "mon_zombie_kevlar_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "BASHES", "GROUP_BASH", "POISON", "NO_BREATHE", "REVIVES", "PUSH_MON", "FILTHY" ] }, @@ -288,7 +292,6 @@ "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "GRAB", 7 ], [ "scratch", 20 ] ], "death_drops": "mon_zombie_military_pilot_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", @@ -348,7 +351,7 @@ "harvest": "zombie", "starting_ammo": { "pressurized_tank": 1000 }, "death_drops": { "subtype": "collection", "groups": [ [ "mon_zombie_soldier_death_drops", 100 ], [ "mon_zombie_flamer", 100 ] ] }, - "death_function": [ "FIREBALL" ], + "death_function": { "effect": { "id": "death_fireball", "hit_self": true } }, "burn_into": "mon_zombie_scorched", "flags": [ "SEES", @@ -398,7 +401,6 @@ "vision_night": 3, "harvest": "zombie", "death_drops": "mon_zombie_armored_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "BASHES", "GROUP_BASH", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ] }, @@ -436,7 +438,6 @@ "special_attacks": [ [ "BIO_OP_TAKEDOWN", 20 ] ], "special_when_hit": [ "ZAPBACK", 75 ], "death_drops": "mon_zombie_bio_op_death_drops", - "death_function": [ "NORMAL" ], "fungalize_into": "mon_zombie_fungus", "flags": [ "SEES", diff --git a/data/json/monsters/zed_survivor.json b/data/json/monsters/zed_survivor.json index e6b3913ff5ea2..b3f147d91fd18 100644 --- a/data/json/monsters/zed_survivor.json +++ b/data/json/monsters/zed_survivor.json @@ -36,7 +36,6 @@ { "id": "scratch", "damage_max_instance": [ { "damage_type": "cut", "amount": 16 } ] } ], "death_drops": "mon_zombie_survivor_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "fungalize_into": "mon_zombie_fungus", "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "BASHES", "GROUP_BASH", "POISON", "NO_BREATHE", "REVIVES", "PUSH_MON", "FILTHY" ] diff --git a/data/mods/Aftershock/mobs/PrepPhyle_mobs.json b/data/mods/Aftershock/mobs/PrepPhyle_mobs.json index 1c1b8b25b203c..601f46666c698 100644 --- a/data/mods/Aftershock/mobs/PrepPhyle_mobs.json +++ b/data/mods/Aftershock/mobs/PrepPhyle_mobs.json @@ -59,7 +59,6 @@ "upgrades": { "age_grow": 42, "into": "afs_mon_cyber_mastiff" }, "biosignature": { "biosig_item": "feces_dog", "biosig_timer": 6 }, "fear_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT" ], - "death_function": [ "NORMAL" ], "special_attacks": [ [ "EAT_FOOD", 100 ] ], "flags": [ "ANIMAL", "DOGFOOD", "HEARS", "KEENNOSE", "PATH_AVOID_DANGER_1", "SEES", "SMELLS", "WARM" ] } diff --git a/data/mods/Aftershock/mobs/abstract_monsters.json b/data/mods/Aftershock/mobs/abstract_monsters.json index d2fbd1dc34a4b..d7954840f18d9 100644 --- a/data/mods/Aftershock/mobs/abstract_monsters.json +++ b/data/mods/Aftershock/mobs/abstract_monsters.json @@ -28,7 +28,7 @@ "vision_day": 50, "path_settings": { "max_dist": 5 }, "death_drops": { "groups": [ [ "broken_robots", 1 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", "BASHES", "ELECTRONIC", "NO_BREATHE", "PRIORITIZE_TARGETS", "PATH_AVOID_DANGER_1" ] }, { @@ -62,7 +62,7 @@ "vision_day": 50, "path_settings": { "max_dist": 5 }, "death_drops": { "groups": [ [ "broken_robots", 1 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", "BASHES", "ELECTRONIC", "NO_BREATHE", "PRIORITIZE_TARGETS", "PATH_AVOID_DANGER_1" ] }, { diff --git a/data/mods/Aftershock/mobs/aliens.json b/data/mods/Aftershock/mobs/aliens.json index f1a43aa30ff1e..f6ac6e32e6049 100644 --- a/data/mods/Aftershock/mobs/aliens.json +++ b/data/mods/Aftershock/mobs/aliens.json @@ -22,7 +22,6 @@ "reproduction": { "baby_monster": "afs_mon_rabbit", "baby_count": 3, "baby_timer": 55 }, "harvest": "alien_small_fur", "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "CATTLEFODDER", "PET_WONT_FOLLOW", "WARM" ] }, { @@ -51,7 +50,6 @@ "vision_night": 25, "path_settings": { "max_dist": 10 }, "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "harvest": "alien_large_leather", "biosignature": { "biosig_item": "feces_manure", "biosig_timer": 8 }, "flags": [ "SEES", "HEARS", "SMELLS", "PET_MOUNTABLE", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM" ] @@ -85,7 +83,6 @@ "vision_night": 7, "path_settings": { "max_dist": 10 }, "anger_triggers": [ "HURT", "MATING_SEASON" ], - "death_function": [ "NORMAL" ], "baby_flags": [ "AUTUMN" ], "harvest": "alien_large_leather", "biosignature": { "biosig_item": "feces_manure", "biosig_timer": 8 }, @@ -119,7 +116,6 @@ "harvest": "alien_small_fur", "path_settings": { "max_dist": 10 }, "anger_triggers": [ "PLAYER_WEAK", "FRIEND_ATTACKED", "FRIEND_DIED" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "WARM", "SWIMS", "ANIMAL", "PATH_AVOID_DANGER_1", "STUMBLES" ] }, { @@ -149,7 +145,6 @@ "harvest": "alien_mammal_fur", "path_settings": { "max_dist": 10 }, "anger_triggers": [ "STALK", "FRIEND_ATTACKED", "FRIEND_DIED", "PLAYER_WEAK", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "KEENNOSE" ] } ] diff --git a/data/mods/Aftershock/mobs/mutants.json b/data/mods/Aftershock/mobs/mutants.json index 28253feaa4eeb..74742e1ce3aa1 100644 --- a/data/mods/Aftershock/mobs/mutants.json +++ b/data/mods/Aftershock/mobs/mutants.json @@ -28,7 +28,6 @@ "vision_night": 3, "path_settings": { "avoid_traps": true, "avoid_sharp": true }, "death_drops": "cryo_lab_drops", - "death_function": [ "NORMAL" ], "anger_triggers": [ "FRIEND_DIED", "FRIEND_ATTACKED", "HURT" ], "flags": [ "SEES", "HEARS", "SMELLS", "BASHES", "GROUP_BASH", "HUMAN", "CAN_OPEN_DOORS", "PATH_AVOID_DANGER_1", "COLDPROOF" ] }, diff --git a/data/mods/Aftershock/mobs/robots.json b/data/mods/Aftershock/mobs/robots.json index c6a4acca00f15..fda0b5e8bc295 100644 --- a/data/mods/Aftershock/mobs/robots.json +++ b/data/mods/Aftershock/mobs/robots.json @@ -32,7 +32,7 @@ } ], "death_drops": { }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "ELECTRONIC", "IMMOBILE", "NO_BREATHE" ] }, { @@ -74,7 +74,7 @@ "starting_ammo": { "40x46mm_m433": 100, "556": 1000 }, "path_settings": { "max_dist": 10 }, "special_attacks": [ [ "CHICKENBOT", 4 ] ], - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", "BASHES", "NO_BREATHE", "ELECTRONIC", "PRIORITIZE_TARGETS", "DROPS_AMMO" ] }, { @@ -106,7 +106,7 @@ "starting_ammo": { "40x46mm_m433": 200, "556": 3000 }, "path_settings": { "max_dist": 20 }, "special_attacks": [ [ "MULTI_ROBOT", 3 ] ], - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", @@ -167,7 +167,7 @@ } ], "death_drops": { "groups": [ [ "robots", 4 ], [ "tripod", 1 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", "GOODHEARING", "BASHES", "NO_BREATHE", "ELECTRONIC", "CLIMBS", "PRIORITIZE_TARGETS", "FIREPROOF" ] }, { @@ -210,7 +210,7 @@ "targeting_sound": "\"Dispatching hostile with lethal force.\"" } ], - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "death_drops": { "groups": [ [ "mon_afs_sentinel_lx_drops", 1 ] ] }, "flags": [ "SEES", @@ -245,7 +245,7 @@ "armor_bullet": 6, "revert_to_itype": "bot_bloodhound_drone", "death_drops": { "groups": [ [ "robots", 4 ], [ "manhack", 1 ], [ "turret_searchlight", 1 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "extend": { "flags": [ "HIT_AND_RUN" ] } }, { @@ -271,7 +271,7 @@ "armor_fire": 4, "armor_acid": 6, "vision_day": 50, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "death_drops": { "groups": [ [ "broken_robots", 3 ] ] }, "flags": [ "SEES", "HEARS", "ELECTRONIC", "NO_BREATHE", "PRIORITIZE_TARGETS", "PATH_AVOID_DANGER_1" ] }, @@ -368,7 +368,7 @@ "vision_day": 50, "special_attacks": [ { "id": "hypo_pkill" } ], "anger_triggers": [ "FRIEND_ATTACKED", "PLAYER_WEAK", "HURT", "PLAYER_CLOSE" ], - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "death_drops": { "groups": [ [ "broken_robots", 3 ] ] }, "flags": [ "SEES", "HEARS", "ELECTRONIC", "NO_BREATHE", "PRIORITIZE_TARGETS", "PATH_AVOID_DANGER_1" ] }, diff --git a/data/mods/Aftershock/mobs/turrets.json b/data/mods/Aftershock/mobs/turrets.json index 95ab5f628d82c..dd66f296d7e8c 100644 --- a/data/mods/Aftershock/mobs/turrets.json +++ b/data/mods/Aftershock/mobs/turrets.json @@ -33,7 +33,7 @@ ], "special_when_hit": [ "RETURN_FIRE", 100 ], "death_drops": { }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "NOHEAD", "ELECTRONIC", "COLDPROOF", "IMMOBILE", "NO_BREATHE" ] } ] diff --git a/data/mods/Aftershock/mobs/uplifted_monsters.json b/data/mods/Aftershock/mobs/uplifted_monsters.json index 6bf8dd1ab0d90..1fe127f542dd2 100644 --- a/data/mods/Aftershock/mobs/uplifted_monsters.json +++ b/data/mods/Aftershock/mobs/uplifted_monsters.json @@ -48,7 +48,6 @@ "vision_night": 10, "path_settings": { "max_dist": 10 }, "anger_triggers": [ "HURT", "PLAYER_NEAR_BABY" ], - "death_function": [ "NORMAL" ], "zombify_into": "mon_zombie_upliftedbear", "death_drops": "xl_uplift_death_drop", "harvest": "demihuman_large_fur", @@ -106,7 +105,6 @@ "death_drops": "xl_uplift_death_drop", "harvest": "demihuman_large_fur", "special_attacks": [ [ "scratch", 20 ] ], - "death_function": [ "NORMAL" ], "zombify_into": "mon_uplifted_ape_zed", "flags": [ "SEES", "SMELLS", "HEARS", "WARM", "BASHES", "GROUP_BASH", "ANIMAL", "PATH_AVOID_DANGER_1", "PATH_AVOID_DANGER_1" ] }, @@ -159,7 +157,6 @@ "vision_night": 7, "path_settings": { "max_dist": 10 }, "anger_triggers": [ "HURT", "PLAYER_NEAR_BABY" ], - "death_function": [ "NORMAL" ], "zombify_into": "mon_zombie_upliftedoctopus", "death_drops": "seabased_death_drop", "harvest": "demihuman", diff --git a/data/mods/Aftershock/mobs/water_mobs.json b/data/mods/Aftershock/mobs/water_mobs.json index 74d02d52527aa..d21389b41385b 100644 --- a/data/mods/Aftershock/mobs/water_mobs.json +++ b/data/mods/Aftershock/mobs/water_mobs.json @@ -34,7 +34,6 @@ { "id": "scratch", "damage_max_instance": [ { "damage_type": "cut", "amount": 19, "armor_multiplier": 0.8 } ] }, [ "TENTACLE", 5 ] ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", @@ -86,7 +85,6 @@ [ "TENTACLE", 5 ], { "type": "spell", "spell_data": { "id": "mi-go_slaver_beam", "min_level": 1 }, "cooldown": 400 } ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", diff --git a/data/mods/Aftershock/mobs/zombies.json b/data/mods/Aftershock/mobs/zombies.json index 3736086ec200a..da720040b5db4 100644 --- a/data/mods/Aftershock/mobs/zombies.json +++ b/data/mods/Aftershock/mobs/zombies.json @@ -22,7 +22,6 @@ "harvest": "zombie", "special_attacks": [ [ "GRAB", 7 ], [ "scratch", 20 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 28, "into": "mon_afs_headless_horror" }, "flags": [ "STUMBLES", @@ -64,7 +63,6 @@ "harvest": "zombie", "special_attacks": [ [ "GRAB", 3 ], [ "scratch", 3 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -114,7 +112,6 @@ } ], "death_drops": "xl_uplift_death_drop", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -158,7 +155,6 @@ "harvest": "zombie_meatslug", "death_drops": "xl_uplift_death_drop", "special_attacks": [ [ "SMASH", 20 ] ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -204,7 +200,6 @@ "harvest": "zombie", "special_attacks": [ [ "SMASH", 28 ] ], "death_drops": "xl_uplift_death_drop", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -249,7 +244,6 @@ "harvest": "zombie_meatslug", "death_drops": "seabased_death_drop", "special_attacks": [ { "type": "bite", "cooldown": 5 } ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -299,7 +293,6 @@ { "type": "bite", "cooldown": 5 }, { "id": "scratch", "damage_max_instance": [ { "damage_type": "cut", "amount": 12 } ] } ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -358,7 +351,6 @@ ] } ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -410,7 +402,6 @@ { "type": "bite", "cooldown": 5 }, { "id": "scratch", "damage_max_instance": [ { "damage_type": "cut", "amount": 6 } ] } ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -455,7 +446,6 @@ "harvest": "frost_human", "death_drops": "default_moxie_human_death_drops", "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "GRAB", 20 ] ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -499,7 +489,6 @@ "harvest": "frost_human", "death_drops": "default_moxie_human_death_drops", "special_attacks": [ [ "PARROT", 0 ] ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -558,7 +547,6 @@ ] } ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -610,7 +598,6 @@ { "type": "bite", "cooldown": 5 }, { "id": "scratch", "damage_max_instance": [ { "damage_type": "cut", "amount": 6 } ] } ], - "death_function": [ "NORMAL" ], "flags": [ "STUMBLES", "HEARS", @@ -657,7 +644,7 @@ "armor_cut": 5, "harvest": "alien_moxphore", "special_attacks": [ [ "ACID", 20 ], { "id": "scratch", "damage_max_instance": [ { "damage_type": "cut", "amount": 6 } ] } ], - "death_function": [ "ACID", "NORMAL" ], + "death_function": { "message": "The %s's body leaks acid.", "effect": { "id": "death_acid", "hit_self": true } }, "flags": [ "SEES", "HEARS", diff --git a/data/mods/CRT_EXPANSION/monsters/crt_monster.json b/data/mods/CRT_EXPANSION/monsters/crt_monster.json index 8717d5a9c1754..dd8c206309a61 100644 --- a/data/mods/CRT_EXPANSION/monsters/crt_monster.json +++ b/data/mods/CRT_EXPANSION/monsters/crt_monster.json @@ -28,7 +28,6 @@ "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 3 }, [ "GRAB", 7 ], [ "scratch", 10 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", @@ -74,7 +73,6 @@ "harvest": "zombie", "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "GRAB", 7 ], [ "scratch", 10 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", @@ -122,7 +120,6 @@ "harvest": "zombie", "special_attacks": [ [ "scratch", 10 ], { "type": "bite", "cooldown": 5 } ], "death_drops": "mon_zombie_cop_death_drops", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "REVIVES", "NO_BREATHE", "POISON", "FILTHY" ] }, { @@ -162,7 +159,6 @@ } ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "CLIMBS", "PUSH_MON", "FILTHY" ] }, @@ -211,7 +207,6 @@ { "id": "impale" } ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_scorched", "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "PUSH_MON", "FILTHY" ] }, @@ -245,7 +240,6 @@ "harvest": "zombie", "special_attacks": [ [ "SHRIEK", 7 ], [ "scratch", 5 ], { "type": "leap", "cooldown": 4, "max_range": 3 } ], "death_drops": { "subtype": "collection", "groups": [ [ "default_zombie_clothes", 100 ], [ "child_items", 65 ] ] }, - "death_function": [ "NORMAL" ], "burn_into": "mon_zombie_child_scorched", "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "CLIMBS", "FILTHY", "SWARMS" ], "//": "no GUILT because it no longer looks enough like a child to evoke pity" @@ -280,7 +274,7 @@ "harvest": "zombie", "special_attacks": [ [ "ACID_BARF", 5 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "ACID", "NORMAL" ], + "death_function": { "message": "The %s's body leaks acid.", "effect": { "id": "death_acid", "hit_self": true } }, "burn_into": "mon_zombie_scorched", "flags": [ "SEES", diff --git a/data/mods/CRT_EXPANSION/monsters/monster.json b/data/mods/CRT_EXPANSION/monsters/monster.json index d3f189c90b4db..7628270547ce1 100644 --- a/data/mods/CRT_EXPANSION/monsters/monster.json +++ b/data/mods/CRT_EXPANSION/monsters/monster.json @@ -26,7 +26,6 @@ "armor_bullet": 13, "harvest": "zombie", "special_attacks": [ [ "TENTACLE", 2 ], [ "scratch", 10 ] ], - "death_function": [ "NORMAL" ], "flags": [ "HEARS", "GOODHEARING", "WARM", "CLIMBS", "NOHEAD", "POISON", "NO_BREATHE" ] }, { @@ -55,7 +54,6 @@ "armor_cut": 40, "harvest": "zombie", "special_attacks": [ [ "TENTACLE", 7 ], [ "scratch", 8 ] ], - "death_function": [ "NORMAL" ], "flags": [ "WARM", "CLIMBS", "NOHEAD", "POISON", "NO_BREATHE" ] } ] diff --git a/data/mods/CrazyCataclysm/crazy_monsters.json b/data/mods/CrazyCataclysm/crazy_monsters.json index 30a5246dfd178..61300bcce983f 100644 --- a/data/mods/CrazyCataclysm/crazy_monsters.json +++ b/data/mods/CrazyCataclysm/crazy_monsters.json @@ -55,7 +55,6 @@ "vision_day": 30, "vision_night": 3, "death_drops": "skeltal_drops", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "HARDTOSHOOT", "REVIVES", "NO_BREATHE", "FILTHY" ], "harvest": "mr_bones", "special_attacks": [ [ "DOOT", 50 ] ] @@ -83,7 +82,7 @@ "dodge": 0, "vision_day": 30, "vision_night": 3, - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "harvest": "mr_bones", "flags": [ "SEES", "HEARS", "HARDTOSHOOT", "REVIVES", "NO_BREATHE", "POISON", "BONES", "FILTHY" ] }, @@ -116,7 +115,7 @@ "special_attacks": [ { "type": "bite", "cooldown": 5 } ], "anger_triggers": [ "HURT", "PLAYER_CLOSE" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "SMOKEBURST" ], + "death_function": { "effect": { "id": "death_smokeburst", "hit_self": true }, "message": "A %s explode!" }, "harvest": "zombie_fur", "flags": [ "SEES", diff --git a/data/mods/Dark-Skies-Above/monsters/alien_cyborgs.json b/data/mods/Dark-Skies-Above/monsters/alien_cyborgs.json index 6eea495a4ba5c..b6b8a6ed20f9b 100644 --- a/data/mods/Dark-Skies-Above/monsters/alien_cyborgs.json +++ b/data/mods/Dark-Skies-Above/monsters/alien_cyborgs.json @@ -52,7 +52,7 @@ "no_ammo_sound": "a roar!" } ], - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", @@ -121,7 +121,7 @@ "no_ammo_sound": "a roar!" } ], - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", @@ -189,7 +189,7 @@ "no_ammo_sound": "a roar!" } ], - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", @@ -244,7 +244,6 @@ } ], "anger_triggers": [ "PLAYER_CLOSE", "PLAYER_WEAK" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "SWIMS", "AQUATIC", "POISON", "HARDTOSHOOT" ] }, { @@ -288,7 +287,6 @@ [ "SMASH", 20 ] ], "anger_triggers": [ "FRIEND_ATTACKED", "HURT" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "BASHES", "DESTROYS", "ACIDPROOF", "CAN_DIG", "ARTHROPOD_BLOOD" ] }, { @@ -321,7 +319,6 @@ "vision_night": 5, "special_attacks": [ { "type": "leap", "cooldown": 10, "max_range": 5 }, { "id": "melee_shock" } ], "path_settings": { "max_dist": 5 }, - "death_function": [ "NORMAL" ], "harvest": "dks_alien_hcyborg", "flags": [ "SEES", "HEARS", "SMELLS", "SWARMS", "WARM", "BASHES", "GROUP_BASH", "PRIORITIZE_TARGETS", "PATH_AVOID_DANGER_2" ] } diff --git a/data/mods/Dark-Skies-Above/monsters/alien_fauna.json b/data/mods/Dark-Skies-Above/monsters/alien_fauna.json index 080acdb4c813e..5254dd7ad8482 100644 --- a/data/mods/Dark-Skies-Above/monsters/alien_fauna.json +++ b/data/mods/Dark-Skies-Above/monsters/alien_fauna.json @@ -35,7 +35,6 @@ } ], "anger_triggers": [ "PLAYER_CLOSE", "PLAYER_WEAK" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "SWIMS", "AQUATIC", "POISON", "HARDTOSHOOT" ] }, { @@ -76,7 +75,6 @@ } ], "anger_triggers": [ "PLAYER_CLOSE", "PLAYER_WEAK" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "SWIMS", "AQUATIC", "POISON" ] }, { @@ -112,7 +110,6 @@ "anger_triggers": [ "HURT" ], "fear_triggers": [ "FIRE" ], "placate_triggers": [ "MEAT", "PLAYER_WEAK" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -157,7 +154,6 @@ "anger_triggers": [ "PLAYER_CLOSE", "FRIEND_ATTACKED", "HURT" ], "fear_triggers": [ "FIRE" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -193,7 +189,7 @@ "morale": 0, "dodge": 4, "fear_triggers": [ "SOUND", "FRIEND_DIED", "FRIEND_ATTACKED", "HURT" ], - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "//": "will want sweets instead of birdfood if/when we can define animal food", "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "FLIES", "BIRDFOOD", "SWARMS" ] }, @@ -224,7 +220,6 @@ "harvest": "mutant_meatslug", "special_attacks": [ [ "ACID_BARF", 10 ] ], "anger_triggers": [ "PLAYER_WEAK" ], - "death_function": [ "NORMAL" ], "flags": [ "KEENNOSE", "HEARS", "SMELLS", "BASHES", "DESTROYS", "ACIDPROOF", "CAN_DIG", "ARTHROPOD_BLOOD" ] } ] diff --git a/data/mods/Dark-Skies-Above/monsters/alien_robots.json b/data/mods/Dark-Skies-Above/monsters/alien_robots.json index e2267a8587ea3..5e52b242886ec 100644 --- a/data/mods/Dark-Skies-Above/monsters/alien_robots.json +++ b/data/mods/Dark-Skies-Above/monsters/alien_robots.json @@ -21,7 +21,7 @@ "luminance": 5, "path_settings": { "max_dist": 5 }, "death_drops": { "groups": [ [ "robots", 4 ] ] }, - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "SEES", "FLIES", "ELECTRONIC", "COLDPROOF", "NO_BREATHE", "NOHEAD", "PRIORITIZE_TARGETS" ] }, { @@ -48,7 +48,7 @@ "special_attacks": [ [ "SEARCHLIGHT", 1 ], [ "DSA_DRONE_SCAN", 2 ] ], "path_settings": { "max_dist": 5 }, "death_drops": { "groups": [ [ "robots", 4 ], [ "eyebot", 1 ], [ "turret_searchlight", 1 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "FLIES", "ELECTRONIC", "COLDPROOF", "NO_BREATHE", "NOHEAD", "PRIORITIZE_TARGETS" ] }, { @@ -89,7 +89,7 @@ "path_settings": { "max_dist": 5 }, "anger_triggers": [ "HURT", "PLAYER_WEAK", "STALK" ], "death_drops": { "groups": [ [ "robots", 4 ], [ "skitterbot", 1 ] ] }, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "FLIES", diff --git a/data/mods/Dark-Skies-Above/monsters/strays.json b/data/mods/Dark-Skies-Above/monsters/strays.json index 97cf7eb220967..c1c0efa4ab0e6 100644 --- a/data/mods/Dark-Skies-Above/monsters/strays.json +++ b/data/mods/Dark-Skies-Above/monsters/strays.json @@ -28,7 +28,6 @@ "path_settings": { "max_dist": 4 }, "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "GRAB", 7 ], [ "scratch", 20 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 21, "into_group": "DKS_GROUP_STRAY_UPGRADE" }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "POISON", "FILTHY", "BASHES", "GROUP_BASH", "PUSH_MON", "REVIVES" ] }, @@ -67,7 +66,6 @@ ], "death_drops": "mon_zombie_cop_death_drops", "upgrades": { "half_life": 60, "into": "dks_mon_crystal_baby" }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "GROUP_BASH", "POISON", "PUSH_MON", "FILTHY", "REVIVES" ] }, { @@ -106,7 +104,6 @@ { "id": "slam", "damage_max_instance": [ { "damage_type": "bash", "amount": 12 } ] } ], "death_drops": "mon_zombie_soldier_death_drops", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 60, "into": "dks_mon_crystal_baby" }, "flags": [ "SEES", "HEARS", "SMELLS", "WARM", "BASHES", "GROUP_BASH", "POISON", "PUSH_MON", "FILTHY", "REVIVES" ] }, @@ -143,7 +140,6 @@ "path_settings": { "max_dist": 4 }, "special_attacks": [ { "id": "slam" }, [ "GRAB", 7 ] ], "death_drops": "mon_zombie_fireman_death_drops", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 60, "into": "dks_mon_crystal_baby" }, "flags": [ "SEES", @@ -191,7 +187,6 @@ "path_settings": { "max_dist": 4 }, "special_attacks": [ { "type": "bite", "cooldown": 5, "min_mul": 0.75, "no_infection_chance": 10 }, [ "GRAB", 6 ], [ "SHRIEK", 10 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 21, "into": "dks_mon_stray_eater" }, "flags": [ "SEES", "HEARS", "SMELLS", "BASHES", "GROUP_BASH", "PUSH_MON", "STUMBLES", "WARM", "POISON", "FILTHY", "REVIVES" ] }, @@ -226,7 +221,7 @@ "path_settings": { "max_dist": 4 }, "special_attacks": [ [ "BOOMER", 20 ], { "type": "bite", "cooldown": 5, "min_mul": 0.75, "no_infection_chance": 10 }, [ "SHRIEK", 10 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "BOOMER", "NORMAL" ], + "death_function": { "effect": { "id": "death_boomer", "hit_self": true }, "message": "A %s explode!" }, "upgrades": { "half_life": 21, "into": "dks_mon_stray_tender" }, "flags": [ "SEES", @@ -276,7 +271,7 @@ "reproduction": { "baby_monster": "dks_mon_crystal_mite", "baby_count": 5, "baby_timer": 60 }, "anger_triggers": [ "PLAYER_CLOSE", "FRIEND_ATTACKED" ], "placate_triggers": [ "PLAYER_WEAK" ], - "death_function": [ "BOOMER_GLOW", "NORMAL" ], + "death_function": { "effect": { "id": "death_boomer_glow", "hit_self": true, "min_level": 1 }, "message": "A %s explode!" }, "upgrades": { "half_life": 60, "into": "dks_mon_crystal_hive" }, "flags": [ "SEES", @@ -322,7 +317,6 @@ "path_settings": { "max_dist": 4 }, "special_when_hit": [ "ZAPBACK", 100 ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 10, "into": "dks_mon_stray_electric" }, "flags": [ "SEES", @@ -370,7 +364,6 @@ "special_attacks": [ [ "SHOCKSTORM", 25 ] ], "special_when_hit": [ "ZAPBACK", 100 ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 60, "into": "dks_mon_crystal_zap" }, "flags": [ "SEES", @@ -426,7 +419,6 @@ } ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 21, "into": "dks_mon_stray_prowler" }, "flags": [ "SEES", @@ -479,7 +471,6 @@ [ "LUNGE", 20 ] ], "death_drops": "default_zombie_death_drops", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 40, "into": "dks_mon_stray_predator" }, "flags": [ "SEES", @@ -535,7 +526,6 @@ ], "death_drops": "mon_zombie_hulk_death_drops", "upgrades": { "half_life": 60, "into": "dks_mon_crystal_baby" }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -587,7 +577,6 @@ ], "death_drops": "default_zombie_death_drops", "upgrades": { "half_life": 21, "into_group": "DKS_GROUP_STRAY_UPGRADE" }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -640,7 +629,6 @@ ], "death_drops": "mon_zombie_hulk_death_drops", "upgrades": { "half_life": 40, "into": "dks_mon_stray_titan" }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -691,7 +679,6 @@ ], "death_drops": "mon_zombie_hulk_death_drops", "upgrades": { "half_life": 50, "into": "dks_mon_crystal_sprout" }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -740,7 +727,6 @@ "path_settings": { "max_dist": 2 }, "special_attacks": [ { "type": "bite", "cooldown": 5 }, [ "scratch", 10 ] ], "death_drops": { "subtype": "collection", "groups": [ [ "default_zombie_children_clothes", 100 ], [ "child_items", 65 ] ] }, - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 50, "into": "dks_mon_stray_wretch" }, "flags": [ "SEES", "HEARS", "SMELLS", "BASHES", "GROUP_BASH", "STUMBLES", "WARM", "GUILT", "POISON", "FILTHY", "REVIVES" ] }, @@ -772,7 +758,6 @@ "harvest": "zombie_fur", "path_settings": { "max_dist": 3 }, "special_attacks": [ [ "scratch", 10 ], { "type": "bite", "cooldown": 5 } ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 21, "into": "dks_mon_stray_wretch" }, "flags": [ "SEES", @@ -825,7 +810,6 @@ "damage_max_instance": [ { "damage_type": "stab", "amount": 10, "armor_multiplier": 0.7 } ] } ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 23, "into_group": "DKS_WRETCH_UPGRADE" }, "flags": [ "SEES", @@ -875,7 +859,6 @@ { "id": "scratch", "damage_max_instance": [ { "damage_type": "cut", "amount": 10, "armor_multiplier": 0.7 } ] }, { "type": "leap", "cooldown": 5, "max_range": 5 } ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -920,7 +903,6 @@ "attack_effs": [ { "id": "paralyzepoison", "duration": 33 } ], "path_settings": { "max_dist": 5 }, "special_attacks": [ { "type": "leap", "cooldown": 10, "max_range": 5 }, [ "RANGED_PULL", 20 ], [ "GRAB_DRAG", 3 ], [ "LONGSWIPE", 20 ] ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -968,7 +950,6 @@ "path_settings": { "max_dist": 10 }, "special_attacks": [ { "type": "leap", "cooldown": 10, "max_range": 5 } ], "special_when_hit": [ "ZAPBACK", 100 ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "LOUDMOVES", "WARM", "BASHES", "POISON", "ELECTRIC", "FILTHY", "REVIVES" ] }, { @@ -1011,7 +992,6 @@ "damage_max_instance": [ { "damage_type": "stab", "amount": 20, "armor_multiplier": 0.5 } ] } ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", @@ -1048,7 +1028,7 @@ "armor_stab": 20, "harvest": "exempt", "special_when_hit": [ "ZAPBACK", 100 ], - "death_function": [ "DISINTEGRATE" ], + "death_function": { "message": "The %s disintegrates!", "corpse_type": "NO_CORPSE" }, "upgrades": { "half_life": 5, "into": "dks_mon_crystal_sprout" }, "flags": [ "IMMOBILE", "NOGIB", "ELECTRIC", "WARM", "NO_BREATHE", "NOHEAD", "ARTHROPOD_BLOOD" ] }, @@ -1075,7 +1055,7 @@ "armor_stab": 30, "harvest": "exempt", "special_when_hit": [ "ZAPBACK", 100 ], - "death_function": [ "DISINTEGRATE" ], + "death_function": { "message": "The %s disintegrates!", "corpse_type": "NO_CORPSE" }, "upgrades": { "half_life": 5, "into_group": "MON_CRYSTAL_UPGRADE" }, "flags": [ "IMMOBILE", "NOGIB", "ELECTRIC", "WARM", "NO_BREATHE", "NOHEAD", "ARTHROPOD_BLOOD" ] }, @@ -1105,7 +1085,7 @@ "harvest": "exempt", "special_attacks": [ [ "SHRIEK_ALERT", 20 ], [ "SHRIEK_STUN", 1 ] ], "special_when_hit": [ "ZAPBACK", 100 ], - "death_function": [ "DISINTEGRATE" ], + "death_function": { "message": "The %s disintegrates!", "corpse_type": "NO_CORPSE" }, "flags": [ "SEES", "IMMOBILE", "HARDTOSHOOT", "NOGIB", "ELECTRIC", "WARM", "NO_BREATHE", "NOHEAD", "ARTHROPOD_BLOOD" ] }, { @@ -1137,7 +1117,7 @@ "harvest": "exempt", "special_attacks": [ [ "RANGED_PULL", 20 ], [ "STRETCH_ATTACK", 20 ] ], "special_when_hit": [ "ZAPBACK", 100 ], - "death_function": [ "DISINTEGRATE" ], + "death_function": { "message": "The %s disintegrates!", "corpse_type": "NO_CORPSE" }, "flags": [ "SEES", "IMMOBILE", "NOGIB", "ELECTRIC", "WARM", "NO_BREATHE", "NOHEAD", "ARTHROPOD_BLOOD" ] }, { @@ -1167,7 +1147,7 @@ "harvest": "exempt", "emit_fields": [ { "emit_id": "emit_shock_cloud", "delay": "3 s" } ], "special_when_hit": [ "ZAPBACK", 100 ], - "death_function": [ "DISINTEGRATE" ], + "death_function": { "message": "The %s disintegrates!", "corpse_type": "NO_CORPSE" }, "flags": [ "IMMOBILE", "NOGIB", "ELECTRIC", "WARM", "NO_BREATHE", "NOHEAD", "ARTHROPOD_BLOOD" ] }, { @@ -1196,7 +1176,7 @@ "luminance": 10, "harvest": "exempt", "special_when_hit": [ "ZAPBACK", 100 ], - "death_function": [ "DISINTEGRATE" ], + "death_function": { "message": "The %s disintegrates!", "corpse_type": "NO_CORPSE" }, "flags": [ "IMMOBILE", "NOGIB", "ELECTRIC", "WARM", "NO_BREATHE", "NOHEAD", "ARTHROPOD_BLOOD" ] }, { @@ -1229,7 +1209,11 @@ "reproduction": { "baby_monster": "dks_mon_crystal_mite", "baby_count": 4, "baby_timer": 60 }, "special_attacks": [ [ "BOOMER_GLOW", 20 ], [ "STRETCH_ATTACK", 20 ], [ "LONGSWIPE", 20 ] ], "special_when_hit": [ "ZAPBACK", 100 ], - "death_function": [ "BOOMER_GLOW", "DISINTEGRATE" ], + "death_function": { + "effect": { "id": "death_boomer_glow", "hit_self": true, "min_level": 1 }, + "message": "A %s explode!", + "corpse_type": "NO_CORPSE" + }, "flags": [ "SEES", "IMMOBILE", "NOGIB", "ELECTRIC", "WARM", "NO_BREATHE", "NOHEAD", "ARTHROPOD_BLOOD" ] }, { @@ -1257,7 +1241,7 @@ "harvest": "exempt", "upgrades": { "age_grow": 12, "into": "dks_mon_crystal_mite_fat" }, "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], - "death_function": [ "DISINTEGRATE" ], + "death_function": { "message": "The %s disintegrates!", "corpse_type": "NO_CORPSE" }, "flags": [ "SEES", "HEARS", diff --git a/data/mods/DinoMod/monsters/dinosaur.json b/data/mods/DinoMod/monsters/dinosaur.json index 6c9993f687e84..bab86c74c7332 100644 --- a/data/mods/DinoMod/monsters/dinosaur.json +++ b/data/mods/DinoMod/monsters/dinosaur.json @@ -67,7 +67,6 @@ "armor_cut": 1, "armor_bullet": 1, "hp": 150, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zilophosaurus", "description": "A medium dinosaur with sharp teeth and two prominent bony crests on its head.", "reproduction": { "baby_egg": "egg_dilophosaurus", "baby_count": 3, "baby_timer": 18 }, @@ -105,7 +104,6 @@ "armor_cut": 2, "armor_bullet": 1, "hp": 70, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zeratosaurus", "description": "A large, fast predatory bipedal dinosaur, decorated with three colorful horns on its head and dotted with bright skin bones with long sharp teeth and a long flexible tail.", "reproduction": { "baby_egg": "egg_ceratosaurus", "baby_count": 3, "baby_timer": 24 }, @@ -141,7 +139,6 @@ "armor_cut": 3, "armor_bullet": 2, "hp": 425, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zpinosaurus", "description": "Meet the king of the river, a huge dinosaur about the size of a small house, with a ferocious crocodile-like head and a sail on its back. Usually feeds on fish.", "reproduction": { "baby_egg": "egg_spinosaurus", "baby_count": 3, "baby_timer": 24 }, @@ -178,7 +175,6 @@ "armor_cut": 1, "armor_bullet": 1, "hp": 160, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zallosaurus", "description": "A large predatory bipedal dinosaur, with tiger-like stripes on its broad back.", "reproduction": { "baby_egg": "egg_allosaurus", "baby_count": 3, "baby_timer": 24 }, @@ -245,7 +241,6 @@ "armor_cut": 2, "armor_bullet": 2, "hp": 300, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zyrannosaurus", "description": "Enormous teeth in a massive jaw, fierce eyes and a powerful frame to drive it forward.", "reproduction": { "baby_egg": "egg_tyrannosaurus", "baby_count": 3, "baby_timer": 24 }, @@ -283,7 +278,6 @@ "armor_cut": 2, "armor_bullet": 2, "hp": 200, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zalbertosaurus", "description": "Looks like a smaller tyrannosaurus rex, but those arms are much longer", "reproduction": { "baby_egg": "egg_albertosaurus", "baby_count": 3, "baby_timer": 24 }, @@ -319,7 +313,6 @@ "vision_day": 50, "armor_bash": 1, "hp": 20, - "death_function": [ "NORMAL" ], "description": "A fast moving bipedal dinosaur about the size of a turkey. Its teeth and claws are small but sharp.", "reproduction": { "baby_egg": "egg_compsognathus", "baby_count": 3, "baby_timer": 12 }, "baby_flags": [ "SPRING", "SUMMER" ], @@ -368,7 +361,6 @@ "armor_cut": 1, "armor_bullet": 1, "hp": 40, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zallimimus", "description": "A feathered bipedal dinosaur, standing as tall as a human. It looks somewhat like a reptilian ostrich.", "reproduction": { "baby_egg": "egg_gallimimus", "baby_count": 3, "baby_timer": 12 }, @@ -415,7 +407,6 @@ "armor_bash": 1, "armor_cut": 1, "hp": 30, - "death_function": [ "NORMAL" ], "vision_night": 5, "special_attacks": [ { "type": "leap", "cooldown": 5, "max_range": 5, "allow_no_target": true }, { "type": "bite", "cooldown": 10 } ], "description": "A small bipedal dinosaur covered with feathers. Small, hooked claws emerge from its feet and hands.", @@ -452,7 +443,6 @@ "armor_cut": 2, "armor_bullet": 2, "hp": 800, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zothronychus", "description": "A large feathered bipedal dinosaur with a pot-bellied stomach and a long neck. Sharp claws extend from its dextrous hands.", "reproduction": { "baby_egg": "egg_nothronychus", "baby_count": 3, "baby_timer": 24 }, @@ -499,7 +489,6 @@ "armor_bash": 1, "armor_cut": 1, "hp": 60, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zeinonychus", "vision_night": 5, "path_settings": { "max_dist": 10, "avoid_traps": true, "avoid_sharp": true }, @@ -549,7 +538,6 @@ "armor_cut": 1, "armor_bullet": 1, "hp": 100, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zutahraptor", "vision_night": 5, "special_attacks": [ { "type": "leap", "cooldown": 5, "max_range": 5, "allow_no_target": true }, { "type": "bite", "cooldown": 5 } ], @@ -585,7 +573,6 @@ "dodge": 4, "armor_bash": 1, "hp": 10, - "death_function": [ "NORMAL" ], "death_drops": { "subtype": "collection", "groups": [ [ "science", 100 ], [ "mut_lab", 10 ] ] }, "description": "A bipedal dinosaur about the size of a chicken. It darts around quickly and has long arms for grabbing what it desires. It's holding something.", "reproduction": { "baby_egg": "egg_eoraptor", "baby_count": 3, "baby_timer": 12 }, @@ -621,7 +608,6 @@ "armor_bullet": 2, "vision_day": 50, "hp": 1000, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zapatosaurus", "special_attacks": [ { "id": "slam", "cooldown": 10, "damage_max_instance": [ { "damage_type": "bash", "amount": 12 } ] }, @@ -748,7 +734,6 @@ "armor_cut": 10, "armor_bullet": 1, "hp": 300, - "death_function": [ "NORMAL" ], "zombify_into": "mon_ztegosaurus", "special_attacks": [ { "id": "slam", "cooldown": 10, "damage_max_instance": [ { "damage_type": "bash", "amount": 12 } ] }, @@ -804,7 +789,6 @@ "armor_cut": 18, "armor_bullet": 6, "hp": 600, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zankylosaurus", "special_attacks": [ { "id": "slam", "cooldown": 10, "damage_max_instance": [ { "damage_type": "bash", "amount": 12 } ] }, @@ -887,7 +871,6 @@ "armor_cut": 2, "armor_bullet": 2, "hp": 160, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zamptosaurus", "description": "A large feathered bipedal dinosaur with strong legs, broad shoulders and a pointed beak. It moves slowly but with enormous strength.", "reproduction": { "baby_egg": "egg_camptosaurus", "baby_count": 30, "baby_timer": 12 }, @@ -936,7 +919,6 @@ "armor_cut": 4, "armor_bullet": 3, "hp": 300, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zarasaurolophus", "description": "A huge mottled dinosaur with a blunt head crest.", "reproduction": { "baby_egg": "egg_parasaurolophus", "baby_count": 30, "baby_timer": 24 }, @@ -1005,7 +987,6 @@ "armor_cut": 1, "armor_bullet": 1, "hp": 40, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zachycephalosaurus", "description": "A feathered bipedal dinosaur, standing as tall as a human. It looks like a reptilian ostrich with a round hard-looking domed head.", "reproduction": { "baby_egg": "egg_pachycephalosaurus", "baby_count": 3, "baby_timer": 12 }, @@ -1098,7 +1079,6 @@ "armor_cut": 4, "armor_bullet": 2, "hp": 600, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zriceratops", "description": "A massive rhino-like dinosaur with a bony crest from which three large horns emerge.", "reproduction": { "baby_egg": "egg_triceratops", "baby_count": 20, "baby_timer": 24 }, @@ -1145,7 +1125,6 @@ "armor_cut": 1, "vision_day": 50, "hp": 2, - "death_function": [ "NORMAL" ], "description": "A feathered flying reptile over three feet long, with short wings and a big colorful beak.", "reproduction": { "baby_egg": "egg_dimorphodon", "baby_count": 3, "baby_timer": 24 }, "baby_flags": [ "SPRING", "SUMMER" ], @@ -1218,7 +1197,6 @@ "armor_cut": 4, "armor_bullet": 6, "hp": 350, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zosasaurus", "description": "A huge aquatic dinosaur about the size of a small house, with a ferocious crocodile-like head and powerful swimming fins.", "reproduction": { "baby_egg": "egg_mosasaurus", "baby_count": 3, "baby_timer": 24 }, @@ -1256,7 +1234,6 @@ "armor_bullet": 12, "hp": 250, "vision_day": 36, - "death_function": [ "NORMAL" ], "zombify_into": "mon_zianzhousaurus", "description": "Also known as pinnochio rex, this bipedal dinosaur is slower than most and covered in fur, it also looks very hungry.", "reproduction": { "baby_egg": "egg_qianzhousaurus", "baby_count": 5, "baby_timer": 23 }, diff --git a/data/mods/DinoMod/monsters/hatchling.json b/data/mods/DinoMod/monsters/hatchling.json index 46bc671dd69bc..7f7c6d8021ae6 100644 --- a/data/mods/DinoMod/monsters/hatchling.json +++ b/data/mods/DinoMod/monsters/hatchling.json @@ -22,7 +22,6 @@ "melee_dice_sides": 1, "melee_cut": 1, "dodge": 1, - "death_function": [ "NORMAL" ], "upgrades": { "age_grow": 14, "into": "mon_compsognathus" }, "flags": [ "SEES", diff --git a/data/mods/DinoMod/monsters/juvenile.json b/data/mods/DinoMod/monsters/juvenile.json index 0dc549715a0e6..c00db4decac9b 100644 --- a/data/mods/DinoMod/monsters/juvenile.json +++ b/data/mods/DinoMod/monsters/juvenile.json @@ -134,7 +134,6 @@ "melee_dice_sides": 1, "melee_cut": 1, "dodge": 2, - "death_function": [ "NORMAL" ], "upgrades": { "age_grow": 70, "into": "mon_gallimimus" }, "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "CATTLEFODDER", "GUILT", "NO_BREED", "CANPLAY" ], "harvest": "bird_small" diff --git a/data/mods/DinoMod/monsters/zed-dinosaur.json b/data/mods/DinoMod/monsters/zed-dinosaur.json index 967bba247de57..6f2781fdb177b 100644 --- a/data/mods/DinoMod/monsters/zed-dinosaur.json +++ b/data/mods/DinoMod/monsters/zed-dinosaur.json @@ -64,7 +64,6 @@ "armor_bash": 6, "armor_cut": 8, "hp": 670, - "death_function": [ "NORMAL" ], "description": "Enormous putrid dinosaur corpse with a ferocious crocodile-like head, oozing black eyes, and a tattered sail on its back.", "special_attacks": [ [ "scratch", 10 ], { "type": "bite", "cooldown": 5 } ], "upgrades": { "half_life": 14, "into_group": "GROUP_zpinosaurus_UPGRADE" }, @@ -211,7 +210,6 @@ "armor_cut": 8, "armor_bullet": 1, "hp": 500, - "death_function": [ "NORMAL" ], "description": "Massive piles of ragged, stinking flesh lifting enormous teeth.", "special_attacks": [ [ "scratch", 10 ], { "type": "bite", "cooldown": 5 } ], "upgrades": { "half_life": 14, "into_group": "GROUP_zyrannosaurus_UPGRADE" }, @@ -282,7 +280,6 @@ "armor_cut": 4, "armor_bullet": 2, "hp": 70, - "death_function": [ "NORMAL" ], "special_attacks": [ [ "scratch", 10 ], { "type": "bite", "cooldown": 5 } ], "description": "The shuffling corpse of a medium-sized bipedal dinosaur, covered with tattered feathers and black, putrid liquid.", "upgrades": { "half_life": 14, "into_group": "GROUP_zallimimus_UPGRADE" }, @@ -335,7 +332,6 @@ "armor_cut": 4, "armor_bullet": 2, "hp": 100, - "death_function": [ "NORMAL" ], "special_attacks": [ { "type": "leap", "cooldown": 5, "max_range": 5, "allow_no_target": true }, [ "scratch", 10 ], @@ -548,7 +544,6 @@ "armor_cut": 21, "armor_bullet": 7, "hp": 1000, - "death_function": [ "NORMAL" ], "special_attacks": [ [ "scratch", 10 ], { "type": "bite", "cooldown": 5 }, @@ -615,7 +610,6 @@ "armor_cut": 4, "armor_bullet": 2, "hp": 130, - "death_function": [ "NORMAL" ], "special_attacks": [ [ "scratch", 10 ], { "type": "bite", "cooldown": 5 } ], "description": "The shuffling corpse of a large, feathered, bipedal dinosaur with strong legs, broad shoulders, and a pointed beak. Its tattered feathers are stained with black, sticky liquid.", "upgrades": { "half_life": 14, "into_group": "GROUP_zamptosaurus_UPGRADE" }, @@ -717,7 +711,6 @@ "armor_cut": 4, "armor_bullet": 1, "hp": 70, - "death_function": [ "NORMAL" ], "special_attacks": [ [ "scratch", 10 ], { "type": "bite", "cooldown": 5 } ], "description": "The shuffling corpse of a medium-sized bipedal dinosaur covered with tattered feathers and black, putrid liquid. It resembles a reptilian ostrich with a hard-looking domed head.", "upgrades": { "half_life": 14, "into_group": "GROUP_zachycephalosaurus_UPGRADE" }, @@ -840,7 +833,6 @@ "armor_cut": 4, "armor_bullet": 1, "hp": 70, - "death_function": [ "NORMAL" ], "special_attacks": [ [ "scratch", 10 ], { "type": "bite", "cooldown": 5 } ], "description": "The ragged but flying corpse of a large, feathered reptile with a long, pointy, toothless beak and a long, pointy head crest.", "upgrades": { "half_life": 14, "into": "mon_zteranodon_brute" }, @@ -932,7 +924,6 @@ "armor_cut": 4, "armor_bullet": 2, "hp": 1500, - "death_function": [ "NORMAL" ], "special_attacks": [ { "id": "slam", "cooldown": 10, "damage_max_instance": [ { "damage_type": "bash", "amount": 12 } ] }, [ "SMASH", 30 ] diff --git a/data/mods/DinoMod/monsters/zinosaur_upgrade.json b/data/mods/DinoMod/monsters/zinosaur_upgrade.json index d0b524038d944..829699fbcca05 100644 --- a/data/mods/DinoMod/monsters/zinosaur_upgrade.json +++ b/data/mods/DinoMod/monsters/zinosaur_upgrade.json @@ -1850,7 +1850,7 @@ { "group": "supplies_mechanics", "count": 10 }, { "group": "supplies_metal", "count": 10 } ], - "death_function": [ "FIREBALL" ] + "death_function": { "effect": { "id": "death_fireball", "hit_self": true } } }, { "type": "MONSTER", @@ -1873,7 +1873,7 @@ { "group": "mil_hw", "count": 10 }, { "group": "supplies_metal", "count": 10 } ], - "death_function": [ "FIREBALL" ] + "death_function": { "effect": { "id": "death_fireball", "hit_self": true } } }, { "type": "MONSTER", diff --git a/data/mods/Magiclysm/monsters.json b/data/mods/Magiclysm/monsters.json index 22a7a32203e29..700b4a4cf3395 100644 --- a/data/mods/Magiclysm/monsters.json +++ b/data/mods/Magiclysm/monsters.json @@ -20,7 +20,7 @@ "harvest": "exempt", "fear_triggers": [ "PLAYER_CLOSE" ], "special_attacks": [ [ "DISAPPEAR", 200 ] ], - "death_function": [ "DISAPPEAR" ], + "death_function": { "message": "The %s disappears.", "corpse_type": "NO_CORPSE" }, "flags": [ "FLIES", "NO_BREATHE", "NOT_HALLUCINATION", "HARDTOSHOOT" ] }, { @@ -51,7 +51,7 @@ "vision_night": 30, "material": [ "steel" ], "harvest": "exempt", - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "SEES", "HEARS", "NOHEAD", "HARDTOSHOOT", "FLIES", "PRIORITIZE_TARGETS", "NO_BREATHE", "NOGIB" ] } ] diff --git a/data/mods/Magiclysm/monsters/Ogre.json b/data/mods/Magiclysm/monsters/Ogre.json index 9049eaca0b634..ac6c4f19ba441 100644 --- a/data/mods/Magiclysm/monsters/Ogre.json +++ b/data/mods/Magiclysm/monsters/Ogre.json @@ -25,7 +25,6 @@ "vision_day": 10, "vision_night": 3, "path_settings": { "avoid_traps": true, "avoid_sharp": true }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "WARM", "BASHES", "FILTHY", "PATH_AVOID_DANGER_1", "FIREPROOF" ] } ] diff --git a/data/mods/Magiclysm/monsters/Orcs.json b/data/mods/Magiclysm/monsters/Orcs.json index d01baf6a96df9..a1445b706f866 100644 --- a/data/mods/Magiclysm/monsters/Orcs.json +++ b/data/mods/Magiclysm/monsters/Orcs.json @@ -44,7 +44,6 @@ { "item": "longsword", "prob": 100 } ] }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "WARM", "BASHES", "FILTHY", "PATH_AVOID_DANGER_1", "SWARMS", "GROUP_MORALE" ] }, { diff --git a/data/mods/Magiclysm/monsters/demon_spider.json b/data/mods/Magiclysm/monsters/demon_spider.json index d97b4c2eaa869..caadb61a2b92b 100644 --- a/data/mods/Magiclysm/monsters/demon_spider.json +++ b/data/mods/Magiclysm/monsters/demon_spider.json @@ -55,7 +55,6 @@ "vision_night": 7, "harvest": "demon_spider", "anger_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT", "STALK", "PLAYER_WEAK", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "VENOM", "WEBWALK", "CLIMBS", "HARDTOSHOOT", "PUSH_MON" ] }, { @@ -93,7 +92,6 @@ "harvest": "demon_spider", "special_attacks": [ { "type": "spell", "spell_data": { "id": "burning_hands", "min_level": 4 }, "cooldown": 20 } ], "anger_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT", "STALK", "PLAYER_WEAK", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "VENOM", "WEBWALK", "CLIMBS", "HARDTOSHOOT", "PUSH_MON" ] }, { diff --git a/data/mods/Magiclysm/monsters/dragon.json b/data/mods/Magiclysm/monsters/dragon.json index ff4bbd5c3f7c8..5d61184fe692e 100644 --- a/data/mods/Magiclysm/monsters/dragon.json +++ b/data/mods/Magiclysm/monsters/dragon.json @@ -96,7 +96,6 @@ "vision_night": 20, "path_settings": { "//min_dist": 8, "avoid_traps": true, "avoid_sharp": true }, "harvest": "dragon_black", - "death_function": [ "NORMAL" ], "special_attacks": [ { "type": "bite", "cooldown": 10 }, [ "scratch", 7 ], diff --git a/data/mods/Magiclysm/monsters/forgedwellers.json b/data/mods/Magiclysm/monsters/forgedwellers.json index e61b444f30e5c..8b5bf0fc5da8c 100644 --- a/data/mods/Magiclysm/monsters/forgedwellers.json +++ b/data/mods/Magiclysm/monsters/forgedwellers.json @@ -31,7 +31,7 @@ "path_settings": { "avoid_traps": true, "avoid_sharp": true }, "special_attacks": [ { "type": "spell", "spell_data": { "id": "manatouched_seeker_bolts", "min_level": 5 }, "cooldown": 60 } ], "anger_triggers": [ "FRIEND_ATTACKED", "HURT" ], - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "NO_BREATHE", "PATH_AVOID_DANGER_1", "LOUDMOVES" ] }, { @@ -95,7 +95,6 @@ "armor_fire": 50, "harvest": "demihuman_large_fur", "special_attacks": [ { "type": "spell", "spell_data": { "id": "demon_breath_fire", "min_level": 7 }, "cooldown": 10 }, [ "scratch", 15 ] ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "WARM", "BASHES", "ANIMAL", "PATH_AVOID_DANGER_1", "NO_BREATHE" ] }, { @@ -127,7 +126,6 @@ "harvest": "demihuman", "path_settings": { "avoid_traps": true, "avoid_sharp": true }, "death_drops": { "subtype": "collection", "groups": [ [ "forge_life", 40 ], [ "bedroom", 1 ], [ "dresser", 5 ], [ "ammo", 18 ] ] }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "WARM", "BASHES", "GROUP_BASH", "HUMAN", "PATH_AVOID_DANGER_1" ] }, { diff --git a/data/mods/Magiclysm/monsters/goblin.json b/data/mods/Magiclysm/monsters/goblin.json index fda530b6396f1..f2e29b5e73547 100644 --- a/data/mods/Magiclysm/monsters/goblin.json +++ b/data/mods/Magiclysm/monsters/goblin.json @@ -35,7 +35,6 @@ { "item": "cudgel", "prob": 95 } ] }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "WARM", "BASHES", "FILTHY", "PATH_AVOID_DANGER_1" ] }, { diff --git a/data/mods/Magiclysm/monsters/golems.json b/data/mods/Magiclysm/monsters/golems.json index b0c35a8cdbbb4..dd6f59ac548ff 100644 --- a/data/mods/Magiclysm/monsters/golems.json +++ b/data/mods/Magiclysm/monsters/golems.json @@ -27,7 +27,7 @@ "dodge": 0, "vision_day": 40, "vision_night": 40, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "NO_BREATHE", "ACIDPROOF", "LOUDMOVES" ] }, { @@ -56,7 +56,7 @@ "vision_day": 30, "vision_night": 30, "regenerates": 4, - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "HEARS", "NO_BREATHE", "LOUDMOVES" ] }, { @@ -88,7 +88,7 @@ "vision_day": 40, "vision_night": 40, "special_attacks": [ { "type": "spell", "spell_data": { "id": "rocket_punch", "min_level": 5 }, "cooldown": 10 } ], - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "NO_BREATHE", "ACIDPROOF", "LOUDMOVES" ] }, { @@ -120,7 +120,7 @@ "vision_day": 40, "vision_night": 40, "special_attacks": [ { "type": "spell", "spell_data": { "id": "gas_attack", "min_level": 5 }, "cooldown": 60 } ], - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "flags": [ "SEES", "NO_BREATHE", "ACIDPROOF", "LOUDMOVES" ] } ] diff --git a/data/mods/Magiclysm/monsters/holiday_magiclysm.json b/data/mods/Magiclysm/monsters/holiday_magiclysm.json index d635d8aca79b9..7fe369ad54232 100644 --- a/data/mods/Magiclysm/monsters/holiday_magiclysm.json +++ b/data/mods/Magiclysm/monsters/holiday_magiclysm.json @@ -27,7 +27,6 @@ "vision_night": 12, "path_settings": { "max_dist": 21, "avoid_traps": true, "avoid_sharp": true }, "harvest": "mammal_fur", - "death_function": [ "NORMAL" ], "reproduction": { "baby_monster": "mon_yulecat_cub", "baby_count": 6, "baby_timer": 234 }, "baby_flags": [ "WINTER" ], "special_attacks": [ { "type": "bite", "cooldown": 10 }, [ "GRAB", 8 ], [ "scratch", 6 ] ], @@ -81,7 +80,6 @@ "armor_bullet": 3, "harvest": "demihuman", "path_settings": { "avoid_traps": true, "avoid_sharp": true }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "PATH_AVOID_DANGER_1", "WARM" ] }, { @@ -106,7 +104,6 @@ "dodge": 6, "harvest": "demihuman", "path_settings": { "avoid_traps": true, "avoid_sharp": true }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "PATH_AVOID_DANGER_1", "WARM" ] } ] diff --git a/data/mods/Magiclysm/monsters/lizardfolk.json b/data/mods/Magiclysm/monsters/lizardfolk.json index 5efa022321446..2aeea3de917d7 100644 --- a/data/mods/Magiclysm/monsters/lizardfolk.json +++ b/data/mods/Magiclysm/monsters/lizardfolk.json @@ -28,7 +28,6 @@ "armor_bullet": 10, "armor_stab": 6, "harvest": "lizardfolk", - "death_function": [ "NORMAL" ], "death_drops": [ { "item": "lizardfolk_club", "prob": 30 }, { "item": "loincloth", "prob": 40 }, diff --git a/data/mods/Magiclysm/monsters/monsters.json b/data/mods/Magiclysm/monsters/monsters.json index dff670b0269d5..f5cdc0d37e2c6 100644 --- a/data/mods/Magiclysm/monsters/monsters.json +++ b/data/mods/Magiclysm/monsters/monsters.json @@ -29,7 +29,6 @@ "harvest": "owlbear", "reproduction": { "baby_egg": "egg_owlbear_rock", "baby_count": 1, "baby_timer": 20 }, "baby_flags": [ "SPRING", "SUMMER", "AUTUMN", "WINTER" ], - "death_function": [ "NORMAL" ], "special_attacks": [ { "type": "bite", "cooldown": 10 }, [ "GRAB", 7 ], [ "scratch", 7 ] ], "flags": [ "SEES", "HEARS", "SMELLS", "KEENNOSE", "PATH_AVOID_DANGER_1", "WARM", "GRABS", "SWARMS" ] }, @@ -60,7 +59,7 @@ "armor_acid": 15, "harvest": "exempt", "path_settings": { "avoid_traps": true, "avoid_sharp": true }, - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "special_attacks": [ { "type": "spell", @@ -98,7 +97,6 @@ "vision_night": 30, "vision_day": 30, "path_settings": { "max_dist": 35 }, - "death_function": [ "NORMAL" ], "anger_triggers": [ "HURT", "PLAYER_CLOSE", "PLAYER_WEAK" ], "special_attacks": [ { @@ -161,7 +159,6 @@ "armor_bullet": 24, "harvest": "bulette", "anger_triggers": [ "SOUND" ], - "death_function": [ "NORMAL" ], "special_attacks": [ { "id": "scratch", @@ -205,7 +202,7 @@ "harvest": "exempt", "death_drops": "wisp_death", "anger_triggers": [ "PLAYER_CLOSE" ], - "death_function": [ "DISINTEGRATE" ], + "death_function": { "message": "The %s disintegrates!", "corpse_type": "NO_CORPSE" }, "flags": [ "SEES", "HEARS", @@ -246,7 +243,6 @@ "vision_day": 40, "vision_night": 3, "harvest": "human_large_leather", - "death_function": [ "NORMAL" ], "special_attacks": [ { "type": "bite", "cooldown": 30 }, [ "GRAB", 15 ], [ "scratch", 15 ], [ "slam", 10 ], [ "SMASH", 30 ] ], "regenerates": 1, "flags": [ "SEES", "SMELLS", "KEENNOSE", "PATH_AVOID_DANGER_1", "WARM", "GRABS", "FLAMMABLE" ] @@ -278,7 +274,6 @@ "harvest": "stirge", "special_attacks": [ { "type": "spell", "spell_data": { "id": "blood_suck", "min_level": 3 }, "cooldown": 3 } ], "anger_triggers": [ "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "FLIES", "HIT_AND_RUN", "PATH_AVOID_FIRE", "SWARMS" ] }, { @@ -305,7 +300,6 @@ "harvest": "shrieker", "special_attacks": [ [ "SHRIEK_ALERT", 1 ] ], "anger_triggers": [ "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "NOHEAD", "POISON", "IMMOBILE", "NO_BREATHE", "PACIFIST" ] }, { @@ -327,7 +321,6 @@ "harvest": "mammal_tiny", "special_attacks": [ { "type": "leap", "cooldown": 10, "max_range": 5 } ], "fear_triggers": [ "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "SWIMS" ] }, { @@ -357,7 +350,6 @@ "vision_night": 40, "harvest": "lemure", "anger_triggers": [ "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "regenerates": 1, "flags": [ "SEES", "SMELLS", "HEARS", "STUMBLES", "PATH_AVOID_FIRE", "REVIVES" ] }, @@ -392,7 +384,6 @@ "special_attacks": [ { "type": "spell", "spell_data": { "id": "cone_cold", "min_level": 4 }, "cooldown": 25 } ], "anger_triggers": [ "STALK", "FRIEND_ATTACKED", "FRIEND_DIED", "PLAYER_WEAK", "PLAYER_CLOSE" ], "placate_triggers": [ "MEAT" ], - "death_function": [ "NORMAL" ], "zombify_into": "mon_zolf", "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "KEENNOSE", "COLDPROOF" ] }, @@ -426,7 +417,6 @@ "harvest": "demihuman_fur", "path_settings": { "max_dist": 10 }, "anger_triggers": [ "STALK", "FRIEND_ATTACKED", "FRIEND_DIED", "PLAYER_WEAK", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "zombify_into": "mon_were_zolf", "flags": [ "SEES", "HEARS", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "KEENNOSE" ] } diff --git a/data/mods/Magiclysm/monsters/zombified_monsters.json b/data/mods/Magiclysm/monsters/zombified_monsters.json index f48845de2c44a..c3b1583b25673 100644 --- a/data/mods/Magiclysm/monsters/zombified_monsters.json +++ b/data/mods/Magiclysm/monsters/zombified_monsters.json @@ -29,7 +29,6 @@ "harvest": "zombie_fur", "special_attacks": [ [ "HOWL", 10 ] ], "fear_triggers": [ "FIRE" ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 28, "into_group": "GROUP_ZOLF_UPGRADE" }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "KEENNOSE", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ] }, @@ -61,7 +60,6 @@ "armor_bullet": 23, "vision_night": 12, "harvest": "orc", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "GROUP_BASH", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ] } ] diff --git a/data/mods/My_Sweet_Cataclysm/sweet_monsters.json b/data/mods/My_Sweet_Cataclysm/sweet_monsters.json index 5d5e1d9266c71..0ce7abd3e2475 100644 --- a/data/mods/My_Sweet_Cataclysm/sweet_monsters.json +++ b/data/mods/My_Sweet_Cataclysm/sweet_monsters.json @@ -15,7 +15,7 @@ "material": [ "junk" ], "symbol": "%", "color": "magenta", - "death_function": [ "BROKEN" ], + "death_function": { "corpse_type": "BROKEN" }, "placate_triggers": [ "HURT" ], "flags": [ "SEES", "HEARS", "GOODHEARING", "SMELLS", "ANIMAL", "PATH_AVOID_DANGER_1", "WARM", "HIT_AND_RUN" ] }, @@ -42,7 +42,6 @@ "vision_day": 30, "vision_night": 3, "harvest": "marshmallow_boy", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 14, "into": "mon_marshmallow_guy" }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "NO_BREATHE" ] }, @@ -67,7 +66,6 @@ "melee_dice_sides": 3, "vision_night": 3, "harvest": "marshmallow_boy", - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 14, "into": "mon_marshmallow_buff" }, "reproduction": { "baby_egg": "marshmallow", "baby_count": 5, "baby_timer": 14 }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "GROUP_BASH", "NO_BREATHE", "PUSH_MON" ] @@ -98,7 +96,6 @@ "vision_night": 4, "harvest": "marshmallow_boy", "special_attacks": [ [ "SMASH", 30 ] ], - "death_function": [ "NORMAL" ], "upgrades": { "half_life": 21, "into": "mon_marshmallow_goliath" }, "reproduction": { "baby_egg": "marshmallow", "baby_count": 7, "baby_timer": 12 }, "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "GROUP_BASH", "NO_BREATHE", "PUSH_MON", "PUSH_VEH" ] @@ -130,7 +127,6 @@ "vision_night": 4, "harvest": "marshmallow_boy", "special_attacks": [ [ "SMASH", 20 ] ], - "death_function": [ "NORMAL" ], "reproduction": { "baby_egg": "marshmallow", "baby_count": 10, "baby_timer": 10 }, "flags": [ "SEES", @@ -249,7 +245,6 @@ "vision_night": 10, "path_settings": { "max_dist": 10 }, "anger_triggers": [ "HURT" ], - "death_function": [ "NORMAL" ], "harvest": "gummy_bear", "reproduction": { "baby_egg": "candy3", "baby_count": 1, "baby_timer": 10 }, "flags": [ "SEES", "HEARS", "SMELLS", "PATH_AVOID_DANGER_1", "WARM", "BASHES", "ATTACKMON", "NO_BREATHE" ] @@ -298,7 +293,6 @@ "harvest": "cracker_boy", "special_attacks": [ [ "scratch", 10 ] ], "upgrades": { "half_life": 15, "into": "mon_cracker" }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "NO_BREATHE" ] }, { @@ -330,7 +324,6 @@ "harvest": "cracker_boy", "special_attacks": [ [ "scratch", 10 ] ], "reproduction": { "baby_egg": "grahmcrackers", "baby_count": 3, "baby_timer": 20 }, - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "NO_BREATHE" ] }, { @@ -373,7 +366,6 @@ "path_settings": { "max_dist": 10 }, "anger_triggers": [ "PLAYER_WEAK" ], "fear_triggers": [ "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "PATH_AVOID_DANGER_1" ], "reproduction": { "baby_egg": "cookies", "baby_count": 10, "baby_timer": 5 } }, @@ -448,7 +440,6 @@ "vision_night": 5, "harvest": "gum_spider", "emit_fields": [ { "emit_id": "emit_gum_web", "delay": "30 m" } ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "CLIMBS", "PATH_AVOID_FIRE", "PATH_AVOID_FALL" ], "reproduction": { "baby_egg": "gum", "baby_count": 10, "baby_timer": 5 } }, @@ -481,7 +472,6 @@ "vision_night": 5, "harvest": "caff_gum_spider", "anger_triggers": [ "STALK", "PLAYER_WEAK", "HURT", "PLAYER_CLOSE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "CLIMBS", "PATH_AVOID_FIRE", "PATH_AVOID_FALL" ] }, { @@ -529,7 +519,6 @@ "vision_day": 23, "vision_night": 50, "harvest": "licorice_snake", - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES" ] }, { diff --git a/data/mods/National_Guard_Camp/military.json b/data/mods/National_Guard_Camp/military.json index 4dc09ad18304c..3e48bbe17e635 100644 --- a/data/mods/National_Guard_Camp/military.json +++ b/data/mods/National_Guard_Camp/military.json @@ -36,7 +36,7 @@ } ], "death_drops": { "groups": [ [ "wraitheon_infantry", 30 ] ] }, - "death_function": [ "DISINTEGRATE" ], + "death_function": { "message": "The %s disintegrates!", "corpse_type": "NO_CORPSE" }, "flags": [ "HEARS", "SEES", "NOHEAD", "ELECTRONIC", "NO_BREATHE", "PATH_AVOID_DANGER_2", "PRIORITIZE_TARGETS" ] }, { diff --git a/data/mods/desert_region/desert_insect_spider.json b/data/mods/desert_region/desert_insect_spider.json index df5fd07075687..372d9d2662dc4 100644 --- a/data/mods/desert_region/desert_insect_spider.json +++ b/data/mods/desert_region/desert_insect_spider.json @@ -27,7 +27,6 @@ "vision_night": 5, "harvest": "arachnid", "special_attacks": [ { "id": "impale" } ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "SMELLS", "HEARS", "BADVENOM", "PARALYZEVENOM", "GRABS" ] } ] diff --git a/data/mods/desert_region/desert_mammal.json b/data/mods/desert_region/desert_mammal.json index 53b6e8189a7ba..f52f7bef73e3e 100644 --- a/data/mods/desert_region/desert_mammal.json +++ b/data/mods/desert_region/desert_mammal.json @@ -25,7 +25,6 @@ "armor_cut": 3, "path_settings": { "max_dist": 20 }, "anger_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED", "HURT", "MATING_SEASON" ], - "death_function": [ "NORMAL" ], "baby_flags": [ "SPRING" ], "//": "Baby elephants don't actually exist (yet), but Spring is the wet season (their mating season) so baby_flags is defined so that they get angry then", "harvest": "mammal_large_leather", diff --git a/data/mods/desert_region/desert_monsters.json b/data/mods/desert_region/desert_monsters.json index 17685e7e77f94..b79cd4f1af472 100644 --- a/data/mods/desert_region/desert_monsters.json +++ b/data/mods/desert_region/desert_monsters.json @@ -33,7 +33,6 @@ ], "anger_triggers": [ "STALK", "PLAYER_WEAK", "PLAYER_CLOSE" ], "fear_triggers": [ "FIRE" ], - "death_function": [ "NORMAL" ], "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "FILTHY", "SWIMS" ] }, { @@ -53,7 +52,7 @@ "melee_dice_sides": 3, "armor_bash": 3, "armor_cut": 1, - "death_function": [ "NORMAL", "FUNGUS" ], + "death_function": { "effect": { "id": "death_fungus", "hit_self": true } }, "special_attacks": [ [ "FUNGUS", 200 ], [ "SMASH", 15 ], [ "FUNGUS_BRISTLE", 20 ], [ "FUNGUS_BIG_BLOSSOM", 30 ] ], "extend": { "flags": [ "POISON", "NO_BREATHE" ] }, "delete": { diff --git a/data/mods/desert_region/desert_reptile_amphibian.json b/data/mods/desert_region/desert_reptile_amphibian.json index d306e8eca142f..e35243b49365f 100644 --- a/data/mods/desert_region/desert_reptile_amphibian.json +++ b/data/mods/desert_region/desert_reptile_amphibian.json @@ -24,7 +24,6 @@ "anger_triggers": [ "HURT", "PLAYER_CLOSE" ], "fear_triggers": [ "PLAYER_CLOSE" ], "placate_triggers": [ "PLAYER_WEAK" ], - "death_function": [ "NORMAL" ], "flags": [ "ANIMAL", "CLIMBS", "KEENNOSE", "SEES", "HEARS", "SMELLS", "BADVENOM" ] } ] diff --git a/doc/MAGIC.md b/doc/MAGIC.md index 31aaf4875c980..d46ce395f3678 100644 --- a/doc/MAGIC.md +++ b/doc/MAGIC.md @@ -97,10 +97,13 @@ Below is a table of currently implemented effects, along with special rules for | Effect | Description |--- |--- | `pain_split` | makes all of your limbs' damage even out -| `move_earth` | "digs" at the target location. some terrain is not diggable this way. | `attack` | "causes damage to targets in its aoe, and applies an effect to the targets named by `effect_str` | `spawn_item` | spawns an item that will disappear at the end of its duration. Default duration is 0. | `summon` | summons a monster ID or group ID from `effect_str` that will disappear at the end of its duration. Default duration is 0. +| `summon_vehicle` | summons a vehicle ID from `effect_str` that will disappear at the end of its duration. Default duration is 0. +| `translocate` | Opens up a window that allows the caster to choose a translocation gate to teleport to. +| `area_pull` | Pulls `valid_targets` in aoe toward the target location +| `area_push` | Pushes `valid_targets` in aoe away from the target location | `teleport_random` | teleports the player randomly range spaces with aoe variation | `targeted_polymorph` | A targeted monster is permanently transformed into the monster ID specified by `effect_str` if it has less HP than the spell's damage. If `effect_str` is left empty, the target will transform into a random monster with a similar difficulty rating, alternatively the flag `"POLYMORPH_GROUP"` can be used to pick a weighted monster ID from a monster group. The player and NPCs are immune to this spell effect. | `recover_energy` | recovers an energy source equal to damage of the spell. The energy source recovered is defined in "effect_str" and may be one of "MANA", "STAMINA", "FATIGUE", "PAIN", "BIONIC" @@ -115,6 +118,14 @@ Below is a table of currently implemented effects, along with special rules for | `charm_monster` | charms a monster that has less hp than damage() for approximately duration() | `mutate` | mutates the target(s). if effect_str is defined, mutates toward that category instead of picking at random. the "MUTATE_TRAIT" flag allows effect_str to be a specific trait instead of a category. damage() / 100 is the percent chance the mutation will be successful (a value of 10000 represents 100.00%) | `bash` | bashes the terrain at the target. uses damage() as the strength of the bash. +| `dash` | dashes forward up to range and hits targets in a cone at the target +| `banishment` | kills monsters in the aoe up to damage hp. any overflow hp the monster has is taken from the caster; if it's more hp than the caster has it fails. +| `revive` | Revives a monster like a zombie necromancer. The monster must have the revives flag +| `upgrade` | Immediately upgrades a target monster +| `guilt` | The target gets the guilt morale as if it killed the caster +| `remove_effect` | Removes `effect_str` effects from all creatures in aoe +| `emit` | Causes an emit at the target +| `fungalize` | Fungalizes the target Another mandatory member is spell "shape". This dictates how the area of effect works. diff --git a/doc/MONSTERS.md b/doc/MONSTERS.md index cd178a3ba2f35..c1aaa28818cb6 100644 --- a/doc/MONSTERS.md +++ b/doc/MONSTERS.md @@ -341,9 +341,16 @@ Percent multiplier on all bleed effects' duration applied to the monster. Values An item group that is used to spawn items when the monster dies. This can be an inlined item group, see [ITEM_SPAWN.md](ITEM_SPAWN.md). The default subtype is "distribution". ## "death_function" -(array of strings, optional) +(object, optional) -How the monster behaves on death. See [JSON_FLAGS.md](JSON_FLAGS.md) for a list of possible functions. +How the monster behaves on death. +```cpp +{ + "corpse_type": "NORMAL", // can be: BROKEN, NO_CORPSE, NORMAL (default) + "message": "The %s dies!", // substitute %s for the monster's name. + "effect": { "id": "death_boomer", "hit_self": true } // the actual effect that gets called when the monster dies. follows the syntax of fake_spell. +} +``` ## "emit_field" (array of objects of emit_id and time_duration, optional) diff --git a/src/magic.cpp b/src/magic.cpp index 46aed434905b3..452fd99a44ac5 100644 --- a/src/magic.cpp +++ b/src/magic.cpp @@ -2350,6 +2350,11 @@ void spellbook_callback::refresh( uilist *menu ) wnoutrefresh( menu->window ); } +bool fake_spell::is_valid() const +{ + return id.is_valid() && !id.is_empty(); +} + void fake_spell::load( const JsonObject &jo ) { mandatory( jo, false, "id", id ); diff --git a/src/magic.h b/src/magic.h index de1cf0ad4b2c9..0388917ab8b7a 100644 --- a/src/magic.h +++ b/src/magic.h @@ -169,6 +169,7 @@ struct fake_spell { // gets the spell with an additional override for minimum level (default 0) spell get_spell( int min_level_override = 0 ) const; + bool is_valid() const; void load( const JsonObject &jo ); void serialize( JsonOut &json ) const; void deserialize( JsonIn &jsin ); @@ -697,6 +698,14 @@ void mutate( const spell &sp, Creature &caster, const tripoint &target ); void bash( const spell &sp, Creature &caster, const tripoint &target ); void dash( const spell &sp, Creature &caster, const tripoint &target ); void banishment( const spell &sp, Creature &caster, const tripoint &target ); +// revives a monster into some kind of zombie if the monster has the revives flag +void revive( const spell &sp, Creature &caster, const tripoint &target ); +void upgrade( const spell &sp, Creature &caster, const tripoint &target ); +// causes guilt to the target as if it killed the caster +void guilt( const spell &sp, Creature &caster, const tripoint &target ); +void remove_effect( const spell &sp, Creature &caster, const tripoint &target ); +void emit( const spell &sp, Creature &caster, const tripoint &target ); +void fungalize( const spell &sp, Creature &caster, const tripoint &target ); void none( const spell &sp, Creature &, const tripoint &target ); static const std::map @@ -735,6 +744,12 @@ effect_map{ { "bash", spell_effect::bash }, { "dash", spell_effect::dash }, { "banishment", spell_effect::banishment }, + { "revive", spell_effect::revive }, + { "upgrade", spell_effect::upgrade }, + { "guilt", spell_effect::guilt }, + { "remove_effect", spell_effect::remove_effect }, + { "emit", spell_effect::emit }, + { "fungalize", spell_effect::fungalize }, { "none", spell_effect::none } }; } // namespace spell_effect diff --git a/src/magic_spell_effect.cpp b/src/magic_spell_effect.cpp index 20da42d70dd54..0409308ed17d6 100644 --- a/src/magic_spell_effect.cpp +++ b/src/magic_spell_effect.cpp @@ -29,8 +29,10 @@ #include "explosion.h" #include "field.h" #include "field_type.h" +#include "fungal_effects.h" #include "game.h" #include "item.h" +#include "kill_tracker.h" #include "line.h" #include "magic.h" #include "magic_spell_effect_helpers.h" @@ -42,6 +44,7 @@ #include "mongroup.h" #include "monster.h" #include "monstergenerator.h" +#include "morale.h" #include "mtype.h" #include "npc.h" #include "optional.h" @@ -61,8 +64,17 @@ #include "vehicle.h" #include "vpart_position.h" +static const json_character_flag json_flag_PRED1( "PRED1" ); +static const json_character_flag json_flag_PRED2( "PRED2" ); +static const json_character_flag json_flag_PRED3( "PRED3" ); +static const json_character_flag json_flag_PRED4( "PRED4" ); + static const mtype_id mon_generator( "mon_generator" ); +static const trait_id trait_KILLER( "KILLER" ); +static const trait_id trait_PACIFIST( "PACIFIST" ); +static const trait_id trait_PSYCHOPATH( "PSYCHOPATH" ); + namespace spell_detail { struct line_iterable { @@ -1180,6 +1192,142 @@ void spell_effect::charm_monster( const spell &sp, Creature &caster, const tripo } } +void spell_effect::revive( const spell &sp, Creature &caster, const tripoint &target ) +{ + const std::set area = spell_effect_area( sp, target, caster ); + ::map &here = get_map(); + const species_id spec( sp.effect_data() ); + for( const tripoint &aoe : area ) { + for( item &corpse : here.i_at( aoe ) ) { + const mtype *mt = corpse.get_mtype(); + if( !( corpse.is_corpse() && corpse.can_revive() && corpse.active && + mt->has_flag( MF_REVIVES ) && mt->in_species( spec ) && + !mt->has_flag( MF_NO_NECRO ) ) ) { + continue; + } + if( g->revive_corpse( aoe, corpse ) ) { + here.i_rem( aoe, &corpse ); + break; + } + } + } +} + +void spell_effect::upgrade( const spell &sp, Creature &caster, const tripoint &target ) +{ + const std::set area = spell_effect_area( sp, target, caster ); + for( const tripoint &aoe : area ) { + monster *mon = g->critter_at( aoe ); + if( mon != nullptr && rng( 1, 10000 ) < sp.damage() ) { + mon->allow_upgrade(); + mon->try_upgrade( false ); + } + } +} + +void spell_effect::guilt( const spell &sp, Creature &caster, const tripoint &target ) +{ + const std::set area = spell_effect_area( sp, target, caster ); + if( !caster.is_monster() ) { + // only monsters cause the guilt morale effect + return; + } + for( const tripoint &aoe : area ) { + Character *guilt_target = g->critter_at( aoe ); + if( guilt_target == nullptr ) { + continue; + } + // there used to be a MAX_GUILT_DISTANCE here, but the spell's range will do this instead. + monster &z = *caster.as_monster(); + const int kill_count = g->get_kill_tracker().kill_count( z.type->id ); + // this is when the player stops caring altogether. + const int max_kills = sp.damage(); + + // different message as we kill more of the same monster + std::string msg = _( "You feel guilty for killing %s." ); // default guilt message + game_message_type msgtype = m_bad; // default guilt message type + std::map guilt_thresholds; + guilt_thresholds[75] = _( "You feel ashamed for killing %s." ); + guilt_thresholds[50] = _( "You regret killing %s." ); + guilt_thresholds[25] = _( "You feel remorse for killing %s." ); + + Character &guy = *guilt_target; + if( guy.has_trait( trait_PSYCHOPATH ) || guy.has_trait( trait_KILLER ) || + guy.has_trait_flag( json_flag_PRED3 ) || guy.has_trait_flag( json_flag_PRED4 ) ) { + // specially immune. + return; + } + + if( kill_count >= max_kills ) { + // player no longer cares + if( kill_count == max_kills ) { + //~ Message after killing a lot of monsters which would normally affect the morale negatively. %s is the monster name, it most likely will be pluralized. + add_msg( m_good, _( "After killing so many bloody %s you no longer care " + "about their deaths anymore." ), z.name( max_kills ) ); + } + return; + } else if( ( guy.has_trait_flag( json_flag_PRED1 ) ) || + ( guy.has_trait_flag( json_flag_PRED2 ) ) ) { + msg = ( _( "Culling the weak is distasteful, but necessary." ) ); + msgtype = m_neutral; + } else { + for( const std::pair &guilt_threshold : guilt_thresholds ) { + if( kill_count >= guilt_threshold.first ) { + msg = guilt_threshold.second; + break; + } + } + } + + add_msg( msgtype, msg, z.name() ); + + int moraleMalus = -50 * ( 1.0 - ( static_cast( kill_count ) / max_kills ) ); + const int maxMalus = -250 * ( 1.0 - ( static_cast( kill_count ) / max_kills ) ); + const time_duration duration = sp.duration_turns() * + ( 1.0 - ( static_cast( kill_count ) / max_kills ) ); + const time_duration decayDelay = 3_minutes * + ( 1.0 - ( static_cast( kill_count ) / max_kills ) ); + if( z.type->in_species( species_id( sp.effect_data() ) ) ) { + moraleMalus /= 10; + if( guy.has_trait( trait_PACIFIST ) ) { + moraleMalus *= 5; + } else if( guy.has_trait_flag( json_flag_PRED1 ) ) { + moraleMalus /= 4; + } else if( guy.has_trait_flag( json_flag_PRED2 ) ) { + moraleMalus /= 5; + } + } + guy.add_morale( MORALE_KILLED_MONSTER, moraleMalus, maxMalus, duration, decayDelay ); + } +} + +void spell_effect::remove_effect( const spell &sp, Creature &caster, const tripoint &target ) +{ + const std::set area = spell_effect_area( sp, target, caster ); + for( const tripoint &aoe : area ) { + if( Creature *critter = g->critter_at( aoe ) ) { + critter->remove_effect( efftype_id( sp.effect_data() ) ); + } + } +} + +void spell_effect::emit( const spell &sp, Creature &caster, const tripoint &target ) +{ + const std::set area = spell_effect_area( sp, target, caster ); + for( const tripoint &aoe : area ) { + get_map().emit_field( aoe, emit_id( sp.effect_data() ) ); + } +} + +void spell_effect::fungalize( const spell &sp, Creature &caster, const tripoint &target ) +{ + const std::set area = spell_effect_area( sp, target, caster ); + fungal_effects fe( *g, get_map() ); + for( const tripoint &aoe : area ) { + fe.fungalize( aoe, &caster, sp.damage() / 10000.0 ); + } +} + void spell_effect::mutate( const spell &sp, Creature &caster, const tripoint &target ) { const std::set area = spell_effect_area( sp, target, caster ); diff --git a/src/mondeath.cpp b/src/mondeath.cpp index a23e51f0b22d3..1d07aa007599d 100644 --- a/src/mondeath.cpp +++ b/src/mondeath.cpp @@ -49,42 +49,10 @@ #include "value_ptr.h" #include "viewer.h" -static const efftype_id effect_amigara( "amigara" ); -static const efftype_id effect_boomered( "boomered" ); -static const efftype_id effect_controlled( "controlled" ); -static const efftype_id effect_darkness( "darkness" ); -static const efftype_id effect_glowing( "glowing" ); static const efftype_id effect_no_ammo( "no_ammo" ); -static const efftype_id effect_rat( "rat" ); -static const json_character_flag json_flag_PRED1( "PRED1" ); -static const json_character_flag json_flag_PRED2( "PRED2" ); -static const json_character_flag json_flag_PRED3( "PRED3" ); -static const json_character_flag json_flag_PRED4( "PRED4" ); - -static const itype_id itype_processor( "processor" ); - -static const species_id species_SLIME( "SLIME" ); static const species_id species_ZOMBIE( "ZOMBIE" ); -static const mtype_id mon_blob( "mon_blob" ); -static const mtype_id mon_blob_brain( "mon_blob_brain" ); -static const mtype_id mon_blob_small( "mon_blob_small" ); -static const mtype_id mon_breather( "mon_breather" ); -static const mtype_id mon_breather_hub( "mon_breather_hub" ); -static const mtype_id mon_creeper_hub( "mon_creeper_hub" ); -static const mtype_id mon_creeper_vine( "mon_creeper_vine" ); -static const mtype_id mon_giant_cockroach_nymph( "mon_giant_cockroach_nymph" ); -static const mtype_id mon_halfworm( "mon_halfworm" ); -static const mtype_id mon_sewer_rat( "mon_sewer_rat" ); -static const mtype_id mon_thing( "mon_thing" ); -static const mtype_id mon_zombie_dancer( "mon_zombie_dancer" ); -static const mtype_id mon_zombie_hulk( "mon_zombie_hulk" ); - -static const trait_id trait_KILLER( "KILLER" ); -static const trait_id trait_PACIFIST( "PACIFIST" ); -static const trait_id trait_PSYCHOPATH( "PSYCHOPATH" ); - void mdeath::normal( monster &z ) { if( z.no_corpse_quiet ) { @@ -108,18 +76,10 @@ void mdeath::normal( monster &z ) z.bleed(); // leave some blood if we have to - if( !pulverized ) { - make_mon_corpse( z, static_cast( std::floor( corpse_damage * itype::damage_scale ) ) ); - } - // if mdeath::splatter was set along normal makes sure it is not called twice - bool splatt = false; - for( const auto &deathfunction : z.type->dies ) { - if( deathfunction == mdeath::splatter ) { - splatt = true; - } - } - if( !splatt ) { + if( pulverized ) { splatter( z ); + } else { + make_mon_corpse( z, static_cast( std::floor( corpse_damage * itype::damage_scale ) ) ); } } } @@ -174,13 +134,6 @@ void mdeath::splatter( monster &z ) const int max_hp = std::max( z.get_hp_max(), 1 ); const float overflow_damage = std::max( -z.get_hp(), 0 ); const float corpse_damage = 2.5 * overflow_damage / max_hp; - bool pulverized = corpse_damage > 5 && overflow_damage > z.get_hp_max(); - // make sure that full splatter happens when this is a set death function, not part of normal - for( const auto &deathfunction : z.type->dies ) { - if( deathfunction == mdeath::splatter ) { - pulverized = true; - } - } const field_type_id type_blood = z.bloodType(); const field_type_id type_gib = z.gibType(); @@ -190,7 +143,7 @@ void mdeath::splatter( monster &z ) const auto area = here.points_in_radius( z.pos(), 1 ); int number_of_gibs = std::min( std::floor( corpse_damage ) - 1, 1 + max_hp / 5.0f ); - if( pulverized && z.type->size >= creature_size::medium ) { + if( z.type->size >= creature_size::medium ) { number_of_gibs += rng( 1, 6 ); sfx::play_variant_sound( "mon_death", "zombie_gibbed", sfx::get_heard_volume( z.pos() ) ); } @@ -207,7 +160,7 @@ void mdeath::splatter( monster &z ) // limit gibbing to 15% gibbed_weight = std::min( gibbed_weight, z_weight * 15 / 100 ); - if( pulverized && gibbable ) { + if( gibbable ) { float overflow_ratio = overflow_damage / max_hp + 1.0f; int gib_distance = std::round( rng( 2, 4 ) ); for( const auto &entry : *z.type->harvest ) { @@ -241,388 +194,11 @@ void mdeath::splatter( monster &z ) } } -void mdeath::acid( monster &z ) -{ - if( get_player_view().sees( z ) ) { - if( z.type->dies.size() == - 1 ) { //If this death function is the only function. The corpse gets dissolved. - add_msg( m_mixed, _( "The %s's body dissolves into acid." ), z.name() ); - } else { - add_msg( m_warning, _( "The %s's body leaks acid." ), z.name() ); - } - } - get_map().add_field( z.pos(), fd_acid, 3 ); -} - -void mdeath::boomer( monster &z ) -{ - map &here = get_map(); - std::string explode = string_format( _( "a %s explode!" ), z.name() ); - sounds::sound( z.pos(), 24, sounds::sound_t::combat, explode, false, "explosion", "small" ); - for( const tripoint &dest : here.points_in_radius( z.pos(), 1 ) ) { // *NOPAD* - here.bash( dest, 10 ); - if( monster *const target = g->critter_at( dest ) ) { - target->stumble(); - target->moves -= 250; - } - } - - Character &player_character = get_player_character(); - if( rl_dist( z.pos(), player_character.pos() ) == 1 ) { - player_character.add_env_effect( effect_boomered, bodypart_id( "eyes" ), 2, 24_turns ); - } - - here.propagate_field( z.pos(), fd_bile, 15, 1 ); -} - -void mdeath::boomer_glow( monster &z ) -{ - std::string explode = string_format( _( "a %s explode!" ), z.name() ); - sounds::sound( z.pos(), 24, sounds::sound_t::combat, explode, false, "explosion", "small" ); - map &here = get_map(); - - for( const tripoint &dest : here.points_in_radius( z.pos(), 1 ) ) { // *NOPAD* - here.bash( dest, 10 ); - if( monster *const target = g->critter_at( dest ) ) { - target->stumble(); - target->moves -= 250; - } - if( Creature *const critter = g->critter_at( dest ) ) { - critter->add_env_effect( effect_boomered, bodypart_id( "eyes" ), 5, 25_turns ); - for( int i = 0; i < rng( 2, 4 ); i++ ) { - const bodypart_id &bp = critter->random_body_part(); - critter->add_env_effect( effect_glowing, bp, 4, 4_minutes ); - if( critter->has_effect( effect_glowing ) ) { - break; - } - } - } - } - - here.propagate_field( z.pos(), fd_bile, 30, 2 ); -} - -void mdeath::kill_vines( monster &z ) -{ - const std::vector vines = g->get_creatures_if( [&]( const Creature & critter ) { - const monster *const mon = dynamic_cast( &critter ); - return mon && mon->type->id == mon_creeper_vine; - } ); - const std::vector hubs = g->get_creatures_if( [&]( const Creature & critter ) { - const monster *const mon = dynamic_cast( &critter ); - return mon && mon != &z && mon->type->id == mon_creeper_hub; - } ); - - for( Creature *const vine : vines ) { - int dist = rl_dist( vine->pos(), z.pos() ); - bool closer = false; - for( const Creature *j : hubs ) { - if( rl_dist( vine->pos(), j->pos() ) < dist ) { - break; - } - } - if( !closer ) { // TODO: closer variable is not being updated and is always false! - vine->die( &z ); - } - } -} - -void mdeath::vine_cut( monster &z ) -{ - map &here = get_map(); - std::vector vines; - for( const tripoint &tmp : here.points_in_radius( z.pos(), 1 ) ) { - if( tmp == z.pos() ) { - continue; // Skip ourselves - } - if( monster *const neighbor = g->critter_at( tmp ) ) { - if( neighbor->type->id == mon_creeper_vine ) { - vines.push_back( neighbor ); - } - } - } - - for( auto &vine : vines ) { - bool found_neighbor = false; - for( const tripoint &dest : here.points_in_radius( vine->pos(), 1 ) ) { - if( dest != z.pos() ) { - // Not the dying vine - if( monster *const v = g->critter_at( dest ) ) { - if( v->type->id == mon_creeper_hub || v->type->id == mon_creeper_vine ) { - found_neighbor = true; - break; - } - } - } - } - if( !found_neighbor ) { - vine->die( &z ); - } - } -} - -void mdeath::triffid_heart( monster &z ) -{ - add_msg_if_player_sees( z, m_warning, _( "The surrounding roots begin to crack and crumble." ) ); - get_timed_events().add( timed_event_type::ROOTS_DIE, calendar::turn + 10_minutes ); -} - -void mdeath::fungus( monster &z ) -{ - //~ the sound of a fungus dying - sounds::sound( z.pos(), 10, sounds::sound_t::combat, _( "Pouf!" ), false, "misc", "puff" ); - - map &here = get_map(); - fungal_effects fe( *g, here ); - for( const tripoint &sporep : here.points_in_radius( z.pos(), 1 ) ) { // *NOPAD* - if( here.impassable( sporep ) ) { - continue; - } - // z is dead, don't credit it with the kill - // Maybe credit z's killer? - fe.fungalize( sporep, nullptr, 0.25 ); - } -} - -void mdeath::disintegrate( monster &z ) -{ - add_msg_if_player_sees( z, m_good, _( "The %s disintegrates!" ), z.name() ); -} - -void mdeath::worm( monster &z ) -{ - if( z.type->dies.size() == 1 ) { - add_msg_if_player_sees( z, m_good, _( "The %s splits in two!" ), z.name() ); - } else { - add_msg_if_player_sees( z, m_warning, _( "Two worms crawl out of the %s's corpse." ), z.name() ); - } - - int worms = 2; - while( worms > 0 && g->place_critter_around( mon_halfworm, z.pos(), 1 ) ) { - worms--; - } -} - void mdeath::disappear( monster &z ) { add_msg_if_player_sees( z, m_good, _( "The %s disappears." ), z.name() ); } -void mdeath::guilt( monster &z ) -{ - const int MAX_GUILT_DISTANCE = 5; - int kill_count = g->get_kill_tracker().kill_count( z.type->id ); - int maxKills = 100; // this is when the player stop caring altogether. - - // different message as we kill more of the same monster - std::string msg = _( "You feel guilty for killing %s." ); // default guilt message - game_message_type msgtype = m_bad; // default guilt message type - std::map guilt_tresholds; - guilt_tresholds[75] = _( "You feel ashamed for killing %s." ); - guilt_tresholds[50] = _( "You regret killing %s." ); - guilt_tresholds[25] = _( "You feel remorse for killing %s." ); - - Character &player_character = get_player_character(); - if( player_character.has_trait( trait_PSYCHOPATH ) || - player_character.has_trait_flag( json_flag_PRED3 ) || - player_character.has_trait_flag( json_flag_PRED4 ) || player_character.has_trait( trait_KILLER ) ) { - return; - } - if( rl_dist( z.pos(), player_character.pos() ) > MAX_GUILT_DISTANCE ) { - // Too far away, we can deal with it. - return; - } - if( z.get_hp() >= 0 ) { - // We probably didn't kill it - return; - } - if( kill_count >= maxKills ) { - // player no longer cares - if( kill_count == maxKills ) { - //~ Message after killing a lot of monsters which would normally affect the morale negatively. %s is the monster name, it will be pluralized with a number of 100. - add_msg( m_good, _( "After killing so many bloody %s you no longer care " - "about their deaths anymore." ), z.name( maxKills ) ); - } - return; - } else if( ( player_character.has_trait_flag( json_flag_PRED1 ) ) || - ( player_character.has_trait_flag( json_flag_PRED2 ) ) ) { - msg = ( _( "Culling the weak is distasteful, but necessary." ) ); - msgtype = m_neutral; - } else { - for( auto &guilt_treshold : guilt_tresholds ) { - if( kill_count >= guilt_treshold.first ) { - msg = guilt_treshold.second; - break; - } - } - } - - add_msg( msgtype, msg, z.name() ); - - int moraleMalus = -50 * ( 1.0 - ( static_cast( kill_count ) / maxKills ) ); - int maxMalus = -250 * ( 1.0 - ( static_cast( kill_count ) / maxKills ) ); - time_duration duration = 30_minutes * ( 1.0 - ( static_cast( kill_count ) / maxKills ) ); - time_duration decayDelay = 3_minutes * ( 1.0 - ( static_cast( kill_count ) / maxKills ) ); - if( z.type->in_species( species_ZOMBIE ) ) { - moraleMalus /= 10; - if( player_character.has_trait( trait_PACIFIST ) ) { - moraleMalus *= 5; - } else if( player_character.has_trait_flag( json_flag_PRED1 ) ) { - moraleMalus /= 4; - } else if( player_character.has_trait_flag( json_flag_PRED2 ) ) { - moraleMalus /= 5; - } - } - player_character.add_morale( MORALE_KILLED_MONSTER, moraleMalus, maxMalus, duration, decayDelay ); - -} - -void mdeath::blobsplit( monster &z ) -{ - int speed = z.get_speed() - rng( 30, 50 ); - get_map().spawn_item( z.pos(), "slime_scrap", 1, 0, calendar::turn ); - bool sees_blob = get_player_view().sees( z ); - if( z.get_speed() <= 0 && sees_blob ) { - // TODO: Add vermin-tagged tiny versions of the splattered blob :) - add_msg( m_good, _( "The %s splatters apart." ), z.name() ); - return; - } - if( sees_blob ) { - if( z.type->dies.size() == 1 ) { - add_msg( m_good, _( "The %s splits in two!" ), z.name() ); - } else { - add_msg( m_bad, _( "Two small slimes slither out of the corpse." ) ); - } - } - - const mtype_id &child = speed < 50 ? mon_blob_small : mon_blob; - for( int s = 0; s < 2; s++ ) { - if( monster *const blob = g->place_critter_around( child, z.pos(), 1 ) ) { - blob->make_ally( z ); - blob->set_speed_base( speed ); - blob->set_hp( speed ); - } - } -} - -void mdeath::brainblob( monster &z ) -{ - for( monster &critter : g->all_monsters() ) { - if( critter.type->in_species( species_SLIME ) && critter.type->id != mon_blob_brain ) { - critter.remove_effect( effect_controlled ); - } - } - blobsplit( z ); -} - -void mdeath::jackson( monster &z ) -{ - bool music_stopped = false; - for( monster &critter : g->all_monsters() ) { - if( critter.type->id == mon_zombie_dancer ) { - critter.poly( mon_zombie_hulk ); - critter.remove_effect( effect_controlled ); - } - music_stopped = true; - } - if( music_stopped ) { - add_msg_if_player_sees( z, m_warning, _( "The music stops!" ) ); - } -} - -void mdeath::melt( monster &z ) -{ - add_msg_if_player_sees( z, m_good, _( "The %s melts away." ), z.name() ); -} - -void mdeath::amigara( monster &z ) -{ - const bool has_others = g->get_creature_if( [&]( const Creature & critter ) { - if( const monster *const candidate = dynamic_cast( &critter ) ) { - return candidate->type == z.type; - } - return false; - } ); - if( has_others ) { - return; - } - - // We were the last! - Character &player_character = get_player_character(); - if( player_character.has_effect( effect_amigara ) ) { - player_character.remove_effect( effect_amigara ); - add_msg( _( "Your obsession with the fault fades away…" ) ); - } - - get_map().spawn_artifact( z.pos(), relic_procgen_id( "netherum_tunnels" ) ); -} - -void mdeath::thing( monster &z ) -{ - g->place_critter_at( mon_thing, z.pos() ); -} - -void mdeath::explode( monster &z ) -{ - int size = 0; - switch( z.type->size ) { - case creature_size::tiny: - size = 4; - break; - case creature_size::small: - size = 8; - break; - case creature_size::medium: - size = 14; - break; - case creature_size::large: - size = 20; - break; - case creature_size::huge: - size = 26; - break; - case creature_size::num_sizes: - debugmsg( "ERROR: Invalid Creature size class." ); - break; - } - explosion_handler::explosion( z.pos(), size ); -} - -void mdeath::focused_beam( monster &z ) -{ - map &here = get_map(); - map_stack items = here.i_at( z.pos() ); - for( map_stack::iterator it = items.begin(); it != items.end(); ) { - if( it->typeId() == itype_processor ) { - it = items.erase( it ); - } else { - ++it; - } - } - - if( !z.inv.empty() ) { - add_msg_if_player_sees( z, m_warning, - _( "As the final light is destroyed, it erupts in a blinding flare!" ) ); - item &settings = z.inv[0]; - - point p2( z.posx() + settings.get_var( "SL_SPOT_X", 0 ), z.posy() + settings.get_var( "SL_SPOT_Y", - 0 ) ); - tripoint p( p2, z.posz() ); - - std::vector traj = line_to( z.pos(), p, 0, 0 ); - for( auto &elem : traj ) { - if( !here.is_transparent( elem ) ) { - break; - } - here.add_field( elem, fd_dazzling, 2 ); - } - } - - z.inv.clear(); - - explosion_handler::explosion( z.pos(), 8 ); -} - void mdeath::broken( monster &z ) { // Bail out if flagged (simulates eyebot flying away) @@ -688,105 +264,6 @@ void mdeath::broken( monster &z ) } } -void mdeath::ratking( monster &z ) -{ - Character &player_character = get_player_character(); - player_character.remove_effect( effect_rat ); - add_msg_if_player_sees( z, m_warning, _( "Rats suddenly swarm into view." ) ); - - for( int rats = 0; rats < 7; rats++ ) { - g->place_critter_around( mon_sewer_rat, z.pos(), 1 ); - } -} - -void mdeath::darkman( monster &z ) -{ - Character &player_character = get_player_character(); - player_character.remove_effect( effect_darkness ); - add_msg_if_player_sees( z, m_good, _( "The %s melts away." ), z.name() ); -} - -void mdeath::gas( monster &z ) -{ - std::string explode = string_format( _( "a %s explode!" ), z.name() ); - sounds::sound( z.pos(), 24, sounds::sound_t::combat, explode, false, "explosion", "small" ); - get_map().emit_field( z.pos(), emit_id( "emit_toxic_blast" ) ); -} - -void mdeath::smokeburst( monster &z ) -{ - std::string explode = string_format( _( "a %s explode!" ), z.name() ); - sounds::sound( z.pos(), 24, sounds::sound_t::combat, explode, false, "explosion", "small" ); - get_map().emit_field( z.pos(), emit_id( "emit_smoke_blast" ) ); -} - -void mdeath::tearburst( monster &z ) -{ - std::string explode = string_format( _( "a %s explode!" ), z.name() ); - sounds::sound( z.pos(), 24, sounds::sound_t::combat, explode, false, "explosion", "small" ); - get_map().emit_field( z.pos(), emit_id( "emit_tear_gas_blast" ) ); -} - -void mdeath::fungalburst( monster &z ) -{ - map &here = get_map(); - // If the fungus died from anti-fungal poison, don't pouf - if( here.get_field_intensity( z.pos(), fd_fungicidal_gas ) ) { - add_msg_if_player_sees( z, m_good, _( "The %s inflates and melts away." ), z.name() ); - return; - } - - std::string explode = string_format( _( "a %s explodes!" ), z.name() ); - sounds::sound( z.pos(), 24, sounds::sound_t::combat, explode, false, "explosion", "small" ); - here.emit_field( z.pos(), emit_id( "emit_fungal_blast" ) ); -} - -void mdeath::jabberwock( monster &z ) -{ - Character *ch = dynamic_cast( z.get_killer() ); - - bool vorpal = ch && ch->is_player() && - ch->weapon.has_flag( STATIC( flag_id( "DIAMOND" ) ) ) && - ch->weapon.volume() > 750_ml; - - if( vorpal && !ch->weapon.has_technique( matec_id( "VORPAL" ) ) ) { - if( ch->sees( z ) ) { - ch->add_msg_if_player( m_info, - //~ %s is the possessive form of the monster's name - _( "As the flames in %s eyes die out, your weapon seems to shine slightly brighter." ), - z.disp_name( true ) ); - } - ch->weapon.add_technique( matec_id( "VORPAL" ) ); - } - - mdeath::normal( z ); -} - -void mdeath::gameover( monster &z ) -{ - add_msg( m_bad, _( "The %s was destroyed! GAME OVER!" ), z.name() ); - get_player_character().set_part_hp_cur( bodypart_id( "torso" ), 0 ); -} - -void mdeath::kill_breathers( monster &/*z*/ ) -{ - for( monster &critter : g->all_monsters() ) { - const mtype_id &monID = critter.type->id; - if( monID == mon_breather_hub || monID == mon_breather ) { - critter.die( nullptr ); - } - } -} - -void mdeath::broken_ammo( monster &z ) -{ - add_msg_if_player_sees( z.pos(), m_info, - //~ %s is the possessive form of the monster's name - _( "The %s's interior compartment sizzles with destructive energy." ), - z.name() ); - mdeath::broken( z ); -} - void make_mon_corpse( monster &z, int damageLvl ) { item corpse = item::make_corpse( z.type->id, calendar::turn, z.unique_name, z.get_upgrade_time() ); @@ -801,65 +278,3 @@ void make_mon_corpse( monster &z, int damageLvl ) } get_map().add_item_or_charges( z.pos(), corpse ); } - -void mdeath::preg_roach( monster &z ) -{ - int num_roach = rng( 1, 3 ); - while( num_roach > 0 && g->place_critter_around( mon_giant_cockroach_nymph, z.pos(), 1 ) ) { - num_roach--; - add_msg_if_player_sees( z, m_warning, - _( "A cockroach nymph crawls out of the pregnant giant cockroach corpse." ) ); - } -} - -void mdeath::fireball( monster &z ) -{ - if( one_in( 10 ) ) { - get_map().propagate_field( z.pos(), fd_fire, 15, 3 ); - std::string explode = string_format( _( "an explosion of tank of the %s's flamethrower!" ), - z.name() ); - sounds::sound( z.pos(), 24, sounds::sound_t::combat, explode, false, "explosion", "default" ); - add_msg( m_good, _( "I love the smell of burning zed in the morning." ) ); - } else { - normal( z ); - } -} - -void mdeath::conflagration( monster &z ) -{ - map &here = get_map(); - for( const auto &dest : here.points_in_radius( z.pos(), 1 ) ) { - here.propagate_field( dest, fd_fire, 18, 3 ); - } - const std::string explode = string_format( _( "a %s explode!" ), z.name() ); - sounds::sound( z.pos(), 24, sounds::sound_t::combat, explode, false, "explosion", "small" ); - -} - -void mdeath::necro_boomer( monster &z ) -{ - map &here = get_map(); - std::string explode = string_format( _( "a %s explode!" ), z.name() ); - sounds::sound( z.pos(), 24, sounds::sound_t::combat, explode, false, "explosion", "small" ); - for( const tripoint &aoe : here.points_in_radius( z.pos(), 10 ) ) { - for( item &corpse : here.i_at( aoe ) ) { - const mtype *mt = corpse.get_mtype(); - if( !( corpse.is_corpse() && corpse.can_revive() && corpse.active && - mt->has_flag( MF_REVIVES ) && mt->in_species( species_ZOMBIE ) && - !mt->has_flag( MF_NO_NECRO ) ) ) { - continue; - } - if( g->revive_corpse( aoe, corpse ) ) { - here.i_rem( aoe, &corpse ); - break; - } - } - } - for( const tripoint &aoe : here.points_in_radius( z.pos(), 10 ) ) { - monster *mon = g->critter_at( aoe ); - if( mon != nullptr && one_in( 10 ) ) { - mon->allow_upgrade(); - mon->try_upgrade( false ); - } - } -} diff --git a/src/mondeath.h b/src/mondeath.h index a34c3b67088f4..a92d38f4d21da 100644 --- a/src/mondeath.h +++ b/src/mondeath.h @@ -10,81 +10,10 @@ namespace mdeath void normal( monster &z ); // Overkill splatter (also part of normal under conditions) void splatter( monster &z ); -// Acid instead of a body -void acid( monster &z ); -// Explodes in vomit :3 -void boomer( monster &z ); -// Explodes in vomit :3 -void boomer_glow( monster &z ); -// Kill all nearby vines -void kill_vines( monster &z ); -// Kill adjacent vine if it's cut -void vine_cut( monster &z ); -// Destroy all roots -void triffid_heart( monster &z ); -// Explodes in spores D: -void fungus( monster &z ); -// Falls apart -void disintegrate( monster &z ); -// Screams loudly -void shriek( monster &z ); -// Wolf's howling -void howl( monster &z ); -// Rattles like a rattlesnake -void rattle( monster &z ); -// Spawns 2 half-worms -void worm( monster &z ); // Hallucination disappears void disappear( monster &z ); -// Morale penalty -void guilt( monster &z ); -// Frees blobs, redirects to blobsplit -void brainblob( monster &z ); -// Creates more blobs -void blobsplit( monster &z ); -// Reverts dancers -void jackson( monster &z ); -// Normal death, but melts -void melt( monster &z ); -// Removes hypnosis if last one -void amigara( monster &z ); -// Turn into a full thing -void thing( monster &z ); -// Damaging explosion -void explode( monster &z ); -// Blinding ray -void focused_beam( monster &z ); // Broken robot drop void broken( monster &z ); -// Cure verminitis -void ratking( monster &z ); -// Sight returns to normal -void darkman( monster &z ); -// Explodes in toxic gas -void gas( monster &z ); -// All breathers die -void kill_breathers( monster &z ); -// Explode like a huge smoke bomb. -void smokeburst( monster &z ); -// Explode like a huge tear gas bomb. -void tearburst( monster &z ); -// Explode releasing fungal haze. -void fungalburst( monster &z ); -// Snicker-snack! -void jabberwock( monster &z ); -// Breaks ammo and then itself -void broken_ammo( monster &z ); -// Spawns 1-3 roach nymphs -void preg_roach( monster &z ); -// Explodes in fire -void fireball( monster &z ); -// Similar to above but bigger and guaranteed. -void conflagration( monster &z ); -// raises and then upgrades all zombies in a radius -void necro_boomer( monster &z ); - -// Game over! Defense mode -void gameover( monster &z ); } //namespace mdeath void make_mon_corpse( monster &z, int damageLvl ); diff --git a/src/monster.cpp b/src/monster.cpp index 9cbe859c40df9..d9d1fb68faa5d 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -121,7 +121,6 @@ static const trait_id trait_BEE( "BEE" ); static const trait_id trait_FLOWERS( "FLOWERS" ); static const trait_id trait_KILLER( "KILLER" ); static const trait_id trait_MYCUS_FRIEND( "MYCUS_FRIEND" ); -static const trait_id trait_PACIFIST( "PACIFIST" ); static const trait_id trait_PHEROMONE_INSECT( "PHEROMONE_INSECT" ); static const trait_id trait_PHEROMONE_MAMMAL( "PHEROMONE_MAMMAL" ); static const trait_id trait_TERRIFYING( "TERRIFYING" ); @@ -2352,22 +2351,19 @@ void monster::die( Creature *nkiller ) if( death_drops && !no_extra_death_drops ) { drop_items_on_death(); } - // TODO: should actually be class Character - player *ch = dynamic_cast( get_killer() ); - if( !is_hallucination() && ch != nullptr ) { - if( ( has_flag( MF_GUILT ) && ch->is_player() ) || ( ch->has_trait( trait_PACIFIST ) && - has_flag( MF_HUMAN ) ) ) { - // has guilt flag or player is pacifist && monster is humanoid - mdeath::guilt( *this ); - } - get_event_bus().send( ch->getID(), type->id ); - if( ch->is_player() && ch->has_trait( trait_KILLER ) ) { - if( one_in( 4 ) ) { - const translation snip = SNIPPET.random_from_category( "killer_on_kill" ).value_or( translation() ); - ch->add_msg_if_player( m_good, "%s", snip ); + if( nkiller != nullptr ) { + // TODO: should actually be class Character + Character *ch = get_killer()->as_character(); + if( !is_hallucination() && ch != nullptr ) { + get_event_bus().send( ch->getID(), type->id ); + if( ch->is_player() && ch->has_trait( trait_KILLER ) ) { + if( one_in( 4 ) ) { + const translation snip = SNIPPET.random_from_category( "killer_on_kill" ).value_or( translation() ); + ch->add_msg_if_player( m_good, "%s", snip ); + } + ch->add_morale( MORALE_KILLER_HAS_KILLED, 5, 10, 6_hours, 4_hours ); + ch->rem_morale( MORALE_KILLER_NEED_TO_KILL ); } - ch->add_morale( MORALE_KILLER_HAS_KILLED, 5, 10, 6_hours, 4_hours ); - ch->rem_morale( MORALE_KILLER_NEED_TO_KILL ); } } if( death_drops ) { @@ -2434,6 +2430,7 @@ void monster::die( Creature *nkiller ) } } mission::on_creature_death( *this ); + // Also, perform our death function if( is_hallucination() || summon_time_limit ) { //Hallucinations always just disappear @@ -2441,9 +2438,32 @@ void monster::die( Creature *nkiller ) return; } - //Not a hallucination, go process the death effects. - for( const auto &deathfunction : type->dies ) { - deathfunction( *this ); + add_msg_if_player_sees( *this, m_good, type->mdeath_effect.death_message.translated(), name() ); + + // drop a corpse, or not + switch( type->mdeath_effect.corpse_type ) { + case mdeath_type::NORMAL: + mdeath::normal( *this ); + break; + case mdeath_type::BROKEN: + mdeath::broken( *this ); + break; + case mdeath_type::SPLATTER: + mdeath::splatter( *this ); + break; + default: + break; + } + + if( type->mdeath_effect.has_effect ) { + //Not a hallucination, go process the death effects. + spell death_spell = type->mdeath_effect.sp.get_spell(); + if( killer != nullptr && type->mdeath_effect.sp.self && + death_spell.is_target_in_range( *this, killer->pos() ) ) { + death_spell.cast_all_effects( *this, killer->pos() ); + } else if( type->mdeath_effect.sp.self ) { + death_spell.cast_all_effects( *this, pos() ); + } } // If our species fears seeing one of our own die, process that diff --git a/src/monstergenerator.cpp b/src/monstergenerator.cpp index 3b7db5a6d6814..352c976c45909 100644 --- a/src/monstergenerator.cpp +++ b/src/monstergenerator.cpp @@ -68,6 +68,25 @@ std::string enum_to_string( mon_trigger data ) abort(); } +template<> +std::string enum_to_string( mdeath_type data ) +{ + switch( data ) { + case mdeath_type::NORMAL: + return "NORMAL"; + case mdeath_type::SPLATTER: + return "SPLATTER"; + case mdeath_type::BROKEN: + return "BROKEN"; + case mdeath_type::NO_CORPSE: + return "NO_CORPSE"; + case mdeath_type::LAST: + break; + } + debugmsg( "Invalid mdeath_type" ); + abort(); +} + template<> std::string enum_to_string( m_flag data ) { @@ -244,7 +263,6 @@ MonsterGenerator::MonsterGenerator() init_phases(); init_attack(); init_defense(); - init_death(); } MonsterGenerator::~MonsterGenerator() = default; @@ -473,90 +491,6 @@ void MonsterGenerator::init_phases() phase_map["PLASMA"] = phase_id::PLASMA; } -void MonsterGenerator::init_death() -{ - // Drop a body - death_map["NORMAL"] = &mdeath::normal; - // Explodes in gibs and chunks - death_map["SPLATTER"] = &mdeath::splatter; - // Acid instead of a body - death_map["ACID"] = &mdeath::acid; - // Explodes in vomit :3 - death_map["BOOMER"] = &mdeath::boomer; - // Explodes in glowing vomit :3 - death_map["BOOMER_GLOW"] = &mdeath::boomer_glow; - // Kill all nearby vines - death_map["KILL_VINES"] = &mdeath::kill_vines; - // Kill adjacent vine if it's cut - death_map["VINE_CUT"] = &mdeath::vine_cut; - // Destroy all roots - death_map["TRIFFID_HEART"] = &mdeath::triffid_heart; - // Explodes in spores D: - death_map["FUNGUS"] = &mdeath::fungus; - // Falls apart - death_map["DISINTEGRATE"] = &mdeath::disintegrate; - // Spawns 2 half-worms - death_map["WORM"] = &mdeath::worm; - // Hallucination disappears - death_map["DISAPPEAR"] = &mdeath::disappear; - // Morale penalty - death_map["GUILT"] = &mdeath::guilt; - // Frees blobs, redirects to brainblob() - death_map["BRAINBLOB"] = &mdeath::brainblob; - // Creates more blobs - death_map["BLOBSPLIT"] = &mdeath::blobsplit; - // Reverts dancers - death_map["JACKSON"] = &mdeath::jackson; - // Normal death, but melts - death_map["MELT"] = &mdeath::melt; - // Removes hypnosis if last one - death_map["AMIGARA"] = &mdeath::amigara; - // Turn into a full thing - death_map["THING"] = &mdeath::thing; - // Damaging explosion - death_map["EXPLODE"] = &mdeath::explode; - // Blinding ray - death_map["FOCUSEDBEAM"] = &mdeath::focused_beam; - // Spawns a broken robot. - death_map["BROKEN"] = &mdeath::broken; - // Cure verminitis - death_map["RATKING"] = &mdeath::ratking; - // Sight returns to normal - death_map["DARKMAN"] = &mdeath::darkman; - // Explodes in toxic gas - death_map["GAS"] = &mdeath::gas; - // All breathers die - death_map["KILL_BREATHERS"] = &mdeath::kill_breathers; - // Gives a message about destroying ammo and then calls "BROKEN" - death_map["BROKEN_AMMO"] = &mdeath::broken_ammo; - // Explode like a huge smoke bomb. - death_map["SMOKEBURST"] = &mdeath::smokeburst; - // Explode like a huge tear gas bomb. - death_map["TEARBURST"] = &mdeath::tearburst; - // Explode with a cloud of fungal haze. - death_map["FUNGALBURST"] = &mdeath::fungalburst; - // Snicker-snack! - death_map["JABBERWOCKY"] = &mdeath::jabberwock; - // Game over! Defense mode - death_map["GAMEOVER"] = &mdeath::gameover; - // Spawn some cockroach nymphs - death_map["PREG_ROACH"] = &mdeath::preg_roach; - // Explode in a fireball - death_map["FIREBALL"] = &mdeath::fireball; - // Explode in a huge fireball - death_map["CONFLAGRATION"] = &mdeath::conflagration; - // resurrect all zombies in the area and upgrade all zombies in the area - death_map["NECRO_BOOMER"] = &mdeath::necro_boomer; - - /* Currently Unimplemented */ - // Screams loudly - //death_map["SHRIEK"] = &mdeath::shriek; - // Wolf's howling - //death_map["HOWL"] = &mdeath::howl; - // Rattles like a rattlesnake - //death_map["RATTLE"] = &mdeath::rattle; -} - void MonsterGenerator::init_attack() { add_hardcoded_attack( "NONE", mattack::none ); @@ -845,12 +779,7 @@ void mtype::load( const JsonObject &jo, const std::string &src ) shearing = shearing_data( entries ); } - const auto death_reader = make_flag_reader( gen.death_map, "monster death function" ); - optional( jo, was_loaded, "death_function", dies, death_reader ); - if( dies.empty() ) { - // TODO: really needed? Is an empty `dies` container not allowed? - dies.push_back( mdeath::normal ); - } + optional( jo, was_loaded, "death_function", mdeath_effect ); if( jo.has_array( "emit_fields" ) ) { JsonArray jar = jo.get_array( "emit_fields" ); @@ -1351,3 +1280,17 @@ void MonsterGenerator::check_monster_definitions() const } } } + +void monster_death_effect::load( const JsonObject &jo ) +{ + optional( jo, was_loaded, "message", death_message, to_translation( "The %s dies!" ) ); + optional( jo, was_loaded, "effect", sp ); + has_effect = sp.is_valid(); + optional( jo, was_loaded, "corpse_type", corpse_type, mdeath_type::NORMAL ); +} + +void monster_death_effect::deserialize( JsonIn &jsin ) +{ + JsonObject data = jsin.get_object(); + load( data ); +} diff --git a/src/monstergenerator.h b/src/monstergenerator.h index 06a29d39ee0b6..83ff673550924 100644 --- a/src/monstergenerator.h +++ b/src/monstergenerator.h @@ -84,7 +84,6 @@ class MonsterGenerator // Init functions void init_phases(); - void init_death(); void init_attack(); void init_defense(); diff --git a/src/mtype.cpp b/src/mtype.cpp index 2c39c0e81b80c..cf45b2938957b 100644 --- a/src/mtype.cpp +++ b/src/mtype.cpp @@ -53,7 +53,6 @@ mtype::mtype() biosig_item = itype_id::NULL_ID(); burn_into = mtype_id::NULL_ID(); - dies.push_back( &mdeath::normal ); sp_defense = nullptr; harvest = harvest_id( "human" ); luminance = 0; diff --git a/src/mtype.h b/src/mtype.h index 9e1b68c8753bc..09d71eba54263 100644 --- a/src/mtype.h +++ b/src/mtype.h @@ -14,6 +14,7 @@ #include "damage.h" #include "enum_bitset.h" #include "enums.h" +#include "magic.h" #include "mattack_common.h" #include "optional.h" #include "pathfinding.h" @@ -202,6 +203,30 @@ struct mon_effect_data { chance( nchance ) {} }; +enum class mdeath_type { + NORMAL, + SPLATTER, + BROKEN, + NO_CORPSE, + LAST +}; + +template<> +struct enum_traits { + static constexpr mdeath_type last = mdeath_type::LAST; +}; + +struct monster_death_effect { + bool was_loaded = false; + bool has_effect = false; + fake_spell sp; + translation death_message; + mdeath_type corpse_type = mdeath_type::NORMAL; + + void load( const JsonObject &jo ); + void deserialize( JsonIn &jsin ); +}; + struct mtype { private: friend class MonsterGenerator; @@ -309,7 +334,7 @@ struct mtype { std::map special_attacks; std::vector special_attacks_names; // names of attacks, in json load order - std::vector dies; // What happens when this monster dies + monster_death_effect mdeath_effect; // This monster's special "defensive" move that may trigger when the monster is attacked. // Note that this can be anything, and is not necessarily beneficial to the monster diff --git a/tests/monster_test.cpp b/tests/monster_test.cpp index 68983eeb63016..02c1ba8ecd532 100644 --- a/tests/monster_test.cpp +++ b/tests/monster_test.cpp @@ -361,12 +361,8 @@ TEST_CASE( "monster_broken_verify", "[monster]" ) // verify monsters with death_function = BROKEN // actually have appropriate broken_name items const MonsterGenerator &generator = MonsterGenerator::generator(); - const mon_action_death func = generator.get_death_function( "BROKEN" ).value(); for( const mtype &montype : generator.get_all_mtypes() ) { - const std::vector &die_funcs = montype.dies; - const auto broken_func_it = std::find( die_funcs.cbegin(), die_funcs.cend(), func ); - - if( broken_func_it == die_funcs.cend() ) { + if( montype.mdeath_effect.corpse_type != mdeath_type::BROKEN ) { continue; } From ef8144d97258b9fb0f6cf083df16c13fa2f4fe04 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Fri, 9 Jul 2021 12:01:15 -0700 Subject: [PATCH 114/116] Fix JSON errors, DPS test, partial proficiency test (#49779) * Fix JSON errors, DPS test Add a missing comma, two spaces between sentences, and fix the DPS test. The DPS test probably could use something more than just matching the value, but that's all I'm doing for now. * Fix partial proficiency tests 'practice_proficiency' was not practicing the correct amount due to focus or other changes when this test was run in conjunction with other tests. Add a function to unconditionally practice a proficiency a certain amount, and use it. * Fix old-style monster death function --- data/json/effect_on_condition.json | 4 ++-- data/json/monsters/nether.json | 2 +- data/json/snippets/effect_on_conditions.json | 6 +++--- src/character.cpp | 10 ++++++++++ src/character.h | 3 +++ tests/crafting_test.cpp | 14 +++++++------- tests/effective_dps_test.cpp | 2 +- 7 files changed, 27 insertions(+), 14 deletions(-) diff --git a/data/json/effect_on_condition.json b/data/json/effect_on_condition.json index f09601fd3ca28..ac131715bc8f1 100644 --- a/data/json/effect_on_condition.json +++ b/data/json/effect_on_condition.json @@ -97,9 +97,9 @@ "type": "effect_on_condition", "id": "EOC_MINOR_SLEEP", "effect": [ { "message": "You feel sleepy…" }, { "u_mod_fatigue": 20 } ] - } + }, { - "type": "effect_on_condition", + "type": "effect_on_condition", "id": "night_messages", "recurrence_min": "4 hours", "recurrence_max": "8 hours", diff --git a/data/json/monsters/nether.json b/data/json/monsters/nether.json index c14478e1f75a1..7b86b198cf4fb 100644 --- a/data/json/monsters/nether.json +++ b/data/json/monsters/nether.json @@ -347,7 +347,7 @@ "//": "Reduce bullet armor when things are harder to hit or players miss more", "anger_triggers": [ "FIRE" ], "fear_triggers": [ "HURT" ], - "death_function": [ "MELT" ], + "death_function": { "corpse_type": "NO_CORPSE", "message": "The %s melts away." }, "flags": [ "SEES", "HEARS", diff --git a/data/json/snippets/effect_on_conditions.json b/data/json/snippets/effect_on_conditions.json index 81489bbbe0691..11138e0ace058 100644 --- a/data/json/snippets/effect_on_conditions.json +++ b/data/json/snippets/effect_on_conditions.json @@ -31,9 +31,9 @@ "You see what seems to be a new constellation in the sky. It reminds you of a serpent - it moves like one.", "You see a shooting star. It seems to be heading straight for you before vanishing suddenly.", "For a brief moment, you see a pentagonal shape in the sky, roughly twice the size of the moon. It splits into several triangles and then reforms before vanishing.", - "As you look at the stars, they wink out for an instant, reappearing just slightly out of place, as if the night sky had been rotated ever so slightly. This occurs twice more, in rapid succession.", - "A strange cloud seems to float in the sky, at the very edge of your peripheral vision. Just as you shift your gaze to it, it evaporates, boiling away into a stream of shooting stars.", - "For a brief moment, you feel like you've been jerked to the side. You haven't moved, though - the stars have.", + "As you look at the stars, they wink out for an instant, reappearing just slightly out of place, as if the night sky had been rotated ever so slightly. This occurs twice more, in rapid succession.", + "A strange cloud seems to float in the sky, at the very edge of your peripheral vision. Just as you shift your gaze to it, it evaporates, boiling away into a stream of shooting stars.", + "For a brief moment, you feel like you've been jerked to the side. You haven't moved, though - the stars have.", "As you look at the stars, a broad swath of them are plunged into darkness, then come back to life in ragged succession." ] } diff --git a/src/character.cpp b/src/character.cpp index 2a3d3ec4456cd..4117b13227e93 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -20,6 +20,7 @@ #include "anatomy.h" #include "avatar.h" #include "bionics.h" +#include "cached_options.h" #include "cata_utility.h" #include "catacharset.h" #include "character_martial_arts.h" @@ -12826,6 +12827,15 @@ std::vector Character::learning_proficiencies() const return _proficiencies->learning_profs(); } +void Character::set_proficiency_practice( const proficiency_id &id, const time_duration &amount ) +{ + if( !test_mode ) { + return; + } + + _proficiencies->practice( id, amount, cata::nullopt ); +} + bool Character::defer_move( const tripoint &next ) { // next must be adjacent to current pos diff --git a/src/character.h b/src/character.h index 0c8c7ed5b922f..148ed686285be 100644 --- a/src/character.h +++ b/src/character.h @@ -1846,6 +1846,9 @@ class Character : public Creature, public visitable std::vector known_proficiencies() const; std::vector learning_proficiencies() const; + // tests only! + void set_proficiency_practice( const proficiency_id &id, const time_duration &amount ); + // --------------- Other Stuff --------------- /** return the calendar::turn the character expired */ diff --git a/tests/crafting_test.cpp b/tests/crafting_test.cpp index a3bc92f8a17ac..ab3c775839648 100644 --- a/tests/crafting_test.cpp +++ b/tests/crafting_test.cpp @@ -938,25 +938,25 @@ TEST_CASE( "partial_proficiency_mitigation", "[crafting][proficiency]" ) GIVEN( "a recipe with required proficiencies" ) { clear_avatar(); clear_map(); + Character &tester = get_player_character(); const recipe &test_recipe = *recipe_id( "leather_belt" ); - grant_skills_to_character( get_player_character(), test_recipe ); - int unmitigated_time_taken = test_recipe.batch_time( get_player_character(), 1, 1, 0 ); + grant_skills_to_character( tester, test_recipe ); + int unmitigated_time_taken = test_recipe.batch_time( tester, 1, 1, 0 ); WHEN( "player acquires partial proficiency" ) { int np = 0; for( const proficiency_id &prof : test_recipe.assist_proficiencies() ) { np++; - get_player_character().practice_proficiency( prof, - get_player_character().proficiency_training_needed( prof ) / 2 ); + tester.set_proficiency_practice( prof, tester.proficiency_training_needed( prof ) / 2 ); } - int mitigated_time_taken = test_recipe.batch_time( get_player_character(), 1, 1, 0 ); + int mitigated_time_taken = test_recipe.batch_time( tester, 1, 1, 0 ); THEN( "it takes less time to craft the recipe" ) { CHECK( mitigated_time_taken < unmitigated_time_taken ); } AND_WHEN( "player acquires missing proficiencies" ) { - grant_proficiencies_to_character( get_player_character(), test_recipe, true ); - int proficient_time_taken = test_recipe.batch_time( get_player_character(), 1, 1, 0 ); + grant_proficiencies_to_character( tester, test_recipe, true ); + int proficient_time_taken = test_recipe.batch_time( tester, 1, 1, 0 ); THEN( "it takes even less time to craft the recipe" ) { CHECK( proficient_time_taken < mitigated_time_taken ); } diff --git a/tests/effective_dps_test.cpp b/tests/effective_dps_test.cpp index 75e4df3b1fee7..fa1aceb1bb8bf 100644 --- a/tests/effective_dps_test.cpp +++ b/tests/effective_dps_test.cpp @@ -268,7 +268,7 @@ TEST_CASE( "expected weapon dps", "[expected][dps]" ) SECTION( "staves" ) { // typical value around 18 calc_expected_dps( test_guy, "i_staff", 22.75 ); - calc_expected_dps( test_guy, "staff_sling", 17 ); + calc_expected_dps( test_guy, "staff_sling", 15 ); calc_expected_dps( test_guy, "q_staff", 20.75 ); calc_expected_dps( test_guy, "l-stick_on", 17.5 ); calc_expected_dps( test_guy, "l-stick", 17.5 ); From e4e6ac8eb94b95186bd69b7b716f2a70828a00a1 Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Fri, 9 Jul 2021 13:09:01 -0700 Subject: [PATCH 115/116] Update src/item.cpp --- src/item.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/item.cpp b/src/item.cpp index d9100c811475b..570d6e3698e35 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -5131,7 +5131,6 @@ units::mass item::weight( bool include_contents, bool integral ) const ret *= 0.75; } - // if this is a gun apply all of its gunmods' weight multipliers if( type->gun ) { for( const item *mod : gunmods() ) { From c1159c2b67204c7517a7061e816968b4453a88b0 Mon Sep 17 00:00:00 2001 From: Saicchi <47158232+Saicchi@users.noreply.github.com> Date: Fri, 9 Jul 2021 18:03:41 -0300 Subject: [PATCH 116/116] Jsonize terrain and furniture lockpicking result (#48836) * lockpick_result and lockpick_message json * lockpicking use new lockpick_result and lockpick_message fields * hardcoded to json lockpicking conversion and open/locked gunsafe --- .../furniture-storage.json | 58 ++++++++++++++++++- .../furniture_and_terrain/terrain-doors.json | 12 ++++ .../terrain-fences-gates.json | 4 ++ doc/JSON_INFO.md | 19 ++++++ src/activity_actor.cpp | 49 ++++++++-------- src/mapdata.cpp | 7 +++ src/mapdata.h | 5 ++ 7 files changed, 128 insertions(+), 26 deletions(-) diff --git a/data/json/furniture_and_terrain/furniture-storage.json b/data/json/furniture_and_terrain/furniture-storage.json index ea36a295ef3ca..524e067292c38 100644 --- a/data/json/furniture_and_terrain/furniture-storage.json +++ b/data/json/furniture_and_terrain/furniture-storage.json @@ -282,11 +282,63 @@ ] } }, + { + "type": "furniture", + "id": "f_gunsafe_o", + "name": "open gun safe", + "description": "A large and heavy container with thick metal walls and a rotary combination lock, this is designed to securely store firearms, weapon mods, and ammunition.", + "symbol": "X", + "color": "light_gray", + "looks_like": "f_gunsafe_ml", + "move_cost_mod": -1, + "coverage": 30, + "required_str": 14, + "max_volume": "250 L", + "close": "f_gunsafe_c", + "flags": [ "TRANSPARENT", "CONTAINER", "PLACE_ITEM", "MOUNTABLE", "MINEABLE" ], + "bash": { + "str_min": 40, + "str_max": 200, + "sound": "screeching metal!", + "sound_fail": "whump!", + "items": [ + { "item": "steel_chunk", "count": [ 1, 5 ] }, + { "item": "scrap", "count": [ 1, 5 ] }, + { "item": "rock", "count": [ 1, 2 ] } + ] + } + }, + { + "type": "furniture", + "id": "f_gunsafe_c", + "name": "closed gun safe", + "description": "A large and heavy container with thick metal walls and a rotary combination lock, this is designed to securely store firearms, weapon mods, and ammunition.", + "symbol": "X", + "color": "light_gray", + "looks_like": "f_gunsafe_ml", + "move_cost_mod": -1, + "coverage": 30, + "required_str": 14, + "max_volume": "250 L", + "open": "f_gunsafe_o", + "flags": [ "TRANSPARENT", "CONTAINER", "SEALED", "PLACE_ITEM", "MOUNTABLE", "MINEABLE" ], + "bash": { + "str_min": 40, + "str_max": 200, + "sound": "screeching metal!", + "sound_fail": "whump!", + "items": [ + { "item": "steel_chunk", "count": [ 1, 5 ] }, + { "item": "scrap", "count": [ 1, 5 ] }, + { "item": "rock", "count": [ 1, 2 ] } + ] + } + }, { "type": "furniture", "id": "f_gunsafe_ml", - "name": "gun safe", - "description": "A large and heavy container with thick metal walls and a rotary combination lock, this is designed to securely store firearms, weapon mods, and ammunition. If you had something to listen close with and a hell of a lot of time, you could probably crack it.", + "name": "locked gun safe", + "description": "A large and heavy container with thick metal walls and a rotary combination lock, this is designed to securely store firearms, weapon mods, and ammunition. If you had something to pick its lock with, you could probably open it.", "symbol": "X", "color": "light_gray", "move_cost_mod": -1, @@ -294,6 +346,8 @@ "required_str": 14, "max_volume": "250 L", "flags": [ "TRANSPARENT", "CONTAINER", "SEALED", "PLACE_ITEM", "MOUNTABLE", "MINEABLE", "PICKABLE" ], + "lockpick_result": "f_gunsafe_o", + "lockpick_message": "With a satisfying click, the lock on the gun safe door opens.", "examine_action": "locked_object_pickable", "bash": { "str_min": 40, diff --git a/data/json/furniture_and_terrain/terrain-doors.json b/data/json/furniture_and_terrain/terrain-doors.json index d017cb560107d..10897f0c9b459 100644 --- a/data/json/furniture_and_terrain/terrain-doors.json +++ b/data/json/furniture_and_terrain/terrain-doors.json @@ -1390,6 +1390,8 @@ "color": "brown", "move_cost": 0, "coverage": 95, + "lockpick_result": "t_door_c", + "lockpick_message": "With a satisfying click, the lock on the door opens.", "roof": "t_flat_roof", "flags": [ "FLAMMABLE_ASH", @@ -1428,6 +1430,8 @@ "color": "brown", "move_cost": 0, "coverage": 95, + "lockpick_result": "t_door_c", + "lockpick_message": "With a satisfying click, the lock on the door opens.", "roof": "t_flat_roof", "flags": [ "FLAMMABLE_ASH", @@ -1468,6 +1472,8 @@ "color": "brown", "move_cost": 0, "coverage": 95, + "lockpick_result": "t_door_c_peep", + "lockpick_message": "With a satisfying click, the lock on the door opens.", "roof": "t_flat_roof", "flags": [ "FLAMMABLE_ASH", @@ -1508,6 +1514,8 @@ "color": "brown", "move_cost": 0, "coverage": 95, + "lockpick_result": "t_door_c", + "lockpick_message": "With a satisfying click, the lock on the door opens.", "roof": "t_flat_roof", "flags": [ "FLAMMABLE_ASH", @@ -2176,6 +2184,8 @@ "color": "cyan", "move_cost": 0, "coverage": 95, + "lockpick_result": "t_door_metal_c", + "lockpick_message": "With a satisfying click, the lock on the door opens.", "roof": "t_flat_roof", "flags": [ "NOITEM", "REDUCE_SCENT", "OPENCLOSE_INSIDE", "CONNECT_TO_WALL", "LOCKED", "BLOCK_WIND", "PICKABLE" ], "open": "t_door_metal_o", @@ -2259,6 +2269,8 @@ "color": "cyan", "move_cost": 0, "roof": "t_flat_roof", + "lockpick_result": "t_door_bar_o", + "lockpick_message": "The door swings open…", "flags": [ "TRANSPARENT", "NOITEM", "PERMEABLE", "CONNECT_TO_WALL", "LOCKED", "THIN_OBSTACLE", "PICKABLE" ], "examine_action": "locked_object_pickable", "bash": { diff --git a/data/json/furniture_and_terrain/terrain-fences-gates.json b/data/json/furniture_and_terrain/terrain-fences-gates.json index 57d8494c1a30f..944d7a42043a3 100644 --- a/data/json/furniture_and_terrain/terrain-fences-gates.json +++ b/data/json/furniture_and_terrain/terrain-fences-gates.json @@ -64,6 +64,8 @@ "symbol": "+", "color": "cyan", "move_cost": 0, + "lockpick_result": "t_chaingate_c", + "lockpick_message": "With a satisfying click, the lock on the gate opens.", "flags": [ "TRANSPARENT", "PERMEABLE", "LOCKED", "PICKABLE", "THIN_OBSTACLE", "BURROWABLE" ], "connects_to": "CHAINFENCE", "examine_action": "locked_object_pickable", @@ -139,6 +141,8 @@ "flags": [ "TRANSPARENT", "PERMEABLE", "LOCKED", "PICKABLE", "THIN_OBSTACLE" ], "connects_to": "WALL", "examine_action": "locked_object_pickable", + "lockpick_result": "t_retractable_gate_c", + "lockpick_message": "With a satisfying click, the lock on the gate opens.", "bash": { "str_min": 17, "str_max": 175, diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index 0bdecf450d93c..0f19d68f9092c 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -3354,6 +3354,8 @@ itype_id of the item dropped as leftovers after butchery or when the monster is "examine_action": "toilet", "close": "f_foo_closed", "open": "f_foo_open", + "lockpick_result": "f_safe_open", + "lockpick_message": "With a click, you unlock the safe.", "bash": "TODO", "deconstruct": "TODO", "max_volume": "1000 L", @@ -3374,6 +3376,13 @@ Same as for terrain, see below in the chapter "Common to furniture and terrain". Movement cost modifier (`-10` = impassable, `0` = no change). This is added to the movecost of the underlying terrain. +#### `lockpick_result` + +(Optional) When the furniture is successfully lockpicked, this is the furniture it will turn into. + +#### `lockpick_message` + +(Optional) When the furniture is successfully lockpicked, this is the message that will be printed to the player. When it is missing, a generic `"The lock opens…"` message will be printed instead. #### `light_emitted` @@ -3419,6 +3428,8 @@ Strength required to move the furniture around. Negative values indicate an unmo "connects_to" : "WALL", "close": "t_foo_closed", "open": "t_foo_open", + "lockpick_result": "t_door_unlocked", + "lockpick_message": "With a click, you unlock the door.", "bash": "TODO", "deconstruct": "TODO", "harvestable": "blueberries", @@ -3450,6 +3461,14 @@ Heat emitted for a terrain. A value of 0 means no fire (i.e, same as not having How much light the terrain emits. 10 will light the tile it's on brightly, 15 will light that tile and the tiles around it brightly, as well as slightly lighting the tiles two tiles away from the source. For examples: An overhead light is 120, a utility light, 240, and a console, 10. +#### `lockpick_result` + +(Optional) When the terrain is successfully lockpicked, this is the terrain it will turn into. + +#### `lockpick_message` + +(Optional) When the terrain is successfully lockpicked, this is the message that will be printed to the player. When it is missing, a generic `"The lock opens…"` message will be printed instead. + #### `trap` (Optional) Id of the build-in trap of that terrain. diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index 73bfcad937ebb..1a9e519989a37 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -1184,6 +1184,9 @@ void lockpick_activity_actor::start( player_activity &act, Character & ) { act.moves_left = moves_total; act.moves_total = moves_total; + + const time_duration lockpicking_time = time_duration::from_moves( moves_total ); + add_msg_debug( debugmode::DF_ACT_LOCKPICK, "lockpicking time = %s", to_string( lockpicking_time ) ); } void lockpick_activity_actor::finish( player_activity &act, Character &who ) @@ -1208,30 +1211,28 @@ void lockpick_activity_actor::finish( player_activity &act, Character &who ) const furn_id furn_type = here.furn( target ); ter_id new_ter_type; furn_id new_furn_type; - std::string open_message; - if( ter_type == t_chaingate_l ) { - new_ter_type = t_chaingate_c; - open_message = _( "With a satisfying click, the lock on the gate opens." ); - } else if( ter_type == t_door_locked || ter_type == t_door_locked_alarm || - ter_type == t_door_locked_interior ) { - new_ter_type = t_door_c; - open_message = _( "With a satisfying click, the lock on the door opens." ); - } else if( ter_type == t_door_locked_peep ) { - new_ter_type = t_door_c_peep; - open_message = _( "With a satisfying click, the lock on the door opens." ); - } else if( ter_type == t_retractable_gate_l ) { - new_ter_type = t_retractable_gate_c; - open_message = _( "With a satisfying click, the lock on the gate opens." ); - } else if( ter_type == t_door_metal_pickable ) { - new_ter_type = t_door_metal_c; - open_message = _( "With a satisfying click, the lock on the door opens." ); - } else if( ter_type == t_door_bar_locked ) { - new_ter_type = t_door_bar_o; - //Bar doors auto-open (and lock if closed again) so show a different message) - open_message = _( "The door swings open…" ); - } else if( furn_type == f_gunsafe_ml ) { - new_furn_type = f_safe_o; - open_message = _( "With a satisfying click, the lock on the door opens." ); + std::string open_message = _( "The lock opens…" ); + + if( here.has_furn( target ) ) { + if( furn_type->lockpick_result.is_null() ) { + debugmsg( "%s lockpick_result is null", furn_type.id().str() ); + return; + } + + new_furn_type = furn_type->lockpick_result; + if( !furn_type->lockpick_message.empty() ) { + open_message = furn_type->lockpick_message.translated(); + } + } else { + if( ter_type->lockpick_result.is_null() ) { + debugmsg( "%s lockpick_result is null", ter_type.id().str() ); + return; + } + + new_ter_type = ter_type->lockpick_result; + if( !ter_type->lockpick_message.empty() ) { + open_message = ter_type->lockpick_message.translated(); + } } bool perfect = it->has_flag( flag_PERFECT_LOCKPICK ); diff --git a/src/mapdata.cpp b/src/mapdata.cpp index 6bbbffebf27a3..e16a219bfed05 100644 --- a/src/mapdata.cpp +++ b/src/mapdata.cpp @@ -1253,6 +1253,9 @@ 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() ); + optional( jo, was_loaded, "lockpick_result", lockpick_result, ter_str_id::NULL_ID() ); + optional( jo, was_loaded, "lockpick_message", lockpick_message, translation() ); + optional( jo, was_loaded, "emissions", emissions ); bash.load( jo, "bash", map_bash_info::terrain, "terrain " + id.str() ); @@ -1393,6 +1396,10 @@ 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() ); + optional( jo, was_loaded, "lockpick_result", lockpick_result, string_id_reader {}, + furn_str_id::NULL_ID() ); + optional( jo, was_loaded, "lockpick_message", lockpick_message, translation() ); + bash.load( jo, "bash", map_bash_info::furniture, "furniture " + id.str() ); deconstruct.load( jo, "deconstruct", true, "furniture " + id.str() ); diff --git a/src/mapdata.h b/src/mapdata.h index b355717e544dd..bf727d4d5c438 100644 --- a/src/mapdata.h +++ b/src/mapdata.h @@ -374,6 +374,9 @@ struct ter_t : map_data_common_t { ter_str_id open; // Open action: transform into terrain with matching id ter_str_id close; // Close action: transform into terrain with matching id + ter_str_id lockpick_result; // Lockpick action: transform when successfully lockpicked + translation lockpick_message; // Lockpick action: message when successfully lockpicked + std::string trap_id_str; // String storing the id string of the trap. ter_str_id transforms_into; // Transform into what terrain? ter_str_id roof; // What will be the floor above this terrain @@ -406,6 +409,8 @@ struct furn_t : map_data_common_t { furn_str_id id; furn_str_id open; // Open action: transform into furniture with matching id furn_str_id close; // Close action: transform into furniture with matching id + furn_str_id lockpick_result; // Lockpick action: transform when successfully lockpicked + translation lockpick_message; // Lockpick action: message when successfully lockpicked itype_id crafting_pseudo_item; units::volume keg_capacity = 0_ml; int comfort = 0;