]> granicus.if.org Git - nethack/commitdiff
Eliminate `erode_obj()` and other erosion.
authorSean Hunt <scshunt@csclub.uwaterloo.ca>
Tue, 24 Feb 2015 20:20:01 +0000 (15:20 -0500)
committerSean Hunt <scshunt@csclub.uwaterloo.ca>
Mon, 2 Mar 2015 17:50:00 +0000 (12:50 -0500)
Now all erosion that isn't fire-based goes through `rust_dmg()`

doc/fixes35.0
include/extern.h
src/mhitm.c
src/mhitu.c
src/potion.c
src/spell.c
src/trap.c
src/uhitm.c
src/wield.c
src/zap.c

index 48da8da363f8d652083d096e118252c6ceb458bf..9dc59fa6604440a49b6a4c7e0ce06b4d6ba9f1e7 100644 (file)
@@ -859,9 +859,11 @@ 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
+object erosion now always identifies fooproof objects
 grease protects from all types of erosion
 all sources of erosion now affect objects the same way
+passive attacks no longer erode armor covered by other armor
+dipping a fooproof item into acid no longer forgets that it's fooproof
 
 
 Platform- and/or Interface-Specific Fixes
index 87d3adee7f2185fcf7ef2f1801faa0f580fca6c1..6ca49b411fa5c6ca75ca79f88ef888d2613b695c 100644 (file)
@@ -1070,6 +1070,7 @@ E int FDECL(sleep_monst, (struct monst *,int,int));
 E void FDECL(slept_monst, (struct monst *));
 E void FDECL(xdrainenergym, (struct monst *,BOOLEAN_P));
 E long FDECL(attk_protection, (int));
+E void FDECL(rustm, (struct monst *,struct obj *));
 
 /* ### mhitu.c ### */
 
@@ -2222,6 +2223,7 @@ E void FDECL(fill_pit, (int,int));
 E int FDECL(float_down, (long, long));
 E void NDECL(climb_pit);
 E int FDECL(fire_damage, (struct obj *,BOOLEAN_P,BOOLEAN_P,XCHAR_P,XCHAR_P));
+E void acid_damage(struct obj *);
 E int FDECL(water_damage, (struct obj *,const char*,BOOLEAN_P));
 E void FDECL(water_damage_chain, (struct obj *,BOOLEAN_P));
 E boolean NDECL(drown);
@@ -2516,7 +2518,6 @@ E void NDECL(uwepgone);
 E void NDECL(uswapwepgone);
 E void NDECL(uqwepgone);
 E void NDECL(untwoweapon);
-E boolean FDECL(erode_obj, (struct obj *,int,BOOLEAN_P,BOOLEAN_P));
 E int FDECL(chwepon, (struct obj *,int));
 E int FDECL(welded, (struct obj *));
 E void FDECL(weldmsg, (struct obj *));
index ae66279e7030f65d3ab84e531e07d728fcabeb2b..31c9dba1163d8f75d8d1b0e6cced40bdb007d2e1 100644 (file)
@@ -16,7 +16,6 @@ static const char brief_feeling[] =
        "have a %s feeling for a moment, then it passes.";
 
 STATIC_DCL char *FDECL(mon_nam_too, (char *,struct monst *,struct monst *));
-STATIC_DCL void FDECL(mrustm, (struct monst *, struct monst *, struct obj *));
 STATIC_DCL int FDECL(hitmm, (struct monst *,struct monst *,struct attack *));
 STATIC_DCL int FDECL(gazemm, (struct monst *,struct monst *,struct attack *));
 STATIC_DCL int FDECL(gulpmm, (struct monst *,struct monst *,struct attack *));
@@ -796,7 +795,7 @@ mdamagem(magr, mdef, mattk)
                                        (grow_up(magr,mdef) ? 0 : MM_AGR_DIED));
                        }
                        if (tmp)
