diff --git a/src/advanced_inv.cpp b/src/advanced_inv.cpp index 975ec9afe2b92..8d6d3ab5f813c 100644 --- a/src/advanced_inv.cpp +++ b/src/advanced_inv.cpp @@ -940,7 +940,7 @@ static itemstack i_stacked( T items ) // check to see if it stacks with each item in a stack, not just front() for( auto &idx : iter->second ) { for( auto &it : stacks[idx] ) { - if( ( got_stacked = it->stacks_with( elem ) ) ) { + if( ( got_stacked = it->display_stacked_with( elem ) ) ) { stacks[idx].push_back( &elem ); break; } diff --git a/src/inventory_ui.cpp b/src/inventory_ui.cpp index e515b70d1f776..f952f04a2c2b5 100644 --- a/src/inventory_ui.cpp +++ b/src/inventory_ui.cpp @@ -1023,7 +1023,7 @@ static std::vector> restack_items( const std::list::cons for( auto it = from; it != to; ++it ) { auto match = std::find_if( res.begin(), res.end(), [ &it, check_components ]( const std::list &e ) { - return it->stacks_with( *const_cast( e.back() ), check_components ); + return it->display_stacked_with( *const_cast( e.back() ), check_components ); } ); if( match != res.end() ) { @@ -1045,7 +1045,7 @@ static std::vector> restack_items( const item_stack::const_ite for( auto it = from; it != to; ++it ) { auto match = std::find_if( res.begin(), res.end(), [ &it, check_components ]( const std::list &e ) { - return it->stacks_with( *const_cast( e.back() ), check_components ); + return it->display_stacked_with( *const_cast( e.back() ), check_components ); } ); if( match != res.end() ) { diff --git a/src/item.cpp b/src/item.cpp index 4b9f58c723fc7..8a5d4682c6bab 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -679,6 +679,11 @@ int item::charges_per_volume( const units::volume &vol ) const } } +bool item::display_stacked_with( const item &rhs, bool check_components ) const +{ + return !count_by_charges() && stacks_with( rhs, check_components ); +} + bool item::stacks_with( const item &rhs, bool check_components ) const { if( type != rhs.type ) { @@ -6588,10 +6593,19 @@ bool item::reload( player &u, item_location loc, int qty ) } } - contents.emplace_back( *ammo ); - contents.back().charges = qty; + item to_reload = *ammo; + to_reload.charges = qty; ammo->charges -= qty; - + bool merged = false; + for( auto &it : contents ) { + if( it.merge_charges( to_reload ) ) { + merged = true; + break; + } + } + if( !merged ) { + contents.emplace_back( to_reload ); + } } else if( is_watertight_container() ) { if( !ammo->made_of_from_type( LIQUID ) ) { debugmsg( "Tried to reload liquid container with non-liquid." ); diff --git a/src/item.h b/src/item.h index 1ac9f2573d894..f41aee934643e 100644 --- a/src/item.h +++ b/src/item.h @@ -444,6 +444,14 @@ class item : public visitable */ int price( bool practical ) const; + /** + * Whether two items should stack when displayed in a inventory menu. + * This is different from stacks_with, when two previously non-stackable + * items are now stackable and mergeable because, for example, they + * reaches the same temperature. This is necessary to avoid misleading + * stacks like "3 items-count-by-charge (5)". + */ + bool display_stacked_with( const item &rhs, bool check_components = false ) const; bool stacks_with( const item &rhs, bool check_components = false ) const; /** * Merge charges of the other item into this item. diff --git a/src/pickup.cpp b/src/pickup.cpp index 868430d9f42a3..442e7c2f617b2 100644 --- a/src/pickup.cpp +++ b/src/pickup.cpp @@ -457,7 +457,7 @@ void Pickup::pick_up( const tripoint &p, int min, from_where get_items_from ) for( item_stack::iterator it : here ) { bool found_stack = false; for( std::list &stack : stacked_here ) { - if( stack.front()->stacks_with( *it ) ) { + if( stack.front()->display_stacked_with( *it ) ) { stack.push_back( it ); found_stack = true; break;