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" ) ); }
virtual void select(int entnum, uimenu *menu) { const int starty = 3; const int startx = menu->w_width - menu->pad_right; itype *ity = item_controller->find_template(standard_itype_ids[entnum]); std::string padding = std::string(menu->pad_right - 1, ' '); for(int i = 0; i < lastlen + starty + 1; i++ ) { mvwprintw(menu->window, 1 + i, startx, "%s", padding.c_str() ); } if ( ity != NULL ) { tmp.make(item_controller->find_template(standard_itype_ids[entnum])); tmp.bday = g->turn; if (tmp.is_tool()) { tmp.charges = dynamic_cast<it_tool *>(tmp.type)->max_charges; } else if (tmp.is_ammo()) { tmp.charges = 100; } else if (tmp.is_gun()) { tmp.charges = 0; } else if (tmp.is_gunmod() && (tmp.has_flag("MODE_AUX") || tmp.typeId() == "spare_mag")) { tmp.charges = 0; } else { tmp.charges = -1; } if( tmp.is_stationary() ) { tmp.note = SNIPPET.assign( (dynamic_cast<it_stationary *>(tmp.type))->category ); } std::vector<std::string> desc = foldstring(tmp.info(true), menu->pad_right - 1); int dsize = desc.size(); if ( dsize > menu->w_height - 5 ) { dsize = menu->w_height - 5; } lastlen = dsize; std::string header = string_format("#%d: %s%s", entnum, standard_itype_ids[entnum].c_str(), ( incontainer ? " (contained)" : "" ) ); mvwprintz(menu->window, 1, startx + ( menu->pad_right - 1 - header.size() ) / 2, c_cyan, "%s", header.c_str() ); for(int i = 0; i < desc.size(); i++ ) { mvwprintw(menu->window, starty + i, startx, "%s", desc[i].c_str() ); } mvwprintz(menu->window, menu->w_height - 3, startx, c_green, "%s", msg.c_str()); msg = padding; mvwprintw(menu->window, menu->w_height - 2, startx, "[/] find, [f] container, [q]uit"); } }
/*static*/ bool inventory::has_category(const item& it, item_cat cat, const player& u) { switch (cat) { case IC_COMESTIBLE: // food if (it.is_food(&u) || it.is_food_container(&u)) { return true; } break; case IC_AMMO: // ammo if (it.is_ammo() || it.is_ammo_container()) { return true; } break; case IC_ARMOR: // armour if (it.is_armor()) { return true; } break; case IC_BOOK: // books if (it.is_book()) { return true; } break; case IC_TOOL: // tools if (it.is_tool()) { return true; } break; case IC_CONTAINER: // containers for liquid handling if (it.is_tool() || it.is_gun()) { if (it.ammo_type() == "gasoline") { return true; } } else { if (it.is_container()) { return true; } } break; } return false; }
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 ); } ); }
int npc::value(item &it) { int ret = it.price() / 50; skill best = best_skill(); if (best != sk_unarmed) { int weapon_val = it.weapon_value(sklevel) - weapon.weapon_value(sklevel); if (weapon_val > 0) ret += weapon_val; } if (it.is_food()) { it_comest* comest = dynamic_cast<it_comest*>(it.type); if (comest->nutr > 0 || comest->quench > 0) ret++; if (hunger > 40) ret += (comest->nutr + hunger - 40) / 6; if (thirst > 40) ret += (comest->quench + thirst - 40) / 4; } if (it.is_ammo()) { it_ammo* ammo = dynamic_cast<it_ammo*>(it.type); it_gun* gun; if (weapon.is_gun()) { gun = dynamic_cast<it_gun*>(weapon.type); if (ammo->type == gun->ammo) ret += 14; } for (int i = 0; i < inv.size(); i++) { if (inv[i].is_gun()) { gun = dynamic_cast<it_gun*>(inv[i].type); if (ammo->type == gun->ammo) ret += 6; } } } if (it.is_book()) { it_book* book = dynamic_cast<it_book*>(it.type); if (book->intel <= int_cur) { ret += book->fun; if (sklevel[book->type] < book->level && sklevel[book->type] >= book->req) ret += book->level * 3; } } // TODO: Sometimes we want more than one tool? Also we don't want EVERY tool. if (it.is_tool() && !has_amount(itype_id(it.type->id), 1)) { ret += 8; } // TODO: Artifact hunting from relevant factions // ALSO TODO: Bionics hunting from relevant factions if (fac_has_job(FACJOB_DRUGS) && it.is_food() && (dynamic_cast<it_comest*>(it.type))->addict >= 5) ret += 10; if (fac_has_job(FACJOB_DOCTORS) && it.type->id >= itm_bandages && it.type->id <= itm_prozac) ret += 10; if (fac_has_value(FACVAL_BOOKS) && it.is_book()) ret += 14; if (fac_has_job(FACJOB_SCAVENGE)) { // Computed last for _reasons_. ret += 6; ret *= 1.3; } return ret; }
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 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 ) { int moves_taken = 100; bool picked_up = false; item leftovers = newit; if( newit.invlet != '\0' && g->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 (!g->u.can_pickWeight(newit.weight(), false)) { add_msg(m_info, _("The %s is too heavy!"), newit.display_name().c_str()); } else if( newit.is_ammo() && (newit.ammo_type() == "arrow" || newit.ammo_type() == "bolt")) { //add ammo to quiver int quivered = handle_quiver_insertion( newit, moves_taken, picked_up); if( newit.charges > 0) { if(!g->u.can_pickVolume( newit.volume())) { if(quivered > 0) { //update the charges for the item that gets re-added to the game map quantity = quivered; leftovers.charges = newit.charges; } 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 item &it = g->u.i_add(newit); picked_up = true; //display output message PickupMap map_pickup; int charges = (newit.count_by_charges()) ? newit.charges : 1; map_pickup.insert(std::pair<std::string, ItemCount>(newit.tname(), ItemCount(it, charges))); show_pickup_message(map_pickup); } } } else if (!g->u.can_pickVolume(newit.volume())) { if( !autopickup ) { // Armor can be instantly worn if (newit.is_armor() && query_yn(_("Put on the %s?"), newit.display_name().c_str())) { if (g->u.wear_item(newit)) { picked_up = true; } } else if (g->u.is_armed()) { if (!g->u.weapon.has_flag("NO_UNWIELD")) { if( !offered_swap ) { offered_swap = true; if ( g->u.weapon.type->id != newit.type->id && query_yn(_("No space for %1$s; wield instead? (drops %2$s)"), newit.display_name().c_str(), g->u.weapon.display_name().c_str()) ) { picked_up = true; g->m.add_item_or_charges( pickup_target, g->u.remove_weapon(), 1 ); g->u.inv.assign_empty_invlet( newit, true ); // force getting an invlet. g->u.wield( &( g->u.i_add(newit) ) ); if (newit.invlet) { add_msg(m_info, _("Wielding %c - %s"), newit.invlet, newit.display_name().c_str()); } else { add_msg(m_info, _("Wielding - %s"), newit.display_name().c_str()); } } } } else { add_msg(m_info, _("There's no room in your inventory for the %s " "and you can't unwield your %s."), newit.display_name().c_str(), g->u.weapon.display_name().c_str()); } } else if( !g->u.is_armed() ) { if (g->u.keep_hands_free) { add_msg(m_info, _("There's no room in your inventory for the %s " "and you have decided to keep your hands free."), newit.display_name().c_str()); } else { g->u.inv.assign_empty_invlet(newit, true); // force getting an invlet. g->u.wield(&(g->u.i_add(newit))); picked_up = true; if (newit.invlet) { add_msg(m_info, _("Wielding %c - %s"), newit.invlet, newit.display_name().c_str()); } else { add_msg(m_info, _("Wielding - %s"), newit.display_name().c_str()); } } } // end of if unarmed } // end of if !autopickup } else { auto &entry = mapPickup[newit.tname()]; entry.second += newit.count_by_charges() ? newit.charges : 1; entry.first = g->u.i_add(newit); picked_up = true; } 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 ); } } }
// Returns false if pickup caused a prompt and the player selected to cancel pickup bool 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; const auto wield_check = u.can_wield( 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; } bool did_prompt = false; newit.charges = u.i_add_to_container( newit, false ); if( newit.is_ammo() && newit.charges == 0 ) { picked_up = true; option = NUM_ANSWERS; //Skip the options part } else if( newit.made_of( LIQUID ) ) { got_water = true; } else if( !u.can_pickWeight( newit, false ) ) { if( !autopickup ) { const std::string &explain = string_format( _( "The %s is too heavy!" ), newit.display_name().c_str() ); option = handle_problematic_pickup( newit, offered_swap, explain ); did_prompt = true; } else { option = CANCEL; } } 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 ); did_prompt = true; } 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 ); did_prompt = true; } 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: if( wield_check.success() ) { picked_up = u.wield( newit ); 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() ); } } else { add_msg( wield_check.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 ) { 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 ); } } return picked_up || !did_prompt; }