fix B14012 - polymorph of monster possessions

Forwarded from the newsgroup:  when a monster gets hit by wand or
spell of polymorph, any armor that fell off was protected from being
hit by that same zap, but a dropped weapon wasn't.  Nor was the whole
dropped inventory in the case where the monster is killed by system
shock rather than transformed.  Protect its entire inventory.
This commit is contained in:
nethack.rankin
2002-11-08 12:45:58 +00:00
parent 52d1737294
commit e639c09f58
12 changed files with 64 additions and 42 deletions

View File

@@ -301,6 +301,8 @@ don't reveal deity name when a high priest(ess) gives temple entry greeting
for ordinary remove curse, don't uncurse quivered object unless it is suitable
to be used as a quivered weapon (ammo or missile)
salamanders have no legs and cannot ride
all objects carried by a monster who's hit by a polymorph zap are protected
from that zap, not just worn armor which falls off due to shape change
Platform- and/or Interface-Specific Fixes

View File

@@ -2187,7 +2187,7 @@ E int FDECL(hitval, (struct obj *,struct monst *));
E int FDECL(dmgval, (struct obj *,struct monst *));
E struct obj *FDECL(select_rwep, (struct monst *));
E struct obj *FDECL(select_hwep, (struct monst *));
E void FDECL(possibly_unwield, (struct monst *));
E void FDECL(possibly_unwield, (struct monst *,BOOLEAN_P));
E int FDECL(mon_wield_item, (struct monst *));
E int NDECL(abon);
E int NDECL(dbon);

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)apply.c 3.4 2002/09/25 */
/* SCCS Id: @(#)apply.c 3.4 2002/11/07 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -2248,7 +2248,7 @@ struct obj *obj;
}
if (gotit) {
obj_extract_self(otmp);
possibly_unwield(mtmp);
possibly_unwield(mtmp, FALSE);
setmnotwielded(mtmp,otmp);
switch (rn2(proficient + 1)) {

View File

@@ -201,6 +201,7 @@ struct obj *corpse;
/* caller has already checked `can_make_bones()' */
clear_bypasses();
fd = open_bonesfile(&u.uz, &bonesid);
if (fd >= 0) {
(void) close(fd);

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)mhitm.c 3.4 2002/10/17 */
/* SCCS Id: @(#)mhitm.c 3.4 2002/11/07 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -242,7 +242,7 @@ mattackm(magr, mdef)
magr->weapon_check = NEED_HTH_WEAPON;
if (mon_wield_item(magr) != 0) return 0;
}
possibly_unwield(magr);
possibly_unwield(magr, FALSE);
otmp = MON_WEP(magr);
if (otmp) {
@@ -1011,7 +1011,7 @@ label2: if (mdef->mhp > 0) return 0;
pline("%s steals %s from %s!", buf,
onambuf, mdefnambuf);
}
possibly_unwield(mdef);
possibly_unwield(mdef, FALSE);
mdef->mstrategy &= ~STRAT_WAITFORU;
mselftouch(mdef, (const char *)0, FALSE);
if (mdef->mhp <= 0)

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)mon.c 3.4 2002/04/06 */
/* SCCS Id: @(#)mon.c 3.4 2002/11/07 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -2459,11 +2459,11 @@ boolean msg; /* "The oldmon turns into a newmon!" */
mtmp->mnamelth = save_mnamelth;
}
possibly_unwield(mtmp, polyspot); /* might lose use of weapon */
mon_break_armor(mtmp, polyspot);
if (!(mtmp->misc_worn_check & W_ARMG))
mselftouch(mtmp, "No longer petrify-resistant, ",
!flags.mon_moving);
possibly_unwield(mtmp);
m_dowear(mtmp, FALSE);
/* This ought to re-test can_carry() on each item in the inventory

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)mthrowu.c 3.4 2002/09/08 */
/* SCCS Id: @(#)mthrowu.c 3.4 2002/11/07 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -489,7 +489,7 @@ struct obj *obj;
obj->owt = weight(obj);
} else {
obj_extract_self(obj);
possibly_unwield(mon);
possibly_unwield(mon, FALSE);
if (obj->owornmask) {
mon->misc_worn_check &= ~obj->owornmask;
update_mon_intrinsics(mon, obj, FALSE, FALSE);

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)uhitm.c 3.4 2002/10/17 */
/* SCCS Id: @(#)uhitm.c 3.4 2002/11/07 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1154,7 +1154,7 @@ struct attack *mattk;
}
/* more take-away handling, after theft message */
if (unwornmask & W_WEP) { /* stole wielded weapon */
possibly_unwield(mdef);
possibly_unwield(mdef, FALSE);
} else if (unwornmask & W_ARMG) { /* stole worn gloves */
mselftouch(mdef, (const char *)0, TRUE);
if (mdef->mhp <= 0) /* it's now a statue */

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)weapon.c 3.4 2002/03/22 */
/* SCCS Id: @(#)weapon.c 3.4 2002/11/07 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -527,18 +527,18 @@ register struct monst *mtmp;
}
/* Called after polymorphing a monster, robbing it, etc.... Monsters
* otherwise never unwield stuff on their own. Shouldn't print messages.
* otherwise never unwield stuff on their own. Might print message.
*/
void
possibly_unwield(mon)
register struct monst *mon;
possibly_unwield(mon, polyspot)
struct monst *mon;
boolean polyspot;
{
register struct obj *obj;
struct obj *mw_tmp;
struct obj *obj, *mw_tmp;
if (!(mw_tmp = MON_WEP(mon)))
return;
for(obj=mon->minvent; obj; obj=obj->nobj)
for (obj = mon->minvent; obj; obj = obj->nobj)
if (obj == mw_tmp) break;
if (!obj) { /* The weapon was stolen or destroyed */
MON_NOWEP(mon);
@@ -550,13 +550,16 @@ register struct monst *mon;
MON_NOWEP(mon);
mon->weapon_check = NO_WEAPON_WANTED;
obj_extract_self(obj);
/* flooreffects unnecessary, can't wield boulders */
place_object(obj, mon->mx, mon->my);
stackobj(obj);
if (cansee(mon->mx, mon->my)) {
pline("%s drops %s.", Monnam(mon),
distant_name(obj, doname));
newsym(mon->mx, mon->my);
pline("%s drops %s.", Monnam(mon),
distant_name(obj, doname));
newsym(mon->mx, mon->my);
}
/* might be dropping object into water or lava */
if (!flooreffects(obj, mon->mx, mon->my, "drop")) {
if (polyspot) bypass_obj(obj);
place_object(obj, mon->mx, mon->my);
stackobj(obj);
}
return;
}
@@ -575,6 +578,7 @@ register struct monst *mon;
*/
if (!(mw_tmp->cursed && mon->weapon_check == NO_WEAPON_WANTED))
mon->weapon_check = NEED_WEAPON;
return;
}
/* Let a monster try to wield a weapon, based on mon->weapon_check.

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)were.c 3.4 1997/05/25 */
/* SCCS Id: @(#)were.c 3.4 2002/11/07 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -83,7 +83,7 @@ register struct monst *mon;
mon->mhp += (mon->mhpmax - mon->mhp) / 4;
newsym(mon->mx,mon->my);
mon_break_armor(mon, FALSE);
possibly_unwield(mon);
possibly_unwield(mon, FALSE);
}
boolean

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)worn.c 3.4 2002/09/08 */
/* SCCS Id: @(#)worn.c 3.4 2002/11/07 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -519,35 +519,49 @@ struct obj *obj;
newsym(mon->mx, mon->my);
}
/* all objects with their bypass bit set should now be reset to normal */
void
clear_bypasses()
{
struct obj *otmp, *nobj;
struct monst *mtmp;
for (otmp = fobj; otmp; otmp = nobj) {
nobj = otmp->nobj;
if (otmp->bypass) {
otmp->bypass = 0;
/* bypass will have inhibited any stacking, but since it's
used for polymorph handling, the objects here probably
have been transformed and won't be stacked in the usual
manner afterwards; so don't bother with this */
#if 0
/* setting otmp->bypass changes mergability.
* If monster can ever drop anything that
* can and should merge, this code block
* should be enabled.
*/
{
if (otmp->where == OBJ_FLOOR) {
struct obj *obj;
xchar ox, oy;
(void) get_obj_location(otmp, &ox, &oy, 0);
obj_extract_self(otmp);
obj = merge_choice(fobj, otmp);
/* If it can't merge, then place it */
if (!obj || (obj && !merged(&obj, &otmp)))
obj = merge_choice(level.objects[ox][oy], otmp);
/* if it doesn't merge then place it back */
if (!obj || !merged(&obj, &otmp))
place_object(otmp, ox, oy);
newsym(ox, oy);
}
#endif
#endif /*0*/
}
}
/* invent and mydogs chains shouldn't matter here */
for (otmp = migrating_objs; otmp; otmp = otmp->nobj)
otmp->bypass = 0;
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp)) continue;
for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
otmp->bypass = 0;
}
for (mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon) {
for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
otmp->bypass = 0;
}
flags.bypasses = FALSE;
}
@@ -647,11 +661,11 @@ boolean polyspot;
#endif
}
if (nohands(mdat) || verysmall(mdat)) {
/* [caller needs to handle weapon checks] */
if ((otmp = which_armor(mon, W_ARMG)) != 0) {
if (vis)
pline("%s drops %s gloves%s!", Monnam(mon), ppronoun,
MON_WEP(mon) ? " and weapon" : "");
possibly_unwield(mon);
if (polyspot) bypass_obj(otmp);
m_lose_armor(mon, otmp);
}

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)zap.c 3.4 2002/09/08 */
/* SCCS Id: @(#)zap.c 3.4 2002/11/07 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -109,9 +109,7 @@ struct obj *otmp;
boolean dbldam = Role_if(PM_KNIGHT) && u.uhave.questart;
int dmg, otyp = otmp->otyp;
const char *zap_type_text = "spell";
#ifdef STEED
struct obj *obj;
#endif
boolean disguised_mimic = (mtmp->data->mlet == S_MIMIC &&
mtmp->m_ap_type != M_AP_NOTHING);
@@ -189,6 +187,9 @@ struct obj *otmp;
pline("%s shudders!", Monnam(mtmp));
makeknown(otyp);
}
/* dropped inventory shouldn't be hit by this zap */
for (obj = mtmp->minvent; obj; obj = obj->nobj)
bypass_obj(obj);
/* flags.bypasses = TRUE; ## for make_corpse() */
/* no corpse after system shock */
xkilled(mtmp, 3);