Esempio n. 1
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" ) );
}
Esempio n. 2
0
        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");
            }
        }
Esempio n. 3
0
/*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;
}
Esempio n. 4
0
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 );
    } );
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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 );
        }
    }
}
Esempio n. 7
0
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 );
        }
    }
}
Esempio n. 8
0
// 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;
}