]> granicus.if.org Git - nethack/commitdiff
Generate random eroded, erodeproof, or greased items
authorPasi Kallinen <paxed@alt.org>
Sun, 29 Jan 2023 09:15:38 +0000 (11:15 +0200)
committerPasi Kallinen <paxed@alt.org>
Sun, 29 Jan 2023 09:20:03 +0000 (11:20 +0200)
Items in initial hero inventory, or generated via lua in
special levels or themed rooms are not subject to this.

Code via xnethack by copperwater <aosdict@gmail.com>,
with some modifications.

doc/fixes3-7-0.txt
src/mkobj.c
src/sp_lev.c

index 1915cd325c5f040863aae7e52c590efebef89794..de34e3c344731e0062a53f66d7a8307533bbfa62 100644 (file)
@@ -1101,6 +1101,7 @@ eating garlic makes nearby monsters flee
 giants occasionally get a battle axe or a two-handed sword
 give gremlin the property it stole, if possible
 'F'orcefighting with a war hammer has a small chance of breaking iron bars
+very rarely random items are generated eroded, erodeproof, or greased
 
 
 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
index 42181f273c8b9b607c2179a201f6f78bc3206fee..9dc92475f6bd92c61e2063e0be84720e0b6b74f1 100644 (file)
@@ -5,6 +5,8 @@
 
 #include "hack.h"
 
+static boolean may_generate_eroded(struct obj *);
+static void mkobj_erosions(struct obj *);
 static void mkbox_cnts(struct obj *);
 static unsigned nextoid(struct obj *, struct obj *);
 static int item_on_ice(struct obj *);
@@ -168,6 +170,54 @@ free_omailcmd(struct obj *otmp)
     }
 }
 
+/* can object be generated eroded? */
+static boolean
+may_generate_eroded(struct obj *otmp)
+{
+    /* initial hero inventory */
+    if (gm.moves <= 1 && !gi.in_mklev)
+        return FALSE;
+    /* already erodeproof or cannot be eroded */
+    if (otmp->oerodeproof || !erosion_matters(otmp) || !is_damageable(otmp))
+        return FALSE;
+    /* part of a monster's body and produced when it dies */
+    if (otmp->otyp == WORM_TOOTH || otmp->otyp == UNICORN_HORN)
+        return FALSE;
+    /* artifacts cannot be generated eroded  */
+    if (otmp->oartifact)
+        return FALSE;
+    return TRUE;
+}
+
+/* random chance of applying erosions/grease to object */
+static void
+mkobj_erosions(struct obj *otmp)
+{
+    if (may_generate_eroded(otmp)) {
+        /* A small fraction of non-artifact items will generate eroded or
+         * possibly erodeproof. An item that generates eroded will never be
+         * erodeproof, and vice versa. */
+        if (!rn2(100)) {
+            otmp->oerodeproof = 1;
+        } else {
+            if (!rn2(80) && (is_flammable(otmp) || is_rustprone(otmp))) {
+                do {
+                    otmp->oeroded++;
+                } while (otmp->oeroded < 3 && !rn2(9));
+            }
+            if (!rn2(80) && (is_rottable(otmp) || is_corrodeable(otmp))) {
+                do {
+                    otmp->oeroded2++;
+                } while (otmp->oeroded2 < 3 && !rn2(9));
+            }
+        }
+        /* and an extremely small fraction of the time, erodable items
+         * will generate greased */
+        if (!rn2(1000))
+            otmp->greased = 1;
+    }
+}
+
 struct obj *
 mkobj_at(char let, coordxy x, coordxy y, boolean artif)
 {
@@ -1097,6 +1147,8 @@ mksobj(int otyp, boolean init, boolean artif)
         }
     }
 
+    mkobj_erosions(otmp);
+
     /* some things must get done (corpsenm, timers) even if init = 0 */
     switch ((otmp->oclass == POTION_CLASS && otmp->otyp != POT_OIL)
             ? POT_WATER
index 25dfffa187d739ae74b00a396a248b7ee7bbf5cf..e067f34e4dc2c24bda8acf4866512e1626076452 100644 (file)
@@ -2217,6 +2217,9 @@ create_object(object* o, struct mkroom* croom)
             otmp->oeroded = (o->eroded % 4);
             otmp->oeroded2 = ((o->eroded >> 2) % 4);
         }
+    } else {
+        otmp->oeroded = otmp->oeroded2 = 0;
+        otmp->oerodeproof = 0;
     }
     if (o->recharged)
         otmp->recharged = (o->recharged % 8);
@@ -2230,6 +2233,9 @@ create_object(object* o, struct mkroom* croom)
         otmp->otrapped = o->trapped;
     if (o->greased)
         otmp->greased = 1;
+    else {
+        otmp->greased = 0;
+    }
 
     if (o->quan > 0 && objects[otmp->otyp].oc_merge) {
         otmp->quan = o->quan;