Beispiel #1
0
    int obtain( Character& ch ) override {
        if( !what ) {
            return INT_MIN;
        }

        // invalidate this item_location
        auto it = get_item();
        what = nullptr;

        int mv = 0;
        bool was_worn = false;

        item *holster = who->find_parent( *it );
        if( holster && who->is_worn( *holster ) && holster->can_holster( *it, true ) ) {
            // Immediate parent is a worn holster capable of holding this item
            auto ptr = dynamic_cast<const holster_actor *>( holster->type->get_use( "holster" )->get_actor_ptr() );
            mv += dynamic_cast<player *>( who )->item_handling_cost( *it, false, ptr->draw_cost );
            was_worn = true;
        } else {
            // Unpack the object followed by any nested containers starting with the innermost
            mv += dynamic_cast<player *>( who )->item_handling_cost( *it );
            for( auto obj = who->find_parent( *it ); obj && who->find_parent( *obj ); obj = who->find_parent( *obj ) ) {
                mv += dynamic_cast<player *>( who )->item_handling_cost( *obj );
            }
        }

        if( who->is_worn( *it ) ) {
            it->on_takeoff( *( dynamic_cast<player *>( who ) ) );
        } else if( !was_worn ) {
            mv *= INVENTORY_HANDLING_FACTOR;
        }

        if( &ch != who ) {
            // @todo implement movement cost for transfering item between characters
        }

        who->moves -= mv;

        if( &ch.i_at( ch.get_item_position( it ) ) == it ) {
            // item already in target characters inventory at base of stack
            return ch.get_item_position( it );
        } else {
            return ch.get_item_position( &ch.i_add( who->i_rem( it ) ) );
        }
    }
Beispiel #2
0
std::list<item> visitable<Character>::remove_items_with( const
        std::function<bool( const item &e )> &filter, int count )
{
    auto ch = static_cast<Character *>( this );
    std::list<item> res;

    if( count <= 0 ) {
        return res; // nothing to do
    }

    // first try and remove items from the inventory
    res = ch->inv.remove_items_with( filter, count );
    count -= res.size();
    if( count == 0 ) {
        return res;
    }

    // then try any worn items
    for( auto iter = ch->worn.begin(); iter != ch->worn.end(); ) {
        if( filter( *iter ) ) {
            iter->on_takeoff( *ch );
            res.splice( res.end(), ch->worn, iter++ );
            if( --count == 0 ) {
                return res;
            }
        } else {
            remove_internal( filter, *iter, count, res );
            if( count == 0 ) {
                return res;
            }
            ++iter;
        }
    }

    // finally try the currently wielded item (if any)
    if( filter( ch->weapon ) ) {
        res.push_back( ch->remove_weapon() );
        count--;
    } else {
        remove_internal( filter, ch->weapon, count, res );
    }

    return res;
}