Ejemplo n.º 1
0
void inventory::update_invlet( item &newit, bool assign_invlet ) {
    // Avoid letters that have been manually assigned to other things.
    if( newit.invlet && assigned_invlet.find( newit.invlet ) != assigned_invlet.end() &&
            assigned_invlet[newit.invlet] != newit.typeId() ) {
        newit.invlet = '\0';
    }

    // Remove letters that are not in the favorites cache
    if( newit.invlet ) {
        auto invlet_list_iter = invlet_cache.find( newit.typeId() );
        bool found = false;
        if( invlet_list_iter != invlet_cache.end() ) {
            auto &invlet_list = invlet_list_iter->second;
            found = std::find( invlet_list.begin(), invlet_list.end(), newit.invlet ) != invlet_list.end();
        }
        if( !found ) {
            newit.invlet = '\0';
        }
    }

    // Remove letters that have been assigned to other items in the inventory
    if( newit.invlet ) {
        char tmp_invlet = newit.invlet;
        newit.invlet = '\0';
        if( g->u.invlet_to_position( tmp_invlet ) == INT_MIN ) {
            newit.invlet = tmp_invlet;
        }
    }

    if( assign_invlet ) {
        // Assign a cached letter to the item
        if( !newit.invlet ) {
            newit.invlet = find_usable_cached_invlet( newit.typeId() );
        }

        // Give the item an invlet if it has none
        if( !newit.invlet ) {
            assign_empty_invlet( newit, g->u );
        }
    }
}
Ejemplo n.º 2
0
std::vector<item> json_item_substitution::get_substitution( const item &it,
        const std::vector<trait_id> &traits ) const
{
    auto iter = substitutions.find( it.typeId() );
    std::vector<item> ret;
    if( iter == substitutions.end() ) {
        for( const item &con : it.contents ) {
            const auto sub = get_substitution( con, traits );
            ret.insert( ret.end(), sub.begin(), sub.end() );
        }
        return ret;
    }

    const auto sub = std::find_if( iter->second.begin(),
    iter->second.end(), [&traits]( const substitution & s ) {
        return s.trait_reqs.meets_condition( traits );
    } );
    if( sub == iter->second.end() ) {
        return ret;
    }

    const long old_amt = it.count();
    for( const substitution::info &inf : sub->infos ) {
        item result( inf.new_item );
        const long new_amt = std::max( 1l, static_cast<long>( std::round( inf.ratio * old_amt ) ) );

        if( !result.count_by_charges() ) {
            for( long i = 0; i < new_amt; i++ ) {
                ret.push_back( result.in_its_container() );
            }
        } else {
            result.mod_charges( -result.charges + new_amt );
            while( result.charges > 0 ) {
                const item pushed = result.in_its_container();
                ret.push_back( pushed );
                result.mod_charges( pushed.contents.empty() ? -pushed.charges : -pushed.contents.back().charges );
            }
        }
    }
    return ret;
}
Ejemplo n.º 3
0
void inventory::assign_empty_invlet( item &it, const Character &p, const bool force )
{
    if( !get_option<bool>( "AUTO_INV_ASSIGN" ) ) {
        return;
    }

    invlets_bitset cur_inv = p.allocated_invlets();
    itype_id target_type = it.typeId();
    for( auto iter : assigned_invlet ) {
        if( iter.second == target_type && !cur_inv[iter.first] ) {
            it.invlet = iter.first;
            return;
        }
    }
    if( cur_inv.count() < inv_chars.size() ) {
        for( const auto &inv_char : inv_chars ) {
            if( assigned_invlet.count( inv_char ) ) {
                // don't overwrite assigned keys
                continue;
            }
            if( !cur_inv[inv_char] ) {
                it.invlet = inv_char;
                return;
            }
        }
    }
    if( !force ) {
        it.invlet = 0;
        return;
    }
    // No free hotkey exist, re-use some of the existing ones
    for( auto &elem : items ) {
        item &o = elem.front();
        if( o.invlet != 0 ) {
            it.invlet = o.invlet;
            o.invlet = 0;
            return;
        }
    }
    debugmsg( "could not find a hotkey for %s", it.tname() );
}
Ejemplo n.º 4
0
// firing is the item that is fired. It may be the wielded gun, but it can also be an attached
// gunmod. p is the character that is firing, this may be a pseudo-character (used by monattack/
// vehicle turrets) or a NPC.
void sfx::generate_gun_sound( const player &p, const item &firing )
{
    end_sfx_timestamp = std::chrono::high_resolution_clock::now();
    sfx_time = end_sfx_timestamp - start_sfx_timestamp;
    if( std::chrono::duration_cast<std::chrono::milliseconds> ( sfx_time ).count() < 80 ) {
        return;
    }
    const tripoint source = p.pos();
    int heard_volume = get_heard_volume( source );
    if( heard_volume <= 30 ) {
        heard_volume = 30;
    }

    itype_id weapon_id = firing.typeId();
    int angle;
    int distance;
    std::string selected_sound;
    // this does not mean p == g->u (it could be a vehicle turret)
    if( g->u.pos() == source ) {
        angle = 0;
        distance = 0;
        selected_sound = "fire_gun";

        const auto mods = firing.gunmods();
        if( std::any_of( mods.begin(), mods.end(), []( const item *e ) { return e->type->gunmod->loudness < 0; } ) ) {
            weapon_id = "weapon_fire_suppressed";
        }

    } else {
        angle = get_heard_angle( source );
        distance = rl_dist( g->u.pos(), source );
        if( distance <= 17 ) {
            selected_sound = "fire_gun";
        } else {
            selected_sound = "fire_gun_distant";
        }
    }

    play_variant_sound( selected_sound, weapon_id, heard_volume, angle, 0.8, 1.2 );
    start_sfx_timestamp = std::chrono::high_resolution_clock::now();
}
Ejemplo n.º 5
0
item_location game_menus::inv::container_for( player &p, const item &liquid, int radius )
{
    const auto filter = [ &liquid ]( const item_location & location ) {
        if( location.where() == item_location::type::character ) {
            Character *character = dynamic_cast<Character *>( g->critter_at( location.position() ) );
            if( character == nullptr ) {
                debugmsg( "Invalid location supplied to the liquid filter: no character found." );
                return false;
            }
            return location->get_remaining_capacity_for_liquid( liquid, *character ) > 0;
        }

        const bool allow_buckets = location.where() == item_location::type::map;
        return location->get_remaining_capacity_for_liquid( liquid, allow_buckets ) > 0;
    };

    return inv_internal( p, inventory_filter_preset( filter ),
                         string_format( _( "Container for %s" ), liquid.display_name( liquid.charges ).c_str() ), radius,
                         string_format( _( "You don't have a suitable container for carrying %s." ),
                                        liquid.tname().c_str() ) );
}
Ejemplo n.º 6
0
void set_item_inventory( item &newit )
{
    if( newit.made_of( LIQUID ) ) {
        g->handle_all_liquid( newit, PICKUP_RANGE );
    } else {
        g->u.inv.assign_empty_invlet( newit );
        // We might not have space for the item
        if( !g->u.can_pickVolume( newit ) ) { //Accounts for result_mult
            add_msg( _( "There's no room in your inventory for the %s, so you drop it." ),
                     newit.tname().c_str() );
            g->m.add_item_or_charges( g->u.pos(), newit );
        } else if( !g->u.can_pickWeight( newit, !get_option<bool>( "DANGEROUS_PICKUPS" ) ) ) {
            add_msg( _( "The %s is too heavy to carry, so you drop it." ),
                     newit.tname().c_str() );
            g->m.add_item_or_charges( g->u.pos(), newit );
        } else {
            newit = g->u.i_add( newit );
            add_msg( m_info, "%c - %s", newit.invlet == 0 ? ' ' : newit.invlet, newit.tname().c_str() );
        }
    }
}
Ejemplo n.º 7
0
int Character::aim_per_time( const item& gun, int recoil ) const
{
    int penalty = 0;

    // Range [0 - 10] after adjustment
    penalty += skill_dispersion( gun, false ) / 60;

    // Ranges [0 - 12] after adjustment
    penalty += ranged_dex_mod() / 15;

    // Range [0 - 10]
    penalty += gun.aim_speed( recoil );

    // @todo consider character status effects

    // always improve by at least 1MOC
    penalty = std::max( 1, 32 - penalty );

    // improvement capped by max aim level of the gun sight being used.
    return std::min( penalty, recoil - gun.sight_dispersion( recoil ) );
}
Ejemplo n.º 8
0
// technique
std::vector<matec_id> player::get_all_techniques( const item &weap ) const
{
    std::vector<matec_id> tecs;
    // Grab individual item techniques
    const auto &weapon_techs = weap.get_techniques();
    tecs.insert( tecs.end(), weapon_techs.begin(), weapon_techs.end() );
    // and martial art techniques
    const auto &style = style_selected.obj();
    tecs.insert( tecs.end(), style.techniques.begin(), style.techniques.end() );

    return tecs;
}
Ejemplo n.º 9
0
pickup_answer handle_problematic_pickup( const item &it, bool &offered_swap, const std::string &explain )
{
    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
    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() );
    if( it.is_armor() ) {
        amenu.addentry( WEAR, u.can_wear( it ), 'W', _("Wear %s"), it.display_name().c_str() );
    }
    if( !it.is_container_empty() && u.can_pickVolume( it.volume() ) ) {
        amenu.addentry( SPILL, true, '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 );
}
Ejemplo n.º 10
0
// TODO: Move pizza scraping here.
// Same for other kinds of nutrition alterations
// This is used by item display, making actual nutrition available to player.
int player::nutrition_for( const item &comest ) const
{
    static const trait_id trait_CARNIVORE( "CARNIVORE" );
    static const trait_id trait_GIZZARD( "GIZZARD" );
    static const trait_id trait_SAPROPHAGE( "SAPROPHAGE" );
    static const std::string flag_CARNIVORE_OK( "CARNIVORE_OK" );
    if( !comest.is_comestible() ) {
        return 0;
    }

    // As float to avoid rounding too many times
    float nutr = comest.type->comestible->nutr;

    if( has_trait( trait_GIZZARD ) ) {
        nutr *= 0.6f;
    }


    if( has_trait( trait_CARNIVORE ) && comest.has_flag( flag_CARNIVORE_OK ) &&
        comest.has_any_flag( carnivore_blacklist ) ) {
        // TODO: Comment pizza scrapping
        nutr *= 0.5f;
    }

    const float relative_rot = comest.get_relative_rot();
    // Saprophages get full nutrition from rotting food
    if( relative_rot > 1.0f && !has_trait( trait_SAPROPHAGE ) ) {
        // everyone else only gets a portion of the nutrition
        // Scaling linearly from 100% at just-rotten to 0 at halfway-rotten-away
        const float rottedness = clamp( 2 * relative_rot - 2.0f, 0.1f, 1.0f );
        nutr *= ( 1.0f - rottedness );
    }

    // Bio-digestion gives extra nutrition
    if( has_bionic( bio_digestion ) ) {
        nutr *= 1.5f;
    }

    return ( int )nutr;
}
Ejemplo n.º 11
0
invlet_state check_invlet( player &p, item &it, char invlet ) {
    if( it.invlet == '\0' ) {
        return NONE;
    } else if( it.invlet == invlet ) {
        if( p.inv.assigned_invlet.find( invlet ) != p.inv.assigned_invlet.end() &&
            p.inv.assigned_invlet[invlet] == it.typeId() ) {
            return ASSIGNED;
        } else {
            return CACHED;
        }
    }
    return UNEXPECTED;
}
Ejemplo n.º 12
0
void player_morale::set_worn( const item &it, bool worn )
{
    const bool just_fancy = it.has_flag( "FANCY" );
    const bool super_fancy = it.has_flag( "SUPER_FANCY" );

    if( just_fancy || super_fancy ) {
        const int sign = ( worn ) ? 1 : -1;

        for( int i = 0; i < num_bp; i++ ) {
            const auto bp = static_cast<body_part>( i );
            if( it.covers( bp ) ) {
                covered[i] = std::max( covered[i] + sign, 0 );
            }
        }

        if( super_fancy ) {
            super_fancy_bonus += 2 * sign;
        }

        update_stylish_bonus();
    }
}
Ejemplo n.º 13
0
/**
 * Determine what a funnel has filled out of game, using funnelcontainer.bday as a starting point.
 */
void retroactively_fill_from_funnel( item &it, const trap &tr, int startturn, int endturn,
                                     const tripoint &location )
{
    if( startturn > endturn || !tr.is_funnel() ) {
        return;
    }

    it.bday = endturn; // bday == last fill check
    auto data = sum_conditions( startturn, endturn, location );

    // Technically 0.0 division is OK, but it will be cleaner without it
    if( data.rain_amount > 0 ) {
        const int rain = divide_roll_remainder( 1.0 / tr.funnel_turns_per_charge( data.rain_amount ), 1.0f );
        it.add_rain_to_container( false, rain );
        // add_msg(m_debug, "Retroactively adding %d water from turn %d to %d", rain, startturn, endturn);
    }

    if( data.acid_amount > 0 ) {
        const int acid = divide_roll_remainder( 1.0 / tr.funnel_turns_per_charge( data.acid_amount ), 1.0f );
        it.add_rain_to_container( true, acid );
    }
}
Ejemplo n.º 14
0
void inventory::add_item(item newit, bool keep_invlet)
{
 if (keep_invlet && !newit.invlet_is_okay())
  assign_empty_invlet(newit); // Keep invlet is true, but invlet is invalid!

 if (newit.is_style())
  return; // Styles never belong in our inventory.
 for (unsigned int i = 0; i < items.size(); i++) {
  if (items[i][0].stacks_with(newit)) {
    newit.invlet = items[i][0].invlet;
   items[i].push_back(newit);
   return;
  } else if (keep_invlet && items[i][0].invlet == newit.invlet)
   assign_empty_invlet(items[i][0]);
 }
 if (!newit.invlet_is_okay() || index_by_letter(newit.invlet) != -1)
  assign_empty_invlet(newit);

 std::vector<item> newstack;
 newstack.push_back(newit);
 items.push_back(newstack);
}
Ejemplo n.º 15
0
//helper function for Pickup::pick_up
//return value is amount of ammo added to quiver
int Pickup::handle_quiver_insertion(item &here, bool inv_on_fail, int &moves_to_decrement,
                                    bool &picked_up)
{
    //add ammo to quiver
    int quivered = here.add_ammo_to_quiver(&g->u, true);
    if(quivered > 0) {
        moves_to_decrement = 0; //moves already decremented in item::add_ammo_to_quiver()
        picked_up = true;
        return quivered;
    } else if (inv_on_fail) {
        //add to inventory instead
        g->u.i_add(here);
        picked_up = true;

        //display output message
        std::map<std::string, int> map_pickup;
        int charges = (here.count_by_charges()) ? here.charges : 1;
        map_pickup.insert(std::pair<std::string, int>(here.tname(), charges));
        show_pickup_message(map_pickup);
    }
    return 0;
}
Ejemplo n.º 16
0
bool player::feed_furnace_with( item &it )
{
    if( !can_feed_furnace_with( it ) ) {
        return false;
    }

    const int energy = get_acquirable_energy( it, rechargeable_cbm::furnace );

    if( energy == 0 ) {
        add_msg_player_or_npc( m_info,
                               _( "You digest your %s, but fail to acquire energy from it." ),
                               _( "<npcname> digests their %s for energy, but fails to acquire energy from it." ),
                               it.tname().c_str() );
    } else if( power_level >= max_power_level ) {
        add_msg_player_or_npc(
            _( "You digest your %s, but you're fully powered already, so the energy is wasted." ),
            _( "<npcname> digests a %s for energy, they're fully powered already, so the energy is wasted." ),
            it.tname().c_str() );
    } else {
        const int profitable_energy = std::min( energy, max_power_level - power_level );
        add_msg_player_or_npc( m_info,
                               ngettext( "You digest your %s and recharge %d point of energy.",
                                         "You digest your %s and recharge %d points of energy.",
                                         profitable_energy
                                       ),
                               ngettext( "<npcname> digests a %s and recharges %d point of energy.",
                                         "<npcname> digests a %s and recharges %d points of energy.",
                                         profitable_energy
                                       ), it.tname().c_str(), profitable_energy
                             );
        charge_power( profitable_energy );
    }

    it.charges = 0;
    mod_moves( -250 );

    return true;
}
static void move_item( player &p, item &it, int quantity, const tripoint &src,
                       const tripoint &dest, vehicle *src_veh, int src_part )
{
    item leftovers = it;

    if( quantity != 0 && it.count_by_charges() ) {
        // Reinserting leftovers happens after item removal to avoid stacking issues.
        leftovers.charges = it.charges - quantity;
        if( leftovers.charges > 0 ) {
            it.charges = quantity;
        }
    } else {
        leftovers.charges = 0;
    }

    // Check that we can pick it up.
    if( !it.made_of_from_type( LIQUID ) ) {
        p.mod_moves( -move_cost( it, src, dest ) );
        put_into_vehicle_or_drop( p, item_drop_reason::deliberate, { it }, dest );
        // Remove from map or vehicle.
        if( src_veh ) {
            src_veh->remove_item( src_part, &it );
        } else {
            g->m.i_rem( src, &it );
        }
    }

    // If we didn't pick up a whole stack, put the remainder back where it came from.
    if( leftovers.charges > 0 ) {
        if( src_veh ) {
            if( !src_veh->add_item( src_part, leftovers ) ) {
                debugmsg( "SortLoot: Source vehicle failed to receive leftover charges." );
            }
        } else {
            g->m.add_item_or_charges( src, leftovers );
        }
    }
}
Ejemplo n.º 18
0
double trap::funnel_turns_per_charge( double rain_depth_mm_per_hour ) const {
    // 1mm rain on 1m^2 == 1 liter water == 1000ml
    // 1 liter == 4 volume
    // 1 volume == 250ml: containers
    // 1 volume == 200ml: water
    // How many turns should it take for us to collect 1 charge of rainwater?
    // "..."
    if ( rain_depth_mm_per_hour == 0 ) {
        return 0;
    }
    const item water(item_controller->find_template("water"), 0);
    const double charge_ml = (double) (water.weight()) / water.charges; // 250ml
    const double PI = 3.14159265358979f;
   
    const double surface_area_mm2 = PI * (funnel_radius_mm * funnel_radius_mm);

    const double vol_mm3_per_hour = surface_area_mm2 * rain_depth_mm_per_hour;
    const double vol_mm3_per_turn = vol_mm3_per_hour / 600;

    const double ml_to_mm3 = 1000;
    const double turns_per_charge = (charge_ml * ml_to_mm3) / vol_mm3_per_turn;
    return turns_per_charge;// / rain_depth_mm_per_hour;
}
Ejemplo n.º 19
0
double funnel_charges_per_turn( const double surface_area_mm2, const double rain_depth_mm_per_hour )
{
    // 1mm rain on 1m^2 == 1 liter water == 1000ml
    // 1 liter == 4 volume
    // 1 volume == 250ml: containers
    // 1 volume == 200ml: water
    // How many charges of water can we collect in a turn (usually <1.0)?
    if( rain_depth_mm_per_hour == 0.0 ) {
        return 0.0;
    }

    // Calculate once, because that part is expensive
    static const item water("water", 0);
    static const double charge_ml = (double) (water.weight()) / water.charges; // 250ml

    const double vol_mm3_per_hour = surface_area_mm2 * rain_depth_mm_per_hour;
    const double vol_mm3_per_turn = vol_mm3_per_hour / 600;

    const double ml_to_mm3 = 1000;
    const double charges_per_turn = vol_mm3_per_turn / (charge_ml * ml_to_mm3);

    return charges_per_turn;
}
Ejemplo n.º 20
0
/**
 * Determine what a funnel has filled out of game, using funnelcontainer.bday as a starting point.
 */
void retroactively_fill_from_funnel( item &it, const trap &tr, const calendar &endturn,
                                     const tripoint &location )
{
    const calendar startturn = calendar( it.bday > 0 ? it.bday - 1 : 0 );

    if ( startturn > endturn || !tr.is_funnel() ) {
        return;
    }

    it.bday = endturn; // bday == last fill check
    auto data = sum_conditions( startturn, endturn, location );

    // Technically 0.0 division is OK, but it will be cleaner without it
    if( data.rain_amount > 0 ) {
        const int rain = 1.0 / tr.funnel_turns_per_charge( data.rain_amount );
        it.add_rain_to_container( false, rain );
    }

    if( data.acid_amount > 0 ) {
        const int acid = 1.0 / tr.funnel_turns_per_charge( data.acid_amount );
        it.add_rain_to_container( true, acid );
    }
}
Ejemplo n.º 21
0
// This function keeps the invlet cache updated when a new item is added.
void inventory::update_cache_with_item( item &newit )
{
    // This function does two things:
    // 1. It adds newit's invlet to the list of favorite letters for newit's item type.
    // 2. It removes newit's invlet from the list of favorite letters for all other item types.

    // no invlet item, just return.
    // TODO: Should we instead remember that the invlet was cleared?
    if( newit.invlet == 0 ) {
        return;
    }

    invlet_cache.set( newit.invlet, newit.typeId() );
}
Ejemplo n.º 22
0
bool vehicle_part::can_reload( const item &obj ) const
{
    // first check part is not destroyed and can contain ammo
    if( !is_fuel_store() ) {
        return false;
    }

    if( !obj.is_null() ) {
        const itype_id obj_type = obj.typeId();
        if( is_reactor() ) {
            return base.is_reloadable_with( obj_type );
        }

        // forbid filling tanks with solids or non-material things
        if( is_tank() && ( obj.made_of( SOLID ) || obj.made_of( PNULL ) ) ) {
            return false;
        }
        // forbid putting liquids, gasses, and plasma in things that aren't tanks
        else if( !obj.made_of( SOLID ) && !is_tank() ) {
            return false;
        }
        // prevent mixing of different ammo
        if( ammo_current() != "null" && ammo_current() != obj_type ) {
            return false;
        }
        // For storage with set type, prevent filling with different types
        if( info().fuel_type != fuel_type_none && info().fuel_type != obj_type ) {
            return false;
        }
        // don't fill magazines with inappropriate fuel
        if( !is_tank() && !base.is_reloadable_with( obj_type ) ) {
            return false;
        }
    }

    return ammo_remaining() < ammo_capacity();
}
Ejemplo n.º 23
0
int Pickup::cost_to_move_item( const Character &who, const item &it )
{
    // Do not involve inventory capacity, it's not like you put it in backpack
    int ret = 50;
    if( who.is_armed() ) {
        // No free hand? That will cost you extra
        ret += 20;
    }

    // Is it too heavy? It'll take 10 moves per kg over limit
    ret += std::max( 0, ( it.weight() - who.weight_capacity() ) / 100_gram );

    // Keep it sane - it's not a long activity
    return std::min( 400, ret );
}
Ejemplo n.º 24
0
bool player::feed_reactor_with( item &it )
{
    if( !can_feed_reactor_with( it ) ) {
        return false;
    }

    const auto iter = plut_charges.find( it.typeId() );
    const int max_amount = iter != plut_charges.end() ? iter->second : 0;
    const int amount = std::min( get_acquirable_energy( it, rechargeable_cbm::reactor ), max_amount );

    if( amount >= PLUTONIUM_CHARGES * 10 &&
        !query_yn( _( "Thats a LOT of plutonium.  Are you sure you want that much?" ) ) ) {
        return false;
    }

    add_msg_player_or_npc( _( "You add your %s to your reactor's tank." ),
                           _( "<npcname> pours %s into their reactor's tank." ),
                           it.tname().c_str() );

    tank_plut += amount; // @todo Encapsulate
    it.charges -= 1;
    mod_moves( -250 );
    return true;
}
Ejemplo n.º 25
0
void inventory::update_invlet( item &newit, bool assign_invlet )
{
    // Avoid letters that have been manually assigned to other things.
    if( newit.invlet && assigned_invlet.find( newit.invlet ) != assigned_invlet.end() &&
        assigned_invlet[newit.invlet] != newit.typeId() ) {
        newit.invlet = '\0';
    }

    // Remove letters that are not in the favorites cache
    if( newit.invlet ) {
        if( !invlet_cache.contains( newit.invlet, newit.typeId() ) ) {
            newit.invlet = '\0';
        }
    }

    // Remove letters that have been assigned to other items in the inventory
    if( newit.invlet ) {
        char tmp_invlet = newit.invlet;
        newit.invlet = '\0';
        if( g->u.invlet_to_position( tmp_invlet ) == INT_MIN ) {
            newit.invlet = tmp_invlet;
        }
    }

    if( assign_invlet ) {
        // Assign a cached letter to the item
        if( !newit.invlet ) {
            newit.invlet = find_usable_cached_invlet( newit.typeId() );
        }

        // Give the item an invlet if it has none
        if( !newit.invlet ) {
            assign_empty_invlet( newit, g->u );
        }
    }
}
Ejemplo n.º 26
0
void monster::init_from_item( const item &itm )
{
    if( itm.typeId() == "corpse" ) {
        const int burnt_penalty = itm.burnt;
        set_speed_base( static_cast<int>( get_speed_base() * 0.8 ) - ( burnt_penalty / 2 ) );
        hp = static_cast<int>( hp * 0.7 ) - burnt_penalty;
        if( itm.damage > 0 ) {
            set_speed_base( speed_base / ( itm.damage + 1 ) );
            hp /= itm.damage + 1;
        }
    } else {
        // must be a robot
        const int damfac = 5 - std::max<int>( 0, itm.damage ); // 5 (no damage) ... 1 (max damage)
        // One hp at least, everything else would be unfair (happens only to monster with *very* low hp),
        hp = std::max( 1, hp * damfac / 5 );
    }
}
Ejemplo n.º 27
0
void inventory::reassign_item( item &it, char invlet, bool remove_old )
{
    if( it.invlet == invlet ) { // no change needed
        return;
    }
    if( remove_old && it.invlet ) {
        auto invlet_list_iter = invlet_cache.find( it.typeId() );
        if( invlet_list_iter != invlet_cache.end() ) {
            auto &invlet_list = invlet_list_iter->second;
            invlet_list.erase( std::remove_if( invlet_list.begin(), invlet_list.end(), [&it]( char cached_invlet ) {
                return cached_invlet == it.invlet;
            } ), invlet_list.end() );
        }
    }
    it.invlet = invlet;
    update_cache_with_item( it );
}
Ejemplo n.º 28
0
//Adds the weight of aItem to the inventory's total weight
//Returns whether or not it succeeded.
bool inventory::incWeight(const item& aItem)
{
    //If the new items weight added to the inventory total weight exceeds the
    //MAX_WEIGHT value, return a failure.
    double item_weight = aItem.getWeight();
    if((item_weight + weight) > MAX_WEIGHT)
    {
        cout << "You're not strong enough to pick up the " << aItem << " with everything else you're carrying." << endl;
        return false;
    }
    else
    {
        cout << "You picked up a " << aItem << "." << endl;
        weight+=item_weight;
        return true;
    }

}
Ejemplo n.º 29
0
item_location game_menus::inv::saw_barrel( player &p, item &tool )
{
    const auto actor = dynamic_cast<const saw_barrel_actor *>
                       ( tool.type->get_use( "saw_barrel" )->get_actor_ptr() );

    if( !actor ) {
        debugmsg( "Tried to use a wrong item." );
        return item_location();
    }

    return inv_internal( p, saw_barrel_inventory_preset( p, tool, *actor ),
                         _( "Saw barrel" ), 1,
                         _( "You don't have any guns." ),
                         string_format( _( "Choose a weapon to use your %s on" ),
                                        tool.tname( 1, false ).c_str()
                                      )
                       );
}
Ejemplo n.º 30
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 );
    } );
}