static VisitResponse visit_internal( const std::function<VisitResponse( item *, item * )> &func, item *node, item *parent = nullptr ) { switch( func( node, parent ) ) { case VisitResponse::ABORT: return VisitResponse::ABORT; case VisitResponse::NEXT: if( node->is_gun() || node->is_magazine() ) { // content of guns and magazines are accessible only via their specific accessors return VisitResponse::NEXT; } for( auto &e : node->contents ) { if( visit_internal( func, &e, node ) == VisitResponse::ABORT ) { return VisitResponse::ABORT; } } /* intentional fallthrough */ case VisitResponse::SKIP: return VisitResponse::NEXT; } /* never reached but suppresses GCC warning */ return VisitResponse::ABORT; }
VisitResponse visitable<Character>::visit_items( const std::function<VisitResponse( item *, item * )> &func ) { auto ch = static_cast<Character *>( this ); if( !ch->weapon.is_null() && visit_internal( func, &ch->weapon ) == VisitResponse::ABORT ) { return VisitResponse::ABORT; } for( auto &e : ch->worn ) { if( visit_internal( func, &e ) == VisitResponse::ABORT ) { return VisitResponse::ABORT; } } return ch->inv.visit_items( func ); }
VisitResponse visitable<vehicle_cursor>::visit_items( const std::function<VisitResponse( item *, item * )> &func ) { auto self = static_cast<vehicle_cursor *>( this ); for( auto &e : self->veh.get_items( self->part ) ) { if( visit_internal( func, &e ) == VisitResponse::ABORT ) { return VisitResponse::ABORT; } } return VisitResponse::NEXT; }
VisitResponse visitable<map_cursor>::visit_items( const std::function<VisitResponse( item *, item * )> &func ) { auto cur = static_cast<map_cursor *>( this ); for( auto &e : g->m.i_at( *cur ) ) { if( visit_internal( func, &e ) == VisitResponse::ABORT ) { return VisitResponse::ABORT; } } return VisitResponse::NEXT; }
VisitResponse visitable<inventory>::visit_items( const std::function<VisitResponse( item *, item * )> &func ) { auto inv = static_cast<inventory *>( this ); for( auto &stack : inv->items ) { for( auto &it : stack ) { if( visit_internal( func, &it ) == VisitResponse::ABORT ) { return VisitResponse::ABORT; } } } return VisitResponse::NEXT; }
VisitResponse visitable<vehicle_cursor>::visit_items( const std::function<VisitResponse( item *, item * )> &func ) { auto self = static_cast<vehicle_cursor *>( this ); int idx = self->veh.part_with_feature( self->part, "CARGO" ); if( idx >= 0 ) { for( auto &e : self->veh.get_items( idx ) ) { if( visit_internal( func, &e ) == VisitResponse::ABORT ) { return VisitResponse::ABORT; } } } return VisitResponse::NEXT; }
VisitResponse visitable<map_cursor>::visit_items( const std::function<VisitResponse( item *, item * )> &func ) { auto cur = static_cast<map_cursor *>( this ); // skip inaccessible items if( g->m.has_flag( "SEALED", *cur ) ) { return VisitResponse::NEXT; } for( auto &e : g->m.i_at( *cur ) ) { if( visit_internal( func, &e ) == VisitResponse::ABORT ) { return VisitResponse::ABORT; } } return VisitResponse::NEXT; }
VisitResponse visitable<item>::visit_items( const std::function<VisitResponse( item *, item * )> &func ) { auto it = static_cast<item *>( this ); return visit_internal( func, it ); }