From 624a1b31d90abcea315675e09e0dbc1c43708330 Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Fri, 13 Oct 2006 05:39:16 +0000 Subject: [PATCH] surviving petrification (trunk only) 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 | 1 + include/extern.h | 1 + src/mhitm.c | 3 +-- src/trap.c | 19 +++++++++++++++---- src/weapon.c | 14 ++++++++++++++ 5 files changed, 32 insertions(+), 6 deletions(-) diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 8ac0e3f9e..5c7441d92 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -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 diff --git a/include/extern.h b/include/extern.h index d7040a0e1..cc75d0bd1 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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); diff --git a/src/mhitm.c b/src/mhitm.c index fbc35a5a4..4f2d3bca8 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -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); } diff --git a/src/trap.c b/src/trap.c index 198524d00..f339b4520 100644 --- a/src/trap.c +++ b/src/trap.c @@ -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); } } diff --git a/src/weapon.c b/src/weapon.c index e2345b119..23b78086d 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -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 */ { -- 2.40.0