-                               mrustm(magr, mdef, otmp);
+                               rustm(mdef, otmp);
                    }
                } else if (pa == &mons[PM_PURPLE_WORM] &&
                            pd == &mons[PM_SHRIEKER]) {
@@ -884,7 +883,7 @@ mdamagem(magr, mdef, mattk)
                    pline("It burns %s!", mon_nam(mdef));
                }
                if (!rn2(30)) erode_armor(mdef, ERODE_CORRODE);
-               if (!rn2(6)) (void) erode_obj(MON_WEP(mdef), 3, TRUE, FALSE);
+               if (!rn2(6)) acid_damage(MON_WEP(mdef));
                break;
            case AD_RUST:
                if (magr->mcan) break;
@@ -1287,24 +1286,24 @@ struct monst *mon;
        }
 }
 
-STATIC_OVL void
-mrustm(magr, mdef, obj)
-register struct monst *magr, *mdef;
+void
+rustm(mdef, obj)
+register struct monst *mdef;
 register struct obj *obj;
 {
        int dmgtyp;
 
-       if (!magr || !mdef || !obj) return; /* just in case */
+       if (!mdef || !obj) return; /* just in case */
        /* AD_ACID is handled in passivemm */
        if (dmgtype(mdef->data, AD_CORR))
-           dmgtyp = 3;
+           dmgtyp = ERODE_CORRODE;
        else if (dmgtype(mdef->data, AD_RUST))
-           dmgtyp = 1;
+           dmgtyp = ERODE_RUST;
        else if (dmgtype(mdef->data, AD_FIRE))
-           dmgtyp = 0;
+           dmgtyp = ERODE_BURN;
        else
            return;
-       (void) erode_obj(obj, dmgtyp, FALSE, FALSE);
+       (void) rust_dmg(obj, 0, dmgtyp, TRUE, TRUE);
 }
 
 STATIC_OVL void
@@ -1362,7 +1361,7 @@ int mdead;
                    }
                } else tmp = 0;
                if (!rn2(30)) erode_armor(magr, ERODE_CORRODE);
-               if (!rn2(6)) (void)erode_obj(MON_WEP(magr), 3, TRUE, FALSE);
+               if (!rn2(6)) acid_damage(MON_WEP(magr));
                goto assess_dmg;
            case AD_ENCH:       /* KMH -- remove enchantment (disenchanter) */
                if (mhit && !mdef->mcan && otmp) {
index cc9b6f1be5438a3e1f21f524d3dc641a9a596106..6aa4225f7303cf1a54b1bc30d049c5042a19f9d4 100644 (file)
@@ -8,7 +8,6 @@
 
 STATIC_VAR NEARDATA struct obj *otmp;
 
-STATIC_DCL void FDECL(urustm, (struct monst *, struct obj *));
 STATIC_DCL boolean FDECL(u_slip_free, (struct monst *,struct attack *));
 STATIC_DCL int FDECL(passiveum, (struct permonst *,struct monst *,struct attack *));
 
@@ -920,7 +919,7 @@ hitmu(mtmp, mattk)
                            if (cloneu())
                                You("divide as %s hits you!", mon_nam(mtmp));
                        }
-                       urustm(mtmp, otmp);
+                       rustm(&youmonst, otmp);
                    } else if (mattk->aatyp != AT_TUCH || dmg != 0 ||
                                mtmp != u.ustuck)
                        hitmsg(mtmp, mattk);
@@ -2079,26 +2078,6 @@ register int n;
        }
 }
 
-STATIC_OVL void
-urustm(mon, obj)
-register struct monst *mon;
-register struct obj *obj;
-{
-       int dmgtyp;
-
-       if (!mon || !obj) return; /* just in case */
-       /* AD_ACID is handled in passiveum */
-       if (dmgtype(youmonst.data, AD_CORR))
-           dmgtyp = 3;
-       else if (dmgtype(youmonst.data, AD_RUST))
-           dmgtyp = 1;
-       else if (dmgtype(youmonst.data, AD_FIRE))
-           dmgtyp = 0;
-       else
-           return;
-       (void) erode_obj(obj, dmgtyp, FALSE, FALSE);
-}
-
 int
 could_seduce(magr,mdef,mattk)
 struct monst *magr, *mdef;
