@@ -550,10 +550,12 @@ void item_contents::force_insert_item( const item &it, item_pocket::pocket_type
550
550
}
551
551
552
552
std::pair<item_location, item_pocket *> item_contents::best_pocket ( const item &it,
553
- item_location &parent, const item *avoid, const bool allow_sealed, const bool ignore_settings )
553
+ item_location &parent, const item *avoid, const bool allow_sealed, const bool ignore_settings,
554
+ const bool nested )
554
555
{
555
- std::pair<item_location, item_pocket *> ret;
556
- ret.second = nullptr ;
556
+ // @TODO: this could be made better by doing a plain preliminary volume check.
557
+ // if the total volume of the parent is not sufficient, a child won't have enough either.
558
+ std::pair<item_location, item_pocket *> ret = { parent, nullptr };
557
559
for ( item_pocket &pocket : contents ) {
558
560
if ( !pocket.is_type ( item_pocket::pocket_type::CONTAINER ) ) {
559
561
// best pocket is for picking stuff up.
@@ -565,29 +567,24 @@ std::pair<item_location, item_pocket *> item_contents::best_pocket( const item &
565
567
// that needs to be something a player explicitly does
566
568
continue ;
567
569
}
568
- if ( !pocket.can_contain ( it ).success () ) {
569
- continue ;
570
- }
571
570
if ( !ignore_settings && !pocket.settings .accepts_item ( it ) ) {
572
571
// Item forbidden by whitelist / blacklist
573
572
continue ;
574
573
}
575
- if ( ret.second == nullptr || ret.second ->better_pocket ( pocket, it ) ) {
576
- // this pocket is the new candidate for "best"
577
- ret.first = parent;
574
+ item_pocket *const nested_content_pocket =
575
+ pocket.best_pocket_in_contents ( parent, it, avoid, allow_sealed, ignore_settings );
576
+ if ( nested_content_pocket != nullptr ) {
577
+ // item fits in pockets contents, no need to check the pocket itself.
578
+ // this gives nested pockets priority over parent pockets.
579
+ ret.second = nested_content_pocket;
580
+ continue ;
581
+ }
582
+ if ( !pocket.can_contain ( it ).success () || ( nested && !pocket.rigid () ) ) {
583
+ // non-rigid nested pocket makes no sense, item should also be able to fit in parent.
584
+ continue ;
585
+ }
586
+ if ( ret.second == nullptr || ret.second ->better_pocket ( pocket, it, /* nested=*/ nested ) ) {
578
587
ret.second = &pocket;
579
- // check all pockets within to see if they are better
580
- for ( item *contained : pocket.all_items_top () ) {
581
- if ( contained == avoid ) {
582
- continue ;
583
- }
584
- std::pair<item_location, item_pocket *> internal_pocket =
585
- contained->best_pocket ( it, parent, avoid, /* allow_sealed=*/ false , /* ignore_settings=*/ false );
586
- if ( internal_pocket.second != nullptr &&
587
- ret.second ->better_pocket ( *internal_pocket.second , it, true ) ) {
588
- ret = internal_pocket;
589
- }
590
- }
591
588
}
592
589
}
593
590
return ret;
0 commit comments