item &inventory::add_item(item newit, bool keep_invlet, bool assign_invlet)
{
    binned = false;
    bool reuse_cached_letter = false;

    // Avoid letters that have been manually assigned to other things.
    if( !keep_invlet && g->u.assigned_invlet.count(newit.invlet) ) {
        newit.invlet = '\0';
    }

    // Check how many stacks of this type already are in our inventory.
    if(!keep_invlet && assign_invlet) {
        // Do we have this item in our inventory favourites cache?
        char temp_invlet = find_usable_cached_invlet(newit.typeId());
        if( temp_invlet != 0 ) {
            newit.invlet = temp_invlet;
            reuse_cached_letter = true;
        }

        // If it's not in our cache and not a lowercase letter, try to give it a low letter.
        if(!reuse_cached_letter && (newit.invlet < 'a' || newit.invlet > 'z')) {
            assign_empty_invlet(newit);
        }

        // Make sure the assigned invlet doesn't exist already.
        if(this == &g->u.inv && g->u.invlet_to_position(newit.invlet) != INT_MIN) {
            assign_empty_invlet(newit);
        }
    }


    // See if we can't stack this item.
    for( auto &elem : items ) {
        std::list<item>::iterator it_ref = elem.begin();
        if( it_ref->stacks_with( newit ) ) {
            if( it_ref->merge_charges( newit ) ) {
                return *it_ref;
            }
            newit.invlet = it_ref->invlet;
            elem.push_back( newit );
            return elem.back();
        } else if( keep_invlet && assign_invlet && it_ref->invlet == newit.invlet ) {
            // If keep_invlet is true, we'll be forcing other items out of their current invlet.
            assign_empty_invlet(*it_ref);
        }
    }

    // Couldn't stack the item, proceed.
    if(!reuse_cached_letter) {
        update_cache_with_item(newit);
    }

    std::list<item> newstack;
    newstack.push_back(newit);
    items.push_back(newstack);
    return items.back().back();
}
void inventory::reassign_item( item &it, char invlet, bool remove_old )
{
    if( it.invlet == invlet ) { // no change needed
        return;
    }
    if( remove_old && it.invlet ) {
        invlet_cache.erase( it.invlet );
    }
    it.invlet = invlet;
    update_cache_with_item( it );
}
item &inventory::add_item( item newit, bool keep_invlet, bool assign_invlet, bool should_stack )
{
    binned = false;

    if( should_stack ) {
        // See if we can't stack this item.
        for( auto &elem : items ) {
            std::list<item>::iterator it_ref = elem.begin();
            if( it_ref->stacks_with( newit ) ) {
                if( it_ref->merge_charges( newit ) ) {
                    return *it_ref;
                }
                if( it_ref->invlet == '\0' ) {
                    if( !keep_invlet ) {
                        update_invlet( newit, assign_invlet );
                    }
                    update_cache_with_item( newit );
                    it_ref->invlet = newit.invlet;
                } else {
                    newit.invlet = it_ref->invlet;
                }
                elem.push_back( newit );
                return elem.back();
            } else if( keep_invlet && assign_invlet && it_ref->invlet == newit.invlet ) {
                // If keep_invlet is true, we'll be forcing other items out of their current invlet.
                assign_empty_invlet( *it_ref, g->u );
            }
        }
    }

    // Couldn't stack the item, proceed.
    if( !keep_invlet ) {
        update_invlet( newit, assign_invlet );
    }
    update_cache_with_item( newit );

    std::list<item> newstack;
    newstack.push_back( newit );
    items.push_back( newstack );
    return items.back().back();
}
void inventory::reassign_item( item &it, char invlet, bool remove_old )
{
    if( it.invlet == invlet ) { // no change needed
        return;
    }
    if( remove_old && it.invlet ) {
        auto invlet_list_iter = invlet_cache.find( it.typeId() );
        if( invlet_list_iter != invlet_cache.end() ) {
            auto &invlet_list = invlet_list_iter->second;
            invlet_list.erase( std::remove_if( invlet_list.begin(), invlet_list.end(), [&it]( char cached_invlet ) {
                return cached_invlet == it.invlet;
            } ), invlet_list.end() );
        }
    }
    it.invlet = invlet;
    update_cache_with_item( it );
}
item &inventory::add_item(item newit, bool keep_invlet, bool assign_invlet)
{
    bool reuse_cached_letter = false;

    // Check how many stacks of this type already are in our inventory.
    if(!keep_invlet && assign_invlet) {
        // Do we have this item in our inventory favourites cache?
        char temp_invlet = get_invlet_for_item( newit.typeId() );
        if( temp_invlet != 0 ) {
            newit.invlet = temp_invlet;
            reuse_cached_letter = true;
        }

        // If it's not in our cache and not a lowercase letter, try to give it a low letter.
        if(!reuse_cached_letter && (newit.invlet < 'a' || newit.invlet > 'z')) {
            assign_empty_invlet(newit);
        }

        // Make sure the assigned invlet doesn't exist already.
        if(this == &g->u.inv && g->u.invlet_to_position(newit.invlet) != INT_MIN) {
            assign_empty_invlet(newit);
        }
    }


    // See if we can't stack this item.
    for (invstack::iterator iter = items.begin(); iter != items.end(); ++iter) {
        std::list<item>::iterator it_ref = iter->begin();
        if (it_ref->type->id == newit.type->id) {
            if (newit.charges != -1 && (newit.is_food() || newit.is_ammo())) {
                it_ref->charges += newit.charges;
                return *it_ref;
            } else if (it_ref->stacks_with(newit)) {
                if (it_ref->is_food() && it_ref->has_flag("HOT")) {
                    int tmpcounter = (it_ref->item_counter + newit.item_counter) / 2;
                    it_ref->item_counter = tmpcounter;
                    newit.item_counter = tmpcounter;
                }
                newit.invlet = it_ref->invlet;
                iter->push_back(newit);
                return iter->back();
            } else if (keep_invlet && assign_invlet && it_ref->invlet == newit.invlet) {
                assign_empty_invlet(*it_ref);
            }
        }
        // If keep_invlet is true, we'll be forcing other items out of their current invlet.
        else if (keep_invlet && assign_invlet && it_ref->invlet == newit.invlet) {
            assign_empty_invlet(*it_ref);
        }
    }

    // Couldn't stack the item, proceed.
    if(!reuse_cached_letter) {
        update_cache_with_item(newit);
    }

    std::list<item> newstack;
    newstack.push_back(newit);
    items.push_back(newstack);
    return items.back().back();
}
Exemple #6
0
item& inventory::add_item(item newit, bool keep_invlet)
{
    if (newit.is_style())
    {
        return nullitem; // Styles never belong in our inventory.
    }

    bool reuse_cached_letter = false;

    // Check how many stacks of this type already are in our inventory.

    if(!keep_invlet) {
        // Do we have this item in our inventory favourites cache?
        if(invlet_cache.count(newit.typeId())) {
            std::vector<char>& preferred_invlets = invlet_cache[newit.typeId()];

            // Some of our preferred letters might already be used.
            int first_free_invlet = -1;
            for(int invlets_index = 0; invlets_index < preferred_invlets.size(); invlets_index++) {
                bool invlet_is_used = false; // Check if anything is using this invlet.
                for (invstack::iterator iter = items.begin(); iter != items.end(); ++iter)
                {
                    if(iter->front().invlet == preferred_invlets[invlets_index]) {
                        invlet_is_used = true;
                        break;
                    }
                }

                // If we found one that isn't used, we're done iterating.
                if(!invlet_is_used) {
                    first_free_invlet = invlets_index;
                    break;
                }
            }

            if(first_free_invlet != -1) {
                newit.invlet = preferred_invlets[first_free_invlet];
                reuse_cached_letter = true;
            }
        }

        // If it's not in our cache and not a lowercase letter, try to give it a low letter.
        if(!reuse_cached_letter && (newit.invlet < 'a' || newit.invlet > 'z')) {
            assign_empty_invlet(newit);
        }

        // Make sure the assigned invlet doesn't exist already.
        if(g->u.has_item(newit.invlet)) {
            assign_empty_invlet(newit);
        }
    }


    // See if we can't stack this item.
    for (invstack::iterator iter = items.begin(); iter != items.end(); ++iter)
    {
        std::list<item>::iterator it_ref = iter->begin();
        if (it_ref->type->id == newit.type->id)
        {
            if (newit.charges != -1 && (newit.is_food() || newit.is_ammo()))
            {
                it_ref->charges += newit.charges;
                return *it_ref;
            }
            else if (it_ref->stacks_with(newit))
            {
                if (it_ref->is_food() && it_ref->has_flag("HOT"))
                {
                    int tmpcounter = (it_ref->item_counter + newit.item_counter) / 2;
                    it_ref->item_counter = tmpcounter;
                    newit.item_counter = tmpcounter;
		        }
                newit.invlet = it_ref->invlet;
                iter->push_back(newit);
                return iter->back();
            }
        }
        // If keep_invlet is true, we'll be forcing other items out of their current invlet.
        else if (keep_invlet && it_ref->invlet == newit.invlet)
        {
            assign_empty_invlet(*it_ref);
            update_cache_with_item(newit);
        }
    }

    // Couldn't stack the item, proceed.
    if(!reuse_cached_letter) {
        update_cache_with_item(newit);
    }

    std::list<item> newstack;
    newstack.push_back(newit);
    items.push_back(newstack);
    return items.back().back();
}