@@ -2442,7 +2421,7 @@ register struct attack *mattk;
                    }
                } else tmp = 0;
                if (!rn2(30)) erode_armor(mtmp, ERODE_CORRODE);
-               if (!rn2(6)) (void)erode_obj(MON_WEP(mtmp), 3, TRUE, FALSE);
+               if (!rn2(6)) acid_damage(MON_WEP(mtmp));
                goto assess_dmg;
            case AD_STON: /* cockatrice */
            {
index 7542ea4512a0be5ada48497e2fac22d3e73cf13c..483544c2bb8a3c2b633f5fb4b8ffe2ce11d6867f 100644 (file)
@@ -1931,7 +1931,7 @@ dodip()
        }
 
        if (potion->otyp == POT_ACID) {
-           if (erode_obj(obj, 3, FALSE, TRUE))
+           if (rust_dmg(obj, 0, ERODE_CORRODE, TRUE, FALSE))
                goto poof;
        }
 
index e1f6fc55be65c0eff3a8b1e3baa490c96271a829..5d499bf73ae78ca430be7e92715a56c8cebd3d4c 100644 (file)
@@ -144,21 +144,7 @@ cursed_book(bp)
        case 5:
                pline_The("book was coated with contact poison!");
                if (uarmg) {
-                   if (uarmg->oerodeproof || !is_corrodeable(uarmg)) {
-                       Your("gloves seem unaffected.");
-                   } else if (uarmg->oeroded2 < MAX_ERODE) {
-                       if (uarmg->greased) {
-                           grease_protect(uarmg, "gloves", &youmonst);
-                       } else {
-                           Your("gloves corrode%s!",
-                                uarmg->oeroded2+1 == MAX_ERODE ?
-                                " completely" : uarmg->oeroded2 ?
-                                " further" : "");
-                           uarmg->oeroded2++;
-                       }
-                   } else
-                       Your("gloves %s completely corroded.",
-                            Blind ? "feel" : "look");
+                    rust_dmg(uarmg, "gloves", ERODE_CORRODE, TRUE, TRUE);
                    break;
                }
                /* temp disable in_use; death should not destroy the book */
index f6266791fe28ec04d173fc8965a5d66cce2b9275..f78b7ad66df0c5e0a3d9049d550a97a8436e0727 100644 (file)
@@ -103,6 +103,8 @@ struct monst *victim;
 
 /* Generic erode-item function.  Returns TRUE if any change in state
  * occurred, or if grease protected the item.
+ * "ostr", if non-null, is an alternate string to print instead of the
+ *   object's name.
  * "check_grease", if FALSE, means that grease is not checked for
  * "print", if set, means to print a message even if no change occurs.
  */
@@ -165,8 +167,8 @@ boolean print;
                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"));
+                   pline("%s %s %s not affected.", s_suffix(Monnam(victim)),
+                          ostr, vtense(ostr, "are"));
            }
             return FALSE;
         } else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) {
@@ -175,8 +177,9 @@ boolean print;
                    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"));
+                   pline("Somehow, %s %s %s not affected.",
+                         s_suffix(mon_nam(victim)), ostr,
+                          vtense(ostr, "are"));
                 else if (visobj)
                     pline("Somehow, the %s %s not affected.", ostr,
                           vtense(ostr, "are"));
@@ -214,8 +217,8 @@ boolean print;
                         vtense(ostr, Blind ? "feel" : "look"),
                         msg[type]);
                else if (vismon)
