User:Ogmobot/Midas Touch Patch

From NetHackWiki
< User:Ogmobot
Revision as of 02:01, 1 October 2019 by Ogmobot (talk | contribs) (Update with new version of artifact)
Jump to navigation Jump to search
diff --git a/include/artilist.h b/include/artilist.h
index d2a8c447..f487df63 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), 0, 0, NO_ATTK, NO_DFNS,
+      NO_CARY, 0, 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..787bf329 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(turn_to_gold, (struct obj *, struct monst *));
 
 /* ### attrib.c ### */
 
diff --git a/src/artifact.c b/src/artifact.c
index 1f9ebdd0..078eaadd 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)
@@ -2802,4 +2804,27 @@ struct monst *mon; /* if null, hero assumed */
     return (struct obj *) 0;
 }
 
+boolean
+turn_to_gold(obj, mon)
+struct obj *obj;
+struct monst *mon; /* if null, hero assumed */
+{
+    if (obj && (obj->material != GOLD) && valid_obj_material(obj, GOLD)
+        && !obj->oartifact) {
+        if ((mon && canseemon(mon)) || (!mon && !Blind))
+            pline("%s to gold!", Tobjnam(obj, "turn"));
+        else if ((obj == uwep || obj == uswapwep)
+                 && (matdensities[obj->material] != matdensities[GOLD]))
+            pline("%s %s.", Tobjnam(obj, "feel"),
+                  matdensities[obj->material] > matdensities[GOLD]
+                  ? "lighter" : "heavier");
+        if (!mon && matprices[obj->material] > matprices[GOLD])
+            costly_alteration(obj, COST_DEGRD);
+        set_material(obj, GOLD);
+        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/do_wear.c b/src/do_wear.c
index da2274a5..803150a0 100644
--- a/src/do_wear.c
+++ b/src/do_wear.c
@@ -610,6 +610,15 @@ Gloves_on(VOID_ARGS)
     if (uarmg->greased)
         Glib |= FROMOUTSIDE;
     uarmg->known = 1; /* gloves' +/- evident because of status line AC */
+
+    if (uarmg->oartifact == ART_MIDAS_TOUCH) {
+        if (uwep) {
+            turn_to_gold(uwep, 0);
+        }
+        if (uswapwep && u.twoweap) {
+            turn_to_gold(uswapwep, 0);
+        }
+    }
     return 0;
 }
 
diff --git a/src/makemon.c b/src/makemon.c
index ea2c0bbe..8fbbad1b 100644
--- a/src/makemon.c
+++ b/src/makemon.c
@@ -927,16 +927,23 @@ register struct monst *mtmp;
             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);
+            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);
+            item = rn2(2) ? KICKING_BOOTS : DWARVISH_BOOTS;
+            (void) mongets(mtmp, item);
+            received = m_carrying(mtmp, item);
             if (received)
                 received->material = 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..0f1c7ed1 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
@@ -3093,6 +3092,11 @@ static const struct icp metal_materials[] = {
 
 /* for objects which are normally wooden */
 static const struct icp wood_materials[] = {
+    { 0, GOLD},
+    /* Gold items of this nature can't be generated normally, but can be
+     * wished for. The gold entry must be placed before the last normal
+     * material to be considered valid.
+     */
     {80, WOOD},
     {10, MINERAL},
     { 4, IRON},
@@ -3138,6 +3142,7 @@ static const struct icp elven_materials[] = {
 
 /* for objects of orcish make - no mithril! */
 static const struct icp orcish_materials[] = {
+    { 0, GOLD},
     {65, IRON},
     {25, BONE},
     {10, MINERAL}
@@ -3180,6 +3185,7 @@ static const struct icp horn_materials[] = {
 /* hacks for specific objects... not great because it's a lot of data, but it's
  * a relatively clean solution */
 static const struct icp elven_helm_boots_materials[] = {
+    { 0, GOLD},
     {70, LEATHER},
     {15, MITHRIL},
     {10, COPPER},
@@ -3188,6 +3194,7 @@ static const struct icp elven_helm_boots_materials[] = {
 };
 
 static const struct icp dwarvish_weapon_materials[] = {
+    { 0, GOLD},
     {70, IRON},
     {25, MITHRIL},
     { 5, GEMSTONE} /* gemstone is very hard and very sharp */
diff --git a/src/uhitm.c b/src/uhitm.c
index ec354b83..47c684a0 100644
--- a/src/uhitm.c
+++ b/src/uhitm.c
@@ -1397,6 +1397,23 @@ int dieroll;
         }
     }
 
+    if ((mdat == &mons[PM_IRON_GOLEM] || mdat == &mons[PM_STONE_GOLEM])
+        && !uwep && !thrown && uarmg && uarmg->oartifact == ART_MIDAS_TOUCH) {
+        char *name = Monnam(mon);
+
+        if (newcham(mon, &mons[PM_GOLD_GOLEM], FALSE, FALSE)) {
+            if (canseemon(mon)) {
+                pline("%s turns to gold as you hit it!", name);
+                hittxt = TRUE;
+            }
+        } else {
+            if (canseemon(mon)) {
+                pline("%s seems to sparkle with gold as you hit it.", name);
+                hittxt = TRUE;
+            }
+        }
+    }
+
     if (!hittxt /*( thrown => obj exists )*/
         && (!destroyed
             || (thrown && m_shot.n > 1 && m_shot.o == obj->otyp))) {
diff --git a/src/weapon.c b/src/weapon.c
index 6f28d6dc..62ea0e23 100644
--- a/src/weapon.c
+++ b/src/weapon.c
@@ -1016,6 +1016,9 @@ register struct monst *mon;
                           ? "nearby"
                           : "in the distance");
         }
+        if (which_armor(mon, W_ARMG)
+            && which_armor(mon, W_ARMG)->oartifact == ART_MIDAS_TOUCH)
+            turn_to_gold(obj, mon);
         obj->owornmask = W_WEP;
         return 1;
     }
diff --git a/src/wield.c b/src/wield.c
index 7d57fad5..af3902d3 100644
--- a/src/wield.c
+++ b/src/wield.c
@@ -106,6 +106,10 @@ register struct obj *obj;
         && ((uwep && uwep->oartifact == ART_GIANTSLAYER)
             || (olduwep && olduwep->oartifact == ART_GIANTSLAYER)))
         context.botl = 1;
+
+    if (uwep == obj && (uarmg && uarmg->oartifact == ART_MIDAS_TOUCH))
+        turn_to_gold(obj, 0);
+
     /* Note: Explicitly wielding a pick-axe will not give a "bashing"
      * message.  Wielding one via 'a'pplying it will.
      * 3.2.2:  Wielding arbitrary objects will give bashing message too.
@@ -697,6 +701,8 @@ dotwoweapon()
         /* Success! */
         You("begin two-weapon combat.");
         u.twoweap = 1;
+        if (uarmg && uarmg->oartifact == ART_MIDAS_TOUCH)
+            turn_to_gold(uswapwep, 0);
         update_inventory();
         return (rnd(20) > ACURR(A_DEX));
     }
diff --git a/src/worn.c b/src/worn.c
index 6fd44fe7..79d37ffb 100644
--- a/src/worn.c
+++ b/src/worn.c
@@ -799,6 +799,9 @@ outer_break:
         } /* else if (!mon->minvis) pline("%s suddenly appears!",
              Amonnam(mon)); */
     }
+    if (flag == W_ARMG && best->oartifact == ART_MIDAS_TOUCH) {
+        turn_to_gold(MON_WEP(mon), mon);
+    }
 }
 #undef RACE_EXCEPTION