]> granicus.if.org Git - nethack/commitdiff
A lot more cleanup to rust and water.
authorSean Hunt <scshunt@csclub.uwaterloo.ca>
Mon, 23 Feb 2015 22:21:11 +0000 (17:21 -0500)
committerSean Hunt <scshunt@csclub.uwaterloo.ca>
Mon, 2 Mar 2015 17:49:59 +0000 (12:49 -0500)
15 files changed:
doc/fixes35.0
include/extern.h
src/do.c
src/do_wear.c
src/dokick.c
src/fountain.c
src/mhitm.c
src/mhitu.c
src/mon.c
src/objnam.c
src/sit.c
src/trap.c
src/uhitm.c
src/worn.c
src/zap.c

index 4fd81cff5507a4751e728cfc91c485cbaaab68bd..48da8da363f8d652083d096e118252c6ceb458bf 100644 (file)
@@ -861,6 +861,7 @@ 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
+all sources of erosion now affect objects the same way
 
 
 Platform- and/or Interface-Specific Fixes
index 87427dd3ae6d9ce360b364c01cff33f0b11079ac..87d3adee7f2185fcf7ef2f1801faa0f580fca6c1 100644 (file)
@@ -434,7 +434,6 @@ E int NDECL(doputon);
 E void NDECL(find_ac);
 E void NDECL(glibr);
 E struct obj *FDECL(some_armor,(struct monst *));
-E void FDECL(erode_armor, (struct monst *,BOOLEAN_P));
 E struct obj *FDECL(stuck_ring, (struct obj *,int));
 E struct obj *NDECL(unchanger);
 E void NDECL(reset_remarm);
@@ -2203,7 +2202,7 @@ E coord *FDECL(gettrack, (int,int));
 /* ### trap.c ### */
 
 E boolean FDECL(burnarmor,(struct monst *));
-E boolean FDECL(rust_dmg, (struct obj *,const char *,int,BOOLEAN_P));
+E boolean FDECL(rust_dmg, (struct obj *,const char *,int,BOOLEAN_P,BOOLEAN_P));
 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));
@@ -2223,7 +2222,8 @@ 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 FDECL(water_damage, (struct obj **,BOOLEAN_P,BOOLEAN_P));
+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);
 E void FDECL(drain_en, (int));
 E int NDECL(dountrap);
@@ -2253,7 +2253,7 @@ E void NDECL(u_init);
 
 /* ### uhitm.c ### */
 
-E void FDECL(hurtmarmor,(struct monst *,int));
+E void FDECL(erode_armor,(struct monst *,int));
 E boolean FDECL(attack_checks, (struct monst *,struct obj *));
 E void FDECL(check_caitiff, (struct monst *));
 E int FDECL(find_roll_to_hit, (struct monst *,UCHAR_P,struct obj *,int *,int *));
index 98198129357bacf8ff446a41b7684801ebdc3449..319317bf59abb567b9fab5a8def6b40a38dbabc2 100644 (file)
--- a/src/do.c
+++ b/src/do.c
@@ -201,8 +201,7 @@ const char *verb;
                    map_background(x, y, 0);
                    newsym(x, y);
                }
-               water_damage(&obj, FALSE, FALSE);
-               if (!obj) return TRUE;
+               return water_damage(obj, NULL, FALSE) == 3;
        } else if (u.ux == x && u.uy == y &&
                (t = t_at(x,y)) != 0 && uteetering_at_seen_pit(t)) {
                if (Blind && !Deaf)
index 414f5a5221ecabe513e7bf553aed1954162a0cab..9925ceaf0cde83425821255756251d8e59628abf 100644 (file)
@@ -1937,20 +1937,6 @@ struct monst *victim;
        return(otmph);
 }
 
-/* erode some arbitrary armor worn by the victim */
-void
-erode_armor(victim, acid_dmg)
-struct monst *victim;
-boolean acid_dmg;
-{
-       struct obj *otmph = some_armor(victim);
-
-       if (otmph && (otmph != uarmf)) {
-           (void) erode_obj(otmph, acid_dmg ? 3 : 1, FALSE, FALSE);
-           if (carried(otmph)) update_inventory();
-       }
-}
-
 /* used for praying to check and fix levitation trouble */
 struct obj *
 stuck_ring(ring, otyp)
index 06ff075e6f048c4be2a8ee9ab2cf0872a2a113fd..c399f6bbcd58b463089af3199d892a2dfcd304a7 100644 (file)
@@ -983,7 +983,7 @@ dokick()
                    if(!rn2(3)) goto ouch;
                    /* make metal boots rust */
                    if(uarmf && rn2(3))
-                       if (!rust_dmg(uarmf, "metal boots", 1, FALSE)) {
+                       if (!water_damage(uarmf, "metal boots", TRUE)) {
                                Your("boots get wet.");
                                /* could cause short-lived fumbling here */
                        }
index f167c09d42ad1804a74f632e9b3272ac4238f1cd..cc8aeb7bf9682f0681f23819347f1408d7b237a3 100644 (file)
@@ -136,7 +136,7 @@ genericptr_t poolcnt;
        levl[x][y].typ = POOL;
        /* No kelp! */
        del_engr_at(x, y);
-       water_damage(&level.objects[x][y], FALSE, TRUE);
+       water_damage_chain(level.objects[x][y], TRUE);
 
        if ((mtmp = m_at(x, y)) != 0)
                (void) minliquid(mtmp);
index 47a14915fd46c72d7e1662e28c1c2c892bb8e391..ae66279e7030f65d3ab84e531e07d728fcabeb2b 100644 (file)
@@ -883,7 +883,7 @@ mdamagem(magr, mdef, mattk)
                    pline("%s is covered in acid!", Monnam(mdef));
                    pline("It burns %s!", mon_nam(mdef));
                }
