]> granicus.if.org Git - nethack/commitdiff
Cover a couple of corner cases with `rust_dmg()`.
authorSean Hunt <scshunt@csclub.uwaterloo.ca>
Mon, 2 Mar 2015 17:36:33 +0000 (12:36 -0500)
committerSean Hunt <scshunt@csclub.uwaterloo.ca>
Mon, 2 Mar 2015 17:49:57 +0000 (12:49 -0500)
doc/fixes35.0
include/extern.h
include/obj.h
src/trap.c

index 3cc0e61dd598ce7aedcccc4c1de22baa2a877210..4fd81cff5507a4751e728cfc91c485cbaaab68bd 100644 (file)
@@ -858,6 +858,9 @@ fix "object_is_local" panic when saving bones after hero is killed by explosion
 if lava burns up the player's water walking boots, the player falls in
 the messages for lava burning items up are always printed
 fix used-up magic trap trying to hit steed.
+messages are now printed when objects on the ground are eroded
+object erosion now always identifies rust/rot/fire/corrodeproof objects
+grease protects from all types of erosion
 
 
 Platform- and/or Interface-Specific Fixes
index 120f7d506286fc485c5650807a39e66e6f1c6e7a..87427dd3ae6d9ce360b364c01cff33f0b11079ac 100644 (file)
@@ -2204,7 +2204,7 @@ E coord *FDECL(gettrack, (int,int));
 
 E boolean FDECL(burnarmor,(struct monst *));
 E boolean FDECL(rust_dmg, (struct obj *,const char *,int,BOOLEAN_P));
-E void FDECL(grease_protect, (struct obj *,const char *,struct monst *));
+E boolean FDECL(grease_protect, (struct obj *,const char *,struct monst *));
 E struct trap *FDECL(maketrap, (int,int,int));
 E void FDECL(fall_through, (BOOLEAN_P));
 E struct monst *FDECL(animate_statue, (struct obj *,XCHAR_P,XCHAR_P,int,int *));
