From 648f7c7d6fdaa86a1c4b7371f11b766bd89f18e8 Mon Sep 17 00:00:00 2001 From: Paul Fenwick Date: Tue, 25 Jan 2022 10:26:44 -0800 Subject: [PATCH] Add optional uncraft time to recipes (#54761) * Add optional `uncraft_time` to recipes This allows for recipes that might take a long time to create, but a short time to disassemble. * Update reversible documentation in JSON_INFO.md --- data/json/recipes/armor/head.json | 2 +- data/json/recipes/other/parts.json | 4 ++-- doc/JSON_INFO.md | 3 ++- src/recipe.cpp | 10 +++++++++- src/recipe.h | 3 +++ src/recipe_dictionary.cpp | 18 +++++++++++++----- 6 files changed, 30 insertions(+), 10 deletions(-) diff --git a/data/json/recipes/armor/head.json b/data/json/recipes/armor/head.json index 1057d122c9217..1f6d14e757e1d 100644 --- a/data/json/recipes/armor/head.json +++ b/data/json/recipes/armor/head.json @@ -1507,7 +1507,7 @@ "subcategory": "CSC_ARMOR_HEAD", "skill_used": "fabrication", "time": "30 m", - "reversible": true, + "reversible": { "time": "6 s" }, "autolearn": true, "components": [ [ [ "rag", 4 ] ], [ [ "pot", 1 ] ] ], "flags": [ "BLIND_HARD" ] diff --git a/data/json/recipes/other/parts.json b/data/json/recipes/other/parts.json index 7fc79ad98f42a..6353d9c1fc8be 100644 --- a/data/json/recipes/other/parts.json +++ b/data/json/recipes/other/parts.json @@ -725,7 +725,7 @@ "skill_used": "fabrication", "difficulty": 1, "time": "2 h", - "reversible": true, + "reversible": { "time": "20 m" }, "autolearn": true, "using": [ [ "sewing_standard", 50 ], [ "welding_standard", 5 ] ], "proficiencies": [ @@ -744,7 +744,7 @@ "skill_used": "fabrication", "difficulty": 1, "time": "6 h", - "reversible": true, + "reversible": { "time": "20 m" }, "autolearn": true, "using": [ [ "sewing_standard", 50 ], [ "welding_standard", 5 ] ], "proficiencies": [ diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index 44b9888419eea..2dd001813d1fd 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -1415,7 +1415,8 @@ Crafting recipes are defined as a JSON object with the following fields: "difficulty": 3, // Difficulty of success check "time": "5 m", // Preferred time to perform recipe, can specify in minutes, hours etc. "time": 5000, // Legacy time to perform recipe (where 1000 ~= 10 turns ~= 10 seconds game time). -"reversible": false, // Can be disassembled. +"reversible": true, // Can be disassembled. Time taken is as long as to craft the item. +"reversible": { "time": "30 s" }, // Can be disassembled. Time to disassemble as specified. "autolearn": true, // Automatically learned upon gaining required skills "autolearn" : [ // Automatically learned upon gaining listed skills [ "survival", 2 ], diff --git a/src/recipe.cpp b/src/recipe.cpp index 67ac50877b354..cbff7ca6fd8bd 100644 --- a/src/recipe.cpp +++ b/src/recipe.cpp @@ -312,7 +312,15 @@ void recipe::load( const JsonObject &jo, const std::string &src ) mandatory( jo, was_loaded, "category", category ); mandatory( jo, was_loaded, "subcategory", subcategory ); assign( jo, "description", description, strict ); - assign( jo, "reversible", reversible, strict ); + + if( jo.has_bool( "reversible" ) ) { + assign( jo, "reversible", reversible, strict ); + } else if( jo.has_object( "reversible" ) ) { + reversible = true; + // Convert duration to time in moves + uncraft_time = to_moves( read_from_json_string + ( jo.get_object( "reversible" ).get_member( "time" ), time_duration::units ) ); + } if( jo.has_member( "byproducts" ) ) { if( this->reversible ) { diff --git a/src/recipe.h b/src/recipe.h index 10025680629f2..cd66beeb8d6fd 100644 --- a/src/recipe.h +++ b/src/recipe.h @@ -302,6 +302,9 @@ class recipe /** Can recipe be used for disassembly of @ref result via @ref disassembly_requirements */ bool reversible = false; + /** Time (in moves) to disassemble if different to assembly. Requires `reversible = true` */ + int64_t uncraft_time = 0; + /** What does the item spawn contained in? Unset ("null") means default container. */ itype_id container = itype_id::NULL_ID(); diff --git a/src/recipe_dictionary.cpp b/src/recipe_dictionary.cpp index e7ac8fb6a8176..a02039129f8de 100644 --- a/src/recipe_dictionary.cpp +++ b/src/recipe_dictionary.cpp @@ -522,8 +522,8 @@ void recipe_dictionary::finalize() finalize_internal( recipe_dict.recipes ); finalize_internal( recipe_dict.uncraft ); - for( auto &e : recipe_dict.recipes ) { - auto &r = e.second; + for( const auto &e : recipe_dict.recipes ) { + const recipe &r = e.second; if( r.obsolete ) { continue; @@ -538,8 +538,16 @@ void recipe_dictionary::finalize() } // if reversible and no specific uncraft recipe exists use this recipe - if( r.is_reversible() && !recipe_dict.uncraft.count( recipe_id( r.result().str() ) ) ) { - recipe_dict.uncraft[ recipe_id( r.result().str() ) ] = r; + + const string_id uncraft_id = recipe_id( r.result().str() ); + if( r.is_reversible() && !recipe_dict.uncraft.count( uncraft_id ) ) { + recipe_dict.uncraft[ uncraft_id ] = r; + + if( r.uncraft_time > 0 ) { + // If a specified uncraft time has been given, use that in the uncraft + // recipe rather than the original. + recipe_dict.uncraft[ uncraft_id ].time = r.uncraft_time; + } } } @@ -551,7 +559,7 @@ void recipe_dictionary::finalize() // books that don't already have an uncrafting recipe if( e->book && !recipe_dict.uncraft.count( rid ) && e->volume > 0_ml ) { int pages = e->volume / 12.5_ml; - auto &bk = recipe_dict.uncraft[rid]; + recipe &bk = recipe_dict.uncraft[rid]; bk.ident_ = rid; bk.result_ = id; bk.reversible = true;