本文整理汇总了C++中item::made_of方法的典型用法代码示例。如果您正苦于以下问题:C++ item::made_of方法的具体用法?C++ item::made_of怎么用?C++ item::made_of使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类item
的用法示例。
在下文中一共展示了item::made_of方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: get_acquirable_energy
int player::get_acquirable_energy( const item &it, rechargeable_cbm cbm ) const
{
switch( cbm ) {
case rechargeable_cbm::none:
break;
case rechargeable_cbm::battery:
return std::min<long>( it.charges, std::numeric_limits<int>::max() );
case rechargeable_cbm::reactor:
if( it.charges > 0 ) {
const auto iter = plut_charges.find( it.typeId() );
return iter != plut_charges.end() ? it.charges * iter->second : 0;
}
break;
case rechargeable_cbm::furnace: {
int amount = ( it.volume() / 250_ml + it.weight() / 1_gram ) / 9;
// @todo JSONize.
if( it.made_of( material_id( "leather" ) ) ) {
amount /= 4;
}
if( it.made_of( material_id( "wood" ) ) ) {
amount /= 2;
}
return amount;
}
}
return 0;
}
示例2: drop_or_handle
void drop_or_handle( const item &newit, player &p )
{
if( newit.made_of( LIQUID ) && &p == &g->u ) { // TODO: what about NPCs?
g->handle_all_liquid( newit, PICKUP_RANGE );
} else {
item tmp( newit );
p.i_add_or_drop( tmp );
}
}
示例3: can_reload
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();
}
示例4: modify
void Item_modifier::modify(item &new_item) const
{
if(new_item.is_null()) {
return;
}
int dm = (damage.first == damage.second) ? damage.first : rng(damage.first, damage.second);
if(dm >= -1 && dm <= 4) {
new_item.damage = dm;
}
long ch = (charges.first == charges.second) ? charges.first : rng(charges.first, charges.second);
if(ch != -1) {
it_tool *t = dynamic_cast<it_tool *>(new_item.type);
it_gun *g = dynamic_cast<it_gun *>(new_item.type);
if(new_item.count_by_charges()) {
// food, ammo
new_item.charges = ch;
} else if(t != NULL) {
new_item.charges = std::min(ch, t->max_charges);
} else if(g != NULL && ammo.get() != NULL) {
item am = ammo->create_single(new_item.bday);
it_ammo *a = dynamic_cast<it_ammo *>(am.type);
if(!am.is_null() && a != NULL) {
new_item.curammo = a;
new_item.charges = std::min<long>(am.charges, new_item.clip_size());
}
}
}
if(container.get() != NULL) {
item cont = container->create_single(new_item.bday);
if (!cont.is_null()) {
if (new_item.made_of(LIQUID)) {
LIQUID_FILL_ERROR err;
int rc = cont.get_remaining_capacity_for_liquid(new_item, err);
if(rc > 0 && (new_item.charges > rc || ch == -1)) {
// make sure the container is not over-full.
// fill up the container (if using default charges)
new_item.charges = rc;
}
}
cont.put_in(new_item);
new_item = cont;
}
}
if (contents.get() != NULL) {
Item_spawn_data::ItemList contentitems = contents->create(new_item.bday);
new_item.contents.insert(new_item.contents.end(), contentitems.begin(), contentitems.end());
}
}
示例5: set_item_inventory
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() );
}
}
}
示例6: modify
void Item_modifier::modify(item &new_item) const
{
if(new_item.is_null()) {
return;
}
new_item.damage = std::min( std::max( (int) rng( damage.first, damage.second ), MIN_ITEM_DAMAGE ), MAX_ITEM_DAMAGE );
long ch = (charges.first == charges.second) ? charges.first : rng(charges.first, charges.second);
if(ch != -1) {
if( new_item.count_by_charges() || new_item.made_of( LIQUID ) ) {
// food, ammo
// count_by_charges requires that charges is at least 1. It makes no sense to
// spawn a "water (0)" item.
new_item.charges = std::max( 1l, ch );
} else if( new_item.is_tool() ) {
const auto qty = std::min( ch, new_item.ammo_capacity() );
new_item.charges = qty;
if( new_item.ammo_type() != "NULL" && qty > 0 ) {
new_item.ammo_set( new_item.ammo_type(), qty );
}
} else if( !new_item.is_gun() ) {
//not gun, food, ammo or tool.
new_item.charges = ch;
}
}
if( new_item.is_gun() && ( ammo.get() != nullptr || ch > 0 ) ) {
if( ammo.get() == nullptr ) {
// In case there is no explicit ammo item defined, use the default ammo
if( new_item.ammo_type() != "NULL" ) {
new_item.charges = ch;
new_item.set_curammo( new_item.ammo_type() );
}
} else {
const item am = ammo->create_single( new_item.bday );
new_item.set_curammo( am );
// Prefer explicit charges of the gun, else take the charges of the ammo item,
// Gun charges are easier to define: {"item":"gun","charge":10,"ammo-item":"ammo"}
if( ch > 0 ) {
new_item.charges = ch;
} else {
new_item.charges = am.charges;
}
}
// Make sure the item is in valid state
if( new_item.ammo_data() && new_item.magazine_integral() ) {
new_item.charges = std::min( new_item.charges, new_item.ammo_capacity() );
} else {
new_item.charges = 0;
}
}
if(container.get() != NULL) {
item cont = container->create_single(new_item.bday);
if (!cont.is_null()) {
if (new_item.made_of(LIQUID)) {
long rc = cont.get_remaining_capacity_for_liquid(new_item);
if(rc > 0 && (new_item.charges > rc || ch == -1)) {
// make sure the container is not over-full.
// fill up the container (if using default charges)
new_item.charges = rc;
}
}
cont.put_in(new_item);
new_item = cont;
}
}
if (contents.get() != NULL) {
Item_spawn_data::ItemList contentitems = contents->create(new_item.bday);
new_item.contents.insert(new_item.contents.end(), contentitems.begin(), contentitems.end());
}
}
示例7: 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() );
//.........这里部分代码省略.........
示例8: 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 {
//.........这里部分代码省略.........
示例9: 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);
//.........这里部分代码省略.........
示例10: 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 );
//.........这里部分代码省略.........
示例11: modify
void Item_modifier::modify(item &new_item) const
{
if(new_item.is_null()) {
return;
}
new_item.damage = std::min( std::max( (int) rng( damage.first, damage.second ), MIN_ITEM_DAMAGE ), MAX_ITEM_DAMAGE );
long ch = (charges.first == charges.second) ? charges.first : rng(charges.first, charges.second);
const auto g = new_item.type->gun.get();
const auto t = dynamic_cast<const it_tool *>(new_item.type);
if(ch != -1) {
if( new_item.count_by_charges() || new_item.made_of( LIQUID ) ) {
// food, ammo
// count_by_charges requires that charges is at least 1. It makes no sense to
// spawn a "water (0)" item.
new_item.charges = std::max( 1l, ch );
} else if(t != NULL) {
new_item.charges = std::min(ch, t->max_charges);
} else if (g == nullptr){
//not gun, food, ammo or tool.
new_item.charges = ch;
}
}
if( g != nullptr && ( ammo.get() != nullptr || ch > 0 ) ) {
if( ammo.get() == nullptr ) {
// In case there is no explicit ammo item defined, use the default ammo
const auto ammoid = default_ammo( g->ammo );
if ( !ammoid.empty() ) {
new_item.set_curammo( ammoid );
new_item.charges = ch;
}
} else {
const item am = ammo->create_single( new_item.bday );
new_item.set_curammo( am );
// Prefer explicit charges of the gun, else take the charges of the ammo item,
// Gun charges are easier to define: {"item":"gun","charge":10,"ammo-item":"ammo"}
if( ch > 0 ) {
new_item.charges = ch;
} else {
new_item.charges = am.charges;
}
}
// Make sure the item is in a valid state curammo==0 <=> charges==0 and respect clip size
if( !new_item.has_curammo() ) {
new_item.charges = 0;
} else {
new_item.charges = std::min<long>( new_item.charges, new_item.clip_size() );
}
}
if(container.get() != NULL) {
item cont = container->create_single(new_item.bday);
if (!cont.is_null()) {
if (new_item.made_of(LIQUID)) {
long rc = cont.get_remaining_capacity_for_liquid(new_item);
if(rc > 0 && (new_item.charges > rc || ch == -1)) {
// make sure the container is not over-full.
// fill up the container (if using default charges)
new_item.charges = rc;
}
}
cont.put_in(new_item);
new_item = cont;
}
}
if (contents.get() != NULL) {
Item_spawn_data::ItemList contentitems = contents->create(new_item.bday);
new_item.contents.insert(new_item.contents.end(), contentitems.begin(), contentitems.end());
}
}
示例12: modify
void Item_modifier::modify( item &new_item ) const
{
if( new_item.is_null() ) {
return;
}
new_item.set_damage( rng( damage.first, damage.second ) );
long ch = ( charges.first == charges.second ) ? charges.first : rng( charges.first,
charges.second );
if( ch != -1 ) {
if( new_item.count_by_charges() || new_item.made_of( LIQUID ) ) {
// food, ammo
// count_by_charges requires that charges is at least 1. It makes no sense to
// spawn a "water (0)" item.
new_item.charges = std::max( 1l, ch );
} else if( new_item.is_tool() ) {
const auto qty = std::min( ch, new_item.ammo_capacity() );
new_item.charges = qty;
if( new_item.ammo_type() && qty > 0 ) {
new_item.ammo_set( new_item.ammo_type()->default_ammotype(), qty );
}
} else if( !new_item.is_gun() ) {
//not gun, food, ammo or tool.
new_item.charges = ch;
}
}
if( ch > 0 && ( new_item.is_gun() || new_item.is_magazine() ) ) {
if( ammo == nullptr ) {
// In case there is no explicit ammo item defined, use the default ammo
if( new_item.ammo_type() ) {
new_item.ammo_set( new_item.ammo_type()->default_ammotype(), ch );
}
} else {
const item am = ammo->create_single( new_item.birthday() );
new_item.ammo_set( am.typeId(), ch );
}
// Make sure the item is in valid state
if( new_item.ammo_data() && new_item.magazine_integral() ) {
new_item.charges = std::min( new_item.charges, new_item.ammo_capacity() );
} else {
new_item.charges = 0;
}
}
if( new_item.is_tool() || new_item.is_gun() || new_item.is_magazine() ) {
bool spawn_ammo = rng( 0, 99 ) < with_ammo && new_item.ammo_remaining() == 0 && ch == -1 &&
( !new_item.is_tool() || new_item.type->tool->rand_charges.empty() );
bool spawn_mag = rng( 0, 99 ) < with_magazine && !new_item.magazine_integral() &&
!new_item.magazine_current();
if( spawn_mag ) {
new_item.contents.emplace_back( new_item.magazine_default(), new_item.birthday() );
}
if( spawn_ammo ) {
if( ammo ) {
const item am = ammo->create_single( new_item.birthday() );
new_item.ammo_set( am.typeId() );
} else {
new_item.ammo_set( new_item.ammo_type()->default_ammotype() );
}
}
}
if( container != nullptr ) {
item cont = container->create_single( new_item.birthday() );
if( !cont.is_null() ) {
if( new_item.made_of( LIQUID ) ) {
long rc = cont.get_remaining_capacity_for_liquid( new_item );
if( rc > 0 && ( new_item.charges > rc || ch == -1 ) ) {
// make sure the container is not over-full.
// fill up the container (if using default charges)
new_item.charges = rc;
}
}
cont.put_in( new_item );
new_item = cont;
}
}
if( contents != nullptr ) {
Item_spawn_data::ItemList contentitems = contents->create( new_item.birthday() );
new_item.contents.insert( new_item.contents.end(), contentitems.begin(), contentitems.end() );
}
for( auto &flag : custom_flags ) {
new_item.set_flag( flag );
}
}
示例13: 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());
//.........这里部分代码省略.........