MCPcopy Create free account
hub / github.com/NetHack/NetHack / destroy_items

Function destroy_items

src/zap.c:5964–6097  ·  view source on GitHub ↗

target items of specified class in mon's inventory for possible destruction return total amount of damage inflicted, though this is unused if mon is the player */

Source from the content-addressed store, hash-verified

5962 return total amount of damage inflicted, though this is unused if mon is
5963 the player */
5964int
5965destroy_items(
5966 struct monst *mon, /* monster whose invent is being subjected to
5967 * destruction */
5968 int dmgtyp, /* AD_**** - currently only cold, fire, elec */
5969 int dmg_in) /* the amount of HP damage the attack dealt */
5970{
5971 struct obj *obj;
5972 int i, defer;
5973 int limit; /* max amount of item stacks destroyed, based on damage */
5974 struct {
5975 unsigned oid;
5976 struct obj *otmp;
5977 boolean deferred;
5978 } items_to_destroy[MAX_ITEMS_DESTROYED];
5979 int elig_stacks = 0; /* number of destroyable objects found so far */
5980 boolean u_carry = (mon == &gy.youmonst);
5981 /* this is a struct obj** because we might destroy the first item in it */
5982 struct obj **objchn = u_carry ? &gi.invent : &mon->minvent;
5983 int dmg_out = 0; /* damage caused by items getting destroyed */
5984 xint8 where = NOBJ_STATES;
5985
5986 /* initialize items_to_destroy */
5987 for (i = 0; i < MAX_ITEMS_DESTROYED; ++i) {
5988 /* 0 should not be a valid o_id for anything */
5989 items_to_destroy[i].oid = 0;
5990 items_to_destroy[i].otmp = (struct obj *) 0;
5991 items_to_destroy[i].deferred = FALSE;
5992 }
5993
5994 /* don't straight up destroy all items with an equal chance; limit it
5995 based on the amount of damage being dealt by the source of the item
5996 destruction */
5997 limit = dmg_in / DMG_DESTROY_SCALE;
5998 if (dmg_in % DMG_DESTROY_SCALE > rn2(DMG_DESTROY_SCALE)) {
5999 limit++; /* dmg = 9: 20% chance of limit=1, 80% of limit=2, etc */
6000 }
6001 if (limit > MAX_ITEMS_DESTROYED) {
6002 /* in case of incredibly high damage, prevent from overflowing
6003 * items_to_destroy */
6004 limit = MAX_ITEMS_DESTROYED;
6005 }
6006 if (limit < 1) {
6007 return 0; /* nothing destroyed */
6008 }
6009
6010 /* Sometimes destroying an item can change inventory aside from
6011 * the item itself (cited case was a potion of unholy water; when
6012 * boiled, potionbreathe() caused hero to transform into were-beast
6013 * form and that resulted in dropping or destroying some worn armor).
6014 *
6015 * Unlike other uses of the object bypass mechanism, destroy_items()
6016 * can be called multiple times for the same event. So we have to
6017 * explicitly clear it before each use and hope no other section of
6018 * code expects it to retain previous value.
6019 *
6020 * Destruction of a ring of levitation or form change which pushes
6021 * off levitation boots could drop hero onto a fire trap that

Callers 15

mhitm_ad_fireFunction · 0.85
mhitm_ad_coldFunction · 0.85
mhitm_ad_elecFunction · 0.85
mcast_fire_pillarFunction · 0.85
mcast_lightningFunction · 0.85
artifact_hitFunction · 0.85
dogazeFunction · 0.85
trapeffect_fire_trapFunction · 0.85
dofiretrapFunction · 0.85
chest_trapFunction · 0.85
lava_effectsFunction · 0.85
zapyourselfFunction · 0.85

Calls 6

rn2Function · 0.85
bypass_objlistFunction · 0.85
nxt_unbypassed_objFunction · 0.85
destroyableFunction · 0.85
maybe_destroy_itemFunction · 0.85
impossibleFunction · 0.70

Tested by

no test coverage detected