diff --git a/build-scripts/get_all_mods.py b/build-scripts/get_all_mods.py index 1bd473299f718..6072b78d68031 100755 --- a/build-scripts/get_all_mods.py +++ b/build-scripts/get_all_mods.py @@ -11,8 +11,7 @@ mods_this_time = [] exclusions = [ - # #74443 - incompatibility between mindovermatter and aftershock due to bug - ('mindovermatter', 'aftershock') + # Tuple of (mod_id, mod_id) - these two mods will be incompatible ] diff --git a/data/json/effects_on_condition/nether_eocs/portal_storm_effect_on_condition.json b/data/json/effects_on_condition/nether_eocs/portal_storm_effect_on_condition.json index d28c093da671d..8ce678af9100c 100644 --- a/data/json/effects_on_condition/nether_eocs/portal_storm_effect_on_condition.json +++ b/data/json/effects_on_condition/nether_eocs/portal_storm_effect_on_condition.json @@ -1120,7 +1120,7 @@ "case": 7, "effect": { "run_eocs": [ - { "id": "EOC_PORTAL_DUNGEON_REWARD_ITEM" }, + "EOC_PORTAL_DUNGEON_REWARD_ITEM", { "id": "EOC_PORTAL_DEPENDENT_DUNGEON_FINAL", "condition": { "u_has_trait": "PORTAL_DEPENDENT" }, diff --git a/data/json/npcs/missiondef.json b/data/json/npcs/missiondef.json index fc67b967c3a57..036f95196f9b7 100644 --- a/data/json/npcs/missiondef.json +++ b/data/json/npcs/missiondef.json @@ -330,9 +330,7 @@ "end": { "effect": [ "stop_following", - { - "weighted_list_eocs": [ [ { "id": "get_katana" }, 5 ], [ { "id": "get_deagle_44" }, 10 ], [ { "id": "get_m4_carbine" }, 6 ] ] - } + { "weighted_list_eocs": [ [ "get_katana", 5 ], [ "get_deagle_44", 10 ], [ "get_m4_carbine", 6 ] ] } ] }, "origins": [ "ORIGIN_SECONDARY" ], diff --git a/data/json/recipes/recipes.json b/data/json/recipes/recipes.json index 38e1e1eeb3f74..06248f451ac65 100644 --- a/data/json/recipes/recipes.json +++ b/data/json/recipes/recipes.json @@ -3,6 +3,7 @@ "type": "recipe_category", "id": "CC_*", "//": "This is just a dummy category. No recipes should be added in here.", + "is_wildcard": true, "recipe_subcategories": [ "CSC_*_FAVORITE", "CSC_*_RECENT", "CSC_*_HIDDEN", "CSC_*_NESTED" ] }, { @@ -125,11 +126,13 @@ "type": "recipe_category", "id": "CC_BUILDING", "recipe_subcategories": [ "CSC_ALL", "CSC_BUILDING_BASES", "CSC_BUILDING_EXPANSIONS" ], + "is_building": true, "is_hidden": true }, { "type": "recipe_category", "id": "CC_PRACTICE", + "is_practice": true, "recipe_subcategories": [ "CSC_ALL", "CSC_PRACTICE_SCIENCE", diff --git a/data/mods/Aftershock/effects_on_condition.json b/data/mods/Aftershock/effects_on_condition.json index 640d9e8e6a526..de47e81cd3595 100644 --- a/data/mods/Aftershock/effects_on_condition.json +++ b/data/mods/Aftershock/effects_on_condition.json @@ -71,11 +71,6 @@ { "u_teleport": { "global_val": "new_map" }, "force": true } ] }, - { - "type": "effect_on_condition", - "id": "EOC_AFS_ESCAPE_POD_CARGO_TP", - "effect": [ { "u_teleport": { "global_val": "new_map" }, "force": true } ] - }, { "type": "effect_on_condition", "id": "EOC_CRASHING_SHIP_SETUP", diff --git a/data/mods/Aftershock/recipes/recipes_categories.json b/data/mods/Aftershock/recipes/recipes_categories.json index 2b9bac376a21a..5831b9362d6c8 100644 --- a/data/mods/Aftershock/recipes/recipes_categories.json +++ b/data/mods/Aftershock/recipes/recipes_categories.json @@ -2,36 +2,13 @@ { "type": "recipe_category", "id": "CC_ELECTRONIC", - "recipe_subcategories": [ - "CSC_ALL", - "CSC_ELECTRONIC_CBMS", - "CSC_ELECTRONIC_TOOLS", - "CSC_ELECTRONIC_PARTS", - "CSC_ELECTRONIC_LIGHTING", - "CSC_ELECTRONIC_COMPONENTS", - "CSC_ELECTRONIC_OTHER" - ] + "copy-from": "CC_ELECTRONIC", + "extend": { "recipe_subcategories": [ "CSC_ELECTRONIC_CBMS" ] } }, { "type": "recipe_category", "id": "CC_PRACTICE", - "recipe_subcategories": [ - "CSC_ALL", - "CSC_PRACTICE_SCIENCE", - "CSC_PRACTICE_ELECTRONICS", - "CSC_PRACTICE_FABRICATION", - "CSC_PRACTICE_FOOD", - "CSC_PRACTICE_SURVIVAL", - "CSC_PRACTICE_TAILORING", - "CSC_PRACTICE_ATHLETICS", - "CSC_PRACTICE_COMPUTERS", - "CSC_PRACTICE_DEVICES", - "CSC_PRACTICE_HEALTH", - "CSC_PRACTICE_MECHANICS", - "CSC_PRACTICE_SOCIAL", - "CSC_PRACTICE_MELEE", - "CSC_PRACTICE_RANGED", - "CSC_PRACTICE_PSI" - ] + "copy-from": "CC_PRACTICE", + "extend": { "recipe_subcategories": [ "CSC_PRACTICE_PSI" ] } } ] diff --git a/data/mods/DinoMod/recipes/recipes.json b/data/mods/DinoMod/recipes/recipes.json index adb8642836f1c..bab8f4537615f 100644 --- a/data/mods/DinoMod/recipes/recipes.json +++ b/data/mods/DinoMod/recipes/recipes.json @@ -2,15 +2,7 @@ { "type": "recipe_category", "id": "CC_ANIMALS", - "recipe_subcategories": [ - "CSC_ALL", - "CSC_ANIMALS_BOVINE ARMOR", - "CSC_ANIMALS_CANINE ARMOR", - "CSC_ANIMALS_EQUINE ARMOR", - "CSC_ANIMALS_ELEPHANT ARMOR", - "CSC_ANIMALS_OSTRICH ARMOR", - "CSC_ANIMALS_BEAR ARMOR", - "CSC_ANIMALS_EQUINE STORAGE" - ] + "copy-from": "CC_ANIMALS", + "extend": { "recipe_subcategories": [ "CSC_ANIMALS_ELEPHANT ARMOR", "CSC_ANIMALS_OSTRICH ARMOR", "CSC_ANIMALS_BEAR ARMOR" ] } } ] diff --git a/data/mods/MindOverMatter/recipes/psionics_practice.json b/data/mods/MindOverMatter/recipes/psionics_practice.json index bce81eebdbef9..c3be72f6f6fdb 100644 --- a/data/mods/MindOverMatter/recipes/psionics_practice.json +++ b/data/mods/MindOverMatter/recipes/psionics_practice.json @@ -2,24 +2,8 @@ { "type": "recipe_category", "id": "CC_PRACTICE", - "recipe_subcategories": [ - "CSC_ALL", - "CSC_PRACTICE_SCIENCE", - "CSC_PRACTICE_ELECTRONICS", - "CSC_PRACTICE_FABRICATION", - "CSC_PRACTICE_FOOD", - "CSC_PRACTICE_SURVIVAL", - "CSC_PRACTICE_TAILORING", - "CSC_PRACTICE_ATHLETICS", - "CSC_PRACTICE_COMPUTERS", - "CSC_PRACTICE_DEVICES", - "CSC_PRACTICE_HEALTH", - "CSC_PRACTICE_MECHANICS", - "CSC_PRACTICE_SOCIAL", - "CSC_PRACTICE_MELEE", - "CSC_PRACTICE_RANGED", - "CSC_PRACTICE_METAPHYSICS" - ] + "copy-from": "CC_PRACTICE", + "extend": { "recipe_subcategories": [ "CSC_PRACTICE_METAPHYSICS" ] } }, { "id": "prac_psionics_begin", diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index 96cbfc71b9c64..c0aa3bcb2612f 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -36,6 +36,7 @@ #include "contents_change_handler.h" #include "coordinates.h" #include "craft_command.h" +#include "crafting_gui.h" #include "creature.h" #include "creature_tracker.h" #include "debug.h" @@ -3768,7 +3769,7 @@ void craft_activity_actor::canceled( player_activity &/*act*/, Character &/*who* } const recipe item_recipe = craft->get_making(); // practice recipe items with no components can be safely removed - if( item_recipe.category == "CC_PRACTICE" && craft->components.empty() ) { + if( item_recipe.category->is_practice && craft->components.empty() ) { craft_item.remove_item(); } } diff --git a/src/crafting.cpp b/src/crafting.cpp index 89bd780ee2fcf..bd94aebbfcf04 100644 --- a/src/crafting.cpp +++ b/src/crafting.cpp @@ -157,7 +157,7 @@ static bool crafting_allowed( const Character &p, const recipe &rec ) return false; } - if( rec.category == "CC_BUILDING" ) { + if( rec.category->is_building ) { add_msg( m_info, _( "Overmap terrain building recipes are not implemented yet!" ) ); return false; } diff --git a/src/crafting_gui.cpp b/src/crafting_gui.cpp index e86a6b14e720e..06a15c5d356e9 100644 --- a/src/crafting_gui.cpp +++ b/src/crafting_gui.cpp @@ -91,9 +91,24 @@ static const std::map craft_speed_reaso {NORMAL_CRAFTING, to_translation( "craftable" )} }; -// TODO: Convert these globals to handling categories via generic_factory? -static std::vector craft_cat_list; -static std::map > craft_subcat_list; +namespace +{ + +generic_factory craft_cat_list( "recipe_category" ); + +} // namespace + +template<> +const crafting_category &string_id::obj() const +{ + return craft_cat_list.obj( *this ); +} + +template<> +bool string_id::is_valid() const +{ + return craft_cat_list.is_valid( *this ); +} static bool query_is_yes( std::string_view query ); static void draw_hidden_amount( const catacurses::window &w, int amount, int num_recipe ); @@ -127,32 +142,39 @@ static std::string get_cat_unprefixed( const std::string_view prefixed_name ) return std::string( prefixed_name.substr( 3, prefixed_name.size() - 3 ) ); } -void load_recipe_category( const JsonObject &jsobj ) +void load_recipe_category( const JsonObject &jsobj, const std::string &src ) { - const std::string category = jsobj.get_string( "id" ); - const bool is_hidden = jsobj.get_bool( "is_hidden", false ); - - if( category.find( "CC_" ) != 0 ) { - jsobj.throw_error( "Crafting category id has to be prefixed with 'CC_'" ); - } - - if( !is_hidden - && std::find( craft_cat_list.begin(), craft_cat_list.end(), category ) == craft_cat_list.end() - ) { - craft_cat_list.push_back( category ); - } - - const std::string cat_name = get_cat_unprefixed( category ); + craft_cat_list.load( jsobj, src ); +} - craft_subcat_list[category].clear(); - for( const std::string subcat_id : jsobj.get_array( "recipe_subcategories" ) ) { +void crafting_category::load( const JsonObject &jo, const std::string_view ) +{ + // Ensure id is correct + if( id.str().find( "CC_" ) != 0 ) { + jo.throw_error( "Crafting category id has to be prefixed with 'CC_'" ); + } + + optional( jo, was_loaded, "is_hidden", is_hidden, false ); + optional( jo, was_loaded, "is_practice", is_practice, false ); + optional( jo, was_loaded, "is_building", is_building, false ); + optional( jo, was_loaded, "is_wildcard", is_wildcard, false ); + mandatory( jo, was_loaded, "recipe_subcategories", subcategories, + auto_flags_reader<> {} ); + + // Ensure subcategory ids are correct and remove dupes + std::string cat_name = get_cat_unprefixed( id.str() ); + std::unordered_set known; + for( auto it = subcategories.begin(); it != subcategories.end(); ) { + const std::string &subcat_id = *it; if( subcat_id.find( "CSC_" + cat_name + "_" ) != 0 && subcat_id != "CSC_ALL" ) { - jsobj.throw_error( "Crafting sub-category id has to be prefixed with CSC__" ); + jo.throw_error( "Crafting sub-category id has to be prefixed with CSC__" ); } - if( find( craft_subcat_list[category].begin(), craft_subcat_list[category].end(), - subcat_id ) == craft_subcat_list[category].end() ) { - craft_subcat_list[category].push_back( subcat_id ); + if( known.find( subcat_id ) != known.end() ) { + it = subcategories.erase( it ); + continue; } + known.emplace( subcat_id ); + ++it; } } @@ -170,8 +192,7 @@ static std::string get_subcat_unprefixed( const std::string_view cat, void reset_recipe_categories() { - craft_cat_list.clear(); - craft_subcat_list.clear(); + craft_cat_list.reset(); } static bool cannot_gain_skill_or_prof( const Character &crafter, const recipe &recp ) @@ -860,7 +881,7 @@ void recipe_result_info_cache::insert_iteminfo_block_separator( std::vector, bool> -recipes_from_cat( const recipe_subset &available_recipes, const std::string &cat, +recipes_from_cat( const recipe_subset &available_recipes, const crafting_category_id &cat, const std::string &subcat ) { if( subcat == "CSC_*_FAVORITE" ) { @@ -1282,8 +1303,16 @@ std::pair select_crafter_and_crafting_recipe( int & bool is_filtered_unread = false; std::map is_cat_unread; std::map> is_subcat_unread; - tab_list tab( craft_cat_list ); - tab_list subtab( craft_subcat_list[tab.cur()] ); + std::vector crafting_categories; + crafting_categories.reserve( craft_cat_list.size() ); + for( const crafting_category &cat : craft_cat_list.get_all() ) { + if( cat.is_hidden ) { + continue; + } + crafting_categories.emplace_back( cat.id.str() ); + } + tab_list tab( crafting_categories ); + tab_list subtab( crafting_category_id( tab.cur() )->subcategories ); std::map> translated_tab_map; std::map> translated_subtab_map; std::map> list_map; @@ -1330,13 +1359,11 @@ std::pair select_crafter_and_crafting_recipe( int & gotocat.end(), [&goto_recipe]( const recipe * r ) { return r && r->ident() == goto_recipe; } ); - if( gotorec != gotocat.end() && - std::find( craft_cat_list.begin(), craft_cat_list.end(), - goto_recipe->category ) != craft_cat_list.end() ) { - while( tab.cur() != goto_recipe->category ) { + if( gotorec != gotocat.end() && ( *gotorec )->category.is_valid() ) { + while( tab.cur() != goto_recipe->category.str() ) { tab.next(); } - subtab = tab_list( craft_subcat_list[tab.cur()] ); + subtab = tab_list( crafting_category_id( tab.cur() )->subcategories ); chosen = *gotorec; show_hidden = true; keepline = true; @@ -1349,12 +1376,12 @@ std::pair select_crafter_and_crafting_recipe( int & ui.on_redraw( [&]( ui_adaptor & ui ) { if( highlight_unread_recipes && recalc_unread ) { if( filterstring.empty() ) { - for( const std::string &cat : craft_cat_list ) { + for( const std::string &cat : crafting_categories ) { is_cat_unread[cat] = false; - for( const std::string &subcat : craft_subcat_list[cat] ) { + for( const std::string &subcat : crafting_category_id( cat )->subcategories ) { is_subcat_unread[cat][subcat] = false; const std::pair, bool> result = recipes_from_cat( available_recipes, - cat, subcat ); + crafting_category_id( cat ), subcat ); const std::vector &recipes = result.first; const bool include_hidden = result.second; for( const recipe *const rcp : recipes ) { @@ -1583,7 +1610,7 @@ std::pair select_crafter_and_crafting_recipe( int & picking.insert( picking.end(), filtered_recipes.begin(), filtered_recipes.end() ); } else { const std::pair, bool> result = recipes_from_cat( available_recipes, - tab.cur(), subtab.cur() ); + crafting_category_id( tab.cur() ), subtab.cur() ); show_hidden = result.second; if( show_hidden ) { current = result.first; @@ -1722,7 +1749,7 @@ std::pair select_crafter_and_crafting_recipe( int & if( entry.second.contains( local_coord ) ) { tab.set_index( entry.first ); recalc = true; - subtab = tab_list( craft_subcat_list[tab.cur()] ); + subtab = tab_list( crafting_category_id( tab.cur() )->subcategories ); handled = true; } } @@ -1751,8 +1778,9 @@ std::pair select_crafter_and_crafting_recipe( int & std::string start = subtab.cur(); do { subtab.prev(); - } while( subtab.cur() != start && available_recipes.empty_category( tab.cur(), - subtab.cur() != "CSC_ALL" ? subtab.cur() : "" ) ); + } while( subtab.cur() != start && + available_recipes.empty_category( crafting_category_id( tab.cur() ), + subtab.cur() != "CSC_ALL" ? subtab.cur() : "" ) ); recalc = true; } else if( action == "SCROLL_ITEM_INFO_UP" ) { line_item_info -= scroll_item_info_lines; @@ -1766,7 +1794,7 @@ std::pair select_crafter_and_crafting_recipe( int & mouse_in_window( coord, w_head_tabs ) ) ) { tab.prev(); // Default ALL - subtab = tab_list( craft_subcat_list[tab.cur()] ); + subtab = tab_list( crafting_category_id( tab.cur() )->subcategories ); recalc = true; } else if( action == "RIGHT" || ( action == "SCROLL_DOWN" && mouse_in_window( coord, w_subhead ) ) ) { @@ -1776,14 +1804,15 @@ std::pair select_crafter_and_crafting_recipe( int & std::string start = subtab.cur(); do { subtab.next(); - } while( subtab.cur() != start && available_recipes.empty_category( tab.cur(), - subtab.cur() != "CSC_ALL" ? subtab.cur() : "" ) ); + } while( subtab.cur() != start && + available_recipes.empty_category( crafting_category_id( tab.cur() ), + subtab.cur() != "CSC_ALL" ? subtab.cur() : "" ) ); recalc = true; } else if( action == "NEXT_TAB" || ( action == "SCROLL_DOWN" && mouse_in_window( coord, w_head_tabs ) ) ) { tab.next(); // Default ALL - subtab = tab_list( craft_subcat_list[tab.cur()] ); + subtab = tab_list( crafting_category_id( tab.cur() )->subcategories ); recalc = true; } else if( action == "DOWN" ) { if( !previously_toggled_unread ) { @@ -2333,12 +2362,15 @@ static std::map> draw_recipe_tabs( const cata case NORMAL: { std::vector translated_cats; translated_cats.reserve( craft_cat_list.size() ); - for( const std::string &cat : craft_cat_list ) { - if( unread[ cat ] ) { + for( const crafting_category &cat : craft_cat_list.get_all() ) { + if( cat.is_hidden ) { + continue; + } + if( unread[ cat.id.str() ] ) { translated_cats.emplace_back( _( get_cat_unprefixed( - cat ) ).append( "⁺" ) ); + cat.id.str() ) ).append( "⁺" ) ); } else { - translated_cats.emplace_back( _( get_cat_unprefixed( cat ) ) ); + translated_cats.emplace_back( _( get_cat_unprefixed( cat.id.str() ) ) ); } } std::pair, size_t> fitted_tabs = fit_tabs_to_width( getmaxx( w ), @@ -2390,19 +2422,22 @@ static std::map> draw_recipe_subtabs( std::vector translated_subcats; std::vector empty_subcats; std::vector unread_subcats; - translated_subcats.reserve( craft_subcat_list[tab].size() ); - empty_subcats.reserve( craft_subcat_list[tab].size() ); - unread_subcats.reserve( craft_subcat_list[tab].size() ); - for( const std::string &subcat : craft_subcat_list[tab] ) { + crafting_category_id current_cat = crafting_category_id( tab ); + size_t subcats_count = current_cat->subcategories.size(); + translated_subcats.reserve( subcats_count ); + empty_subcats.reserve( subcats_count ); + unread_subcats.reserve( subcats_count ); + for( const std::string &subcat : current_cat->subcategories ) { translated_subcats.emplace_back( _( get_subcat_unprefixed( tab, subcat ) ) ); - empty_subcats.emplace_back( available_recipes.empty_category( tab, - subcat != "CSC_ALL" ? subcat : "" ) ); + empty_subcats.emplace_back( available_recipes.empty_category( + crafting_category_id( tab ), + subcat != "CSC_ALL" ? subcat : "" ) ); unread_subcats.emplace_back( unread[subcat] ); } std::pair, size_t> fitted_subcat_list = fit_tabs_to_width( getmaxx( w ), subtab, translated_subcats ); size_t offset = fitted_subcat_list.second; - if( fitted_subcat_list.first.size() + offset > craft_subcat_list[tab].size() ) { + if( fitted_subcat_list.first.size() + offset > subcats_count ) { break; } // Draw the tabs on each other @@ -2440,9 +2475,9 @@ static std::map> draw_recipe_subtabs( const std::vector *subcategories_for_category( const std::string &category ) { - auto it = craft_subcat_list.find( category ); - if( it != craft_subcat_list.end() ) { - return &it->second; + crafting_category_id cat( category ); + if( !cat.is_valid() ) { + return nullptr; } - return nullptr; + return &cat->subcategories; } diff --git a/src/crafting_gui.h b/src/crafting_gui.h index 0e2039bbe1d85..149cc934dbeec 100644 --- a/src/crafting_gui.h +++ b/src/crafting_gui.h @@ -23,11 +23,24 @@ class recipe; std::pair select_crafter_and_crafting_recipe( int &batch_size_out, const recipe_id &goto_recipe, Character *crafter, std::string filterstring = "" ); -void load_recipe_category( const JsonObject &jsobj ); +void load_recipe_category( const JsonObject &jsobj, const std::string &src ); void reset_recipe_categories(); // Returns nullptr if the category does not exist, or a pointer to its vector // of subcategories it the category does exist const std::vector *subcategories_for_category( const std::string &category ); +struct crafting_category { + crafting_category_id id; + bool was_loaded = false; + + bool is_hidden; + bool is_practice; + bool is_building; + bool is_wildcard; + std::vector subcategories; + + void load( const JsonObject &jo, std::string_view src ); +}; + #endif // CATA_SRC_CRAFTING_GUI_H diff --git a/src/damage.cpp b/src/damage.cpp index 010119be717a7..6fda13eb70975 100644 --- a/src/damage.cpp +++ b/src/damage.cpp @@ -112,7 +112,7 @@ static damage_info_order::info_disp read_info_disp( const std::string &s ) } } -void damage_type::load( const JsonObject &jo, std::string_view ) +void damage_type::load( const JsonObject &jo, std::string_view src ) { mandatory( jo, was_loaded, "name", name ); optional( jo, was_loaded, "skill", skill, skill_id::NULL_ID() ); @@ -151,11 +151,11 @@ void damage_type::load( const JsonObject &jo, std::string_view ) } for( JsonValue jv : jo.get_array( "onhit_eocs" ) ) { - onhit_eocs.push_back( effect_on_conditions::load_inline_eoc( jv, "" ) ); + onhit_eocs.push_back( effect_on_conditions::load_inline_eoc( jv, std::string( src ) ) ); } for( JsonValue jv : jo.get_array( "ondamage_eocs" ) ) { - ondamage_eocs.push_back( effect_on_conditions::load_inline_eoc( jv, "" ) ); + ondamage_eocs.push_back( effect_on_conditions::load_inline_eoc( jv, std::string( src ) ) ); } } diff --git a/src/dialogue.h b/src/dialogue.h index 8b815a7bb30ec..fb1d3f7e8c3ee 100644 --- a/src/dialogue.h +++ b/src/dialogue.h @@ -129,12 +129,14 @@ struct talk_effect_t { void set_effect_consequence( const talk_effect_fun_t &fun, dialogue_consequence con ); void set_effect_consequence( const std::function &ptr, dialogue_consequence con ); - void load_effect( const JsonObject &jo, const std::string &member_name ); - void parse_sub_effect( const JsonObject &jo ); - void parse_string_effect( const std::string &effect_id, const JsonObject &jo ); + void load_effect( const JsonObject &jo, const std::string &member_name, + std::string_view src ); + void parse_sub_effect( const JsonObject &jo, std::string_view src ); + void parse_string_effect( const std::string &effect_id, const JsonObject &jo, + std::string_view src ); talk_effect_t() = default; - explicit talk_effect_t( const JsonObject &, const std::string & ); + explicit talk_effect_t( const JsonObject &, const std::string &, std::string_view src ); /** * Functions that are called when the response is chosen. @@ -178,7 +180,7 @@ struct talk_response { std::set get_consequences( dialogue &d ) const; talk_response(); - explicit talk_response( const JsonObject & ); + explicit talk_response( const JsonObject &, std::string_view ); }; struct dialogue { @@ -368,12 +370,12 @@ class json_talk_response // the topic to move to on failure std::string failure_topic; - void load_condition( const JsonObject &jo ); + void load_condition( const JsonObject &jo, std::string_view src ); bool test_condition( dialogue &d ) const; public: json_talk_response() = default; - explicit json_talk_response( const JsonObject &jo ); + explicit json_talk_response( const JsonObject &jo, std::string_view src ); const talk_response &get_actual_response() const; bool has_condition() const { @@ -394,7 +396,7 @@ class json_talk_repeat_response { public: json_talk_repeat_response() = default; - explicit json_talk_repeat_response( const JsonObject &jo ); + explicit json_talk_repeat_response( const JsonObject &jo, std::string_view src ); bool is_npc = false; bool include_containers = false; std::vector for_item; @@ -408,7 +410,7 @@ class json_dynamic_line_effect std::function condition; talk_effect_t effect; public: - json_dynamic_line_effect( const JsonObject &jo, const std::string &id ); + json_dynamic_line_effect( const JsonObject &jo, const std::string &id, std::string_view src ); bool test_condition( dialogue &d ) const; void apply( dialogue &d ) const; }; @@ -433,7 +435,7 @@ class json_talk_topic * It will override dynamic_line and replace_built_in_responses if those entries * exist in the input, otherwise they will not be changed at all. */ - void load( const JsonObject &jo ); + void load( const JsonObject &jo, std::string_view src ); std::string get_dynamic_line( dialogue &d ) const; std::vector get_speaker_effects() const; @@ -452,6 +454,6 @@ class json_talk_topic }; void unload_talk_topics(); -void load_talk_topic( const JsonObject &jo ); +void load_talk_topic( const JsonObject &jo, std::string_view src ); #endif // CATA_SRC_DIALOGUE_H diff --git a/src/effect.cpp b/src/effect.cpp index 8fcd43e4f2359..a2181aa3dd748 100644 --- a/src/effect.cpp +++ b/src/effect.cpp @@ -1503,7 +1503,7 @@ static const std::unordered_set hardcoded_movement_impairing = {{ } }; -void load_effect_type( const JsonObject &jo ) +void load_effect_type( const JsonObject &jo, const std::string_view src ) { effect_type new_etype; new_etype.id = efftype_id( jo.get_string( "id" ) ); @@ -1605,7 +1605,7 @@ void load_effect_type( const JsonObject &jo ) for( JsonValue jv : jo.get_array( "enchantments" ) ) { std::string enchant_name = "INLINE_ENCH_" + new_etype.id.str() + "_" + std::to_string( enchant_num++ ); - new_etype.enchantments.push_back( enchantment::load_inline_enchantment( jv, "", enchant_name ) ); + new_etype.enchantments.push_back( enchantment::load_inline_enchantment( jv, src, enchant_name ) ); } effect_types[new_etype.id] = new_etype; } diff --git a/src/effect.h b/src/effect.h index 519bd4291bc36..b9f9a3cb6dff2 100644 --- a/src/effect.h +++ b/src/effect.h @@ -103,7 +103,7 @@ struct effect_dur_mod { class effect_type { - friend void load_effect_type( const JsonObject &jo ); + friend void load_effect_type( const JsonObject &jo, std::string_view src ); friend class effect; public: enum class memorial_gender : int { @@ -444,7 +444,7 @@ class effect }; -void load_effect_type( const JsonObject &jo ); +void load_effect_type( const JsonObject &jo, std::string_view src ); void reset_effect_types(); const std::map &get_effect_types(); diff --git a/src/effect_on_condition.cpp b/src/effect_on_condition.cpp index 276caba9baac0..268ea51f73551 100644 --- a/src/effect_on_condition.cpp +++ b/src/effect_on_condition.cpp @@ -75,7 +75,7 @@ void effect_on_conditions::check_consistency() { } -void effect_on_condition::load( const JsonObject &jo, const std::string_view ) +void effect_on_condition::load( const JsonObject &jo, const std::string_view src ) { mandatory( jo, was_loaded, "id", id ); optional( jo, was_loaded, "eoc_type", type, eoc_type::NUM_EOC_TYPES ); @@ -98,10 +98,10 @@ void effect_on_condition::load( const JsonObject &jo, const std::string_view ) read_condition( jo, "condition", condition, false ); has_condition = true; } - true_effect.load_effect( jo, "effect" ); + true_effect.load_effect( jo, "effect", std::string( src ) ); if( jo.has_member( "false_effect" ) ) { - false_effect.load_effect( jo, "false_effect" ); + false_effect.load_effect( jo, "false_effect", std::string( src ) ); has_false_effect = true; } @@ -117,7 +117,7 @@ void effect_on_condition::load( const JsonObject &jo, const std::string_view ) } effect_on_condition_id effect_on_conditions::load_inline_eoc( const JsonValue &jv, - std::string_view src ) + const std::string_view src ) { if( jv.test_string() ) { return effect_on_condition_id( jv.get_string() ); diff --git a/src/iexamine.h b/src/iexamine.h index 2806f303c5f09..d884de63c2fd8 100644 --- a/src/iexamine.h +++ b/src/iexamine.h @@ -29,7 +29,7 @@ struct iexamine_actor { explicit iexamine_actor( const std::string &type ) : type( type ) {} - virtual void load( const JsonObject & ) = 0; + virtual void load( const JsonObject &, const std::string & ) = 0; virtual void call( Character &, const tripoint & ) const = 0; virtual void finalize() const = 0; diff --git a/src/iexamine_actors.cpp b/src/iexamine_actors.cpp index de9deaaf1e354..3b0218d173358 100644 --- a/src/iexamine_actors.cpp +++ b/src/iexamine_actors.cpp @@ -16,7 +16,7 @@ static const ter_str_id ter_t_door_metal_c( "t_door_metal_c" ); static const ter_str_id ter_t_door_metal_locked( "t_door_metal_locked" ); -void appliance_convert_examine_actor::load( const JsonObject &jo ) +void appliance_convert_examine_actor::load( const JsonObject &jo, const std::string & ) { optional( jo, false, "furn_set", furn_set ); optional( jo, false, "ter_set", ter_set ); @@ -193,7 +193,7 @@ void cardreader_examine_actor::call( Character &you, const tripoint &examp ) con } } -void cardreader_examine_actor::load( const JsonObject &jo ) +void cardreader_examine_actor::load( const JsonObject &jo, const std::string & ) { mandatory( jo, false, "flags", allowed_flags ); optional( jo, false, "consume_card", consume, true ); @@ -257,10 +257,10 @@ void eoc_examine_actor::call( Character &you, const tripoint &examp ) const } } -void eoc_examine_actor::load( const JsonObject &jo ) +void eoc_examine_actor::load( const JsonObject &jo, const std::string &src ) { for( JsonValue jv : jo.get_array( "effect_on_conditions" ) ) { - eocs.emplace_back( effect_on_conditions::load_inline_eoc( jv, "" ) ); + eocs.emplace_back( effect_on_conditions::load_inline_eoc( jv, src ) ); } } diff --git a/src/iexamine_actors.h b/src/iexamine_actors.h index 3ec29e6fc3b78..2cfa9990dc7d8 100644 --- a/src/iexamine_actors.h +++ b/src/iexamine_actors.h @@ -20,7 +20,7 @@ class appliance_convert_examine_actor : public iexamine_actor explicit appliance_convert_examine_actor( const std::string &type = "appliance_convert" ) : iexamine_actor( type ) {} - void load( const JsonObject &jo ) override; + void load( const JsonObject &jo, const std::string & ) override; void call( Character &you, const tripoint &examp ) const override; void finalize() const override; @@ -60,7 +60,7 @@ class cardreader_examine_actor : public iexamine_actor explicit cardreader_examine_actor( const std::string &type = "cardreader" ) : iexamine_actor( type ) {} - void load( const JsonObject &jo ) override; + void load( const JsonObject &jo, const std::string & ) override; void call( Character &you, const tripoint &examp ) const override; void finalize() const override; @@ -75,7 +75,7 @@ class eoc_examine_actor : public iexamine_actor explicit eoc_examine_actor( const std::string &type = "effect_on_condition" ) : iexamine_actor( type ) {} - void load( const JsonObject &jo ) override; + void load( const JsonObject &jo, const std::string &src ) override; void call( Character &you, const tripoint &examp ) const override; void finalize() const override; diff --git a/src/init.cpp b/src/init.cpp index 76ff135154a96..0bb49026b1952 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -301,8 +301,8 @@ void DynamicDataLoader::initialize() // json/colors.json would be listed here, but it's loaded before the others (see init_colors()) // Non Static Function Access - add( "snippet", []( const JsonObject & jo ) { - SNIPPET.load_snippet( jo ); + add( "snippet", []( const JsonObject & jo, const std::string & src ) { + SNIPPET.load_snippet( jo, src ); } ); add( "item_group", []( const JsonObject & jo ) { item_controller->load_item_group( jo ); diff --git a/src/item_factory.cpp b/src/item_factory.cpp index 5f75230722fcb..b5af8bfff8fc6 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -66,6 +66,8 @@ static const ammo_effect_str_id ammo_effect_SPECIAL_COOKOFF( "SPECIAL_COOKOFF" ) static const ammotype ammo_NULL( "NULL" ); +static const crafting_category_id crafting_category_CC_FOOD( "CC_FOOD" ); + static const damage_type_id damage_bash( "bash" ); static const damage_type_id damage_bullet( "bullet" ); @@ -1654,7 +1656,7 @@ class iuse_function_wrapper : public iuse_actor return std::make_unique( *this ); } - void load( const JsonObject & ) override {} + void load( const JsonObject &, const std::string & ) override {} }; class iuse_function_wrapper_with_info : public iuse_function_wrapper @@ -2666,7 +2668,7 @@ static void load_memory_card_data( memory_card_info &mcd, const JsonObject &jo ) mcd.recipes_categories.emplace( cat ); } } else { - mcd.recipes_categories = { "CC_FOOD" }; + mcd.recipes_categories = { crafting_category_CC_FOOD }; } if( jo.has_member( "secret_recipes" ) ) { mcd.secret_recipes = jo.get_bool( "secret_recipes" ); @@ -4395,8 +4397,8 @@ void Item_factory::load_basic_info( const JsonObject &jo, itype &def, const std: } } - set_use_methods_from_json( jo, "use_action", def.use_methods, def.ammo_scale ); - set_use_methods_from_json( jo, "tick_action", def.tick_action, def.ammo_scale ); + set_use_methods_from_json( jo, src, "use_action", def.use_methods, def.ammo_scale ); + set_use_methods_from_json( jo, src, "tick_action", def.tick_action, def.ammo_scale ); assign( jo, "countdown_interval", def.countdown_interval ); assign( jo, "revert_to", def.revert_to, strict ); @@ -4406,7 +4408,7 @@ void Item_factory::load_basic_info( const JsonObject &jo, itype &def, const std: } else if( jo.has_object( "countdown_action" ) ) { JsonObject tmp = jo.get_object( "countdown_action" ); - use_function fun = usage_from_object( tmp ).second; + use_function fun = usage_from_object( tmp, src ).second; if( fun ) { def.countdown_action = fun; } @@ -4417,7 +4419,7 @@ void Item_factory::load_basic_info( const JsonObject &jo, itype &def, const std: } else if( jo.has_object( "drop_action" ) ) { JsonObject tmp = jo.get_object( "drop_action" ); - use_function fun = usage_from_object( tmp ).second; + use_function fun = usage_from_object( tmp, src ).second; if( fun ) { def.drop_action = fun; } @@ -4492,7 +4494,7 @@ void Item_factory::load_basic_info( const JsonObject &jo, itype &def, const std: // auto-create a category that is unlikely to already be used and put the // snippets in it. def.snippet_category = "auto:" + def.id.str(); - SNIPPET.add_snippets_from_json( def.snippet_category, jo.get_array( "snippet_category" ) ); + SNIPPET.add_snippets_from_json( def.snippet_category, jo.get_array( "snippet_category" ), src ); } else { def.snippet_category = jo.get_string( "snippet_category", "" ); } @@ -5189,8 +5191,9 @@ void Item_factory::load_item_group_data( const JsonObject &jsobj, Item_group *ig } } -void Item_factory::set_use_methods_from_json( const JsonObject &jo, const std::string &member, - std::map &use_methods, std::map &ammo_scale ) +void Item_factory::set_use_methods_from_json( const JsonObject &jo, const std::string &src, + const std::string &member, std::map &use_methods, + std::map &ammo_scale ) { if( !jo.has_member( member ) ) { return; @@ -5205,7 +5208,7 @@ void Item_factory::set_use_methods_from_json( const JsonObject &jo, const std::s emplace_usage( use_methods, type ); } else if( entry.test_object() ) { JsonObject obj = entry.get_object(); - std::pair fun = usage_from_object( obj ); + std::pair fun = usage_from_object( obj, src ); if( fun.second ) { use_methods.insert( fun ); if( obj.has_int( "ammo_scale" ) ) { @@ -5229,7 +5232,7 @@ void Item_factory::set_use_methods_from_json( const JsonObject &jo, const std::s emplace_usage( use_methods, type ); } else if( jo.has_object( member ) ) { JsonObject obj = jo.get_object( member ); - std::pair fun = usage_from_object( obj ); + std::pair fun = usage_from_object( obj, src ); if( fun.second ) { use_methods.insert( fun ); if( obj.has_int( "ammo_scale" ) ) { @@ -5253,7 +5256,8 @@ void Item_factory::emplace_usage( std::map &container } } -std::pair Item_factory::usage_from_object( const JsonObject &obj ) +std::pair Item_factory::usage_from_object( const JsonObject &obj, + const std::string &src ) { std::string type = obj.get_string( "type" ); @@ -5271,7 +5275,7 @@ std::pair Item_factory::usage_from_object( const Json return std::make_pair( type, use_function() ); } - method.get_actor_ptr()->load( obj ); + method.get_actor_ptr()->load( obj, src ); return std::make_pair( type, method ); } diff --git a/src/item_factory.h b/src/item_factory.h index b6622d730095e..8a51f583a4d10 100644 --- a/src/item_factory.h +++ b/src/item_factory.h @@ -329,12 +329,14 @@ class Item_factory void emplace_usage( std::map &container, const std::string &iuse_id ); - void set_use_methods_from_json( const JsonObject &jo, const std::string &member, - std::map &use_methods, std::map &ammo_scale ); + void set_use_methods_from_json( const JsonObject &jo, const std::string &src, + const std::string &member, std::map &use_methods, + std::map &ammo_scale ); use_function usage_from_string( const std::string &type ) const; - std::pair usage_from_object( const JsonObject &obj ); + std::pair usage_from_object( const JsonObject &obj, + const std::string & ); /** * Helper function for Item_group loading diff --git a/src/itype.h b/src/itype.h index 5a8dcff50cfee..68afdb3d90008 100644 --- a/src/itype.h +++ b/src/itype.h @@ -1182,7 +1182,7 @@ struct memory_card_info { int recipes_amount; int recipes_level_min; int recipes_level_max; - std::set recipes_categories; + std::set recipes_categories; bool secret_recipes; }; diff --git a/src/iuse.cpp b/src/iuse.cpp index 8a4e5679dee52..32a72b0ada2a8 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -146,6 +146,8 @@ static const construction_str_id construction_constr_pit( "constr_pit" ); static const construction_str_id construction_constr_pit_shallow( "constr_pit_shallow" ); static const construction_str_id construction_constr_water_channel( "constr_water_channel" ); +static const crafting_category_id crafting_category_CC_FOOD( "CC_FOOD" ); + static const efftype_id effect_adrenaline( "adrenaline" ); static const efftype_id effect_antibiotic( "antibiotic" ); static const efftype_id effect_antibiotic_visible( "antibiotic_visible" ); @@ -7569,7 +7571,8 @@ std::optional iuse::multicooker( Character *p, item *it, const tripoint &po int counter = 0; static const std::set multicooked_subcats = { "CSC_FOOD_MEAT", "CSC_FOOD_VEGGI", "CSC_FOOD_PASTA" }; - for( const recipe * const &r : get_avatar().get_learned_recipes().in_category( "CC_FOOD" ) ) { + for( const recipe * const &r : get_avatar().get_learned_recipes().in_category( + crafting_category_CC_FOOD ) ) { if( multicooked_subcats.count( r->subcategory ) > 0 ) { dishes.push_back( r ); const bool can_make = r->deduped_requirements().can_make_with_inventory( diff --git a/src/iuse.h b/src/iuse.h index 523d8efc8aabe..010996399dead 100644 --- a/src/iuse.h +++ b/src/iuse.h @@ -285,7 +285,7 @@ class iuse_actor int cost; virtual ~iuse_actor() = default; - virtual void load( const JsonObject &jo ) = 0; + virtual void load( const JsonObject &jo, const std::string &src ) = 0; virtual std::optional use( Character *, item &, const tripoint & ) const = 0; virtual ret_val can_use( const Character &, const item &, const tripoint & ) const; virtual void info( const item &, std::vector & ) const {} diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 59a2ce367396b..9021ccb9cfa96 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -168,7 +168,7 @@ std::unique_ptr iuse_transform::clone() const return std::make_unique( *this ); } -void iuse_transform::load( const JsonObject &obj ) +void iuse_transform::load( const JsonObject &obj, const std::string & ) { obj.read( "target", target, true ); @@ -484,7 +484,7 @@ std::unique_ptr unpack_actor::clone() const return std::make_unique( *this ); } -void unpack_actor::load( const JsonObject &obj ) +void unpack_actor::load( const JsonObject &obj, const std::string & ) { obj.read( "group", unpack_group ); obj.read( "items_fit", items_fit ); @@ -537,7 +537,7 @@ std::unique_ptr message_iuse::clone() const return std::make_unique( *this ); } -void message_iuse::load( const JsonObject &obj ) +void message_iuse::load( const JsonObject &obj, const std::string & ) { obj.read( "name", name ); obj.read( "message", message ); @@ -570,7 +570,7 @@ std::unique_ptr sound_iuse::clone() const return std::make_unique( *this ); } -void sound_iuse::load( const JsonObject &obj ) +void sound_iuse::load( const JsonObject &obj, const std::string & ) { obj.read( "name", name ); obj.read( "sound_message", sound_message ); @@ -625,7 +625,7 @@ static std::vector points_for_gas_cloud( const tripoint ¢er, int r return result; } -void explosion_iuse::load( const JsonObject &obj ) +void explosion_iuse::load( const JsonObject &obj, const std::string & ) { if( obj.has_object( "explosion" ) ) { JsonObject expl = obj.get_object( "explosion" ); @@ -717,7 +717,7 @@ static effect_data load_effect_data( const JsonObject &e ) bodypart_id( e.get_string( "bp", "bp_null" ) ), e.get_bool( "permanent", false ) ); } -void consume_drug_iuse::load( const JsonObject &obj ) +void consume_drug_iuse::load( const JsonObject &obj, const std::string & ) { obj.read( "activation_message", activation_message ); obj.read( "charges_needed", charges_needed ); @@ -855,9 +855,9 @@ std::unique_ptr delayed_transform_iuse::clone() const return std::make_unique( *this ); } -void delayed_transform_iuse::load( const JsonObject &obj ) +void delayed_transform_iuse::load( const JsonObject &obj, const std::string &src ) { - iuse_transform::load( obj ); + iuse_transform::load( obj, src ); obj.get_member( "not_ready_msg" ).read( not_ready_msg ); transform_age = obj.get_int( "transform_age" ); } @@ -883,7 +883,7 @@ std::unique_ptr place_monster_iuse::clone() const return std::make_unique( *this ); } -void place_monster_iuse::load( const JsonObject &obj ) +void place_monster_iuse::load( const JsonObject &obj, const std::string & ) { mtypeid = mtype_id( obj.get_string( "monster_id" ) ); obj.read( "friendly_msg", friendly_msg ); @@ -989,7 +989,7 @@ std::unique_ptr place_npc_iuse::clone() const return std::make_unique( *this ); } -void place_npc_iuse::load( const JsonObject &obj ) +void place_npc_iuse::load( const JsonObject &obj, const std::string & ) { npc_class_id = string_id( obj.get_string( "npc_class_id" ) ); obj.read( "summon_msg", summon_msg ); @@ -1069,7 +1069,7 @@ void deploy_furn_actor::info( const item &, std::vector &dump ) const } } -void deploy_furn_actor::load( const JsonObject &obj ) +void deploy_furn_actor::load( const JsonObject &obj, const std::string & ) { furn_type = furn_str_id( obj.get_string( "furn_type" ) ); } @@ -1170,7 +1170,7 @@ void deploy_appliance_actor::info( const item &, std::vector &dump ) c vpart_appliance_from_item( appliance_base )->name() ) ); } -void deploy_appliance_actor::load( const JsonObject &obj ) +void deploy_appliance_actor::load( const JsonObject &obj, const std::string & ) { mandatory( obj, false, "base", appliance_base ); } @@ -1194,7 +1194,7 @@ std::unique_ptr reveal_map_actor::clone() const return std::make_unique( *this ); } -void reveal_map_actor::load( const JsonObject &obj ) +void reveal_map_actor::load( const JsonObject &obj, const std::string & ) { radius = obj.get_int( "radius" ); obj.get_member( "message" ).read( message ); @@ -1257,7 +1257,7 @@ std::optional reveal_map_actor::use( Character *p, item &it, const tripoint return 0; } -void firestarter_actor::load( const JsonObject &obj ) +void firestarter_actor::load( const JsonObject &obj, const std::string & ) { moves_cost_fast = obj.get_int( "moves", moves_cost_fast ); moves_cost_slow = obj.get_int( "moves_slow", moves_cost_fast * 10 ); @@ -1457,7 +1457,7 @@ std::optional firestarter_actor::use( Character *p, item &it, return 0; } -void salvage_actor::load( const JsonObject &obj ) +void salvage_actor::load( const JsonObject &obj, const std::string & ) { assign( obj, "cost", cost ); assign( obj, "moves_per_part", moves_per_part ); @@ -1785,7 +1785,7 @@ void salvage_actor::cut_up( Character &p, item_location &cut ) const } } -void inscribe_actor::load( const JsonObject &obj ) +void inscribe_actor::load( const JsonObject &obj, const std::string & ) { assign( obj, "cost", cost ); assign( obj, "on_items", on_items ); @@ -1935,7 +1935,7 @@ std::optional inscribe_actor::use( Character *p, item &it, const tripoint & return std::nullopt; } -void fireweapon_off_actor::load( const JsonObject &obj ) +void fireweapon_off_actor::load( const JsonObject &obj, const std::string & ) { obj.read( "target_id", target_id, true ); obj.read( "success_message", success_message ); @@ -1991,7 +1991,7 @@ ret_val fireweapon_off_actor::can_use( const Character &p, const item &it, return ret_val::make_success(); } -void fireweapon_on_actor::load( const JsonObject &obj ) +void fireweapon_on_actor::load( const JsonObject &obj, const std::string & ) { obj.read( "noise_message", noise_message ); obj.get_member( "charges_extinguish_message" ).read( charges_extinguish_message ); @@ -2039,7 +2039,7 @@ std::optional fireweapon_on_actor::use( Character *p, item &it, return 1; } -void manualnoise_actor::load( const JsonObject &obj ) +void manualnoise_actor::load( const JsonObject &obj, const std::string & ) { obj.get_member( "use_message" ).read( use_message ); obj.read( "noise_message", noise_message ); @@ -2076,7 +2076,7 @@ ret_val manualnoise_actor::can_use( const Character &p, const item &it, return ret_val::make_success(); } -void play_instrument_iuse::load( const JsonObject & ) +void play_instrument_iuse::load( const JsonObject &, const std::string & ) { } @@ -2113,7 +2113,7 @@ std::unique_ptr musical_instrument_actor::clone() const return std::make_unique( *this ); } -void musical_instrument_actor::load( const JsonObject &obj ) +void musical_instrument_actor::load( const JsonObject &obj, const std::string & ) { speed_penalty = obj.get_int( "speed_penalty", 10 ); volume = obj.get_int( "volume" ); @@ -2261,7 +2261,7 @@ std::unique_ptr learn_spell_actor::clone() const return std::make_unique( *this ); } -void learn_spell_actor::load( const JsonObject &obj ) +void learn_spell_actor::load( const JsonObject &obj, const std::string & ) { spells = obj.get_string_array( "spells" ); } @@ -2404,7 +2404,7 @@ std::unique_ptr cast_spell_actor::clone() const return std::make_unique( *this ); } -void cast_spell_actor::load( const JsonObject &obj ) +void cast_spell_actor::load( const JsonObject &obj, const std::string & ) { no_fail = obj.get_bool( "no_fail" ); item_spell = spell_id( obj.get_string( "spell_id" ) ); @@ -2478,7 +2478,7 @@ std::unique_ptr holster_actor::clone() const return std::make_unique( *this ); } -void holster_actor::load( const JsonObject &obj ) +void holster_actor::load( const JsonObject &obj, const std::string & ) { obj.read( "holster_prompt", holster_prompt ); obj.read( "holster_msg", holster_msg ); @@ -2633,7 +2633,7 @@ std::unique_ptr ammobelt_actor::clone() const return std::make_unique( *this ); } -void ammobelt_actor::load( const JsonObject &obj ) +void ammobelt_actor::load( const JsonObject &obj, const std::string & ) { belt = itype_id( obj.get_string( "belt" ) ); } @@ -2665,7 +2665,7 @@ std::optional ammobelt_actor::use( Character *p, item &, const tripoint & ) return 0; } -void repair_item_actor::load( const JsonObject &obj ) +void repair_item_actor::load( const JsonObject &obj, const std::string & ) { // Mandatory: for( const std::string line : obj.get_array( "materials" ) ) { @@ -3259,7 +3259,7 @@ std::string repair_item_actor::get_description() const return string_format( _( "Repair %s" ), mats ); } -void heal_actor::load( const JsonObject &obj ) +void heal_actor::load( const JsonObject &obj, const std::string & ) { // Mandatory move_cost = obj.get_int( "move_cost" ); @@ -3770,7 +3770,7 @@ void place_trap_actor::data::load( const JsonObject &obj ) assign( obj, "moves", moves ); } -void place_trap_actor::load( const JsonObject &obj ) +void place_trap_actor::load( const JsonObject &obj, const std::string & ) { assign( obj, "allow_underwater", allow_underwater ); assign( obj, "allow_under_player", allow_under_player ); @@ -3937,7 +3937,7 @@ std::optional place_trap_actor::use( Character *p, item &it, const tripoint return 1; } -void emit_actor::load( const JsonObject &obj ) +void emit_actor::load( const JsonObject &obj, const std::string & ) { assign( obj, "emits", emits ); assign( obj, "scale_qty", scale_qty ); @@ -3977,7 +3977,7 @@ void emit_actor::finalize( const itype_id &my_item_type ) } } -void saw_barrel_actor::load( const JsonObject &jo ) +void saw_barrel_actor::load( const JsonObject &jo, const std::string & ) { assign( jo, "cost", cost ); } @@ -4038,7 +4038,7 @@ std::unique_ptr saw_barrel_actor::clone() const return std::make_unique( *this ); } -void saw_stock_actor::load( const JsonObject &jo ) +void saw_stock_actor::load( const JsonObject &jo, const std::string & ) { assign( jo, "cost", cost ); } @@ -4113,7 +4113,7 @@ std::unique_ptr saw_stock_actor::clone() const return std::make_unique( *this ); } -void molle_attach_actor::load( const JsonObject &jo ) +void molle_attach_actor::load( const JsonObject &jo, const std::string & ) { assign( jo, "size", size ); assign( jo, "moves", moves ); @@ -4180,7 +4180,7 @@ std::unique_ptr molle_detach_actor::clone() const return std::make_unique( *this ); } -void molle_detach_actor::load( const JsonObject &jo ) +void molle_detach_actor::load( const JsonObject &jo, const std::string & ) { assign( jo, "moves", moves ); } @@ -4423,7 +4423,7 @@ void modify_gunmods_actor::finalize( const itype_id &my_item_type ) } } -void link_up_actor::load( const JsonObject &jo ) +void link_up_actor::load( const JsonObject &jo, const std::string & ) { jo.read( "cable_length", cable_length ); jo.read( "charge_rate", charge_rate ); @@ -5148,7 +5148,7 @@ std::unique_ptr deploy_tent_actor::clone() const return std::make_unique( *this ); } -void deploy_tent_actor::load( const JsonObject &obj ) +void deploy_tent_actor::load( const JsonObject &obj, const std::string & ) { assign( obj, "radius", radius ); assign( obj, "wall", wall ); @@ -5253,7 +5253,7 @@ std::optional weigh_self_actor::use( Character *p, item &, const tripoint & return 0; } -void weigh_self_actor::load( const JsonObject &jo ) +void weigh_self_actor::load( const JsonObject &jo, const std::string & ) { assign( jo, "max_weight", max_weight ); } @@ -5263,7 +5263,7 @@ std::unique_ptr weigh_self_actor::clone() const return std::make_unique( *this ); } -void sew_advanced_actor::load( const JsonObject &obj ) +void sew_advanced_actor::load( const JsonObject &obj, const std::string & ) { // Mandatory: for( const std::string line : obj.get_array( "materials" ) ) { @@ -5505,7 +5505,7 @@ std::unique_ptr sew_advanced_actor::clone() const return std::make_unique( *this ); } -void change_scent_iuse::load( const JsonObject &obj ) +void change_scent_iuse::load( const JsonObject &obj, const std::string & ) { scenttypeid = scenttype_id( obj.get_string( "scent_typeid" ) ); if( !scenttypeid.is_valid() ) { @@ -5551,12 +5551,12 @@ std::unique_ptr effect_on_conditons_actor::clone() const return std::make_unique( *this ); } -void effect_on_conditons_actor::load( const JsonObject &obj ) +void effect_on_conditons_actor::load( const JsonObject &obj, const std::string &src ) { obj.read( "description", description ); obj.read( "menu_text", menu_text ); for( JsonValue jv : obj.get_array( "effect_on_conditions" ) ) { - eocs.emplace_back( effect_on_conditions::load_inline_eoc( jv, "" ) ); + eocs.emplace_back( effect_on_conditions::load_inline_eoc( jv, src ) ); } } diff --git a/src/iuse_actor.h b/src/iuse_actor.h index 97e0db9669ab3..79eac39c44092 100644 --- a/src/iuse_actor.h +++ b/src/iuse_actor.h @@ -109,7 +109,7 @@ class iuse_transform : public iuse_actor explicit iuse_transform( const std::string &type = "transform" ) : iuse_actor( type ) {} ~iuse_transform() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; ret_val can_use( const Character &, const item &, const tripoint & ) const override; std::unique_ptr clone() const override; @@ -138,7 +138,7 @@ class unpack_actor : public iuse_actor explicit unpack_actor( const std::string &type = "unpack" ) : iuse_actor( type ) {} ~unpack_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *p, item &it, const tripoint & ) const override; std::unique_ptr clone() const override; void info( const item &, std::vector &dump ) const override; @@ -156,7 +156,7 @@ class message_iuse : public iuse_actor translation message; ~message_iuse() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; std::string get_name() const override; @@ -178,7 +178,7 @@ class sound_iuse : public iuse_actor std::string sound_variant = "default"; ~sound_iuse() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; std::string get_name() const override; @@ -216,7 +216,7 @@ class explosion_iuse : public iuse_actor explicit explosion_iuse( const std::string &type = "explosion" ) : iuse_actor( type ) {} ~explosion_iuse() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; void info( const item &, std::vector & ) const override; @@ -264,7 +264,7 @@ class consume_drug_iuse : public iuse_actor explicit consume_drug_iuse( const std::string &type = "consume_drug" ) : iuse_actor( type ) {} ~consume_drug_iuse() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; void info( const item &, std::vector & ) const override; @@ -299,7 +299,7 @@ class delayed_transform_iuse : public iuse_transform type ) {} ~delayed_transform_iuse() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; }; @@ -332,7 +332,7 @@ class place_monster_iuse : public iuse_actor place_monster_iuse() : iuse_actor( "place_monster" ) { } ~place_monster_iuse() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; }; @@ -360,7 +360,7 @@ class change_scent_iuse : public iuse_actor change_scent_iuse() : iuse_actor( "change_scent" ) { } ~change_scent_iuse() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; }; @@ -379,7 +379,7 @@ class place_npc_iuse : public iuse_actor place_npc_iuse() : iuse_actor( "place_npc" ) { } ~place_npc_iuse() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; }; @@ -398,7 +398,7 @@ class deploy_furn_actor : public iuse_actor deploy_furn_actor() : iuse_actor( "deploy_furn" ) {} ~deploy_furn_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; void info( const item &, std::vector & ) const override; @@ -415,7 +415,7 @@ class deploy_appliance_actor : public iuse_actor deploy_appliance_actor() : iuse_actor( "deploy_appliance" ) {} ~deploy_appliance_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; void info( const item &, std::vector & ) const override; @@ -451,7 +451,7 @@ class reveal_map_actor : public iuse_actor explicit reveal_map_actor( const std::string &type = "reveal_map" ) : iuse_actor( type ) {} ~reveal_map_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; }; @@ -488,7 +488,7 @@ class firestarter_actor : public iuse_actor explicit firestarter_actor( const std::string &type = "firestarter" ) : iuse_actor( type ) {} ~firestarter_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; ret_val can_use( const Character &, const item &, const tripoint & ) const override; std::unique_ptr clone() const override; @@ -510,7 +510,7 @@ class salvage_actor : public iuse_actor explicit salvage_actor( const std::string &type = "salvage" ) : iuse_actor( type ) {} ~salvage_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; private: @@ -553,7 +553,7 @@ class inscribe_actor : public iuse_actor explicit inscribe_actor( const std::string &type = "inscribe" ) : iuse_actor( type ) {} ~inscribe_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; }; @@ -576,7 +576,7 @@ class fireweapon_off_actor : public iuse_actor fireweapon_off_actor() : iuse_actor( "fireweapon_off" ) {} ~fireweapon_off_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; ret_val can_use( const Character &, const item &, const tripoint & ) const override; std::unique_ptr clone() const override; @@ -597,7 +597,7 @@ class fireweapon_on_actor : public iuse_actor explicit fireweapon_on_actor( const std::string &type = "fireweapon_on" ) : iuse_actor( type ) {} ~fireweapon_on_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; }; @@ -618,7 +618,7 @@ class manualnoise_actor : public iuse_actor explicit manualnoise_actor( const std::string &type = "manualnoise" ) : iuse_actor( type ) {} ~manualnoise_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; ret_val can_use( const Character &, const item &, const tripoint & ) const override; std::unique_ptr clone() const override; @@ -630,7 +630,7 @@ class play_instrument_iuse : public iuse_actor explicit play_instrument_iuse( const std::string &type = "play_instrument" ) : iuse_actor( type ) {} ~play_instrument_iuse() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; ret_val can_use( const Character &, const item &, const tripoint & ) const override; std::unique_ptr clone() const override; @@ -675,7 +675,7 @@ class musical_instrument_actor : public iuse_actor type ) {} ~musical_instrument_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; ret_val can_use( const Character &, const item &, const tripoint & ) const override; std::unique_ptr clone() const override; @@ -693,7 +693,7 @@ class learn_spell_actor : public iuse_actor explicit learn_spell_actor( const std::string &type = "learn_spell" ) : iuse_actor( type ) {} ~learn_spell_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *p, item &, const tripoint & ) const override; std::unique_ptr clone() const override; void info( const item &, std::vector & ) const override; @@ -720,7 +720,7 @@ class cast_spell_actor : public iuse_actor explicit cast_spell_actor( const std::string &type = "cast_spell" ) : iuse_actor( type ) {} ~cast_spell_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *p, item &it, const tripoint & ) const override; std::unique_ptr clone() const override; void info( const item &, std::vector & ) const override; @@ -747,7 +747,7 @@ class holster_actor : public iuse_actor explicit holster_actor( const std::string &type = "holster" ) : iuse_actor( type ) {} ~holster_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; void info( const item &, std::vector & ) const override; @@ -761,7 +761,7 @@ class ammobelt_actor : public iuse_actor ammobelt_actor() : iuse_actor( "ammobelt" ) {} ~ammobelt_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; void info( const item &, std::vector & ) const override; @@ -852,7 +852,7 @@ class repair_item_actor : public iuse_actor explicit repair_item_actor( const std::string &type = "repair_item" ) : iuse_actor( type ) {} ~repair_item_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; @@ -919,7 +919,7 @@ class heal_actor : public iuse_actor explicit heal_actor( const std::string &type = "heal" ) : iuse_actor( type ) {} ~heal_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; void info( const item &, std::vector & ) const override; @@ -966,7 +966,7 @@ class place_trap_actor : public iuse_actor explicit place_trap_actor( const std::string &type = "place_trap" ); ~place_trap_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; }; @@ -980,7 +980,7 @@ class emit_actor : public iuse_actor explicit emit_actor( const std::string &type = "emit_actor" ) : iuse_actor( type ) {} ~emit_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; void finalize( const itype_id &my_item_type ) override; @@ -991,7 +991,7 @@ class saw_barrel_actor : public iuse_actor public: explicit saw_barrel_actor( const std::string &type = "saw_barrel" ) : iuse_actor( type ) {} - void load( const JsonObject &jo ) override; + void load( const JsonObject &jo, const std::string & ) override; std::optional use( Character *p, item &it, const tripoint &pnt ) const override; std::unique_ptr clone() const override; @@ -1003,7 +1003,7 @@ class saw_stock_actor : public iuse_actor public: explicit saw_stock_actor( const std::string &type = "saw_stock" ) : iuse_actor( type ) {} - void load( const JsonObject &jo ) override; + void load( const JsonObject &jo, const std::string & ) override; std::optional use( Character *p, item &it, const tripoint &pnt ) const override; std::unique_ptr clone() const override; @@ -1019,7 +1019,7 @@ class molle_attach_actor : public iuse_actor int size; int moves; - void load( const JsonObject &jo ) override; + void load( const JsonObject &jo, const std::string & ) override; std::optional use( Character *p, item &it, const tripoint &pnt ) const override; std::unique_ptr clone() const override; }; @@ -1032,7 +1032,7 @@ class molle_detach_actor : public iuse_actor int moves; - void load( const JsonObject &jo ) override; + void load( const JsonObject &jo, const std::string & ) override; std::optional use( Character *p, item &it, const tripoint &pnt ) const override; std::unique_ptr clone() const override; }; @@ -1042,7 +1042,7 @@ class install_bionic_actor : public iuse_actor public: explicit install_bionic_actor( const std::string &type = "install_bionic" ) : iuse_actor( type ) {} - void load( const JsonObject & ) override {} + void load( const JsonObject &, const std::string & ) override {} std::optional use( Character *p, item &it, const tripoint &pnt ) const override; ret_val can_use( const Character &, const item &it, const tripoint & ) const override; std::unique_ptr clone() const override; @@ -1054,7 +1054,7 @@ class detach_gunmods_actor : public iuse_actor public: explicit detach_gunmods_actor( const std::string &type = "detach_gunmods" ) : iuse_actor( type ) {} - void load( const JsonObject & ) override {} + void load( const JsonObject &, const std::string & ) override {} std::optional use( Character *p, item &it, const tripoint &pnt ) const override; ret_val can_use( const Character &, const item &it, const tripoint & ) const override; std::unique_ptr clone() const override; @@ -1066,7 +1066,7 @@ class modify_gunmods_actor : public iuse_actor public: explicit modify_gunmods_actor( const std::string &type = "modify_gunmods" ) : iuse_actor( type ) {} - void load( const JsonObject & ) override {} + void load( const JsonObject &, const std::string & ) override {} std::optional use( Character *p, item &it, const tripoint &pnt ) const override; ret_val can_use( const Character &, const item &it, const tripoint & ) const override; std::unique_ptr clone() const override; @@ -1098,7 +1098,7 @@ class link_up_actor : public iuse_actor link_up_actor() : iuse_actor( "link_up" ) {} ~link_up_actor() override = default; - void load( const JsonObject &jo ) override; + void load( const JsonObject &jo, const std::string & ) override; std::unique_ptr clone() const override; std::string get_name() const override; void info( const item &, std::vector & ) const override; @@ -1119,7 +1119,7 @@ class deploy_tent_actor : public iuse_actor deploy_tent_actor() : iuse_actor( "deploy_tent" ) {} ~deploy_tent_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; @@ -1138,7 +1138,7 @@ class weigh_self_actor : public iuse_actor explicit weigh_self_actor( const std::string &type = "weigh_self" ) : iuse_actor( type ) {} ~weigh_self_actor() override = default; - void load( const JsonObject &jo ) override; + void load( const JsonObject &jo, const std::string & ) override; std::optional use( Character *p, item &, const tripoint & ) const override; std::unique_ptr clone() const override; void info( const item &, std::vector & ) const override; @@ -1160,7 +1160,7 @@ class sew_advanced_actor : public iuse_actor explicit sew_advanced_actor( const std::string &type = "sew_advanced" ) : iuse_actor( type ) {} ~sew_advanced_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string & ) override; std::optional use( Character *, item &, const tripoint & ) const override; std::unique_ptr clone() const override; }; @@ -1178,7 +1178,7 @@ class effect_on_conditons_actor : public iuse_actor type ) {} ~effect_on_conditons_actor() override = default; - void load( const JsonObject &obj ) override; + void load( const JsonObject &obj, const std::string &src ) override; std::optional use( Character *p, item &it, const tripoint &point ) const override; std::unique_ptr clone() const override; std::string get_name() const override; diff --git a/src/magic_enchantment.cpp b/src/magic_enchantment.cpp index 5bc094b2bfaf9..1b0be70dea650 100644 --- a/src/magic_enchantment.cpp +++ b/src/magic_enchantment.cpp @@ -240,13 +240,10 @@ enchantment_id enchantment::load_inline_enchantment( const JsonValue &jv, if( inline_id.empty() ) { jv.throw_error( "Inline enchantment cannot be created without an id." ); } - if( spell_factory.is_valid( enchantment_id( inline_id ) ) ) { - jv.throw_error( "Inline enchantment " + inline_id + - " cannot be created as an enchantment already has this id." ); - } enchantment inline_enchant; inline_enchant.load( jv.get_object(), src, inline_id ); + mod_tracker::assign_src( inline_enchant, src ); spell_factory.insert( inline_enchant ); return enchantment_id( inline_id ); } else { diff --git a/src/mapdata.cpp b/src/mapdata.cpp index 3872a50a7c7c5..2a4a0085d4afe 100644 --- a/src/mapdata.cpp +++ b/src/mapdata.cpp @@ -822,7 +822,7 @@ void init_mapdata() add_actor( std::make_unique() ); } -void map_data_common_t::load( const JsonObject &jo, const std::string & ) +void map_data_common_t::load( const JsonObject &jo, const std::string &src ) { if( jo.has_string( "examine_action" ) ) { examine_actor = nullptr; @@ -830,7 +830,7 @@ void map_data_common_t::load( const JsonObject &jo, const std::string & ) } else if( jo.has_object( "examine_action" ) ) { JsonObject data = jo.get_object( "examine_action" ); examine_actor = iexamine_actor_from_jsobj( data ); - examine_actor->load( data ); + examine_actor->load( data, src ); examine_func = iexamine_functions_from_string( "invalid" ); } else if( !was_loaded ) { examine_actor = nullptr; diff --git a/src/mission.h b/src/mission.h index 5e7c3a2623f5f..6ad01ef886796 100644 --- a/src/mission.h +++ b/src/mission.h @@ -260,7 +260,8 @@ struct mission_type { static void finalize(); static void check_consistency(); - bool parse_funcs( const JsonObject &jo, std::function &phase_func ); + bool parse_funcs( const JsonObject &jo, std::string_view src, + std::function &phase_func ); void load( const JsonObject &jo, const std::string &src ); /** diff --git a/src/mission_util.cpp b/src/mission_util.cpp index b5cc7d0b4c5e2..d50189f7199a0 100644 --- a/src/mission_util.cpp +++ b/src/mission_util.cpp @@ -526,7 +526,8 @@ bool mission_util::load_funcs( const JsonObject &jo, return true; } -bool mission_type::parse_funcs( const JsonObject &jo, std::function &phase_func ) +bool mission_type::parse_funcs( const JsonObject &jo, const std::string_view src, + std::function &phase_func ) { std::vector> funcs; if( !mission_util::load_funcs( jo, funcs ) ) { @@ -537,7 +538,7 @@ bool mission_type::parse_funcs( const JsonObject &jo, std::functionfind_npc( miss->get_npc_id() ); ::dialogue d( get_talker_for( get_avatar() ), diff --git a/src/missiondef.cpp b/src/missiondef.cpp index a942ec3e6851c..c7f2b1ff96e88 100644 --- a/src/missiondef.cpp +++ b/src/missiondef.cpp @@ -365,7 +365,7 @@ void mission_type::load( const JsonObject &jo, const std::string &src ) assign_function( jo, phase, phase_func, mission_function_map ); } else if( jo.has_member( phase ) ) { JsonObject j_start = jo.get_object( phase ); - if( !parse_funcs( j_start, phase_func ) ) { + if( !parse_funcs( j_start, src, phase_func ) ) { deferred.emplace_back( jo, src ); jo.allow_omitted_members(); j_start.allow_omitted_members(); diff --git a/src/npc.cpp b/src/npc.cpp index 79fddacf97d07..dee63fcc56c64 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -296,7 +296,7 @@ npc &npc::operator=( npc && ) noexcept( list_is_noexcept ) = default; static std::map, npc_template> npc_templates; -void npc_template::load( const JsonObject &jsobj ) +void npc_template::load( const JsonObject &jsobj, const std::string_view src ) { npc_template tem; npc &guy = tem.guy; @@ -450,7 +450,7 @@ void npc_template::load( const JsonObject &jsobj ) tem.personality->altruism = personality.get_int( "altruism" ); } for( JsonValue jv : jsobj.get_array( "death_eocs" ) ) { - guy.death_eocs.emplace_back( effect_on_conditions::load_inline_eoc( jv, "" ) ); + guy.death_eocs.emplace_back( effect_on_conditions::load_inline_eoc( jv, src ) ); } npc_templates.emplace( guy.idz, std::move( tem ) ); diff --git a/src/npc.h b/src/npc.h index c087293756f31..61e9206412771 100644 --- a/src/npc.h +++ b/src/npc.h @@ -1513,7 +1513,7 @@ class npc_template std::optional per; std::optional personality; - static void load( const JsonObject &jsobj ); + static void load( const JsonObject &jsobj, std::string_view src ); static void reset(); static void check_consistency(); }; diff --git a/src/npctalk.cpp b/src/npctalk.cpp index 1dea0eac3d7b2..95de6f3e67983 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -127,29 +127,33 @@ using item_menu = std::function; using item_menu_mul = std::function; struct sub_effect_parser { - using f_t = talk_effect_fun_t::func( * )( const JsonObject &, std::string_view ); - using f_t_beta = talk_effect_fun_t::func( * )( const JsonObject &, std::string_view, bool ); - using f_t_effect = talk_effect_fun_t ( * )( const JsonObject &, std::string_view ); - using f_t_beta_effect = talk_effect_fun_t ( * )( const JsonObject &, std::string_view, bool ); + using f_t = talk_effect_fun_t::func( * )( const JsonObject &, std::string_view, + const std::string_view src ); + using f_t_beta = talk_effect_fun_t::func( * )( const JsonObject &, std::string_view, + const std::string_view src, bool ); + using f_t_effect = talk_effect_fun_t ( * )( const JsonObject &, std::string_view, + const std::string_view src ); + using f_t_beta_effect = talk_effect_fun_t ( * )( const JsonObject &, std::string_view, + const std::string_view src, bool ); sub_effect_parser( std::string_view key_alpha_, jarg arg_, f_t f_ ) : key_alpha( key_alpha_ ), arg( arg_ ) { - f = [f_]( const JsonObject & jo, std::string_view key, bool ) { - return talk_effect_fun_t( f_( jo, key ) ); + f = [f_]( const JsonObject & jo, std::string_view key, const std::string_view src, bool ) { + return talk_effect_fun_t( f_( jo, key, src ) ); }; } sub_effect_parser( std::string_view key_alpha_, std::string_view key_beta_, jarg arg_, f_t_beta f_ ) : key_alpha( key_alpha_ ), key_beta( key_beta_ ), arg( arg_ ) { - f = [f_]( const JsonObject & jo, std::string_view key, bool beta ) { - return talk_effect_fun_t( f_( jo, key, beta ) ); + f = [f_]( const JsonObject & jo, std::string_view key, const std::string_view src, bool beta ) { + return talk_effect_fun_t( f_( jo, key, src, beta ) ); }; has_beta = true; } sub_effect_parser( std::string_view key_alpha_, jarg arg_, f_t_effect f_ ) : key_alpha( key_alpha_ ), arg( arg_ ) { - f = [f_]( const JsonObject & jo, std::string_view key, bool ) { - return f_( jo, key ); + f = [f_]( const JsonObject & jo, std::string_view key, const std::string_view src, bool ) { + return f_( jo, key, src ); }; } @@ -168,7 +172,8 @@ struct sub_effect_parser { std::string_view key_alpha; std::string_view key_beta; jarg arg; - std::function f; + std::function + f; }; struct item_search_data { @@ -269,15 +274,15 @@ static void run_eoc_vector( const std::vector &eocs, con } static std::vector load_eoc_vector( const JsonObject &jo, - const std::string_view member ) + const std::string_view member, const std::string_view src ) { std::vector eocs; if( jo.has_array( member ) ) { for( JsonValue jv : jo.get_array( member ) ) { - eocs.push_back( effect_on_conditions::load_inline_eoc( jv, "" ) ); + eocs.push_back( effect_on_conditions::load_inline_eoc( jv, src ) ); } } else if( jo.has_member( member ) ) { - eocs.push_back( effect_on_conditions::load_inline_eoc( jo.get_member( member ), "" ) ); + eocs.push_back( effect_on_conditions::load_inline_eoc( jo.get_member( member ), src ) ); } return eocs; } @@ -288,10 +293,10 @@ struct eoc_entry { }; static std::vector load_eoc_vector_id_and_var( - const JsonObject &jo, const std::string_view member ) + const JsonObject &jo, const std::string_view member, const std::string_view src ) { std::vector eocs_entries; - auto process_jv = [member, &eocs_entries]( const JsonValue & jv ) { + auto process_jv = [member, &eocs_entries, &src]( const JsonValue & jv ) { eoc_entry entry; if( jv.test_object() ) { JsonObject jo = jv.get_object(); @@ -301,7 +306,7 @@ load_eoc_vector_id_and_var( } } if( !entry.var ) { - entry.id = effect_on_conditions::load_inline_eoc( jv, "" ); + entry.id = effect_on_conditions::load_inline_eoc( jv, src ); } eocs_entries.push_back( entry ); }; @@ -2747,10 +2752,10 @@ talk_trial::talk_trial( const JsonObject &jo ) } } -static talk_topic load_inline_topic( const JsonObject &jo ) +static talk_topic load_inline_topic( const JsonObject &jo, const std::string_view src ) { const std::string id = jo.get_string( "id" ); - json_talk_topics[id].load( jo ); + json_talk_topics[id].load( jo, src ); return talk_topic( id ); } @@ -2897,7 +2902,8 @@ namespace talk_effect_fun { namespace { -talk_effect_fun_t::func f_companion_mission( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_companion_mission( const JsonObject &jo, std::string_view member, + const std::string_view ) { str_or_var id = get_str_or_var( jo.get_member( member ), member, true ); return [id]( dialogue const & d ) { @@ -2907,7 +2913,7 @@ talk_effect_fun_t::func f_companion_mission( const JsonObject &jo, std::string_v } talk_effect_fun_t::func f_add_effect( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var new_effect = get_str_or_var( jo.get_member( member ), member, true ); bool permanent = false; @@ -2945,7 +2951,7 @@ talk_effect_fun_t::func f_add_effect( const JsonObject &jo, std::string_view mem } talk_effect_fun_t::func f_remove_effect( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var old_effect = get_str_or_var( jo.get_member( member ), member, true ); @@ -2962,7 +2968,7 @@ talk_effect_fun_t::func f_remove_effect( const JsonObject &jo, std::string_view } talk_effect_fun_t::func f_add_trait( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var new_trait = get_str_or_var( jo.get_member( member ), member, true ); str_or_var new_variant; @@ -2982,7 +2988,7 @@ talk_effect_fun_t::func f_add_trait( const JsonObject &jo, std::string_view memb } talk_effect_fun_t::func f_activate_trait( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var new_trait = get_str_or_var( jo.get_member( member ), member, true ); return [is_npc, new_trait]( dialogue const & d ) { @@ -2991,7 +2997,7 @@ talk_effect_fun_t::func f_activate_trait( const JsonObject &jo, std::string_view } talk_effect_fun_t::func f_deactivate_trait( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var new_trait = get_str_or_var( jo.get_member( member ), member, true ); return [is_npc, new_trait]( dialogue const & d ) { @@ -3000,7 +3006,7 @@ talk_effect_fun_t::func f_deactivate_trait( const JsonObject &jo, std::string_vi } talk_effect_fun_t::func f_remove_trait( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var old_trait = get_str_or_var( jo.get_member( member ), member, true ); return [is_npc, old_trait]( dialogue const & d ) { @@ -3009,7 +3015,7 @@ talk_effect_fun_t::func f_remove_trait( const JsonObject &jo, std::string_view m } talk_effect_fun_t::func f_learn_martial_art( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var ma_to_learn = get_str_or_var( jo.get_member( member ), member, true ); return [is_npc, ma_to_learn]( dialogue const & d ) { @@ -3018,7 +3024,7 @@ talk_effect_fun_t::func f_learn_martial_art( const JsonObject &jo, std::string_v } talk_effect_fun_t::func f_forget_martial_art( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var ma_to_forget = get_str_or_var( jo.get_member( member ), member, true ); return [is_npc, ma_to_forget]( dialogue const & d ) { @@ -3027,7 +3033,7 @@ talk_effect_fun_t::func f_forget_martial_art( const JsonObject &jo, std::string_ } talk_effect_fun_t::func f_mutate( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { dbl_or_var highest_cat = get_dbl_or_var( jo, member, true, 0 ); const bool use_vitamins = jo.get_bool( "use_vitamins", true ); @@ -3037,7 +3043,7 @@ talk_effect_fun_t::func f_mutate( const JsonObject &jo, std::string_view member, } talk_effect_fun_t::func f_mutate_category( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var mut_cat = get_str_or_var( jo.get_member( member ), member, true, "" ); const bool use_vitamins = jo.get_bool( "use_vitamins", true ); @@ -3047,7 +3053,7 @@ talk_effect_fun_t::func f_mutate_category( const JsonObject &jo, std::string_vie } talk_effect_fun_t::func f_mutate_towards( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var trait = get_str_or_var( jo.get_member( member ), member, true, "" ); str_or_var mut_cat; @@ -3065,7 +3071,7 @@ talk_effect_fun_t::func f_mutate_towards( const JsonObject &jo, std::string_view } talk_effect_fun_t::func f_add_bionic( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var new_bionic = get_str_or_var( jo.get_member( member ), member, true ); return [is_npc, new_bionic]( dialogue const & d ) { @@ -3074,7 +3080,7 @@ talk_effect_fun_t::func f_add_bionic( const JsonObject &jo, std::string_view mem } talk_effect_fun_t::func f_lose_bionic( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var old_bionic = get_str_or_var( jo.get_member( member ), member, true ); return [is_npc, old_bionic]( dialogue const & d ) { @@ -3083,7 +3089,7 @@ talk_effect_fun_t::func f_lose_bionic( const JsonObject &jo, std::string_view me } talk_effect_fun_t::func f_add_var( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { dbl_or_var empty; const std::string var_name = get_talk_varname( jo, member, false, empty ); @@ -3107,7 +3113,7 @@ talk_effect_fun_t::func f_add_var( const JsonObject &jo, std::string_view member } talk_effect_fun_t::func f_remove_var( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { dbl_or_var empty; const std::string var_name = get_talk_varname( jo, member, false, empty ); @@ -3214,7 +3220,8 @@ void receive_item( itype_id &item_name, int count, std::string_view container_na } } -talk_effect_fun_t f_spawn_item( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t f_spawn_item( const JsonObject &jo, std::string_view member, + const std::string_view ) { str_or_var item_name = get_str_or_var( jo.get_member( member ), member, true ); str_or_var container_name; @@ -3263,10 +3270,11 @@ talk_effect_fun_t f_spawn_item( const JsonObject &jo, std::string_view member ) return ret; } -talk_effect_fun_t::func f_u_buy_item( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_u_buy_item( const JsonObject &jo, std::string_view member, + const std::string_view src ) { - std::vector true_eocs = load_eoc_vector( jo, "true_eocs" ); - std::vector false_eocs = load_eoc_vector( jo, "false_eocs" ); + std::vector true_eocs = load_eoc_vector( jo, "true_eocs", src ); + std::vector false_eocs = load_eoc_vector( jo, "false_eocs", src ); dbl_or_var cost = get_dbl_or_var( jo, "cost", false, 0 ); dbl_or_var count; if( !jo.has_int( "charges" ) ) { @@ -3307,10 +3315,11 @@ talk_effect_fun_t::func f_u_buy_item( const JsonObject &jo, std::string_view mem }; } -talk_effect_fun_t::func f_u_sell_item( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_u_sell_item( const JsonObject &jo, std::string_view member, + const std::string_view src ) { - std::vector true_eocs = load_eoc_vector( jo, "true_eocs" ); - std::vector false_eocs = load_eoc_vector( jo, "false_eocs" ); + std::vector true_eocs = load_eoc_vector( jo, "true_eocs", src ); + std::vector false_eocs = load_eoc_vector( jo, "false_eocs", src ); dbl_or_var cost = get_dbl_or_var( jo, "cost", false, 0 ); dbl_or_var count; if( !jo.has_int( "charges" ) ) { @@ -3354,7 +3363,7 @@ talk_effect_fun_t::func f_u_sell_item( const JsonObject &jo, std::string_view me } talk_effect_fun_t::func f_consume_item( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var item_name = get_str_or_var( jo.get_member( member ), member, true ); dbl_or_var charges = get_dbl_or_var( jo, "charges", false, 0 ); @@ -3409,7 +3418,7 @@ talk_effect_fun_t::func f_consume_item( const JsonObject &jo, std::string_view m } talk_effect_fun_t::func f_remove_item_with( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var item_name = get_str_or_var( jo.get_member( member ), member, true ); return [is_npc, item_name]( dialogue const & d ) { @@ -3420,11 +3429,12 @@ talk_effect_fun_t::func f_remove_item_with( const JsonObject &jo, std::string_vi }; } -talk_effect_fun_t::func f_u_spend_cash( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_u_spend_cash( const JsonObject &jo, std::string_view member, + const std::string_view src ) { dbl_or_var amount = get_dbl_or_var( jo, member ); - std::vector true_eocs = load_eoc_vector( jo, "true_eocs" ); - std::vector false_eocs = load_eoc_vector( jo, "false_eocs" ); + std::vector true_eocs = load_eoc_vector( jo, "true_eocs", src ); + std::vector false_eocs = load_eoc_vector( jo, "false_eocs", src ); return [amount, true_eocs, false_eocs]( dialogue & d ) { if( d.actor( true )->buy_from( amount.evaluate( d ) ) ) { run_eoc_vector( true_eocs, d ); @@ -3434,7 +3444,8 @@ talk_effect_fun_t::func f_u_spend_cash( const JsonObject &jo, std::string_view m }; } -talk_effect_fun_t::func f_npc_change_faction( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_npc_change_faction( const JsonObject &jo, std::string_view member, + const std::string_view ) { str_or_var faction_name = get_str_or_var( jo.get_member( member ), member, true ); return [faction_name]( dialogue const & d ) { @@ -3442,7 +3453,8 @@ talk_effect_fun_t::func f_npc_change_faction( const JsonObject &jo, std::string_ }; } -talk_effect_fun_t::func f_npc_change_class( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_npc_change_class( const JsonObject &jo, std::string_view member, + const std::string_view ) { str_or_var class_name = get_str_or_var( jo.get_member( member ), member, true ); return [class_name]( dialogue const & d ) { @@ -3450,7 +3462,8 @@ talk_effect_fun_t::func f_npc_change_class( const JsonObject &jo, std::string_vi }; } -talk_effect_fun_t::func f_change_faction_rep( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_change_faction_rep( const JsonObject &jo, std::string_view member, + const std::string_view ) { dbl_or_var rep_change = get_dbl_or_var( jo, member ); return [rep_change]( dialogue & d ) { @@ -3458,7 +3471,8 @@ talk_effect_fun_t::func f_change_faction_rep( const JsonObject &jo, std::string_ }; } -talk_effect_fun_t::func f_add_debt( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_add_debt( const JsonObject &jo, std::string_view member, + const std::string_view ) { std::vector debt_modifiers; for( JsonArray jmod : jo.get_array( member ) ) { @@ -3480,7 +3494,8 @@ talk_effect_fun_t::func f_add_debt( const JsonObject &jo, std::string_view membe }; } -talk_effect_fun_t::func f_toggle_npc_rule( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_toggle_npc_rule( const JsonObject &jo, std::string_view member, + const std::string_view ) { str_or_var rule = get_str_or_var( jo.get_member( member ), member, true ); return [rule]( dialogue const & d ) { @@ -3488,7 +3503,8 @@ talk_effect_fun_t::func f_toggle_npc_rule( const JsonObject &jo, std::string_vie }; } -talk_effect_fun_t::func f_set_npc_rule( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_set_npc_rule( const JsonObject &jo, std::string_view member, + const std::string_view ) { str_or_var rule = get_str_or_var( jo.get_member( member ), member, true ); return [rule]( dialogue const & d ) { @@ -3496,7 +3512,8 @@ talk_effect_fun_t::func f_set_npc_rule( const JsonObject &jo, std::string_view m }; } -talk_effect_fun_t::func f_clear_npc_rule( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_clear_npc_rule( const JsonObject &jo, std::string_view member, + const std::string_view ) { str_or_var rule = get_str_or_var( jo.get_member( member ), member, true ); return [rule]( dialogue const & d ) { @@ -3505,7 +3522,7 @@ talk_effect_fun_t::func f_clear_npc_rule( const JsonObject &jo, std::string_view } talk_effect_fun_t::func f_npc_engagement_rule( const JsonObject &jo, - std::string_view member ) + std::string_view member, const std::string_view ) { str_or_var rule = get_str_or_var( jo.get_member( member ), member, true ); return [rule]( dialogue const & d ) { @@ -3513,7 +3530,8 @@ talk_effect_fun_t::func f_npc_engagement_rule( const JsonObject &jo, }; } -talk_effect_fun_t::func f_npc_aim_rule( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_npc_aim_rule( const JsonObject &jo, std::string_view member, + const std::string_view ) { str_or_var rule = get_str_or_var( jo.get_member( member ), member, true ); return [rule]( dialogue const & d ) { @@ -3522,7 +3540,7 @@ talk_effect_fun_t::func f_npc_aim_rule( const JsonObject &jo, std::string_view m } talk_effect_fun_t::func f_npc_cbm_reserve_rule( const JsonObject &jo, - std::string_view member ) + std::string_view member, const std::string_view ) { str_or_var rule = get_str_or_var( jo.get_member( member ), member, true ); return [rule]( dialogue const & d ) { @@ -3531,7 +3549,7 @@ talk_effect_fun_t::func f_npc_cbm_reserve_rule( const JsonObject &jo, } talk_effect_fun_t::func f_npc_cbm_recharge_rule( const JsonObject &jo, - std::string_view member ) + std::string_view member, const std::string_view ) { str_or_var rule = get_str_or_var( jo.get_member( member ), member, true ); return [rule]( dialogue const & d ) { @@ -3540,7 +3558,7 @@ talk_effect_fun_t::func f_npc_cbm_recharge_rule( const JsonObject &jo, } talk_effect_fun_t::func f_location_variable( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view src, bool is_npc ) { dbl_or_var dov_min_radius = get_dbl_or_var( jo, "min_radius", false, 0 ); dbl_or_var dov_max_radius = get_dbl_or_var( jo, "max_radius", false, 0 ); @@ -3595,8 +3613,8 @@ talk_effect_fun_t::func f_location_variable( const JsonObject &jo, std::string_v var_type type = var.type; std::string var_name = var.name; - std::vector true_eocs = load_eoc_vector( jo, "true_eocs" ); - std::vector false_eocs = load_eoc_vector( jo, "false_eocs" ); + std::vector true_eocs = load_eoc_vector( jo, "true_eocs", src ); + std::vector false_eocs = load_eoc_vector( jo, "false_eocs", src ); return [dov_min_radius, dov_max_radius, var_name, outdoor_only, passable_only, target_params, is_npc, type, dov_x_adjust, dov_y_adjust, dov_z_adjust, z_override, true_eocs, false_eocs, @@ -3726,7 +3744,7 @@ talk_effect_fun_t::func f_location_variable( const JsonObject &jo, std::string_v } talk_effect_fun_t::func f_location_variable_adjust( const JsonObject &jo, - std::string_view member ) + std::string_view member, const std::string_view ) { dbl_or_var dov_z_adjust = get_dbl_or_var( jo, "z_adjust", false, 0 ); dbl_or_var dov_x_adjust = get_dbl_or_var( jo, "x_adjust", false, 0 ); @@ -3765,7 +3783,7 @@ talk_effect_fun_t::func f_location_variable_adjust( const JsonObject &jo, } talk_effect_fun_t::func f_transform_radius( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var transform = get_str_or_var( jo.get_member( "ter_furn_transform" ), "ter_furn_transform", true ); @@ -3810,7 +3828,8 @@ talk_effect_fun_t::func f_transform_radius( const JsonObject &jo, std::string_vi }; } -talk_effect_fun_t::func f_transform_line( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_transform_line( const JsonObject &jo, std::string_view member, + const std::string_view ) { str_or_var transform = get_str_or_var( jo.get_member( member ), member, true ); var_info first = read_var_info( jo.get_object( "first" ) ); @@ -3826,7 +3845,8 @@ talk_effect_fun_t::func f_transform_line( const JsonObject &jo, std::string_view }; } -talk_effect_fun_t::func f_place_override( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_place_override( const JsonObject &jo, std::string_view member, + const std::string_view ) { translation_or_var new_place = get_translation_or_var( jo.get_member( member ), member ); duration_or_var dov_length = get_duration_or_var( jo, "length", true ); @@ -3844,7 +3864,8 @@ talk_effect_fun_t::func f_place_override( const JsonObject &jo, std::string_view }; } -talk_effect_fun_t::func f_mapgen_update( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_mapgen_update( const JsonObject &jo, std::string_view member, + const std::string_view ) { mission_target_params target_params = mission_util::parse_mission_om_target( jo ); std::vector update_ids; @@ -3899,7 +3920,8 @@ talk_effect_fun_t::func f_mapgen_update( const JsonObject &jo, std::string_view }; } -talk_effect_fun_t::func f_alter_timed_events( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_alter_timed_events( const JsonObject &jo, std::string_view member, + const std::string_view ) { str_or_var key = get_str_or_var( jo.get_member( member ), member, true ); duration_or_var time_in_future = get_duration_or_var( jo, "time_in_future", false, @@ -3909,7 +3931,8 @@ talk_effect_fun_t::func f_alter_timed_events( const JsonObject &jo, std::string_ }; } -talk_effect_fun_t::func f_revert_location( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_revert_location( const JsonObject &jo, std::string_view member, + const std::string_view ) { duration_or_var dov_time_in_future = get_duration_or_var( jo, "time_in_future", true ); str_or_var key; @@ -3950,12 +3973,12 @@ talk_effect_fun_t::func f_revert_location( const JsonObject &jo, std::string_vie } talk_effect_fun_t::func f_npc_goal( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view src, bool is_npc ) { mission_target_params dest_params = mission_util::parse_mission_om_target( jo.get_object( member ) ); - std::vector true_eocs = load_eoc_vector( jo, "true_eocs" ); - std::vector false_eocs = load_eoc_vector( jo, "false_eocs" ); + std::vector true_eocs = load_eoc_vector( jo, "true_eocs", src ); + std::vector false_eocs = load_eoc_vector( jo, "false_eocs", src ); return [dest_params, true_eocs, false_eocs, is_npc]( dialogue & d ) { npc *guy = d.actor( is_npc )->get_npc(); if( guy ) { @@ -3981,7 +4004,7 @@ talk_effect_fun_t::func f_npc_goal( const JsonObject &jo, std::string_view membe } talk_effect_fun_t::func f_guard_pos( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { std::optional target_var = read_var_info( jo.get_object( member ) ); bool unique_id = jo.get_bool( "unique_id", false ); @@ -4000,7 +4023,7 @@ talk_effect_fun_t::func f_guard_pos( const JsonObject &jo, std::string_view memb } talk_effect_fun_t::func f_bulk_trade_accept( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { dbl_or_var dov_quantity; if( jo.has_member( member ) ) { @@ -4156,7 +4179,8 @@ talk_effect_fun_t::func f_npc_gets_item( bool to_use ) }; } -talk_effect_fun_t::func f_add_mission( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_add_mission( const JsonObject &jo, std::string_view member, + const std::string_view ) { str_or_var mission_id = get_str_or_var( jo.get_member( member ), member, true ); return [mission_id]( dialogue const & d ) { @@ -4164,7 +4188,8 @@ talk_effect_fun_t::func f_add_mission( const JsonObject &jo, std::string_view me }; } -talk_effect_fun_t::func f_u_buy_monster( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_u_buy_monster( const JsonObject &jo, std::string_view member, + const std::string_view src ) { str_or_var monster_type_id = get_str_or_var( jo.get_member( member ), member, true ); dbl_or_var cost = get_dbl_or_var( jo, "cost", false, 0 ); @@ -4176,8 +4201,8 @@ talk_effect_fun_t::func f_u_buy_monster( const JsonObject &jo, std::string_view } else { name.str_val = translation(); } - std::vector true_eocs = load_eoc_vector( jo, "true_eocs" ); - std::vector false_eocs = load_eoc_vector( jo, "false_eocs" ); + std::vector true_eocs = load_eoc_vector( jo, "true_eocs", src ); + std::vector false_eocs = load_eoc_vector( jo, "false_eocs", src ); return [monster_type_id, cost, count, pacified, name, true_eocs, false_eocs]( dialogue & d ) { const mtype_id mtype( monster_type_id.evaluate( d ) ); @@ -4192,7 +4217,7 @@ talk_effect_fun_t::func f_u_buy_monster( const JsonObject &jo, std::string_view } talk_effect_fun_t::func f_learn_recipe( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var learned_recipe_id = get_str_or_var( jo.get_member( member ), member, true ); return [learned_recipe_id, is_npc]( dialogue const & d ) { @@ -4202,7 +4227,7 @@ talk_effect_fun_t::func f_learn_recipe( const JsonObject &jo, std::string_view m } talk_effect_fun_t::func f_forget_recipe( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var forgotten_recipe_id = get_str_or_var( jo.get_member( member ), member, true ); return [forgotten_recipe_id, is_npc]( dialogue const & d ) { @@ -4211,7 +4236,8 @@ talk_effect_fun_t::func f_forget_recipe( const JsonObject &jo, std::string_view }; } -talk_effect_fun_t::func f_turn_cost( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_turn_cost( const JsonObject &jo, std::string_view member, + const std::string_view ) { duration_or_var cost = get_duration_or_var( jo, member, true ); return [cost]( dialogue & d ) { @@ -4222,7 +4248,8 @@ talk_effect_fun_t::func f_turn_cost( const JsonObject &jo, std::string_view memb }; } -talk_effect_fun_t::func f_npc_first_topic( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_npc_first_topic( const JsonObject &jo, std::string_view member, + const std::string_view ) { str_or_var chat_topic = get_str_or_var( jo.get_member( member ), member, true ); return [chat_topic]( dialogue const & d ) { @@ -4231,7 +4258,7 @@ talk_effect_fun_t::func f_npc_first_topic( const JsonObject &jo, std::string_vie } talk_effect_fun_t::func f_message( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { const bool snippet = jo.get_bool( "snippet", false ); str_or_var snip_id; @@ -4356,7 +4383,7 @@ talk_effect_fun_t::func f_message( const JsonObject &jo, std::string_view member } talk_effect_fun_t::func f_assign_activity( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { duration_or_var dov = get_duration_or_var( jo, "duration", true ); str_or_var act = get_str_or_var( jo.get_member( member ), member, true ); @@ -4369,7 +4396,7 @@ talk_effect_fun_t::func f_assign_activity( const JsonObject &jo, std::string_vie } talk_effect_fun_t::func f_add_wet( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { dbl_or_var dov = get_dbl_or_var( jo, member ); return [is_npc, dov]( dialogue & d ) { @@ -4380,7 +4407,8 @@ talk_effect_fun_t::func f_add_wet( const JsonObject &jo, std::string_view member }; } -talk_effect_fun_t::func f_open_dialogue( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_open_dialogue( const JsonObject &jo, std::string_view member, + const std::string_view src ) { std::vector true_eocs; std::vector false_eocs; @@ -4389,8 +4417,8 @@ talk_effect_fun_t::func f_open_dialogue( const JsonObject &jo, std::string_view if( jo.has_object( member ) ) { has_member = true; JsonObject innerJo = jo.get_object( member ); - true_eocs = load_eoc_vector( innerJo, "true_eocs" ); - false_eocs = load_eoc_vector( innerJo, "false_eocs" ); + true_eocs = load_eoc_vector( innerJo, "true_eocs", src ); + false_eocs = load_eoc_vector( innerJo, "false_eocs", src ); topic = get_str_or_var( innerJo.get_member( "topic" ), "topic" ); } return [true_eocs, false_eocs, topic, has_member]( dialogue const & d ) { @@ -4419,10 +4447,11 @@ talk_effect_fun_t::func f_open_dialogue( const JsonObject &jo, std::string_view }; } -talk_effect_fun_t::func f_take_control( const JsonObject &jo, std::string_view ) +talk_effect_fun_t::func f_take_control( const JsonObject &jo, std::string_view, + const std::string_view src ) { - std::vector true_eocs = load_eoc_vector( jo, "true_eocs" ); - std::vector false_eocs = load_eoc_vector( jo, "false_eocs" ); + std::vector true_eocs = load_eoc_vector( jo, "true_eocs", src ); + std::vector false_eocs = load_eoc_vector( jo, "false_eocs", src ); return [true_eocs, false_eocs]( dialogue const & d ) { if( !d.actor( false )->get_character()->is_avatar() ) { //only take control if the avatar is alpha run_eoc_vector( false_eocs, d ); @@ -4441,7 +4470,8 @@ talk_effect_fun_t::func f_take_control_menu() }; } -talk_effect_fun_t::func f_sound_effect( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_sound_effect( const JsonObject &jo, std::string_view member, + const std::string_view ) { str_or_var variant = get_str_or_var( jo.get_member( member ), member, true ); str_or_var id = get_str_or_var( jo.get_member( "id" ), "id", true ); @@ -4475,7 +4505,8 @@ talk_effect_fun_t::func f_sound_effect( const JsonObject &jo, std::string_view m }; } -talk_effect_fun_t::func f_give_achievment( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_give_achievment( const JsonObject &jo, std::string_view member, + const std::string_view ) { str_or_var achieve = get_str_or_var( jo.get_member( member ), member, true ); return [achieve]( dialogue const & d ) { @@ -4495,7 +4526,7 @@ talk_effect_fun_t::func f_give_achievment( const JsonObject &jo, std::string_vie } talk_effect_fun_t::func f_mod_healthy( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { dbl_or_var dov_amount = get_dbl_or_var( jo, member ); dbl_or_var dov_cap = get_dbl_or_var( jo, "cap" ); @@ -4507,10 +4538,10 @@ talk_effect_fun_t::func f_mod_healthy( const JsonObject &jo, std::string_view me } talk_effect_fun_t::func f_cast_spell( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view src, bool is_npc ) { - std::vector true_eocs = load_eoc_vector( jo, "true_eocs" ); - std::vector false_eocs = load_eoc_vector( jo, "false_eocs" ); + std::vector true_eocs = load_eoc_vector( jo, "true_eocs", src ); + std::vector false_eocs = load_eoc_vector( jo, "false_eocs", src ); bool targeted = jo.get_bool( "targeted", false ); std::optional loc_var; @@ -4587,7 +4618,7 @@ talk_effect_fun_t::func f_cast_spell( const JsonObject &jo, std::string_view mem } talk_effect_fun_t::func f_attack( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var force_technique = get_str_or_var( jo.get_member( member ), member, true ); bool allow_special = jo.get_bool( "allow_special", true ); @@ -4641,7 +4672,8 @@ talk_effect_fun_t::func f_next_weather() }; } -talk_effect_fun_t::func f_set_string_var( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_set_string_var( const JsonObject &jo, std::string_view member, + const std::string_view ) { const bool i18n = jo.get_bool( "i18n", false ); std::vector str_vals; @@ -4676,7 +4708,8 @@ talk_effect_fun_t::func f_set_string_var( const JsonObject &jo, std::string_view }; } -talk_effect_fun_t::func f_set_condition( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_set_condition( const JsonObject &jo, std::string_view member, + const std::string_view ) { str_or_var value; value = get_str_or_var( jo.get_member( member ), member ); @@ -4689,7 +4722,7 @@ talk_effect_fun_t::func f_set_condition( const JsonObject &jo, std::string_view } talk_effect_fun_t::func f_set_item_category_spawn_rates( const JsonObject &jo, - std::string_view member ) + std::string_view member, const std::string_view ) { if( jo.has_array( member ) ) { std::set> rates; @@ -4713,7 +4746,8 @@ talk_effect_fun_t::func f_set_item_category_spawn_rates( const JsonObject &jo, } } -talk_effect_fun_t::func f_assign_mission( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_assign_mission( const JsonObject &jo, std::string_view member, + const std::string_view ) { str_or_var mission_name = get_str_or_var( jo.get_member( member ), member, true ); return [mission_name]( dialogue const & d ) { @@ -4725,7 +4759,8 @@ talk_effect_fun_t::func f_assign_mission( const JsonObject &jo, std::string_view }; } -talk_effect_fun_t::func f_finish_mission( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_finish_mission( const JsonObject &jo, std::string_view member, + const std::string_view ) { str_or_var mission_name = get_str_or_var( jo.get_member( member ), member, true ); bool success = false; @@ -4756,7 +4791,7 @@ talk_effect_fun_t::func f_finish_mission( const JsonObject &jo, std::string_view } talk_effect_fun_t::func f_remove_active_mission( const JsonObject &jo, - std::string_view member ) + std::string_view member, const std::string_view ) { str_or_var mission_name = get_str_or_var( jo.get_member( member ), member, true ); return [mission_name]( dialogue const & d ) { @@ -4772,7 +4807,8 @@ talk_effect_fun_t::func f_remove_active_mission( const JsonObject &jo, }; } -talk_effect_fun_t::func f_offer_mission( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_offer_mission( const JsonObject &jo, std::string_view member, + const std::string_view ) { std::vector mission_names; @@ -4799,7 +4835,7 @@ talk_effect_fun_t::func f_offer_mission( const JsonObject &jo, std::string_view } talk_effect_fun_t::func f_set_flag( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var flag = get_str_or_var( jo.get_member( member ), member, true ); @@ -4816,7 +4852,7 @@ talk_effect_fun_t::func f_set_flag( const JsonObject &jo, std::string_view membe } talk_effect_fun_t::func f_unset_flag( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var flag = get_str_or_var( jo.get_member( member ), member, true ); @@ -4833,7 +4869,7 @@ talk_effect_fun_t::func f_unset_flag( const JsonObject &jo, std::string_view mem } talk_effect_fun_t::func f_activate( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var method = get_str_or_var( jo.get_member( member ), member, true ); std::optional target_var; @@ -4870,7 +4906,8 @@ talk_effect_fun_t::func f_activate( const JsonObject &jo, std::string_view membe }; } -talk_effect_fun_t::func f_math( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_math( const JsonObject &jo, std::string_view member, + const std::string_view ) { eoc_math math; math.from_json( jo, member, eoc_math::type_t::assign ); @@ -4880,7 +4917,8 @@ talk_effect_fun_t::func f_math( const JsonObject &jo, std::string_view member ) } -talk_effect_fun_t::func f_transform_item( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_transform_item( const JsonObject &jo, std::string_view member, + const std::string_view ) { str_or_var target_id = get_str_or_var( jo.get_member( member ), member, true ); bool activate = jo.get_bool( "active", false ); @@ -4899,7 +4937,7 @@ talk_effect_fun_t::func f_transform_item( const JsonObject &jo, std::string_view } talk_effect_fun_t::func f_make_sound( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { dbl_or_var volume = get_dbl_or_var( jo, "volume", true ); bool ambient = jo.get_bool( "ambient", false ); @@ -4973,9 +5011,10 @@ talk_effect_fun_t::func f_make_sound( const JsonObject &jo, std::string_view mem -talk_effect_fun_t::func f_run_eocs( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_run_eocs( const JsonObject &jo, std::string_view member, + const std::string_view src ) { - std::vector eocs_entries = load_eoc_vector_id_and_var( jo, member ); + std::vector eocs_entries = load_eoc_vector_id_and_var( jo, member, src ); if( eocs_entries.empty() ) { jo.throw_error( "Invalid input for run_eocs" ); @@ -4990,9 +5029,10 @@ talk_effect_fun_t::func f_run_eocs( const JsonObject &jo, std::string_view membe }; } -talk_effect_fun_t::func f_run_eoc_until( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_run_eoc_until( const JsonObject &jo, std::string_view member, + const std::string_view src ) { - effect_on_condition_id eoc = effect_on_conditions::load_inline_eoc( jo.get_member( member ), "" ); + effect_on_condition_id eoc = effect_on_conditions::load_inline_eoc( jo.get_member( member ), src ); std::function cond; read_condition( jo, "condition", cond, true ); // The default result of this condition is true @@ -5015,10 +5055,11 @@ talk_effect_fun_t::func f_run_eoc_until( const JsonObject &jo, std::string_view }; } -talk_effect_fun_t::func f_run_eoc_selector( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_run_eoc_selector( const JsonObject &jo, std::string_view member, + const std::string_view src ) { - std::vector eocs = load_eoc_vector_id_and_var( jo, member ); + std::vector eocs = load_eoc_vector_id_and_var( jo, member, src ); if( eocs.empty() ) { jo.throw_error( "Invalid input for run_eocs" ); } @@ -5175,9 +5216,10 @@ talk_effect_fun_t::func f_run_eoc_selector( const JsonObject &jo, std::string_vi } -talk_effect_fun_t::func f_run_eoc_with( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_run_eoc_with( const JsonObject &jo, std::string_view member, + const std::string_view src ) { - effect_on_condition_id eoc = effect_on_conditions::load_inline_eoc( jo.get_member( member ), "" ); + effect_on_condition_id eoc = effect_on_conditions::load_inline_eoc( jo.get_member( member ), src ); std::unordered_map context; if( jo.has_object( "variables" ) ) { @@ -5215,7 +5257,7 @@ talk_effect_fun_t::func f_run_eoc_with( const JsonObject &jo, std::string_view m has_alpha_var = false; } - std::vector false_eocs = load_eoc_vector( jo, "false_eocs" ); + std::vector false_eocs = load_eoc_vector( jo, "false_eocs", src ); return [eoc, context, alpha_var, beta_var, is_alpha_loc, is_beta_loc, has_alpha_var, has_beta_var, false_eocs]( dialogue const & d ) { @@ -5273,9 +5315,9 @@ talk_effect_fun_t::func f_run_eoc_with( const JsonObject &jo, std::string_view m } talk_effect_fun_t::func f_run_npc_eocs( const JsonObject &jo, - std::string_view member, bool is_npc ) + std::string_view member, const std::string_view src, bool is_npc ) { - std::vector eocs = load_eoc_vector( jo, member ); + std::vector eocs = load_eoc_vector( jo, member, src ); std::vector unique_ids; for( JsonValue jv : jo.get_array( "unique_ids" ) ) { unique_ids.emplace_back( get_str_or_var( jv, "unique_ids" ) ); @@ -5335,9 +5377,9 @@ talk_effect_fun_t::func f_run_npc_eocs( const JsonObject &jo, } talk_effect_fun_t::func f_run_monster_eocs( const JsonObject &jo, - std::string_view member, bool is_npc ) + std::string_view member, const std::string_view src, bool is_npc ) { - std::vector eocs = load_eoc_vector( jo, member ); + std::vector eocs = load_eoc_vector( jo, member, src ); std::vector mtype_ids; for( JsonValue jv : jo.get_array( "mtype_ids" ) ) { mtype_ids.emplace_back( get_str_or_var( jv, "mtype_ids" ) ); @@ -5383,11 +5425,11 @@ talk_effect_fun_t::func f_run_monster_eocs( const JsonObject &jo, talk_effect_fun_t::func f_run_inv_eocs( const JsonObject &jo, - std::string_view member, bool is_npc ) + std::string_view member, const std::string_view src, bool is_npc ) { str_or_var option = get_str_or_var( jo.get_member( member ), member ); - std::vector true_eocs = load_eoc_vector( jo, "true_eocs" ); - std::vector false_eocs = load_eoc_vector( jo, "false_eocs" ); + std::vector true_eocs = load_eoc_vector( jo, "true_eocs", src ); + std::vector false_eocs = load_eoc_vector( jo, "false_eocs", src ); std::vector data; for( const JsonValue &search_data_jo : jo.get_array( "search_data" ) ) { data.emplace_back( search_data_jo ); @@ -5415,11 +5457,11 @@ talk_effect_fun_t::func f_run_inv_eocs( const JsonObject &jo, } talk_effect_fun_t::func f_map_run_item_eocs( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view src, bool is_npc ) { str_or_var option = get_str_or_var( jo.get_member( member ), member ); - std::vector true_eocs = load_eoc_vector( jo, "true_eocs" ); - std::vector false_eocs = load_eoc_vector( jo, "false_eocs" ); + std::vector true_eocs = load_eoc_vector( jo, "true_eocs", src ); + std::vector false_eocs = load_eoc_vector( jo, "false_eocs", src ); std::vector data; for( const JsonValue &search_data_jo : jo.get_array( "search_data" ) ) { data.emplace_back( search_data_jo ); @@ -5495,7 +5537,8 @@ talk_effect_fun_t::func f_map_run_item_eocs( const JsonObject &jo, std::string_v }; } -talk_effect_fun_t::func f_set_talker( const JsonObject &jo, std::string_view member, bool is_npc ) +talk_effect_fun_t::func f_set_talker( const JsonObject &jo, std::string_view member, + const std::string_view, bool is_npc ) { var_info var = read_var_info( jo.get_object( member ) ); var_type type = var.type; @@ -5524,9 +5567,10 @@ void process_eoc( const effect_on_condition_id &eoc, dialogue &d, } } -talk_effect_fun_t::func f_queue_eocs( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_queue_eocs( const JsonObject &jo, std::string_view member, + const std::string_view src ) { - std::vector eocs_entries = load_eoc_vector_id_and_var( jo, member ); + std::vector eocs_entries = load_eoc_vector_id_and_var( jo, member, src ); if( eocs_entries.empty() ) { jo.throw_error( "Invalid input for queue_eocs" ); } @@ -5543,9 +5587,10 @@ talk_effect_fun_t::func f_queue_eocs( const JsonObject &jo, std::string_view mem }; } -talk_effect_fun_t::func f_queue_eoc_with( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_queue_eoc_with( const JsonObject &jo, std::string_view member, + const std::string_view src ) { - effect_on_condition_id eoc = effect_on_conditions::load_inline_eoc( jo.get_member( member ), "" ); + effect_on_condition_id eoc = effect_on_conditions::load_inline_eoc( jo.get_member( member ), src ); std::unordered_map context; if( jo.has_object( "variables" ) ) { @@ -5582,7 +5627,7 @@ talk_effect_fun_t::func f_queue_eoc_with( const JsonObject &jo, std::string_view } talk_effect_fun_t::func f_weighted_list_eocs( const JsonObject &jo, - std::string_view member ) + std::string_view member, const std::string_view src ) { std::vector> eoc_pairs; for( JsonArray ja : jo.get_array( member ) ) { @@ -5593,7 +5638,7 @@ talk_effect_fun_t::func f_weighted_list_eocs( const JsonObject &jo, } else { eoc_weight.min = get_dbl_or_var_part( ja.next_value(), member ); } - eoc_pairs.emplace_back( effect_on_conditions::load_inline_eoc( eoc, "" ), + eoc_pairs.emplace_back( effect_on_conditions::load_inline_eoc( eoc, src ), eoc_weight ); } return [eoc_pairs]( dialogue & d ) { @@ -5608,15 +5653,16 @@ talk_effect_fun_t::func f_weighted_list_eocs( const JsonObject &jo, }; } -talk_effect_fun_t::func f_if( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_if( const JsonObject &jo, std::string_view member, + const std::string_view src ) { std::function cond; talk_effect_t then_effect; talk_effect_t else_effect; read_condition( jo, std::string( member ), cond, false ); - then_effect.load_effect( jo, "then" ); + then_effect.load_effect( jo, "then", src ); if( jo.has_member( "else" ) || jo.has_array( "else" ) ) { - else_effect.load_effect( jo, "else" ); + else_effect.load_effect( jo, "else", src ); } return [cond, then_effect, else_effect]( dialogue & d ) { @@ -5628,14 +5674,15 @@ talk_effect_fun_t::func f_if( const JsonObject &jo, std::string_view member ) }; } -talk_effect_fun_t::func f_switch( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_switch( const JsonObject &jo, std::string_view member, + const std::string_view src ) { dbl_or_var eoc_switch = get_dbl_or_var( jo, member ); std::vector> case_pairs; for( const JsonValue jv : jo.get_array( "cases" ) ) { JsonObject array_case = jv.get_object(); talk_effect_t case_effect; - case_effect.load_effect( array_case, "effect" ); + case_effect.load_effect( array_case, "effect", src ); case_pairs.emplace_back( get_dbl_or_var( array_case, "case" ), case_effect ); } return [eoc_switch, case_pairs]( dialogue & d ) { @@ -5651,12 +5698,13 @@ talk_effect_fun_t::func f_switch( const JsonObject &jo, std::string_view member }; } -talk_effect_fun_t::func f_foreach( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_foreach( const JsonObject &jo, std::string_view member, + const std::string_view src ) { std::string type = jo.get_string( member.data() ); var_info itr = read_var_info( jo.get_object( "var" ) ); talk_effect_t effect; - effect.load_effect( jo, "effect" ); + effect.load_effect( jo, "effect", src ); std::string target; std::vector array; if( jo.has_string( "target" ) ) { @@ -5711,7 +5759,7 @@ talk_effect_fun_t::func f_foreach( const JsonObject &jo, std::string_view member } talk_effect_fun_t::func f_roll_remainder( const JsonObject &jo, - std::string_view member, bool is_npc ) + std::string_view member, const std::string_view src, bool is_npc ) { std::vector list; for( JsonValue jv : jo.get_array( member ) ) { @@ -5724,8 +5772,8 @@ talk_effect_fun_t::func f_roll_remainder( const JsonObject &jo, } else { message.str_val = translation(); } - std::vector true_eocs = load_eoc_vector( jo, "true_eocs" ); - std::vector false_eocs = load_eoc_vector( jo, "false_eocs" ); + std::vector true_eocs = load_eoc_vector( jo, "true_eocs", src ); + std::vector false_eocs = load_eoc_vector( jo, "false_eocs", src ); return [list, type, is_npc, true_eocs, false_eocs, message]( dialogue const & d ) { std::vector not_had; @@ -5788,7 +5836,7 @@ talk_effect_fun_t::func f_roll_remainder( const JsonObject &jo, } talk_effect_fun_t::func f_add_morale( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var new_type = get_str_or_var( jo.get_member( member ), member, true ); dbl_or_var dov_bonus = get_dbl_or_var( jo, "bonus" ); @@ -5808,7 +5856,7 @@ talk_effect_fun_t::func f_add_morale( const JsonObject &jo, std::string_view mem } talk_effect_fun_t::func f_lose_morale( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var old_morale = get_str_or_var( jo.get_member( member ), member, true ); return [is_npc, old_morale]( dialogue const & d ) { @@ -5816,7 +5864,8 @@ talk_effect_fun_t::func f_lose_morale( const JsonObject &jo, std::string_view me }; } -talk_effect_fun_t::func f_add_faction_trust( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_add_faction_trust( const JsonObject &jo, std::string_view member, + const std::string_view ) { dbl_or_var dov = get_dbl_or_var( jo, member ); return [dov]( dialogue & d ) { @@ -5825,7 +5874,7 @@ talk_effect_fun_t::func f_add_faction_trust( const JsonObject &jo, std::string_v } talk_effect_fun_t::func f_lose_faction_trust( const JsonObject &jo, - std::string_view member ) + std::string_view member, const std::string_view ) { dbl_or_var dov = get_dbl_or_var( jo, member ); return [dov]( dialogue & d ) { @@ -5834,7 +5883,7 @@ talk_effect_fun_t::func f_lose_faction_trust( const JsonObject &jo, } talk_effect_fun_t::func f_custom_light_level( const JsonObject &jo, - std::string_view member ) + std::string_view member, const std::string_view ) { dbl_or_var dov = get_dbl_or_var( jo, member, true ); duration_or_var dov_length = get_duration_or_var( jo, "length", false, 0_seconds ); @@ -5852,7 +5901,8 @@ talk_effect_fun_t::func f_custom_light_level( const JsonObject &jo, }; } -talk_effect_fun_t::func f_give_equipment( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_give_equipment( const JsonObject &jo, std::string_view member, + const std::string_view ) { JsonObject jobj = jo.get_object( member ); int allowance = 0; @@ -5883,7 +5933,7 @@ talk_effect_fun_t::func f_give_equipment( const JsonObject &jo, std::string_view } talk_effect_fun_t::func f_spawn_monster( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view src, bool is_npc ) { bool group = jo.get_bool( "group", false ); bool single_target = jo.get_bool( "single_target", false ); @@ -5912,8 +5962,8 @@ talk_effect_fun_t::func f_spawn_monster( const JsonObject &jo, std::string_view jo.read( "spawn_message", spawn_message ); translation spawn_message_plural; jo.read( "spawn_message_plural", spawn_message_plural ); - std::vector true_eocs = load_eoc_vector( jo, "true_eocs" ); - std::vector false_eocs = load_eoc_vector( jo, "false_eocs" ); + std::vector true_eocs = load_eoc_vector( jo, "true_eocs", src ); + std::vector false_eocs = load_eoc_vector( jo, "false_eocs", src ); return [monster_id, dov_target_range, dov_hallucination_count, dov_real_count, dov_min_radius, dov_max_radius, outdoor_only, indoor_only, group, single_target, dov_lifespan, target_var, spawn_message, spawn_message_plural, true_eocs, false_eocs, open_air_allowed, temporary_drop_items, @@ -6063,7 +6113,7 @@ talk_effect_fun_t::func f_spawn_monster( const JsonObject &jo, std::string_view } talk_effect_fun_t::func f_spawn_npc( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view src, bool is_npc ) { str_or_var sov_npc_class = get_str_or_var( jo.get_member( member ), member ); str_or_var unique_id; @@ -6099,8 +6149,8 @@ talk_effect_fun_t::func f_spawn_npc( const JsonObject &jo, std::string_view memb jo.read( "spawn_message", spawn_message ); translation spawn_message_plural; jo.read( "spawn_message_plural", spawn_message_plural ); - std::vector true_eocs = load_eoc_vector( jo, "true_eocs" ); - std::vector false_eocs = load_eoc_vector( jo, "false_eocs" ); + std::vector true_eocs = load_eoc_vector( jo, "true_eocs", src ); + std::vector false_eocs = load_eoc_vector( jo, "false_eocs", src ); return [sov_npc_class, unique_id, traits, dov_hallucination_count, dov_real_count, dov_min_radius, dov_max_radius, outdoor_only, indoor_only, dov_lifespan, target_var, spawn_message, @@ -6177,7 +6227,7 @@ talk_effect_fun_t::func f_spawn_npc( const JsonObject &jo, std::string_view memb } talk_effect_fun_t::func f_field( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { str_or_var new_field = get_str_or_var( jo.get_member( member ), member, true ); dbl_or_var dov_intensity = get_dbl_or_var( jo, "intensity", false, 1 ); @@ -6214,7 +6264,7 @@ talk_effect_fun_t::func f_field( const JsonObject &jo, std::string_view member, } talk_effect_fun_t::func f_teleport( const JsonObject &jo, std::string_view member, - bool is_npc ) + const std::string_view, bool is_npc ) { std::optional target_var = read_var_info( jo.get_object( member ) ); translation_or_var fail_message; @@ -6268,7 +6318,8 @@ talk_effect_fun_t::func f_wants_to_talk( bool is_npc ) }; } -talk_effect_fun_t::func f_trigger_event( const JsonObject &jo, std::string_view member ) +talk_effect_fun_t::func f_trigger_event( const JsonObject &jo, std::string_view member, + const std::string_view ) { std::string const type_str = jo.get_string( member.data() ); JsonArray const &jargs = jo.get_array( "args" ); @@ -6376,11 +6427,12 @@ void talk_effect_t::update_missions( dialogue &d ) } } -talk_effect_t::talk_effect_t( const JsonObject &jo, const std::string &member_name ) +talk_effect_t::talk_effect_t( const JsonObject &jo, const std::string &member_name, + const std::string_view src ) { - load_effect( jo, member_name ); + load_effect( jo, member_name, src ); if( jo.has_object( "topic" ) ) { - next_topic = load_inline_topic( jo.get_object( "topic" ) ); + next_topic = load_inline_topic( jo.get_object( "topic" ), src ); } else if( jo.has_string( "topic" ) ) { next_topic = talk_topic( jo.get_string( "topic" ) ); } @@ -6494,26 +6546,27 @@ parsers = { { "transform_item", jarg::member, &talk_effect_fun::f_transform_item }, }; -void talk_effect_t::parse_sub_effect( const JsonObject &jo ) +void talk_effect_t::parse_sub_effect( const JsonObject &jo, const std::string_view src ) { for( const sub_effect_parser &p : parsers ) { if( p.has_beta ) { if( p.check( jo ) ) { - set_effect( p.f( jo, p.key_alpha, false ) ); + set_effect( p.f( jo, p.key_alpha, src, false ) ); return; } else if( p.check( jo, true ) ) { - set_effect( p.f( jo, p.key_beta, true ) ); + set_effect( p.f( jo, p.key_beta, src, true ) ); return; } } else if( p.check( jo ) ) { - set_effect( p.f( jo, p.key_alpha, false ) ); + set_effect( p.f( jo, p.key_alpha, src, false ) ); return; } } jo.throw_error( "invalid sub effect syntax: " + jo.str() ); } -void talk_effect_t::parse_string_effect( const std::string &effect_id, const JsonObject &jo ) +void talk_effect_t::parse_string_effect( const std::string &effect_id, const JsonObject &jo, + const std::string_view src ) { static const std::unordered_map static_functions_map = { { @@ -6613,7 +6666,8 @@ void talk_effect_t::parse_string_effect( const std::string &effect_id, const Jso if( effect_id == "u_bulk_trade_accept" || effect_id == "npc_bulk_trade_accept" || effect_id == "u_bulk_donate" || effect_id == "npc_bulk_donate" ) { bool is_npc = effect_id == "npc_bulk_trade_accept" || effect_id == "npc_bulk_donate"; - set_effect( talk_effect_fun_t( talk_effect_fun::f_bulk_trade_accept( jo, effect_id, is_npc ) ) ); + set_effect( talk_effect_fun_t( talk_effect_fun::f_bulk_trade_accept( jo, effect_id, src, + is_npc ) ) ); return; } @@ -6654,11 +6708,11 @@ void talk_effect_t::parse_string_effect( const std::string &effect_id, const Jso } if( effect_id == "open_dialogue" ) { - set_effect( talk_effect_fun_t( talk_effect_fun::f_open_dialogue( jo, "" ) ) ); + set_effect( talk_effect_fun_t( talk_effect_fun::f_open_dialogue( jo, "", src ) ) ); return; } if( effect_id == "take_control" ) { - set_effect( talk_effect_fun_t( talk_effect_fun::f_take_control( jo, "" ) ) ); + set_effect( talk_effect_fun_t( talk_effect_fun::f_take_control( jo, "", src ) ) ); return; } if( effect_id == "take_control_menu" ) { @@ -6676,7 +6730,8 @@ void talk_effect_t::parse_string_effect( const std::string &effect_id, const Jso jo.throw_error_at( effect_id, "unknown effect string" ); } -void talk_effect_t::load_effect( const JsonObject &jo, const std::string &member_name ) +void talk_effect_t::load_effect( const JsonObject &jo, const std::string &member_name, + const std::string_view src ) { if( jo.has_member( "opinion" ) ) { JsonValue jv = jo.get_member( "opinion" ); @@ -6692,18 +6747,18 @@ void talk_effect_t::load_effect( const JsonObject &jo, const std::string &member return; } else if( jo.has_string( member_name ) ) { const std::string type = jo.get_string( member_name ); - parse_string_effect( type, jo ); + parse_string_effect( type, jo, src ); } else if( jo.has_object( member_name ) ) { JsonObject sub_effect = jo.get_object( member_name ); - parse_sub_effect( sub_effect ); + parse_sub_effect( sub_effect, src ); } else if( jo.has_array( member_name ) ) { for( const JsonValue entry : jo.get_array( member_name ) ) { if( entry.test_string() ) { const std::string type = entry.get_string(); - parse_string_effect( type, jo ); + parse_string_effect( type, jo, src ); } else if( entry.test_object() ) { JsonObject sub_effect = entry.get_object(); - parse_sub_effect( sub_effect ); + parse_sub_effect( sub_effect, src ); } else { jo.throw_error_at( member_name, "invalid effect array syntax" ); } @@ -6729,7 +6784,7 @@ talk_response::talk_response() dialogue_spell = spell_id(); } -talk_response::talk_response( const JsonObject &jo ) +talk_response::talk_response( const JsonObject &jo, const std::string_view src ) { if( jo.has_member( "truefalsetext" ) ) { JsonObject truefalse_jo = jo.get_object( "truefalsetext" ); @@ -6748,20 +6803,20 @@ talk_response::talk_response( const JsonObject &jo ) } if( jo.has_member( "success" ) ) { JsonObject success_obj = jo.get_object( "success" ); - success = talk_effect_t( success_obj, "effect" ); + success = talk_effect_t( success_obj, "effect", src ); } else if( jo.has_string( "topic" ) ) { // This is for simple topic switching without a possible failure success.next_topic = talk_topic( jo.get_string( "topic" ) ); - success.load_effect( jo, "effect" ); + success.load_effect( jo, "effect", src ); } else if( jo.has_object( "topic" ) ) { - success.next_topic = load_inline_topic( jo.get_object( "topic" ) ); + success.next_topic = load_inline_topic( jo.get_object( "topic" ), src ); } if( trial && !jo.has_member( "failure" ) ) { jo.throw_error( "the failure effect is mandatory if a talk_trial has been defined" ); } if( jo.has_member( "failure" ) ) { JsonObject failure_obj = jo.get_object( "failure" ); - failure = talk_effect_t( failure_obj, "effect" ); + failure = talk_effect_t( failure_obj, "effect", src ); } // TODO: mission_selected @@ -6769,7 +6824,8 @@ talk_response::talk_response( const JsonObject &jo ) // TODO: style } -json_talk_repeat_response::json_talk_repeat_response( const JsonObject &jo ) +json_talk_repeat_response::json_talk_repeat_response( const JsonObject &jo, + const std::string_view src ) { if( jo.has_bool( "is_npc" ) ) { is_npc = true; @@ -6797,19 +6853,19 @@ json_talk_repeat_response::json_talk_repeat_response( const JsonObject &jo ) } if( jo.has_object( "response" ) ) { JsonObject response_obj = jo.get_object( "response" ); - response = json_talk_response( response_obj ); + response = json_talk_response( response_obj, src ); } else { jo.throw_error( "Repeat response with no response!" ); } } -json_talk_response::json_talk_response( const JsonObject &jo ) - : actual_response( jo ) +json_talk_response::json_talk_response( const JsonObject &jo, const std::string_view src ) + : actual_response( jo, src ) { - load_condition( jo ); + load_condition( jo, src ); } -void json_talk_response::load_condition( const JsonObject &jo ) +void json_talk_response::load_condition( const JsonObject &jo, const std::string_view ) { has_condition_ = jo.has_member( "condition" ); is_switch = jo.get_bool( "switch", false ); @@ -7062,11 +7118,11 @@ dynamic_line_t::dynamic_line_t( const JsonArray &ja ) } json_dynamic_line_effect::json_dynamic_line_effect( const JsonObject &jo, - const std::string &id ) + const std::string &id, const std::string_view src ) { std::function tmp_condition; read_condition( jo, "condition", tmp_condition, true ); - talk_effect_t tmp_effect = talk_effect_t( jo, "effect" ); + talk_effect_t tmp_effect = talk_effect_t( jo, "effect", src ); // if the topic has a sentinel, it means implicitly add a check for the sentinel value // and do not run the effects if it is set. if it is not set, run the effects and // set the sentinel @@ -7096,7 +7152,7 @@ void json_dynamic_line_effect::apply( dialogue &d ) const effect.apply( d ); } -void json_talk_topic::load( const JsonObject &jo ) +void json_talk_topic::load( const JsonObject &jo, const std::string_view src ) { if( jo.has_member( "dynamic_line" ) ) { dynamic_line = dynamic_line_t::from_member( jo, "dynamic_line" ); @@ -7110,10 +7166,10 @@ void json_talk_topic::load( const JsonObject &jo ) } if( jo.has_object( "speaker_effect" ) ) { JsonObject speaker_effect = jo.get_object( "speaker_effect" ); - speaker_effects.emplace_back( speaker_effect, id ); + speaker_effects.emplace_back( speaker_effect, id, src ); } else if( jo.has_array( "speaker_effect" ) ) { for( JsonObject speaker_effect : jo.get_array( "speaker_effect" ) ) { - speaker_effects.emplace_back( speaker_effect, id ); + speaker_effects.emplace_back( speaker_effect, id, src ); } } } @@ -7123,7 +7179,7 @@ void json_talk_topic::load( const JsonObject &jo ) } if( !insert_above_bottom || responses.empty() ) { for( JsonObject response : jo.get_array( "responses" ) ) { - responses.emplace_back( response ); + responses.emplace_back( response, src ); } } else { int dec_count = 0; @@ -7136,14 +7192,14 @@ void json_talk_topic::load( const JsonObject &jo ) dec_count = 2; } for( JsonObject response : jo.get_array( "responses" ) ) { - responses.emplace( responses.end() - dec_count, response ); + responses.emplace( responses.end() - dec_count, response, src ); } } if( jo.has_object( "repeat_responses" ) ) { - repeat_responses.emplace_back( jo.get_object( "repeat_responses" ) ); + repeat_responses.emplace_back( jo.get_object( "repeat_responses" ), src ); } else if( jo.has_array( "repeat_responses" ) ) { for( JsonObject elem : jo.get_array( "repeat_responses" ) ) { - repeat_responses.emplace_back( elem ); + repeat_responses.emplace_back( elem, src ); } } if( responses.empty() ) { @@ -7231,15 +7287,15 @@ void unload_talk_topics() json_talk_topics.clear(); } -void load_talk_topic( const JsonObject &jo ) +void load_talk_topic( const JsonObject &jo, const std::string_view src ) { if( jo.has_array( "id" ) ) { for( auto &id : jo.get_string_array( "id" ) ) { - json_talk_topics[id].load( jo ); + json_talk_topics[id].load( jo, src ); } } else { const std::string id = jo.get_string( "id" ); - json_talk_topics[id].load( jo ); + json_talk_topics[id].load( jo, src ); } } diff --git a/src/output.h b/src/output.h index eddd46c7553a3..124874c520099 100644 --- a/src/output.h +++ b/src/output.h @@ -1221,9 +1221,9 @@ class tab_list { private: size_t _index = 0; - std::vector *_list; + const std::vector *_list; public: - explicit tab_list( std::vector &_list ) : _list( &_list ) { + explicit tab_list( const std::vector &_list ) : _list( &_list ) { } void last() { diff --git a/src/recipe.cpp b/src/recipe.cpp index a2515db29da86..06a6e97b290f6 100644 --- a/src/recipe.cpp +++ b/src/recipe.cpp @@ -15,6 +15,7 @@ #include "cata_utility.h" #include "character.h" #include "color.h" +#include "crafting_gui.h" #include "debug.h" #include "enum_traits.h" #include "effect_on_condition.h" @@ -662,7 +663,7 @@ void recipe::add_requirements( const std::vector> std::string recipe::get_consistency_error() const { - if( category == "CC_BUILDING" ) { + if( category.is_valid() && category->is_building ) { if( is_blueprint() || oter_str_id( result_.c_str() ).is_valid() ) { return std::string(); } diff --git a/src/recipe.h b/src/recipe.h index 0a8a7e63f895a..9e9532bf75787 100644 --- a/src/recipe.h +++ b/src/recipe.h @@ -123,7 +123,7 @@ class recipe bool was_loaded = false; bool obsolete = false; - std::string category; + crafting_category_id category; std::string subcategory; translation description; diff --git a/src/recipe_dictionary.cpp b/src/recipe_dictionary.cpp index 0566f6832257c..1aa1417a547c4 100644 --- a/src/recipe_dictionary.cpp +++ b/src/recipe_dictionary.cpp @@ -341,7 +341,8 @@ std::vector recipe_subset::recipes_that_produce( const itype_id return res; } -bool recipe_subset::empty_category( const std::string &cat, const std::string &subcat ) const +bool recipe_subset::empty_category( const crafting_category_id &cat, + const std::string &subcat ) const { if( subcat == "CSC_*_FAVORITE" ) { return uistate.favorite_recipes.empty(); @@ -349,7 +350,7 @@ bool recipe_subset::empty_category( const std::string &cat, const std::string &s return uistate.recent_recipes.empty(); } else if( subcat == "CSC_*_HIDDEN" ) { return uistate.hidden_recipes.empty(); - } else if( cat == "CC_*" ) { + } else if( cat->is_wildcard ) { //any other category in CC_* is populated return false; } @@ -369,7 +370,7 @@ bool recipe_subset::empty_category( const std::string &cat, const std::string &s return true; } -std::vector recipe_subset::in_category( const std::string &cat, +std::vector recipe_subset::in_category( const crafting_category_id &cat, const std::string &subcat ) const { std::vector res; @@ -676,7 +677,7 @@ void recipe_dictionary::check_consistency() for( const auto &e : recipe_dict.recipes ) { const recipe &r = e.second; - if( r.category.empty() ) { + if( r.category.str().empty() ) { if( !r.subcategory.empty() ) { debugmsg( "recipe %s has subcategory but no category", r.ident().str() ); } @@ -684,18 +685,19 @@ void recipe_dictionary::check_consistency() continue; } - const std::vector *subcategories = subcategories_for_category( r.category ); - if( !subcategories ) { - debugmsg( "recipe %s has invalid category %s", r.ident().str(), r.category ); + if( !r.category.is_valid() ) { + debugmsg( "recipe %s has invalid category %s", r.ident().str(), r.category.str() ); continue; } + const std::vector &subcategories = r.category->subcategories; + if( !r.subcategory.empty() ) { - auto it = std::find( subcategories->begin(), subcategories->end(), r.subcategory ); - if( it == subcategories->end() ) { + auto it = std::find( subcategories.begin(), subcategories.end(), r.subcategory ); + if( it == subcategories.end() ) { debugmsg( "recipe %s has subcategory %s which is invalid or doesn't match category %s", - r.ident().str(), r.subcategory, r.category ); + r.ident().str(), r.subcategory, r.category.str() ); } } } diff --git a/src/recipe_dictionary.h b/src/recipe_dictionary.h index 56375fed242d0..ffeef002336f1 100644 --- a/src/recipe_dictionary.h +++ b/src/recipe_dictionary.h @@ -128,11 +128,12 @@ class recipe_subset int get_custom_difficulty( const recipe *r ) const; /** Check if there is any recipes in given category (optionally restricted to subcategory), index which is for nested categories */ - bool empty_category( const std::string &cat, const std::string &subcat = std::string() ) const; + bool empty_category( const crafting_category_id &cat, + const std::string &subcat = std::string() ) const; /** Get all recipes in given category (optionally restricted to subcategory) */ std::vector in_category( - const std::string &cat, + const crafting_category_id &cat, const std::string &subcat = std::string() ) const; /** Returns all recipes which could use component */ @@ -202,7 +203,7 @@ class recipe_subset private: std::set recipes; std::map difficulties; - std::map> category; + std::map> category; std::map> component; }; diff --git a/src/text_snippets.cpp b/src/text_snippets.cpp index 6ed5e5a834f97..10a9eef1a4b4a 100644 --- a/src/text_snippets.cpp +++ b/src/text_snippets.cpp @@ -14,7 +14,7 @@ snippet_library SNIPPET; -void snippet_library::load_snippet( const JsonObject &jsobj ) +void snippet_library::load_snippet( const JsonObject &jsobj, const std::string &src ) { if( hash_to_id_migration.has_value() ) { debugmsg( "snippet_library::load_snippet called after snippet_library::migrate_hash_to_id." ); @@ -22,13 +22,14 @@ void snippet_library::load_snippet( const JsonObject &jsobj ) hash_to_id_migration = std::nullopt; const std::string category = jsobj.get_string( "category" ); if( jsobj.has_array( "text" ) ) { - add_snippets_from_json( category, jsobj.get_array( "text" ) ); + add_snippets_from_json( category, jsobj.get_array( "text" ), src ); } else { - add_snippet_from_json( category, jsobj ); + add_snippet_from_json( category, jsobj, src ); } } -void snippet_library::add_snippets_from_json( const std::string &category, const JsonArray &jarr ) +void snippet_library::add_snippets_from_json( const std::string &category, const JsonArray &jarr, + const std::string &src ) { if( hash_to_id_migration.has_value() ) { debugmsg( "snippet_library::add_snippets_from_json called after snippet_library::migrate_hash_to_id." ); @@ -45,12 +46,13 @@ void snippet_library::add_snippets_from_json( const std::string &category, const no_id.emplace_back( weighted_translation{ weight_acc, text } ); } else { JsonObject jo = entry.get_object(); - add_snippet_from_json( category, jo ); + add_snippet_from_json( category, jo, src ); } } } -void snippet_library::add_snippet_from_json( const std::string &category, const JsonObject &jo ) +void snippet_library::add_snippet_from_json( const std::string &category, const JsonObject &jo, + const std::string &src ) { if( hash_to_id_migration.has_value() ) { debugmsg( "snippet_library::add_snippet_from_json called after snippet_library::migrate_hash_to_id." ); @@ -74,7 +76,7 @@ void snippet_library::add_snippet_from_json( const std::string &category, const ids.emplace_back( weighted_id{ weight_acc, id } ); snippets_by_id[id] = text; if( jo.has_member( "effect_on_examine" ) ) { - EOC_by_id[id] = talk_effect_t( jo, "effect_on_examine" ); + EOC_by_id[id] = talk_effect_t( jo, "effect_on_examine", src ); } translation name; optional( jo, false, "name", name ); diff --git a/src/text_snippets.h b/src/text_snippets.h index 8a94fc14e9179..bec4ca2fa59e4 100644 --- a/src/text_snippets.h +++ b/src/text_snippets.h @@ -23,20 +23,22 @@ class snippet_library /** * Load snippet from the standalone entry, used by the @ref DynamicDataLoader. */ - void load_snippet( const JsonObject &jsobj ); + void load_snippet( const JsonObject &jsobj, const std::string &src ); /** * Load all snippet definitions in the json array into given category. * Entries in the array can be simple strings, or json objects (for the * later see add_snippet_from_json). */ - void add_snippets_from_json( const std::string &category, const JsonArray &jarr ); + void add_snippets_from_json( const std::string &category, const JsonArray &jarr, + const std::string &src ); /** * Load a single snippet text from the json object. The object should have * a "text" member with the text of the snippet. * A "id" member is optional and if present gives the snippet text a id, * stored in snippets_by_id. */ - void add_snippet_from_json( const std::string &category, const JsonObject &jo ); + void add_snippet_from_json( const std::string &category, const JsonObject &jo, + const std::string &src ); /** * Load name list from name.h/cpp */ diff --git a/src/type_id.h b/src/type_id.h index 13685d8e419b9..bfbe45db19c4c 100644 --- a/src/type_id.h +++ b/src/type_id.h @@ -58,6 +58,9 @@ using construction_group_str_id = string_id; struct clothing_mod; using clothing_mod_id = string_id; +struct crafting_category; +using crafting_category_id = string_id; + struct effect_on_condition; using effect_on_condition_id = string_id; diff --git a/tests/crafting_test.cpp b/tests/crafting_test.cpp index ea93639d0200a..a1ce14c96d21a 100644 --- a/tests/crafting_test.cpp +++ b/tests/crafting_test.cpp @@ -44,6 +44,8 @@ static const activity_id ACT_CRAFT( "ACT_CRAFT" ); +static const crafting_category_id crafting_category_CC_FOOD( "CC_FOOD" ); + static const flag_id json_flag_ITEM_BROKEN( "ITEM_BROKEN" ); static const flag_id json_flag_USE_UPS( "USE_UPS" ); @@ -142,7 +144,7 @@ TEST_CASE( "recipe_subset" ) CHECK( subset.get_custom_difficulty( r ) == r->difficulty ); } THEN( "it's in the right category" ) { - const auto cat_recipes( subset.in_category( "CC_FOOD" ) ); + const auto cat_recipes( subset.in_category( crafting_category_CC_FOOD ) ); CHECK( cat_recipes.size() == 1 ); CHECK( std::find( cat_recipes.begin(), cat_recipes.end(), r ) != cat_recipes.end() );