extern struct obj *nxt_unbypassed_obj(struct obj *);
extern struct obj *nxt_unbypassed_loot(Loot *, struct obj *);
extern int racial_exception(struct monst *, struct obj *);
+extern void extract_from_minvent(struct monst *, struct obj *, boolean,
+ boolean);
/* ### write.c ### */
void
discard_minvent(struct monst* mtmp, boolean uncreate_artifacts)
{
- struct obj *otmp, *mwep = MON_WEP(mtmp);
- boolean keeping_mon = !DEADMONSTER(mtmp);
+ struct obj *otmp;
while ((otmp = mtmp->minvent) != 0) {
/* this has now become very similar to m_useupall()... */
- obj_extract_self(otmp);
- if (otmp->owornmask) {
- if (keeping_mon) {
- if (otmp == mwep)
- mwepgone(mtmp), mwep = 0;
- mtmp->misc_worn_check &= ~otmp->owornmask;
- update_mon_intrinsics(mtmp, otmp, FALSE, TRUE);
- }
- otmp->owornmask = 0L; /* obfree() expects this */
- }
+ extract_from_minvent(mtmp, otmp, TRUE, TRUE);
if (uncreate_artifacts && otmp->oartifact)
artifact_exists(otmp, safe_oname(otmp), FALSE);
obfree(otmp, (struct obj *) 0); /* dealloc_obj() isn't sufficient */
oldminvent = 0;
/* some objects may end up outside the statue */
while ((obj = mdef->minvent) != 0) {
- obj_extract_self(obj);
- if (obj->owornmask)
- update_mon_intrinsics(mdef, obj, FALSE, TRUE);
- obj_no_longer_held(obj);
- if (obj->owornmask & W_WEP)
- setmnotwielded(mdef, obj);
- obj->owornmask = 0L;
+ extract_from_minvent(mdef, obj, TRUE, TRUE);
if (obj->otyp == BOULDER
#if 0 /* monsters don't carry statues */
|| (obj->otyp == STATUE
return MM_HIT;
}
-
-
/* remove an entire item from a monster's inventory; destroy that item */
void
m_useupall(struct monst* mon, struct obj* obj)
{
- obj_extract_self(obj);
- if (obj->owornmask) {
- if (obj == MON_WEP(mon))
- mwepgone(mon);
- mon->misc_worn_check &= ~obj->owornmask;
- update_mon_intrinsics(mon, obj, FALSE, FALSE);
- obj->owornmask = 0L;
- }
+ extract_from_minvent(mon, obj, TRUE, FALSE);
obfree(obj, (struct obj *) 0);
}
* *prev_loot is set to TRUE if something was actually acquired in here.
*/
if (mtmp && mtmp != u.usteed && (otmp = which_armor(mtmp, W_SADDLE))) {
- long unwornmask;
-
if (passed_info)
*passed_info = 1;
Sprintf(qbuf, "Do you want to remove the saddle from %s?",
/* the attempt costs you time */
return 1;
}
- obj_extract_self(otmp);
- if ((unwornmask = otmp->owornmask) != 0L) {
- mtmp->misc_worn_check &= ~unwornmask;
- otmp->owornmask = 0L;
- update_mon_intrinsics(mtmp, otmp, FALSE, FALSE);
- }
+ extract_from_minvent(mtmp, otmp, TRUE, FALSE);
otmp = hold_another_object(otmp, "You drop %s!", doname(otmp),
(const char *) 0);
nhUse(otmp);
boolean verbosely)
{
int omx = mon->mx, omy = mon->my;
- boolean update_mon = FALSE;
-
- if (obj->owornmask) {
- /* perform worn item handling if the monster is still alive */
- if (!DEADMONSTER(mon)) {
- mon->misc_worn_check &= ~obj->owornmask;
- update_mon = TRUE;
-
- /* don't charge for an owned saddle on dead steed (provided
- that the hero is within the same shop at the time) */
- } else if (mon->mtame && (obj->owornmask & W_SADDLE) != 0L
- && !obj->unpaid && costly_spot(omx, omy)
- /* being at costly_spot guarantees lev->roomno is not 0 */
- && index(in_rooms(u.ux, u.uy, SHOPBASE),
- levl[omx][omy].roomno)) {
- obj->no_charge = 1;
- }
- /* this should be done even if the monster has died */
- if (obj->owornmask & W_WEP)
- setmnotwielded(mon, obj);
- obj->owornmask = 0L;
+ boolean unwornmask = obj->owornmask;
+
+ extract_from_minvent(mon, obj, FALSE, TRUE);
+ /* don't charge for an owned saddle on dead steed (provided
+ that the hero is within the same shop at the time) */
+ if (unwornmask && mon->mtame && (unwornmask & W_SADDLE) != 0L
+ && !obj->unpaid && costly_spot(omx, omy)
+ /* being at costly_spot guarantees lev->roomno is not 0 */
+ && index(in_rooms(u.ux, u.uy, SHOPBASE), levl[omx][omy].roomno)) {
+ obj->no_charge = 1;
}
/* obj_no_longer_held(obj); -- done by place_object */
if (verbosely && cansee(omx, omy))
stackobj(obj);
}
/* do this last, after placing obj on floor; removing steed's saddle
- throws rider, possibly inflicting fatal damage and producing bones */
- if (update_mon)
+ throws rider, possibly inflicting fatal damage and producing bones; this
+ is why we had to call extract_from_minvent() with do_intrinsics=FALSE */
+ if (!DEADMONSTER(mon) && unwornmask)
update_mon_intrinsics(mon, obj, FALSE, TRUE);
}
current role's quest artifact is rescued too--quest artifacts
for the other roles are not */
if (obj_resists(obj, 0, 0) || is_quest_artifact(obj)) {
- obj_extract_self(obj);
if (mon->mx) {
mdrop_obj(mon, obj, FALSE);
} else { /* migrating monster not on map */
- if (obj->owornmask) {
- mon->misc_worn_check &= ~obj->owornmask;
- if (obj->owornmask & W_WEP)
- setmnotwielded(mon, obj);
- obj->owornmask = 0L;
- }
+ extract_from_minvent(mon, obj, TRUE, TRUE);
rloco(obj);
}
}
} /* isgd && has gold */
while ((otmp = (is_pet ? droppables(mtmp) : mtmp->minvent)) != 0) {
- obj_extract_self(otmp);
mdrop_obj(mtmp, otmp, is_pet && flags.verbose);
}
mpickobj(mdef, gold), gold = 0;
if (!Upolyd)
break; /* no longer have ability to steal */
+ unwornmask = otmp->owornmask;
/* take the object away from the monster */
- obj_extract_self(otmp);
- if ((unwornmask = otmp->owornmask) != 0L) {
- mdef->misc_worn_check &= ~unwornmask;
- if (otmp->owornmask & W_WEP)
- setmnotwielded(mdef, otmp);
- otmp->owornmask = 0L;
- update_mon_intrinsics(mdef, otmp, FALSE, FALSE);
- /* give monster a chance to wear other equipment on its next
- move instead of waiting until it picks something up */
- mdef->misc_worn_check |= I_SPECIAL;
-
- if (otmp == ustealo) /* special message for final item */
- pline("%s finishes taking off %s suit.", Monnam(mdef),
- mhis(mdef));
- }
+ extract_from_minvent(mdef, otmp, TRUE, FALSE);
+ /* special message for final item; no need to check owornmask because
+ * ustealo is only set on objects with (owornmask & W_ARM) */
+ if (otmp == ustealo)
+ pline("%s finishes taking off %s suit.", Monnam(mdef),
+ mhis(mdef));
/* give the object to the character */
otmp = hold_another_object(otmp, "You snatched but dropped %s.",
doname(otmp), "You steal: ");
if (u.usteed == mdef && obj == which_armor(mdef, W_SADDLE))
/* "You can no longer ride <steed>." */
dismount_steed(DISMOUNT_POLY);
- obj_extract_self(obj);
- if (obj->owornmask) {
- mdef->misc_worn_check &= ~obj->owornmask;
- if (obj->owornmask & W_WEP)
- mwepgone(mdef);
- obj->owornmask = 0L;
- update_mon_intrinsics(mdef, obj, FALSE, FALSE);
- /* give monster a chance to wear other equipment on its next
- move instead of waiting until it picks something up */
- mdef->misc_worn_check |= I_SPECIAL;
- }
+ extract_from_minvent(mdef, obj, TRUE, FALSE);
/* add_to_minv() might free 'obj' [if it merges] */
if (g.vis)
Strcpy(onambuf, doname(obj));
static void
m_lose_armor(struct monst *mon, struct obj *obj)
{
- mon->misc_worn_check &= ~obj->owornmask;
- if (obj->owornmask)
- update_mon_intrinsics(mon, obj, FALSE, FALSE);
- obj->owornmask = 0L;
-
- obj_extract_self(obj);
+ extract_from_minvent(mon, obj, TRUE, FALSE);
place_object(obj, mon->mx, mon->my);
/* call stackobj() if we ever drop anything that can merge */
newsym(mon->mx, mon->my);
return 0;
}
+
+/* Remove an object from a monster's inventory.
+ * At its core this is just obj_extract_self(), but it also handles any updates
+ * that needs to happen if the gear is equipped or in some other sort of state
+ * that needs handling.
+ * Note that like obj_extract_self(), this leaves obj free. */
+void
+extract_from_minvent(struct monst *mon, struct obj *obj,
+ boolean do_intrinsics, /* whether to call
+ update_mon_intrinsics */
+ boolean silently) /* doesn't affect all possible messages,
+ just update_mon_intrinsics's */
+{
+ long unwornmask = obj->owornmask;
+
+ if (obj->where != OBJ_MINVENT) {
+ impossible("extract_from_minvent called on object not in minvent");
+ return;
+ }
+ obj_extract_self(obj);
+ obj->owornmask = 0L;
+ if (unwornmask) {
+ if (!DEADMONSTER(mon) && do_intrinsics) {
+ update_mon_intrinsics(mon, obj, FALSE, silently);
+ }
+ mon->misc_worn_check &= ~unwornmask;
+ /* give monster a chance to wear other equipment on its next
+ move instead of waiting until it picks something up */
+ mon->misc_worn_check |= I_SPECIAL;
+ }
+ obj_no_longer_held(obj);
+ if (unwornmask & W_WEP) {
+ mwepgone(mon); /* unwields and sets weapon_check to NEED_WEAPON */
+ }
+}
/*worn.c*/
} else if (canspotmon(mtmp)) {
pline("%s falls off.", buf);
}
- obj_extract_self(obj);
mdrop_obj(mtmp, obj, FALSE);
}
break;
for (otmp = mon->minvent; otmp; otmp = otmp2) {
otmp2 = otmp->nobj;
if (!oresist_disintegration(otmp)) {
- if (otmp->owornmask) {
- /* in case monster's life gets saved */
- mon->misc_worn_check &= ~otmp->owornmask;
- if (otmp->owornmask & W_WEP)
- setmnotwielded(mon, otmp);
- /* also dismounts hero if this object is steed's saddle */
- update_mon_intrinsics(mon, otmp, FALSE, TRUE);
- otmp->owornmask = 0L;
- }
- obj_extract_self(otmp);
+ extract_from_minvent(mon, otmp, TRUE, TRUE);
obfree(otmp, (struct obj *) 0);
}
}