]> granicus.if.org Git - nethack/commitdiff
surviving petrification (trunk only)
authornethack.rankin <nethack.rankin>
Fri, 13 Oct 2006 05:39:16 +0000 (05:39 +0000)
committernethack.rankin <nethack.rankin>
Fri, 13 Oct 2006 05:39:16 +0000 (05:39 +0000)
     From the newsgroup:  if you were wielding a cockatrice corpse without
gloves while polymorphed into something capable of doing that, then were
turned to stone when rehumanizing, you'd be left wielding the untouchable
corpse if life-saving kept the game going.  This causes it to stop being
wielded if you get that far.  Likewise for monsters.

doc/fixes35.0
include/extern.h
src/mhitm.c
src/trap.c
src/weapon.c

index 8ac0e3f9ea404bf498ebdca8c5041ea4bbb380ae..5c7441d9216c5cbea61ec8681a0292e6dd594524 100644 (file)
@@ -164,6 +164,7 @@ getting a particular rotten food result can't make attempting to eat a
        corpse of one of the Riders be survivable
 pad shortest rumors to improve distribution of delivered rumors
 wake up sleeping steed when putting on saddle or mounting
+stop wielding cockatrice corpse which triggered own death followed by life-save
 
 
 Platform- and/or Interface-Specific Fixes
index d7040a0e1633eda21e00b02f264338bebdf88ab6..cc75d0bd19a7bfcccdfe3abfc75b79565b71517a 100644 (file)
@@ -2430,6 +2430,7 @@ 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 *,BOOLEAN_P));
+E void FDECL(mwepgone, (struct monst *));
 E int FDECL(mon_wield_item, (struct monst *));
 E int NDECL(abon);
 E int NDECL(dbon);
index fbc35a5a4507d704a63a18d1241a7ca180b66f8d..4f2d3bca8e4683810479cf19a52e1acf7eb748ac 100644 (file)
@@ -1130,8 +1130,7 @@ mdamagem(magr, mdef, mattk)
                        obj_extract_self(otmp);
                        if (otmp->owornmask) {
                                mdef->misc_worn_check &= ~otmp->owornmask;
-                               if (otmp->owornmask & W_WEP)
-                                   setmnotwielded(mdef,otmp);
+                               if (otmp->owornmask & W_WEP) mwepgone(mdef);
                                otmp->owornmask = 0L;
                                update_mon_intrinsics(mdef, otmp, FALSE, FALSE);
                        }
index 198524d0037952ff58bfc0efbf8a49aaf79af39e..f339b452099323ed9cd5c63cd1ad0074ed5fac46 100644 (file)
@@ -2448,14 +2448,19 @@ const char *arg;
                        mons[uwep->corpsenm].mname);
                Sprintf(kbuf, "%s corpse", an(mons[uwep->corpsenm].mname));
                instapetrify(kbuf);
+               /* life-saved; unwield the corpse if we can't handle it */
+               if (!uarmg && !Stone_resistance) uwepgone();
        }
-       /* Or your secondary weapon, if wielded */
+       /* Or your secondary weapon, if wielded [hypothetical; we don't
+          allow two-weapon combat when either weapon is a corpse] */
        if(u.twoweap && uswapwep && uswapwep->otyp == CORPSE &&
                        touch_petrifies(&mons[uswapwep->corpsenm]) && !Stone_resistance){
                pline("%s touch the %s corpse.", arg,
                        mons[uswapwep->corpsenm].mname);
                Sprintf(kbuf, "%s corpse", an(mons[uswapwep->corpsenm].mname));
                instapetrify(kbuf);
+               /* life-saved; unwield the corpse */
+               if (!uarmg && !Stone_resistance) uswapwepgone();
        }
 }
 
@@ -2467,13 +2472,19 @@ boolean byplayer;
 {
        struct obj *mwep = MON_WEP(mon);
 
-       if (mwep && mwep->otyp == CORPSE && touch_petrifies(&mons[mwep->corpsenm])) {
+       if (mwep && mwep->otyp == CORPSE &&
+                   touch_petrifies(&mons[mwep->corpsenm]) &&
+                   !resists_ston(mon)) {
                if (cansee(mon->mx, mon->my)) {
-                       pline("%s%s touches the %s corpse.",
+                       pline("%s%s touches %s.",
                            arg ? arg : "", arg ? mon_nam(mon) : Monnam(mon),
-                           mons[mwep->corpsenm].mname);
+                           corpse_xname(mwep, (const char *)0, CXN_PFX_THE));
                }
                minstapetrify(mon, byplayer);
+               /* if life-saved, might not be able to continue wielding */
+               if (mon->mhp > 0 && !which_armor(mon, W_ARMG) &&
+                       !resists_ston(mon))
+                   mwepgone(mon);
        }
 }
 
index e2345b1195e0407b443bd66acac851c3ddfb1f9c..23b78086d13953f9a3a2d6dade47e85919056d2d 100644 (file)
@@ -706,6 +706,20 @@ register struct monst *mon;
        return 0;
 }
 
+/* force monster to stop wielding current weapon, if any */
+void
+mwepgone(mon)
+struct monst *mon;
+{
+    struct obj *mwep = MON_WEP(mon);
+
+    if (mwep) {
+       setmnotwielded(mon, mwep);
+       MON_NOWEP(mon);
+       mon->weapon_check = NEED_WEAPON;
+    }
+}
+
 int
 abon()         /* attack bonus for strength & dexterity */
 {