-               if (!rn2(30)) erode_armor(mdef, TRUE);
+               if (!rn2(30)) erode_armor(mdef, ERODE_CORRODE);
                if (!rn2(6)) (void) erode_obj(MON_WEP(mdef), 3, TRUE, FALSE);
                break;
            case AD_RUST:
@@ -897,13 +897,13 @@ mdamagem(magr, mdef, mattk)
                        return (MM_DEF_DIED | (grow_up(magr,mdef) ?
                                                        0 : MM_AGR_DIED));
                }
-               hurtmarmor(mdef, AD_RUST);
+               erode_armor(mdef, ERODE_RUST);
                mdef->mstrategy &= ~STRAT_WAITFORU;
                tmp = 0;
                break;
            case AD_CORR:
                if (magr->mcan) break;
-               hurtmarmor(mdef, AD_CORR);
+               erode_armor(mdef, ERODE_CORRODE);
                mdef->mstrategy &= ~STRAT_WAITFORU;
                tmp = 0;
                break;
@@ -919,7 +919,7 @@ mdamagem(magr, mdef, mattk)
                        return (MM_DEF_DIED | (grow_up(magr,mdef) ?
                                                        0 : MM_AGR_DIED));
                }
-               hurtmarmor(mdef, AD_DCAY);
+               erode_armor(mdef, ERODE_CORRODE);
                mdef->mstrategy &= ~STRAT_WAITFORU;
                tmp = 0;
                break;
@@ -1361,7 +1361,7 @@ int mdead;
                        tmp = 0;
                    }
                } else tmp = 0;
-               if (!rn2(30)) erode_armor(magr, TRUE);
+               if (!rn2(30)) erode_armor(magr, ERODE_CORRODE);
                if (!rn2(6)) (void)erode_obj(MON_WEP(magr), 3, TRUE, FALSE);
                goto assess_dmg;
            case AD_ENCH:       /* KMH -- remove enchantment (disenchanter) */
index 416edaa5be3572c2529a7c2efe631af9afeada56..cc9b6f1be5438a3e1f21f524d3dc641a9a596106 100644 (file)
@@ -22,7 +22,6 @@ STATIC_DCL void FDECL(missmu,(struct monst *,BOOLEAN_P,struct attack *));
 STATIC_DCL void FDECL(mswings,(struct monst *,struct obj *));
 STATIC_DCL void FDECL(wildmiss, (struct monst *,struct attack *));
 
-STATIC_DCL void FDECL(hurtarmor,(int));
 STATIC_DCL void FDECL(hitmsg,(struct monst *,struct attack *));
 
 /* See comment in mhitm.c.  If we use this a lot it probably should be */
@@ -714,67 +713,6 @@ mattacku(mtmp)
        return(0);
 }
 
-/*
- * helper function for some compilers that have trouble with hitmu
- */
-
-STATIC_OVL void
-hurtarmor(attk)
-int attk;
-{
-       int     hurt;
-
-       switch(attk) {
-           /* 0 is burning, which we should never be called with */
-           case AD_RUST: hurt = 1; break;
-           case AD_CORR: hurt = 3; break;
-           default: hurt = 2; break;
-       }
-
-       /* What the following code does: it keeps looping until it
-        * finds a target for the rust monster.
-        * Head, feet, etc... not covered by metal, or covered by
-        * rusty metal, are not targets.  However, your body always
-        * is, no matter what covers it.
-        */
-       while (1) {
-           switch(rn2(5)) {
-           case 0:
-               if (!uarmh || !rust_dmg(uarmh, xname(uarmh), hurt, FALSE))
-                       continue;
-               break;
-           case 1:
-               if (uarmc) {
-                   (void)rust_dmg(uarmc, xname(uarmc), hurt, TRUE);
-                   break;
-               }
-               /* Note the difference between break and continue;
-                * break means it was hit and didn't rust; continue
-                * means it wasn't a target and though it didn't rust
-                * something else did.
-                */
-               if (uarm)
-                   (void)rust_dmg(uarm, xname(uarm), hurt, TRUE);
-               else if (uarmu)
-                   (void)rust_dmg(uarmu, xname(uarmu), hurt, TRUE);
-               break;
-           case 2:
-               if (!uarms || !rust_dmg(uarms, xname(uarms), hurt, FALSE))
-                   continue;
-               break;
-           case 3:
-               if (!uarmg || !rust_dmg(uarmg, xname(uarmg), hurt, FALSE))
-                   continue;
-               break;
-           case 4:
-               if (!uarmf || !rust_dmg(uarmf, xname(uarmf), hurt, FALSE))
-                   continue;
-               break;
-           }
-           break; /* Out of while loop */
-       }
-}
-
 STATIC_OVL boolean
 diseasemu(mdat)
 struct permonst *mdat;
