int item::volume() { if (typeId() == itm_corpse) { switch (corpse->size) { case MS_TINY: return 2; case MS_SMALL: return 40; case MS_MEDIUM: return 75; case MS_LARGE: return 160; case MS_HUGE: return 600; } } if( is_null() ) return 0; int ret = type->volume; if (count_by_charges()) { ret *= charges; ret /= 100; } if (is_gun()) { for (int i = 0; i < contents.size(); i++) ret += contents[i].volume(); } return ret; }
int print_items( const recipe &r, const catacurses::window &w, int ypos, int xpos, nc_color col, int batch ) { if( !r.has_byproducts() ) { return 0; } const int oldy = ypos; mvwprintz( w, ypos++, xpos, col, _( "Byproducts:" ) ); for( const auto &bp : r.byproducts ) { const auto t = item::find_type( bp.first ); int amount = bp.second * batch; std::string desc; if( t->count_by_charges() ) { amount *= t->charges_default(); desc = string_format( "> %s (%d)", t->nname( 1 ).c_str(), amount ); } else { desc = string_format( "> %d %s", amount, t->nname( static_cast<unsigned int>( amount ) ).c_str() ); } mvwprintz( w, ypos++, xpos, col, desc.c_str() ); } return ypos - oldy; }
bool item::craft_has_charges() { if (count_by_charges()) return true; else if (ammo_type() == AT_NULL) return true; return false; }
int item::weight() { if (typeId() == itm_corpse) { int ret; switch (corpse->size) { case MS_TINY: ret = 5; break; case MS_SMALL: ret = 60; break; case MS_MEDIUM: ret = 520; break; case MS_LARGE: ret = 2000; break; case MS_HUGE: ret = 4000; break; } if (made_of(VEGGY)) ret /= 10; else if (made_of(IRON) || made_of(STEEL) || made_of(STONE)) ret *= 5; return ret; } if( is_null() ) return 0; int ret = type->weight; if (count_by_charges() && !made_of(LIQUID)) { ret *= charges; ret /= 100; } for (int i = 0; i < contents.size(); i++) if (contents[i].made_of(LIQUID)) { if (contents[i].type->is_food()) { it_comest* tmp_comest = dynamic_cast<it_comest*>(contents[i].type); ret += contents[i].weight() * (contents[i].charges / tmp_comest->charges); } else if (contents[i].type->is_ammo()) { it_ammo* tmp_ammo = dynamic_cast<it_ammo*>(contents[i].type); ret += contents[i].weight() * (contents[i].charges / tmp_ammo->count); } else ret += contents[i].weight(); } else ret += contents[i].weight(); return ret; }
static point get_item_pointers_from_activity( std::list<item *> &selected_items, std::list<int> &item_quantities, std::list<item *> &selected_worn_items, std::list<int> &worn_item_quantities ) { // Drop activity has indices of items in inventory and quantities of same. // Indices and quantities alternate on the list. // First iterate over the indices and quantities, retrieving item references. for( size_t index = 0; index < g->u.activity.values.size(); index += 2 ) { const int position = g->u.activity.values[index]; const int quantity = g->u.activity.values[index + 1]; const bool is_worn = position < -1; const bool is_weapon = position == -1; if( is_worn ) { selected_worn_items.push_back( &g->u.worn[player::worn_position_to_index(position)] ); worn_item_quantities.push_back( quantity ); } else if( is_weapon ) { selected_items.push_back( &g->u.weapon ); item_quantities.push_back( quantity ); } else { // We MUST have pointers to these items, and this is the only way I can see to get them. std::list<item> &stack = (std::list<item> &)g->u.inv.const_stack( position ); int items_dropped = 0; for( auto it = stack.begin(); it != stack.end(); ++it ) { selected_items.push_back( &*it ); if( it->count_by_charges() ) { const int qty_to_drop = std::min( quantity - items_dropped, (int)it->charges ); item_quantities.push_back( qty_to_drop ); items_dropped += qty_to_drop; } else { item_quantities.push_back( 1 ); items_dropped++; } if( items_dropped >= quantity ) { break; } } } } point drop_target = g->u.activity.placement; // Now that we have all the data, cancel the activity, // if we don't finish it we'll make a new one with the remaining items. g->u.cancel_activity(); return drop_target; }
std::list<item> profession::items( bool male, const std::vector<trait_id> &traits ) const { std::list<item> result; auto add_legacy_items = [&result]( const itypedecvec & vec ) { for( const itypedec &elem : vec ) { item it( elem.type_id, 0, item::default_charges_tag {} ); if( !elem.snippet_id.empty() ) { it.set_snippet( elem.snippet_id ); } it = it.in_its_container(); result.push_back( it ); } }; add_legacy_items( legacy_starting_items ); add_legacy_items( male ? legacy_starting_items_male : legacy_starting_items_female ); const std::vector<item> group_both = item_group::items_from( _starting_items ); const std::vector<item> group_gender = item_group::items_from( male ? _starting_items_male : _starting_items_female ); result.insert( result.begin(), group_both.begin(), group_both.end() ); result.insert( result.begin(), group_gender.begin(), group_gender.end() ); std::vector<itype_id> bonus = item_substitutions.get_bonus_items( traits ); for( const itype_id &elem : bonus ) { if( elem != no_bonus ) { result.push_back( item( elem, 0, item::default_charges_tag {} ) ); } } for( auto iter = result.begin(); iter != result.end(); ) { const auto sub = item_substitutions.get_substitution( *iter, traits ); if( !sub.empty() ) { result.insert( result.begin(), sub.begin(), sub.end() ); iter = result.erase( iter ); } else { ++iter; } } for( item &it : result ) { if( it.has_flag( "VARSIZE" ) ) { it.item_tags.insert( "FIT" ); } } if( result.empty() ) { // No need to do the below stuff. Plus it would cause said below stuff to crash return result; } // Merge charges for items that stack with each other for( auto outer = result.begin(); outer != result.end(); ++outer ) { if( !outer->count_by_charges() ) { continue; } for( auto inner = std::next( outer ); inner != result.end(); ) { if( outer->stacks_with( *inner ) ) { outer->merge_charges( *inner ); inner = result.erase( inner ); } else { ++inner; } } } result.sort( []( const item & first, const item & second ) { return first.get_layer() < second.get_layer(); } ); return result; }