From e812b54aa5fef250e1d702869cdbb09088d207ab Mon Sep 17 00:00:00 2001 From: Valiant Date: Thu, 5 Dec 2019 22:51:53 +0400 Subject: [PATCH 01/16] Check for armor coverage Also fixed a bug when bees phase through solid matter --- src/map_field.cpp | 57 +++++++++++++---------------------------------- 1 file changed, 16 insertions(+), 41 deletions(-) diff --git a/src/map_field.cpp b/src/map_field.cpp index a559e9bb487ac..dab6c6928ca24 100644 --- a/src/map_field.cpp +++ b/src/map_field.cpp @@ -1233,7 +1233,7 @@ bool map::process_fields_in_submap( submap *const current_submap, // Bees chase the player if in range, wander randomly otherwise. if( !g->u.is_underwater() && rl_dist( p, g->u.pos() ) < 10 && - clear_path( p, g->u.pos(), 10, 0, 100 ) ) { + clear_path( p, g->u.pos(), 10, 1, 100 ) ) { std::vector candidate_positions = squares_in_direction( p.xy(), point( g->u.posx(), g->u.posy() ) ); @@ -1602,47 +1602,22 @@ void map::player_in_field( player &u ) if( ft == fd_bees ) { // Player is immune to bees while underwater. if( !u.is_underwater() ) { - int times_stung = 0; const int intensity = cur.get_field_intensity(); - // If the bees can get at you, they cause steadily increasing pain. - // TODO: Specific stinging messages. - times_stung += one_in( 4 ) && - u.add_env_effect( effect_stung, bp_torso, intensity, 9_minutes ); - times_stung += one_in( 4 ) && - u.add_env_effect( effect_stung, bp_torso, intensity, 9_minutes ); - times_stung += one_in( 4 ) && - u.add_env_effect( effect_stung, bp_torso, intensity, 9_minutes ); - times_stung += one_in( 4 ) && - u.add_env_effect( effect_stung, bp_torso, intensity, 9_minutes ); - times_stung += one_in( 4 ) && - u.add_env_effect( effect_stung, bp_torso, intensity, 9_minutes ); - times_stung += one_in( 4 ) && - u.add_env_effect( effect_stung, bp_torso, intensity, 9_minutes ); - times_stung += one_in( 4 ) && - u.add_env_effect( effect_stung, bp_torso, intensity, 9_minutes ); - times_stung += one_in( 4 ) && - u.add_env_effect( effect_stung, bp_torso, intensity, 9_minutes ); - switch( times_stung ) { - case 0: - // Woo, unscathed! - break; - case 1: - u.add_msg_if_player( m_bad, _( "The bees sting you!" ) ); - break; - case 2: - case 3: - u.add_msg_if_player( m_bad, _( "The bees sting you several times!" ) ); - break; - case 4: - case 5: - u.add_msg_if_player( m_bad, _( "The bees sting you many times!" ) ); - break; - case 6: - case 7: - case 8: - default: - u.add_msg_if_player( m_bad, _( "The bees sting you all over your body!" ) ); - break; + // Bees will try to sting you in random body parts, up to 8 times. + for( int i = 0; i < rng( 1, 7 ); i++ ) { + body_part bp = random_body_part(); + int sum_cover = 0; + for( const item &i : u.worn ) { + if( i.covers( bp ) ) { + sum_cover += i.get_coverage(); + } + } + // Get stung if [clothing on a body part isn't thick enough (like t-shirt) OR clothing covers less than 100% of body part] + // AND clothing on affected body part has low environmental protection value + if( ( u.get_armor_cut( bp ) <= 1 || ( sum_cover < 100 && x_in_y( 100 - sum_cover, 100 ) ) ) && + u.add_env_effect( effect_stung, bp, intensity, 9_minutes ) ) { + u.add_msg_if_player( m_bad, _( "The bees sting you in %s!" ), body_part_name_accusative( bp ) ); + } } } } From 3f5ade8d1022dc0d1f21688308b3df463d5460c4 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Wed, 4 Dec 2019 17:55:22 +0000 Subject: [PATCH 02/16] Fix Toxins not working with simplified nutrition This commit adds vitamin `types`, different variations of vitamins that can later be expanded to have different effects. These are dynamically loaded from JSON into 4 types, vitamin, toxin, drug, and counter. Only vitamin, toxin, and counter are used right now. Only the vitamin type has an effect, used with simplified nutrition to make it so that that vitamin has no effect. --- data/json/vitamin.json | 7 +++++++ src/consumption.cpp | 2 +- src/item_factory.cpp | 6 +++++- src/vitamin.cpp | 27 +++++++++++++++++++++++++++ src/vitamin.h | 18 ++++++++++++++++++ 5 files changed, 58 insertions(+), 2 deletions(-) diff --git a/data/json/vitamin.json b/data/json/vitamin.json index 7afb21569abb0..9e448c98b0337 100644 --- a/data/json/vitamin.json +++ b/data/json/vitamin.json @@ -2,6 +2,7 @@ { "id": "calcium", "type": "vitamin", + "vit_type": "vitamin", "name": "Calcium", "deficiency": "hypocalcemia", "min": -12000, @@ -11,6 +12,7 @@ { "id": "iron", "type": "vitamin", + "vit_type": "vitamin", "name": "Iron", "excess": "hypervitaminosis", "deficiency": "anemia", @@ -22,6 +24,7 @@ { "id": "vitA", "type": "vitamin", + "vit_type": "vitamin", "name": "Vitamin A", "excess": "hypervitaminosis", "deficiency": "hypovitA", @@ -33,6 +36,7 @@ { "id": "vitB", "type": "vitamin", + "vit_type": "vitamin", "name": "Vitamin B12", "deficiency": "hypovitB", "min": -5600, @@ -42,6 +46,7 @@ { "id": "vitC", "type": "vitamin", + "vit_type": "vitamin", "name": "Vitamin C", "deficiency": "scurvy", "min": -5600, @@ -51,6 +56,7 @@ { "id": "mutant_toxin", "type": "vitamin", + "vit_type": "toxin", "name": "Toxins", "excess": "toxin_buildup", "min": 0, @@ -61,6 +67,7 @@ { "id": "bad_food", "type": "vitamin", + "vit_type": "counter", "name": "Disgusting Diet", "excess": "bad_food_ennui", "min": 0, diff --git a/src/consumption.cpp b/src/consumption.cpp index 47e90619f2c05..8790d1c3da315 100644 --- a/src/consumption.cpp +++ b/src/consumption.cpp @@ -374,7 +374,7 @@ void player::vitamins_mod( const std::map &vitamins, bool cappe int Character::vitamin_get( const vitamin_id &vit ) const { - if( get_option( "NO_VITAMINS" ) ) { + if( get_option( "NO_VITAMINS" ) && vit->type() == vitamin_type::VITAMIN ) { return 0; } diff --git a/src/item_factory.cpp b/src/item_factory.cpp index 1e1bb80649f28..ee4945c339bcb 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -309,7 +309,11 @@ void Item_factory::finalize_pre( itype &obj ) if( obj.comestible ) { if( get_option( "NO_VITAMINS" ) ) { - obj.comestible->vitamins.clear(); + for( auto &vit : obj.comestible->vitamins ) { + if( vit.first->type() == vitamin_type::VITAMIN ) { + vit.second = 0; + } + } } else if( obj.comestible->vitamins.empty() && obj.comestible->healthy >= 0 ) { // Default vitamins of healthy comestibles to their edible base materials if none explicitly specified. auto healthy = std::max( obj.comestible->healthy, 1 ) * 10; diff --git a/src/vitamin.cpp b/src/vitamin.cpp index 2959ff66f4cfa..5f2f49ab337f4 100644 --- a/src/vitamin.cpp +++ b/src/vitamin.cpp @@ -61,6 +61,11 @@ void vitamin::load_vitamin( JsonObject &jo ) vit.max_ = jo.get_int( "max", 0 ); vit.rate_ = read_from_json_string( *jo.get_raw( "rate" ), time_duration::units ); + if( !jo.has_string( "vit_type" ) ) { + jo.throw_error( "vitamin must have a vitamin type", "vit_type" ); + } + vit.type_ = jo.get_enum_value( "vit_type" ); + if( vit.rate_ < 0_turns ) { jo.throw_error( "vitamin consumption rate cannot be negative", "rate" ); } @@ -102,3 +107,25 @@ void vitamin::reset() { vitamins_all.clear(); } + +namespace io +{ +template<> +std::string enum_to_string( vitamin_type data ) +{ + switch( data ) { + case vitamin_type::VITAMIN: + return "vitamin"; + case vitamin_type::TOXIN: + return "toxin"; + case vitamin_type::DRUG: + return "drug"; + case vitamin_type::COUNTER: + return "counter"; + case vitamin_type::num_vitamin_types: + break; + } + debugmsg( "Invalid vitamin_type" ); + abort(); +} +} // namespace io diff --git a/src/vitamin.h b/src/vitamin.h index 81e5019216a9d..7493b03bef350 100644 --- a/src/vitamin.h +++ b/src/vitamin.h @@ -14,6 +14,19 @@ class JsonObject; +enum vitamin_type { + VITAMIN, + TOXIN, + DRUG, + COUNTER, + num_vitamin_types +}; + +template<> +struct enum_traits { + static constexpr auto last = vitamin_type::num_vitamin_types; +}; + class vitamin { public: @@ -23,6 +36,10 @@ class vitamin return id_; } + const vitamin_type &type() const { + return type_; + } + bool is_null() const { return id_ == vitamin_id( "null" ); } @@ -76,6 +93,7 @@ class vitamin private: vitamin_id id_; + vitamin_type type_; translation name_; efftype_id deficiency_; efftype_id excess_; From d1d895b73c52e57a5ecb96c789afefac79b43016 Mon Sep 17 00:00:00 2001 From: KorGgenT Date: Fri, 6 Dec 2019 16:43:10 -0500 Subject: [PATCH 03/16] change holiday to christmas --- src/main_menu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main_menu.cpp b/src/main_menu.cpp index 624037a57fcbb..72aa67f3d0334 100644 --- a/src/main_menu.cpp +++ b/src/main_menu.cpp @@ -42,7 +42,7 @@ #define dbg(x) DebugLog((DebugLevel)(x),D_GAME) << __FILE__ << ":" << __LINE__ << ": " -static const holiday current_holiday = holiday::thanksgiving; +static const holiday current_holiday = holiday::christmas; void main_menu::on_move() const { From cd4fe380fbb74b0b3e937f2e9629d6d78c7d13fa Mon Sep 17 00:00:00 2001 From: Maleclypse <54345792+Maleclypse@users.noreply.github.com> Date: Fri, 6 Dec 2019 17:10:55 -0500 Subject: [PATCH 04/16] Afs Mi-go turrets fix (#35897) * AFS turret fix * Update afs_bioparts.json * Update afs_deconstruction.json * Update afs_robots.json --- data/mods/Aftershock/items/afs_bioparts.json | 19 ++++++++++++++++++- data/mods/Aftershock/mobs/afs_robots.json | 2 +- .../recipes/afs_deconstruction.json | 4 ++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/data/mods/Aftershock/items/afs_bioparts.json b/data/mods/Aftershock/items/afs_bioparts.json index b23e873406192..eb43c4a03da3b 100644 --- a/data/mods/Aftershock/items/afs_bioparts.json +++ b/data/mods/Aftershock/items/afs_bioparts.json @@ -41,7 +41,7 @@ "name_plural": "sensory clusters", "description": "This lump of flesh has various lobes protruding from it that at intervals will emit toned sounds. Perhaps it works via echolocation. Like all mi-go bioparts the openings on this piece closed up after it was cut free and it seems to have gone into a form of hibernation with the pulses occurring slower and slower as it conserves energy.", "weight": "40 g", - "volume": "250 mL", + "volume": "250 ml", "price": 100, "to_hit": -1, "bashing": 1, @@ -67,6 +67,23 @@ "color": "pink", "looks_like": "ruined_chunks" }, + { + "type": "GENERIC", + "id": "broken_afs_mon_migoturret", + "symbol": ",", + "color": "green", + "name": "broken mi-go turret", + "category": "other", + "description": "A broken mi-go turret. It's leaking fluids and smells you can't identify. Could be butchered for parts.", + "price": 1000, + "material": [ "alien_resin", "flesh" ], + "weight": "40750 g", + "volume": "30 L", + "bashing": 6, + "cutting": 6, + "to_hit": -3, + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] + }, { "id": "vibrating_blaster", "looks_like": "ar15", diff --git a/data/mods/Aftershock/mobs/afs_robots.json b/data/mods/Aftershock/mobs/afs_robots.json index 05dd2bb9a4387..42e052301ade5 100644 --- a/data/mods/Aftershock/mobs/afs_robots.json +++ b/data/mods/Aftershock/mobs/afs_robots.json @@ -25,7 +25,7 @@ { "type": "gun", "cooldown": 1, - "gun_type": "laser_cannon", + "gun_type": "vibrating_blaster", "fake_skills": [ [ "gun", 2 ], [ "rifle", 3 ] ], "ranges": [ [ 0, 20, "DEFAULT" ] ] } diff --git a/data/mods/Aftershock/recipes/afs_deconstruction.json b/data/mods/Aftershock/recipes/afs_deconstruction.json index 72145ead92b67..23d3494fe4e61 100644 --- a/data/mods/Aftershock/recipes/afs_deconstruction.json +++ b/data/mods/Aftershock/recipes/afs_deconstruction.json @@ -1,6 +1,6 @@ [ { - "result": "broken_migoturret", + "result": "broken_afs_mon_migoturret", "type": "uncraft", "skill_used": "survival", "difficulty": 5, @@ -9,7 +9,7 @@ "qualities": [ { "id": "SCREW", "level": 1 } ], "components": [ [ [ "living_brain_jar", 1 ] ], - [ [ "brains", 4 ] ], + [ [ "brain", 4 ] ], [ [ "mutant_meat", 12 ] ], [ [ "vibrating_blaster", 1 ] ], [ [ "humming_heart", 1 ] ], From da8679251d0589be025531ea0306354d1d5c37e6 Mon Sep 17 00:00:00 2001 From: Anton Burmistrov Date: Sat, 7 Dec 2019 02:13:59 +0400 Subject: [PATCH 05/16] Fixed tools activating for one turn even without charges (#35896) * Fixed tools activation even without charges * Fixed some more tools --- data/json/items/melee/swords_and_blades.json | 14 ++++++++++---- data/json/items/tool/radio_tools.json | 2 ++ data/json/items/tool_armor.json | 1 + data/json/items/tools.json | 5 +++++ 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/data/json/items/melee/swords_and_blades.json b/data/json/items/melee/swords_and_blades.json index ea24d1bd9d857..2d2c932dc99a6 100644 --- a/data/json/items/melee/swords_and_blades.json +++ b/data/json/items/melee/swords_and_blades.json @@ -298,6 +298,7 @@ "symbol": "/", "color": "dark_gray", "ammo": "gasoline", + "charges_per_use": 1, "max_charges": 50, "techniques": "WBLOCK_2", "use_action": { @@ -866,6 +867,7 @@ "symbol": "/", "color": "light_gray", "ammo": "gasoline", + "charges_per_use": 1, "max_charges": 50, "techniques": [ "WBLOCK_1", "WIDE", "BRUTAL", "SWEEP" ], "use_action": { @@ -1307,6 +1309,7 @@ "symbol": "/", "color": "light_gray", "ammo": "gasoline", + "charges_per_use": 1, "max_charges": 50, "techniques": "WBLOCK_2", "use_action": { @@ -1474,6 +1477,7 @@ "symbol": "/", "color": "light_gray", "ammo": "gasoline", + "charges_per_use": 1, "max_charges": 50, "techniques": [ "RAPID", "WBLOCK_2" ], "use_action": { @@ -1713,8 +1717,7 @@ "color": "red", "ammo": "gasoline", "max_charges": 800, - "turns_per_charge": 1, - "revert_to": "chainsaw_off", + "charges_per_use": 5, "techniques": [ "WBLOCK_1", "SPIN", "SWEEP" ], "use_action": "CS_LAJATANG_OFF", "flags": [ "NONCONDUCTIVE", "ALWAYS_TWOHAND" ] @@ -1730,6 +1733,7 @@ "cutting": 140, "revert_to": "cs_lajatang_off", "use_action": "CS_LAJATANG_ON", + "turns_per_charge": 1, "qualities": [ [ "AXE", 3 ], [ "BUTCHER", -250 ] ], "flags": [ "MESSY", "HURT_WHEN_PULLED", "DURABLE_MELEE", "TRADER_AVOID", "NONCONDUCTIVE", "ALWAYS_TWOHAND" ] }, @@ -1748,8 +1752,7 @@ "symbol": "/", "color": "red", "ammo": "battery", - "power_draw": 4000000, - "revert_to": "elec_chainsaw_off", + "charges_per_use": 5, "techniques": [ "WBLOCK_1", "SPIN", "SWEEP" ], "use_action": "ECS_LAJATANG_OFF", "flags": [ "NONCONDUCTIVE", "ALWAYS_TWOHAND" ], @@ -1767,6 +1770,7 @@ "description": "A long wooden pole with electric chainsaws impractically attached to both ends. They are currently on and draining power; use this item to turn them off.", "bashing": 4, "cutting": 140, + "power_draw": 4000000, "revert_to": "ecs_lajatang_off", "use_action": "ECS_LAJATANG_ON", "flags": [ "MESSY", "HURT_WHEN_PULLED", "DURABLE_MELEE", "TRADER_AVOID", "NONCONDUCTIVE", "ALWAYS_TWOHAND" ], @@ -1826,6 +1830,7 @@ "symbol": "/", "color": "light_gray", "ammo": "gasoline", + "charges_per_use": 5, "max_charges": 450, "use_action": "COMBATSAW_OFF", "techniques": [ "WBLOCK_1", "SWEEP" ], @@ -1862,6 +1867,7 @@ "symbol": "/", "color": "light_gray", "ammo": "battery", + "charges_per_use": 5, "use_action": "E_COMBATSAW_OFF", "techniques": [ "WBLOCK_1", "SWEEP" ], "flags": [ "ALWAYS_TWOHAND" ], diff --git a/data/json/items/tool/radio_tools.json b/data/json/items/tool/radio_tools.json index 1be2239ee5a21..45b25db2074e7 100644 --- a/data/json/items/tool/radio_tools.json +++ b/data/json/items/tool/radio_tools.json @@ -97,6 +97,7 @@ "symbol": ";", "color": "light_gray", "ammo": "battery", + "charges_per_use": 1, "use_action": "RADIO_OFF", "magazines": [ [ @@ -140,6 +141,7 @@ "symbol": ";", "color": "green", "ammo": "battery", + "charges_per_use": 1, "flags": [ "TWO_WAY_RADIO" ], "magazines": [ [ diff --git a/data/json/items/tool_armor.json b/data/json/items/tool_armor.json index fac1c90c64df9..c34ec91f32f5e 100644 --- a/data/json/items/tool_armor.json +++ b/data/json/items/tool_armor.json @@ -648,6 +648,7 @@ "volume": "9 L", "to_hit": -3, "max_charges": 5000, + "charges_per_use": 5, "ammo": "plutonium", "use_action": "RM13ARMOR_OFF", "covers": [ "HEAD", "MOUTH", "EYES", "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], diff --git a/data/json/items/tools.json b/data/json/items/tools.json index 0cd4d632839ba..4c9d760118ff5 100644 --- a/data/json/items/tools.json +++ b/data/json/items/tools.json @@ -931,6 +931,7 @@ "symbol": "/", "color": "yellow", "ammo": "battery", + "charges_per_use": 5, "use_action": "CARVER_OFF", "flags": [ "SHEATH_SWORD", "NONCONDUCTIVE" ], "magazines": [ @@ -1098,6 +1099,7 @@ "symbol": "/", "color": "red", "ammo": "gasoline", + "charges_per_use": 5, "max_charges": 450, "techniques": "SWEEP", "use_action": "CHAINSAW_OFF", @@ -2072,6 +2074,7 @@ "symbol": "/", "color": "red", "ammo": "battery", + "charges_per_use": 5, "techniques": "SWEEP", "use_action": "ELEC_CHAINSAW_OFF", "flags": [ "NONCONDUCTIVE" ], @@ -5309,6 +5312,7 @@ "symbol": "/", "color": "light_gray", "ammo": "gasoline", + "charges_per_use": 1, "max_charges": 50, "use_action": { "type": "fireweapon_off", @@ -6494,6 +6498,7 @@ "color": "green", "ammo": "gasoline", "max_charges": 600, + "charges_per_use": 5, "use_action": "TRIMMER_OFF", "flags": [ "NONCONDUCTIVE" ] }, From 45147cdcb4fc12c907be5cc18e429c91326b057a Mon Sep 17 00:00:00 2001 From: ZhilkinSerg Date: Sat, 7 Dec 2019 01:15:17 +0300 Subject: [PATCH 06/16] Appease clang (2019-12-06) (#35891) --- src/overmap_ui.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/overmap_ui.cpp b/src/overmap_ui.cpp index 803b65f738687..a293bb01cd995 100644 --- a/src/overmap_ui.cpp +++ b/src/overmap_ui.cpp @@ -1093,9 +1093,8 @@ static bool search( tripoint &curs, const tripoint &orig, const bool show_explor std::string term = string_input_popup() .title( _( "Search term:" ) ) - // NOLINTNEXTLINE(cata-text-style): literal comma .description( string_format( - _( "Multiple entries separated with , Excludes starting with -\n" + _( "Multiple entries separated with comma (,). Excludes starting with hyphen (-)\n" "Current search radius is %d. It can be changed in options." ), radius ) ) .query_string(); From 92c284c399cd25a102b162993c66621c5c7b6ca9 Mon Sep 17 00:00:00 2001 From: I-am-Erk <45136638+I-am-Erk@users.noreply.github.com> Date: Fri, 6 Dec 2019 14:16:55 -0800 Subject: [PATCH 07/16] Further updates evac shelters, adding vandalized and used variants. (#35872) * Add mi-go atmosphere effect * Major evac center update * fix errors caught in play test * minor tweaks * further tweak spawn chances * Adjustments to shelter, add vandalized version to first shelter, change location of basement so stairs align * add bad food vitamin * Update effects.json * Add (currently nonfunctional) bad_food "vitamin" to bars Will cause a buildup of negative morale if these are all you eat. For now it's just a warning I guess, until morale effects json is implemented. * Update protein.json * more vandalism * last vandalism * move terminal into chunks so it can be broken * Create shelter_nested.json * Create graffiti.json * Update graffiti.json * Update shelter.json * expand graffiti options * more shelter graffiti * Update shelter.json * Add 'used' variant to shelters * Add "used" SUS for shelters * adjust used locker SUS appearance rate should be the same as general locker appearance rate * adjust appearance rate of variants, make used the most common * more shelter graffiti --- data/json/effects.json | 13 + .../SUS_specific_use_storage_items.json | 133 ++++- data/json/items/comestibles/protein.json | 4 +- data/json/mapgen/nested/shelter_nested.json | 456 ++++++++++++++++++ data/json/mapgen/shelter.json | 164 ++++--- data/json/mapgen_palettes/shelter.json | 6 +- data/json/snippets/graffiti.json | 116 +++++ data/json/vitamin.json | 10 + 8 files changed, 809 insertions(+), 93 deletions(-) create mode 100644 data/json/mapgen/nested/shelter_nested.json create mode 100644 data/json/snippets/graffiti.json diff --git a/data/json/effects.json b/data/json/effects.json index 94e2e7235239e..d4ee92de7dfd6 100644 --- a/data/json/effects.json +++ b/data/json/effects.json @@ -1600,6 +1600,19 @@ "max_intensity": 3, "scaling_mods": { "h_mod_min": [ -5 ] } }, + { + "type": "effect_type", + "id": "bad_food_ennui", + "name": [ "Gross food", "Demoralizing food", "Depressing food" ], + "desc": [ + "The food you eat is disgusting.", + "Eating nothing but disgusting rations is starting to get you down.", + "Sure, you survived, but what kind of survival is this, eating these disgusting rations day in and day out?" + ], + "max_intensity": 3, + "//": "No morale_mod is currently possible in effects, for some reason. As soon as it's implemented, it goes here.", + "rating": "bad" + }, { "type": "effect_type", "id": "cough_suppress" diff --git a/data/json/itemgroups/SUS_specific_use_storage_items.json b/data/json/itemgroups/SUS_specific_use_storage_items.json index 1bedb02635cd9..615eb4f23b702 100644 --- a/data/json/itemgroups/SUS_specific_use_storage_items.json +++ b/data/json/itemgroups/SUS_specific_use_storage_items.json @@ -9,13 +9,52 @@ [ "evac_pamphlet", 99 ], [ "jacket_evac", 75 ], [ "emer_blanket", 75 ], - [ "mask_gas", 5 ], + [ "mask_gas", 2 ], [ "flashlight", 50 ], + [ "light_disposable_cell", 10 ], [ "lighter", 20 ], - { "item": "water_clean", "count": 2, "prob": 80 }, - { "item": "protein_bar_evac", "count": 3 }, + { "item": "water_clean", "count": [ 1, 2 ], "prob": 80 }, + { "item": "protein_bar_evac", "count": [ 2, 3 ] }, { - "collection": [ { "item": "plastic_spoon" }, { "item": "plastic_knife" }, { "item": "plastic_fork" }, { "item": "bowl_plastic" } ], + "collection": [ + { "item": "plastic_spoon", "prob": 90 }, + { "item": "plastic_knife", "prob": 90 }, + { "item": "plastic_fork", "prob": 90 }, + { "item": "bowl_plastic", "prob": 90 } + ], + "prob": 90 + } + ] + }, + { + "id": "SUS_evac_shelter_locker_used", + "type": "item_group", + "//": "SUS item groups are collections that contain a reasonable realistic distribution of items that might spawn in a given storage furniture.", + "//2": "This locker has been picked through by an evacuee already. Not everyone wants the jacket, plenty leave the blanket or the gas mask, but the useful stuff is usually gone. Some people left junk behind.", + "subtype": "collection", + "items": [ + [ "evac_pamphlet", 95 ], + [ "jacket_evac", 15 ], + [ "emer_blanket", 45 ], + [ "mask_gas", 1 ], + [ "flashlight", 10 ], + [ "wrapper", 50 ], + [ "survnote", 5 ], + [ "plastic_shopping_bag", 5 ], + [ "box_small", 5 ], + [ "bag_plastic", 5 ], + [ "bowl_plastic", 5 ], + [ "can_food_unsealed", 5 ], + [ "can_opener", 3 ], + { "item": "bottle_plastic", "count": [ 1, 2 ], "prob": 50 }, + { "item": "protein_bar_evac", "count": [ 2, 3 ], "prob": 70 }, + { + "collection": [ + { "item": "plastic_spoon", "prob": 70 }, + { "item": "plastic_knife", "prob": 70 }, + { "item": "plastic_fork", "prob": 70 }, + { "item": "bowl_plastic", "prob": 50 } + ], "prob": 90 } ] @@ -30,15 +69,18 @@ { "distribution": [ { - "collection": [ { "item": "emer_blanket", "count": 5, "prob": 80 }, { "item": "jacket_evac", "count": 5, "prob": 80 } ], + "collection": [ + { "item": "emer_blanket", "count": [ 5, 10 ], "prob": 80 }, + { "item": "jacket_evac", "count": [ 5, 10 ], "prob": 80 } + ], "prob": 30 }, - { "item": "water_clean", "count": 12, "prob": 20 }, - { "item": "protein_bar_evac", "count": 24, "prob": 60 }, + { "item": "water_clean", "count": [ 6, 12 ], "prob": 20 }, + { "item": "protein_bar_evac", "count": [ 20, 24 ], "prob": 60 }, { "collection": [ { "item": "extinguisher", "prob": 70 }, - { "item": "1st_aid", "count": [ 1, 3 ], "prob": 85 }, + { "item": "1st_aid", "count": [ 1, 3 ], "prob": 65 }, { "item": "two_way_radio", "prob": 65 }, { "item": "light_disposable_cell", "count": [ 2, 4 ], "prob": 65 }, { "item": "electric_lantern", "prob": 35 } @@ -47,18 +89,81 @@ }, { "collection": [ - { "item": "detergent", "count": [ 1, 2 ] }, + { "item": "detergent", "count": [ 0, 2 ] }, + { "item": "brush", "prob": 85 }, + { "item": "bleach", "prob": 45 }, + { "item": "ammonia", "prob": 15 } + ], + "prob": 15 + }, + { + "collection": [ + { "item": "can_beans", "count": [ 8, 12 ], "prob": 50 }, + { "item": "can_tomato", "count": [ 8, 12 ], "prob": 40 }, + { "item": "soup_chicken", "count": [ 8, 12 ], "prob": 20 }, + { "item": "can_opener", "prob": 90 } + ], + "prob": 5 + } + ] + }, + [ "evac_pamphlet", 15 ] + ] + }, + { + "id": "SUS_evac_shelter_cabinet_used", + "type": "item_group", + "//": "SUS item groups are collections that contain a reasonable realistic distribution of items that might spawn in a given storage furniture.", + "//2": "These cabinets have been picked over by a previous flood of evacuees, but plenty of good stuff could still be left.", + "subtype": "collection", + "items": [ + { + "distribution": [ + { + "collection": [ + { "item": "emer_blanket", "count": [ 1, 10 ], "prob": 60 }, + { "item": "jacket_evac", "count": [ 1, 10 ], "prob": 50 } + ], + "prob": 30 + }, + { + "collection": [ + { "item": "water_clean", "count": [ 1, 6 ], "prob": 60 }, + { "item": "bottle_plastic", "count": [ 1, 6 ], "prob": 90 } + ], + "prob": 50 + }, + { "item": "protein_bar_evac", "count": [ 1, 23 ], "prob": 60 }, + { + "collection": [ + { "item": "extinguisher", "prob": 50 }, + { "item": "1st_aid", "prob": 5 }, + { "item": "two_way_radio", "prob": 25 }, + { "item": "electric_lantern", "prob": 5 } + ], + "prob": 10 + }, + { + "collection": [ + { "item": "detergent", "count": [ 0, 2 ] }, { "item": "brush", "prob": 85 }, - { "item": "bleach", "prob": 65 }, - { "item": "ammonia", "prob": 35 } + { "item": "bleach", "charges-min": 1, "prob": 45 }, + { "item": "box_small", "prob": 5 }, + { "item": "bag_plastic", "prob": 5 }, + { "item": "bowl_plastic", "prob": 5 }, + { "item": "ammonia", "charges-min": 1, "prob": 15 } ], "prob": 15 }, { "collection": [ - { "item": "can_beans", "count": 12, "prob": 50 }, - { "item": "can_tomato", "count": 12, "prob": 40 }, - { "item": "soup_chicken", "count": 12, "prob": 20 }, + { "item": "can_beans", "count": [ 1, 2 ], "prob": 10 }, + { "item": "can_tomato", "count": [ 1, 2 ], "prob": 5 }, + { "item": "soup_chicken", "count": [ 1, 2 ], "prob": 2 }, + { "item": "box_small", "prob": 5 }, + { "item": "bag_plastic", "prob": 5 }, + { "item": "bowl_plastic", "prob": 5 }, + { "item": "can_food_unsealed", "count": [ 1, 30 ], "prob": 90 }, { "item": "can_opener", "prob": 90 } ], "prob": 5 diff --git a/data/json/items/comestibles/protein.json b/data/json/items/comestibles/protein.json index bebe718077864..eb2798cad8308 100644 --- a/data/json/items/comestibles/protein.json +++ b/data/json/items/comestibles/protein.json @@ -77,7 +77,7 @@ "id": "protein_bar_evac", "type": "COMESTIBLE", "comestible_type": "FOOD", - "name": { "str": "emergency protein ration", "str_pl": "emergency protein rations" }, + "name": { "str": "protein ration" }, "//": "Inspired by, but not based on, a true story", "description": "SoyPelusa ran a highly successful crowdfunding campaign for this protein bar. A person can live on one of these bars, three times a day, presumably forever. After backers received their product, a single flaw was found: most consumers found starvation preferable to the flavor. Warehouses of the product went unsold as the company went bankrupt, providing the perfect opportunity for FEMA to scoop them up and stock the evac shelters. Now, you hold a piece of famous crowdfunding history in your hands. How exciting.", "weight": "150 g", @@ -92,7 +92,7 @@ "color": "green", "container": "wrapper", "calories": 400, - "vitamins": [ [ "calcium", 30 ], [ "iron", 30 ], [ "vitA", 30 ], [ "vitB", 30 ], [ "vitC", 30 ] ] + "vitamins": [ [ "calcium", 30 ], [ "iron", 30 ], [ "vitA", 30 ], [ "vitB", 30 ], [ "vitC", 30 ], [ "bad_food", 5 ] ] }, { "id": "protein_shake", diff --git a/data/json/mapgen/nested/shelter_nested.json b/data/json/mapgen/nested/shelter_nested.json new file mode 100644 index 0000000000000..528a9a1157c9e --- /dev/null +++ b/data/json/mapgen/nested/shelter_nested.json @@ -0,0 +1,456 @@ +[ + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "shelter_nest_base", + "object": { + "mapgensize": [ 24, 24 ], + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " llll c 6 ", + " b b b c ", + " b b b c ", + " b b b c ", + " b b b ", + " ", + " ", + " ", + " ", + " b b b ", + " b b b c ", + " b b b c ", + " b b c ", + " c 6 ", + " " + ], + "terrain": { " ": "t_null" }, + "furniture": { "b": "f_bench", "c": "f_cupboard", "l": "f_locker", "S": "f_sink", "%": "f_trashcan" }, + "computers": { + "6": { + "name": "Evac shelter computer", + "options": [ + { "name": "Emergency Message", "action": "emerg_mess" }, + { "name": "Disable External Power", "action": "complete_disable_external_power" }, + { "name": "Contact Us", "action": "emerg_ref_center" } + ] + } + }, + "items": { "l": { "item": "SUS_evac_shelter_locker", "chance": 75 }, "c": { "item": "SUS_evac_shelter_cabinet", "chance": 50 } } + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "shelter_nest_used", + "object": { + "mapgensize": [ 24, 24 ], + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " |||||:|++|:||||| ", + " |llll......c..6| ", + " |.b.b.b....c...| ", + " |.b.b.b....c...| ", + " |.b.b.b....c...| ", + " :.b.b.b........: ", + " |..............| ", + " |..............| ", + " |..............| ", + " |..............| ", + " :.b.b.b........: ", + " |.b.b.b....c...| ", + " |.b.b.b....c...| ", + " |||.b.b....c...| ", + " | =........c..x| ", + " |||||:||+|:||||| " + ], + "terrain": { "x": "t_console_broken" }, + "furniture": { "b": "f_bench", "c": "f_cupboard", "l": "f_locker", "S": "f_sink", "%": "f_trashcan" }, + "computers": { + "6": { + "name": "Evac shelter computer", + "options": [ + { "name": "Emergency Message", "action": "emerg_mess" }, + { "name": "Disable External Power", "action": "complete_disable_external_power" }, + { "name": "Contact Us", "action": "emerg_ref_center" } + ] + } + }, + "items": { + "l": { "item": "SUS_evac_shelter_locker_used", "chance": 75 }, + "c": { "item": "SUS_evac_shelter_cabinet_used", "chance": 50 }, + "b": [ { "item": "shelter_supplies", "chance": 2 }, { "item": "trash", "chance": 2 } ], + ".": [ + { "item": "shelter_supplies", "chance": 1 }, + { "item": "trash", "chance": 1 }, + { "item": "trash_forest", "chance": 1 } + ] + }, + "nested": { "|": { "chunks": [ [ "shelter_graffiti", 10 ], [ "null", 90 ] ] } } + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "shelter_nest_vandalized", + "object": { + "mapgensize": [ 24, 24 ], + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " |||||:|++|:||||| ", + " |llll......c..6| ", + " |.b.b.b....c...| ", + " |.b.b.b....c...| ", + " |.b.b.b....c...| ", + " :.b.b.b........: ", + " |..............| ", + " |..............| ", + " |..............| ", + " |..............| ", + " :.b.b.b........: ", + " |.b.b.b....c...| ", + " |.b.b.b....c...| ", + " |||.b.b....c...| ", + " | =........c..6| ", + " |||||:||+|:||||| " + ], + "terrain": { + ":": [ "t_window_frame", "t_window" ], + "+": [ "t_door_c", "t_door_b" ], + "=": [ "t_door_b", "t_door_locked_interior", "t_door_c", "t_door_o" ], + "6": "t_console_broken" + }, + "furniture": { "b": "f_bench", "c": "f_cupboard", "l": [ [ "f_locker", 2 ], "f_wreckage" ], "S": "f_sink", "%": "f_trashcan" }, + "items": { + "l": { "item": "shelter_supplies", "chance": 40 }, + "c": [ { "item": "trash", "chance": 1 }, { "item": "softdrugs", "chance": 2 }, { "item": "shelter_supplies", "chance": 10 } ], + "b": [ { "item": "softdrugs", "chance": 2 }, { "item": "shelter_supplies", "chance": 1 }, { "item": "trash", "chance": 1 } ], + ".": [ { "item": "trash", "chance": 1 }, { "item": "trash_forest", "chance": 1 } ] + }, + "nested": { "|": { "chunks": [ [ "shelter_graffiti", 5 ], [ "general_graffiti", 20 ], [ "null", 75 ] ] } } + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "shelter_1_nest_base", + "object": { + "mapgensize": [ 24, 24 ], + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " bbbbb c 6 ", + " c ", + " bbbbb c ", + " cc ", + " bbbbb ", + " l ", + " l ", + " l ", + " b b b c ", + " b b b c l ", + " b b b c l ", + " l ", + " " + ], + "terrain": { " ": "t_null" }, + "furniture": { "b": "f_bench", "c": "f_cupboard", "l": "f_locker", "S": "f_sink", "%": "f_trashcan" }, + "items": { "l": { "item": "SUS_evac_shelter_locker", "chance": 70 }, "c": { "item": "SUS_evac_shelter_cabinet", "chance": 50 } }, + "computers": { + "6": { + "name": "Evac shelter computer", + "options": [ + { "name": "Emergency Message", "action": "emerg_mess" }, + { "name": "Disable External Power", "action": "complete_disable_external_power" }, + { "name": "Contact Us", "action": "emerg_ref_center" } + ] + } + } + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "shelter_1_nest_used", + "object": { + "mapgensize": [ 24, 24 ], + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ||||++|||| ", + " |........| ", + " ||:|........| ", + " |...........|:|| ", + " |.bbbbb.....c.6| ", + " |...........c..| ", + " :.bbbbb.....c..: ", + " |...........cc.| ", + " |.bbbbb........| ", + " |.......l|||...| ", + " |.-----.l| =...| ", + " :.......l|||...: ", + " |.b.b.b...c|-+-| ", + " |.b.b.b...c|..l| ", + " |.b.b.b...c|..l| ", + " |..........|..l| ", + " |||||:||+|:||||| " + ], + "terrain": { "x": "t_console_broken" }, + "furniture": { "b": "f_bench", "c": "f_cupboard", "l": "f_locker", "S": "f_sink", "%": "f_trashcan" }, + "computers": { + "6": { + "name": "Evac shelter computer", + "options": [ + { "name": "Emergency Message", "action": "emerg_mess" }, + { "name": "Disable External Power", "action": "complete_disable_external_power" }, + { "name": "Contact Us", "action": "emerg_ref_center" } + ] + } + }, + "items": { + "l": { "item": "SUS_evac_shelter_locker_used", "chance": 70 }, + "c": { "item": "SUS_evac_shelter_cabinet_used", "chance": 50 }, + "b": [ { "item": "shelter_supplies", "chance": 2 }, { "item": "trash", "chance": 2 } ], + ".": [ { "item": "shelter_supplies", "chance": 1 }, { "item": "trash", "chance": 1 } ] + }, + "nested": { "|": { "chunks": [ [ "shelter_graffiti", 10 ], [ "null", 90 ] ] } } + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "shelter_1_nest_vandalized", + "object": { + "mapgensize": [ 24, 24 ], + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ||||++|||| ", + " |........| ", + " ||:|........| ", + " |...........|:|| ", + " |.bbbbb.....c.6| ", + " |...........c..| ", + " :.bbbbb.....c..: ", + " |...........cc.| ", + " |.bbbbb........| ", + " |.......l|||...| ", + " |.-----.l| =...| ", + " :.......l|||...: ", + " |.b.b.b...c|-+-| ", + " |.b.b.b...c|..l| ", + " |.b.b.b...c|..l| ", + " |..........|..l| ", + " |||||:||+|:||||| " + ], + "terrain": { + ":": [ "t_window_frame", "t_window" ], + "+": [ "t_door_c", "t_door_b" ], + "=": [ "t_door_b", "t_door_locked_interior", "t_door_c", "t_door_o" ], + "6": "t_console_broken" + }, + "furniture": { "b": "f_bench", "c": "f_cupboard", "l": [ [ "f_locker", 2 ], "f_wreckage" ], "S": "f_sink", "%": "f_trashcan" }, + "items": { + "l": { "item": "shelter_supplies", "chance": 40 }, + "c": [ { "item": "trash", "chance": 1 }, { "item": "softdrugs", "chance": 2 }, { "item": "shelter_supplies", "chance": 10 } ], + "b": [ { "item": "softdrugs", "chance": 2 }, { "item": "shelter_supplies", "chance": 1 }, { "item": "trash", "chance": 1 } ], + ".": [ { "item": "trash", "chance": 1 }, { "item": "trash_forest", "chance": 1 } ] + }, + "nested": { "|": { "chunks": [ [ "shelter_graffiti", 5 ], [ "general_graffiti", 20 ], [ "null", 75 ] ] } } + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "shelter_2_nest_base", + "object": { + "mapgensize": [ 24, 24 ], + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " % l ", + " cccc6 l ", + " l ", + " ", + " b bbbbb b b ", + " b b b b ", + " b b llll b b ", + " b b b b ", + " b b b b ", + " b b b b ", + " b b b b ", + " b b llll b b ", + " b b b b ", + " bbbb ", + " 6 ", + " c ", + " " + ], + "terrain": { " ": "t_null" }, + "furniture": { "b": "f_bench", "c": "f_cupboard", "l": "f_locker", "S": "f_sink", "%": "f_trashcan" }, + "items": { "l": { "item": "SUS_evac_shelter_locker", "chance": 70 }, "c": { "item": "SUS_evac_shelter_cabinet", "chance": 50 } } + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "shelter_2_nest_used", + "object": { + "mapgensize": [ 24, 24 ], + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ||:|++|:|| ", + " |||||||||%......l| ", + " |*|cccc6........l| ", + " |.=.............l| ", + " |--|.............||| ", + " |b.....bbbbb...b..b| ", + " :b..b..........b..b: ", + " |b..b...llll...b..b| ", + " |b..b...|--|...b..b| ", + " |b..b..........b..b| ", + " |b..b..........b..b| ", + " :b..b...|--|...b..b: ", + " |b..b...llll...b..b| ", + " |b..b..........b..b| ", + " |--.....bbbb.....||| ", + " |l..............x| ", + " ||||||||||......c| ", + " ||:|+|:|| " + ], + "terrain": { "x": "t_console_broken" }, + "furniture": { "b": "f_bench", "c": "f_cupboard", "l": "f_locker", "S": "f_sink", "%": "f_trashcan" }, + "computers": { + "6": { + "name": "Evac shelter computer", + "options": [ + { "name": "Emergency Message", "action": "emerg_mess" }, + { "name": "Disable External Power", "action": "complete_disable_external_power" }, + { "name": "Contact Us", "action": "emerg_ref_center" } + ] + } + }, + "items": { + "l": { "item": "SUS_evac_shelter_locker_used", "chance": 70 }, + "c": { "item": "SUS_evac_shelter_cabinet_used", "chance": 50 }, + "%": [ + { "item": "shelter_supplies", "chance": 15, "repeat": [ 1, 2 ] }, + { "item": "trash", "chance": 25, "repeat": [ 1, 3 ] } + ], + "b": [ { "item": "shelter_supplies", "chance": 2 }, { "item": "trash", "chance": 2 } ], + ".": [ { "item": "shelter_supplies", "chance": 1 }, { "item": "trash", "chance": 1 } ] + }, + "nested": { "|": { "chunks": [ [ "shelter_graffiti", 10 ], [ "null", 90 ] ] } } + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "shelter_2_nest_vandalized", + "object": { + "mapgensize": [ 24, 24 ], + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ||:|++|:|| ", + " |||||||||%......l| ", + " |*|cccc6........l| ", + " |.=.............l| ", + " |--|.............||| ", + " |b.....bbbbb...b..b| ", + " :b..b..........b..b: ", + " |b..b...llll...b..b| ", + " |b..b...|--|...b..b| ", + " |b..b..........b..b| ", + " |b..b..........b..b| ", + " :b..b...|--|...b..b: ", + " |b..b..........b..b| ", + " |b..b..........b..b| ", + " |--.....bbbb.....||| ", + " |l..............x| ", + " ||||||||||......c| ", + " ||:|+|:|| " + ], + "terrain": { + ":": [ "t_window_frame", "t_window" ], + "+": [ "t_door_c", "t_door_b" ], + "=": [ "t_door_b", "t_door_locked_interior", "t_door_c", "t_door_o" ], + "6": [ "t_console", "t_console_broken" ] + }, + "furniture": { "b": "f_bench", "c": "f_cupboard", "l": [ [ "f_locker", 2 ], "f_wreckage" ], "S": "f_sink", "%": "f_trashcan" }, + "items": { + "l": { "item": "shelter_supplies", "chance": 40 }, + "c": [ { "item": "trash", "chance": 1 }, { "item": "softdrugs", "chance": 2 }, { "item": "shelter_supplies", "chance": 10 } ], + "b": [ { "item": "softdrugs", "chance": 2 }, { "item": "shelter_supplies", "chance": 1 }, { "item": "trash", "chance": 1 } ], + ".": [ { "item": "trash", "chance": 1 }, { "item": "trash_forest", "chance": 1 } ] + }, + "nested": { "|": { "chunks": [ [ "shelter_graffiti", 5 ], [ "general_graffiti", 20 ], [ "null", 75 ] ] } } + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "shelter_graffiti", + "object": { "mapgensize": [ 1, 1 ], "place_graffiti": [ { "x": 0, "y": 0, "snippet": "shelter_graffiti_snippets" } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "general_graffiti", + "object": { "mapgensize": [ 1, 1 ], "place_graffiti": [ { "x": 0, "y": 0, "snippet": "general_graffiti_snippets" } ] } + } +] diff --git a/data/json/mapgen/shelter.json b/data/json/mapgen/shelter.json index 907e696968a78..08c04be62d0d2 100644 --- a/data/json/mapgen/shelter.json +++ b/data/json/mapgen/shelter.json @@ -3,8 +3,20 @@ "id": "shelter_supplies", "type": "item_group", "subtype": "collection", - "//": "obsolete item group, use SUS instead", - "items": [ [ "jacket_evac", 100 ], [ "emer_blanket", 100 ], [ "mask_gas", 12 ] ] + "//": "now used for shelters that have been looted by kids, see SUS groups for general shelter supplies", + "items": [ + [ "jacket_evac", 10 ], + [ "emer_blanket", 40 ], + [ "wrapper", 90 ], + [ "glass_shard", 80 ], + [ "bottle_plastic", 30 ], + [ "plastic_knife", 20 ], + [ "plastic_spoon", 20 ], + [ "plastic_fork", 20 ], + [ "bowl_plastic", 10 ], + [ "evac_pamphlet", 80 ], + { "item": "protein_bar_evac", "count": [ 0, 3 ] } + ] }, { "type": "mapgen", @@ -23,33 +35,30 @@ " `!!!!`!!!!`!!!!` ", " &&&&&&&&&&&&&&&& ", " |----:-++-:----| ", - " |llll......c..6| ", - " |.b.b.b....c...| ", - " |.b.b.b....c...| ", - " |.b.b.b....c...| ", - " :.b.b.b........: ", + " |.............6| ", + " |..............| ", + " |..............| ", + " |..............| ", + " :..............: ", " |..............| ", " |......>>......| ", " |......>>......| ", " |..............| ", - " :.b.b.b........: ", - " |.b.b.b....c...| ", - " |.b.b.b....c...| ", - " |||.b.b....c...| ", - " |*=........c..x| ", + " :..............: ", + " |..............| ", + " |..............| ", + " |||............| ", + " |*=...........6| ", " |----:--+-:----|4 " ], "palettes": [ "shelter" ], - "computers": { - "6": { - "name": "Evac shelter computer", - "options": [ - { "name": "Emergency Message", "action": "emerg_mess" }, - { "name": "Disable External Power", "action": "complete_disable_external_power" }, - { "name": "Contact Us", "action": "emerg_ref_center" } - ] + "place_nested": [ + { + "chunks": [ [ "shelter_nest_base", 25 ], [ "shelter_nest_used", 45 ], [ "shelter_nest_vandalized", 30 ] ], + "x": 0, + "y": 0 } - } + ] } }, { @@ -118,31 +127,28 @@ " |........| ", " |-:|........| ", " |...........|:-| ", - " |.bbbbb.....c.6| ", - " |...........c..| ", - " :.bbbbb.....c..: ", - " |...........cc.| ", - " |.bbbbb........| ", + " |.............6| ", + " |..............| ", + " :..............: ", + " |..............| ", + " |..............| ", " |........|||...| ", " |.-----..|*=...| ", " :........|||...: ", - " |.b.b.b...c|-+-| ", - " |.b.b.b...c|..l| ", - " |.b.b.b...c|>.l| ", - " |..........|>.l|4 ", + " |..........|-+-| ", + " |..........|...| ", + " |..........|>..| ", + " |..........|>..|4 ", " |----:--+-:----| " ], "palettes": [ "shelter" ], - "computers": { - "6": { - "name": "Evac shelter computer", - "options": [ - { "name": "Emergency Message", "action": "emerg_mess" }, - { "name": "Disable External Power", "action": "complete_disable_external_power" }, - { "name": "Contact Us", "action": "emerg_ref_center" } - ] + "place_nested": [ + { + "chunks": [ [ "shelter_1_nest_base", 25 ], [ "shelter_1_nest_used", 45 ], [ "shelter_1_nest_vandalized", 30 ] ], + "x": 0, + "y": 0 } - } + ] } }, { @@ -207,25 +213,32 @@ " `!!!!`!!!!`!!!!` ", " &&&&&&&&&&&&&&&& ", " |-:-++-:-| ", - " ||------|%......l| ", - " |*|cccc6........l| ", - " |.=.............l| ", + " ||------|........| ", + " |*|..............| ", + " |.=..............| ", " |--|.............--| ", - " |b......bbbb......b| ", - " :b................b: ", - " |b......llll......b| ", - " |c......|--|......c| ", - " |c.......>>.......c| ", - " |b.......>>.......b| ", - " :b......|--|......b: ", - " |b......llll......b| ", - " |--..............-- ", - " |c.....bbbb.....c| ", - " |cccx........cccc|4 ", - " |---|l......l|---| ", - " |-:--+-:-| " + " |..................| ", + " :..................: ", + " |..................| ", + " |.......|--|.......| ", + " |........>>........| ", + " |........>>........| ", + " :.......|--|.......: ", + " |..................| ", + " |..................| ", + " |--..............--| ", + " |................|4 ", + " |--------|.......| ", + " |-:-+-:-| " ], "palettes": [ "shelter" ], + "place_nested": [ + { + "chunks": [ [ "shelter_2_nest_base", 25 ], [ "shelter_2_nest_used", 45 ], [ "shelter_2_nest_vandalized", 30 ] ], + "x": 0, + "y": 0 + } + ], "computers": { "6": { "name": "Evac shelter computer", @@ -265,11 +278,11 @@ " |..................3 ", " |..................3 ", " |.....&............3 ", + " |..................3 ", " ||................33 ", - " |................3 ", " |................5 ", - " |---|........|---3 ", - " |--------| " + " |--------|.......3 ", + " |-------3 " ], "terrain": { ".": "t_flat_roof", @@ -293,6 +306,10 @@ "object": { "fill_ter": "t_linoleum_white", "rows": [ + "########################", + "########################", + "########################", + "########################", "########################", "########################", "########################", @@ -301,25 +318,21 @@ "####;bbbbbbbbbbbbbb;####", "####;b____________b;####", "####;----_________b;####", - "####;T|T||lllll___b;####", + "####;T|T||bbbbb___b;####", "####;____|----|___b;####", "####;S%S_+____|___b;####", "####;----|_<<_+___b;####", "####;S%S_|_<<_+___b;####", "####;____+____|___b;####", "####;T|T||----|___b;####", - "####;---|llllll___b;####", + "####;---|%bbbbb___b;####", "####;b____________b;####", "####;b____________b;####", "####;bbbbbbbbbbbbbb;####", - "####;;;;;;;;;;;;;;;;####", - "########################", - "########################", - "########################", - "########################" + "####;;;;;;;;;;;;;;;;####" ], "palettes": [ "shelter" ], - "items": { "_": { "item": "shelter", "chance": 1 } } + "items": { "_": { "item": "shelter_supplies", "chance": 1 } } } }, { @@ -330,6 +343,10 @@ "object": { "fill_ter": "t_linoleum_white", "rows": [ + "########################", + "########################", + "########################", + "########################", "########################", "########################", "########################", @@ -338,25 +355,24 @@ "####;bbbbbbbbbbbbbb;####", "####;b____________b;####", "####;----_________b;####", - "####;T|T||lllll___b;####", + "####;T|T||bbbbb___b;####", "####;____|----|___b;####", "####;S%S_+____|___b;####", "####;----|_<<_+___b;####", "####;S%S_|_<<_+___b;####", "####;____+____|___b;####", "####;T|T||----|___b;####", - "####;---|llllll___b;####", + "####;---|%bbbbb___b;####", "####;b____________b;####", "####;b____________b;####", "####;bbbbbbbbbbbbbb;####", - "####;;;;;;;;;;;;;;;;####", - "########################", - "########################", - "########################", - "########################" + "####;;;;;;;;;;;;;;;;####" ], "palettes": [ "shelter" ], - "items": { "_": { "item": "shelter", "chance": 10 } }, + "items": { + "_": [ { "item": "trash", "chance": 1 }, { "item": "shelter_supplies", "chance": 7 } ], + "b": { "item": "shelter", "chance": 4 } + }, "monsters": { "_": { "monster": "GROUP_ZOMBIE", "chance": 40 }, "b": { "monster": "GROUP_ZOMBIE", "chance": 10 } } } } diff --git a/data/json/mapgen_palettes/shelter.json b/data/json/mapgen_palettes/shelter.json index 15eac21c69a91..f3bb04936e2eb 100644 --- a/data/json/mapgen_palettes/shelter.json +++ b/data/json/mapgen_palettes/shelter.json @@ -22,11 +22,11 @@ "=": "t_door_locked_interior", "4": "t_gutter_downspout" }, - "furniture": { "b": "f_bench", "c": "f_counter", "l": "f_locker", "S": "f_sink", "%": "f_trashcan" }, + "furniture": { "b": "f_bench", "c": "f_cupboard", "l": "f_locker", "S": "f_sink", "%": "f_trashcan" }, "toilets": { "T": { } }, "items": { - "l": { "item": "SUS_evac_shelter_locker", "chance": 90 }, - "c": { "item": "SUS_evac_shelter_cabinet", "chance": 70 }, + "l": { "item": "SUS_evac_shelter_locker", "chance": 80 }, + "c": { "item": "SUS_evac_shelter_cabinet", "chance": 60 }, "S": { "item": "SUS_evac_shelter_sink", "chance": 70 } } } diff --git a/data/json/snippets/graffiti.json b/data/json/snippets/graffiti.json new file mode 100644 index 0000000000000..806c57f564ec9 --- /dev/null +++ b/data/json/snippets/graffiti.json @@ -0,0 +1,116 @@ +[ + { + "type": "snippet", + "category": "general_graffiti_snippets", + "//": "This graffiti is generally assumed to come from before the cataclysm", + "text": [ + { "id": "general_graffiti_1", "text": " is the biggest slut in , and I'm damn proud of it!" }, + { "id": "general_graffiti_2", "text": "There is a beautifully drawn graffiti tag on the wall here." }, + { "id": "general_graffiti_3", "text": " is a heteronormative bully!" }, + { "id": "general_graffiti_4", "text": " + " }, + { "id": "general_graffiti_5", "text": "Hell in " }, + { "id": "general_graffiti_6", "text": "were all gonna die" }, + { "id": "general_graffiti_7", "text": "MOM" }, + { "id": "general_graffiti_8", "text": "FUCK YOU" }, + { "id": "general_graffiti_9", "text": "This is a cartoon rendition of a zombie." }, + { "id": "general_graffiti_10", "text": "This is a crudely spraypainted tag adorned with skulls." }, + { + "id": "general_graffiti_11", + "text": "I have a secure and loving relationship with your mom and you're going to need to come to terms with that.\n\nDo you want to talk about it? You know where to find me. Love you sweety." + }, + { "id": "general_graffiti_12", "text": " you fuckin gave me ADES you SHIT." }, + { "id": "general_graffiti_13", "text": "I <3 ." }, + { "id": "general_graffiti_14", "text": " fucked ." }, + { "id": "general_graffiti_15", "text": "This is a spraypainted drawing of an angel with wings made of vines." }, + { "id": "general_graffiti_16", "text": "Mr. is a vampire!" }, + { "id": "general_graffiti_17", "text": "Their hiding the truth" }, + { "id": "general_graffiti_18", "text": "FOLLOW THE CHEMTRAILS" }, + { + "id": "general_graffiti_19", + "text": "This is a curious drawing of a roll of toilet paper dissolving into a rainbow." + }, + { "id": "general_graffiti_20", "text": "All we wanna do is eat yer brains" }, + { "id": "general_graffiti_21", "text": "" }, + { "id": "general_graffiti_22", "text": "don't drink the water" }, + { + "id": "general_graffiti_23", + "text": "And they walked upon His Earth, and there was a RECKONING, and only the worthy survived" + }, + { "id": "general_graffiti_24", "text": "This is a drawing of a zombie with a bullethole in its head." }, + { "id": "general_graffiti_25", "text": "This is a surprisingly artistic drawing of a penis." }, + { "id": "general_graffiti_26", "text": "This is a simple spraypainted graphic of a forest made of bones." }, + { + "id": "general_graffiti_27", + "text": "This is a spraypainted mural of a giant mushroom with people praying at its base." + }, + { "id": "general_graffiti_28", "text": "we can never go back" }, + { "id": "general_graffiti_29", "text": "dont by meth from " }, + { "id": "general_graffiti_30", "text": " you owe me fifty bucks" }, + { "id": "general_graffiti_31", "text": "Im gonna kill u " }, + { "id": "general_graffiti_32", "text": "its in the water" }, + { + "id": "general_graffiti_33", + "text": "This is a spraypainting of an anatomically unlikely woman wearing very little." + } + ] + }, + { + "type": "snippet", + "category": "shelter_graffiti_snippets", + "text": [ + { "id": "shelter_graffiti_1", "text": "BIGGEST WASTE OF TAX MONEY FUCK YOU GOVERMINT" }, + { "id": "shelter_graffiti_2", "text": "Dont eat the proten bars" }, + { "id": "shelter_graffiti_3", "text": "FEMA: FUCKIN EAT MY ASSHOLE" }, + { + "id": "shelter_graffiti_4", + "text": "This is a simple drawing of a skinny figure wearing an emergency evac jacket and a gas mask. Scrawled beneath, it says \"thanks for the outfit\"." + }, + { "id": "shelter_graffiti_5", "text": "Abandon hope, all ye who enter here." }, + { "id": "shelter_graffiti_6", "text": "NO ONE IS COMING FOR US" }, + { "id": "shelter_graffiti_7", "text": "THERE'S NO RESCUE BUS" }, + { "id": "shelter_graffiti_8", "text": "THEY LET US DOWN" }, + { "id": "shelter_graffiti_9", "text": "Don't dead open inside" }, + { "id": "shelter_graffiti_10", "text": "SANCTUARY" }, + { "id": "shelter_graffiti_11", "text": "'s cosplay supply all welcome" }, + { "id": "shelter_graffiti_12", "text": "Cataclysm Bus Stop" }, + { "id": "shelter_graffiti_13", "text": "They aren't coming to help, they're coming to clean up" }, + { + "id": "shelter_graffiti_14", + "text": "This is a far-too-detailed drawing of an enormous mind-bending monster, the sort that attacked during the Cataclysm." + }, + { + "id": "shelter_graffiti_15", + "text": "This is a quick rendition in permanent marker of a swirling gateway, with zombies spilling out of it. Underneath, it reads \"What did they do?\"" + }, + { "id": "shelter_graffiti_16", "text": "RIP humanity" }, + { "id": "shelter_graffiti_17", "text": "Everyone's dead Dave" }, + { "id": "shelter_graffiti_18", "text": "WE'RE ALL FINE HERE HOW R U" }, + { + "id": "shelter_graffiti_19", + "text": " I couldn't wait any longer, went to camp 36. Meet me there. Love ." + }, + { "id": "shelter_graffiti_20", "text": " I am still looking for you." }, + { "id": "shelter_graffiti_21", "text": " was here and still alive" }, + { "id": "shelter_graffiti_22", "text": "Blue 52" }, + { "id": "shelter_graffiti_23", "text": " I no I said Id wait for u but I gotta run, find me" }, + { + "id": "shelter_graffiti_24", + "text": "In memoriam:\n\n\n\n\n\nI would not be alive without all of you. I will not forget." + }, + { + "id": "shelter_graffiti_25", + "text": "This is a drawing of a cartoon character smashing a zombie corpse with a sledgehammer. Beneath it is a scrawled message: \"Gotta pulp em all\"" + }, + { "id": "shelter_graffiti_26", "text": "They get back up. Headshots don't work." }, + { "id": "shelter_graffiti_27", "text": "stay out of " }, + { "id": "shelter_graffiti_28", "text": " has fallen" }, + { "id": "shelter_graffiti_29", "text": "NO ONE LEFT HERE MOVE ON" }, + { "id": "shelter_graffiti_30", "text": "deth trap" }, + { "id": "shelter_graffiti_31", "text": "no ones coming" }, + { "id": "shelter_graffiti_32", "text": "GOVERMENT DID THIS TO US" }, + { "id": "shelter_graffiti_33", "text": "FUCK CHINA" }, + { "id": "shelter_graffiti_34", "text": "FUCK THE COMMUNISTS" }, + { "id": "shelter_graffiti_35", "text": "Remember " } + ] + } +] diff --git a/data/json/vitamin.json b/data/json/vitamin.json index 1dddbdbc9a61b..7afb21569abb0 100644 --- a/data/json/vitamin.json +++ b/data/json/vitamin.json @@ -57,5 +57,15 @@ "max": 1800, "rate": "15 m", "disease_excess": [ [ 500, 949 ], [ 950, 1399 ], [ 1400, 1800 ] ] + }, + { + "id": "bad_food", + "type": "vitamin", + "name": "Disgusting Diet", + "excess": "bad_food_ennui", + "min": 0, + "max": 40, + "rate": "4 h", + "disease_excess": [ [ 10, 19 ], [ 20, 29 ], [ 30, 40 ] ] } ] From f04c6d58150fd07576e0a900bb7364f12449b158 Mon Sep 17 00:00:00 2001 From: BevapDin Date: Fri, 6 Dec 2019 23:17:47 +0100 Subject: [PATCH 08/16] Implement iterators for JsonArray: (#35852) * Rename JsonArray::end member to avoid conflict later * Make some member functions of JsonArray const. * Use size_t instead of int as index value in JsonArray * Implement iterators for JsonArray: This allows to iterate over a `JsonArray` with a range-based for loop. Changes some code to use the form of iterating. This now also works with unnamed `JsonArray` instances, e.g. `for( ... : foo.get_array( ... ) )`. * Fix test errors from unvisited JSON object members. Functions take a copy of the JSON object, so the members in the original object are never visited and that is reported as error. * Fix variable name collision in *some* compilers. Yes, I'm looking at you GCC 5.3.1. --- src/json.cpp | 62 +++++++------ src/json.h | 156 ++++++++++++++++++++++++-------- src/magic.cpp | 8 +- src/magic_teleporter_list.cpp | 5 +- src/magic_ter_fur_transform.cpp | 26 ++---- src/mapdata.cpp | 8 +- src/mapgen.cpp | 35 +++---- src/martialarts.cpp | 4 +- src/material.cpp | 27 ++---- src/mattack_actors.cpp | 16 +--- src/mission_util.cpp | 4 +- src/mod_manager.cpp | 5 +- src/mongroup.cpp | 10 +- src/monstergenerator.cpp | 10 +- src/mutation_data.cpp | 90 ++++++------------ src/npc.cpp | 5 +- src/npc_class.cpp | 12 +-- src/npctalk.cpp | 46 ++++------ src/overlay_ordering.cpp | 4 +- src/overmap.cpp | 10 +- src/panels.cpp | 12 +-- src/profession.cpp | 16 +--- src/recipe.cpp | 41 ++------- src/recipe_groups.cpp | 8 +- src/regional_settings.cpp | 29 ++---- src/relic.cpp | 8 +- src/requirements.cpp | 10 +- src/savegame.cpp | 20 ++-- src/savegame_json.cpp | 58 +++--------- src/sdlsound.cpp | 17 +--- src/tutorial.cpp | 5 +- src/veh_type.cpp | 30 ++---- src/vehicle_group.cpp | 21 +---- src/vitamin.cpp | 8 +- src/worldfactory.cpp | 4 +- 35 files changed, 334 insertions(+), 496 deletions(-) diff --git a/src/json.cpp b/src/json.cpp index 49c9ea7391dbf..b670243e59fca 100644 --- a/src/json.cpp +++ b/src/json.cpp @@ -411,7 +411,7 @@ JsonArray::JsonArray( JsonIn &j ) positions.push_back( jsin->tell() ); jsin->skip_value(); } - end = jsin->tell(); + end_ = jsin->tell(); final_separator = jsin->get_ate_separator(); } @@ -421,7 +421,7 @@ JsonArray::JsonArray( const JsonArray &ja ) start = ja.start; index = 0; positions = ja.positions; - end = ja.end; + end_ = ja.end_; final_separator = ja.final_separator; } @@ -431,7 +431,7 @@ JsonArray &JsonArray::operator=( const JsonArray &ja ) start = ja.start; index = 0; positions = ja.positions; - end = ja.end; + end_ = ja.end_; final_separator = ja.final_separator; return *this; @@ -440,14 +440,14 @@ JsonArray &JsonArray::operator=( const JsonArray &ja ) void JsonArray::finish() { if( jsin && jsin->good() ) { - jsin->seek( end ); + jsin->seek( end_ ); jsin->set_ate_separator( final_separator ); } } -bool JsonArray::has_more() +bool JsonArray::has_more() const { - return ( index >= 0 && size_t( index ) < positions.size() ); + return index < positions.size(); } size_t JsonArray::size() const { @@ -461,17 +461,17 @@ bool JsonArray::empty() std::string JsonArray::str() { if( jsin ) { - return jsin->substr( start, end - start ); + return jsin->substr( start, end_ - start ); } else { return "[]"; } } -void JsonArray::verify_index( int i ) +void JsonArray::verify_index( const size_t i ) const { if( !jsin ) { throw JsonError( "tried to access empty array." ); - } else if( i < 0 || size_t( i ) >= positions.size() ) { + } else if( i >= positions.size() ) { jsin->seek( start ); std::stringstream err; err << "bad index value: " << i; @@ -531,42 +531,42 @@ void JsonArray::skip_value() /* static access */ -bool JsonArray::get_bool( int i ) +bool JsonArray::get_bool( const size_t i ) const { verify_index( i ); jsin->seek( positions[i] ); return jsin->get_bool(); } -int JsonArray::get_int( int i ) +int JsonArray::get_int( const size_t i ) const { verify_index( i ); jsin->seek( positions[i] ); return jsin->get_int(); } -double JsonArray::get_float( int i ) +double JsonArray::get_float( const size_t i ) const { verify_index( i ); jsin->seek( positions[i] ); return jsin->get_float(); } -std::string JsonArray::get_string( int i ) +std::string JsonArray::get_string( const size_t i ) const { verify_index( i ); jsin->seek( positions[i] ); return jsin->get_string(); } -JsonArray JsonArray::get_array( int i ) +JsonArray JsonArray::get_array( const size_t i ) const { verify_index( i ); jsin->seek( positions[i] ); return jsin->get_array(); } -JsonObject JsonArray::get_object( int i ) +JsonObject JsonArray::get_object( const size_t i ) const { verify_index( i ); jsin->seek( positions[i] ); @@ -575,7 +575,7 @@ JsonObject JsonArray::get_object( int i ) /* iterative type checking */ -bool JsonArray::test_null() +bool JsonArray::test_null() const { if( !has_more() ) { return false; @@ -584,7 +584,7 @@ bool JsonArray::test_null() return jsin->test_null(); } -bool JsonArray::test_bool() +bool JsonArray::test_bool() const { if( !has_more() ) { return false; @@ -593,7 +593,7 @@ bool JsonArray::test_bool() return jsin->test_bool(); } -bool JsonArray::test_number() +bool JsonArray::test_number() const { if( !has_more() ) { return false; @@ -602,7 +602,7 @@ bool JsonArray::test_number() return jsin->test_number(); } -bool JsonArray::test_string() +bool JsonArray::test_string() const { if( !has_more() ) { return false; @@ -611,7 +611,7 @@ bool JsonArray::test_string() return jsin->test_string(); } -bool JsonArray::test_bitset() +bool JsonArray::test_bitset() const { if( !has_more() ) { return false; @@ -620,7 +620,7 @@ bool JsonArray::test_bitset() return jsin->test_bitset(); } -bool JsonArray::test_array() +bool JsonArray::test_array() const { if( !has_more() ) { return false; @@ -629,7 +629,7 @@ bool JsonArray::test_array() return jsin->test_array(); } -bool JsonArray::test_object() +bool JsonArray::test_object() const { if( !has_more() ) { return false; @@ -640,42 +640,42 @@ bool JsonArray::test_object() /* random-access type checking */ -bool JsonArray::has_null( int i ) +bool JsonArray::has_null( const size_t i ) const { verify_index( i ); jsin->seek( positions[i] ); return jsin->test_null(); } -bool JsonArray::has_bool( int i ) +bool JsonArray::has_bool( const size_t i ) const { verify_index( i ); jsin->seek( positions[i] ); return jsin->test_bool(); } -bool JsonArray::has_number( int i ) +bool JsonArray::has_number( const size_t i ) const { verify_index( i ); jsin->seek( positions[i] ); return jsin->test_number(); } -bool JsonArray::has_string( int i ) +bool JsonArray::has_string( const size_t i ) const { verify_index( i ); jsin->seek( positions[i] ); return jsin->test_string(); } -bool JsonArray::has_array( int i ) +bool JsonArray::has_array( const size_t i ) const { verify_index( i ); jsin->seek( positions[i] ); return jsin->test_array(); } -bool JsonArray::has_object( int i ) +bool JsonArray::has_object( const size_t i ) const { verify_index( i ); jsin->seek( positions[i] ); @@ -1793,3 +1793,9 @@ std::ostream &operator<<( std::ostream &stream, const JsonError &err ) // instantiate them here, or move the templated read/write functions into the header. template void JsonOut::write<12>( const std::bitset<12> & ); template bool JsonIn::read<12>( std::bitset<12> &, bool throw_on_error ); + +JsonIn &JsonArrayValueRef::seek() const +{ + jsin_.seek( pos_ ); + return jsin_; +} diff --git a/src/json.h b/src/json.h index 6f5c5e0b8e1a4..7c3628d8607f7 100644 --- a/src/json.h +++ b/src/json.h @@ -888,6 +888,8 @@ class JsonObject std::string line_number(); // for occasional use only }; +class JsonArrayValueRef; + /* JsonArray * ========= * @@ -961,18 +963,20 @@ class JsonObject class JsonArray { private: - std::vector positions; + friend JsonArrayValueRef; + + std::vector positions; int start; - int index; - int end; + size_t index; + int end_; bool final_separator; JsonIn *jsin; - void verify_index( int i ); + void verify_index( size_t i ) const; public: JsonArray( JsonIn &jsin ); JsonArray( const JsonArray &ja ); - JsonArray() : start( 0 ), index( 0 ), end( 0 ), jsin( nullptr ) {} + JsonArray() : start( 0 ), index( 0 ), end_( 0 ), jsin( nullptr ) {} ~JsonArray() { finish(); } @@ -980,7 +984,7 @@ class JsonArray void finish(); // move the stream position to the end of the array - bool has_more(); // true iff more elements may be retrieved with next_* + bool has_more() const; // true iff more elements may be retrieved with next_* size_t size() const; bool empty(); std::string str(); // copy array json as string @@ -997,45 +1001,50 @@ class JsonArray void skip_value(); // ignore whatever is next // static access - bool get_bool( int index ); - int get_int( int index ); - double get_float( int index ); - std::string get_string( int index ); - JsonArray get_array( int index ); - JsonObject get_object( int index ); + bool get_bool( size_t index ) const; + int get_int( size_t index ) const; + double get_float( size_t index ) const; + std::string get_string( size_t index ) const; + JsonArray get_array( size_t index ) const; + JsonObject get_object( size_t index ) const; // get_tags returns empty set if none found template - std::set get_tags( int index ); + std::set get_tags( size_t index ) const; + + class const_iterator; + + const_iterator begin() const; + const_iterator end() const; // iterative type checking - bool test_null(); - bool test_bool(); - bool test_number(); - bool test_int() { + bool test_null() const; + bool test_bool() const; + bool test_number() const; + bool test_int() const { return test_number(); } - bool test_float() { + bool test_float() const { return test_number(); } - bool test_string(); - bool test_bitset(); - bool test_array(); - bool test_object(); + bool test_string() const; + bool test_bitset() const; + bool test_array() const; + bool test_object() const; // random-access type checking - bool has_null( int index ); - bool has_bool( int index ); - bool has_number( int index ); - bool has_int( int index ) { + bool has_null( size_t index ) const; + bool has_bool( size_t index ) const; + bool has_number( size_t index ) const; + bool has_int( size_t index ) const { return has_number( index ); } - bool has_float( int index ) { + bool has_float( size_t index ) const { return has_number( index ); } - bool has_string( int index ); - bool has_array( int index ); - bool has_object( int index ); + bool has_string( size_t index ) const; + bool has_array( size_t index ) const; + bool has_object( size_t index ) const; // iteratively read values by reference template bool read_next( T &t ) { @@ -1044,15 +1053,88 @@ class JsonArray return jsin->read( t ); } // random-access read values by reference - template bool read( int i, T &t ) { + template bool read( size_t i, T &t ) const { verify_index( i ); jsin->seek( positions[i] ); return jsin->read( t ); } }; +class JsonArrayValueRef +{ + private: + friend JsonArray::const_iterator; + + JsonIn &jsin_; + int pos_; + + JsonArrayValueRef( JsonIn &jsin, int pos ) : jsin_( jsin ), pos_( pos ) { } + + JsonIn &seek() const; + + public: + operator std::string() const { + return seek().get_string(); + } + operator int() const { + return seek().get_int(); + } + operator bool() const { + return seek().get_bool(); + } + operator double() const { + return seek().get_float(); + } + operator JsonObject() const { + return seek().get_object(); + } + operator JsonArray() const { + return seek().get_array(); + } + template + bool read( T &t ) const { + return seek().read( t ); + } +}; + +class JsonArray::const_iterator +{ + private: + JsonArray array_; + size_t index_; + + public: + const_iterator( const JsonArray &array, size_t index ) : array_( array ), index_( index ) { } + + const_iterator &operator++() { + index_++; + return *this; + } + JsonArrayValueRef operator*() const { + array_.verify_index( index_ ); + return JsonArrayValueRef( *array_.jsin, array_.positions[index_] ); + } + + friend bool operator==( const const_iterator &lhs, const const_iterator &rhs ) { + return lhs.index_ == rhs.index_; + } + friend bool operator!=( const const_iterator &lhs, const const_iterator &rhs ) { + return !operator==( lhs, rhs ); + } +}; + +inline JsonArray::const_iterator JsonArray::begin() const +{ + return const_iterator( *this, 0 ); +} + +inline JsonArray::const_iterator JsonArray::end() const +{ + return const_iterator( *this, size() ); +} + template -std::set JsonArray::get_tags( int index ) +std::set JsonArray::get_tags( const size_t index ) const { std::set res; @@ -1065,9 +1147,8 @@ std::set JsonArray::get_tags( int index ) return res; } - JsonArray jsarr = jsin->get_array(); - while( jsarr.has_more() ) { - res.insert( T( jsarr.next_string() ) ); + for( const std::string &line : jsin->get_array() ) { + res.insert( T( line ) ); } return res; @@ -1091,9 +1172,8 @@ std::set JsonObject::get_tags( const std::string &name ) } // otherwise assume it's an array and error if it isn't. - JsonArray jsarr = jsin->get_array(); - while( jsarr.has_more() ) { - res.insert( T( jsarr.next_string() ) ); + for( const std::string &line : jsin->get_array() ) { + res.insert( T( line ) ); } return res; diff --git a/src/magic.cpp b/src/magic.cpp index ed5c62ea99b72..8ce1f21d434c4 100644 --- a/src/magic.cpp +++ b/src/magic.cpp @@ -251,10 +251,8 @@ void spell_type::load( JsonObject &jo, const std::string & ) mandatory( jo, was_loaded, "valid_targets", valid_targets, trigger_reader ); if( jo.has_array( "extra_effects" ) ) { - JsonArray jarray = jo.get_array( "extra_effects" ); - while( jarray.has_more() ) { + for( JsonObject fake_spell_obj : jo.get_array( "extra_effects" ) ) { fake_spell temp; - JsonObject fake_spell_obj = jarray.next_object(); temp.load( fake_spell_obj ); additional_spells.emplace_back( temp ); } @@ -1178,9 +1176,7 @@ void known_magic::deserialize( JsonIn &jsin ) JsonObject data = jsin.get_object(); data.read( "mana", mana ); - JsonArray parray = data.get_array( "spellbook" ); - while( parray.has_more() ) { - JsonObject jo = parray.next_object(); + for( JsonObject jo : data.get_array( "spellbook" ) ) { std::string id = jo.get_string( "id" ); spell_id sp = spell_id( id ); int xp = jo.get_int( "xp" ); diff --git a/src/magic_teleporter_list.cpp b/src/magic_teleporter_list.cpp index bb751ab455f9a..b93f72c870cf2 100644 --- a/src/magic_teleporter_list.cpp +++ b/src/magic_teleporter_list.cpp @@ -141,10 +141,7 @@ void teleporter_list::deserialize( JsonIn &jsin ) { JsonObject data = jsin.get_object(); - JsonArray parray = data.get_array( "known_teleporters" ); - while( parray.has_more() ) { - JsonObject jo = parray.next_object(); - + for( JsonObject jo : data.get_array( "known_teleporters" ) ) { tripoint temp_pos; jo.read( "position", temp_pos ); std::string name; diff --git a/src/magic_ter_fur_transform.cpp b/src/magic_ter_fur_transform.cpp index e44bff623b9c7..61a17941750c4 100644 --- a/src/magic_ter_fur_transform.cpp +++ b/src/magic_ter_fur_transform.cpp @@ -82,44 +82,30 @@ void ter_furn_transform::load( JsonObject &jo, const std::string & ) optional( jo, was_loaded, "fail_message", fail_message, "" ); if( jo.has_member( "terrain" ) ) { - JsonArray obj_array = jo.get_array( "terrain" ); - while( obj_array.has_more() ) { - JsonObject ter_obj = obj_array.next_object(); - JsonArray target_array = ter_obj.get_array( "valid_terrain" ); + for( JsonObject ter_obj : jo.get_array( "terrain" ) ) { ter_furn_data cur_results = ter_furn_data(); cur_results.load( ter_obj ); - while( target_array.has_more() ) { - const std::string valid_terrain = target_array.next_string(); + for( const std::string &valid_terrain : ter_obj.get_array( "valid_terrain" ) ) { ter_transform.emplace( ter_str_id( valid_terrain ), cur_results ); } - target_array = ter_obj.get_array( "valid_flags" ); - - while( target_array.has_more() ) { - const std::string valid_terrain = target_array.next_string(); + for( const std::string &valid_terrain : ter_obj.get_array( "valid_flags" ) ) { ter_flag_transform.emplace( valid_terrain, cur_results ); } } } if( jo.has_member( "furniture" ) ) { - JsonArray obj_array = jo.get_array( "furniture" ); - while( obj_array.has_more() ) { - JsonObject furn_obj = obj_array.next_object(); - JsonArray target_array = furn_obj.get_array( "valid_furniture" ); + for( JsonObject furn_obj : jo.get_array( "furniture" ) ) { ter_furn_data cur_results = ter_furn_data(); cur_results.load( furn_obj ); - while( target_array.has_more() ) { - const std::string valid_furn = target_array.next_string(); + for( const std::string &valid_furn : furn_obj.get_array( "valid_furniture" ) ) { furn_transform.emplace( furn_str_id( valid_furn ), cur_results ); } - target_array = furn_obj.get_array( "valid_flags" ); - - while( target_array.has_more() ) { - const std::string valid_terrain = target_array.next_string(); + for( const std::string &valid_terrain : furn_obj.get_array( "valid_flags" ) ) { furn_flag_transform.emplace( valid_terrain, cur_results ); } } diff --git a/src/mapdata.cpp b/src/mapdata.cpp index 56167247f4705..30ef6b04b6c16 100644 --- a/src/mapdata.cpp +++ b/src/mapdata.cpp @@ -184,8 +184,8 @@ static const std::unordered_map ter_connects_map = { static void load_map_bash_tent_centers( JsonArray ja, std::vector ¢ers ) { - while( ja.has_more() ) { - centers.emplace_back( ja.next_string() ); + for( const std::string &line : ja ) { + centers.emplace_back( line ); } } @@ -1108,9 +1108,7 @@ void map_data_common_t::load( JsonObject &jo, const std::string &src ) } if( jo.has_array( "harvest_by_season" ) ) { - JsonArray jsarr = jo.get_array( "harvest_by_season" ); - while( jsarr.has_more() ) { - JsonObject harvest_jo = jsarr.next_object(); + for( JsonObject harvest_jo : jo.get_array( "harvest_by_season" ) ) { auto season_strings = harvest_jo.get_tags( "seasons" ); std::set seasons; std::transform( season_strings.begin(), season_strings.end(), std::inserter( seasons, diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 1f109517f03ff..14978b3319cbc 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -411,10 +411,8 @@ void load_mapgen( JsonObject &jo ) JsonArray ja = jo.get_array( "om_terrain" ); if( ja.test_array() ) { point offset; - while( ja.has_more() ) { - JsonArray row_items = ja.next_array(); - while( row_items.has_more() ) { - const std::string mapgenid = row_items.next_string(); + for( JsonArray row_items : ja ) { + for( const std::string &mapgenid : row_items ) { const auto mgfunc = load_mapgen_function( jo, mapgenid, -1, offset ); if( mgfunc ) { oter_mapgen[ mapgenid ].push_back( mgfunc ); @@ -426,8 +424,8 @@ void load_mapgen( JsonObject &jo ) } } else { std::vector mapgenid_list; - while( ja.has_more() ) { - mapgenid_list.push_back( ja.next_string() ); + for( const std::string &line : ja ) { + mapgenid_list.push_back( line ); } if( !mapgenid_list.empty() ) { const std::string mapgenid = mapgenid_list[0]; @@ -771,9 +769,7 @@ class jmapgen_npc : public jmapgen_piece std::string new_trait = jsi.get_string( "add_trait" ); traits.emplace_back( new_trait ); } else if( jsi.has_array( "add_trait" ) ) { - JsonArray ja = jsi.get_array( "add_trait" ); - while( ja.has_more() ) { - std::string new_trait = ja.next_string(); + for( const std::string &new_trait : jsi.get_array( "add_trait" ) ) { traits.emplace_back( new_trait ); } } @@ -1448,16 +1444,12 @@ class jmapgen_computer : public jmapgen_piece security = jsi.get_int( "security", 0 ); target = jsi.get_bool( "target", false ); if( jsi.has_array( "options" ) ) { - JsonArray opts = jsi.get_array( "options" ); - while( opts.has_more() ) { - JsonObject jo = opts.next_object(); + for( JsonObject jo : jsi.get_array( "options" ) ) { options.emplace_back( computer_option::from_json( jo ) ); } } if( jsi.has_array( "failures" ) ) { - JsonArray opts = jsi.get_array( "failures" ); - while( opts.has_more() ) { - JsonObject jo = opts.next_object(); + for( JsonObject jo : jsi.get_array( "failures" ) ) { failures.emplace_back( computer_failure::from_json( jo ) ); } } @@ -1766,9 +1758,7 @@ void jmapgen_objects::add( const jmapgen_place &place, template void jmapgen_objects::load_objects( JsonArray parray ) { - while( parray.has_more() ) { - auto jsi = parray.next_object(); - + for( JsonObject jsi : parray ) { jmapgen_place where( jsi ); where.offset( m_offset ); @@ -1783,8 +1773,7 @@ void jmapgen_objects::load_objects( JsonArray parray ) template<> void jmapgen_objects::load_objects( JsonArray parray ) { - while( parray.has_more() ) { - auto jsi = parray.next_object(); + for( JsonObject jsi : parray ) { jmapgen_place where( jsi ); where.offset( m_offset ); @@ -1840,9 +1829,9 @@ void load_place_mapings( JsonObject &pjo, const std::string &key, if( pjo.has_object( key ) ) { load_place_mapings( pjo.get_object( key ), vect ); } else { - JsonArray jarr = pjo.get_array( key ); - while( jarr.has_more() ) { - load_place_mapings( jarr.next_object(), vect ); + for( JsonObject jo : pjo.get_array( key ) ) { + load_place_mapings( jo, vect ); + jo.allow_omitted_members(); } } } diff --git a/src/martialarts.cpp b/src/martialarts.cpp index 1e73b4050ee27..b3b0b6f609957 100644 --- a/src/martialarts.cpp +++ b/src/martialarts.cpp @@ -217,9 +217,7 @@ void martialart::load( JsonObject &jo, const std::string & ) mandatory( jo, was_loaded, "name", name ); mandatory( jo, was_loaded, "description", description ); mandatory( jo, was_loaded, "initiate", initiate ); - JsonArray jsarr = jo.get_array( "autolearn" ); - while( jsarr.has_more() ) { - JsonArray skillArray = jsarr.next_array(); + for( JsonArray skillArray : jo.get_array( "autolearn" ) ) { std::string skill_name = skillArray.get_string( 0 ); int skill_level = 0; std::string skill_level_string = skillArray.get_string( 1 ); diff --git a/src/material.cpp b/src/material.cpp index a86ee8902f559..5e86bb6d83dbb 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -80,24 +80,19 @@ void material_type::load( JsonObject &jsobj, const std::string & ) optional( jsobj, was_loaded, "soft", _soft, false ); optional( jsobj, was_loaded, "reinforces", _reinforces, false ); - auto arr = jsobj.get_array( "vitamins" ); - while( arr.has_more() ) { - auto pair = arr.next_array(); + for( JsonArray pair : jsobj.get_array( "vitamins" ) ) { _vitamins.emplace( vitamin_id( pair.get_string( 0 ) ), pair.get_float( 1 ) ); } mandatory( jsobj, was_loaded, "bash_dmg_verb", _bash_dmg_verb ); mandatory( jsobj, was_loaded, "cut_dmg_verb", _cut_dmg_verb ); - JsonArray jsarr = jsobj.get_array( "dmg_adj" ); - while( jsarr.has_more() ) { - _dmg_adj.push_back( jsarr.next_string() ); + for( const std::string &line : jsobj.get_array( "dmg_adj" ) ) { + _dmg_adj.push_back( line ); } if( jsobj.has_array( "burn_data" ) ) { - JsonArray burn_data_array = jsobj.get_array( "burn_data" ); - while( burn_data_array.has_more() ) { - JsonObject brn = burn_data_array.next_object(); + for( JsonObject brn : jsobj.get_array( "burn_data" ) ) { _burn_data.emplace_back( load_mat_burn_data( brn ) ); } } else { @@ -109,19 +104,15 @@ void material_type::load( JsonObject &jsobj, const std::string & ) _burn_data.emplace_back( mbd ); } - auto bp_array = jsobj.get_array( "burn_products" ); - while( bp_array.has_more( ) ) { - auto pair = bp_array.next_array(); + for( JsonArray pair : jsobj.get_array( "burn_products" ) ) { _burn_products.emplace_back( pair.get_string( 0 ), static_cast< float >( pair.get_float( 1 ) ) ); } - auto compactor_in_array = jsobj.get_array( "compact_accepts" ); - while( compactor_in_array.has_more( ) ) { - _compact_accepts.emplace_back( compactor_in_array.next_string() ); + for( const std::string &line : jsobj.get_array( "compact_accepts" ) ) { + _compact_accepts.emplace_back( line ); } - auto compactor_out_array = jsobj.get_array( "compacts_into" ); - while( compactor_out_array.has_more( ) ) { - _compacts_into.emplace_back( compactor_out_array.next_string() ); + for( const std::string &line : jsobj.get_array( "compacts_into" ) ) { + _compacts_into.emplace_back( line ); } } diff --git a/src/mattack_actors.cpp b/src/mattack_actors.cpp index e1a7e9da9ff53..e72764b2376d1 100644 --- a/src/mattack_actors.cpp +++ b/src/mattack_actors.cpp @@ -239,9 +239,7 @@ void melee_actor::load_internal( JsonObject &obj, const std::string & ) to_translation( "The %1$s bites 's %2$s!" ) ); if( obj.has_array( "body_parts" ) ) { - JsonArray jarr = obj.get_array( "body_parts" ); - while( jarr.has_more() ) { - JsonArray sub = jarr.next_array(); + for( JsonArray sub : obj.get_array( "body_parts" ) ) { const body_part bp = get_body_part_token( sub.get_string( 0 ) ); const float prob = sub.get_float( 1 ); body_parts.add_or_replace( bp, prob ); @@ -249,9 +247,7 @@ void melee_actor::load_internal( JsonObject &obj, const std::string & ) } if( obj.has_array( "effects" ) ) { - JsonArray jarr = obj.get_array( "effects" ); - while( jarr.has_more() ) { - JsonObject eff = jarr.next_object(); + for( JsonObject eff : obj.get_array( "effects" ) ) { effects.push_back( load_mon_effect_data( eff ) ); } } @@ -390,9 +386,7 @@ void gun_actor::load_internal( JsonObject &obj, const std::string & ) obj.read( "ammo_type", ammo_type ); if( obj.has_array( "fake_skills" ) ) { - JsonArray jarr = obj.get_array( "fake_skills" ); - while( jarr.has_more() ) { - JsonArray cur = jarr.next_array(); + for( JsonArray cur : obj.get_array( "fake_skills" ) ) { fake_skills[skill_id( cur.get_string( 0 ) )] = cur.get_int( 1 ); } } @@ -402,9 +396,7 @@ void gun_actor::load_internal( JsonObject &obj, const std::string & ) obj.read( "fake_int", fake_int ); obj.read( "fake_per", fake_per ); - auto arr = obj.get_array( "ranges" ); - while( arr.has_more() ) { - auto mode = arr.next_array(); + for( JsonArray mode : obj.get_array( "ranges" ) ) { if( mode.size() < 2 || mode.get_int( 0 ) > mode.get_int( 1 ) ) { obj.throw_error( "incomplete or invalid range specified", "ranges" ); } diff --git a/src/mission_util.cpp b/src/mission_util.cpp index 50352a0112c84..6623122fd1f63 100644 --- a/src/mission_util.cpp +++ b/src/mission_util.cpp @@ -486,9 +486,7 @@ bool mission_util::load_funcs( JsonObject &jo, return false; } } else if( jo.has_array( "update_mapgen" ) ) { - JsonArray mapgen_array = jo.get_array( "update_mapgen" ); - while( mapgen_array.has_more() ) { - JsonObject update_mapgen = mapgen_array.next_object(); + for( JsonObject update_mapgen : jo.get_array( "update_mapgen" ) ) { if( !set_update_mapgen( update_mapgen, funcs ) ) { return false; } diff --git a/src/mod_manager.cpp b/src/mod_manager.cpp index 430e21ca31bca..44762ccb019a1 100644 --- a/src/mod_manager.cpp +++ b/src/mod_manager.cpp @@ -404,9 +404,8 @@ void mod_manager::load_mods_list( WORLDPTR world ) const amo.clear(); bool obsolete_mod_found = false; read_from_file_optional_json( get_mods_list_file( world ), [&]( JsonIn & jsin ) { - JsonArray ja = jsin.get_array(); - while( ja.has_more() ) { - const mod_id mod( ja.next_string() ); + for( const std::string &line : jsin.get_array() ) { + const mod_id mod( line ); if( std::find( amo.begin(), amo.end(), mod ) != amo.end() ) { continue; } diff --git a/src/mongroup.cpp b/src/mongroup.cpp index f8057dd2515ac..c7affd6ffe3b2 100644 --- a/src/mongroup.cpp +++ b/src/mongroup.cpp @@ -346,10 +346,7 @@ void MonsterGroupManager::LoadMonsterGroup( JsonObject &jo ) } g.is_animal = jo.get_bool( "is_animal", false ); if( jo.has_array( "monsters" ) ) { - JsonArray monarr = jo.get_array( "monsters" ); - - while( monarr.has_more() ) { - JsonObject mon = monarr.next_object(); + for( JsonObject mon : jo.get_array( "monsters" ) ) { const mtype_id name = mtype_id( mon.get_string( "monster" ) ); int freq = mon.get_int( "freq" ); @@ -373,9 +370,8 @@ void MonsterGroupManager::LoadMonsterGroup( JsonObject &jo ) MonsterGroupEntry new_mon_group = MonsterGroupEntry( name, freq, cost, pack_min, pack_max, starts, ends ); if( mon.has_member( "conditions" ) ) { - JsonArray conditions_arr = mon.get_array( "conditions" ); - while( conditions_arr.has_more() ) { - new_mon_group.conditions.push_back( conditions_arr.next_string() ); + for( const std::string &line : mon.get_array( "conditions" ) ) { + new_mon_group.conditions.push_back( line ); } } diff --git a/src/monstergenerator.cpp b/src/monstergenerator.cpp index 777068fdd9b0f..36fd46844464c 100644 --- a/src/monstergenerator.cpp +++ b/src/monstergenerator.cpp @@ -686,9 +686,8 @@ void mtype::load( JsonObject &jo, const std::string &src ) } if( jo.has_array( "scents_tracked" ) ) { - JsonArray jar = jo.get_array( "scents_tracked" ); - while( jar.has_more() ) { - scents_tracked.emplace( jar.next_string() ); + for( const std::string &line : jo.get_array( "scents_tracked" ) ) { + scents_tracked.emplace( line ); } } @@ -783,9 +782,8 @@ void mtype::load( JsonObject &jo, const std::string &src ) if( jo.has_member( "baby_flags" ) ) { // Because this determines mating season and some monsters have a mating season but not in-game offspring, declare this separately baby_flags.clear(); - JsonArray baby_tags = jo.get_array( "baby_flags" ); - while( baby_tags.has_more() ) { - baby_flags.push_back( baby_tags.next_string() ); + for( const std::string &line : jo.get_array( "baby_flags" ) ) { + baby_flags.push_back( line ); } } diff --git a/src/mutation_data.cpp b/src/mutation_data.cpp index 4df00c15e464c..6d81e4fad3dd5 100644 --- a/src/mutation_data.cpp +++ b/src/mutation_data.cpp @@ -308,22 +308,15 @@ void mutation_branch::load( JsonObject &jo, const std::string & ) optional( jo, was_loaded, "debug", debug, false ); optional( jo, was_loaded, "player_display", player_display, true ); - JsonArray vr = jo.get_array( "vitamin_rates" ); - - while( vr.has_more() ) { - auto pair = vr.next_array(); + for( JsonArray pair : jo.get_array( "vitamin_rates" ) ) { vitamin_rates.emplace( vitamin_id( pair.get_string( 0 ) ), time_duration::from_turns( pair.get_int( 1 ) ) ); } - auto vam = jo.get_array( "vitamins_absorb_multi" ); - while( vam.has_more() ) { - auto pair = vam.next_array(); + for( JsonArray pair : jo.get_array( "vitamins_absorb_multi" ) ) { std::map vit; - auto vit_array = pair.get_array( 1 ); // fill the inner map with vitamins - while( vit_array.has_more() ) { - auto vitamins = vit_array.next_array(); + for( JsonArray vitamins : pair.get_array( 1 ) ) { vit.emplace( vitamin_id( vitamins.get_string( 0 ) ), vitamins.get_float( 1 ) ); } // assign the inner vitamin map to the material_id key @@ -394,64 +387,49 @@ void mutation_branch::load( JsonObject &jo, const std::string & ) optional( jo, was_loaded, "flags", flags, string_reader{} ); optional( jo, was_loaded, "types", types, string_reader{} ); - JsonArray jsar = jo.get_array( "no_cbm_on_bp" ); - while( jsar.has_more() ) { - std::string s = jsar.next_string(); + for( const std::string &s : jo.get_array( "no_cbm_on_bp" ) ) { no_cbm_on_bp.emplace( get_body_part_token( s ) ); } optional( jo, was_loaded, "category", category, string_reader{} ); - JsonArray jsarr = jo.get_array( "spells_learned" ); - while( jsarr.has_more() ) { - JsonArray ja = jsarr.next_array(); + for( JsonArray ja : jo.get_array( "spells_learned" ) ) { const spell_id sp( ja.next_string() ); spells_learned.emplace( sp, ja.next_int() ); } - jsarr = jo.get_array( "lumination" ); - while( jsarr.has_more() ) { - JsonArray ja = jsarr.next_array(); + for( JsonArray ja : jo.get_array( "lumination" ) ) { const body_part bp = get_body_part_token( ja.next_string() ); lumination.emplace( bp, ja.next_float() ); } - jsarr = jo.get_array( "wet_protection" ); - while( jsarr.has_more() ) { - JsonObject jo = jsarr.next_object(); - std::string part_id = jo.get_string( "part" ); - int ignored = jo.get_int( "ignored", 0 ); - int neutral = jo.get_int( "neutral", 0 ); - int good = jo.get_int( "good", 0 ); + for( JsonObject wp : jo.get_array( "wet_protection" ) ) { + std::string part_id = wp.get_string( "part" ); + int ignored = wp.get_int( "ignored", 0 ); + int neutral = wp.get_int( "neutral", 0 ); + int good = wp.get_int( "good", 0 ); tripoint protect = tripoint( ignored, neutral, good ); protection[get_body_part_token( part_id )] = protect; } - jsarr = jo.get_array( "encumbrance_always" ); - while( jsarr.has_more() ) { - JsonArray jo = jsarr.next_array(); - std::string part_id = jo.next_string(); - int enc = jo.next_int(); + for( JsonArray ea : jo.get_array( "encumbrance_always" ) ) { + std::string part_id = ea.next_string(); + int enc = ea.next_int(); encumbrance_always[get_body_part_token( part_id )] = enc; } - jsarr = jo.get_array( "encumbrance_covered" ); - while( jsarr.has_more() ) { - JsonArray jo = jsarr.next_array(); - std::string part_id = jo.next_string(); - int enc = jo.next_int(); + for( JsonArray ec : jo.get_array( "encumbrance_covered" ) ) { + std::string part_id = ec.next_string(); + int enc = ec.next_int(); encumbrance_covered[get_body_part_token( part_id )] = enc; } - jsarr = jo.get_array( "restricts_gear" ); - while( jsarr.has_more() ) { - restricts_gear.insert( get_body_part_token( jsarr.next_string() ) ); + for( const std::string &line : jo.get_array( "restricts_gear" ) ) { + restricts_gear.insert( get_body_part_token( line ) ); } - jsarr = jo.get_array( "armor" ); - while( jsarr.has_more() ) { - JsonObject jo = jsarr.next_object(); - auto parts = jo.get_tags( "parts" ); + for( JsonObject ao : jo.get_array( "armor" ) ) { + auto parts = ao.get_tags( "parts" ); std::set bps; for( const std::string &part_string : parts ) { if( part_string == "ALL" ) { @@ -462,7 +440,7 @@ void mutation_branch::load( JsonObject &jo, const std::string & ) } } - resistances res = load_resistances_instance( jo ); + resistances res = load_resistances_instance( ao ); for( body_part bp : bps ) { armor[ bp ] = res; @@ -470,10 +448,8 @@ void mutation_branch::load( JsonObject &jo, const std::string & ) } if( jo.has_array( "attacks" ) ) { - jsarr = jo.get_array( "attacks" ); - while( jsarr.has_more() ) { - JsonObject jo = jsarr.next_object(); - attacks_granted.emplace_back( load_mutation_attack( jo ) ); + for( JsonObject ao : jo.get_array( "attacks" ) ) { + attacks_granted.emplace_back( load_mutation_attack( ao ) ); } } else if( jo.has_object( "attacks" ) ) { JsonObject attack = jo.get_object( "attacks" ); @@ -591,9 +567,8 @@ void dream::load( JsonObject &jsobj ) newdream.strength = jsobj.get_int( "strength" ); newdream.category = jsobj.get_string( "category" ); - JsonArray jsarr = jsobj.get_array( "messages" ); - while( jsarr.has_more() ) { - newdream.raw_messages.push_back( jsarr.next_string() ); + for( const std::string &line : jsobj.get_array( "messages" ) ) { + newdream.raw_messages.push_back( line ); } dreams.push_back( newdream ); @@ -606,9 +581,8 @@ bool trait_display_sort( const trait_id &a, const trait_id &b ) noexcept void mutation_branch::load_trait_blacklist( JsonObject &jsobj ) { - JsonArray jarr = jsobj.get_array( "traits" ); - while( jarr.has_more() ) { - trait_blacklist.insert( trait_id( jarr.next_string() ) ); + for( const std::string &line : jsobj.get_array( "traits" ) ) { + trait_blacklist.insert( trait_id( line ) ); } } @@ -696,9 +670,7 @@ void mutation_branch::load_trait_group( JsonObject &jsobj, const trait_group::Tr // TODO: (sm) Looks like this makes the new code backwards-compatible with the old format. Great if so! if( subtype == "old" ) { - JsonArray traits = jsobj.get_array( "traits" ); - while( traits.has_more() ) { - JsonArray pair = traits.next_array(); + for( JsonArray pair : jsobj.get_array( "traits" ) ) { tg.add_trait_entry( trait_id( pair.get_string( 0 ) ), pair.get_int( 1 ) ); } return; @@ -706,9 +678,7 @@ void mutation_branch::load_trait_group( JsonObject &jsobj, const trait_group::Tr // TODO: (sm) Taken from item_factory.cpp almost verbatim. Ensure that these work! if( jsobj.has_member( "entries" ) ) { - JsonArray traits = jsobj.get_array( "entries" ); - while( traits.has_more() ) { - JsonObject subobj = traits.next_object(); + for( JsonObject subobj : jsobj.get_array( "entries" ) ) { add_entry( tg, subobj ); } } diff --git a/src/npc.cpp b/src/npc.cpp index a60c85d9dc937..ef79d00f2de60 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -231,9 +231,8 @@ void npc_template::load( JsonObject &jsobj ) if( jsobj.has_string( "mission_offered" ) ) { guy.miss_ids.emplace_back( mission_type_id( jsobj.get_string( "mission_offered" ) ) ); } else if( jsobj.has_array( "mission_offered" ) ) { - JsonArray ja = jsobj.get_array( "mission_offered" ); - while( ja.has_more() ) { - guy.miss_ids.emplace_back( mission_type_id( ja.next_string() ) ); + for( const std::string &line : jsobj.get_array( "mission_offered" ) ) { + guy.miss_ids.emplace_back( mission_type_id( line ) ); } } npc_templates.emplace( string_id( guy.idz ), std::move( tem ) ); diff --git a/src/npc_class.cpp b/src/npc_class.cpp index 82123203e1de2..a90b2fa06bc19 100644 --- a/src/npc_class.cpp +++ b/src/npc_class.cpp @@ -252,9 +252,7 @@ void npc_class::load( JsonObject &jo, const std::string & ) } if( jo.has_array( "spells" ) ) { - JsonArray array = jo.get_array( "spells" ); - while( array.has_more() ) { - JsonObject subobj = array.next_object(); + for( JsonObject subobj : jo.get_array( "spells" ) ) { const int level = subobj.get_int( "level" ); const spell_id sp = spell_id( subobj.get_string( "id" ) ); _starting_spells.emplace( sp, level ); @@ -286,9 +284,7 @@ void npc_class::load( JsonObject &jo, const std::string & ) } if( jo.has_array( "skills" ) ) { - JsonArray jarr = jo.get_array( "skills" ); - while( jarr.has_more() ) { - JsonObject skill_obj = jarr.next_object(); + for( JsonObject skill_obj : jo.get_array( "skills" ) ) { auto skill_ids = skill_obj.get_tags( "skill" ); if( skill_obj.has_object( "level" ) ) { const distribution dis = load_distribution( skill_obj, "level" ); @@ -305,9 +301,7 @@ void npc_class::load( JsonObject &jo, const std::string & ) } if( jo.has_array( "bionics" ) ) { - JsonArray jarr = jo.get_array( "bionics" ); - while( jarr.has_more() ) { - JsonObject bionic_obj = jarr.next_object(); + for( JsonObject bionic_obj : jo.get_array( "bionics" ) ) { auto bionic_ids = bionic_obj.get_tags( "id" ); int chance = bionic_obj.get_int( "chance" ); for( const auto &bid : bionic_ids ) { diff --git a/src/npctalk.cpp b/src/npctalk.cpp index d2c4cac144e47..3dc7feb3dc858 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -1796,9 +1796,7 @@ talk_trial::talk_trial( JsonObject &jo ) read_condition( jo, "condition", condition, false ); if( jo.has_array( "mod" ) ) { - JsonArray ja = jo.get_array( "mod" ); - while( ja.has_more() ) { - JsonArray jmod = ja.next_array(); + for( JsonArray jmod : jo.get_array( "mod" ) ) { trial_mod this_modifier; this_modifier.first = jmod.next_string(); this_modifier.second = jmod.next_int(); @@ -2206,9 +2204,8 @@ void talk_effect_fun_t::set_mapgen_update( JsonObject &jo, const std::string &me if( jo.has_string( member ) ) { update_ids.emplace_back( jo.get_string( member ) ); } else if( jo.has_array( member ) ) { - JsonArray ja = jo.get_array( member ); - while( ja.has_more() ) { - update_ids.emplace_back( ja.next_string() ); + for( const std::string &line : jo.get_array( member ) ) { + update_ids.emplace_back( line ); } } @@ -2512,9 +2509,7 @@ void talk_effect_t::parse_sub_effect( JsonObject &jo ) subeffect_fun.set_change_faction_rep( faction_rep ); } else if( jo.has_array( "add_debt" ) ) { std::vector debt_modifiers; - JsonArray ja = jo.get_array( "add_debt" ); - while( ja.has_more() ) { - JsonArray jmod = ja.next_array(); + for( JsonArray jmod : jo.get_array( "add_debt" ) ) { trial_mod this_modifier; this_modifier.first = jmod.next_string(); this_modifier.second = jmod.next_int(); @@ -2770,16 +2765,14 @@ json_talk_repeat_response::json_talk_repeat_response( JsonObject jo ) if( jo.has_string( "for_item" ) ) { for_item.emplace_back( jo.get_string( "for_item" ) ); } else if( jo.has_array( "for_item" ) ) { - JsonArray ja = jo.get_array( "for_item" ); - while( ja.has_more() ) { - for_item.emplace_back( ja.next_string() ); + for( const std::string &line : jo.get_array( "for_item" ) ) { + for_item.emplace_back( line ); } } else if( jo.has_string( "for_category" ) ) { for_category.emplace_back( jo.get_string( "for_category" ) ); } else if( jo.has_array( "for_category" ) ) { - JsonArray ja = jo.get_array( "for_category" ); - while( ja.has_more() ) { - for_category.emplace_back( ja.next_string() ); + for( const std::string &line : jo.get_array( "for_category" ) ) { + for_category.emplace_back( line ); } } else { jo.throw_error( "Repeat response with no repeat information!" ); @@ -2921,12 +2914,9 @@ dynamic_line_t::dynamic_line_t( JsonObject jo ) jo.throw_error( R"(dynamic line with "gendered_line" must also have "relevant_genders")" ); } - JsonArray ja = jo.get_array( "relevant_genders" ); std::vector relevant_genders; - while( ja.has_more() ) { - relevant_genders.push_back( ja.next_string() ); - } - for( const std::string &gender : relevant_genders ) { + for( const std::string &gender : jo.get_array( "relevant_genders" ) ) { + relevant_genders.push_back( gender ); if( gender != "npc" && gender != "u" ) { jo.throw_error( "Unexpected subject in relevant_genders; expected 'npc' or 'u'" ); } @@ -3037,25 +3027,21 @@ void json_talk_topic::load( JsonObject &jo ) JsonObject speaker_effect = jo.get_object( "speaker_effect" ); speaker_effects.emplace_back( speaker_effect, id ); } else if( jo.has_array( "speaker_effect" ) ) { - JsonArray ja = jo.get_array( "speaker_effect" ); - while( ja.has_more() ) { - JsonObject speaker_effect = ja.next_object(); + for( JsonObject speaker_effect : jo.get_array( "speaker_effect" ) ) { speaker_effects.emplace_back( speaker_effect, id ); } } } - JsonArray ja = jo.get_array( "responses" ); - responses.reserve( responses.size() + ja.size() ); - while( ja.has_more() ) { - JsonObject response = ja.next_object(); + for( JsonObject response : jo.get_array( "responses" ) ) { responses.emplace_back( response ); + response.allow_omitted_members(); } if( jo.has_object( "repeat_responses" ) ) { repeat_responses.emplace_back( jo.get_object( "repeat_responses" ) ); } else if( jo.has_array( "repeat_responses" ) ) { - ja = jo.get_array( "repeat_responses" ); - while( ja.has_more() ) { - repeat_responses.emplace_back( ja.next_object() ); + for( JsonObject elem : jo.get_array( "repeat_responses" ) ) { + repeat_responses.emplace_back( elem ); + elem.allow_omitted_members(); } } if( responses.empty() ) { diff --git a/src/overlay_ordering.cpp b/src/overlay_ordering.cpp index 4c971a2b0ca19..957498198294d 100644 --- a/src/overlay_ordering.cpp +++ b/src/overlay_ordering.cpp @@ -15,9 +15,7 @@ void load_overlay_ordering( JsonObject &jsobj ) void load_overlay_ordering_into_array( JsonObject &jsobj, std::map &orderarray ) { - JsonArray jarr = jsobj.get_array( "overlay_ordering" ); - while( jarr.has_more() ) { - JsonObject ordering = jarr.next_object(); + for( JsonObject ordering : jsobj.get_array( "overlay_ordering" ) ) { int order = ordering.get_int( "order" ); for( auto &id : ordering.get_tags( "id" ) ) { orderarray[id] = order; diff --git a/src/overmap.cpp b/src/overmap.cpp index 5365e959a02b0..c5b87fc75cc5f 100644 --- a/src/overmap.cpp +++ b/src/overmap.cpp @@ -539,14 +539,8 @@ static void load_overmap_terrain_mapgens( JsonObject &jo, const std::string &id_ } } if( jo.has_array( jsonkey ) ) { - JsonArray ja = jo.get_array( jsonkey ); - int c = 0; - while( ja.has_more() ) { - if( ja.has_object( c ) ) { - JsonObject jio = ja.next_object(); - load_mapgen_function( jio, fmapkey, default_idx ); - } - c++; + for( JsonObject jio : jo.get_array( jsonkey ) ) { + load_mapgen_function( jio, fmapkey, default_idx ); } } } diff --git a/src/panels.cpp b/src/panels.cpp index 1da92b89d42ea..d4cb1b3779023 100644 --- a/src/panels.cpp +++ b/src/panels.cpp @@ -2211,20 +2211,12 @@ void panel_manager::deserialize( JsonIn &jsin ) JsonObject joLayouts( jsin.get_object() ); current_layout_id = joLayouts.get_string( "current_layout_id" ); - JsonArray jaLayouts = joLayouts.get_array( "layouts" ); - - while( jaLayouts.has_more() ) { - JsonObject joLayout = jaLayouts.next_object(); - + for( JsonObject joLayout : joLayouts.get_array( "layouts" ) ) { std::string layout_id = joLayout.get_string( "layout_id" ); auto &layout = layouts.find( layout_id )->second; auto it = layout.begin(); - JsonArray jaPanels = joLayout.get_array( "panels" ); - - while( jaPanels.has_more() ) { - JsonObject joPanel = jaPanels.next_object(); - + for( JsonObject joPanel : joLayout.get_array( "panels" ) ) { std::string name = joPanel.get_string( "name" ); bool toggle = joPanel.get_bool( "toggle" ); diff --git a/src/profession.cpp b/src/profession.cpp index a7951e66927d9..111a88ae40d3b 100644 --- a/src/profession.cpp +++ b/src/profession.cpp @@ -170,9 +170,7 @@ void profession::load( JsonObject &jo, const std::string & ) _description_female = to_translation( "prof_desc_female", desc ); } if( jo.has_array( "pets" ) ) { - JsonArray array = jo.get_array( "pets" ); - while( array.has_more() ) { - JsonObject subobj = array.next_object(); + for( JsonObject subobj : jo.get_array( "pets" ) ) { int count = subobj.get_int( "amount" ); mtype_id mon = mtype_id( subobj.get_string( "name" ) ); for( int start = 0; start < count; ++start ) { @@ -182,9 +180,7 @@ void profession::load( JsonObject &jo, const std::string & ) } if( jo.has_array( "spells" ) ) { - JsonArray array = jo.get_array( "spells" ); - while( array.has_more() ) { - JsonObject subobj = array.next_object(); + for( JsonObject subobj : jo.get_array( "spells" ) ) { int level = subobj.get_int( "level" ); spell_id sp = spell_id( subobj.get_string( "id" ) ); _starting_spells.emplace( sp, level ); @@ -513,9 +509,7 @@ void json_item_substitution::load( JsonObject &jo ) if( !jo.has_array( "substitutions" ) ) { jo.throw_error( "No `substitutions` array found." ); } - JsonArray outer_arr = jo.get_array( "substitutions" ); - while( outer_arr.has_more() ) { - JsonObject subobj = outer_arr.next_object(); + for( JsonObject subobj : jo.get_array( "substitutions" ) ) { do_load( subobj ); } } @@ -546,9 +540,7 @@ void json_item_substitution::do_load( JsonObject &jo ) jo.throw_error( "Missing sub array" ); } - JsonArray sub = jo.get_array( "sub" ); - while( sub.has_more() ) { - JsonArray line = sub.next_array(); + for( JsonArray line : jo.get_array( "sub" ) ) { substitution s; const itype_id old_it = item_mode ? title : line.next_string(); if( item_mode ) { diff --git a/src/recipe.cpp b/src/recipe.cpp index 7a0211ca360f2..5d0c3c78c0f80 100644 --- a/src/recipe.cpp +++ b/src/recipe.cpp @@ -132,8 +132,7 @@ void recipe::load( JsonObject &jo, const std::string &src ) } else if( sk.has_array( 0 ) ) { // multiple requirements - while( sk.has_more() ) { - auto arr = sk.next_array(); + for( JsonArray arr : sk ) { required_skills[skill_id( arr.get_string( 0 ) )] = arr.get_int( 1 ); } @@ -149,9 +148,7 @@ void recipe::load( JsonObject &jo, const std::string &src ) } else if( jo.has_array( "autolearn" ) ) { autolearn = true; - auto sk = jo.get_array( "autolearn" ); - while( sk.has_more() ) { - auto arr = sk.next_array(); + for( JsonArray arr : jo.get_array( "autolearn" ) ) { autolearn_requirements[skill_id( arr.get_string( 0 ) )] = arr.get_int( 1 ); } } @@ -171,20 +168,15 @@ void recipe::load( JsonObject &jo, const std::string &src ) assign( jo, "decomp_learn", learn_by_disassembly[skill_used] ); } else if( jo.has_array( "decomp_learn" ) ) { - auto sk = jo.get_array( "decomp_learn" ); - while( sk.has_more() ) { - auto arr = sk.next_array(); + for( JsonArray arr : jo.get_array( "decomp_learn" ) ) { learn_by_disassembly[skill_id( arr.get_string( 0 ) )] = arr.get_int( 1 ); } } } if( jo.has_member( "book_learn" ) ) { - auto bk = jo.get_array( "book_learn" ); booksets.clear(); - - while( bk.has_more() ) { - auto arr = bk.next_array(); + for( JsonArray arr : jo.get_array( "book_learn" ) ) { booksets.emplace( arr.get_string( 0 ), arr.size() > 1 ? arr.get_int( 1 ) : -1 ); } } @@ -198,11 +190,8 @@ void recipe::load( JsonObject &jo, const std::string &src ) reqs_external = { { requirement_id( jo.get_string( "using" ) ), 1 } }; } else if( jo.has_array( "using" ) ) { - auto arr = jo.get_array( "using" ); reqs_external.clear(); - - while( arr.has_more() ) { - auto cur = arr.next_array(); + for( JsonArray cur : jo.get_array( "using" ) ) { reqs_external.emplace_back( requirement_id( cur.get_string( 0 ) ), cur.get_int( 1 ) ); } } @@ -226,41 +215,31 @@ void recipe::load( JsonObject &jo, const std::string &src ) if( this->reversible ) { jo.throw_error( "Recipe cannot be reversible and have byproducts" ); } - auto bp = jo.get_array( "byproducts" ); byproducts.clear(); - while( bp.has_more() ) { - auto arr = bp.next_array(); + for( JsonArray arr : jo.get_array( "byproducts" ) ) { byproducts[ arr.get_string( 0 ) ] += arr.size() == 2 ? arr.get_int( 1 ) : 1; } } assign( jo, "construction_blueprint", blueprint ); if( !blueprint.empty() ) { assign( jo, "blueprint_name", bp_name ); - JsonArray bp_array = jo.get_array( "blueprint_resources" ); bp_resources.clear(); - while( bp_array.has_more() ) { - std::string resource = bp_array.next_string(); + for( const std::string &resource : jo.get_array( "blueprint_resources" ) ) { bp_resources.emplace_back( resource ); } - bp_array = jo.get_array( "blueprint_provides" ); - while( bp_array.has_more() ) { - JsonObject provide = bp_array.next_object(); + for( JsonObject provide : jo.get_array( "blueprint_provides" ) ) { bp_provides.emplace_back( std::make_pair( provide.get_string( "id" ), provide.get_int( "amount", 1 ) ) ); } // all blueprints provide themselves with needing it written in JSON bp_provides.emplace_back( std::make_pair( result_, 1 ) ); - bp_array = jo.get_array( "blueprint_requires" ); - while( bp_array.has_more() ) { - JsonObject require = bp_array.next_object(); + for( JsonObject require : jo.get_array( "blueprint_requires" ) ) { bp_requires.emplace_back( std::make_pair( require.get_string( "id" ), require.get_int( "amount", 1 ) ) ); } // all blueprints exclude themselves with needing it written in JSON bp_excludes.emplace_back( std::make_pair( result_, 1 ) ); - bp_array = jo.get_array( "blueprint_excludes" ); - while( bp_array.has_more() ) { - JsonObject exclude = bp_array.next_object(); + for( JsonObject exclude : jo.get_array( "blueprint_excludes" ) ) { bp_excludes.emplace_back( std::make_pair( exclude.get_string( "id" ), exclude.get_int( "amount", 1 ) ) ); } diff --git a/src/recipe_groups.cpp b/src/recipe_groups.cpp index affe850a9025f..220291d5b8074 100644 --- a/src/recipe_groups.cpp +++ b/src/recipe_groups.cpp @@ -40,18 +40,14 @@ generic_factory recipe_groups_data( "recipe group type", "nam void recipe_group_data::load( JsonObject &jo, const std::string & ) { building_type = jo.get_string( "building_type" ); - JsonArray jsarr = jo.get_array( "recipes" ); - while( jsarr.has_more() ) { - JsonObject ordering = jsarr.next_object(); + for( JsonObject ordering : jo.get_array( "recipes" ) ) { recipe_id name_id; ordering.read( "id", name_id ); translation desc; ordering.read( "description", desc ); recipes.emplace( name_id, desc ); om_terrains[name_id] = std::set(); - JsonArray js_terr = ordering.get_array( "om_terrains" ); - while( js_terr.has_more() ) { - const std::string ter_type = js_terr.next_string(); + for( const std::string &ter_type : ordering.get_array( "om_terrains" ) ) { om_terrains[name_id].insert( ter_type ); } } diff --git a/src/regional_settings.cpp b/src/regional_settings.cpp index 31c7d8a79cf7a..fc0615afca0ce 100644 --- a/src/regional_settings.cpp +++ b/src/regional_settings.cpp @@ -267,9 +267,8 @@ static void load_overmap_feature_flag_settings( JsonObject &jo, overmap_feature_flag_settings_jo.throw_error( "blacklist required" ); } } else { - JsonArray blacklist_ja = overmap_feature_flag_settings_jo.get_array( "blacklist" ); - while( blacklist_ja.has_more() ) { - overmap_feature_flag_settings.blacklist.emplace( blacklist_ja.next_string() ); + for( const std::string &line : overmap_feature_flag_settings_jo.get_array( "blacklist" ) ) { + overmap_feature_flag_settings.blacklist.emplace( line ); } } @@ -278,9 +277,8 @@ static void load_overmap_feature_flag_settings( JsonObject &jo, overmap_feature_flag_settings_jo.throw_error( "whitelist required" ); } } else { - JsonArray whitelist_ja = overmap_feature_flag_settings_jo.get_array( "whitelist" ); - while( whitelist_ja.has_more() ) { - overmap_feature_flag_settings.whitelist.emplace( whitelist_ja.next_string() ); + for( const std::string &line : overmap_feature_flag_settings_jo.get_array( "whitelist" ) ) { + overmap_feature_flag_settings.whitelist.emplace( line ); } } } @@ -343,12 +341,10 @@ static void load_overmap_lake_settings( JsonObject &jo, overmap_lake_settings_jo.throw_error( "shore_extendable_overmap_terrain_aliases required" ); } } else { - JsonArray aliases_jarr = - overmap_lake_settings_jo.get_array( "shore_extendable_overmap_terrain_aliases" ); oter_str_id alias; - while( aliases_jarr.has_more() ) { + for( JsonObject jo : + overmap_lake_settings_jo.get_array( "shore_extendable_overmap_terrain_aliases" ) ) { shore_extendable_overmap_terrain_alias alias; - JsonObject jo = aliases_jarr.next_object(); jo.read( "om_terrain", alias.overmap_terrain ); jo.read( "alias", alias.alias ); alias.match_type = jo.get_enum_value( "om_terrain_match_type", @@ -439,10 +435,8 @@ void load_region_settings( JsonObject &jo ) jo.throw_error( "river_scale required for default" ); } if( jo.has_array( "default_groundcover" ) ) { - JsonArray jia = jo.get_array( "default_groundcover" ); new_region.default_groundcover_str.reset( new weighted_int_list ); - while( jia.has_more() ) { - JsonArray inner = jia.next_array(); + for( JsonArray inner : jo.get_array( "default_groundcover" ) ) { if( new_region.default_groundcover_str->add( ter_str_id( inner.get_string( 0 ) ), inner.get_int( 1 ) ) == nullptr ) { jo.throw_error( "'default_groundcover' must be a weighted list: an array of pairs [ \"id\", weight ]" ); @@ -624,10 +618,7 @@ void load_region_overlay( JsonObject &jo ) { if( jo.has_array( "regions" ) ) { JsonArray regions = jo.get_array( "regions" ); - - while( regions.has_more() ) { - std::string regionid = regions.next_string(); - + for( const std::string ®ionid : regions ) { if( regionid == "all" ) { if( regions.size() != 1 ) { jo.throw_error( "regions: More than one region is not allowed when \"all\" is used" ); @@ -655,10 +646,8 @@ void apply_region_overlay( JsonObject &jo, regional_settings ®ion ) jo.read( "default_oter", region.default_oter ); jo.read( "river_scale", region.river_scale ); if( jo.has_array( "default_groundcover" ) ) { - JsonArray jia = jo.get_array( "default_groundcover" ); region.default_groundcover_str.reset( new weighted_int_list ); - while( jia.has_more() ) { - JsonArray inner = jia.next_array(); + for( JsonArray inner : jo.get_array( "default_groundcover" ) ) { if( region.default_groundcover_str->add( ter_str_id( inner.get_string( 0 ) ), inner.get_int( 1 ) ) == nullptr ) { jo.throw_error( "'default_groundcover' must be a weighted list: an array of pairs [ \"id\", weight ]" ); diff --git a/src/relic.cpp b/src/relic.cpp index 1f91f9ce9cb8d..bd15456d797a2 100644 --- a/src/relic.cpp +++ b/src/relic.cpp @@ -27,19 +27,15 @@ void relic::add_passive_effect( const enchantment &nench ) void relic::load( JsonObject &jo ) { if( jo.has_array( "active_effects" ) ) { - JsonArray jarray = jo.get_array( "active_effects" ); - while( jarray.has_more() ) { + for( JsonObject jobj : jo.get_array( "active_effects" ) ) { fake_spell sp; - JsonObject jobj = jarray.next_object(); sp.load( jobj ); add_active_effect( sp ); } } if( jo.has_array( "passive_effects" ) ) { - JsonArray jarray = jo.get_array( "passive_effects" ); - while( jarray.has_more() ) { + for( JsonObject jobj : jo.get_array( "passive_effects" ) ) { enchantment ench; - JsonObject jobj = jarray.next_object(); ench.load( jobj ); add_passive_effect( ench ); } diff --git a/src/requirements.cpp b/src/requirements.cpp index d0545b6dca78e..738f1ebd3457b 100644 --- a/src/requirements.cpp +++ b/src/requirements.cpp @@ -71,12 +71,10 @@ void quality::load( JsonObject &jo, const std::string & ) { mandatory( jo, was_loaded, "name", name ); - JsonArray arr = jo.get_array( "usages" ); - while( arr.has_more() ) { - auto lvl = arr.next_array(); - auto funcs = lvl.get_array( 1 ); - while( funcs.has_more() ) { - usages.emplace_back( lvl.get_int( 0 ), funcs.next_string() ); + for( JsonArray levels : jo.get_array( "usages" ) ) { + const int level = levels.get_int( 0 ); + for( const std::string &line : levels.get_array( 1 ) ) { + usages.emplace_back( level, line ); } } } diff --git a/src/savegame.cpp b/src/savegame.cpp index 32436d6f19572..d5e163bf4e441 100644 --- a/src/savegame.cpp +++ b/src/savegame.cpp @@ -201,11 +201,10 @@ void game::unserialize( std::istream &fin ) } data.read( "active_monsters", *critter_tracker ); - JsonArray vdata = data.get_array( "stair_monsters" ); coming_to_stairs.clear(); - while( vdata.has_more() ) { + for( auto elem : data.get_array( "stair_monsters" ) ) { monster stairtmp; - vdata.read_next( stairtmp ); + elem.read( stairtmp ); coming_to_stairs.push_back( stairtmp ); } @@ -221,10 +220,7 @@ void game::unserialize( std::istream &fin ) kills[mtype_id( member )] = odata.get_int( member ); } - vdata = data.get_array( "npc_kills" ); - while( vdata.has_more() ) { - std::string npc_name; - vdata.read_next( npc_name ); + for( const std::string &npc_name : data.get_array( "npc_kills" ) ) { npc_kills.push_back( npc_name ); } @@ -277,11 +273,10 @@ void game::load_shortcuts( std::istream &fin ) quick_shortcuts_map.clear(); for( std::set::iterator it = qsl_members.begin(); it != qsl_members.end(); ++it ) { - JsonArray ja = qs.get_array( *it ); std::list &qslist = quick_shortcuts_map[ *it ]; qslist.clear(); - while( ja.has_more() ) { - qslist.push_back( input_event( ja.next_int(), CATA_INPUT_KEYBOARD ) ); + for( const int i : qs.get_array( *it ) ) { + qslist.push_back( input_event( i, CATA_INPUT_KEYBOARD ) ); } } } @@ -318,9 +313,8 @@ std::unordered_set obsolete_terrains; void overmap::load_obsolete_terrains( JsonObject &jo ) { - JsonArray ja = jo.get_array( "terrains" ); - while( ja.has_more() ) { - obsolete_terrains.emplace( ja.next_string() ); + for( const std::string &line : jo.get_array( "terrains" ) ) { + obsolete_terrains.emplace( line ); } } diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 8c9f977001821..6efdf30b875df 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -885,10 +885,8 @@ void player::load( JsonObject &data ) data.read( "addictions", addictions ); data.read( "followers", follower_ids ); - JsonArray traps = data.get_array( "known_traps" ); known_traps.clear(); - while( traps.has_more() ) { - JsonObject pmap = traps.next_object(); + for( JsonObject pmap : data.get_array( "known_traps" ) ) { const tripoint p( pmap.get_int( "x" ), pmap.get_int( "y" ), pmap.get_int( "z" ) ); const std::string t = pmap.get_string( "trap" ); known_traps.insert( trap_map::value_type( p, t ) ); @@ -916,9 +914,7 @@ void player::load( JsonObject &data ) } if( data.has_array( "faction_warnings" ) ) { - JsonArray warning_arr = data.get_array( "faction_warnings" ); - while( warning_arr.has_more() ) { - JsonObject warning_data = warning_arr.next_object(); + for( JsonObject warning_data : data.get_array( "faction_warnings" ) ) { std::string fac_id = warning_data.get_string( "fac_warning_id" ); int warning_num = warning_data.get_int( "fac_warning_num" ); time_point warning_time = calendar::before_time_starts; @@ -946,10 +942,8 @@ void player::load( JsonObject &data ) last_target = g->critter_tracker->from_temporary_id( tmptar ); } data.read( "destination_point", destination_point ); - JsonArray basecamps = data.get_array( "camps" ); camps.clear(); - while( basecamps.has_more() ) { - JsonObject bcdata = basecamps.next_object(); + for( JsonObject bcdata : data.get_array( "camps" ) ) { tripoint bcpt; bcdata.read( "pos", bcpt ); camps.insert( bcpt ); @@ -1169,9 +1163,7 @@ void avatar::load( JsonObject &data ) } data.read( "show_map_memory", show_map_memory ); - JsonArray parray = data.get_array( "assigned_invlet" ); - while( parray.has_more() ) { - JsonArray pair = parray.next_array(); + for( JsonArray pair : data.get_array( "assigned_invlet" ) ) { inv.assigned_invlet[static_cast( pair.get_int( 0 ) )] = pair.get_string( 1 ); } @@ -1740,15 +1732,12 @@ void inventory::json_load_invcache( JsonIn &jsin ) { try { std::unordered_map map; - JsonArray ja = jsin.get_array(); - while( ja.has_more() ) { - JsonObject jo = ja.next_object(); + for( JsonObject jo : jsin.get_array() ) { std::set members = jo.get_member_names(); for( const auto &member : members ) { std::string invlets; - JsonArray pvect = jo.get_array( member ); - while( pvect.has_more() ) { - invlets.push_back( pvect.next_int() ); + for( const int i : jo.get_array( member ) ) { + invlets.push_back( i ); } map[member] = invlets; } @@ -2650,9 +2639,7 @@ void vehicle::deserialize( JsonIn &jsin ) point p; zone_data zd; - JsonArray ja = data.get_array( "zones" ); - while( ja.has_more() ) { - JsonObject sdata = ja.next_object(); + for( JsonObject sdata : data.get_array( "zones" ) ) { sdata.read( "point", p ); sdata.read( "zone", zd ); loot_zones.emplace( p, zd ); @@ -3145,19 +3132,15 @@ void map_memory::load( JsonIn &jsin ) // Deserializer for legacy object-based memory map. void map_memory::load( JsonObject &jsin ) { - JsonArray map_memory_tiles = jsin.get_array( "map_memory_tiles" ); tile_cache.clear(); - while( map_memory_tiles.has_more() ) { - JsonObject pmap = map_memory_tiles.next_object(); + for( JsonObject pmap : jsin.get_array( "map_memory_tiles" ) ) { 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" ) ); } - JsonArray map_memory_curses = jsin.get_array( "map_memory_curses" ); symbol_cache.clear(); - while( map_memory_curses.has_more() ) { - JsonObject pmap = map_memory_curses.next_object(); + for( JsonObject pmap : jsin.get_array( "map_memory_curses" ) ) { 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" ) ); } @@ -3345,9 +3328,7 @@ void basecamp::deserialize( JsonIn &jsin ) data.read( "name", name ); data.read( "pos", omt_pos ); data.read( "bb_pos", bb_pos ); - JsonArray ja = data.get_array( "expansions" ); - while( ja.has_more() ) { - JsonObject edata = ja.next_object(); + for( JsonObject edata : data.get_array( "expansions" ) ) { expansion_data e; point dir; if( edata.has_string( "dir" ) ) { @@ -3363,9 +3344,7 @@ void basecamp::deserialize( JsonIn &jsin ) } if( edata.has_array( "provides" ) ) { e.cur_level = -1; - JsonArray provides_arr = edata.get_array( "provides" ); - while( provides_arr.has_more() ) { - JsonObject provide_data = provides_arr.next_object(); + for( JsonObject provide_data : edata.get_array( "provides" ) ) { std::string id = provide_data.get_string( "id" ); int amount = provide_data.get_int( "amount" ); e.provides[ id ] = amount; @@ -3376,9 +3355,7 @@ void basecamp::deserialize( JsonIn &jsin ) if( e.provides.find( initial_provide ) == e.provides.end() ) { e.provides[ initial_provide ] = 1; } - JsonArray in_progress_arr = edata.get_array( "in_progress" ); - while( in_progress_arr.has_more() ) { - JsonObject in_progress_data = in_progress_arr.next_object(); + for( JsonObject in_progress_data : edata.get_array( "in_progress" ) ) { std::string id = in_progress_data.get_string( "id" ); int amount = in_progress_data.get_int( "amount" ); e.in_progress[ id ] = amount; @@ -3389,9 +3366,7 @@ void basecamp::deserialize( JsonIn &jsin ) directions.push_back( dir ); } } - JsonArray jo = data.get_array( "fortifications" ); - while( jo.has_more() ) { - JsonObject edata = jo.next_object(); + for( JsonObject edata : data.get_array( "fortifications" ) ) { tripoint restore_pos; edata.read( "pos", restore_pos ); fortifications.push_back( restore_pos ); @@ -3426,10 +3401,7 @@ void kill_tracker::deserialize( JsonIn &jsin ) kills[mtype_id( member )] = kills_obj.get_int( member ); } - JsonArray npc_kills_array = data.get_array( "npc_kills" ); - while( npc_kills_array.has_more() ) { - std::string npc_name; - npc_kills_array.read_next( npc_name ); + for( const std::string &npc_name : data.get_array( "npc_kills" ) ) { npc_kills.push_back( npc_name ); } } diff --git a/src/sdlsound.cpp b/src/sdlsound.cpp index da6b331422862..83f0f67f946c6 100644 --- a/src/sdlsound.cpp +++ b/src/sdlsound.cpp @@ -313,10 +313,8 @@ void sfx::load_sound_effects( JsonObject &jsobj ) const int volume = jsobj.get_int( "volume", 100 ); auto &effects = sfx_resources.sound_effects[ key ]; - JsonArray jsarr = jsobj.get_array( "files" ); - while( jsarr.has_more() ) { + for( const std::string file : jsobj.get_array( "files" ) ) { sound_effect new_sound_effect; - const std::string file = jsarr.next_string(); new_sound_effect.volume = volume; new_sound_effect.resource_id = add_sfx_path( file ); @@ -329,9 +327,7 @@ void sfx::load_sound_effect_preload( JsonObject &jsobj ) return; } - JsonArray jsarr = jsobj.get_array( "preload" ); - while( jsarr.has_more() ) { - JsonObject aobj = jsarr.next_object(); + for( JsonObject aobj : jsobj.get_array( "preload" ) ) { const id_and_variant preload_key( aobj.get_string( "id" ), aobj.get_string( "variant", "default" ) ); sfx_preload.push_back( preload_key ); @@ -344,17 +340,12 @@ void sfx::load_playlist( JsonObject &jsobj ) return; } - JsonArray jarr = jsobj.get_array( "playlists" ); - while( jarr.has_more() ) { - JsonObject playlist = jarr.next_object(); - + for( JsonObject playlist : jsobj.get_array( "playlists" ) ) { const std::string playlist_id = playlist.get_string( "id" ); music_playlist playlist_to_load; playlist_to_load.shuffle = playlist.get_bool( "shuffle", false ); - JsonArray files = playlist.get_array( "files" ); - while( files.has_more() ) { - JsonObject entry = files.next_object(); + for( JsonObject entry : playlist.get_array( "files" ) ) { const music_playlist::entry e{ entry.get_string( "file" ), entry.get_int( "volume" ) }; playlist_to_load.entries.push_back( e ); } diff --git a/src/tutorial.cpp b/src/tutorial.cpp index ae71a52f19230..1f8c6969e718c 100644 --- a/src/tutorial.cpp +++ b/src/tutorial.cpp @@ -274,10 +274,9 @@ void load_tutorial_messages( JsonObject &jo ) { // loading them all at once, as they have to be in exact order tut_text.clear(); - JsonArray messages = jo.get_array( "messages" ); - while( messages.has_more() ) { + for( auto messages : jo.get_array( "messages" ) ) { translation next; - messages.read_next( next ); + messages.read( next ); tut_text.emplace_back( next ); } } diff --git a/src/veh_type.cpp b/src/veh_type.cpp index 2624941594718..d85528ee9367a 100644 --- a/src/veh_type.cpp +++ b/src/veh_type.cpp @@ -171,8 +171,7 @@ static void parse_vp_reqs( JsonObject &obj, const std::string &id, const std::st if( !sk.empty() ) { skills.clear(); } - while( sk.has_more() ) { - auto cur = sk.next_array(); + for( JsonArray cur : sk ) { skills.emplace( skill_id( cur.get_string( 0 ) ), cur.size() >= 2 ? cur.get_int( 1 ) : 1 ); } @@ -187,9 +186,7 @@ static void parse_vp_reqs( JsonObject &obj, const std::string &id, const std::st reqs = { { requirement_id( src.get_string( "using" ) ), 1 } }; } else if( src.has_array( "using" ) ) { reqs.clear(); - auto arr = src.get_array( "using" ); - while( arr.has_more() ) { - auto cur = arr.next_array(); + for( JsonArray cur : src.get_array( "using" ) ) { reqs.emplace_back( requirement_id( cur.get_string( 0 ) ), cur.get_int( 1 ) ); } } else { @@ -221,15 +218,15 @@ void vpart_info::load_engine( cata::optional &eptr, JsonObject &j auto excludes = jo.get_array( "exclusions" ); if( !excludes.empty() ) { e_info.exclusions.clear(); - while( excludes.has_more() ) { - e_info.exclusions.push_back( excludes.next_string() ); + for( const std::string &line : excludes ) { + e_info.exclusions.push_back( line ); } } auto fuel_opts = jo.get_array( "fuel_options" ); if( !fuel_opts.empty() ) { e_info.fuel_opts.clear(); - while( fuel_opts.has_more() ) { - e_info.fuel_opts.push_back( itype_id( fuel_opts.next_string() ) ); + for( const std::string &line : fuel_opts ) { + e_info.fuel_opts.push_back( itype_id( line ) ); } } else if( e_info.fuel_opts.empty() && fuel_type != itype_id( "null" ) ) { e_info.fuel_opts.push_back( fuel_type ); @@ -347,9 +344,7 @@ void vpart_info::load( JsonObject &jo, const std::string &src ) if( jo.has_member( "transform_terrain" ) ) { JsonObject jttd = jo.get_object( "transform_terrain" ); - JsonArray jpf = jttd.get_array( "pre_flags" ); - while( jpf.has_more() ) { - std::string pre_flag = jpf.next_string(); + for( const std::string &pre_flag : jttd.get_array( "pre_flags" ) ) { def.transform_terrain.pre_flags.emplace( pre_flag ); } def.transform_terrain.post_terrain = jttd.get_string( "post_terrain", "t_null" ); @@ -403,8 +398,7 @@ void vpart_info::load( JsonObject &jo, const std::string &src ) auto qual = jo.get_array( "qualities" ); if( !qual.empty() ) { def.qualities.clear(); - while( qual.has_more() ) { - auto pair = qual.next_array(); + for( JsonArray pair : qual ) { def.qualities[ quality_id( pair.get_string( 0 ) ) ] = pair.get_int( 1 ); } } @@ -949,9 +943,7 @@ void vehicle_prototype::load( JsonObject &jo ) vproto.parts.push_back( pt ); }; - JsonArray parts = jo.get_array( "parts" ); - while( parts.has_more() ) { - JsonObject part = parts.next_object(); + for( JsonObject part : jo.get_array( "parts" ) ) { point pos = point( part.get_int( "x" ), part.get_int( "y" ) ); if( part.has_string( "part" ) ) { @@ -970,9 +962,7 @@ void vehicle_prototype::load( JsonObject &jo ) } } - JsonArray items = jo.get_array( "items" ); - while( items.has_more() ) { - JsonObject spawn_info = items.next_object(); + for( JsonObject spawn_info : jo.get_array( "items" ) ) { vehicle_item_spawn next_spawn; next_spawn.pos.x = spawn_info.get_int( "x" ); next_spawn.pos.y = spawn_info.get_int( "y" ); diff --git a/src/vehicle_group.cpp b/src/vehicle_group.cpp index c8965c68ca692..40d0ee5c74c6c 100644 --- a/src/vehicle_group.cpp +++ b/src/vehicle_group.cpp @@ -65,9 +65,7 @@ void VehicleGroup::load( JsonObject &jo ) { VehicleGroup &group = vgroups[vgroup_id( jo.get_string( "id" ) )]; - JsonArray vehicles = jo.get_array( "vehicles" ); - while( vehicles.has_more() ) { - JsonArray pair = vehicles.next_array(); + for( JsonArray pair : jo.get_array( "vehicles" ) ) { group.add_vehicle( vproto_id( pair.get_string( 0 ) ), pair.get_int( 1 ) ); } } @@ -80,10 +78,8 @@ void VehicleGroup::reset() VehicleFacings::VehicleFacings( JsonObject &jo, const std::string &key ) { if( jo.has_array( key ) ) { - JsonArray jpos = jo.get_array( key ); - - while( jpos.has_more() ) { - values.push_back( jpos.next_int() ); + for( const int i : jo.get_array( key ) ) { + values.push_back( i ); } } else { values.push_back( jo.get_int( key ) ); @@ -94,10 +90,7 @@ void VehiclePlacement::load( JsonObject &jo ) { VehiclePlacement &placement = vplacements[vplacement_id( jo.get_string( "id" ) )]; - JsonArray locations = jo.get_array( "locations" ); - while( locations.has_more() ) { - JsonObject jloc = locations.next_object(); - + for( JsonObject jloc : jo.get_array( "locations" ) ) { placement.add( jmapgen_int( jloc, "x" ), jmapgen_int( jloc, "y" ), VehicleFacings( jloc, "facing" ) ); } @@ -173,11 +166,7 @@ bool string_id::is_valid() const void VehicleSpawn::load( JsonObject &jo ) { VehicleSpawn &spawn = vspawns[vspawn_id( jo.get_string( "id" ) )]; - JsonArray types = jo.get_array( "spawn_types" ); - - while( types.has_more() ) { - JsonObject type = types.next_object(); - + for( JsonObject type : jo.get_array( "spawn_types" ) ) { if( type.has_object( "vehicle_json" ) ) { JsonObject vjo = type.get_object( "vehicle_json" ); spawn.add( type.get_float( "weight" ), make_shared_fast( vjo ) ); diff --git a/src/vitamin.cpp b/src/vitamin.cpp index 6c5f09e0f5c35..2959ff66f4cfa 100644 --- a/src/vitamin.cpp +++ b/src/vitamin.cpp @@ -65,15 +65,11 @@ void vitamin::load_vitamin( JsonObject &jo ) jo.throw_error( "vitamin consumption rate cannot be negative", "rate" ); } - JsonArray def = jo.get_array( "disease" ); - while( def.has_more() ) { - JsonArray e = def.next_array(); + for( JsonArray e : jo.get_array( "disease" ) ) { vit.disease_.emplace_back( e.get_int( 0 ), e.get_int( 1 ) ); } - auto exc = jo.get_array( "disease_excess" ); - while( exc.has_more() ) { - auto e = exc.next_array(); + for( JsonArray e : jo.get_array( "disease_excess" ) ) { vit.disease_excess_.emplace_back( e.get_int( 0 ), e.get_int( 1 ) ); } diff --git a/src/worldfactory.cpp b/src/worldfactory.cpp index f889b85fee155..10130d24794ca 100644 --- a/src/worldfactory.cpp +++ b/src/worldfactory.cpp @@ -1412,8 +1412,8 @@ void load_world_option( JsonObject &jo ) if( arr.empty() ) { jo.throw_error( "no options specified", "options" ); } - while( arr.has_more() ) { - get_options().get_option( arr.next_string() ).setValue( "true" ); + for( const std::string &line : arr ) { + get_options().get_option( line ).setValue( "true" ); } } From 0c0bfd5fa5b8b7cfee5a4ab2b465c5d93606116c Mon Sep 17 00:00:00 2001 From: KorGgenT Date: Fri, 6 Dec 2019 18:30:48 -0500 Subject: [PATCH 09/16] add norse myth book to itemgroup --- data/mods/Magiclysm/itemgroups/recipe_books.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/mods/Magiclysm/itemgroups/recipe_books.json b/data/mods/Magiclysm/itemgroups/recipe_books.json index 9dd08cfd19c58..776d33dc21e6a 100644 --- a/data/mods/Magiclysm/itemgroups/recipe_books.json +++ b/data/mods/Magiclysm/itemgroups/recipe_books.json @@ -3,6 +3,6 @@ "id": "magic_recipe_basic", "type": "item_group", "//": "Lower tier recipes, many of which can be done with the alchemist rune. Usually has at least one recipe requiring related school rune or rune weapon", - "items": [ [ "alchemy_basic", 30 ], [ "necro_basic", 30 ], [ "techno_basic", 30 ] ] + "items": [ [ "alchemy_basic", 30 ], [ "necro_basic", 30 ], [ "techno_basic", 30 ], [ "book_mythological", 10 ] ] } ] From c95dfbada82d38292aec8bf570e67e2a44af8fc2 Mon Sep 17 00:00:00 2001 From: kmullinax <57138675+kmullinax@users.noreply.github.com> Date: Fri, 6 Dec 2019 22:07:01 -0500 Subject: [PATCH 10/16] [Magiclysm] Lizardfolk (#35138) * Lizardfolk - main monster file * Lizardfolk - updated base files * Lizardfolk - modified effects file * Lizardfolk - new weapons file * Lizardfolk - new shaman spell file * restore removed harvest entries * lint * change symbols of lizardfolk to L * remove superfluous json members * adjust javelin names * adjust shaman spells * alter shaman drops * adjust lizard folk special attack messages * fix crocodile summoning grammar * adjust lizardfolk descriptions * lizardfolk weapon adjustments * remove superfluous effect --- .../Magiclysm/Spells/lizardfolk_shaman.json | 41 +++++ data/mods/Magiclysm/harvest.json | 14 ++ data/mods/Magiclysm/items/weapons.json | 57 +++++++ data/mods/Magiclysm/monster_attacks.json | 30 ++++ data/mods/Magiclysm/monster_factions.json | 9 +- data/mods/Magiclysm/monsters/lizardfolk.json | 140 ++++++++++++++++++ data/mods/Magiclysm/species.json | 6 + 7 files changed, 295 insertions(+), 2 deletions(-) create mode 100644 data/mods/Magiclysm/Spells/lizardfolk_shaman.json create mode 100644 data/mods/Magiclysm/items/weapons.json create mode 100644 data/mods/Magiclysm/monster_attacks.json create mode 100644 data/mods/Magiclysm/monsters/lizardfolk.json diff --git a/data/mods/Magiclysm/Spells/lizardfolk_shaman.json b/data/mods/Magiclysm/Spells/lizardfolk_shaman.json new file mode 100644 index 0000000000000..d059955839e87 --- /dev/null +++ b/data/mods/Magiclysm/Spells/lizardfolk_shaman.json @@ -0,0 +1,41 @@ +[ + { + "type": "SPELL", + "id": "spell_summon_crocodile", + "name": "Summon Crocodile", + "description": "Summons a permanent crocodile.", + "flags": [ "HOSTILE_SUMMON", "PERMANENT" ], + "valid_targets": [ "ground" ], + "base_casting_time": 200, + "min_damage": 1, + "max_damage": 1, + "min_aoe": 2, + "max_aoe": 2, + "message": "The shaman summons a crocodile!", + "effect": "summon", + "effect_str": "mon_crocodile" + }, + { + "type": "SPELL", + "id": "spell_shaman_base", + "name": "an ancient reptilian spell", + "description": "Causes one of the shaman spells to be cast.", + "valid_targets": [ "hostile", "ground" ], + "effect": "none", + "base_casting_time": 100, + "flags": [ "WONDER" ], + "min_damage": 1, + "max_damage": 1, + "message": "", + "extra_effects": [ + { "id": "druid_veggrasp" }, + { "id": "druid_veggrasp" }, + { "id": "druid_veggrasp" }, + { "id": "druid_veggrasp" }, + { "id": "light_healing", "self": true }, + { "id": "light_healing", "self": true }, + { "id": "light_healing", "self": true }, + { "id": "spell_summon_crocodile" } + ] + } +] diff --git a/data/mods/Magiclysm/harvest.json b/data/mods/Magiclysm/harvest.json index c0f2e7a3480ec..878359ae6d638 100644 --- a/data/mods/Magiclysm/harvest.json +++ b/data/mods/Magiclysm/harvest.json @@ -319,5 +319,19 @@ { "drop": "tainted_blood", "type": "flesh", "mass_ratio": 0.1 }, { "drop": "meat", "type": "flesh", "mass_ratio": 0.4 } ] + }, + { + "id": "lizardfolk", + "type": "harvest", + "entries": [ + { "drop": "meat", "type": "flesh", "mass_ratio": 0.32 }, + { "drop": "lung", "type": "flesh", "mass_ratio": 0.0035 }, + { "drop": "liver", "type": "offal", "mass_ratio": 0.01 }, + { "drop": "brain", "type": "flesh", "mass_ratio": 0.005 }, + { "drop": "kidney", "type": "offal", "mass_ratio": 0.002 }, + { "drop": "raw_leather", "type": "skin", "mass_ratio": 0.02 }, + { "drop": "sinew", "type": "bone", "mass_ratio": 0.00035 }, + { "drop": "bone", "type": "bone", "mass_ratio": 0.1 } + ] } ] diff --git a/data/mods/Magiclysm/items/weapons.json b/data/mods/Magiclysm/items/weapons.json new file mode 100644 index 0000000000000..9ece7743f7615 --- /dev/null +++ b/data/mods/Magiclysm/items/weapons.json @@ -0,0 +1,57 @@ +[ + { + "id": "lizardfolk_club", + "type": "GENERIC", + "name": "greatclub", + "category": "weapons", + "copy-from": "shillelagh", + "//": "A heavier version of the standard shillelagh (from melee.json) with a different description to match the lizardfolk lore. Not craftable, but wieldable if discovered.", + "description": "A stout knotty club with a large knob at the top. While it's very heavy, it's a very effective weapon in the hands of a strong opponent.", + "weight": "10 kg", + "volume": "8 L", + "price": 5000, + "flags": [ "UNBREAKABLE_MELEE", "ALWAYS_TWOHAND", "NO_PICKUP", "TRADER_AVOID", "SLOW_WIELD", "FIREWOOD", "NO_REPAIR" ], + "bashing": 22, + "to_hit": 1 + }, + { + "id": "lizardfolk_trident", + "type": "GENERIC", + "name": "wood trident", + "copy-from": "spear_forked", + "description": "A wooden melee weapon with a hand-forged steel forked spearhead attached to the end. It can be used for stabbing opponents either in close-range or as a thrown weapon, and in the right hands can also readily disarm opponents.", + "weight": "1650 g", + "to_hit": 2, + "techniques": [ "WBLOCK_2", "DEF_DISARM", "IMPALE" ], + "volume": "3 L", + "cutting": 29, + "flags": [ "SPEAR", "REACH_ATTACK", "NONCONDUCTIVE", "DURABLE_MELEE", "SHEATH_SPEAR" ], + "price": 15000 + }, + { + "id": "lizardfolk_javelin", + "type": "GENERIC", + "name": "barbed javelin", + "category": "weapons", + "copy-from": "javelin", + "//": "A barbed version of the standard javelin (from spears_and_polearms.json) with a different description to match the lizardfolk lore. Not craftable, but wieldable if discovered.", + "description": "This weapon measures about 3 feet in length and is fletched like an arrow for better accuracy. The business end of the javelin has wicked-looking barbs which could cause significant bleeding.", + "weight": "2500 g", + "volume": "2830 ml", + "flags": [ "SPEAR", "SHEATH_SPEAR", "JAVELIN", "TRADER_AVOID", "BLEED", "NO_REPAIR" ] + }, + { + "id": "lizardfolk_javelin_gun", + "type": "GUN", + "copy-from": "fake_item", + "name": "barbed javelin", + "description": "Fake gun that fires barbed javelins.", + "flags": [ "NEVER_JAMS", "NONCONDUCTIVE", "NO_REPAIR", "WATERPROOF_GUN", "NO_SALVAGE", "NO_UNLOAD" ], + "skill": "rifle", + "durability": 10, + "range": 10, + "dispersion": 10, + "body_parts": [ [ "TORSO", 1 ] ], + "ranged_damage": [ { "damage_type": "stab", "amount": 5 } ] + } +] diff --git a/data/mods/Magiclysm/monster_attacks.json b/data/mods/Magiclysm/monster_attacks.json new file mode 100644 index 0000000000000..3c59d0f081983 --- /dev/null +++ b/data/mods/Magiclysm/monster_attacks.json @@ -0,0 +1,30 @@ +[ + { + "type": "monster_attack", + "attack_type": "melee", + "id": "skewer", + "cooldown": 20, + "move_cost": 180, + "damage_max_instance": [ { "damage_type": "stab", "amount": 15, "armor_penetration": 15, "armor_multiplier": 0.5 } ], + "body_parts": [ [ "TORSO", 1 ] ], + "effects": [ { "id": "bleed", "duration": 100, "bp": "TORSO" }, { "id": "downed", "duration": 3 } ], + "hit_dmg_u": "The %1$s impales your %2$s with its trident!", + "hit_dmg_npc": "The %1$s impales 's %2$s with its trident!", + "no_dmg_msg_u": "The %1$s tries to impale your %2$s with its trident, but fails to penetrate your armor!", + "no_dmg_msg_npc": "The %1$s tries to impale 's %2$s with its trident, but fails to penetrate their armor!" + }, + { + "type": "monster_attack", + "attack_type": "melee", + "id": "crush", + "cooldown": 20, + "move_cost": 180, + "damage_max_instance": [ { "damage_type": "bash", "amount": 8 } ], + "effects": [ { "id": "downed", "duration": 3 } ], + "body_parts": [ [ "HEAD", 3 ], [ "EYES", 2 ], [ "MOUTH", 1 ], [ "ARM_L", 3 ], [ "ARM_R", 3 ], [ "TORSO", 4 ] ], + "hit_dmg_u": "The %1$s crushes your %2$s with its greatclub!", + "hit_dmg_npc": "The %1$s crushes 's %2$s with its greatclub!", + "no_dmg_msg_u": "The %1$s tries to crush your %2$s with its greatclub, but swings wide and stumbles.", + "no_dmg_msg_npc": "The %1$s tries to crush 's %2$s with its greatclub, but swings wide and stumbles." + } +] diff --git a/data/mods/Magiclysm/monster_factions.json b/data/mods/Magiclysm/monster_factions.json index d273d01c7133c..b9adba0930c22 100644 --- a/data/mods/Magiclysm/monster_factions.json +++ b/data/mods/Magiclysm/monster_factions.json @@ -6,11 +6,16 @@ { "type": "MONSTER_FACTION", "name": "dragon_black", - "friendly": [ "ooze" ] + "friendly": [ "ooze", "lizardfolk" ] }, { "type": "MONSTER_FACTION", "name": "ooze", - "friendly": [ "dragon_black" ] + "friendly": [ "dragon_black", "lizardfolk", "ooze" ] + }, + { + "type": "MONSTER_FACTION", + "name": "lizardfolk", + "friendly": [ "dragon_black", "ooze", "lizardfolk" ] } ] diff --git a/data/mods/Magiclysm/monsters/lizardfolk.json b/data/mods/Magiclysm/monsters/lizardfolk.json new file mode 100644 index 0000000000000..0906cc21a36af --- /dev/null +++ b/data/mods/Magiclysm/monsters/lizardfolk.json @@ -0,0 +1,140 @@ +[ + { + "id": "mon_lizardfolk_warrior", + "type": "MONSTER", + "name": "lizardfolk warrior", + "description": "A tall, powerful, reptilian humanoid with a muscular tail whose skin is covered in dark gray-green scales. They are tribal and tend to be found in caves and near water, especially in areas inhabited by dragons and wyrms. They aren't particularly hostile, though they don't care for outsiders and are highly dangerous when provoked. While they usually prefer to fight with their greatclubs, they are equally ferocious with their sharp teeth and claws.", + "default_faction": "lizardfolk", + "bodytype": "human", + "species": [ "LIZARDFOLK" ], + "size": "MEDIUM", + "volume": "80 L", + "weight": "100 kg", + "hp": 70, + "speed": 105, + "material": [ "flesh" ], + "symbol": "L", + "color": "green", + "aggression": 80, + "morale": 80, + "vision_day": 10, + "vision_night": 20, + "melee_skill": 4, + "melee_dice": 2, + "melee_dice_sides": 4, + "dodge": 5, + "armor_bash": 2, + "armor_cut": 12, + "armor_stab": 6, + "harvest": "lizardfolk", + "death_function": [ "NORMAL" ], + "death_drops": [ + { "item": "lizardfolk_club", "prob": 30 }, + { "item": "loincloth", "prob": 40 }, + { "item": "leather_belt", "prob": 20 }, + { "item": "bone_human", "prob": 10 } + ], + "special_attacks": [ [ "crush", 5 ], { "type": "bite", "cooldown": 5 } ], + "flags": [ + "SEES", + "HEARS", + "SMELLS", + "KEENNOSE", + "PATH_AVOID_DANGER_1", + "CLIMBS", + "GROUP_MORALE", + "LEATHER", + "SWIMS", + "ATTACKMON", + "PUSH_MON", + "SWARMS", + "BONES", + "CAN_OPEN_DOORS", + "NO_BREATHE" + ] + }, + { + "id": "mon_lizardfolk_hunter", + "type": "MONSTER", + "name": "lizardfolk hunter", + "description": "The hunter is a smaller lizardfolk than a warrior, but equally as deadly, with their lithe figures and accurate javelin throws.", + "copy-from": "mon_lizardfolk_warrior", + "symbol": "L", + "special_attacks": [ + { + "type": "gun", + "cooldown": 5, + "move_cost": 150, + "gun_type": "lizardfolk_barbed_dart", + "fake_skills": [ [ "gun", 8 ], [ "rifle", 8 ] ], + "fake_dex": 8, + "fake_per": 8, + "require_targeting_player": false, + "ranges": [ [ 2, 10, "DEFAULT" ] ], + "description": "The hunter hurls a barbed dart at you!" + }, + { "type": "bite", "cooldown": 5 } + ], + "death_drops": [ + { "item": "lizardfolk_javelin", "prob": 30 }, + { "item": "loincloth", "prob": 40 }, + { "item": "spearsling", "prob": 20 }, + { "item": "bone_human", "prob": 10 } + ] + }, + { + "id": "mon_lizardfolk_shaman", + "type": "MONSTER", + "name": "lizardfolk shaman", + "description": "Lizardfolk are very intelligent and cunning, but magical ability is a rare quality. Shamans are chosen from the tribe during childhood, when magical abilities mark the fate of the young tribesman. Not much is known about the initiation ritual they must undergo, but few survive the experience. Shamans are druidic spellcasters that can use the forces of nature to battle enemies, as well as summoning assistance when needed.", + "copy-from": "mon_lizardfolk_warrior", + "symbol": "L", + "hp": 80, + "melee_skill": 3, + "melee_dice": 2, + "melee_dice_sides": 6, + "special_attacks": [ { "type": "spell", "spell_id": "spell_shaman_base", "cooldown": 5 }, [ "scratch", 5 ] ], + "death_drops": { + "type": "item_group", + "subtype": "distribution", + "items": [ + { "group": "enchanted_small_items", "prob": 40 }, + { "group": "enchanted_melee_weapons_plus1", "prob": 20 }, + { "group": "enchanted_wands_lesser", "prob": 10 }, + { "item": "robe", "prob": 40 }, + { "item": "leather_belt", "prob": 20 } + ] + } + }, + { + "id": "mon_lizardfolk_chieftan", + "type": "MONSTER", + "name": "lizardfolk chieftan", + "description": "Among the lizardfolk, ambition is a rare quality. Chieftans earn their place by exhibiting unusually high levels of ambition, often mistaken by outsiders as excessive, brutal violence. This chief is the largest and strongest member of its tribe and carries a fierce trident to compliment its teeth and claws.", + "copy-from": "mon_lizardfolk_warrior", + "symbol": "L", + "hp": 200, + "melee_skill": 4, + "melee_dice": 3, + "melee_dice_sides": 3, + "special_attacks": [ [ "skewer", 2 ], { "type": "bite", "cooldown": 5 } ], + "death_drops": [ + { "item": "lizardfolk_trident", "prob": 30 }, + { "group": "lair_loot_generic", "prob": 40 }, + { "item": "spearsling", "prob": 20 }, + { "item": "bone_human", "prob": 10 } + ] + }, + { + "id": "mon_crocodile", + "type": "MONSTER", + "name": "crocodile", + "copy-from": "mon_gator", + "//": "A copy of the standard mon_gator (from reptile_amphibian.json) with a different description to match the lizardfolk lore. Lizardfolk Shamans are able to shapeshift into crocodile form.", + "description": "A once-and-future lizardfolk shaman, this large crocodile no longer has any hint of any humanoid characteristics and looks very, very dangerous.", + "default_faction": "lizardfolk", + "species": [ "LIZARDFOLK" ], + "symbol": "C", + "harvest": "lizardfolk" + } +] diff --git a/data/mods/Magiclysm/species.json b/data/mods/Magiclysm/species.json index e236565a49af4..c546b8ed1b82d 100644 --- a/data/mods/Magiclysm/species.json +++ b/data/mods/Magiclysm/species.json @@ -7,5 +7,11 @@ "type": "SPECIES", "id": "DRAGON", "anger_triggers": [ "HURT", "PLAYER_CLOSE", "PLAYER_WEAK", "STALK" ] + }, + { + "type": "SPECIES", + "id": "LIZARDFOLK", + "anger_triggers": [ "FRIEND_ATTACKED" ], + "fear_triggers": [ "FIRE" ] } ] From 3539cd58dca837cf227c4d16aa241171e43366eb Mon Sep 17 00:00:00 2001 From: curstwist <39442864+curstwist@users.noreply.github.com> Date: Fri, 6 Dec 2019 22:51:05 -0500 Subject: [PATCH 11/16] fix black dragon lair spawn --- data/json/overmap/special_locations.json | 5 +++++ data/mods/Magiclysm/worldgen/overmap_specials.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/data/json/overmap/special_locations.json b/data/json/overmap/special_locations.json index 0a515d2198231..f169a6bb4ac68 100644 --- a/data/json/overmap/special_locations.json +++ b/data/json/overmap/special_locations.json @@ -9,6 +9,11 @@ "id": "forest_without_trail", "terrains": [ "forest", "forest_thick" ] }, + { + "type": "overmap_location", + "id": "forest_with_swamp", + "terrains": [ "forest", "forest_thick", "forest_water" ] + }, { "type": "overmap_location", "id": "forest", diff --git a/data/mods/Magiclysm/worldgen/overmap_specials.json b/data/mods/Magiclysm/worldgen/overmap_specials.json index 4b2d64dbda181..81e38c066449b 100644 --- a/data/mods/Magiclysm/worldgen/overmap_specials.json +++ b/data/mods/Magiclysm/worldgen/overmap_specials.json @@ -45,7 +45,7 @@ { "point": [ 0, 1, -4 ], "overmap": "black_dragon_lair_z-4_SW_north" }, { "point": [ 1, 1, -4 ], "overmap": "black_dragon_lair_z-4_SE_north" } ], - "locations": [ "wilderness" ], + "locations": [ "forest_with_swamp" ], "city_distance": [ 20, -1 ], "city_sizes": [ 0, 20 ], "occurrences": [ 0, 0 ] From c95b0a8cb5c30d7c2cb43b96f85e45ab38f90881 Mon Sep 17 00:00:00 2001 From: Lil Shining Man <56778776+LilShiningMan@users.noreply.github.com> Date: Fri, 6 Dec 2019 21:29:19 -0800 Subject: [PATCH 12/16] Tobacco Products list added Added item group "Tobacco Products" and eliminated redundant item entries in various spawn lists --- data/json/itemgroups/gear.json | 6 +- data/json/itemgroups/item_groups.json | 92 ++++++++------------------- data/json/itemgroups/mansion.json | 12 +--- 3 files changed, 28 insertions(+), 82 deletions(-) diff --git a/data/json/itemgroups/gear.json b/data/json/itemgroups/gear.json index 5fc77023a9c4e..021013b7cefc6 100644 --- a/data/json/itemgroups/gear.json +++ b/data/json/itemgroups/gear.json @@ -14,11 +14,7 @@ [ "joint", 10 ], [ "ref_lighter", 50 ], [ "matches", 50 ], - [ "ecig", 15 ], - [ "chaw", 5 ], - [ "cigar", 5 ], - [ "advanced_ecig", 10 ], - [ "nicotine_liquid", 25 ], + { "group": "tobacco_products", "prob": 60 }, [ "permanent_marker", 10 ], [ "dog_whistle", 5 ], [ "multitool", 1 ], diff --git a/data/json/itemgroups/item_groups.json b/data/json/itemgroups/item_groups.json index 1b8b560a8b604..a4da5291b5873 100644 --- a/data/json/itemgroups/item_groups.json +++ b/data/json/itemgroups/item_groups.json @@ -202,14 +202,7 @@ { "item": "orangesoda", "prob": 15, "container-item": "bottle_plastic" }, { "item": "colamdew", "prob": 10, "container-item": "bottle_plastic" }, [ "sponge", 5 ], - [ "cig", 90 ], - [ "chaw", 20 ], - [ "cigar", 5 ], - [ "ecig", 10 ], - [ "advanced_ecig", 8 ], - [ "nicotine_liquid", 8 ], - [ "pipe_tobacco", 5 ], - [ "tobacco", 5 ], + { "group": "tobacco_products", "prob": 151 }, [ "weed", 10 ], [ "joint", 10 ], [ "seed_weed", 5 ], @@ -817,17 +810,10 @@ [ "backpack_hiking", 3 ], [ "clock", 10 ], [ "basket_laundry", 30 ], - [ "cig", 60 ], - [ "tobacco", 30 ], - [ "chaw", 20 ], - [ "cigar", 5 ], - [ "pipe_tobacco", 5 ], + { "group": "tobacco_products", "prob": 146 }, [ "weed", 15 ], [ "joint", 5 ], [ "razor_blade", 5 ], - [ "ecig", 10 ], - [ "advanced_ecig", 8 ], - [ "nicotine_liquid", 8 ], [ "weed", 20 ], [ "seed_weed", 15 ], [ "seed_tobacco", 5 ], @@ -1285,14 +1271,8 @@ "items": [ [ "aspirin", 85 ], [ "caffeine", 25 ], - [ "cig", 60 ], - [ "tobacco", 30 ], - [ "chaw", 40 ], - [ "cigar", 5 ], - [ "ecig", 10 ], + { "group": "tobacco_products", "prob": 161 }, [ "sponge", 10 ], - [ "advanced_ecig", 8 ], - [ "nicotine_liquid", 8 ], { "group": "ammo_pocket_batteries_full", "prob": 50 }, [ "l_enforcer_45", 4 ], [ "l_sp_45", 3 ], @@ -2881,10 +2861,7 @@ [ "recipe_augs", 8 ], [ "aspirin", 85 ], [ "junk_burrito", 25 ], - [ "cigar", 5 ], - [ "ecig", 10 ], - [ "advanced_ecig", 8 ], - [ "nicotine_liquid", 8 ], + { "group": "tobacco_products", "prob": 31 }, [ "glasses_eye", 90 ], [ "contacts", 15 ], [ "sunglasses", 90 ], @@ -2954,11 +2931,7 @@ [ "decoy_anarch", 10 ], [ "aspirin", 85 ], [ "maltballs", 30 ], - [ "cigar", 5 ], - [ "ecig", 10 ], - [ "advanced_ecig", 8 ], - [ "nicotine_liquid", 8 ], - [ "chaw", 10 ], + { "group": "tobacco_products", "prob": 151 }, [ "glasses_eye", 90 ], [ "contacts", 15 ], [ "sunglasses", 90 ], @@ -2987,9 +2960,6 @@ [ "bubblewrap", 50 ], [ "coffee_raw", 15 ], [ "usb_drive", 5 ], - [ "cig", 80 ], - [ "tobacco", 10 ], - [ "chaw", 20 ], [ "coat_rain", 50 ], [ "hood_rain", 10 ], [ "poncho", 15 ], @@ -3028,13 +2998,10 @@ [ "cookies", 60 ], [ "brownie", 60 ], [ "aspirin", 40 ], - [ "ecig", 20 ], - [ "chaw", 20 ], - [ "cig", 100 ], + { "group": "tobacco_products", "prob": 150 }, [ "gum", 100 ], [ "caff_gum", 20 ], [ "nic_gum", 20 ], - [ "tobacco", 10 ], [ "weed", 10 ], [ "joint", 10 ], [ "matches", 50 ], @@ -4606,14 +4573,7 @@ [ "inhaler", 14 ], [ "eyedrops", 20 ], [ "clock", 10 ], - [ "cig", 90 ], - [ "chaw", 20 ], - [ "cigar", 5 ], - [ "ecig", 10 ], - [ "advanced_ecig", 8 ], - [ "nicotine_liquid", 8 ], - [ "pipe_tobacco", 5 ], - [ "tobacco", 5 ], + { "group": "tobacco_products", "prob": 151 }, [ "weed", 10 ], [ "joint", 10 ], [ "seed_weed", 15 ], @@ -5066,12 +5026,7 @@ { "group": "softdrinks_canned", "prob": 290 }, [ "caffeine", 25 ], [ "maltballs", 30 ], - [ "cig", 90 ], - [ "ecig", 10 ], - [ "advanced_ecig", 8 ], - [ "nicotine_liquid", 8 ], - [ "chaw", 20 ], - [ "pipe_tobacco", 5 ], + { "group": "tobacco_products", "prob": 141 }, [ "weed", 10 ], [ "joint", 10 ], [ "seed_weed", 15 ], @@ -5618,11 +5573,7 @@ [ "iodine", 5 ], [ "prussian_blue", 5 ], [ "adrenaline_injector", 4 ], - [ "cig", 90 ], - [ "ecig", 10 ], - [ "advanced_ecig", 8 ], - [ "nicotine_liquid", 8 ], - [ "chaw", 30 ], + { "group": "tobacco_products", "prob": 146 }, [ "knife_combat", 14 ], [ "kukri", 2 ], [ "throwing_knife", 7 ], @@ -6206,10 +6157,7 @@ [ "matches", 8 ], [ "lighter", 10 ], [ "ref_lighter", 2 ], - [ "cig", 15 ], - [ "cigar", 2 ], - [ "ecig", 5 ], - [ "advanced_ecig", 1 ], + { "group": "tobacco_products", "prob": 26 }, [ "gum", 13 ], [ "glowstick", 2 ], [ "flashlight", 5 ], @@ -6338,11 +6286,7 @@ [ "pocket_firstaid", 10 ], [ "pocketwatch", 5 ], [ "wristwatch", 10 ], - [ "cigar", 5 ], - [ "ecig", 10 ], - [ "advanced_ecig", 8 ], - [ "nicotine_liquid", 8 ], - [ "chaw", 1 ], + { "group": "tobacco_products", "prob": 32 }, [ "ref_lighter", 1 ], [ "flask_hip", 1 ], [ "textbook_fireman", 10 ], @@ -6368,6 +6312,20 @@ [ "bag_body_bag", 5 ] ] }, + { + "type": "item_group", + "id": "tobacco_products", + "items": [ + [ "cig", 60 ], + [ "tobacco", 20 ], + [ "chaw", 20 ], + [ "cigar", 10 ], + [ "ecig", 10 ], + [ "advanced_ecig", 8 ], + [ "nicotine_liquid", 15 ], + [ "pipe_tobacco", 10 ] + ] + }, { "type": "item_group", "id": "rad_gear", diff --git a/data/json/itemgroups/mansion.json b/data/json/itemgroups/mansion.json index 353f90610d01a..84aebd6001746 100644 --- a/data/json/itemgroups/mansion.json +++ b/data/json/itemgroups/mansion.json @@ -1163,7 +1163,7 @@ [ "novel_pulp", 30 ], [ "mag_news", 30 ], [ "mag_tv", 30 ], - [ "cig", 30 ], + { "group": "tobacco_products", "prob": 50 }, [ "gum", 30 ], { "group": "vending_drink", "prob": 20 }, [ "mag_beauty", 20 ], @@ -1174,15 +1174,11 @@ [ "mp3", 10 ], [ "weeks_old_newspaper", 5 ], [ "newest_newspaper", 5 ], - [ "advanced_ecig", 5 ], [ "portable_game", 5 ], [ "cell_phone", 1 ], [ "smart_phone", 5 ], [ "phonebook", 5 ], [ "hairpin", 5 ], - [ "cigar", 5 ], - [ "chaw", 5 ], - [ "ecig", 5 ], { "group": "tinware", "prob": 5 }, [ "months_old_newspaper", 4 ], [ "one_year_old_newspaper", 3 ], @@ -1200,16 +1196,12 @@ { "item": "beer", "prob": 40, "container-item": "glass" }, { "group": "beer_selection", "prob": 40 }, { "group": "glass_of_wine", "prob": 40 }, - [ "cig", 30 ], { "group": "vending_drink", "prob": 20 }, [ "glass", 20 ], - [ "cigar", 20 ], - [ "ecig", 20 ], + { "group": "tobacco_products", "prob": 75 }, [ "money_bundle", 10 ], - [ "advanced_ecig", 5 ], [ "pretzels", 5 ], [ "chips", 5 ], - [ "chaw", 5 ], { "item": "cash_card", "prob": 1, "charges-min": 25000, "charges-max": 100000 } ] }, From ded70194753bfd23e8cef9b1f759a2c9a529b147 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Fri, 6 Dec 2019 21:46:58 -0800 Subject: [PATCH 13/16] Add vitamin documentation (#35920) --- doc/VITAMIN.md | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 doc/VITAMIN.md diff --git a/doc/VITAMIN.md b/doc/VITAMIN.md new file mode 100644 index 0000000000000..adc9224043311 --- /dev/null +++ b/doc/VITAMIN.md @@ -0,0 +1,66 @@ +## vitamin + +```JSON +{ + "id": "iron", + "type": "vitamin", + "vit_type": "vitamin", + "name": "Iron", + "excess": "hypervitaminosis", + "deficiency": "anemia", + "min": -12000, + "max": 3600, + "rate": "15 m", + "disease": [ [ -4800, -5600 ], [ -5601, -6400 ], [ -6401, -12000 ] ], + "disease_excess": [ [ 10, 19 ], [ 20, 29 ], [ 30, 40 ] ] +}, +``` +### `id` +Mandatory. The id of the vitamin. + +### `type` +Mandatory. Must be `vitamin`. + +### `vit_type` +The type of the vitamin. Valid values are: + +#### `vitamin` +When simplified nutrition is enabled, this vitamin will not be added to any items and any time the game attempts to retrieve it from the player it will give 0. +Only nutritional vitamins should have this type. + +#### `toxin` +This is some toxic chemical or component. This currently has no effect. + +#### `drug` +This is a drug. This currently has no effect. + +#### `counter` +This is a counter for something, that is neither a toxin, vitamin, or drug. This currently has no effect. + +### `name` +What the vitamin shows up as where vitamins are displayed, such as the vitamins display in the item menu. + +### `deficiency` +The id of an effect that is triggered by a deficiency of this vitamin. + +### `excess` +The id of an effect that is triggered by a excess of this vitamin. + +### `min` +The smallest amount of this vitamin that the player can have. + +### `max` +The highest amount of this vitamin that the avatar can have. + +### `rate` +How long it takes to lose one unit of this vitamin. + +### `disease` +What the thresholds of deficiency of this vitamin are. +Each pair in the list determines the start and end points of that tier of deficiency. +Each tier of deficiency corresponds to the intensity level of the effect defined in `deficiency`. + +### `disease_excess` +What the thresholds of excess of this vitamin are. +Each pair in the list determines the start and end points of that tier of excess. +Each tier of excess corresponds to the intensity level of the effect defined in `excess`. From cc32f2b9281847407e106e749a3901c86411163e Mon Sep 17 00:00:00 2001 From: Anton Burmistrov Date: Sat, 7 Dec 2019 09:50:23 +0400 Subject: [PATCH 14/16] Added NOCOLLIDE flag to crafting spots (#35923) --- data/json/furniture_and_terrain/furniture-fakes.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/json/furniture_and_terrain/furniture-fakes.json b/data/json/furniture_and_terrain/furniture-fakes.json index 7bd3baa8d2c56..057c71b14fb8b 100644 --- a/data/json/furniture_and_terrain/furniture-fakes.json +++ b/data/json/furniture_and_terrain/furniture-fakes.json @@ -23,14 +23,14 @@ "required_str": 0, "deconstruct": { "items": [ ] }, "bash": { "str_min": 0, "str_max": 0, "items": [ ] }, - "flags": [ "PLACE_ITEM", "TRANSPARENT", "EASY_DECONSTRUCT" ], + "flags": [ "PLACE_ITEM", "TRANSPARENT", "EASY_DECONSTRUCT", "NOCOLLIDE" ], "examine_action": "workbench", "workbench": { "multiplier": 0.7, "mass": 1000000, "volume": "1000L" } }, { "type": "furniture", "id": "f_no_item", - "//": "This is used in a hack to clear furniture with the keg iexamine of all items execept the stored liquid before usage.", + "//": "This is used in a hack to clear furniture with the keg iexamine of all items except the stored liquid before usage.", "name": "seeing this is a bug", "description": "Seeing this is a bug. If seen, please report and destroy.", "symbol": "#", From 36c3dc5b6290e189af887c20ae1a54749c695d2d Mon Sep 17 00:00:00 2001 From: Termineitor244 <53200489+Termineitor244@users.noreply.github.com> Date: Fri, 6 Dec 2019 23:51:17 -0600 Subject: [PATCH 15/16] Science ID cards as possible drop for zombies scientist (#35890) --- data/json/monsterdrops/zombie_lab.json | 1 + 1 file changed, 1 insertion(+) diff --git a/data/json/monsterdrops/zombie_lab.json b/data/json/monsterdrops/zombie_lab.json index a6106b371f9e0..46e5ab4e4542d 100644 --- a/data/json/monsterdrops/zombie_lab.json +++ b/data/json/monsterdrops/zombie_lab.json @@ -22,6 +22,7 @@ { "group": "textbooks", "prob": 25 } ] }, + { "item": "id_science", "prob": 5 }, { "item": "cash_card", "charges-min": 0, "charges-max": 50000 } ] }, From e0f74b7c319d9e2fa5090e746a6e4116ddad7684 Mon Sep 17 00:00:00 2001 From: Curtis Merrill Date: Sat, 7 Dec 2019 00:52:14 -0500 Subject: [PATCH 16/16] More name, weight, and volume updates (#35903) * Update insect_spider.json * Update marloss.json * Update mechsuits.json * Update mi-go.json * Update mutant.json * Update mi-go.json --- data/json/monsters/insect_spider.json | 154 +++++++++++++------------- data/json/monsters/marloss.json | 8 +- data/json/monsters/mechsuits.json | 12 +- data/json/monsters/mi-go.json | 26 ++--- data/json/monsters/mutant.json | 10 +- 5 files changed, 105 insertions(+), 105 deletions(-) diff --git a/data/json/monsters/insect_spider.json b/data/json/monsters/insect_spider.json index f75df896308f1..41d925dae76fb 100644 --- a/data/json/monsters/insect_spider.json +++ b/data/json/monsters/insect_spider.json @@ -2,14 +2,14 @@ { "id": "mon_skittering_plague", "type": "MONSTER", - "name": "skittering plague", + "name": { "str": "skittering plague" }, "description": "A giant infected roach, it has been feeding on the undead.", "default_faction": "roach", "bodytype": "insect", "species": [ "INSECT" ], "diff": 2, - "volume": "30000 ml", - "weight": 40750, + "volume": "30 L", + "weight": "40750 g", "hp": 30, "speed": 120, "material": [ "iflesh" ], @@ -39,14 +39,14 @@ { "id": "mon_plague_nymph", "type": "MONSTER", - "name": "plague nymph", + "name": { "str": "plague nymph" }, "description": "An infected mutant cockroach about the size of a rat.", "default_faction": "roach", "bodytype": "insect", "species": [ "INSECT", "ZOMBIE" ], "diff": 2, "volume": "750 ml", - "weight": 1000, + "weight": "1 kg", "hp": 3, "speed": 100, "material": [ "iflesh" ], @@ -70,14 +70,14 @@ { "id": "mon_plague_vector", "type": "MONSTER", - "name": "plague vector", + "name": { "str": "plague vector" }, "description": "This infected roach has been feeding on the undead and started to mutate chaotically. Extra limbs and growths sprout from its thorax.", "default_faction": "roach", "bodytype": "insect", "species": [ "INSECT" ], "diff": 2, - "volume": "30000 ml", - "weight": 40750, + "volume": "30 L", + "weight": "40750 g", "hp": 70, "speed": 100, "material": [ "iflesh" ], @@ -111,8 +111,8 @@ "default_faction": "roach", "bodytype": "insect", "species": [ "INSECT" ], - "volume": "30000 ml", - "weight": 40750, + "volume": "30 L", + "weight": "40750 g", "hp": 40, "speed": 100, "material": [ "iflesh" ], @@ -141,13 +141,13 @@ { "id": "mon_giant_cockroach_nymph", "type": "MONSTER", - "name": "giant cockroach nymph", + "name": { "str": "giant cockroach nymph" }, "description": "A baby mutant cockroach about the size of a rat.", "default_faction": "roach", "bodytype": "insect", "species": [ "INSECT" ], "volume": "750 ml", - "weight": 1000, + "weight": "1 kg", "hp": 10, "speed": 50, "material": [ "iflesh" ], @@ -177,8 +177,8 @@ "bodytype": "insect", "species": [ "INSECT" ], "diff": 2, - "volume": "30000 ml", - "weight": 40750, + "volume": "30 L", + "weight": "40750 g", "hp": 40, "speed": 100, "material": [ "iflesh" ], @@ -206,14 +206,14 @@ { "id": "mon_bee", "type": "MONSTER", - "name": "giant bee", + "name": { "str": "giant bee" }, "description": "With a stinger the size of a kitchen knife, this dog-sized insect's black and yellow markings warn you to leave it undisturbed.", "default_faction": "bee", "bodytype": "flying insect", "species": [ "INSECT" ], "diff": 2, - "volume": "30000 ml", - "weight": 40750, + "volume": "30 L", + "weight": "40750 g", "hp": 30, "speed": 140, "material": [ "iflesh" ], @@ -239,14 +239,14 @@ { "id": "mon_centipede_giant", "type": "MONSTER", - "name": "giant centipede", + "name": { "str": "giant centipede" }, "description": "A meter-long centipede with a menacing pair of pincers, moving swiftly on dozens of spindly legs.", "default_faction": "centipede", "bodytype": "insect", "species": [ "INSECT" ], "diff": 2, "volume": "62500 ml", - "weight": 81500, + "weight": "81500 g", "hp": 70, "speed": 140, "material": [ "iflesh" ], @@ -275,8 +275,8 @@ "default_faction": "dragonfly", "bodytype": "flying insect", "species": [ "INSECT" ], - "volume": "30000 ml", - "weight": 40750, + "volume": "30 L", + "weight": "40750 g", "hp": 70, "speed": 150, "material": [ "iflesh" ], @@ -306,8 +306,8 @@ "default_faction": "small_animal", "bodytype": "flying insect", "species": [ "INSECT" ], - "volume": "30000 ml", - "weight": 40750, + "volume": "30 L", + "weight": "40750 g", "hp": 25, "speed": 120, "material": [ "iflesh" ], @@ -330,14 +330,14 @@ { "id": "mon_mosquito_giant", "type": "MONSTER", - "name": "giant mosquito", + "name": { "str": "giant mosquito" }, "description": "An enormous mutant mosquito, fluttering erratically. Its face is dominated by a long, spear-tipped proboscis.", "default_faction": "mosquito", "bodytype": "flying insect", "species": [ "INSECT" ], "diff": 2, - "volume": "30000 ml", - "weight": 40750, + "volume": "30 L", + "weight": "40750 g", "hp": 20, "speed": 120, "material": [ "iflesh" ], @@ -359,14 +359,14 @@ { "id": "mon_spider_cellar_giant", "type": "MONSTER", - "name": "giant cellar spider", + "name": { "str": "giant cellar spider" }, "description": "A twitchy mutant brown spider, with a relatively small body and spindly long legs. Its smaller brethren are known for being agile, and for preying upon other spiders.", "default_faction": "spider_cellar", "bodytype": "spider", "species": [ "SPIDER" ], "diff": 2, - "volume": "30000 ml", - "weight": 40750, + "volume": "30 L", + "weight": "40750 g", "hp": 45, "speed": 150, "material": [ "iflesh" ], @@ -393,13 +393,13 @@ { "id": "mon_spider_cellar_giant_s", "type": "MONSTER", - "name": "immature giant cellar spider", + "name": { "str": "immature giant cellar spider" }, "description": "A newly-hatched giant cellar spider. Too small to possess much venom, but still quick and agile like an adult.", "default_faction": "spider_cellar", "bodytype": "spider", "species": [ "SPIDER" ], "volume": "750 ml", - "weight": 1000, + "weight": "1 kg", "hp": 23, "speed": 150, "material": [ "iflesh" ], @@ -425,14 +425,14 @@ { "id": "mon_spider_jumping_giant", "type": "MONSTER", - "name": "giant jumping spider", + "name": { "str": "giant jumping spider" }, "description": "A giant spider with big forelegs and two pairs of inquisitive-looking eyes. It can leap quite quickly, even into the treetops.", "default_faction": "spider_jumping", "bodytype": "spider", "species": [ "SPIDER" ], "diff": 2, - "volume": "30000 ml", - "weight": 40750, + "volume": "30 L", + "weight": "40750 g", "hp": 30, "speed": 100, "material": [ "iflesh" ], @@ -457,14 +457,14 @@ { "id": "mon_spider_trapdoor_giant", "type": "MONSTER", - "name": "giant trapdoor spider", + "name": { "str": "giant trapdoor spider" }, "description": "A gigantic spider with a bulbous thorax. It digs a deep underground burrow that serves as a pit to trap unwary prey.", "default_faction": "spider_trapdoor", "bodytype": "spider", "species": [ "SPIDER" ], "diff": 2, "volume": "62500 ml", - "weight": 81500, + "weight": "81500 g", "hp": 70, "speed": 110, "material": [ "iflesh" ], @@ -488,14 +488,14 @@ { "id": "mon_spider_web", "type": "MONSTER", - "name": "giant web spider", + "name": { "str": "giant web spider" }, "description": "A giant mutated grass spider, it waits for prey to become ensnared in the vast webs that it weaves between the trees.", "default_faction": "spider_web", "bodytype": "spider", "species": [ "SPIDER" ], "diff": 2, "volume": "62500 ml", - "weight": 81500, + "weight": "81500 g", "hp": 40, "speed": 110, "material": [ "iflesh" ], @@ -519,14 +519,14 @@ { "id": "mon_spider_fungus", "type": "MONSTER", - "name": "fungal spider", + "name": { "str": "fungal spider" }, "description": "The abdomen of this sickly looking giant spider is now home to many lumps of blooming fungi. It is leaving behind a trail of tainted secretions when the spider struggles to drag it along the ground.", "default_faction": "fungus", "bodytype": "spider", "species": [ "FUNGUS" ], "diff": 2, "volume": "62500 ml", - "weight": 81500, + "weight": "81500 g", "hp": 20, "speed": 60, "material": [ "iflesh" ], @@ -551,13 +551,13 @@ { "id": "mon_spider_web_s", "type": "MONSTER", - "name": "immature giant web spider", + "name": { "str": "immature giant web spider" }, "description": "A still immature giant grass spider. Too young to be venomous, or to walk proficiently for that matter", "default_faction": "spider_web", "bodytype": "spider", "species": [ "SPIDER" ], "volume": "750 ml", - "weight": 1000, + "weight": "1 kg", "hp": 20, "speed": 40, "material": [ "iflesh" ], @@ -581,14 +581,14 @@ { "id": "mon_spider_widow_giant", "type": "MONSTER", - "name": "giant black widow", + "name": { "str": "giant black widow" }, "description": "A giant mutated black widow spider. A highly venomous nightmare come to life.", "default_faction": "spider_widow", "bodytype": "spider", "species": [ "SPIDER" ], "diff": 2, - "volume": "30000 ml", - "weight": 40750, + "volume": "30 L", + "weight": "40750 g", "hp": 60, "speed": 90, "material": [ "iflesh" ], @@ -613,14 +613,14 @@ { "id": "mon_spider_widow_giant_s", "type": "MONSTER", - "name": "giant black widow spiderling", + "name": { "str": "giant black widow spiderling" }, "description": "The horrid spawn of a giant black widow spider. Even as a newborn, this foul creature knows only how to kill.", "default_faction": "spider_widow", "bodytype": "spider", "species": [ "SPIDER" ], "diff": 2, "volume": "750 ml", - "weight": 1000, + "weight": "1 kg", "hp": 30, "speed": 90, "material": [ "iflesh" ], @@ -645,14 +645,14 @@ { "id": "mon_spider_wolf_giant", "type": "MONSTER", - "name": "giant wolf spider", + "name": { "str": "giant wolf spider" }, "description": "A wolf spider mutated to about thirty times its normal size, it moves quickly and aggressively to catch and consume prey.", "default_faction": "spider_wolf", "bodytype": "spider", "species": [ "SPIDER" ], "diff": 2, "volume": "62500 ml", - "weight": 81500, + "weight": "81500 g", "hp": 40, "speed": 150, "material": [ "iflesh" ], @@ -677,14 +677,14 @@ { "id": "mon_wasp", "type": "MONSTER", - "name": "giant wasp", + "name": { "str": "giant wasp" }, "description": "A gigantic slender-bodied wasp with an evil-looking stinger protruding from its abdomen. Its exoskeleton glowers with ominous red markings.", "default_faction": "wasp", "bodytype": "flying insect", "species": [ "INSECT" ], "diff": 2, "volume": "62500 ml", - "weight": 81500, + "weight": "81500 g", "hp": 40, "speed": 150, "material": [ "iflesh" ], @@ -710,14 +710,14 @@ { "id": "mon_dermatik", "type": "MONSTER", - "name": "dermatik", + "name": { "str": "dermatik" }, "description": "A mutated wasp nearly the size of a cat, with a barbed ovipositor extruding from the abdomen.", "default_faction": "dermatik", "bodytype": "flying insect", "species": [ "INSECT" ], "diff": 2, "volume": "750 ml", - "weight": 1000, + "weight": "1 kg", "hp": 60, "speed": 110, "material": [ "iflesh" ], @@ -747,7 +747,7 @@ "species": [ "INSECT" ], "diff": 2, "volume": "750 ml", - "weight": 1000, + "weight": "1 kg", "hp": 10, "speed": 20, "material": [ "iflesh" ], @@ -768,13 +768,13 @@ { "id": "mon_ant", "type": "MONSTER", - "name": "giant ant", + "name": { "str": "giant ant" }, "description": "An enormous red ant covered in chitinous plates. It possesses a pair of wriggling antennae and vicious-looking mandibles.", "default_faction": "ant", "bodytype": "insect", "species": [ "INSECT" ], "volume": "62500 ml", - "weight": 81500, + "weight": "81500 g", "hp": 40, "speed": 100, "material": [ "iflesh" ], @@ -800,14 +800,14 @@ { "id": "mon_ant_acid", "type": "MONSTER", - "name": "giant acidic ant", + "name": { "str": "giant acidic ant" }, "description": "A monstrous brown ant with a swollen abdomen, that ends with a small orifice at the tip. Glistening liquid seems to drip out periodically.", "default_faction": "acid_ant", "bodytype": "insect", "species": [ "INSECT" ], "diff": 2, "volume": "62500 ml", - "weight": 81500, + "weight": "81500 g", "hp": 60, "speed": 100, "material": [ "iflesh" ], @@ -838,8 +838,8 @@ "default_faction": "acid_ant", "bodytype": "insect", "species": [ "INSECT" ], - "volume": "30000 ml", - "weight": 40750, + "volume": "30 L", + "weight": "40750 g", "hp": 20, "speed": 15, "material": [ "iflesh" ], @@ -859,14 +859,14 @@ { "id": "mon_ant_acid_queen", "type": "MONSTER", - "name": "acidic queen ant", + "name": { "str": "acidic queen ant" }, "description": "An enormous brown ant with an elongated, pulsating abdomen. Its orifice seems developed only for egg-laying rather than spraying acid like the rest of the colony, but it doesn't seem affected by the acrid liquid either.", "default_faction": "acid_ant", "bodytype": "insect", "species": [ "INSECT" ], "diff": 2, "volume": "92500 ml", - "weight": 120000, + "weight": "120 kg", "hp": 100, "speed": 60, "material": [ "iflesh" ], @@ -890,14 +890,14 @@ { "id": "mon_ant_acid_soldier", "type": "MONSTER", - "name": "acidic soldier ant", + "name": { "str": "acidic soldier ant" }, "description": "A massive woolly brown ant that towers over the worker ants with a giant head crest. Along with its huge mandibles, a corrosive liquid seeps from the end of its bloated abdomen.", "default_faction": "acid_ant", "bodytype": "insect", "species": [ "INSECT" ], "diff": 2, "volume": "62500 ml", - "weight": 81500, + "weight": "81500 g", "hp": 100, "speed": 100, "material": [ "iflesh" ], @@ -923,14 +923,14 @@ { "id": "mon_ant_fungus", "type": "MONSTER", - "name": "fungal ant", + "name": { "str": "fungal ant" }, "description": "Pale, sickly gray in color, this giant ant's cracked exoskeleton is barely held together by coils of fungus erupting from every joint in its body.", "default_faction": "fungus", "bodytype": "insect", "species": [ "FUNGUS" ], "diff": 2, "volume": "62500 ml", - "weight": 81500, + "weight": "81500 g", "hp": 40, "speed": 60, "material": [ "veggy" ], @@ -960,8 +960,8 @@ "default_faction": "ant", "bodytype": "insect", "species": [ "INSECT" ], - "volume": "30000 ml", - "weight": 40750, + "volume": "30 L", + "weight": "40750 g", "hp": 10, "speed": 15, "material": [ "iflesh" ], @@ -981,13 +981,13 @@ { "id": "mon_ant_queen", "type": "MONSTER", - "name": "queen ant", + "name": { "str": "queen ant" }, "description": "A colossal red ant with a bulging, bloated thorax. It moves slowly and deliberately, tending to nearby eggs and continually laying more.", "default_faction": "ant", "bodytype": "insect", "species": [ "INSECT" ], "volume": "92500 ml", - "weight": 120000, + "weight": "120 kg", "hp": 80, "speed": 40, "material": [ "iflesh" ], @@ -1010,13 +1010,13 @@ { "id": "mon_ant_soldier", "type": "MONSTER", - "name": "soldier ant", + "name": { "str": "soldier ant" }, "description": "A huge and hairy red ant almost twice the size of other giant ants. Bulging pincers extend from its jaws.", "default_faction": "ant", "bodytype": "insect", "species": [ "INSECT" ], "volume": "62500 ml", - "weight": 81500, + "weight": "81500 g", "hp": 80, "speed": 100, "material": [ "iflesh" ], @@ -1041,13 +1041,13 @@ { "id": "mon_locust", "type": "MONSTER", - "name": "giant locust", + "name": { "str": "giant locust" }, "description": "An overgrown locust. You don't think it'll eat you but it could cause massive damage to nearby plants.", "default_faction": "locust", "bodytype": "flying insect", "species": [ "INSECT" ], - "volume": "30000 ml", - "weight": 40750, + "volume": "30 L", + "weight": "40750 g", "hp": 30, "speed": 90, "material": [ "flesh" ], @@ -1075,13 +1075,13 @@ { "id": "mon_locust_nymph", "type": "MONSTER", - "name": "locust nymph", + "name": { "str": "locust nymph" }, "description": "A locust the size of a rabbit. You'd hate to think what a swarm of these could do.", "default_faction": "locust", "bodytype": "flying insect", "species": [ "INSECT" ], "volume": "750 ml", - "weight": 1000, + "weight": "1 kg", "hp": 5, "speed": 80, "material": [ "flesh" ], diff --git a/data/json/monsters/marloss.json b/data/json/monsters/marloss.json index eb9791f78a239..4bddf7ba93bd9 100644 --- a/data/json/monsters/marloss.json +++ b/data/json/monsters/marloss.json @@ -2,13 +2,13 @@ { "id": "mon_marloss_zealot_f", "type": "MONSTER", - "name": "marloss zealot", + "name": { "str": "marloss zealot" }, "description": "Her eyes lie vacant and spittle foams in her mouth, as she recites from the hymns in rapturous ecstasy.", "default_faction": "fungus", "bodytype": "human", "species": [ "FUNGUS" ], "volume": "62500 ml", - "weight": 81500, + "weight": "81500 g", "hp": 80, "speed": 100, "material": [ "flesh" ], @@ -33,13 +33,13 @@ { "id": "mon_marloss_zealot_m", "type": "MONSTER", - "name": "marloss zealot", + "name": { "str": "marloss zealot" }, "description": "His eyes lie vacant and spittle foams in his mouth, as he recites from the hymns in rapturous ecstasy.", "default_faction": "fungus", "bodytype": "human", "species": [ "FUNGUS" ], "volume": "62500 ml", - "weight": 81500, + "weight": "81500 g", "hp": 80, "speed": 100, "material": [ "flesh" ], diff --git a/data/json/monsters/mechsuits.json b/data/json/monsters/mechsuits.json index f9ab06eaea320..3007b8968743e 100644 --- a/data/json/monsters/mechsuits.json +++ b/data/json/monsters/mechsuits.json @@ -2,13 +2,13 @@ { "id": "mon_mech_recon", "type": "MONSTER", - "name": "X-03: 'Spectre' Recon Mech", + "name": { "str": "X-03: 'Spectre' Recon Mech" }, "description": "The Boeing-Daewoo RMES (Recon Mechanical Exoskeleton Suit), a recent acquisition by the US military, it was designed to be used in a scout-recon-sniper role, due to its mobility and integrated laser sniper rifle and suite of optics for target designation and battlefield awareness. It was not deployed before the Cataclysm hit, though there were a few prototypes in the field. You may be able to hack it to accept you as its pilot. Like all mech-suits it can act as a UPS from its large battery.", "default_faction": "mech_bot", "species": [ "ROBOT" ], "diff": 5, "volume": "700388 ml", - "weight": 700388, + "weight": "700388 g", "hp": 320, "speed": 120, "material": [ "superalloy" ], @@ -47,13 +47,13 @@ { "id": "mon_mech_combat", "type": "MONSTER", - "name": "X-02: 'Grunt' Combat Mech", + "name": { "str": "X-02: 'Grunt' Combat Mech" }, "description": "The Boeing-Daewoo CMES (Combat Mechanical Exoskeleton Suit), a recent acquisition by the US military, it was designed to be used in a fire support role, due to its fearsome integrated gatling laser. It was not deployed before the Cataclysm hit, though there were a few prototypes in the field. You may be able to hack it to accept you as its pilot. Like all mech-suits it can act as a UPS from its large battery.", "default_faction": "mech_bot", "species": [ "ROBOT" ], "diff": 5, "volume": "1480388 ml", - "weight": 1480388, + "weight": "1480388 g", "hp": 550, "speed": 65, "material": [ "superalloy" ], @@ -92,13 +92,13 @@ { "id": "mon_mech_lifter", "type": "MONSTER", - "name": "X-01: 'Jack' Lifting Mech", + "name": { "str": "X-01: 'Jack' Lifting Mech" }, "description": "The Boeing-Daewoo LMES (Lifting Mechanical Exoskeleton Suit), a recent acquisition by the US military, it was designed to be piloted by an operator to load and unload heavy material, and for limited combat support roles, it was not deployed before the Cataclysm hit, though there were a few prototypes in the field. You may be able to hack it to accept you as its pilot. Like all mech-suits it can act as a UPS from its large battery.", "default_faction": "mech_bot", "species": [ "ROBOT" ], "diff": 5, "volume": "1280388 ml", - "weight": 1280388, + "weight": "1280388 g", "hp": 400, "speed": 50, "material": [ "superalloy" ], diff --git a/data/json/monsters/mi-go.json b/data/json/monsters/mi-go.json index cd51de980b57d..a70c9c67d4d77 100644 --- a/data/json/monsters/mi-go.json +++ b/data/json/monsters/mi-go.json @@ -2,13 +2,13 @@ { "id": "mon_mi_go", "type": "MONSTER", - "name": "mi-go", + "name": { "str": "mi-go" }, "description": "This is an alien creature of uncertain origin. Its shapeless pink body bears numerous sets of paired appendages of unknown function, and a pair of ribbed, membranous wings which seem to be quite useless. Its odd, vaguely pyramid-shaped head bristles with numerous wavering antennae, and simply gazing upon the unnatural beast fills you with primordial dread.", "default_faction": "mi-go", "bodytype": "migo", "species": [ "NETHER" ], "volume": "92500 ml", - "weight": 120000, + "weight": "120 kg", "hp": 210, "speed": 120, "material": [ "flesh" ], @@ -48,14 +48,14 @@ { "id": "mon_mi_go_slaver", "type": "MONSTER", - "name": "mi-go slaver", + "name": { "str": "mi-go slaver" }, "description": "This is an alien creature of uncertain origin. Its shapeless pink body bears numerous sets of paired appendages of unknown function, and a pair of ribbed, membranous wings which seem to be quite useless. Its odd, vaguely pyramid-shaped head bristles with numerous wavering antennae, and simply gazing upon the unnatural beast fills you with primordial dread. It is carrying an oblong object that hums with an odd keening sound.", "default_faction": "mi-go", "bodytype": "migo", "species": [ "NETHER" ], "looks_like": "mon_mi_go", "volume": "92500 ml", - "weight": 120000, + "weight": "120 kg", "hp": 240, "speed": 120, "material": [ "flesh" ], @@ -96,14 +96,14 @@ { "id": "mon_mi_go_surgeon", "type": "MONSTER", - "name": "mi-go surgeon", + "name": { "str": "mi-go surgeon" }, "description": "This mi-go has a slender body with snaking carapace along it, and even more paired clawed appendages. Its claws are smaller and more delicate looking, but that does not make them less unnerving.", "default_faction": "mi-go", "bodytype": "migo", "species": [ "NETHER" ], "looks_like": "mon_mi_go", "volume": "92500 ml", - "weight": 110000, + "weight": "110 kg", "hp": 160, "speed": 120, "material": [ "flesh" ], @@ -143,14 +143,14 @@ { "id": "mon_mi_go_guard", "type": "MONSTER", - "name": "mi-go guard", + "name": { "str": "mi-go guard" }, "description": "This, like the more common mi-go, is an alien creature; this one is more heavily armoured. Its trunk is a shapeless mass of strange flesh encased in an iridescent carapace, from which sprout several appendages terminating in what appear to be devices of some sort. Its pyramidal head is encrusted in barnacle-like armor, aside from the bristling antennae that serve as its - you must assume sensory devices and mouth.", "default_faction": "mi-go", "bodytype": "migo", "species": [ "NETHER" ], "looks_like": "mon_mi_go", "volume": "98500 ml", - "weight": 190000, + "weight": "190 kg", "hp": 350, "speed": 110, "material": [ "flesh" ], @@ -194,14 +194,14 @@ { "id": "mon_mi_go_myrmidon", "type": "MONSTER", - "name": "mi-go myrmidon", + "name": { "str": "mi-go myrmidon" }, "description": "This creature resembles the smaller mi-go like a grizzly bear resembles a human. Its enormous, thick body is covered in an iridescent segmented carapace, like a scarab crossed with an isopod. It boasts several pairs of deadly looking claws and other appendages, and it moves with a strange, slow grace, like an otherworldly dancer. It actually appears to be carrying weaponry.", "default_faction": "mi-go", "bodytype": "migo", "species": [ "NETHER" ], "looks_like": "mon_mi_go", - "volume": "875000 ml", - "weight": 260000, + "volume": "875 L", + "weight": "260 kg", "hp": 610, "speed": 80, "material": [ "flesh" ], @@ -244,14 +244,14 @@ { "id": "mon_mi_go_scout", "type": "MONSTER", - "name": "mi-go scout", + "name": { "str": "mi-go scout" }, "description": "This slender mi-go is a little smaller than most others of its kind. It has a weird oblong thing attached to the center of its body with some sort of a diaphragm or a membrane on the end. The thing seems like an integral part of the mi-go, and all its appendages are supporting it to prevent swaying.", "default_faction": "mi-go", "bodytype": "migo", "species": [ "NETHER" ], "looks_like": "mon_mi_go", "volume": "80500 ml", - "weight": 90000, + "weight": "90 kg", "hp": 200, "speed": 150, "material": [ "flesh" ], diff --git a/data/json/monsters/mutant.json b/data/json/monsters/mutant.json index 0390c6f8c28ea..7adccc8eafc4b 100644 --- a/data/json/monsters/mutant.json +++ b/data/json/monsters/mutant.json @@ -2,13 +2,13 @@ { "id": "mon_mutant_experimental", "type": "MONSTER", - "name": "experimental mutant", + "name": { "str": "experimental mutant" }, "description": "A deformed amalgamation of man and animal. Grotesque humanoid covered in fur and a torn jumpsuit. The sinister fangs, claws and the look of insanity in his pale yellow eyes are a testament to that he lost all of his humanity.", "default_faction": "factionless", "bodytype": "human", "species": [ "MUTANT" ], "volume": "62500 ml", - "weight": 81500, + "weight": "81500 g", "hp": 150, "speed": 100, "material": [ "flesh" ], @@ -56,11 +56,11 @@ { "id": "mon_mutant_evolved", "type": "MONSTER", - "name": "evolved mutant", + "name": { "str": "evolved mutant" }, "description": "A towering beast that is neither human nor animal anymore. A malformed, huge creature covered in thick fur and the torn bottom part of a jumpsuit. The sinister fangs, claws and the look of insanity in his pale yellow eyes are a testament to that he lost all of his humanity.", "copy-from": "mon_mutant_experimental", - "volume": "875000 ml", - "weight": 200000, + "volume": "875 L", + "weight": "200 kg", "hp": 300, "speed": 110, "aggression": 100,