User:Ogmobot/Midas Touch Patch

From NetHackWiki
Jump to navigation Jump to search
diff --git a/include/artifact.h b/include/artifact.h
index 987c0bf6..d45229b1 100644
--- a/include/artifact.h
+++ b/include/artifact.h
@@ -68,7 +68,8 @@ enum invoke_prop_types {
     CREATE_PORTAL,
     ENLIGHTENING,
     CREATE_AMMO,
-    PHASING
+    PHASING,
+    CHANGE_MATERIAL
 };
 
 #endif /* ARTIFACT_H */
diff --git a/include/artilist.h b/include/artilist.h
index d2a8c447..119a7a0b 100644
--- a/include/artilist.h
+++ b/include/artilist.h
@@ -221,6 +221,10 @@ STATIC_OVL NEARDATA struct artifact artilist[] = {
     A("Luck Blade", BROADSWORD, (SPFX_RESTR | SPFX_LUCK | SPFX_INTEL), 0, 0,
       PHYS(5,6), NO_DFNS, NO_CARY, 0, A_CHAOTIC, PM_CONVICT, NON_PM, 3000L,
       NO_COLOR),
+    /* Golden gauntlets that turn wielded items into gold. These belong to Croesus.
+     */
+    A("Midas Touch", GAUNTLETS, (SPFX_NOGEN | SPFX_RESTR | SPFX_DEFN), 0, 0, NO_ATTK, DFNS(AD_DISE),
+      NO_CARY, CHANGE_MATERIAL, A_NEUTRAL, NON_PM, NON_PM, 5000L, NO_COLOR),
 
     /*
      *      The artifacts for the quest dungeon, all self-willed.
diff --git a/include/extern.h b/include/extern.h
index 13ce605c..b99b2ca4 100644
--- a/include/extern.h
+++ b/include/extern.h
@@ -104,6 +104,7 @@ E void FDECL(retouch_equipment, (int));
 E void NDECL(mkot_trap_warn);
 E boolean FDECL(is_magic_key, (struct monst *, struct obj *));
 E struct obj *FDECL(has_magic_key, (struct monst *));
+E boolean FDECL(change_material, (struct obj *, int mat));
 
 /* ### attrib.c ### */
 
diff --git a/src/artifact.c b/src/artifact.c
index 1f9ebdd0..21f2dfbc 100644
--- a/src/artifact.c
+++ b/src/artifact.c
@@ -15,6 +15,8 @@
  */
 
 extern boolean notonhead; /* for long worms */
+extern const int matprices[];
+extern const int matdensities[];
 
 #define get_artifact(o) \
     (((o) && (o)->oartifact) ? &artilist[(int) (o)->oartifact] : 0)
@@ -2146,6 +2148,24 @@ struct obj *obj;
             incr_itimeout(&HPasses_walls, (50 + rnd(100)));
             obj->age += HPasses_walls; /* Time begins after phasing ends */
             break;
+        case CHANGE_MATERIAL: {
+            int mat, tryct = 0;
+            if (oart == &artilist[ART_MIDAS_TOUCH])
+                /* Transform wielded item into gold, if possible */
+                mat = GOLD;
+            else if (uwep) {
+                /* Transform wielded item into something different */
+                mat = uwep->material;
+                while ((mat == uwep->material
+                       || (mat == objects[uwep->otyp].oc_material && rn2(3))
+                       || !valid_obj_material(uwep, mat)) && tryct++ < 100)
+                    mat = rnd(NUM_MATERIAL_TYPES - 1);
+            } else
+                mat = 0; /* Should always be invalid */
+            if (!change_material(uwep, mat))
+                goto nothing_special;
+            break;
+        }
         }
     } else {
         long eprop = (u.uprops[oart->inv_prop].extrinsic ^= W_ARTI),
@@ -2802,4 +2822,30 @@ struct monst *mon; /* if null, hero assumed */
     return (struct obj *) 0;
 }
 
