From 5e882cd8bbb08b60392065a77ad360e9d177533c Mon Sep 17 00:00:00 2001 From: Kamayana Date: Wed, 27 Dec 2023 05:20:35 -0600 Subject: [PATCH 1/3] Actually check items inserted into special pockets --- src/item_pocket.cpp | 48 ++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/src/item_pocket.cpp b/src/item_pocket.cpp index 5b14aece98b02..3283106e5ddd1 100644 --- a/src/item_pocket.cpp +++ b/src/item_pocket.cpp @@ -1331,9 +1331,19 @@ static int charges_per_volume_recursive( const units::volume &max_item_volume, ret_val item_pocket::is_compatible( const item &it ) const { - if( it.has_flag( flag_NO_UNWIELD ) ) { - return ret_val::make_failure( - contain_code::ERR_MOD, _( "cannot unwield item" ) ); + if( data->type == pocket_type::MIGRATION ) { + // migration pockets need to always succeed + return ret_val::make_success(); + } + + + if( data->type == pocket_type::MOD ) { + if( it.is_toolmod() || it.is_gunmod() ) { + return ret_val::make_success(); + } else { + return ret_val::make_failure( + contain_code::ERR_MOD, _( "only mods can go into mod pocket" ) ); + } } if( data->type == pocket_type::CORPSE ) { @@ -1342,6 +1352,15 @@ ret_val item_pocket::is_compatible( const item &it ) return ret_val::make_success(); } + if( data->type == pocket_type::SOFTWARE ) { + if( it.has_flag( flag_NO_DROP ) && it.has_flag( flag_IRREMOVABLE ) ) { + return ret_val::make_success(); + } else { + return ret_val::make_failure( + contain_code::ERR_MOD, _( "only immaterial items can go into software pocket" ) ); + } + } + if( data->type == pocket_type::EBOOK ) { if( it.is_book() ) { return ret_val::make_success(); @@ -1360,13 +1379,9 @@ ret_val item_pocket::is_compatible( const item &it ) } } - if( data->type == pocket_type::MOD ) { - if( it.is_toolmod() || it.is_gunmod() ) { - return ret_val::make_success(); - } else { - return ret_val::make_failure( - contain_code::ERR_MOD, _( "only mods can go into mod pocket" ) ); - } + if( it.has_flag( flag_NO_UNWIELD ) ) { + return ret_val::make_failure( + contain_code::ERR_MOD, _( "cannot unwield item" ) ); } if( !data->item_id_restriction.empty() || !data->get_flag_restrictions().empty() || @@ -1456,12 +1471,6 @@ ret_val item_pocket::_can_contain( const item &it, if( copies_remaining <= 0 ) { return ret_val::make_success(); } - if( data->type == pocket_type::CORPSE ) { - // corpses can't have items stored in them the normal way, - // we simply don't want them to "spill" - copies_remaining = 0; - return ret_val::make_success(); - } // To prevent debugmsg. Casings can only be inserted in a magazine during firing. if( data->type == pocket_type::MAGAZINE && it.has_flag( flag_CASING ) ) { copies_remaining = 0; @@ -1471,6 +1480,10 @@ ret_val item_pocket::_can_contain( const item &it, if( !compatible.success() ) { return compatible; } + if( !is_standard_type() ) { + copies_remaining = 0; + return ret_val::make_success(); + } if( it.made_of( phase_id::LIQUID ) ) { if( size() != 0 && !contents.front().can_combine( it ) && data->watertight ) { @@ -2185,8 +2198,7 @@ std::list &item_pocket::edit_contents() ret_val item_pocket::insert_item( const item &it, const bool into_bottom, bool restack_charges, bool ignore_contents ) { - ret_val containable = !is_standard_type() ? - ret_val::make_success() : can_contain( it, ignore_contents ); + ret_val containable = can_contain( it, ignore_contents ); if( !containable.success() ) { return ret_val::make_failure( nullptr, containable.str() ); From 5cc5f57d1fa0101c3ed64f456d712d9032ddcba0 Mon Sep 17 00:00:00 2001 From: Kamayana Date: Wed, 27 Dec 2023 05:21:54 -0600 Subject: [PATCH 2/3] Migrate invalid MOD pocket contents on load --- src/item_contents.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/item_contents.cpp b/src/item_contents.cpp index fb52ecc76e1bb..f59cbde10d74b 100644 --- a/src/item_contents.cpp +++ b/src/item_contents.cpp @@ -646,7 +646,12 @@ void item_contents::read_mods( const item_contents &read_input ) for( const item_pocket &pocket : read_input.contents ) { if( pocket.saved_type() == pocket_type::MOD ) { for( const item *it : pocket.all_items_top() ) { - insert_item( *it, pocket_type::MOD ); + if( it->is_gunmod() || it->is_toolmod() ) { + insert_item( *it, pocket_type::MOD ); + } else { + debugmsg( "Non-mod %s in MOD pocket!", it->tname() ); + insert_item( *it, pocket_type::MIGRATION ); + } } } } From 6163aa6e77244a466c64413f9cb1aa544985f434 Mon Sep 17 00:00:00 2001 From: Kamayana Date: Wed, 27 Dec 2023 07:30:29 -0600 Subject: [PATCH 3/3] Attempt to re-insert contents of mismatched pockets --- src/item_contents.cpp | 17 +++++++++++++++++ src/item_pocket.cpp | 1 - 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/item_contents.cpp b/src/item_contents.cpp index f59cbde10d74b..c7102c3d01c9a 100644 --- a/src/item_contents.cpp +++ b/src/item_contents.cpp @@ -660,6 +660,7 @@ void item_contents::read_mods( const item_contents &read_input ) void item_contents::combine( const item_contents &read_input, const bool convert, const bool into_bottom, bool restack_charges, bool ignore_contents ) { + std::list mismatched_pockets; std::vector uninserted_items; size_t pocket_index = 0; @@ -702,6 +703,11 @@ void item_contents::combine( const item_contents &read_input, const bool convert auto current_pocket_iter = contents.begin(); std::advance( current_pocket_iter, pocket_index ); + if( !current_pocket_iter->is_type( pocket.saved_type() ) ) { + mismatched_pockets.push_back( pocket ); + continue; + } + for( const item *it : pocket.all_items_top() ) { const ret_val inserted = current_pocket_iter->insert_item( *it, into_bottom, restack_charges, ignore_contents ); @@ -724,6 +730,17 @@ void item_contents::combine( const item_contents &read_input, const bool convert ++pocket_index; } + for( const item_pocket &pocket : mismatched_pockets ) { + for( const item *it : pocket.all_items_top() ) { + const ret_val inserted = insert_item( *it, pocket.saved_type(), ignore_contents ); + if( !inserted.success() ) { + uninserted_items.push_back( *it ); + debugmsg( "error: item %s cannot fit into any pocket while loading: %s", + it->typeId().str(), inserted.str() ); + } + } + } + for( const item &uninserted_item : uninserted_items ) { insert_item( uninserted_item, pocket_type::MIGRATION, ignore_contents ); } diff --git a/src/item_pocket.cpp b/src/item_pocket.cpp index 3283106e5ddd1..f6e9120ff7a71 100644 --- a/src/item_pocket.cpp +++ b/src/item_pocket.cpp @@ -1336,7 +1336,6 @@ ret_val item_pocket::is_compatible( const item &it ) return ret_val::make_success(); } - if( data->type == pocket_type::MOD ) { if( it.is_toolmod() || it.is_gunmod() ) { return ret_val::make_success();