Exemplo n.º 1
0
bool Pickup::handle_spillable_contents( Character &c, item &it, map &m )
{
    if( it.is_bucket_nonempty() ) {
        const item &it_cont = it.contents.front();
        int num_charges = it_cont.charges;
        while( !it.spill_contents( c ) ) {
            if( num_charges > it_cont.charges ) {
                num_charges = it_cont.charges;
            } else {
                break;
            }
        }

        // If bucket is still not empty then player opted not to handle the
        // rest of the contents
        if( it.is_bucket_nonempty() ) {
            c.add_msg_player_or_npc(
                _( "To avoid spilling its contents, you set your %1$s on the %2$s." ),
                _( "To avoid spilling its contents, <npcname> sets their %1$s on the %2$s." ),
                it.display_name(), m.name( c.pos() )
            );
            m.add_item_or_charges( c.pos(), it );
            return true;
        }
    }

    return false;
}
Exemplo n.º 2
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 );
        }
    }
}
Exemplo n.º 3
0
void 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_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 ) {
        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 );
        }
    }
}