@@ -1336,12 +1274,12 @@ dopois:
                        rehumanize();
                        break;
                }
-               hurtarmor(AD_RUST);
+               erode_armor(&youmonst, ERODE_RUST);
                break;
            case AD_CORR:
                hitmsg(mtmp, mattk);
                if (mtmp->mcan) break;
-               hurtarmor(AD_CORR);
+               erode_armor(&youmonst, ERODE_CORRODE);
                break;
            case AD_DCAY:
                hitmsg(mtmp, mattk);
@@ -1353,7 +1291,7 @@ dopois:
                        rehumanize();
                        break;
                }
-               hurtarmor(AD_DCAY);
+               erode_armor(&youmonst, ERODE_ROT);
                break;
            case AD_HEAL:
                /* a cancelled nurse is just an ordinary monster,
@@ -2503,7 +2441,7 @@ register struct attack *mattk;
                        tmp = 0;
                    }
                } else tmp = 0;
-               if (!rn2(30)) erode_armor(mtmp, TRUE);
+               if (!rn2(30)) erode_armor(mtmp, ERODE_CORRODE);
                if (!rn2(6)) (void)erode_obj(MON_WEP(mtmp), 3, TRUE, FALSE);
                goto assess_dmg;
            case AD_STON: /* cockatrice */
index f617dad4c066c24fe8a42d465aa23c11f6135fc5..1c2009a0b6cb8c0f62046b0244caa3d36a121d63 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -333,7 +333,7 @@ register struct monst *mtmp;
     if (mtmp->data == &mons[PM_GREMLIN] && (inpool || infountain) && rn2(3)) {
        if (split_mon(mtmp, (struct monst *)0))
            dryup(mtmp->mx, mtmp->my, FALSE);
-       if (inpool) water_damage(&mtmp->minvent, FALSE, FALSE);
+       if (inpool) water_damage_chain(mtmp->minvent, FALSE);
        return (0);
     } else if (mtmp->data == &mons[PM_IRON_GOLEM] && inpool && !rn2(5)) {
        int dam = d(2,6);
@@ -345,7 +345,7 @@ register struct monst *mtmp;
            mondead(mtmp);
            if (mtmp->mhp < 1) return (1);
        }
-       water_damage(&mtmp->minvent, FALSE, FALSE);
+       water_damage_chain(mtmp->minvent, FALSE);
        return (0);
     }
 
@@ -398,7 +398,7 @@ register struct monst *mtmp;
            }
            mondead(mtmp);
            if (mtmp->mhp > 0) {
-               water_damage(&mtmp->minvent, FALSE, FALSE);
+               water_damage_chain(mtmp->minvent, FALSE);
                (void) rloc(mtmp, FALSE);
                return 0;
            }
index 84c3599f44190a6a0b858ecfe8ff7711ee02c4ae..fe692b226d8b8017922e0ff7d7190490b82b03aa 100644 (file)
@@ -2893,7 +2893,7 @@ wiztrap:
                        del_engr_at(x, y);
                        pline("A %s.", (lev->typ == POOL) ? "pool" : "moat");
                        /* Must manually make kelp! */
-                       water_damage(&level.objects[x][y], FALSE, TRUE);
+                       water_damage_chain(level.objects[x][y], TRUE);
                        newsym(x, y);
                        return &zeroobj;
                }
index e5e77aa42528bbcc33afda49afccb076b02650fa..19cd634719f961fea2b97f6577cf2189aa913db2 100644 (file)
--- a/src/sit.c
+++ b/src/sit.c
@@ -113,9 +113,9 @@ dosit()
  in_water:
            You("sit in the water.");
            if (!rn2(10) && uarm)
-               (void) rust_dmg(uarm, "armor", 1, TRUE);
+               (void) water_damage(uarm, "armor", TRUE);
            if (!rn2(10) && uarmf && uarmf->otyp != WATER_WALKING_BOOTS)
