From 1c44ad7dab1b836af91c05a499d4b06c36827431 Mon Sep 17 00:00:00 2001 From: Qrox Date: Sat, 26 Jun 2021 09:42:13 +0800 Subject: [PATCH] Allow removing items in pocket whitelist/blacklist but not nearby --- src/item_contents.cpp | 79 +++++++++++++++++++++++++++++++++++-------- src/item_pocket.cpp | 22 ++++++++++++ src/item_pocket.h | 5 +++ 3 files changed, 91 insertions(+), 15 deletions(-) diff --git a/src/item_contents.cpp b/src/item_contents.cpp index e9b93f6fae5ca..eb51af4911dcd 100644 --- a/src/item_contents.cpp +++ b/src/item_contents.cpp @@ -141,30 +141,67 @@ bool pocket_favorite_callback::key( const input_context &, const input_event &ev const bool cat_id = input == 'c'; uilist selector_menu; + const std::string remove_prefix = "- "; + const std::string add_prefix = "+ "; + if( item_id ) { - std::map nearby_itypes; + const cata::flat_set &listed_itypes = whitelist + ? selected_pocket->settings.get_item_whitelist() + : selected_pocket->settings.get_item_blacklist(); + cata::flat_set nearby_itypes; selector_menu.title = _( "Select an item from nearby" ); for( const std::list *it_list : get_player_character().crafting_inventory().const_slice() ) { - nearby_itypes.emplace( it_list->front().typeId()->nname( 1 ), it_list->front().type ); + nearby_itypes.insert( it_list->front().typeId() ); } - std::vector itype_initializer; - for( const std::pair &name : nearby_itypes ) { - itype_initializer.emplace_back( name.first ); + std::vector> listed_names; + std::vector> nearby_names; + for( const itype_id &id : listed_itypes ) { + listed_names.emplace_back( id, id->nname( 1 ) ); + } + for( const itype_id &id : nearby_itypes ) { + if( !listed_itypes.count( id ) ) { + nearby_names.emplace_back( id, id->nname( 1 ) ); + } } - std::sort( itype_initializer.begin(), itype_initializer.end(), localized_compare ); + const auto &compare_names = []( const std::pair &lhs, + const std::pair &rhs ) { + return localized_compare( lhs.second, rhs.second ); + }; + std::sort( listed_names.begin(), listed_names.end(), compare_names ); + std::sort( nearby_names.begin(), nearby_names.end(), compare_names ); - for( const std::string &it : itype_initializer ) { - selector_menu.addentry( it ); + for( const std::pair &it : listed_names ) { + selector_menu.addentry( remove_prefix + it.second ); + } + for( const std::pair &it : nearby_names ) { + selector_menu.addentry( add_prefix + it.second ); } selector_menu.query(); - if( selector_menu.ret >= 0 ) { - const itype_id id( nearby_itypes[itype_initializer.at( selector_menu.ret )]->get_id() ); + const int selected = selector_menu.ret; + itype_id selected_id = itype_id::NULL_ID(); + if( selected >= 0 ) { + size_t idx = selected; + const std::vector> *names = nullptr; + if( idx < listed_names.size() ) { + names = &listed_names; + } else { + idx -= listed_names.size(); + } + if( !names && idx < nearby_names.size() ) { + names = &nearby_names; + } + if( names ) { + selected_id = ( *names )[idx].first; + } + } + + if( !selected_id.is_null() ) { if( whitelist ) { - selected_pocket->settings.whitelist_item( id ); + selected_pocket->settings.whitelist_item( selected_id ); } else { - selected_pocket->settings.blacklist_item( id ); + selected_pocket->settings.blacklist_item( selected_id ); } } @@ -172,18 +209,30 @@ bool pocket_favorite_callback::key( const input_context &, const input_event &ev } else if( cat_id ) { // Get all categories and sort by name std::vector all_cat = item_category::get_all(); - std::sort( all_cat.begin(), all_cat.end(), []( const item_category & lhs, + const cata::flat_set &listed_cat = whitelist + ? selected_pocket->settings.get_category_whitelist() + : selected_pocket->settings.get_category_blacklist(); + std::sort( all_cat.begin(), all_cat.end(), [&]( const item_category & lhs, const item_category & rhs ) { + const bool lhs_in_list = listed_cat.count( lhs.get_id() ); + const bool rhs_in_list = listed_cat.count( rhs.get_id() ); + if( lhs_in_list && !rhs_in_list ) { + return true; + } else if( !lhs_in_list && rhs_in_list ) { + return false; + } return localized_compare( lhs.name(), rhs.name() ); } ); for( const item_category &cat : all_cat ) { - selector_menu.addentry( cat.name() ); + const bool in_list = listed_cat.count( cat.get_id() ); + const std::string &prefix = in_list ? remove_prefix : add_prefix; + selector_menu.addentry( prefix + cat.name() ); } selector_menu.query(); if( selector_menu.ret >= 0 ) { - const item_category_id id( all_cat.at( selector_menu.ret ).id ); + const item_category_id id( all_cat.at( selector_menu.ret ).get_id() ); if( whitelist ) { selected_pocket->settings.whitelist_category( id ); } else { diff --git a/src/item_pocket.cpp b/src/item_pocket.cpp index 2ac13bc398231..286c7ab3e666f 100644 --- a/src/item_pocket.cpp +++ b/src/item_pocket.cpp @@ -1605,6 +1605,28 @@ void item_pocket::favorite_settings::clear_item( const itype_id &id ) item_blacklist.erase( id ); } +const cata::flat_set &item_pocket::favorite_settings::get_item_whitelist() const +{ + return item_whitelist; +} + +const cata::flat_set &item_pocket::favorite_settings::get_item_blacklist() const +{ + return item_blacklist; +} + +const cata::flat_set & +item_pocket::favorite_settings::get_category_whitelist() const +{ + return category_whitelist; +} + +const cata::flat_set & +item_pocket::favorite_settings::get_category_blacklist() const +{ + return category_blacklist; +} + void item_pocket::favorite_settings::whitelist_category( const item_category_id &id ) { category_blacklist.clear(); diff --git a/src/item_pocket.h b/src/item_pocket.h index 3be380c88fd88..074112fe654b7 100644 --- a/src/item_pocket.h +++ b/src/item_pocket.h @@ -88,6 +88,11 @@ class item_pocket void blacklist_item( const itype_id &id ); void clear_item( const itype_id &id ); + const cata::flat_set &get_item_whitelist() const; + const cata::flat_set &get_item_blacklist() const; + const cata::flat_set &get_category_whitelist() const; + const cata::flat_set &get_category_blacklist() const; + void whitelist_category( const item_category_id &id ); void blacklist_category( const item_category_id &id ); void clear_category( const item_category_id &id );