From 06adba28b4f9f07d3c8078ce02bdeb00b29e97ea Mon Sep 17 00:00:00 2001 From: zeropol Date: Thu, 1 Apr 2021 03:58:53 +0200 Subject: [PATCH] Filter items by book skill ( V, e, / ), fixes #47530 (#48275) * Add a filter to search books by skills they teach * Hide books not skimmed when filtering items The player was able to know which skill a book tech without first skim it. * Fix typographic error * Check non-skill by ID name() is i18n-dependent and it may return something other than "nothing" in different languages. Co-authored-by: Binrui Dong --- src/item.cpp | 10 ++++++++++ src/item.h | 2 ++ src/item_search.cpp | 10 ++++++++++ src/output.cpp | 5 +++-- 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/item.cpp b/src/item.cpp index 012a7e7d8f17b..5bac244aa48bb 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -7099,6 +7099,16 @@ bool item::is_book() const return !!type->book; } +std::string item::get_book_skill() const +{ + if( is_book() ) { + if( type->book->skill->ident() != skill_id::NULL_ID() ) { + return type->book->skill->name(); + } + } + return ""; +} + bool item::is_map() const { return get_category_shallow().get_id() == item_category_maps; diff --git a/src/item.h b/src/item.h index 9569cade94e2c..75ccd1f5c0602 100644 --- a/src/item.h +++ b/src/item.h @@ -1243,6 +1243,8 @@ class item : public visitable /** Returns true if the item is A: is SOLID and if it B: is of type LIQUID */ bool is_frozen_liquid() const; + /** Returns empty string if the book teach no skill */ + std::string get_book_skill() const; float get_specific_heat_liquid() const; float get_specific_heat_solid() const; float get_latent_heat() const; diff --git a/src/item_search.cpp b/src/item_search.cpp index fd6b92bd44d22..04ff020e4a3e0 100644 --- a/src/item_search.cpp +++ b/src/item_search.cpp @@ -3,7 +3,9 @@ #include #include +#include "avatar.h" #include "cata_utility.h" +#include "game.h" #include "item.h" #include "item_category.h" #include "material.h" @@ -68,6 +70,14 @@ std::function basic_item_filter( std::string filter ) const std::string note = i.get_var( "item_note" ); return !note.empty() && lcmatch( note, filter ); }; + // by book skill + case 's': + return [filter]( const item & i ) { + if( get_avatar().has_identified( i.typeId() ) ) { + return lcmatch( i.get_book_skill(), filter ); + } + return false; + }; // by name default: return [filter]( const item & a ) { diff --git a/src/output.cpp b/src/output.cpp index cdd163a12ce1f..545cbf00c5e07 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -870,11 +870,12 @@ void draw_item_filter_rules( const catacurses::window &win, int starty, int heig starty += fold_and_print( win, point( 1, starty ), len, c_white, _( "Search [c]ategory, [m]aterial, " - "[q]uality, [n]otes or " + "[q]uality, [n]otes, " + "[s]skill taught by books or " "[d]isassembled components." ) ); fold_and_print( win, point( 1, starty ), len, c_white, //~ An example of how to filter items based on category or material. - _( "Examples: c:food,m:iron,q:hammering,n:toolshelf,d:pipe" ) ); + _( "Examples: c:food,m:iron,q:hammering,n:toolshelf,d:pipe,s:devices" ) ); wnoutrefresh( win ); }