index dc522b338b139762c9033ed16dffe88bc67a616c..12b1fce356584743dfbecc061e205dd134aad289 100644 (file)
@@ -319,6 +319,12 @@ struct obj {
 #define CONTAINED_TOO  0x1
 #define BURIED_TOO     0x2
 
+/* object erosion types */
+#define ERODE_BURN 0
+#define ERODE_RUST 1
+#define ERODE_ROT 2
+#define ERODE_CORRODE 3
+
 /*
  *  Notes for adding new oextra structures:
  *
index d819724a5c89c6f78292f218d50b5577d8104fc1..1220105f56855836e8db98c2e85aa8e72d4fd0cf 100644 (file)
@@ -101,10 +101,9 @@ struct monst *victim;
 #undef burn_dmg
 }
 
-/* Generic rust-armor function.  Returns TRUE if a message was printed;
- * "print", if set, means to print a message (and thus to return TRUE) even
- * if the item could not be rusted; otherwise a message is printed and TRUE is
- * returned only for rustable items.
+/* Generic erode-item function.  Returns TRUE if any change in state
+ * occurred. "print", if set, means to print a message even if no change
+ * occurs.
  */
 boolean
 rust_dmg(otmp, ostr, type, print)
@@ -119,69 +118,95 @@ boolean print;
        boolean grprot = FALSE;
        boolean is_primary = TRUE;
        int erosion;
-        struct monst *victim =
-            carried(otmp) ? &youmonst : mcarried(otmp) ? otmp->ocarry : NULL;
-       boolean vismon = (victim != &youmonst) && canseemon(victim);
+        struct monst *victim;
+       boolean vismon;
+        boolean visobj;
 
        if (!otmp) return(FALSE);
+
+        victim = carried(otmp) ? &youmonst : mcarried(otmp) ?
+            otmp->ocarry : NULL;
+        vismon = victim && (victim != &youmonst) && canseemon(victim);
+        /* Is bhitpos correct here? Ugh. */
+        visobj = !victim && cansee(bhitpos.x, bhitpos.y);
+
        switch(type) {
-               case 0: vulnerable = is_flammable(otmp);
-                       break;
-               case 1: vulnerable = is_rustprone(otmp);
-                       grprot = TRUE;
-                       break;
-               case 2: vulnerable = is_rottable(otmp);
-                       is_primary = FALSE;
-                       break;
-               case 3: vulnerable = is_corrodeable(otmp);
-                       grprot = TRUE;
-                       is_primary = FALSE;
-                       break;
+               case ERODE_BURN:
+                    vulnerable = is_flammable(otmp);
+                   break;
+               case ERODE_RUST:
+                    vulnerable = is_rustprone(otmp);
+                   grprot = TRUE;
+                   break;
+               case ERODE_ROT:
+                    vulnerable = is_rottable(otmp);
+                   is_primary = FALSE;
+                   break;
+               case ERODE_CORRODE:
+                    vulnerable = is_corrodeable(otmp);
+                   grprot = TRUE;
+                   is_primary = FALSE;
+                   break;
+                default:
+                    impossible("Invalid erosion type in rust_dmg");
+                    return FALSE;
        }
        erosion = is_primary ? otmp->oeroded : otmp->oeroded2;
 
-       if (!print && (!vulnerable || otmp->oerodeproof || erosion == MAX_ERODE))
-               return FALSE;
+        if (!ostr)
+            ostr = cxname(otmp);
 
-       if (!vulnerable) {
-           if (flags.verbose) {
+        if (grprot && otmp->greased) {
+            return grease_protect(otmp, ostr, victim);
+        } else if (!vulnerable || (otmp->oerodeproof && otmp->rknown)) {
+           if (print && flags.verbose) {
                if (victim == &youmonst)
                    Your("%s %s not affected.", ostr, vtense(ostr, "are"));
                else if (vismon)
                    pline("%s's %s %s not affected.", Monnam(victim), ostr,
                          vtense(ostr, "are"));
            }
-       } else if (erosion < MAX_ERODE) {
-           if (grprot && otmp->greased) {
-               grease_protect(otmp,ostr,victim);
-           } else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) {
-               if (flags.verbose) {
-                   if (victim == &youmonst)
-                       pline("Somehow, your %s %s not affected.",
-                             ostr, vtense(ostr, "are"));
-                   else if (vismon)
-                       pline("Somehow, %s's %s %s not affected.",
-                             mon_nam(victim), ostr, vtense(ostr, "are"));
-               }
-           } else {
+            return FALSE;
+        } else if (otmp->oerodeproof || otmp->blessed && !rnl(4)) {
+            if (flags.verbose && (print || otmp->oerodeproof)) {
                if (victim == &youmonst)
-                   Your("%s %s%s!", ostr,
-                        vtense(ostr, action[type]),
-                        erosion+1 == MAX_ERODE ? " completely" :
-                           erosion ? " further" : "");
+                   pline("Somehow, your %s %s not affected.",
+                         ostr, vtense(ostr, "are"));
                else if (vismon)
-                   pline("%s's %s %s%s!", Monnam(victim), ostr,
-                       vtense(ostr, action[type]),
-                       erosion+1 == MAX_ERODE ? " completely" :
-                         erosion ? " further" : "");
-               if (is_primary)
-                   otmp->oeroded++;
-               else
-                   otmp->oeroded2++;
-               update_inventory();
-           }
+                   pline("Somehow, %s's %s %s not affected.",
+                         mon_nam(victim), ostr, vtense(ostr, "are"));
+                else if (visobj)
+                    pline("Somehow, the %s %s not affected." ostr,
+                          vtense(ostr, "are"));
+            }
+            /* We assume here that if the object is protected because it
+             * is blessed, it still shows some minor signs of wear, and
+             * the hero can distinguish this from an object that is
+             * actually proof against damage. */
+            if (otmp->oerodeproof)
+                otmp->rknown = TRUE;
+            return FALSE;
+       } else if (erosion < MAX_ERODE) {
+            const char *adverb = (erosion + 1 == MAX_ERODE) ?
+                " complete" : erosion ? " further" : "";
+
+            if (victim == &youmonst)
+                Your("%s %s%s!", ostr, vtense(ostr, action[type]), adverb);
+            else if (vismon)
+                pline("%s's %s %s%s!", Monnam(victim), ostr,
+                      vtense(ostr, action[type]), adverb);
+            else if (visobj)
+                pline("The %s %s%s!", ostr, vtense(ostr, action[type]), adverb);
+
+            if (is_primary)
+                otmp->oeroded++;
+            else
+                otmp->oeroded2++;
+
+            update_inventory();
+            return TRUE;
        } else {
-           if (flags.verbose) {
+           if (flags.verbose && print) {
                if (victim == &youmonst)
                    Your("%s %s completely %s.", ostr,
                         vtense(ostr, Blind ? "feel" : "look"),
@@ -190,12 +215,18 @@ boolean print;
                    pline("%s's %s %s completely %s.",
                          Monnam(victim), ostr,
                          vtense(ostr, "look"), msg[type]);
+                else if (visobj)
+                    pline("The %s %s completely %s.", ostr,
+                          vtense(ostr, "look"), msg[type]);
            }
+            return FALSE;
        }
-       return(TRUE);
 }
 
-void
+/* Protect an item from erosion with grease. Returns TRUE if the grease
+ * wears off.
+ */
+boolean
 grease_protect(otmp,ostr,victim)
 register struct obj *otmp;
 register const char *ostr;
@@ -219,7 +250,9 @@ struct monst *victim;
                pline_The("grease dissolves.");
                update_inventory();
            }
+            return TRUE;
        }
+        return FALSE;
 }
 
 struct trap *