]> granicus.if.org Git - nethack/commitdiff
fix #Q404 - monster wielding cursed corpse
authornethack.rankin <nethack.rankin>
Sat, 10 Feb 2007 05:14:22 +0000 (05:14 +0000)
committernethack.rankin <nethack.rankin>
Sat, 10 Feb 2007 05:14:22 +0000 (05:14 +0000)
     From a bug report, applying a bullwhip
towards a monster to try to steal its weapon would report that a cursed
cockatrice corpse was welded to the monster's hands even though corpses
wielded by the player never become welded.  Code for monsters deciding
what to wield knew that corpses don't weld; everywhere else seems to
assume that they only wield weldable weapons.  Add a routine to check
whether a wielded item is welded, similar to what's done for the hero.  I
fixed a couple of other spots besides use_whip() but didn't hunt all over.

doc/fixes34.4
include/extern.h
src/apply.c
src/muse.c
src/weapon.c
src/wield.c

index 02316e4951d7cf2a34ffcfa4f1c9d4e06ef7c91f..6faeacc733bd82fbf3654498fa5db2ea648ae147 100644 (file)
@@ -315,6 +315,7 @@ shapechangers who take on mimic or hider form will mimic or hide when feasible
 avoid War message if tinning a Rider corpse fails
 prevent long messages from triggering access violation or segmentation fault
        due to buffer overflow in pline()
+cursed corpse wielded by a monster isn't welded to its hand or paw
 
 
 Platform- and/or Interface-Specific Fixes
index b4cd4761021f53a0109c74d261c3e87103ea4352..4a3320078b48e46aa6bc4ee21fac81ea44576f45 100644 (file)
@@ -2510,6 +2510,7 @@ E int FDECL(chwepon, (struct obj *,int));
 E int FDECL(welded, (struct obj *));
 E void FDECL(weldmsg, (struct obj *));
 E void FDECL(setmnotwielded, (struct monst *,struct obj *));
+E boolean FDECL(mwelded, (struct obj *));
 
 /* ### windows.c ### */
 
index e114a914a7a32bb335a53fa0d18d6d00e226104c..ef080c525f95077e6888fa9b47f29bffc2ba39df 100644 (file)
@@ -2397,7 +2397,7 @@ struct obj *obj;
                mon_hand = 0;   /* lint suppression */
 
            You("wrap your bullwhip around %s.", yname(otmp));
-           if (gotit && otmp->cursed) {
+           if (gotit && mwelded(otmp)) {
                pline("%s welded to %s %s%c",
                      (otmp->quan == 1L) ? "It is" : "They are",
                      mhis(mtmp), mon_hand,
index f9e96b4a0b857e937716df814447c30208b3158e..a8466ad42a11d56a054d97ed850307c5beb994a9 100644 (file)
@@ -2210,19 +2210,21 @@ mcould_eat_tin(mon)
 struct monst *mon;
 {
        struct obj *obj, *mwep;
+       boolean welded_wep;
 
        /* monkeys who manage to steal tins can't open and eat them
           even if they happen to also have the appropriate tool */
        if (is_animal(mon->data)) return FALSE;
 
        mwep = MON_WEP(mon);
+       welded_wep = mwep && mwelded(mwep);
        /* this is different from the player; tin opener or dagger doesn't
           have to be wielded, and knife can be used instead of dagger
           (even so, non-nymphs don't pick up tins, so only nymphs might
           end up being able to benefit from them) */
        for (obj = mon->minvent; obj; obj = obj->nobj) {
            /* if stuck with a cursed weapon, don't check rest of inventory */
-           if (mwep && mwep->cursed && obj != mwep) continue;
+           if (welded_wep && obj != mwep) continue;
 
            if (obj->otyp == TIN_OPENER ||
                (obj->oclass == WEAPON_CLASS &&
index cc148852fb3262082fc472294f616a23c6c7b19c..1127d0ddd0bb00797a1a2d62e40f9282dfc8711d 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)weapon.c   3.5     2006/12/14      */
+/*     SCCS Id: @(#)weapon.c   3.5     2007/02/09      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -458,7 +458,7 @@ register struct monst *mtmp;
                case P_CROSSBOW:
                  propellor = (oselect(mtmp, CROSSBOW));
                }
-               if ((otmp = MON_WEP(mtmp)) && otmp->cursed && otmp != propellor
+               if ((otmp = MON_WEP(mtmp)) && mwelded(otmp) && otmp != propellor
                                && mtmp->weapon_check == NO_WEAPON_WANTED)
                        propellor = 0;
            }
@@ -474,7 +474,7 @@ register struct monst *mtmp;
                if (rwep[i] != LOADSTONE) {
                        /* Don't throw a cursed weapon-in-hand or an artifact */
                        if ((otmp = oselect(mtmp, rwep[i])) && !otmp->oartifact
-                           && (!otmp->cursed || otmp != MON_WEP(mtmp)))
+                           && !(otmp == MON_WEP(mtmp) && mwelded(otmp)))
                                return(otmp);
                } else for(otmp=mtmp->minvent; otmp; otmp=otmp->nobj) {
                    if (otmp->otyp == LOADSTONE && !otmp->cursed)
@@ -592,7 +592,7 @@ boolean polyspot;
         * polymorphed into little monster.  But it's not quite clear how to
         * handle this anyway....
         */
-       if (!(mw_tmp->cursed && mon->weapon_check == NO_WEAPON_WANTED))
+       if (!(mwelded(mw_tmp) && mon->weapon_check == NO_WEAPON_WANTED))
            mon->weapon_check = NEED_WEAPON;
        return;
 }
@@ -653,7 +653,7 @@ register struct monst *mon;
                 * can know it's cursed and needn't even bother trying.
                 * Still....
                 */
-               if (mw_tmp && mw_tmp->cursed && mw_tmp->otyp != CORPSE) {
+               if (mw_tmp && mwelded(mw_tmp)) {
                    if (canseemon(mon)) {
                        char welded_buf[BUFSZ];
                        const char *mon_hand = mbodypart(mon, HAND);
@@ -684,7 +684,7 @@ register struct monst *mon;
                mon->weapon_check = NEED_WEAPON;
                if (canseemon(mon)) {
                    pline("%s wields %s!", Monnam(mon), doname(obj));
-                   if (obj->cursed && obj->otyp != CORPSE) {
+                   if (mwelded(mw_tmp)) {
                        pline("%s %s to %s %s!",
                            Tobjnam(obj, "weld"),
                            is_plural(obj) ? "themselves" : "itself",
index 3a4883e0af323181775eb4fdc09eab3e3247c922..c0ac0319225db8b21ed5eaf2adc8de8e37169dc1 100644 (file)
@@ -855,4 +855,14 @@ register struct obj *obj;
        obj->owornmask = savewornmask;
 }
 
+/* test whether monster's wielded weapon is stuck to hand/paw/whatever */
+boolean
+mwelded(obj)
+struct obj *obj;
+{
+    /* caller is responsible for making sure this is a monster's item */
+    if (obj && (obj->owornmask & W_WEP) && will_weld(obj)) return TRUE;
+    return FALSE;
+}
+
 /*wield.c*/