void item_comp::load( JsonArray &ja ) { JsonArray comp = ja.next_array(); type = comp.get_string( 0 ); count = comp.get_int( 1 ); size_t handled = 2; while( comp.size() > handled ) { const std::string &flag = comp.get_string( handled++ ); if( flag == "NO_RECOVER" ) { recoverable = false; } else if( flag == "LIST" ) { requirement = true; } } if( count <= 0 ) { ja.throw_error( "item count must be a positive number" ); } }
void mtype::add_special_attacks( JsonObject &jo, const std::string &member, const std::string &src ) { if( !jo.has_array( member ) ) { return; } JsonArray outer = jo.get_array( member ); while( outer.has_more() ) { if( outer.test_array() ) { add_special_attack( outer.next_array(), src ); } else if( outer.test_object() ) { add_special_attack( outer.next_object(), src ); } else { outer.throw_error( "array element is neither array nor object." ); } } }
void npc_class::load( JsonObject &jo, const std::string & ) { mandatory( jo, was_loaded, "name", name, translated_string_reader ); mandatory( jo, was_loaded, "job_description", job_description, translated_string_reader ); optional( jo, was_loaded, "common", common, true ); bonus_str = load_distribution( jo, "bonus_str" ); bonus_dex = load_distribution( jo, "bonus_dex" ); bonus_int = load_distribution( jo, "bonus_int" ); bonus_per = load_distribution( jo, "bonus_per" ); optional( jo, was_loaded, "shopkeeper_item_group", shopkeeper_item_group, "EMPTY_GROUP" ); optional( jo, was_loaded, "worn_override", worn_override ); optional( jo, was_loaded, "carry_override", carry_override ); optional( jo, was_loaded, "weapon_override", weapon_override ); if( jo.has_array( "traits" ) ) { JsonArray jarr = jo.get_array( "traits" ); while( jarr.has_more() ) { JsonArray jarr_in = jarr.next_array(); traits[ trait_id( jarr_in.get_string( 0 ) ) ] = jarr_in.get_int( 1 ); } } if( jo.has_array( "skills" ) ) { JsonArray jarr = jo.get_array( "skills" ); while( jarr.has_more() ) { JsonObject skill_obj = jarr.next_object(); auto skill_ids = skill_obj.get_tags( "skill" ); if( skill_obj.has_object( "level" ) ) { distribution dis = load_distribution( skill_obj, "level" ); for( const auto &sid : skill_ids ) { skills[ skill_id( sid ) ] = dis; } } else { distribution dis = load_distribution( skill_obj, "bonus" ); for( const auto &sid : skill_ids ) { bonus_skills[ skill_id( sid ) ] = dis; } } } } }
void requirements::load_obj_list(JsonArray &jsarr, std::vector< std::vector<T> > &objs) { while (jsarr.has_more()) { if(jsarr.test_array()) { std::vector<T> choices; JsonArray ja = jsarr.next_array(); while (ja.has_more()) { choices.push_back(T()); choices.back().load(ja); } if( !choices.empty() ) { objs.push_back( choices ); } } else { // tool qualities don't normally use a list of alternatives // each quality is mandatory. objs.push_back(std::vector<T>(1)); objs.back().back().load(jsarr); } } }
void mutation_branch::load_trait_group( JsonArray &entries, const trait_group::Trait_group_tag &gid, const bool is_collection ) { Trait_group &tg = make_group_or_throw( gid, is_collection ); while( entries.has_more() ) { // Backwards-compatibility with old format ["TRAIT", 100] if( entries.test_array() ) { JsonArray subarr = entries.next_array(); trait_id id( subarr.get_string( 0 ) ); std::unique_ptr<Trait_creation_data> ptr( new Single_trait_creator( id, subarr.get_int( 1 ) ) ); tg.add_entry( ptr ); // Otherwise load new format {"trait": ... } or {"group": ...} } else { JsonObject subobj = entries.next_object(); add_entry( tg, subobj ); } } }
void MonsterGenerator::load_special_attacks(mtype *m, JsonObject &jo, std::string member) { m->sp_attack.clear(); // make sure we're running with m->sp_freq.clear(); // everything cleared if (jo.has_array(member)) { JsonArray outer = jo.get_array(member); while (outer.has_more()) { JsonArray inner = outer.next_array(); if ( attack_map.find(inner.get_string(0)) != attack_map.end() ) { m->sp_attack.push_back(attack_map[inner.get_string(0)]); m->sp_freq.push_back(inner.get_int(1)); } else { inner.throw_error("Invalid special_attacks"); } } } if (m->sp_attack.empty()) { m->sp_attack.push_back(attack_map["NONE"]); m->sp_freq.push_back(0); } }
void game::load_monitem(JsonObject &jo) { std::vector<std::string> tmp_keys; std::vector<items_location_and_chance> tmp_items; std::string mkey=""; if ( jo.has_string("id") ) { tmp_keys.push_back( jo.get_string("id") ); } else if ( jo.has_array("id") ) { jo.read("id", tmp_keys); } else { jo.throw_error("monitems: requires \"id\": \"monster_id\" or \"id\": [ \"multiple\", \"monster_ids\" ]"); } if ( ! jo.has_array("item_groups") ) { jo.throw_error("monitems: requires \"item_groups\": [ [ \"group_one\", (chance) ], ... ]"); } JsonArray ja = jo.get_array("item_groups"); JsonArray ga; while ( ja.has_more() ) { ga = ja.next_array(); if ( ! ga.has_string(0) || ! ga.has_number(1) ) { jo.throw_error("monitems: item_groups must contain arrays of [ \"string\", number ]"); } tmp_items.push_back( items_location_and_chance( ga.get_string(0), ga.get_int(1) ) ); } for( size_t i = 0; i < tmp_keys.size(); ++i ) { std::map<std::string, std::vector <items_location_and_chance> >::iterator it = monitems.find( tmp_keys[i] ); if ( it == monitems.end() ) { monitems[ tmp_keys[i] ] = tmp_items; } else { it->second.insert( it->second.end(), tmp_items.begin(), tmp_items.end() ); } } }
void load_construction(JsonObject &jo) { construction *con = new construction; JsonArray temp; con->description = _(jo.get_string("description").c_str()); con->difficulty = jo.get_int("difficulty"); con->time = jo.get_int("time"); temp = jo.get_array("tools"); while (temp.has_more()) { std::vector<component> tool_choices; JsonArray ja = temp.next_array(); while (ja.has_more()) { std::string name = ja.next_string(); tool_choices.push_back(component(name, 1)); } con->tools.push_back(tool_choices); } temp = jo.get_array("components"); while (temp.has_more()) { std::vector<component> comp_choices; JsonArray ja = temp.next_array(); while (ja.has_more()) { JsonArray comp = ja.next_array(); std::string name = comp.get_string(0); int quant = comp.get_int(1); comp_choices.push_back(component(name, quant)); } con->components.push_back(comp_choices); } con->pre_terrain = jo.get_string("pre_terrain", ""); if (con->pre_terrain.size() > 1 && con->pre_terrain[0] == 'f' && con->pre_terrain[1] == '_') { con->pre_is_furniture = true; } else { con->pre_is_furniture = false; } con->post_terrain = jo.get_string("post_terrain", ""); if (con->post_terrain.size() > 1 && con->post_terrain[0] == 'f' && con->post_terrain[1] == '_') { con->post_is_furniture = true; } else { con->post_is_furniture = false; } con->pre_flags = jo.get_tags("pre_flags"); std::string prefunc = jo.get_string("pre_special", ""); if (prefunc == "check_empty") { con->pre_special = &construct::check_empty; } else if (prefunc == "check_support") { con->pre_special = &construct::check_support; } else { // should probably print warning if not "" con->pre_special = &construct::check_nothing; } std::string postfunc = jo.get_string("post_special", ""); if (postfunc == "done_tree") { con->post_special = &construct::done_tree; } else if (postfunc == "done_trunk_log") { con->post_special = &construct::done_trunk_log; } else if (postfunc == "done_trunk_plank") { con->post_special = &construct::done_trunk_plank; } else if (postfunc == "done_vehicle") { con->post_special = &construct::done_vehicle; } else if (postfunc == "done_deconstruct") { con->post_special = &construct::done_deconstruct; } else { // ditto, should probably warn here con->post_special = &construct::done_nothing; } con->id = constructions.size(); constructions.push_back(con); constructions_by_desc[con->description].push_back(con); }
void mutation_branch::load( JsonObject &jsobj ) { const std::string id = jsobj.get_string( "id" ); mutation_branch &new_mut = mutation_data[id]; JsonArray jsarr; new_mut.name = _(jsobj.get_string("name").c_str()); new_mut.description = _(jsobj.get_string("description").c_str()); new_mut.points = jsobj.get_int("points"); new_mut.visibility = jsobj.get_int("visibility", 0); new_mut.ugliness = jsobj.get_int("ugliness", 0); new_mut.startingtrait = jsobj.get_bool("starting_trait", false); new_mut.mixed_effect = jsobj.get_bool("mixed_effect", false); new_mut.activated = jsobj.get_bool("active", false); new_mut.starts_active = jsobj.get_bool("starts_active", false); new_mut.destroys_gear = jsobj.get_bool("destroys_gear", false); new_mut.allow_soft_gear = jsobj.get_bool("allow_soft_gear", false); new_mut.cost = jsobj.get_int("cost", 0); new_mut.cooldown = jsobj.get_int("time",0); new_mut.hunger = jsobj.get_bool("hunger",false); new_mut.thirst = jsobj.get_bool("thirst",false); new_mut.fatigue = jsobj.get_bool("fatigue",false); new_mut.valid = jsobj.get_bool("valid", true); new_mut.purifiable = jsobj.get_bool("purifiable", true); for( auto & s : jsobj.get_string_array( "initial_ma_styles" ) ) { new_mut.initial_ma_styles.push_back( matype_id( s ) ); } JsonArray bodytemp_array = jsobj.get_array( "bodytemp_modifiers" ); if( bodytemp_array.has_more() ) { new_mut.bodytemp_min = bodytemp_array.get_int( 0 ); new_mut.bodytemp_max = bodytemp_array.get_int( 1 ); } new_mut.bodytemp_sleep = jsobj.get_int( "bodytemp_sleep", 0 ); new_mut.threshold = jsobj.get_bool("threshold", false); new_mut.profession = jsobj.get_bool("profession", false); auto vr = jsobj.get_array( "vitamin_rates" ); while( vr.has_more() ) { auto pair = vr.next_array(); new_mut.vitamin_rates[ vitamin_id( pair.get_string( 0 ) ) ] = pair.get_int( 1 ); } load_mutation_mods(jsobj, "passive_mods", new_mut.mods); /* Not currently supported due to inability to save active mutation state load_mutation_mods(jsobj, "active_mods", new_mut.mods); */ new_mut.prereqs = jsobj.get_string_array( "prereqs" ); // Helps to be able to have a trait require more than one other trait // (Individual prereq-lists are "OR", not "AND".) // Traits shoud NOT appear in both lists for a given mutation, unless // you want that trait to satisfy both requirements. // These are additional to the first list. new_mut.prereqs2 = jsobj.get_string_array( "prereqs2" ); // Dedicated-purpose prereq slot for Threshold mutations // Stuff like Huge might fit in more than one mutcat post-threshold, so yeah new_mut.threshreq = jsobj.get_string_array( "threshreq" ); new_mut.cancels = jsobj.get_string_array( "cancels" ); new_mut.replacements = jsobj.get_string_array( "changes_to" ); new_mut.additions = jsobj.get_string_array( "leads_to" ); new_mut.flags = jsobj.get_tags( "flags" ); jsarr = jsobj.get_array("category"); while (jsarr.has_more()) { std::string s = jsarr.next_string(); new_mut.category.push_back(s); mutations_category[s].push_back(id); } jsarr = jsobj.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); tripoint protect = tripoint(ignored, neutral, good); new_mut.protection[get_body_part_token( part_id )] = protect; } jsarr = jsobj.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(); new_mut.encumbrance_always[get_body_part_token( part_id )] = enc; } jsarr = jsobj.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(); new_mut.encumbrance_covered[get_body_part_token( part_id )] = enc; } jsarr = jsobj.get_array("restricts_gear"); while( jsarr.has_more() ) { new_mut.restricts_gear.insert( get_body_part_token( jsarr.next_string() ) ); } jsarr = jsobj.get_array( "armor" ); while( jsarr.has_more() ) { JsonObject jo = jsarr.next_object(); auto parts = jo.get_tags( "parts" ); std::set<body_part> bps; for( const std::string &part_string : parts ) { if( part_string == "ALL" ) { // Shorthand, since many muts protect whole body for( size_t i = 0; i < num_bp; i++ ) { bps.insert( static_cast<body_part>( i ) ); } } else { bps.insert( get_body_part_token( part_string ) ); } } resistances res = load_resistances_instance( jo ); for( body_part bp : bps ) { new_mut.armor[ bp ] = res; } } }
void mutation_branch::load( JsonObject &jo, const std::string & ) { mandatory( jo, was_loaded, "id", id ); mandatory( jo, was_loaded, "name", raw_name, translated_string_reader ); mandatory( jo, was_loaded, "description", raw_desc, translated_string_reader ); mandatory( jo, was_loaded, "points", points ); optional( jo, was_loaded, "visibility", visibility, 0 ); optional( jo, was_loaded, "ugliness", ugliness, 0 ); optional( jo, was_loaded, "starting_trait", startingtrait, false ); optional( jo, was_loaded, "mixed_effect", mixed_effect, false ); optional( jo, was_loaded, "active", activated, false ); optional( jo, was_loaded, "starts_active", starts_active, false ); optional( jo, was_loaded, "destroys_gear", destroys_gear, false ); optional( jo, was_loaded, "allow_soft_gear", allow_soft_gear, false ); optional( jo, was_loaded, "cost", cost, 0 ); optional( jo, was_loaded, "time", cooldown, 0 ); optional( jo, was_loaded, "hunger", hunger, false ); optional( jo, was_loaded, "thirst", thirst, false ); optional( jo, was_loaded, "fatigue", fatigue, false ); optional( jo, was_loaded, "valid", valid, true ); optional( jo, was_loaded, "purifiable", purifiable, true ); if( jo.has_object( "spawn_item" ) ) { auto si = jo.get_object( "spawn_item" ); optional( si, was_loaded, "type", spawn_item ); optional( si, was_loaded, "message", raw_spawn_item_message ); } if( jo.has_object( "ranged_mutation" ) ) { auto si = jo.get_object( "ranged_mutation" ); optional( si, was_loaded, "type", ranged_mutation ); optional( si, was_loaded, "message", raw_ranged_mutation_message ); } optional( jo, was_loaded, "initial_ma_styles", initial_ma_styles ); if( jo.has_array( "bodytemp_modifiers" ) ) { auto bodytemp_array = jo.get_array( "bodytemp_modifiers" ); bodytemp_min = bodytemp_array.get_int( 0 ); bodytemp_max = bodytemp_array.get_int( 1 ); } optional( jo, was_loaded, "bodytemp_sleep", bodytemp_sleep, 0 ); optional( jo, was_loaded, "threshold", threshold, false ); optional( jo, was_loaded, "profession", profession, false ); 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(); 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(); std::map<vitamin_id, double> 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(); vit.emplace( vitamin_id( vitamins.get_string( 0 ) ), vitamins.get_float( 1 ) ); } // assign the inner vitamin map to the material_id key vitamin_absorb_multi.emplace( material_id( pair.get_string( 0 ) ), vit ); } optional( jo, was_loaded, "healing_awake", healing_awake, 0.0f ); optional( jo, was_loaded, "healing_resting", healing_resting, 0.0f ); optional( jo, was_loaded, "hp_modifier", hp_modifier, 0.0f ); optional( jo, was_loaded, "hp_modifier_secondary", hp_modifier_secondary, 0.0f ); optional( jo, was_loaded, "hp_adjustment", hp_adjustment, 0.0f ); optional( jo, was_loaded, "stealth_modifier", stealth_modifier, 0.0f ); optional( jo, was_loaded, "str_modifier", str_modifier, 0.0f ); optional( jo, was_loaded, "dodge_modifier", dodge_modifier, 0.0f ); optional( jo, was_loaded, "speed_modifier", speed_modifier, 1.0f ); optional( jo, was_loaded, "movecost_modifier", movecost_modifier, 1.0f ); optional( jo, was_loaded, "movecost_flatground_modifier", movecost_flatground_modifier, 1.0f ); optional( jo, was_loaded, "movecost_obstacle_modifier", movecost_obstacle_modifier, 1.0f ); optional( jo, was_loaded, "attackcost_modifier", attackcost_modifier, 1.0f ); optional( jo, was_loaded, "max_stamina_modifier", max_stamina_modifier, 1.0f ); optional( jo, was_loaded, "weight_capacity_modifier", weight_capacity_modifier, 1.0f ); optional( jo, was_loaded, "hearing_modifier", hearing_modifier, 1.0f ); optional( jo, was_loaded, "noise_modifier", noise_modifier, 1.0f ); optional( jo, was_loaded, "metabolism_modifier", metabolism_modifier, 0.0f ); optional( jo, was_loaded, "thirst_modifier", thirst_modifier, 0.0f ); optional( jo, was_loaded, "fatigue_modifier", fatigue_modifier, 0.0f ); optional( jo, was_loaded, "fatigue_regen_modifier", fatigue_regen_modifier, 0.0f ); optional( jo, was_loaded, "stamina_regen_modifier", stamina_regen_modifier, 0.0f ); optional( jo, was_loaded, "overmap_sight", overmap_sight, 0.0f ); optional( jo, was_loaded, "overmap_multiplier", overmap_multiplier, 1.0f ); if( jo.has_object( "social_modifiers" ) ) { JsonObject sm = jo.get_object( "social_modifiers" ); social_mods = load_mutation_social_mods( sm ); } load_mutation_mods( jo, "passive_mods", mods ); /* Not currently supported due to inability to save active mutation state load_mutation_mods(jsobj, "active_mods", new_mut.mods); */ optional( jo, was_loaded, "prereqs", prereqs ); optional( jo, was_loaded, "prereqs2", prereqs2 ); optional( jo, was_loaded, "threshreq", threshreq ); optional( jo, was_loaded, "cancels", cancels ); optional( jo, was_loaded, "changes_to", replacements ); optional( jo, was_loaded, "leads_to", additions ); optional( jo, was_loaded, "flags", flags ); optional( jo, was_loaded, "types", types ); auto jsarr = jo.get_array( "category" ); while( jsarr.has_more() ) { std::string s = jsarr.next_string(); category.push_back( s ); mutations_category[s].push_back( trait_id( id ) ); } 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 ); 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(); 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(); 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() ) ); } jsarr = jo.get_array( "armor" ); while( jsarr.has_more() ) { JsonObject jo = jsarr.next_object(); auto parts = jo.get_tags( "parts" ); std::set<body_part> bps; for( const std::string &part_string : parts ) { if( part_string == "ALL" ) { // Shorthand, since many mutations protect whole body bps.insert( all_body_parts.begin(), all_body_parts.end() ); } else { bps.insert( get_body_part_token( part_string ) ); } } resistances res = load_resistances_instance( jo ); for( body_part bp : bps ) { armor[ bp ] = res; } } 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 ) ); } } else if( jo.has_object( "attacks" ) ) { JsonObject attack = jo.get_object( "attacks" ); attacks_granted.emplace_back( load_mutation_attack( attack ) ); } }
void gun_actor::load_internal( JsonObject &obj, const std::string & ) { gun_type = obj.get_string( "gun_type" ); 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(); fake_skills[skill_id( cur.get_string( 0 ) )] = cur.get_int( 1 ); } } obj.read( "fake_str", fake_str ); obj.read( "fake_dex", fake_dex ); 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(); if( mode.size() < 2 || mode.get_int( 0 ) > mode.get_int( 1 ) ) { obj.throw_error( "incomplete or invalid range specified", "ranges" ); } ranges.emplace( std::make_pair<int, int>( mode.get_int( 0 ), mode.get_int( 1 ) ), gun_mode_id( mode.size() > 2 ? mode.get_string( 2 ) : "" ) ); } obj.read( "max_ammo", max_ammo ); obj.read( "move_cost", move_cost ); if( obj.read( "description", description ) ) { description = _( description ); } if( obj.read( "failure_msg", failure_msg ) ) { failure_msg = _( failure_msg ); } if( obj.read( "no_ammo_sound", no_ammo_sound ) ) { no_ammo_sound = _( no_ammo_sound ); } else { no_ammo_sound = _( "Click." ); } obj.read( "targeting_cost", targeting_cost ); obj.read( "require_targeting_player", require_targeting_player ); obj.read( "require_targeting_npc", require_targeting_npc ); obj.read( "require_targeting_monster", require_targeting_monster ); obj.read( "targeting_timeout", targeting_timeout ); obj.read( "targeting_timeout_extend", targeting_timeout_extend ); if( obj.read( "targeting_sound", targeting_sound ) ) { targeting_sound = _( targeting_sound ); } else { targeting_sound = _( "Beep." ); } obj.read( "targeting_volume", targeting_volume ); obj.get_bool( "laser_lock", laser_lock ); obj.read( "require_sunlight", require_sunlight ); }
void item_comp::load( JsonArray &ja ) { JsonArray comp = ja.next_array(); type = comp.get_string( 0 ); count = comp.get_int( 1 ); }