]> granicus.if.org Git - nethack/commitdiff
fix B14012 - polymorph of monster possessions
authornethack.rankin <nethack.rankin>
Fri, 8 Nov 2002 12:45:58 +0000 (12:45 +0000)
committernethack.rankin <nethack.rankin>
Fri, 8 Nov 2002 12:45:58 +0000 (12:45 +0000)
     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.

12 files changed:
doc/fixes34.1
include/extern.h
src/apply.c
src/bones.c
src/mhitm.c
src/mon.c
src/mthrowu.c
src/uhitm.c
src/weapon.c
src/were.c
src/worn.c
src/zap.c

index 2120876e3238b220d96cd595d8a0945e02f79124..5ed827fed2bff1bb852030f70552cc4625eb7f7d 100644 (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
index f97d06de1e671e2b61f1382c69f29fa9a554054e..0bf4a7a6b046384b490fa732885ba631a35450c8 100644 (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);
index 2b6ec335f3834e01b131b170338c667117535261..82b7a7003c9d29471e9f9a3c05017a048254f410 100644 (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)) {
index b01eb643db6151333c6702a15160d69622a5edc1..e4bd22837325a268f24c25c76e26ca89a678ed4e 100644 (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);
index 593ad5606bf3f1f314fb9a1c1b6831105ae99f5c..5bf713dc56b6f6aa6024bfe333f50dabfb8aff3b 100644 (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)
index c2a51f53e512c41734b3b56971f34f8d588243a0..b2b858be892d2e11d626acb6e7c663235691cfec 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -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
index b2a979aacc3b7af13f96bb5420971d3e3f19309d..e368b0994dd0f6085227695d27bc74c042d28d00 100644 (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);
index 017e11ebdb2a74a496c119a6f6fcc2f4a2a69ebe..49880d9aa76290a1335b36766ae84193fdf13011 100644 (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 */
index 9089f798362533777fb1d752ce04507fd70ccff1..b3ff14ee540f1923e2dad86010ee0827df1b785f 100644 (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.
index 97c91112bf9699f09fd87d14383b6baf671c4c29..933fdde321e07dc121faf571fcb24831d44989b6 100644 (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
index 1e646aa88da17c76640e1a54e4c05f49b43cd6b4..1078d9a9eb6ca704516df3b70955492cff079a66 100644 (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);
            }
index 00f87fd3e69b99f62fe7564769bc048e89e25cf9..465834cdfe00115ca880353658634ebde1b62cbe 100644 (file)
--- a/src/zap.c
+++ b/src/zap.c
@@ -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);