-               (void) rust_dmg(uarm, "armor", 1, TRUE);
+               (void) water_damage(uarm, "armor", TRUE);
        } else if(IS_SINK(typ)) {
            You(sit_message, defsyms[S_sink].explanation);
            Your("%s gets wet.", humanoid(youmonst.data) ? "rump" : "underside");
index 1220105f56855836e8db98c2e85aa8e72d4fd0cf..f6266791fe28ec04d173fc8965a5d66cce2b9275 100644 (file)
@@ -55,7 +55,7 @@ struct monst *victim;
     int mat_idx;
     
     if (!victim) return 0;
-#define burn_dmg(obj,descr) rust_dmg(obj, descr, 0, FALSE)
+#define burn_dmg(obj,descr) rust_dmg(obj, descr, ERODE_BURN, TRUE, FALSE)
     while (1) {
        switch (rn2(5)) {
        case 0:
@@ -102,20 +102,21 @@ struct monst *victim;
 }
 
 /* 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.
+ * occurred, or if grease protected the item.
+ * "check_grease", if FALSE, means that grease is not checked for
+ * "print", if set, means to print a message even if no change occurs.
  */
 boolean
-rust_dmg(otmp, ostr, type, print)
+rust_dmg(otmp, ostr, type, check_grease, print)
 register struct obj *otmp;
 register const char *ostr;
 int type;
+boolean check_grease;
 boolean print;
 {
        static NEARDATA const char * const action[] = { "smoulder", "rust", "rot", "corrode" };
        static NEARDATA const char * const msg[] =  { "burnt", "rusted", "rotten", "corroded" };
        boolean vulnerable = FALSE;
-       boolean grprot = FALSE;
        boolean is_primary = TRUE;
        int erosion;
         struct monst *victim;
@@ -133,18 +134,18 @@ boolean print;
        switch(type) {
                case ERODE_BURN:
                     vulnerable = is_flammable(otmp);
+                    check_grease = FALSE;
                    break;
                case ERODE_RUST:
                     vulnerable = is_rustprone(otmp);
-                   grprot = TRUE;
                    break;
                case ERODE_ROT:
                     vulnerable = is_rottable(otmp);
+                    check_grease = FALSE;
                    is_primary = FALSE;
                    break;
                case ERODE_CORRODE:
                     vulnerable = is_corrodeable(otmp);
-                   grprot = TRUE;
                    is_primary = FALSE;
                    break;
                 default:
@@ -156,8 +157,9 @@ boolean print;
         if (!ostr)
             ostr = cxname(otmp);
 
-        if (grprot && otmp->greased) {
-            return grease_protect(otmp, ostr, victim);
+        if (check_grease && otmp->greased) {
+            grease_protect(otmp, ostr, victim);
+            return TRUE;
         } else if (!vulnerable || (otmp->oerodeproof && otmp->rknown)) {
            if (print && flags.verbose) {
                if (victim == &youmonst)
@@ -167,7 +169,7 @@ boolean print;
                          vtense(ostr, "are"));
            }
             return FALSE;
-        } else if (otmp->oerodeproof || otmp->blessed && !rnl(4)) {
+        } else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) {
             if (flags.verbose && (print || otmp->oerodeproof)) {
                if (victim == &youmonst)
                    pline("Somehow, your %s %s not affected.",
@@ -176,7 +178,7 @@ boolean print;
                    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,
+                    pline("Somehow, the %s %s not affected.", ostr,
                           vtense(ostr, "are"));
             }
             /* We assume here that if the object is protected because it
@@ -188,7 +190,7 @@ boolean print;
             return FALSE;
        } else if (erosion < MAX_ERODE) {
             const char *adverb = (erosion + 1 == MAX_ERODE) ?
-                " complete" : erosion ? " further" : "";
+                " completely" : erosion ? " further" : "";
 
             if (victim == &youmonst)
                 Your("%s %s%s!", ostr, vtense(ostr, action[type]), adverb);
@@ -931,18 +933,6 @@ unsigned trflags;
 
            case RUST_TRAP:
                seetrap(trap);
-               if (u.umonnum == PM_IRON_GOLEM) {
-                   int dam = u.mhmax;
-
-                   pline("%s you!", A_gush_of_water_hits);
-                   You("are covered with rust!");
-                   losehp(Maybe_Half_Phys(dam), "rusting away", KILLED_BY);
-                   break;
-               } else if (u.umonnum == PM_GREMLIN && rn2(3)) {
-                   pline("%s you!", A_gush_of_water_hits);
-                   (void)split_mon(&youmonst, (struct monst *)0);
-                   break;
-               }
 
            /* Unlike monsters, traps cannot aim their rust attacks at
             * you, so instead of looping through and taking either the
@@ -953,18 +943,18 @@ unsigned trflags;
                    case 0:
                        pline("%s you on the %s!", A_gush_of_water_hits,
                                    body_part(HEAD));
-                       (void) rust_dmg(uarmh, helm_simple_name(uarmh),
-                                       1, TRUE);
+                       (void) water_damage(uarmh, helm_simple_name(uarmh),
+                                           TRUE);
                        break;
                    case 1:
                        pline("%s your left %s!", A_gush_of_water_hits,
                                    body_part(ARM));
-                       if (rust_dmg(uarms, "shield", 1, TRUE))
+                       if (water_damage(uarms, "shield", TRUE))
                            break;
                        if (u.twoweap || (uwep && bimanual(uwep)))
                            (void) erode_obj(u.twoweap ? uswapwep : uwep,
                                             1, TRUE, FALSE);
-glovecheck:            (void) rust_dmg(uarmg, "gauntlets", 1, TRUE);
+glovecheck:            (void) water_damage(uarmg, "gauntlets", TRUE);
                        /* Not "metal gauntlets" since it gets called
                         * even if it's leather for the message
                         */
@@ -981,14 +971,26 @@ glovecheck:               (void) rust_dmg(uarmg, "gauntlets", 1, TRUE);
                                    (otmp != uswapwep || !u.twoweap))
                                (void) snuff_lit(otmp);
                        if (uarmc)
-                           (void) rust_dmg(uarmc, cloak_simple_name(uarmc),
-                                               1, TRUE);
+                           (void) water_damage(uarmc, cloak_simple_name(uarmc),
+                                               TRUE);
                        else if (uarm)
-                           (void) rust_dmg(uarm, "armor", 1, TRUE);
+                           (void) water_damage(uarm, "armor", TRUE);
                        else if (uarmu)
-                           (void) rust_dmg(uarmu, "shirt", 1, TRUE);
+                           (void) water_damage(uarmu, "shirt", TRUE);
                }
                update_inventory();
+
+               if (u.umonnum == PM_IRON_GOLEM) {
+                   int dam = u.mhmax;
+
+                   pline("%s you!", A_gush_of_water_hits);
+                   You("are covered with rust!");
+                   losehp(Maybe_Half_Phys(dam), "rusting away", KILLED_BY);
+               } else if (u.umonnum == PM_GREMLIN && rn2(3)) {
+                   pline("%s you!", A_gush_of_water_hits);
+                   (void)split_mon(&youmonst, (struct monst *)0);
+               }
+
                break;
 
            case FIRE_TRAP:
@@ -2084,21 +2086,21 @@ register struct monst *mtmp;
                                pline("%s %s on the %s!", A_gush_of_water_hits,
                                    mon_nam(mtmp), mbodypart(mtmp, HEAD));
                            target = which_armor(mtmp, W_ARMH);
-                           (void) rust_dmg(target, helm_simple_name(target),
-                                           1, TRUE);
+                           (void) water_damage(target, helm_simple_name(target),
+                                               TRUE);
                            break;
                        case 1:
                            if (in_sight)
                                pline("%s %s's left %s!", A_gush_of_water_hits,
                                    mon_nam(mtmp), mbodypart(mtmp, ARM));
                            target = which_armor(mtmp, W_ARMS);
-                           if (rust_dmg(target, "shield", 1, TRUE))
+                           if (water_damage(target, "shield", TRUE))
                                break;
                            target = MON_WEP(mtmp);
                            if (target && bimanual(target))
                                (void) erode_obj(target, 1, TRUE, FALSE);
 glovecheck:                target = which_armor(mtmp, W_ARMG);
-                           (void) rust_dmg(target, "gauntlets", 1, TRUE);
+                           (void) water_damage(target, "gauntlets", TRUE);
                            break;
                        case 2:
                            if (in_sight)
@@ -2115,13 +2117,13 @@ glovecheck:                 target = which_armor(mtmp, W_ARMG);
                                        (otmp->owornmask & (W_WEP|W_SWAPWEP)) == 0)
                                    (void) snuff_lit(otmp);
                            if ((target = which_armor(mtmp, W_ARMC)) != 0)
-                               (void) rust_dmg(target,
-                                               cloak_simple_name(target),
-                                               1, TRUE);
+                               (void) water_damage(target,
+                                                   cloak_simple_name(target),
+                                                   TRUE);
                            else if ((target = which_armor(mtmp, W_ARM)) != 0)
-                               (void) rust_dmg(target, "armor", 1, TRUE);
+                               (void) water_damage(target, "armor", TRUE);
                            else if ((target = which_armor(mtmp, W_ARMU)) != 0)
-                               (void) rust_dmg(target, "shirt", 1, TRUE);
+                               (void) water_damage(target, "shirt", TRUE);
                        }
 
                        if (mptr == &mons[PM_IRON_GOLEM]) {
@@ -3067,107 +3069,112 @@ xchar x, y;
     return retval;
 }
 
-void
-water_damage(objp, force, here)
-struct obj **objp;
-boolean force, here;
+/* returns:
+ *  0 if obj is unaffected
+ *  1 if obj is protected by grease
+ *  2 if obj is changed but survived
+ *  3 if obj is destroyed
+ */
+int
+water_damage(obj, ostr, force)
+struct obj *obj;
+const char *ostr;
+boolean force;
 {
-       register struct obj *obj = *objp, *otmp;
        boolean loose_obj = (obj && obj->where == OBJ_FREE), exploded = FALSE;
 
-       if (loose_obj && (obj->nobj || obj->nexthere)) {
-               /* [this should actually be a panic()] */
-               impossible("water_damage: loose object has%s%s%s list%s?",
-                          obj->nobj ? " nobj" : "",
-                          (obj->nobj && obj->nexthere) ? " and" : "",
-                          obj->nexthere ? " nexthere" : "",
-                          (obj->nobj && obj->nexthere) ? "s" : "");
-       }
-
-       /* Scrolls, spellbooks, potions, weapons and
-          pieces of armor may get affected by the water.
-
-          [FIXME?  The item transformations here lack shop price/billing
-          handling [costly_alteration()], which is okay as long as shops
-          don't contain any pools.  However, that's probably not a valid
-          assumption; a broken fountain might spill new pools far enough
-          to put one inside a nearby shop, particularly if dug walls in
-          Minetown haven't been repaired yet.  Note that water_damage()
-          might be getting called right now because we're in the midst
-          of creating such a pool, not just because one has already been
-          created and we've walked into it while carrying unpaid stuff.]
-        */
-       for (; obj; obj = otmp) {
-               otmp = here ? obj->nexthere : obj->nobj;
-
-               (void) snuff_lit(obj);
-
-               if(obj->otyp == CAN_OF_GREASE && obj->spe > 0) {
-                       continue;
-               } else if(obj->greased) {
-                       if (force || !rn2(2)) obj->greased = 0;
-               } else if(Is_container(obj) && !Is_box(obj) &&
-                       (obj->otyp != OILSKIN_SACK || (obj->cursed && !rn2(3)))) {
-                       water_damage(&obj->cobj, force, FALSE);
-               } else if (!force && (Luck + 5) > rn2(20)) {
-                       /*  chance per item of sustaining damage:
-                        *      max luck:               10%
-                        *      avg luck (Luck==0):     75%
-                        *      awful luck (Luck<-4):  100%
-                        */
-                       continue;
-               } else if (obj->oclass == SCROLL_CLASS) {
+        (void) snuff_lit(obj);
+
+        if(obj->otyp == CAN_OF_GREASE && obj->spe > 0) {
+                return 0;
+        } else if(obj->greased) {
+                if (!rn2(2)) obj->greased = 0;
+                if (carried(obj)) update_inventory();
+                return 1;
+        } else if(Is_container(obj) && !Is_box(obj) &&
+                (obj->otyp != OILSKIN_SACK || (obj->cursed && !rn2(3)))) {
+                water_damage_chain(obj->cobj, FALSE);
+                return 0;
+        } else if (!force && (Luck + 5) > rn2(20)) {
+                /*  chance per item of sustaining damage:
+                    *  max luck:               10%
+                    *  avg luck (Luck==0):     75%
+                    *  awful luck (Luck<-4):  100%
+                    */
+                return 0;
+        } else if (obj->oclass == SCROLL_CLASS) {
 #ifdef MAIL
-                       if (obj->otyp == SCR_MAIL) continue;
+                if (obj->otyp == SCR_MAIL) return 0;
 #endif
-                       obj->otyp = SCR_BLANK_PAPER;
-                       obj->dknown = 0;
-                       obj->spe = 0;
-               } else if (obj->oclass == SPBOOK_CLASS) {
-                       if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
-                               pline("Steam rises from %s.", the(xname(obj)));
-                               continue;
-                       }
-                       obj->otyp = SPE_BLANK_PAPER;
-                       obj->dknown = 0;
-               } else if (obj->oclass == POTION_CLASS) {
-                       if (obj->otyp == POT_ACID) {
-                               char *bufp, buf[BUFSZ];
-                               boolean one = (obj->quan == 1L);
-
-                               bufp = strcpy(buf, "potion");
-                               if (!one) bufp = makeplural(bufp);
-                               /* [should we damage player/monster?] */
-                               pline("%s %s %s!",  /* "A potion explodes!" */
-                                     !exploded ? (one ? "A" : "Some") :
-                                                 (one ? "Another" : "More"),
-                                     bufp, vtense(bufp, "explode"));
-                               exploded = TRUE;
-                               /* let caller know that obj has gone away
-                                  [when obj is part of a list, delobj()'s
-                                  obj_extract_self() takes care of this;
-                                  for loose_obj, obj should always equal
-                                  *objp and otmp should always be null] */
-                               if (loose_obj && obj == *objp) *objp = otmp;
-                               delobj(obj);
-                               continue;
-                       } else if (obj->odiluted) {
-                               obj->otyp = POT_WATER;
-                               obj->dknown = 0;
-                               obj->blessed = obj->cursed = 0;
-                               obj->odiluted = 0;
-                       } else if (obj->otyp != POT_WATER)
-                               obj->odiluted++;
-               } else if (is_rustprone(obj) && obj->oeroded < MAX_ERODE &&
-                         !(obj->oerodeproof || (obj->blessed && !rnl(4)))) {
-                       /* all metal stuff and armor except (body armor
-                          protected by oilskin cloak) */
-                       if(obj->oclass != ARMOR_CLASS || obj != uarm ||
-                          !uarmc || uarmc->otyp != OILSKIN_CLOAK ||
-                          (uarmc->cursed && !rn2(3)))
-                               obj->oeroded++;
-               }
-       }
+                obj->otyp = SCR_BLANK_PAPER;
+                obj->dknown = 0;
+                obj->spe = 0;
+                if (carried(obj))
+                    update_inventory();
+                return 2;
+        } else if (obj->oclass == SPBOOK_CLASS) {
+                if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
+                        pline("Steam rises from %s.", the(xname(obj)));
+                        return 0;
+                }
+                obj->otyp = SPE_BLANK_PAPER;
+                obj->dknown = 0;
+                if (carried(obj))
+                    update_inventory();
+                return 2;
+        } else if (obj->oclass == POTION_CLASS) {
+                if (obj->otyp == POT_ACID) {
+                        char *bufp, buf[BUFSZ];
+                        boolean one = (obj->quan == 1L);
+                        boolean update = carried(obj);
+
+                        bufp = strcpy(buf, "potion");
+                        if (!one) bufp = makeplural(bufp);
+                        /* [should we damage player/monster?] */
+                        pline("%s %s %s!",  /* "A potion explodes!" */
+                                !exploded ? (one ? "A" : "Some") :
+                                            (one ? "Another" : "More"),
+                                bufp, vtense(bufp, "explode"));
+                        exploded = TRUE;
+                        /* let caller know that obj has gone away
+                            [when obj is part of a list, delobj()'s
+                            obj_extract_self() takes care of this;
+                            for loose_obj, obj should always equal
+                            *objp and otmp should always be null] */
+                        delobj(obj);
+                        if (update)
+                            update_inventory();
+                        return 3;
+                } else if (obj->odiluted) {
+                        obj->otyp = POT_WATER;
+                        obj->dknown = 0;
+                        obj->blessed = obj->cursed = 0;
+                        obj->odiluted = 0;
+                        if (carried(obj))
+                            update_inventory();
+                        return 2;
+                } else if (obj->otyp != POT_WATER) {
+                        obj->odiluted++;
+                        if (carried(obj))
+                            update_inventory();
+                        return 2;
+                }
+        } else {
+                return rust_dmg(obj, ostr, ERODE_RUST, FALSE, FALSE) ? 2 : 0;
+        }
+        return 0;
+}
+
+void
+water_damage_chain(obj,here)
+struct obj *obj;
+boolean here;
+{
+        struct obj *otmp;
+        for (; obj; obj = otmp) {
+            otmp = here ? obj->nexthere : obj->nobj;
+            water_damage(obj, NULL, FALSE);
+        }
 }
 
 /*
@@ -3246,7 +3253,7 @@ drown()
                        Hallucination ? "the Titanic" : "a rock");
        }
 
-       water_damage(&invent, FALSE, FALSE);
+       water_damage_chain(invent, FALSE);
 
        if (u.umonnum == PM_GREMLIN && rn2(3))
            (void)split_mon(&youmonst, (struct monst *)0);
index 1ccb8a2cb9f53e4c501ff1e2b63f178f992062e7..a0f90d3dec74c8aaf6d250b1e631a580b5f83dde 100644 (file)
@@ -30,22 +30,13 @@ static boolean override_confirmation = FALSE;
 
 #define PROJECTILE(obj)        ((obj) && is_ammo(obj))
 
-/* modified from hurtarmor() in mhitu.c */
-/* This is not static because it is also used for monsters rusting monsters */
 void
