Merge branch 'extract-from-minvent' of https://github.com/copperwater/NetHack into copperwater-pr455-2

This commit is contained in:
nhmall
2021-01-30 15:24:07 -05:00
9 changed files with 65 additions and 110 deletions

View File

@@ -3101,6 +3101,8 @@ extern void bypass_objlist(struct obj *, boolean);
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 ### */

View File

@@ -1878,21 +1878,11 @@ remove_object(struct obj* otmp)
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 */

View File

@@ -2597,13 +2597,7 @@ monstone(struct monst* mdef)
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

View File

@@ -842,20 +842,11 @@ breamm(struct monst* mtmp, struct attack* mattk, struct monst* mtarg)
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);
}

View File

@@ -2104,8 +2104,6 @@ loot_mon(struct monst *mtmp, int *passed_info, boolean *prev_loot)
* *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?",
@@ -2123,12 +2121,7 @@ loot_mon(struct monst *mtmp, int *passed_info, boolean *prev_loot)
/* 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);

View File

@@ -671,27 +671,16 @@ mdrop_obj(
boolean verbosely)
{
int omx = mon->mx, omy = mon->my;
boolean update_mon = FALSE;
boolean unwornmask = obj->owornmask;
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;
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))
@@ -701,8 +690,9 @@ mdrop_obj(
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);
}
@@ -721,16 +711,10 @@ mdrop_special_objs(struct monst* mon)
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);
}
}
@@ -757,7 +741,6 @@ relobj(
} /* isgd && has gold */
while ((otmp = (is_pet ? droppables(mtmp) : mtmp->minvent)) != 0) {
obj_extract_self(otmp);
mdrop_obj(mtmp, otmp, is_pet && flags.verbose);
}

View File

@@ -1626,22 +1626,14 @@ steal_it(struct monst *mdef, struct attack *mattk)
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: ");
@@ -3917,17 +3909,7 @@ mhitm_ad_sedu(struct monst *magr, struct attack *mattk, struct monst *mdef,
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));

View File

@@ -709,12 +709,7 @@ which_armor(struct monst *mon, long flag)
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);
@@ -1039,4 +1034,39 @@ racial_exception(struct monst *mon, struct obj *obj)
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*/

View File

@@ -347,7 +347,6 @@ bhitm(struct monst *mtmp, struct obj *otmp)
} else if (canspotmon(mtmp)) {
pline("%s falls off.", buf);
}
obj_extract_self(obj);
mdrop_obj(mtmp, obj, FALSE);
}
break;
@@ -4052,16 +4051,7 @@ disintegrate_mon(struct monst *mon,
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);
}
}