-                   pline("%s's %s %s completely %s.",
-                         Monnam(victim), ostr,
+                   pline("%s %s %s completely %s.",
+                         s_suffix(Monnam(victim)), ostr,
                          vtense(ostr, "look"), msg[type]);
                 else if (visobj)
                     pline("The %s %s completely %s.", ostr,
@@ -952,8 +955,8 @@ unsigned trflags;
                        if (water_damage(uarms, "shield", TRUE))
                            break;
                        if (u.twoweap || (uwep && bimanual(uwep)))
-                           (void) erode_obj(u.twoweap ? uswapwep : uwep,
-                                            1, TRUE, FALSE);
+                           (void) water_damage(u.twoweap ? uswapwep : uwep, 0,
+                                               TRUE);
 glovecheck:            (void) water_damage(uarmg, "gauntlets", TRUE);
                        /* Not "metal gauntlets" since it gets called
                         * even if it's leather for the message
@@ -962,7 +965,7 @@ glovecheck:         (void) water_damage(uarmg, "gauntlets", TRUE);
                    case 2:
                        pline("%s your right %s!", A_gush_of_water_hits,
                                    body_part(ARM));
-                       (void) erode_obj(uwep, 1, TRUE, FALSE);
+                       (void) water_damage(uwep, 0, TRUE);
                        goto glovecheck;
                    default:
                        pline("%s you!", A_gush_of_water_hits);
@@ -2098,7 +2101,7 @@ register struct monst *mtmp;
                                break;
                            target = MON_WEP(mtmp);
                            if (target && bimanual(target))
-                               (void) erode_obj(target, 1, TRUE, FALSE);
+                               (void) water_damage(target, 0, TRUE);
 glovecheck:                target = which_armor(mtmp, W_ARMG);
                            (void) water_damage(target, "gauntlets", TRUE);
                            break;
@@ -2106,7 +2109,7 @@ glovecheck:                   target = which_armor(mtmp, W_ARMG);
                            if (in_sight)
                                pline("%s %s's right %s!", A_gush_of_water_hits,
                                    mon_nam(mtmp), mbodypart(mtmp, ARM));
-                           (void) erode_obj(MON_WEP(mtmp), 1, TRUE, FALSE);
+                           (void) water_damage(MON_WEP(mtmp), 0, TRUE);
                            goto glovecheck;
                        default:
                            if (in_sight)
@@ -3069,6 +3072,38 @@ xchar x, y;
     return retval;
 }
 
+void
+acid_damage(obj)
+struct obj *obj;
+{
+    /* Scrolls but not spellbooks can be erased by acid. */
+    struct monst *victim =
+        carried(obj) ? &youmonst : mcarried(obj) ? obj->ocarry : NULL;
+    boolean vismon = victim && (victim != &youmonst) && canseemon(victim);
+
+    if (obj->greased)
+        grease_protect(obj, NULL, victim);
+    else if (obj->oclass == SCROLL_CLASS && obj->otyp != SCR_BLANK_PAPER) {
+        if (obj->otyp != SCR_BLANK_PAPER
+#ifdef MAIL
+                && obj->otyp != SCR_MAIL
+#endif
+           ) {
+            if (!Blind) {
+                if (victim == &youmonst)
+                    pline("Your %s.", aobjnam(obj, "fade"));
+                else if (vismon)
+                    pline("%s %s.", s_suffix(Monnam(victim)),
+                          aobjnam(obj, "fade"));
+            }
+        }
+        obj->otyp = SCR_BLANK_PAPER;
+        obj->spe = 0;
+        obj->dknown = 0;
+    } else
+        rust_dmg(obj, NULL, ERODE_CORRODE, TRUE, TRUE);
+}
+
 /* returns:
  *  0 if obj is unaffected
  *  1 if obj is protected by grease
index a0f90d3dec74c8aaf6d250b1e631a580b5f83dde..51f38eee0d10ac67425d398bf052766341b2e4be 100644 (file)
@@ -2446,22 +2446,22 @@ struct attack *mattk;           /* null means we find one internally */
 
        case AD_FIRE:
            if(!rn2(6) && !mon->mcan) {
-               (void) erode_obj(obj, 0, FALSE, FALSE);
+               (void) rust_dmg(obj, 0, ERODE_BURN, FALSE, FALSE);
            }
            break;
        case AD_ACID:
            if(!rn2(6)) {
-               (void) erode_obj(obj, 3, FALSE, FALSE);
+               (void) rust_dmg(obj, 0, ERODE_CORRODE, FALSE, FALSE);
            }
            break;
        case AD_RUST:
            if(!mon->mcan) {
-               (void) erode_obj(obj, 1, FALSE, FALSE);
+               (void) rust_dmg(obj, 0, ERODE_RUST, FALSE, FALSE);
            }
            break;
        case AD_CORR:
            if(!mon->mcan) {
-               (void) erode_obj(obj, 3, FALSE, FALSE);
+               (void) rust_dmg(obj, 0, ERODE_CORRODE, FALSE, FALSE);
            }
            break;
        case AD_ENCH:
index dbb5d271f4b767bc5926388949499cfee8587fe2..9e1447bff3313a1b3901603f193042b4f0425674 100644 (file)
@@ -597,131 +597,6 @@ untwoweapon()
        return;
 }
 