+/* Changes an object into the given material, if possible.
+ * TODO: allow some objects to change to a material that's not
+ *       usually allowed for it; e.g. gold orcish items.
+ */
+boolean
+change_material(obj, mat)
+struct obj *obj;
+int mat;
+{
+    if (obj && obj->material != mat && !obj->oartifact
+        && valid_obj_material(obj, mat)) {
+        if (!Blind)
+            pline("%s %s!", Tobjnam(obj, "become"), materialnm[mat]);
+        else if ((obj == uwep || obj == uswapwep)
+                 && (matdensities[obj->material] != matdensities[mat]))
+            pline("%s %s.", Tobjnam(obj, "feel"),
+                  matdensities[obj->material] > matdensities[mat]
+                  ? "lighter" : "heavier");
+        if (carried(obj) && matprices[obj->material] > matprices[mat])
+            costly_alteration(obj, COST_DEGRD);
+        set_material(obj, mat);
+        return TRUE;
+    } else
+        return FALSE;
+}
+
 /*artifact.c*/
diff --git a/src/do_name.c b/src/do_name.c
index 8e037c37..2eea2482 100644
--- a/src/do_name.c
+++ b/src/do_name.c
@@ -1350,6 +1350,9 @@ const char *name;
         case ART_IRON_BALL_OF_LIBERATION:
             set_material(obj, IRON);
             break;
+        case ART_MIDAS_TOUCH:
+            set_material(obj, GOLD);
+            break;
         default:
             /* prevent any wishes for materials on an artifact */
             set_material(obj, objects[obj->otyp].oc_material);
diff --git a/src/makemon.c b/src/makemon.c
index ea2c0bbe..f2ad939d 100644
--- a/src/makemon.c
+++ b/src/makemon.c
@@ -921,22 +921,29 @@ register struct monst *mtmp;
             (void) mongets(mtmp, TWO_HANDED_SWORD);
             struct obj* received = m_carrying(mtmp, TWO_HANDED_SWORD);
             if (received)
-                received->material = GOLD;
+                set_material(received, GOLD);
             int item = rn2(2) ? BANDED_MAIL : PLATE_MAIL;
             (void) mongets(mtmp, item);
             received = m_carrying(mtmp, item);
             if (received)
-                received->material = GOLD;
-            int item2 = rn2(2) ? HELMET : DWARVISH_HELM;
-            (void) mongets(mtmp, item2);
-            received = m_carrying(mtmp, item2);
+                set_material(received, GOLD);
+            item = rn2(2) ? HELMET : DWARVISH_HELM;
+            (void) mongets(mtmp, item);
+            received = m_carrying(mtmp, item);
             if (received)
-                received->material = GOLD;
-            int item3 = rn2(2) ? KICKING_BOOTS : DWARVISH_BOOTS;
-            (void) mongets(mtmp, item3);
-            received = m_carrying(mtmp, item3);
+                set_material(received, GOLD);
+            item = rn2(2) ? KICKING_BOOTS : DWARVISH_BOOTS;
+            (void) mongets(mtmp, item);
+            received = m_carrying(mtmp, item);
             if (received)
-                received->material = GOLD;
+                set_material(received, GOLD);
+            otmp = mksobj(GAUNTLETS, FALSE, FALSE);
+            otmp->material = GOLD;
+            if (!rn2(2)) {
+                otmp = oname(otmp, artiname(ART_MIDAS_TOUCH));
+                curse(otmp);
+            }
+            (void) mpickobj(mtmp, otmp);
         }
         break;
 
diff --git a/src/mkobj.c b/src/mkobj.c
index c977853a..f2b1e9cc 100644
--- a/src/mkobj.c
+++ b/src/mkobj.c
@@ -1459,7 +1459,6 @@ unsigned onoff; /* 1 or 0 */
  * counterpart, and things such as wooden plate mails were incredibly
  * overpowered by weighing about one-tenth as much as the iron counterpart.
  * Instead, use arbitrary units. */
-STATIC_DCL
 const int matdensities[] = {
     0,   // will cause div/0 errors if anything is this material
     10,  // LIQUID