diff --git a/src/item.cpp b/src/item.cpp index 6fde92bb035ec..d524896e6906a 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -5661,6 +5661,27 @@ void item::melee_combat_info( std::vector &info, const iteminfo_query } } +std::vector> get_item_duplicate_counts( + const std::list &items ) +{ + std::vector> counted_items; + for( const item *contents_item : items ) { + bool found = false; + for( std::pair &content : counted_items ) { + if( content.first->display_stacked_with( *contents_item ) ) { + content.second += 1; + found = true; + } + } + if( !found ) { + std::pair new_content( contents_item, 1 ); + counted_items.push_back( new_content ); + } + } + return counted_items; +} + + void item::contents_info( std::vector &info, const iteminfo_query *parts, int batch, bool /*debug*/ ) const { @@ -5686,8 +5707,14 @@ void item::contents_info( std::vector &info, const iteminfo_query *par info.emplace_back( "DESCRIPTION", mod_str ); info.emplace_back( "DESCRIPTION", mod->type->description.translated() ); } + + const std::list all_contents = contents.all_items_top(); + const std::vector> counted_contents = get_item_duplicate_counts( + all_contents ); bool contents_header = false; - for( const item *contents_item : contents.all_items_top() ) { + for( const std::pair &content_w_count : counted_contents ) { + const item *contents_item = content_w_count.first; + int count = content_w_count.second; if( !contents_header ) { insert_separation_line( info ); info.emplace_back( "DESCRIPTION", _( "Contents of this item:" ) ); @@ -5701,12 +5728,16 @@ void item::contents_info( std::vector &info, const iteminfo_query *par if( contents_item->made_of_from_type( phase_id::LIQUID ) ) { units::volume contents_volume = contents_item->volume() * batch; - info.emplace_back( "DESCRIPTION", colorize( contents_item->display_name(), - contents_item->color_in_inventory() ) ); + info.emplace_back( "DESCRIPTION", + colorize( contents_item->display_name(), contents_item->color_in_inventory() ) ); info.emplace_back( vol_to_info( "CONTAINER", description + space, contents_volume ) ); } else { - info.emplace_back( "DESCRIPTION", colorize( contents_item->display_name(), - contents_item->color_in_inventory() ) ); + std::string name; + if( count > 1 ) { + name += std::to_string( count ) + " "; + } + name += colorize( contents_item->display_name( count ), contents_item->color_in_inventory() ); + info.emplace_back( "DESCRIPTION", name ); info.emplace_back( "DESCRIPTION", description.translated() ); } } diff --git a/src/item.h b/src/item.h index e3ea202ce2ccc..fd5d2cef95594 100644 --- a/src/item.h +++ b/src/item.h @@ -3347,3 +3347,12 @@ struct disp_mod_by_barrel { dispersion_modifier( disp ) {} void deserialize( const JsonObject &jo ); }; + +/** + * Given an iterable of `const item* ` (such as obtained from `all_items_top()`), + * returns the vector of each unique item in the iterable, and the amount of times it + * was encountered. + * For display purposes only. + */ +std::vector> get_item_duplicate_counts( + const std::list &items ); diff --git a/src/item_pocket.cpp b/src/item_pocket.cpp index 310b4251137a6..503732020e0b1 100644 --- a/src/item_pocket.cpp +++ b/src/item_pocket.cpp @@ -1268,42 +1268,34 @@ void item_pocket::contents_info( std::vector &info, int pocket_number, // ablative pockets have their contents displayed earlier in the UI if( !is_ablative() ) { - std::vector> counted_contents; + std::vector> counted_contents = get_item_duplicate_counts( + all_items_top() ); bool contents_header = false; - for( const item &contents_item : contents ) { + + for( std::pair content : counted_contents ) { + const item *contents_item = content.first; + const int count = content.second; + if( !contents_header ) { info.emplace_back( "DESCRIPTION", _( "Contents of this pocket:" ) ); contents_header = true; } - const translation &desc = contents_item.type->description; + const translation &desc = contents_item->type->description; - if( contents_item.made_of_from_type( phase_id::LIQUID ) ) { - info.emplace_back( "DESCRIPTION", colorize( space + contents_item.display_name(), - contents_item.color_in_inventory() ) ); - info.emplace_back( vol_to_info( cont_type_str, desc + space, contents_item.volume() ) ); - } else { - bool found = false; - for( std::pair &content : counted_contents ) { - if( content.first->display_stacked_with( contents_item ) ) { - content.second += 1; - found = true; - } - } - if( !found ) { - std::pair new_content( &contents_item, 1 ); - counted_contents.push_back( new_content ); - } - } - } - for( std::pair content : counted_contents ) { - if( content.second > 1 ) { + if( contents_item->made_of_from_type( phase_id::LIQUID ) ) { info.emplace_back( "DESCRIPTION", - space + std::to_string( content.second ) + " " + colorize( content.first->display_name( - content.second ), content.first->color_in_inventory() ) ); + colorize( space + contents_item->display_name(), contents_item->color_in_inventory() ) ); + info.emplace_back( vol_to_info( cont_type_str, desc + space, contents_item->volume() ) ); } else { - info.emplace_back( "DESCRIPTION", space + colorize( content.first->display_name(), - content.first->color_in_inventory() ) ); + if( count > 1 ) { + info.emplace_back( "DESCRIPTION", + space + std::to_string( count ) + " " + colorize( contents_item->display_name( + count ), contents_item->color_in_inventory() ) ); + } else { + info.emplace_back( "DESCRIPTION", + space + colorize( contents_item->display_name(), contents_item->color_in_inventory() ) ); + } } } }