Пример #1
0
resistances::resistances( const item &armor, bool to_self )
{
    // Armors protect, but all items can resist
    if( to_self || armor.is_armor() ) {
        for( int i = 0; i < NUM_DT; i++ ) {
            damage_type dt = static_cast<damage_type>( i );
            set_resist( dt, armor.damage_resist( dt, to_self ) );
        }
    }
}
Пример #2
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;
}
Пример #3
0
pickup_answer handle_problematic_pickup( const item &it, bool &offered_swap,
        const std::string &explain )
{
    if( offered_swap ) {
        return CANCEL;
    }

    player &u = g->u;

    uimenu amenu;
    amenu.return_invalid = true;

    amenu.selected = 0;
    amenu.text = explain;

    offered_swap = true;
    // @todo Gray out if not enough hands
    if( u.is_armed() ) {
        amenu.addentry( WIELD, !u.weapon.has_flag( "NO_UNWIELD" ), 'w',
                        _( "Dispose of %s and wield %s" ), u.weapon.display_name().c_str(),
                        it.display_name().c_str() );
    } else {
        amenu.addentry( WIELD, true, 'w', _( "Wield %s" ), it.display_name().c_str() );
    }
    if( it.is_armor() ) {
        amenu.addentry( WEAR, u.can_wear( it ), 'W', _( "Wear %s" ), it.display_name().c_str() );
    }
    if( it.is_bucket_nonempty() ) {
        amenu.addentry( SPILL, u.can_pickVolume( it ), 's', _( "Spill %s, then pick up %s" ),
                        it.contents.front().tname().c_str(), it.display_name().c_str() );
    }

    amenu.query();
    int choice = amenu.ret;

    if( choice <= CANCEL || choice >= NUM_ANSWERS ) {
        return CANCEL;
    }

    return static_cast<pickup_answer>( choice );
}
Пример #4
0
bool npc::wear_if_wanted(item it)
{
 if (!it.is_armor())
  return false;

 it_armor* armor = dynamic_cast<it_armor*>(it.type);
 int max_encumb[num_bp] = {2, 3, 3, 4, 3, 3, 3, 2};
 bool encumb_ok = true;
 for (int i = 0; i < num_bp && encumb_ok; i++) {
  if (armor->covers & mfb(i) && encumb(body_part(i)) + armor->encumber >
       max_encumb[i])
   encumb_ok = false;
 }
 if (encumb_ok) {
  worn.push_back(it);
  return true;
 }
// Otherwise, maybe we should take off one or more items and replace them
 std::vector<int> removal;
 for (int i = 0; i < worn.size(); i++) {
  for (int j = 0; j < num_bp; j++) {
   if (armor->covers & mfb(j) &&
       dynamic_cast<it_armor*>(worn[i].type)->covers & mfb(j)) {
    removal.push_back(i);
    j = num_bp;
   }
  }
 }
 for (int i = 0; i < removal.size(); i++) {
  if (true) {
//  if (worn[removal[i]].value_to(this) < it.value_to(this)) {
   inv.push_back(worn[removal[i]]);
   worn.push_back(it);
   return true;
  }
 }
 return false;
} 
Пример #5
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 );
        }
    }
}