diff --git a/src/item.cpp b/src/item.cpp index 2fa4b9fd62603..3db57d5ffc59c 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -3295,39 +3295,41 @@ void item::final_info( std::vector &info, const iteminfo_query *parts, } // list recipes you could use it in - itype_id tid; - if( contents.empty() ) { // use this item - tid = typeId(); - } else { // use the contained item - tid = contents.front().typeId(); - } - const std::set &known_recipes = g->u.get_learned_recipes().of_component( tid ); - if( !known_recipes.empty() && parts->test( iteminfo_parts::DESCRIPTION_APPLICABLE_RECIPES ) ) { - const inventory &inv = g->u.crafting_inventory(); + if( parts->test( iteminfo_parts::DESCRIPTION_APPLICABLE_RECIPES ) ) { + itype_id tid = contents.empty() ? typeId() : contents.front().typeId(); + const inventory &crafting_inv = g->u.crafting_inventory(); + const recipe_subset available_recipe_subset = g->u.get_available_recipes( crafting_inv ); + const std::set &item_recipes = available_recipe_subset.of_component( tid ); - if( known_recipes.size() > 24 ) { - insert_separation_line( info ); - info.push_back( iteminfo( "DESCRIPTION", - _( "You know dozens of things you could craft with it." ) ) ); - } else if( known_recipes.size() > 12 ) { + if( item_recipes.empty() ) { insert_separation_line( info ); info.push_back( iteminfo( "DESCRIPTION", - _( "You could use it to craft various other things." ) ) ); + _( "You know of nothing you could craft with it." ) ) ); } else { - const std::string recipes = enumerate_as_string( known_recipes.begin(), known_recipes.end(), - [ &inv ]( const recipe * r ) { - if( r->deduped_requirements().can_make_with_inventory( - inv, r->get_component_filter() ) ) { - return r->result_name(); - } else { - return string_format( "%s", r->result_name() ); - } - } ); - if( !recipes.empty() ) { + if( item_recipes.size() > 24 ) { + insert_separation_line( info ); + info.push_back( iteminfo( "DESCRIPTION", + _( "You know dozens of things you could craft with it." ) ) ); + } else if( item_recipes.size() > 12 ) { insert_separation_line( info ); info.push_back( iteminfo( "DESCRIPTION", - string_format( _( "You could use it to craft: %s" ), - recipes ) ) ); + _( "You could use it to craft various other things." ) ) ); + } else { + const std::string recipes = enumerate_as_string( item_recipes.begin(), item_recipes.end(), + [ &crafting_inv ]( const recipe * r ) { + if( r->deduped_requirements().can_make_with_inventory( + crafting_inv, r->get_component_filter() ) ) { + return r->result_name(); + } else { + return string_format( "%s", r->result_name() ); + } + } ); + if( !recipes.empty() ) { + insert_separation_line( info ); + info.push_back( iteminfo( "DESCRIPTION", + string_format( _( "You could use it to craft: %s" ), + recipes ) ) ); + } } } } diff --git a/tests/iteminfo_test.cpp b/tests/iteminfo_test.cpp index 46a1e4ea495e1..7c7fdd7c80cc1 100644 --- a/tests/iteminfo_test.cpp +++ b/tests/iteminfo_test.cpp @@ -7,6 +7,7 @@ #include "game.h" #include "item.h" #include "iteminfo_query.h" +#include "recipe_dictionary.h" static void iteminfo_test( const item &i, const iteminfo_query &q, const std::string &reference ) { @@ -99,3 +100,58 @@ TEST_CASE( "nutrient_ranges_for_recipe_exemplars", "[item][iteminfo]" ) "Vitamins (RDA): Calcium (7-28%), Iron (0-83%), " "Vitamin A (3-11%), Vitamin B12 (2-6%), and Vitamin C (1-85%)\n" ); } + +TEST_CASE( "show available recipes with item as an ingredient", "[item][iteminfo][recipes]" ) +{ + iteminfo_query q( { iteminfo_parts::DESCRIPTION_APPLICABLE_RECIPES } ); + const recipe *purtab = &recipe_id( "pur_tablets" ).obj(); + g->u.empty_traits(); + + GIVEN( "character has a potassium iodide tablet and no skill" ) { + item &iodine = g->u.i_add( item( "iodine" ) ); + g->u.empty_skills(); + + THEN( "nothing is craftable from it" ) { + iteminfo_test( + iodine, q, + "--\nYou know of nothing you could craft with it.\n" ); + } + + WHEN( "they acquire the needed skills" ) { + g->u.set_skill_level( purtab->skill_used, purtab->difficulty ); + REQUIRE( g->u.get_skill_level( purtab->skill_used ) == purtab->difficulty ); + + THEN( "still nothing is craftable from it" ) { + iteminfo_test( + iodine, q, + "--\nYou know of nothing you could craft with it.\n" ); + } + + WHEN( "they have no book, but have the recipe memorized" ) { + g->u.learn_recipe( purtab ); + REQUIRE( g->u.knows_recipe( purtab ) ); + + THEN( "they can use potassium iodide tablets to craft it" ) { + iteminfo_test( + iodine, q, + "--\n" + "You could use it to craft: " + "water purification tablet\n" ); + } + } + + WHEN( "they have the recipe in a book, but not memorized" ) { + g->u.i_add( item( "textbook_chemistry" ) ); + + THEN( "they can use potassium iodide tablets to craft it" ) { + iteminfo_test( + iodine, q, + "--\n" + "You could use it to craft: " + "water purification tablet\n" ); + } + } + } + } +} +