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(); }
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(); }