-hurtmarmor(mdef, attk)
+erode_armor(mdef, hurt)
 struct monst *mdef;
-int attk;
+int hurt;
 {
-       int     hurt;
        struct obj *target;
 
-       switch(attk) {
-           /* 0 is burning, which we should never be called with */
-           case AD_RUST: hurt = 1; break;
-           case AD_CORR: hurt = 3; break;
-           default: hurt = 2; break;
-       }
        /* What the following code does: it keeps looping until it
         * finds a target for the rust monster.
         * Head, feet, etc... not covered by metal, or covered by
@@ -56,34 +47,34 @@ int attk;
            switch(rn2(5)) {
            case 0:
                target = which_armor(mdef, W_ARMH);
-               if (!target || !rust_dmg(target, xname(target), hurt, FALSE))
+               if (!target || !rust_dmg(target, xname(target), hurt, TRUE, FALSE))
                    continue;
                break;
            case 1:
                target = which_armor(mdef, W_ARMC);
                if (target) {
-                   (void)rust_dmg(target, xname(target), hurt, TRUE);
+                   (void)rust_dmg(target, xname(target), hurt, TRUE, TRUE);
                    break;
                }
                if ((target = which_armor(mdef, W_ARM)) != (struct obj *)0) {
-                   (void)rust_dmg(target, xname(target), hurt, TRUE);
+                   (void)rust_dmg(target, xname(target), hurt, TRUE, TRUE);
                } else if ((target = which_armor(mdef, W_ARMU)) != (struct obj *)0) {
-                   (void)rust_dmg(target, xname(target), hurt, TRUE);
+                   (void)rust_dmg(target, xname(target), hurt, TRUE, TRUE);
                }
                break;
            case 2:
                target = which_armor(mdef, W_ARMS);
-               if (!target || !rust_dmg(target, xname(target), hurt, FALSE))
+               if (!target || !rust_dmg(target, xname(target), hurt, TRUE, FALSE))
                    continue;
                break;
            case 3:
                target = which_armor(mdef, W_ARMG);
-               if (!target || !rust_dmg(target, xname(target), hurt, FALSE))
+               if (!target || !rust_dmg(target, xname(target), hurt, TRUE, FALSE))
                    continue;
                break;
            case 4:
                target = which_armor(mdef, W_ARMF);
-               if (!target || !rust_dmg(target, xname(target), hurt, FALSE))
+               if (!target || !rust_dmg(target, xname(target), hurt, TRUE, FALSE))
                    continue;
                break;
            }
@@ -1536,11 +1527,11 @@ register struct attack *mattk;
                        pline("%s falls to pieces!", Monnam(mdef));
                        xkilled(mdef,0);
                }
-               hurtmarmor(mdef, AD_RUST);
+               erode_armor(mdef, ERODE_RUST);
                tmp = 0;
                break;
            case AD_CORR:
-               hurtmarmor(mdef, AD_CORR);
+               erode_armor(mdef, ERODE_CORRODE);
                tmp = 0;
                break;
            case AD_DCAY:
@@ -1549,7 +1540,7 @@ register struct attack *mattk;
                        pline("%s falls to pieces!", Monnam(mdef));
                        xkilled(mdef,0);
                }
-               hurtmarmor(mdef, AD_DCAY);
+               erode_armor(mdef, ERODE_ROT);
                tmp = 0;
                break;
            case AD_DREN:
@@ -2231,7 +2222,7 @@ boolean wep_was_destroyed;
            if(mhit && !mon->mcan) {
                if (aatyp == AT_KICK) {
                    if (uarmf && !rn2(6))
-                       (void)rust_dmg(uarmf, xname(uarmf), 0, TRUE);
+                       (void)rust_dmg(uarmf, xname(uarmf), ERODE_BURN, TRUE, TRUE);
                } else if (aatyp == AT_WEAP || aatyp == AT_CLAW ||
                           aatyp == AT_MAGC || aatyp == AT_TUCH)
                    passive_obj(mon, (struct obj*)0, &(ptr->mattk[i]));
@@ -2246,12 +2237,12 @@ boolean wep_was_destroyed;
 
                if (!Acid_resistance)
                        mdamageu(mon, tmp);
-               if(!rn2(30)) erode_armor(&youmonst, TRUE);
+               if(!rn2(30)) erode_armor(&youmonst, ERODE_CORRODE);
            }
            if (mhit) {
                if (aatyp == AT_KICK) {
                    if (uarmf && !rn2(6))
-                       (void)rust_dmg(uarmf, xname(uarmf), 3, TRUE);
+                       (void)rust_dmg(uarmf, xname(uarmf), ERODE_CORRODE, TRUE, TRUE);
                } else if (aatyp == AT_WEAP || aatyp == AT_CLAW ||
                           aatyp == AT_MAGC || aatyp == AT_TUCH)
                    passive_obj(mon, (struct obj*)0, &(ptr->mattk[i]));
@@ -2284,7 +2275,7 @@ boolean wep_was_destroyed;
            if(mhit && !mon->mcan) {
                if (aatyp == AT_KICK) {
                    if (uarmf)
-                       (void)rust_dmg(uarmf, xname(uarmf), 1, TRUE);
+                       (void)rust_dmg(uarmf, xname(uarmf), ERODE_RUST, TRUE, TRUE);
                } else if (aatyp == AT_WEAP || aatyp == AT_CLAW ||
                           aatyp == AT_MAGC || aatyp == AT_TUCH)
                    passive_obj(mon, (struct obj*)0, &(ptr->mattk[i]));
@@ -2294,7 +2285,7 @@ boolean wep_was_destroyed;
            if(mhit && !mon->mcan) {
                if (aatyp == AT_KICK) {
                    if (uarmf)
-                       (void)rust_dmg(uarmf, xname(uarmf), 3, TRUE);
+                       (void)rust_dmg(uarmf, xname(uarmf), ERODE_CORRODE, TRUE, TRUE);
                } else if (aatyp == AT_WEAP || aatyp == AT_CLAW ||
                           aatyp == AT_MAGC || aatyp == AT_TUCH)
                    passive_obj(mon, (struct obj*)0, &(ptr->mattk[i]));
index 32bfe1003637fb60a4f329b4fac48e5c9ed87b04..a542f3be4c6f169a1107799ea2d0e03f4a37e989 100644 (file)
@@ -583,11 +583,28 @@ which_armor(mon, flag)
 struct monst *mon;
 long flag;
 {
-       register struct obj *obj;
-
-       for(obj = mon->minvent; obj; obj = obj->nobj)
-               if (obj->owornmask & flag) return obj;
-       return((struct obj *)0);
+        if (mon == &youmonst) {
+            switch (flag) {
+                case W_ARM: return uarm;
+                case W_ARMC: return uarmc;
+                case W_ARMH: return uarmh;
+                case W_ARMS: return uarms;
+                case W_ARMG: return uarmg;
+                case W_ARMF: return uarmf;
+#ifdef TOURIST
+                case W_ARMU: return uarmu;
+#endif
+                default:
+                             impossible("bad flag in which_armor");
+                             return 0;
+            }
+        } else {
+            register struct obj *obj;
+
+            for(obj = mon->minvent; obj; obj = obj->nobj)
+                    if (obj->owornmask & flag) return obj;
+            return((struct obj *)0);
+        }
 }
 
 /* remove an item of armor and then drop it */
index 03cbc6c520f8e3fd465cbbd1f13f247eaeb1a9d4..2fb2396de20d73245e212c1d406a18c894e95ebe 100644 (file)
--- a/src/zap.c
+++ b/src/zap.c
@@ -3396,7 +3396,7 @@ struct obj **ootmp;       /* to return worn armor for caller to disintegrate */
                }
                tmp = d(nd,6);
                if (!rn2(6)) (void) erode_obj(MON_WEP(mon), 3, TRUE, FALSE);
-               if (!rn2(6)) erode_armor(mon, TRUE);
+               if (!rn2(6)) erode_armor(mon, ERODE_CORRODE);
                break;
        }
        if (sho_shieldeff) shieldeff(mon->mx, mon->my);
@@ -3525,7 +3525,7 @@ xchar sx, sy;
                (void) erode_obj(uwep, 3, TRUE, FALSE);
            if (u.twoweap && !rn2(3))
                (void) erode_obj(uswapwep, 3, TRUE, FALSE);
-           if (!rn2(6)) erode_armor(&youmonst, TRUE);
+           if (!rn2(6)) erode_armor(&youmonst, ERODE_CORRODE);
            break;
        }