本文整理汇总了C++中item::tname方法的典型用法代码示例。如果您正苦于以下问题:C++ item::tname方法的具体用法?C++ item::tname怎么用?C++ item::tname使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类item
的用法示例。
在下文中一共展示了item::tname方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: inv_internal
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() ) );
}
示例2: handle_quiver_insertion
//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;
}
示例3: item_location
item_location game_menus::inv::holster( player &p, item &holster )
{
const std::string holster_name = holster.tname( 1, false );
const auto actor = dynamic_cast<const holster_actor *>
( holster.type->get_use( "holster" )->get_actor_ptr() );
if( !actor ) {
const std::string msg = string_format( _( "You can't put anything into your %s." ),
holster_name.c_str() );
popup( msg, PF_GET_KEY );
return item_location();
}
const std::string title = actor->holster_prompt.empty()
? _( "Holster item" )
: _( actor->holster_prompt.c_str() );
const std::string hint = string_format( _( "Choose a weapon to put into your %s" ),
holster_name.c_str() );
return inv_internal( p, holster_inventory_preset( p, *actor ), title, 1,
string_format( _( "You have no weapons you could put into your %s." ),
holster_name.c_str() ),
hint );
}
示例4: feed_reactor_with
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;
}
示例5: pick_one_up
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() );
//.........这里部分代码省略.........
示例6: pick_one_up
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 {
//.........这里部分代码省略.........
示例7: throw_item
void game::throw_item(player &p, int tarx, int tary, item &thrown,
std::vector<point> &trajectory)
{
int deviation = 0;
int trange = 1.5 * rl_dist(p.posx, p.posy, tarx, tary);
// Throwing attempts below "Basic Competency" level are extra-bad
int skillLevel = p.skillLevel("throw");
if (skillLevel < 3)
deviation += rng(0, 8 - skillLevel);
if (skillLevel < 8)
deviation += rng(0, 8 - skillLevel);
else
deviation -= skillLevel - 6;
deviation += p.throw_dex_mod();
if (p.per_cur < 6)
deviation += rng(0, 8 - p.per_cur);
else if (p.per_cur > 8)
deviation -= p.per_cur - 8;
deviation += rng(0, p.encumb(bp_hands) * 2 + p.encumb(bp_eyes) + 1);
if (thrown.volume() > 5)
deviation += rng(0, 1 + (thrown.volume() - 5) / 4);
if (thrown.volume() == 0)
deviation += rng(0, 3);
deviation += rng(0, 1 + abs(p.str_cur - thrown.weight()));
double missed_by = .01 * deviation * trange;
bool missed = false;
int tart;
if (missed_by >= 1) {
// We missed D:
// Shoot a random nearby space?
if (missed_by > 9)
missed_by = 9;
tarx += rng(0 - int(sqrt(double(missed_by))), int(sqrt(double(missed_by))));
tary += rng(0 - int(sqrt(double(missed_by))), int(sqrt(double(missed_by))));
if (m.sees(p.posx, p.posy, tarx, tary, -1, tart))
trajectory = line_to(p.posx, p.posy, tarx, tary, tart);
else
trajectory = line_to(p.posx, p.posy, tarx, tary, 0);
missed = true;
if (!p.is_npc())
add_msg("You miss!");
} else if (missed_by >= .6) {
// Hit the space, but not necessarily the monster there
missed = true;
if (!p.is_npc())
add_msg("You barely miss!");
}
std::string message;
int dam = (thrown.weight() / 4 + thrown.type->melee_dam / 2 + p.str_cur / 2) /
double(2 + double(thrown.volume() / 4));
if (dam > thrown.weight() * 3)
dam = thrown.weight() * 3;
int i = 0, tx = 0, ty = 0;
for (i = 0; i < trajectory.size() && dam > -10; i++) {
message = "";
double goodhit = missed_by;
tx = trajectory[i].x;
ty = trajectory[i].y;
// If there's a monster in the path of our item, and either our aim was true,
// OR it's not the monster we were aiming at and we were lucky enough to hit it
if (mon_at(tx, ty) != -1 &&
(!missed || one_in(7 - int(z[mon_at(tx, ty)].type->size)))) {
if (rng(0, 100) < 20 + skillLevel * 12 &&
thrown.type->melee_cut > 0) {
if (!p.is_npc()) {
message += " You cut the ";
message += z[mon_at(tx, ty)].name();
message += "!";
}
if (thrown.type->melee_cut > z[mon_at(tx, ty)].armor_cut())
dam += (thrown.type->melee_cut - z[mon_at(tx, ty)].armor_cut());
}
if (thrown.made_of(GLASS) && !thrown.active && // active = molotov, etc.
rng(0, thrown.volume() + 8) - rng(0, p.str_cur) < thrown.volume()) {
if (u_see(tx, ty))
add_msg("The %s shatters!", thrown.tname().c_str());
for (int i = 0; i < thrown.contents.size(); i++)
m.add_item(tx, ty, thrown.contents[i]);
sound(tx, ty, 16, "glass breaking!");
int glassdam = rng(0, thrown.volume() * 2);
if (glassdam > z[mon_at(tx, ty)].armor_cut())
dam += (glassdam - z[mon_at(tx, ty)].armor_cut());
} else
m.add_item(tx, ty, thrown);
if (i < trajectory.size() - 1)
goodhit = double(double(rand() / RAND_MAX) / 2);
if (goodhit < .1 && !z[mon_at(tx, ty)].has_flag(MF_NOHEAD)) {
message = "Headshot!";
dam = rng(dam, dam * 3);
//.........这里部分代码省略.........
示例8: pick_one_up
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 );
//.........这里部分代码省略.........
示例9: can_disassemble
bool player::can_disassemble( const item &obj, const inventory &inv, std::string *err ) const
{
const auto error = [&err]( const std::string & message ) {
if( err != nullptr ) {
*err = message;
}
return false;
};
const auto &r = recipe_dictionary::get_uncraft( obj.typeId() );
if( !r ) {
return error( string_format( _( "You cannot disassemble this." ) ) );
}
// check sufficient light
if( lighting_craft_speed_multiplier( r ) == 0.0f ) {
return error( _( "You can't see to craft!" ) );
}
// refuse to disassemble rotten items
if( obj.goes_bad() || ( obj.is_food_container() && obj.contents.front().goes_bad() ) ) {
if( obj.rotten() || ( obj.is_food_container() && obj.contents.front().rotten() ) ) {
return error( _( "It's rotten, I'm not taking that apart." ) );
}
}
if( obj.count_by_charges() && !r.has_flag( "UNCRAFT_SINGLE_CHARGE" ) ) {
// Create a new item to get the default charges
int qty = r.create_result().charges;
if( obj.charges < qty ) {
auto msg = ngettext( "You need at least %d charge of %s.",
"You need at least %d charges of %s.", qty );
return error( string_format( msg, qty, obj.tname().c_str() ) );
}
}
const auto &dis = r.disassembly_requirements();
for( const auto &opts : dis.get_qualities() ) {
for( const auto &qual : opts ) {
if( !qual.has( inv ) ) {
// Here should be no dot at the end of the string as 'to_string()' provides it.
return error( string_format( _( "You need %s" ), qual.to_string().c_str() ) );
}
}
}
for( const auto &opts : dis.get_tools() ) {
const bool found = std::any_of( opts.begin(), opts.end(),
[&]( const tool_comp & tool ) {
return ( tool.count <= 0 && inv.has_tools( tool.type, 1 ) ) ||
( tool.count > 0 && inv.has_charges( tool.type, tool.count ) );
} );
if( !found ) {
if( opts.front().count <= 0 ) {
return error( string_format( _( "You need %s." ),
item::nname( opts.front().type ).c_str() ) );
} else {
return error( string_format( ngettext( "You need a %s with %d charge.",
"You need a %s with %d charges.",
opts.front().count ),
item::nname( opts.front().type ).c_str(), opts.front().count ) );
}
}
}
return true;
}
示例10: disassemble
bool player::disassemble( item &obj, int pos, bool ground, bool interactive )
{
// check sufficient tools for disassembly
std::string err;
if( !can_disassemble( obj, crafting_inventory(), &err ) ) {
if( interactive ) {
add_msg_if_player( m_info, "%s", err.c_str() );
}
return false;
}
const auto &r = recipe_dictionary::get_uncraft( obj.typeId() );
// last chance to back out
if( interactive && get_option<bool>( "QUERY_DISASSEMBLE" ) ) {
const auto components( r.disassembly_requirements().get_components() );
std::ostringstream list;
for( const auto &elem : components ) {
list << "- " << elem.front().to_string() << std::endl;
}
if( !query_yn( _( "Disassembling the %s may yield:\n%s\nReally disassemble?" ), obj.tname().c_str(),
list.str().c_str() ) ) {
return false;
}
}
if( activity.id() != activity_id( "ACT_DISASSEMBLE" ) ) {
assign_activity( activity_id( "ACT_DISASSEMBLE" ), r.time );
} else if( activity.moves_left <= 0 ) {
activity.moves_left = r.time;
}
activity.values.push_back( pos );
activity.coords.push_back( ground ? this->pos() : tripoint_min );
activity.str_values.push_back( r.result );
return true;
}
示例11: throw_item
void game::throw_item(player &p, int tarx, int tary, item &thrown,
std::vector<point> &trajectory)
{
int deviation = 0;
int trange = 1.5 * rl_dist(p.posx, p.posy, tarx, tary);
std::set<std::string> no_effects;
// Throwing attempts below "Basic Competency" level are extra-bad
int skillLevel = p.skillLevel("throw");
if (skillLevel < 3) {
deviation += rng(0, 8 - skillLevel);
}
if (skillLevel < 8) {
deviation += rng(0, 8 - skillLevel);
} else {
deviation -= skillLevel - 6;
}
deviation += p.throw_dex_mod();
if (p.per_cur < 6) {
deviation += rng(0, 8 - p.per_cur);
} else if (p.per_cur > 8) {
deviation -= p.per_cur - 8;
}
deviation += rng(0, p.encumb(bp_hands) * 2 + p.encumb(bp_eyes) + 1);
if (thrown.volume() > 5) {
deviation += rng(0, 1 + (thrown.volume() - 5) / 4);
}
if (thrown.volume() == 0) {
deviation += rng(0, 3);
}
deviation += rng(0, std::max( 0, p.str_cur - thrown.weight() / 113 ) );
double missed_by = .01 * deviation * trange;
bool missed = false;
int tart;
if (missed_by >= 1) {
// We missed D:
// Shoot a random nearby space?
if (missed_by > 9) {
missed_by = 9;
}
tarx += rng(0 - int(sqrt(double(missed_by))), int(sqrt(double(missed_by))));
tary += rng(0 - int(sqrt(double(missed_by))), int(sqrt(double(missed_by))));
if (m.sees(p.posx, p.posy, tarx, tary, -1, tart)) {
trajectory = line_to(p.posx, p.posy, tarx, tary, tart);
} else {
trajectory = line_to(p.posx, p.posy, tarx, tary, 0);
}
missed = true;
add_msg_if_player(&p,_("You miss!"));
} else if (missed_by >= .6) {
// Hit the space, but not necessarily the monster there
missed = true;
add_msg_if_player(&p,_("You barely miss!"));
}
std::string message;
int real_dam = (thrown.weight() / 452 + thrown.type->melee_dam / 2 + p.str_cur / 2) /
double(2 + double(thrown.volume() / 4));
if (real_dam > thrown.weight() / 40) {
real_dam = thrown.weight() / 40;
}
if (p.has_active_bionic("bio_railgun") && (thrown.made_of("iron") || thrown.made_of("steel"))) {
real_dam *= 2;
}
int dam = real_dam;
int i = 0, tx = 0, ty = 0;
for (i = 0; i < trajectory.size() && dam >= 0; i++) {
message = "";
double goodhit = missed_by;
tx = trajectory[i].x;
ty = trajectory[i].y;
const int zid = mon_at(tx, ty);
// If there's a monster in the path of our item, and either our aim was true,
// OR it's not the monster we were aiming at and we were lucky enough to hit it
if (zid != -1 && (!missed || one_in(7 - int(zombie(zid).type->size)))) {
monster &z = zombie(zid);
if (rng(0, 100) < 20 + skillLevel * 12 && thrown.type->melee_cut > 0) {
if (!p.is_npc()) {
message += string_format(_(" You cut the %s!"), z.name().c_str());
}
if (thrown.type->melee_cut > z.get_armor_cut(bp_torso)) {
dam += (thrown.type->melee_cut - z.get_armor_cut(bp_torso));
}
}
if (thrown.made_of("glass") && !thrown.active && // active = molotov, etc.
rng(0, thrown.volume() + 8) - rng(0, p.str_cur) < thrown.volume()) {
if (u_see(tx, ty)) {
add_msg(_("The %s shatters!"), thrown.tname().c_str());
//.........这里部分代码省略.........
示例12: consume_effects
//.........这里部分代码省略.........
}
// Morale is in minutes
int morale_time = HOURS( 2 ) / MINUTES( 1 );
if( food.has_flag( "HOT" ) && food.has_flag( "EATEN_HOT" ) ) {
morale_time = HOURS( 3 ) / MINUTES( 1 );
int clamped_nutr = std::max( 5, std::min( 20, nutr / 10 ) );
add_morale( MORALE_FOOD_HOT, clamped_nutr, 20, morale_time, morale_time / 2 );
}
std::pair<int, int> fun = fun_for( food );
if( fun.first < 0 ) {
add_morale( MORALE_FOOD_BAD, fun.first, fun.second, morale_time, morale_time / 2, false,
food.type );
} else if( fun.first > 0 ) {
add_morale( MORALE_FOOD_GOOD, fun.first, fun.second, morale_time, morale_time / 2, false,
food.type );
}
const bool hibernate = has_active_mutation( trait_id( "HIBERNATE" ) );
if( hibernate ) {
if( ( nutr > 0 && get_hunger() < -60 ) || ( comest.quench > 0 && get_thirst() < -60 ) ) {
//Tell the player what's going on
add_msg_if_player( _( "You gorge yourself, preparing to hibernate." ) );
if( one_in( 2 ) ) {
//50% chance of the food tiring you
mod_fatigue( nutr );
}
}
if( ( nutr > 0 && get_hunger() < -200 ) || ( comest.quench > 0 && get_thirst() < -200 ) ) {
//Hibernation should cut burn to 60/day
add_msg_if_player( _( "You feel stocked for a day or two. Got your bed all ready and secured?" ) );
if( one_in( 2 ) ) {
//And another 50%, intended cumulative
mod_fatigue( nutr );
}
}
if( ( nutr > 0 && get_hunger() < -400 ) || ( comest.quench > 0 && get_thirst() < -400 ) ) {
add_msg_if_player(
_( "Mmm. You can still fit some more in...but maybe you should get comfortable and sleep." ) );
if( !one_in( 3 ) ) {
//Third check, this one at 66%
mod_fatigue( nutr );
}
}
if( ( nutr > 0 && get_hunger() < -600 ) || ( comest.quench > 0 && get_thirst() < -600 ) ) {
add_msg_if_player( _( "That filled a hole! Time for bed..." ) );
// At this point, you're done. Schlaf gut.
mod_fatigue( nutr );
}
}
// Moved here and changed a bit - it was too complex
// Incredibly minor stuff like this shouldn't require complexity
if( !is_npc() && has_trait( trait_id( "SLIMESPAWNER" ) ) &&
( get_hunger() < capacity + 40 || get_thirst() < capacity + 40 ) ) {
add_msg_if_player( m_mixed,
_( "You feel as though you're going to split open! In a good way?" ) );
mod_pain( 5 );
std::vector<tripoint> valid;
for( const tripoint &dest : g->m.points_in_radius( pos(), 1 ) ) {
if( g->is_empty( dest ) ) {
valid.push_back( dest );
}
}
int numslime = 1;
for( int i = 0; i < numslime && !valid.empty(); i++ ) {
const tripoint target = random_entry_removed( valid );
if( monster *const slime = g->summon_mon( mon_player_blob, target ) ) {
slime->friendly = -1;
}
}
mod_hunger( 40 );
mod_thirst( 40 );
//~slimespawns have *small voices* which may be the Nice equivalent
//~of the Rat King's ALL CAPS invective. Probably shared-brain telepathy.
add_msg_if_player( m_good, _( "hey, you look like me! let's work together!" ) );
}
// Last thing that happens before capping hunger
if( get_hunger() < capacity && has_trait( trait_id( "EATHEALTH" ) ) ) {
int excess_food = capacity - get_hunger();
add_msg_player_or_npc( _( "You feel the %s filling you out." ),
_( "<npcname> looks better after eating the %s." ),
food.tname().c_str() );
// Guaranteed 1 HP healing, no matter what. You're welcome. ;-)
if( excess_food <= 5 ) {
healall( 1 );
} else {
// Straight conversion, except it's divided amongst all your body parts.
healall( excess_food /= 5 );
}
// Note: We want this here to prevent "you can't finish this" messages
set_hunger( capacity );
}
cap_nutrition_thirst( *this, capacity, nutr > 0, comest.quench > 0 );
}
示例13: eat
bool player::eat( item &food, bool force )
{
if( !food.is_food() ) {
return false;
}
// Check if it's rotten before eating!
food.calc_rot( global_square_location() );
const auto ret = force ? can_eat( food ) : will_eat( food, is_player() );
if( !ret.success() ) {
return false;
}
if( food.type->has_use() ) {
if( food.type->invoke( *this, food, pos() ) <= 0 ) {
return false;
}
}
// Note: the block below assumes we decided to eat it
// No coming back from here
const bool hibernate = has_active_mutation( trait_id( "HIBERNATE" ) );
const int nutr = nutrition_for( food );
const int quench = food.type->comestible->quench;
const bool spoiled = food.rotten();
// The item is solid food
const bool chew = food.type->comestible->comesttype == "FOOD" || food.has_flag( "USE_EAT_VERB" );
// This item is a drink and not a solid food (and not a thick soup)
const bool drinkable = !chew && food.type->comestible->comesttype == "DRINK";
// If neither of the above is true then it's a drug and shouldn't get mealtime penalty/bonus
if( hibernate &&
( get_hunger() > -60 && get_thirst() > -60 ) &&
( get_hunger() - nutr < -60 || get_thirst() - quench < -60 ) ) {
add_memorial_log( pgettext( "memorial_male", "Began preparing for hibernation." ),
pgettext( "memorial_female", "Began preparing for hibernation." ) );
add_msg_if_player(
_( "You've begun stockpiling calories and liquid for hibernation. You get the feeling that you should prepare for bed, just in case, but...you're hungry again, and you could eat a whole week's worth of food RIGHT NOW." ) );
}
const bool will_vomit = get_hunger() < 0 && nutr >= 5 && !has_trait( trait_id( "GOURMAND" ) ) &&
!hibernate &&
!has_trait( trait_id( "SLIMESPAWNER" ) ) && !has_trait( trait_id( "EATHEALTH" ) ) &&
rng( -200, 0 ) > get_hunger() - nutr;
const bool saprophage = has_trait( trait_id( "SAPROPHAGE" ) );
if( spoiled && !saprophage ) {
add_msg_if_player( m_bad, _( "Ick, this %s doesn't taste so good..." ), food.tname().c_str() );
if( !has_trait( trait_id( "SAPROVORE" ) ) && !has_trait( trait_id( "EATDEAD" ) ) &&
( !has_bionic( bio_digestion ) || one_in( 3 ) ) ) {
add_effect( effect_foodpoison, rng( 60, ( nutr + 1 ) * 60 ) );
}
consume_effects( food );
} else if( spoiled && saprophage ) {
add_msg_if_player( m_good, _( "Mmm, this %s tastes delicious..." ), food.tname().c_str() );
consume_effects( food );
} else {
consume_effects( food );
}
const bool amorphous = has_trait( trait_id( "AMORPHOUS" ) );
int mealtime = 250;
if( drinkable || chew ) {
// Those bonuses/penalties only apply to food
// Not to smoking weed or applying bandages!
if( has_trait( trait_id( "MOUTH_TENTACLES" ) ) || has_trait( trait_id( "MANDIBLES" ) ) ) {
mealtime /= 2;
} else if( has_trait( trait_id( "GOURMAND" ) ) ) {
// Don't stack those two - that would be 25 moves per item
mealtime -= 100;
}
if( has_trait( trait_id( "BEAK_HUM" ) ) && !drinkable ) {
mealtime += 200; // Much better than PROBOSCIS but still optimized for fluids
} else if( has_trait( trait_id( "SABER_TEETH" ) ) ) {
mealtime += 250; // They get In The Way
}
if( amorphous ) {
mealtime *= 1.1;
// Minor speed penalty for having to flow around it
// rather than just grab & munch
}
}
moves -= mealtime;
// If it's poisonous... poison us.
// TODO: Move this to a flag
if( food.poison > 0 && !has_trait( trait_id( "EATPOISON" ) ) &&
!has_trait( trait_id( "EATDEAD" ) ) ) {
if( food.poison >= rng( 2, 4 ) ) {
add_effect( effect_poison, food.poison * 100 );
}
add_effect( effect_foodpoison, food.poison * 300 );
}
if( amorphous ) {
add_msg_player_or_npc( _( "You assimilate your %s." ), _( "<npcname> assimilates a %s." ),
//.........这里部分代码省略.........
示例14: happy
ret_val<edible_rating> player::will_eat( const item &food, bool interactive ) const
{
const auto ret = can_eat( food );
if( !ret.success() ) {
if( interactive ) {
add_msg_if_player( m_info, "%s", ret.c_str() );
}
return ret;
}
std::vector<ret_val<edible_rating>> consequences;
const auto add_consequence = [&consequences]( const std::string & msg, edible_rating code ) {
consequences.emplace_back( ret_val<edible_rating>::make_failure( code, msg ) );
};
const bool saprophage = has_trait( trait_id( "SAPROPHAGE" ) );
const auto &comest = food.type->comestible;
if( food.rotten() ) {
const bool saprovore = has_trait( trait_id( "SAPROVORE" ) );
if( !saprophage && !saprovore ) {
add_consequence( _( "This is rotten and smells awful!" ), ROTTEN );
}
}
const bool carnivore = has_trait( trait_id( "CARNIVORE" ) );
if( food.has_flag( "CANNIBALISM" ) && !has_trait_flag( "CANNIBAL" ) ) {
add_consequence( _( "The thought of eating human flesh makes you feel sick." ), CANNIBALISM );
}
const bool edible = comest->comesttype == "FOOD" || food.has_flag( "USE_EAT_VERB" );
if( edible && has_effect( effect_nausea ) ) {
add_consequence( _( "You still feel nauseous and will probably puke it all up again." ), NAUSEA );
}
if( ( allergy_type( food ) != MORALE_NULL ) || ( carnivore && food.has_flag( "ALLERGEN_JUNK" ) &&
!food.has_flag( "CARNIVORE_OK" ) ) ) {
add_consequence( _( "Your stomach won't be happy (allergy)." ), ALLERGY );
}
if( saprophage && edible && food.rotten() && !food.has_flag( "FERTILIZER" ) ) {
// Note: We're allowing all non-solid "food". This includes drugs
// Hard-coding fertilizer for now - should be a separate flag later
//~ No, we don't eat "rotten" food. We eat properly aged food, like a normal person.
//~ Semantic difference, but greatly facilitates people being proud of their character.
add_consequence( _( "Your stomach won't be happy (not rotten enough)." ), ALLERGY_WEAK );
}
const int nutr = nutrition_for( food );
const int quench = comest->quench;
const int temp_hunger = get_hunger() - nutr;
const int temp_thirst = get_thirst() - quench;
if( !has_active_mutation( trait_id( "EATHEALTH" ) ) &&
!has_active_mutation( trait_id( "HIBERNATE" ) ) &&
!has_trait( trait_id( "SLIMESPAWNER" ) ) ) {
if( get_hunger() < 0 && nutr >= 5 && !has_active_mutation( trait_id( "GOURMAND" ) ) ) {
add_consequence( _( "You're full already and will be forcing yourself to eat." ), TOO_FULL );
} else if( ( ( nutr > 0 && temp_hunger < stomach_capacity() ) ||
( comest->quench > 0 && temp_thirst < stomach_capacity() ) ) &&
!food.has_infinite_charges() ) {
add_consequence( _( "You will not be able to finish it all." ), TOO_FULL );
}
}
if( !consequences.empty() ) {
if( !interactive ) {
return consequences.front();
}
std::ostringstream req;
for( const auto &elem : consequences ) {
req << elem.str() << std::endl;
}
const bool eat_verb = food.has_flag( "USE_EAT_VERB" );
if( eat_verb || comest->comesttype == "FOOD" ) {
req << string_format( _( "Eat your %s anyway?" ), food.tname().c_str() );
} else if( !eat_verb && comest->comesttype == "DRINK" ) {
req << string_format( _( "Drink your %s anyway?" ), food.tname().c_str() );
} else {
req << string_format( _( "Consume your %s anyway?" ), food.tname().c_str() );
}
if( !query_yn( req.str() ) ) {
return consequences.front();
}
}
// All checks ended, it's edible (or we're pretending it is)
return ret_val<edible_rating>::make_success();
}
示例15: consume_effects
//.........这里部分代码省略.........
} else {
fun = 1;
}
}
const bool gourmand = has_trait( "GOURMAND" );
const bool hibernate = has_active_mutation( "HIBERNATE" );
if( gourmand ) {
if( fun < -2 ) {
add_morale( MORALE_FOOD_BAD, fun * 0.5, fun, 60, 30, false, food.type );
} else if( fun > 0 ) {
add_morale( MORALE_FOOD_GOOD, fun * 3, fun * 6, 60, 30, false, food.type );
}
} else if( fun < 0 ) {
add_morale( MORALE_FOOD_BAD, fun, fun * 6, 60, 30, false, food.type );
} else if( fun > 0 ) {
add_morale( MORALE_FOOD_GOOD, fun, fun * 4, 60, 30, false, food.type );
}
if( hibernate ) {
if( ( nutr > 0 && get_hunger() < -60 ) || ( comest->quench > 0 && get_thirst() < -60 ) ) {
//Tell the player what's going on
add_msg_if_player( _( "You gorge yourself, preparing to hibernate." ) );
if( one_in( 2 ) ) {
//50% chance of the food tiring you
mod_fatigue( nutr );
}
}
if( ( nutr > 0 && get_hunger() < -200 ) || ( comest->quench > 0 && get_thirst() < -200 ) ) {
//Hibernation should cut burn to 60/day
add_msg_if_player( _( "You feel stocked for a day or two. Got your bed all ready and secured?" ) );
if( one_in( 2 ) ) {
//And another 50%, intended cumulative
mod_fatigue( nutr );
}
}
if( ( nutr > 0 && get_hunger() < -400 ) || ( comest->quench > 0 && get_thirst() < -400 ) ) {
add_msg_if_player(
_( "Mmm. You can still fit some more in...but maybe you should get comfortable and sleep." ) );
if( !one_in( 3 ) ) {
//Third check, this one at 66%
mod_fatigue( nutr );
}
}
if( ( nutr > 0 && get_hunger() < -600 ) || ( comest->quench > 0 && get_thirst() < -600 ) ) {
add_msg_if_player( _( "That filled a hole! Time for bed..." ) );
// At this point, you're done. Schlaf gut.
mod_fatigue( nutr );
}
}
// Moved here and changed a bit - it was too complex
// Incredibly minor stuff like this shouldn't require complexity
if( !is_npc() && has_trait( "SLIMESPAWNER" ) &&
( get_hunger() < capacity + 40 || get_thirst() < capacity + 40 ) ) {
add_msg_if_player( m_mixed,
_( "You feel as though you're going to split open! In a good way?" ) );
mod_pain( 5 );
std::vector<tripoint> valid;
for( const tripoint &dest : g->m.points_in_radius( pos(), 1 ) ) {
if( g->is_empty( dest ) ) {
valid.push_back( dest );
}
}
int numslime = 1;
for( int i = 0; i < numslime && !valid.empty(); i++ ) {
const tripoint target = random_entry_removed( valid );
if( g->summon_mon( mon_player_blob, target ) ) {
monster *slime = g->monster_at( target );
slime->friendly = -1;
}
}
mod_hunger( 40 );
mod_thirst( 40 );
//~slimespawns have *small voices* which may be the Nice equivalent
//~of the Rat King's ALL CAPS invective. Probably shared-brain telepathy.
add_msg_if_player( m_good, _( "hey, you look like me! let's work together!" ) );
}
// Last thing that happens before capping hunger
if( get_hunger() < capacity && has_trait( "EATHEALTH" ) ) {
int excess_food = capacity - get_hunger();
add_msg_player_or_npc( _( "You feel the %s filling you out." ),
_( "<npcname> looks better after eating the %s." ),
food.tname().c_str() );
// Guaranteed 1 HP healing, no matter what. You're welcome. ;-)
if( excess_food <= 5 ) {
healall( 1 );
} else {
// Straight conversion, except it's divided amongst all your body parts.
healall( excess_food /= 5 );
}
// Note: We want this here to prevent "you can't finish this" messages
set_hunger( capacity );
}
cap_nutrition_thirst( *this, capacity, nutr > 0, comest->quench > 0 );
}