void remove_ammo( item *dis_item, player &p ) { for( auto iter = dis_item->contents.begin(); iter != dis_item->contents.end(); ) { if( iter->has_flag( "IRREMOVABLE" ) ) { iter++; continue; } drop_or_handle( *iter, p ); iter = dis_item->contents.erase( iter ); } if( dis_item->has_flag( "NO_UNLOAD" ) ) { return; } if( dis_item->is_gun() && dis_item->ammo_current() != "null" ) { item ammodrop( dis_item->ammo_current(), calendar::turn ); ammodrop.charges = dis_item->charges; drop_or_handle( ammodrop, p ); dis_item->charges = 0; } if( dis_item->is_tool() && dis_item->charges > 0 && dis_item->ammo_type() ) { item ammodrop( default_ammo( dis_item->ammo_type() ), calendar::turn ); ammodrop.charges = dis_item->charges; if( dis_item->ammo_type() == ammotype( "plutonium" ) ) { ammodrop.charges /= PLUTONIUM_CHARGES; } drop_or_handle( ammodrop, p ); dis_item->charges = 0; } }
bool player::can_feed_battery_with( const item &it ) const { if( !it.is_ammo() || can_eat( it ).success() || !has_active_bionic( bio_batteries ) ) { return false; } return it.type->ammo->type.count( ammotype( "battery" ) ); }
bool player::can_feed_reactor_with( const item &it ) const { static const std::set<ammotype> acceptable = {{ ammotype( "reactor_slurry" ), ammotype( "plutonium" ) } }; if( !it.is_ammo() || can_eat( it ).success() ) { return false; } if( !has_active_bionic( bio_reactor ) && !has_active_bionic( bio_advreactor ) ) { return false; } return std::any_of( acceptable.begin(), acceptable.end(), [ &it ]( const ammotype & elem ) { return it.type->ammo->type.count( elem ); } ); }
void Pickup::pick_one_up( const tripoint &pickup_target, item &newit, vehicle *veh, int cargo_part, int index, int quantity, bool &got_water, bool &offered_swap, PickupMap &mapPickup, bool autopickup ) { player &u = g->u; int moves_taken = 100; bool picked_up = false; pickup_answer option = CANCEL; item leftovers = newit; if( newit.invlet != '\0' && u.invlet_to_position( newit.invlet ) != INT_MIN ) { // Existing invlet is not re-usable, remove it and let the code in player.cpp/inventory.cpp // add a new invlet, otherwise keep the (usable) invlet. newit.invlet = '\0'; } if( quantity != 0 && newit.count_by_charges() ) { // Reinserting leftovers happens after item removal to avoid stacking issues. leftovers.charges = newit.charges - quantity; if( leftovers.charges > 0 ) { newit.charges = quantity; } } else { leftovers.charges = 0; } if( newit.made_of( LIQUID ) ) { got_water = true; } else if( !u.can_pickWeight( newit, false ) ) { add_msg( m_info, _( "The %s is too heavy!" ), newit.display_name().c_str() ); } else if( newit.is_ammo() && ( newit.ammo_type() == ammotype( "arrow" ) || newit.ammo_type() == ammotype( "bolt" ) ) ) { // @todo Make quiver code generic so that ammo pouches can use it too //add ammo to quiver int quivered = handle_quiver_insertion( newit, moves_taken, picked_up ); if( quivered > 0 ) { quantity = quivered; //already picked up some for quiver so use special case handling picked_up = true; option = NUM_ANSWERS; } if( newit.charges > 0 ) { if( !u.can_pickVolume( newit ) ) { if( !autopickup ) { // Silence some messaging if we're doing autopickup. add_msg( m_info, ngettext( "There's no room in your inventory for the %s.", "There's no room in your inventory for the %s.", newit.charges ), newit.tname( newit.charges ).c_str() ); } } else { // Add to inventory instead option = STASH; } } if( option == NUM_ANSWERS ) { //not picking up the rest so //update the charges for the item that gets re-added to the game map leftovers.charges = newit.charges; } } else if( newit.is_bucket() && !newit.is_container_empty() ) { if( !autopickup ) { const std::string &explain = string_format( _( "Can't stash %s while it's not empty" ), newit.display_name().c_str() ); option = handle_problematic_pickup( newit, offered_swap, explain ); } else { option = CANCEL; } } else if( !u.can_pickVolume( newit ) ) { if( !autopickup ) { const std::string &explain = string_format( _( "Not enough capacity to stash %s" ), newit.display_name().c_str() ); option = handle_problematic_pickup( newit, offered_swap, explain ); } else { option = CANCEL; } } else { option = STASH; } switch( option ) { case NUM_ANSWERS: // Some other option break; case CANCEL: picked_up = false; break; case WEAR: picked_up = u.wear_item( newit ); break; case WIELD: picked_up = u.wield( newit ); if( !picked_up ) { break; } if( u.weapon.invlet ) { add_msg( m_info, _( "Wielding %c - %s" ), u.weapon.invlet, u.weapon.display_name().c_str() ); } else { add_msg( m_info, _( "Wielding - %s" ), u.weapon.display_name().c_str() ); } break; case SPILL: if( newit.is_container_empty() ) { debugmsg( "Tried to spill contents from an empty container" ); break; } picked_up = newit.spill_contents( u ); if( !picked_up ) { break; } // Intentional fallthrough case STASH: auto &entry = mapPickup[newit.tname()]; entry.second += newit.count_by_charges() ? newit.charges : 1; entry.first = u.i_add( newit ); picked_up = true; break; } if( picked_up ) { Pickup::remove_from_map_or_vehicle( pickup_target, veh, cargo_part, moves_taken, index ); } if( leftovers.charges > 0 ) { bool to_map = veh == nullptr; if( !to_map ) { to_map = !veh->add_item( cargo_part, leftovers ); } if( to_map ) { g->m.add_item_or_charges( pickup_target, leftovers ); } } }
void ammunition_type::load_ammunition_type( JsonObject &jsobj ) { ammunition_type &res = all_ammunition_types()[ ammotype( jsobj.get_string( "id" ) ) ]; res.name_ = jsobj.get_string( "name" ); res.default_ammotype_ = jsobj.get_string( "default" ); }