From d17b0717fe5c4fc5e683f460f95bba049b26e010 Mon Sep 17 00:00:00 2001
From: moxian <moxian@users.noreply.github.com>
Date: Sat, 7 Dec 2024 00:29:41 -0800
Subject: [PATCH 1/6] Deduplicate item contents in the examine display

---
 src/item.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 43 insertions(+), 5 deletions(-)

diff --git a/src/item.cpp b/src/item.cpp
index 4a06128fdf848..a15e436acdc69 100644
--- a/src/item.cpp
+++ b/src/item.cpp
@@ -5658,6 +5658,35 @@ void item::melee_combat_info( std::vector<iteminfo> &info, const iteminfo_query
     }
 }
 
+static std::vector<std::pair<const item *, int>> deduplicate_items(
+    const std::list<const item*>& items )
+{
+    std::vector<std::pair<item const *, int>> counted_items;
+    bool contents_header = false;
+    for( const item* contents_item : items ) {
+        if( contents_item->made_of_from_type( phase_id::LIQUID ) ){
+            // we won't have duplicate liquids and counting them
+            // doesn't really make much sense anyway
+            std::pair<const item *, int> new_content( contents_item, 1 );
+            counted_items.push_back( new_content );
+        } else {
+            bool found = false;
+            for( std::pair<const item *, int>& content : counted_items ) {
+                if( content.first->stacks_with( *contents_item ) ) {
+                    content.second += 1;
+                    found = true;
+                }
+            }
+            if( !found ) {
+                std::pair<const item *, int> new_content( contents_item, 1 );
+                counted_items.push_back( new_content );
+            }
+        }
+    }
+    return counted_items;
+}
+
+
 void item::contents_info( std::vector<iteminfo> &info, const iteminfo_query *parts, int batch,
                           bool /*debug*/ ) const
 {
@@ -5683,8 +5712,13 @@ void item::contents_info( std::vector<iteminfo> &info, const iteminfo_query *par
         info.emplace_back( "DESCRIPTION", mod_str );
         info.emplace_back( "DESCRIPTION", mod->type->description.translated() );
     }
+    
+    const std::list<const item *> all_contents = contents.all_items_top();
+    std::vector<std::pair<item const *, int>> counted_contents = deduplicate_items(all_contents);
     bool contents_header = false;
-    for( const item *contents_item : contents.all_items_top() ) {
+    for( const auto 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", _( "<bold>Contents of this item</bold>:" ) );
@@ -5698,12 +5732,16 @@ void item::contents_info( std::vector<iteminfo> &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() );
         }
     }

From 799a7a9e468d5e968253c45db15b6b4066213853 Mon Sep 17 00:00:00 2001
From: moxian <moxian@users.noreply.github.com>
Date: Sat, 7 Dec 2024 00:53:55 -0800
Subject: [PATCH 2/6] astyle

---
 src/item.cpp | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/item.cpp b/src/item.cpp
index a15e436acdc69..63d0d61f050e3 100644
--- a/src/item.cpp
+++ b/src/item.cpp
@@ -5659,19 +5659,19 @@ void item::melee_combat_info( std::vector<iteminfo> &info, const iteminfo_query
 }
 
 static std::vector<std::pair<const item *, int>> deduplicate_items(
-    const std::list<const item*>& items )
+            const std::list<const item *> &items )
 {
     std::vector<std::pair<item const *, int>> counted_items;
     bool contents_header = false;
-    for( const item* contents_item : items ) {
-        if( contents_item->made_of_from_type( phase_id::LIQUID ) ){
+    for( const item *contents_item : items ) {
+        if( contents_item->made_of_from_type( phase_id::LIQUID ) ) {
             // we won't have duplicate liquids and counting them
             // doesn't really make much sense anyway
             std::pair<const item *, int> new_content( contents_item, 1 );
             counted_items.push_back( new_content );
         } else {
             bool found = false;
-            for( std::pair<const item *, int>& content : counted_items ) {
+            for( std::pair<const item *, int> &content : counted_items ) {
                 if( content.first->stacks_with( *contents_item ) ) {
                     content.second += 1;
                     found = true;
@@ -5712,12 +5712,12 @@ void item::contents_info( std::vector<iteminfo> &info, const iteminfo_query *par
         info.emplace_back( "DESCRIPTION", mod_str );
         info.emplace_back( "DESCRIPTION", mod->type->description.translated() );
     }
-    
+
     const std::list<const item *> all_contents = contents.all_items_top();
-    std::vector<std::pair<item const *, int>> counted_contents = deduplicate_items(all_contents);
+    std::vector<std::pair<item const *, int>> counted_contents = deduplicate_items( all_contents );
     bool contents_header = false;
-    for( const auto content_w_count : counted_contents ){
-        const item * contents_item = content_w_count.first;
+    for( const auto 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 );
@@ -5733,11 +5733,11 @@ void item::contents_info( std::vector<iteminfo> &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() ) );
+                               colorize( contents_item->display_name(), contents_item->color_in_inventory() ) );
             info.emplace_back( vol_to_info( "CONTAINER", description + space, contents_volume ) );
         } else {
             std::string name;
-            if( count > 1 ){
+            if( count > 1 ) {
                 name += std::to_string( count ) + " ";
             }
             name += colorize( contents_item->display_name( count ), contents_item->color_in_inventory() );

From aee6a554b54f4603757b22647f3cbc4bf793812b Mon Sep 17 00:00:00 2001
From: moxian <moxian@users.noreply.github.com>
Date: Sun, 8 Dec 2024 19:31:50 -0800
Subject: [PATCH 3/6] deduplicate code

---
 src/item.cpp        | 28 ++++++++++------------------
 src/item.h          |  8 ++++++++
 src/item_pocket.cpp | 45 ++++++++++++++++++---------------------------
 3 files changed, 36 insertions(+), 45 deletions(-)

diff --git a/src/item.cpp b/src/item.cpp
index 63d0d61f050e3..30bf18a0d4c85 100644
--- a/src/item.cpp
+++ b/src/item.cpp
@@ -5658,29 +5658,21 @@ void item::melee_combat_info( std::vector<iteminfo> &info, const iteminfo_query
     }
 }
 
-static std::vector<std::pair<const item *, int>> deduplicate_items(
+std::vector<std::pair<const item *, int>> get_item_duplicate_counts(
             const std::list<const item *> &items )
 {
     std::vector<std::pair<item const *, int>> counted_items;
-    bool contents_header = false;
     for( const item *contents_item : items ) {
-        if( contents_item->made_of_from_type( phase_id::LIQUID ) ) {
-            // we won't have duplicate liquids and counting them
-            // doesn't really make much sense anyway
+        bool found = false;
+        for( std::pair<const item *, int> &content : counted_items ) {
+            if( content.first->display_stacked_with( *contents_item ) ) {
+                content.second += 1;
+                found = true;
+            }
+        }
+        if( !found ) {
             std::pair<const item *, int> new_content( contents_item, 1 );
             counted_items.push_back( new_content );
-        } else {
-            bool found = false;
-            for( std::pair<const item *, int> &content : counted_items ) {
-                if( content.first->stacks_with( *contents_item ) ) {
-                    content.second += 1;
-                    found = true;
-                }
-            }
-            if( !found ) {
-                std::pair<const item *, int> new_content( contents_item, 1 );
-                counted_items.push_back( new_content );
-            }
         }
     }
     return counted_items;
@@ -5714,7 +5706,7 @@ void item::contents_info( std::vector<iteminfo> &info, const iteminfo_query *par
     }
 
     const std::list<const item *> all_contents = contents.all_items_top();
-    std::vector<std::pair<item const *, int>> counted_contents = deduplicate_items( all_contents );
+    const std::vector<std::pair<item const *, int>> counted_contents = get_item_duplicate_counts( all_contents );
     bool contents_header = false;
     for( const auto content_w_count : counted_contents ) {
         const item *contents_item = content_w_count.first;
diff --git a/src/item.h b/src/item.h
index 461fd00251b50..d818d4288d1b0 100644
--- a/src/item.h
+++ b/src/item.h
@@ -3345,3 +3345,11 @@ 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<std::pair<const item*, int>> get_item_duplicate_counts( const std::list<const item*>& items );
diff --git a/src/item_pocket.cpp b/src/item_pocket.cpp
index 310b4251137a6..1950806fa72f3 100644
--- a/src/item_pocket.cpp
+++ b/src/item_pocket.cpp
@@ -1268,42 +1268,33 @@ void item_pocket::contents_info( std::vector<iteminfo> &info, int pocket_number,
 
     // ablative pockets have their contents displayed earlier in the UI
     if( !is_ablative() ) {
-        std::vector<std::pair<item const *, int>> counted_contents;
+        std::vector<std::pair<const item *, int>> counted_contents = get_item_duplicate_counts( all_items_top() );
         bool contents_header = false;
-        for( const item &contents_item : contents ) {
+
+        for( std::pair<item const *, int> content : counted_contents ) {
+            const item* contents_item = content.first;
+            const int count = content.second;
+
             if( !contents_header ) {
                 info.emplace_back( "DESCRIPTION", _( "<bold>Contents of this pocket</bold>:" ) );
                 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<item const *, int> &content : counted_contents ) {
-                    if( content.first->display_stacked_with( contents_item ) ) {
-                        content.second += 1;
-                        found = true;
-                    }
-                }
-                if( !found ) {
-                    std::pair<item const *, int> new_content( &contents_item, 1 );
-                    counted_contents.push_back( new_content );
-                }
-            }
-        }
-        for( std::pair<item const *, int> 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() ) );
+                }
             }
         }
     }

From 7cb7a4c725e25cc8d2c72e6bd2ec3bfb100ebae6 Mon Sep 17 00:00:00 2001
From: moxian <moxian@users.noreply.github.com>
Date: Sun, 8 Dec 2024 19:46:59 -0800
Subject: [PATCH 4/6] astyle

---
 src/item.cpp        |  5 +++--
 src/item.h          |  3 ++-
 src/item_pocket.cpp | 19 ++++++++++---------
 3 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/src/item.cpp b/src/item.cpp
index 30bf18a0d4c85..4d937ecbbc3cc 100644
--- a/src/item.cpp
+++ b/src/item.cpp
@@ -5659,7 +5659,7 @@ void item::melee_combat_info( std::vector<iteminfo> &info, const iteminfo_query
 }
 
 std::vector<std::pair<const item *, int>> get_item_duplicate_counts(
-            const std::list<const item *> &items )
+        const std::list<const item *> &items )
 {
     std::vector<std::pair<item const *, int>> counted_items;
     for( const item *contents_item : items ) {
@@ -5706,7 +5706,8 @@ void item::contents_info( std::vector<iteminfo> &info, const iteminfo_query *par
     }
 
     const std::list<const item *> all_contents = contents.all_items_top();
-    const std::vector<std::pair<item const *, int>> counted_contents = get_item_duplicate_counts( all_contents );
+    const std::vector<std::pair<item const *, int>> counted_contents = get_item_duplicate_counts(
+                all_contents );
     bool contents_header = false;
     for( const auto content_w_count : counted_contents ) {
         const item *contents_item = content_w_count.first;
diff --git a/src/item.h b/src/item.h
index d818d4288d1b0..b6f92d9af6d85 100644
--- a/src/item.h
+++ b/src/item.h
@@ -3352,4 +3352,5 @@ struct disp_mod_by_barrel {
  * was encountered.
  * For display purposes only.
  */
-std::vector<std::pair<const item*, int>> get_item_duplicate_counts( const std::list<const item*>& items );
+std::vector<std::pair<const item *, int>> get_item_duplicate_counts( const std::list<const item *>
+                                       &items );
diff --git a/src/item_pocket.cpp b/src/item_pocket.cpp
index 1950806fa72f3..503732020e0b1 100644
--- a/src/item_pocket.cpp
+++ b/src/item_pocket.cpp
@@ -1268,11 +1268,12 @@ void item_pocket::contents_info( std::vector<iteminfo> &info, int pocket_number,
 
     // ablative pockets have their contents displayed earlier in the UI
     if( !is_ablative() ) {
-        std::vector<std::pair<const item *, int>> counted_contents = get_item_duplicate_counts( all_items_top() );
+        std::vector<std::pair<const item *, int>> counted_contents = get_item_duplicate_counts(
+                all_items_top() );
         bool contents_header = false;
 
         for( std::pair<item const *, int> content : counted_contents ) {
-            const item* contents_item = content.first;
+            const item *contents_item = content.first;
             const int count = content.second;
 
             if( !contents_header ) {
@@ -1282,18 +1283,18 @@ void item_pocket::contents_info( std::vector<iteminfo> &info, int pocket_number,
 
             const translation &desc = contents_item->type->description;
 
-            if( contents_item->made_of_from_type(phase_id::LIQUID) ) {
+            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() ) );
+                                   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 {
-                if( count > 1) {
+                if( count > 1 ) {
                     info.emplace_back( "DESCRIPTION",
-                        space + std::to_string(count) + " " + colorize( contents_item->display_name(
-                            count ), contents_item->color_in_inventory() ) );
+                                       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() ) );
+                    info.emplace_back( "DESCRIPTION",
+                                       space + colorize( contents_item->display_name(), contents_item->color_in_inventory() ) );
                 }
             }
         }

From cd01c9c76883ac97a2d5ebcc7a0701cc57971b32 Mon Sep 17 00:00:00 2001
From: moxian <moxian@users.noreply.github.com>
Date: Sun, 8 Dec 2024 19:57:23 -0800
Subject: [PATCH 5/6] astyle again

---
 src/item.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/item.h b/src/item.h
index b6f92d9af6d85..1b334125529ab 100644
--- a/src/item.h
+++ b/src/item.h
@@ -3352,5 +3352,5 @@ struct disp_mod_by_barrel {
  * was encountered.
  * For display purposes only.
  */
-std::vector<std::pair<const item *, int>> get_item_duplicate_counts( const std::list<const item *>
-                                       &items );
+std::vector<std::pair<const item *, int>> get_item_duplicate_counts(
+        const std::list<const item *> &items );

From 5db93b3b3f4cd12990f98108b9ec526d8d2a631f Mon Sep 17 00:00:00 2001
From: moxian <moxian@users.noreply.github.com>
Date: Mon, 16 Dec 2024 01:00:51 -0800
Subject: [PATCH 6/6] Thank you, clang-tidy!

---
 src/item.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/item.cpp b/src/item.cpp
index 4d937ecbbc3cc..8fea9d7237038 100644
--- a/src/item.cpp
+++ b/src/item.cpp
@@ -5709,7 +5709,7 @@ void item::contents_info( std::vector<iteminfo> &info, const iteminfo_query *par
     const std::vector<std::pair<item const *, int>> counted_contents = get_item_duplicate_counts(
                 all_contents );
     bool contents_header = false;
-    for( const auto content_w_count : counted_contents ) {
+    for( const std::pair<const item *, int> &content_w_count : counted_contents ) {
         const item *contents_item = content_w_count.first;
         int count = content_w_count.second;
         if( !contents_header ) {