-/* Maybe rust (or corrode, burn, rot) object.
- * Returns TRUE if something happened. */
-boolean
-erode_obj(target, type, fade_scrolls, for_dip)
-struct obj *target;            /* object (e.g. weapon or armor) to erode */
-int type;
-boolean fade_scrolls;
-boolean for_dip;
-{
-       static NEARDATA const char * const action[] = { "smoulder", "rust", "rot", "corrode" };
-       static NEARDATA const char * const msg[] =  { "burnt", "rusty", "rotten", "corroded" };
-       boolean vulnerable = FALSE;
-       boolean grprot = FALSE;
-       boolean is_primary = TRUE;
-       int erosion;
-       int dmgtyp = AD_ACID;
-       struct monst *victim;
-       boolean vismon, visobj, chill;
-       boolean ret = FALSE;
-       boolean already_affected = FALSE;
-
-       if (!target)
-           return FALSE;
-       victim = carried(target) ? &youmonst :
-           mcarried(target) ? target->ocarry : (struct monst *)0;
-       vismon = victim && (victim != &youmonst) && canseemon(victim);
-       visobj = !victim && cansee(bhitpos.x, bhitpos.y); /* assume thrown */
-
-       switch(type) {
-       case 0: vulnerable = is_flammable(target);
-           dmgtyp = AD_FIRE;
-           break;
-       case 1: vulnerable = is_rustprone(target);
-           dmgtyp = AD_RUST;
-           grprot = TRUE;
-           if (target->lamplit) {
-               already_affected = snuff_lit(target);
-               if (already_affected) ret = TRUE;
-           }
-           break;
-       case 2: vulnerable = is_rottable(target);
-           dmgtyp = AD_DCAY;
-           is_primary = FALSE;
-           break;
-       case 3: vulnerable = is_corrodeable(target);
-           dmgtyp = AD_ACID;
-           grprot = TRUE;
-           is_primary = FALSE;
-           break;
-       }
-       erosion = is_primary ? target->oeroded : target->oeroded2;
-
-       if (target->greased && grprot) {
-           grease_protect(target,(char *)0,victim);
-           ret = TRUE;
-       } else if (target->oclass == SCROLL_CLASS && (type == 1 || type == 3)) {
-           if(fade_scrolls && target->otyp != SCR_BLANK_PAPER
-#ifdef MAIL
-           && target->otyp != SCR_MAIL
-#endif
-                                       )
-           {
-               if (!Blind) {
-                   if ((victim == &youmonst) || vismon || visobj)
-                       pline("%s.", Yobjnam2(target, "fade"));
-               }
-               target->otyp = SCR_BLANK_PAPER;
-               target->spe = 0;
-               ret = TRUE;
-           }
-       } else if (target->oartifact && arti_immune(target, dmgtyp)) {
-           if (flags.verbose && (dmgtyp != AD_FIRE)) {
-               if (victim == &youmonst)
-                   pline("%s.", Yobjnam2(target, "sizzle"));
-           }
-           /* no damage to object */
-       } else if (target->oartifact && (type == 1) &&
-               /* cold and fire provide partial protection against rust */
-               ((chill = arti_immune(target, AD_COLD)) != 0 ||
-                arti_immune(target, AD_FIRE)) &&
-               /* once rusted, the chance for further rusting goes up */
-               rn2(2 * (MAX_ERODE + 1 - erosion))) {
-           if (flags.verbose && target->oclass == WEAPON_CLASS) {
-               if (victim == &youmonst || vismon || visobj)
-                   pline("%s some water.",
-                         Yobjnam2(target, chill ? "freeze" : "boil"));
-           }
-           /* no damage to object */
-       } else if (target->oerodeproof || !vulnerable) {
-           /* no message if dipping or not carried */
-           if (for_dip) {
-               /* assumes that for_dip implies player action */
-               if (!Blind) target->rknown = 0;
-           } else if (victim == &youmonst || vismon) {
-               if (flags.verbose || (vulnerable && !target->rknown))
-                   pline("%s not %s.", Yobjnam2(target, "are"),
-                         already_affected ? "harmed" : "affected");
-               if (vulnerable) target->rknown = 1;
-           }
-       } else if (erosion < MAX_ERODE) {
-           if (victim == &youmonst || vismon || visobj) {
-               pline("%s%s!", Yobjnam2(target, action[type]),
-                   erosion+1 == MAX_ERODE ? " completely" :
-                   erosion ? " further" : "");
-               target->rknown = 1;     /* it's obviously not erode-proof */
-           }
-           if (is_primary)
-               target->oeroded++;
-           else
-               target->oeroded2++;
-           ret = TRUE;
-       } else {
-           if (flags.verbose && !for_dip) {
-               if (victim == &youmonst)
-                   pline("%s completely %s.",
-                       Yobjnam2(target, Blind ? "feel" : "look"), msg[type]);
-               else if (vismon || visobj)
-                   pline("%s completely %s.",
-                       Yobjnam2(target, "look"), msg[type]);
-           }
-       }
-
-       return ret;
-}
-
 int
 chwepon(otmp, amount)
 register struct obj *otmp;
index 2fb2396de20d73245e212c1d406a18c894e95ebe..95b9760a39c9ea3283b45a46b6826deba26710ff 100644 (file)
--- a/src/zap.c
+++ b/src/zap.c
@@ -3395,7 +3395,7 @@ struct obj **ootmp;       /* to return worn armor for caller to disintegrate */
                    break;
                }
                tmp = d(nd,6);
-               if (!rn2(6)) (void) erode_obj(MON_WEP(mon), 3, TRUE, FALSE);
+               if (!rn2(6)) acid_damage(MON_WEP(mon));
                if (!rn2(6)) erode_armor(mon, ERODE_CORRODE);
                break;
        }
@@ -3522,9 +3522,9 @@ xchar sx, sy;
            }
            /* using two weapons at once makes both of them more vulnerable */
            if (!rn2(u.twoweap ? 3 : 6))
-               (void) erode_obj(uwep, 3, TRUE, FALSE);
+               acid_damage(uwep);
            if (u.twoweap && !rn2(3))
-               (void) erode_obj(uswapwep, 3, TRUE, FALSE);
+               acid_damage(uswapwep);
            if (!rn2(6)) erode_armor(&youmonst, ERODE_CORRODE);
            break;
        }