]> granicus.if.org Git - nethack/commitdiff
exploding wands
authornethack.rankin <nethack.rankin>
Sat, 23 Apr 2005 05:07:32 +0000 (05:07 +0000)
committernethack.rankin <nethack.rankin>
Sat, 23 Apr 2005 05:07:32 +0000 (05:07 +0000)
     Pointed out by <Someone>:  engraving with a cursed wand should pose a
risk of having it explode just like zapping does.  [At the moment when one
explodes, any existing engraving doesn't get changed.]  Suggested by someone
(<Someone>?) some time back:  explosion due to recharging could be consolidated
with explosion due to zapping cursed wands.  And noted by <Someone> in the
newsgroup:  '+' in an engraving--perhaps written by someone trying to leave
bones file notes--should have a chance of being partially rubbed out to '-'.

doc/fixes34.4
include/extern.h
src/engrave.c
src/read.c

index 898e9cedb1a6906fa04ea48e8f4099eecc597b60..aea59ed743dc1be827e9881b8756b00fa38740dd 100644 (file)
@@ -117,6 +117,7 @@ with astral vision, the ";" command should only display "normal vision"
        for things that could be seen without astral vision
 reanimating a statue containing gold produced double gold
 probing the resulting double-gold monster caused "static object freed" panic
+cursed wand might explode if used to engrave
 
 
 Platform- and/or Interface-Specific Fixes
index 8156471322c2b7e36e248e9d93e6949e280c9e27..9132614eccb87fac08f91c79e6e8a52a07c5f83e 100644 (file)
@@ -1711,6 +1711,7 @@ E void FDECL(forget_levels, (int));
 E void NDECL(forget_traps);
 E void FDECL(forget_map, (int));
 E int FDECL(seffects, (struct obj *));
+E void FDECL(wand_explode, (struct obj *,int));
 #ifdef USE_TRAMPOLI
 E void FDECL(set_lit, (int,int,genericptr_t));
 #endif
index 30cfc23a77d6328ea0b3444b85c459921cdcd7e5..388253cbb8ddec62f0183c171c31baf4eb3f19da 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)engrave.c  3.5     2005/03/28      */
+/*     SCCS Id: @(#)engrave.c  3.5     2005/04/22      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -64,7 +64,8 @@ static const struct {
        {'h', "n"},     {'j', "i"},     {'k', "|"},     {'l', "|"},
        {'m', "nr"},    {'n', "r"},     {'o', "c"},     {'q', "c"},
        {'w', "v"},     {'y', "v"},
-       {':', "."},     {';', ","},
+       {':', "."},     {';', ",:"},    {',', "."},     {'=', "-"},
+       {'+', "-|"},    {'*', "+"},     {'@', "0"},
        {'0', "C("},    {'1', "|"},     {'6', "o"},     {'7', "/"},
        {'8', "3o"}
 };
@@ -594,6 +595,10 @@ doengrave()
            case WAND_CLASS:
                if (zappable(otmp)) {
                    check_unpaid(otmp);
+                   if (otmp->cursed && !rn2(100)) { /* same as when zapping */
+                       wand_explode(otmp, 0);
+                       return 1;
+                   }
                    zapwand = TRUE;
                    if (Levitation) ptext = FALSE;
 
@@ -857,7 +862,8 @@ doengrave()
            pline("%s %sturns to dust.",
                  The(xname(otmp)), Blind ? "" : "glows violently, then ");
            if (!IS_GRAVE(levl[u.ux][u.uy].typ))
-               You("are not going to get anywhere trying to write in the %s with your dust.",
+               You(
+     "are not going to get anywhere trying to write in the %s with your dust.",
                    is_ice(u.ux,u.uy) ? "frost" : "dust");
            useup(otmp);
            ptext = FALSE;
index 80def904dcdad9e979113426f55dbda1ab60b0bd..9576e9f4cbfed243715f4a8476cf5ec14dcdbfa1 100644 (file)
@@ -17,7 +17,6 @@ static NEARDATA const char readable[] =
                   { ALL_CLASSES, SCROLL_CLASS, SPBOOK_CLASS, 0 };
 static const char all_count[] = { ALLOW_COUNT, ALL_CLASSES, 0 };
 
-STATIC_DCL void FDECL(wand_explode, (struct obj *));
 STATIC_DCL void NDECL(do_class_genocide);
 STATIC_DCL void FDECL(stripspe,(struct obj *));
 STATIC_DCL void FDECL(p_glow1,(struct obj *));
@@ -214,6 +213,9 @@ int curse_bless;
        is_blessed = curse_bless > 0;
 
        if (obj->oclass == WAND_CLASS) {
+           int lim = (obj->otyp == WAN_WISHING) ? 3 :
+                       (objects[obj->otyp].oc_dir != NODIR) ? 8 : 15;
+
            /* undo any prior cancellation, even when is_cursed */
            if (obj->spe == -1) obj->spe = 0;
 
@@ -234,7 +236,7 @@ int curse_bless;
            n = (int)obj->recharged;
            if (n > 0 && (obj->otyp == WAN_WISHING ||
                    (n * n * n > rn2(7*7*7)))) {        /* recharge_limit */
-               wand_explode(obj);
+               wand_explode(obj, rnd(lim));
                return;
            }
            /* didn't explode, so increment the recharge count */
@@ -244,16 +246,13 @@ int curse_bless;
            if (is_cursed) {
                stripspe(obj);
            } else {
-               int lim = (obj->otyp == WAN_WISHING) ? 3 :
-                       (objects[obj->otyp].oc_dir != NODIR) ? 8 : 15;
-
                n = (lim == 3) ? 3 : rn1(5, lim + 1 - 5);
                if (!is_blessed) n = rnd(n);
 
                if (obj->spe < n) obj->spe = n;
                else obj->spe++;
                if (obj->otyp == WAN_WISHING && obj->spe > 3) {
-                   wand_explode(obj);
+                   wand_explode(obj, 1);
                    return;
                }
                if (obj->spe >= lim) p_glow2(obj, NH_BLUE);
@@ -1364,17 +1363,45 @@ struct obj *sobj;
        return(0);
 }
 
-STATIC_OVL void
-wand_explode(obj)
-register struct obj *obj;
+/* overcharging any wand or zapping/engraving cursed wand */
+void
+wand_explode(obj, chg)
+struct obj *obj;
+int chg;               /* recharging */
 {
-    int vibration_dmg;
-    obj->in_use = TRUE;        /* in case losehp() is fatal */
-    pline("%s vibrates violently, and explodes!", Yname2(obj));
-    nhbell();
-    vibration_dmg = rnd(2*(u.uhpmax+1)/3); 
-    losehp(Maybe_Half_Phys(vibration_dmg), "exploding wand", KILLED_BY_AN);
+    const char *expl = !chg ? "suddenly" : "vibrates violently and";
+    int dmg, n, k;
+
+    /* number of damage dice */
+    if (!chg) chg = 2;         /* zap/engrave adjustment */
+    n = obj->spe + chg;
+    if (n < 2) n = 2;          /* arbitrary minimum */
+    /* size of damage dice */
+    switch (obj->otyp) {
+    case WAN_WISHING:
+       k = 12; break;
+    case WAN_CANCELLATION:
+    case WAN_DEATH:
+    case WAN_POLYMORPH:
+    case WAN_UNDEAD_TURNING:
+       k = 10; break;
+    case WAN_COLD:
+    case WAN_FIRE:
+    case WAN_LIGHTNING:
+    case WAN_MAGIC_MISSILE:
+       k = 8; break;
+    case WAN_NOTHING:
+       k = 4; break;
+    default:
+       k = 6; break;
+    }
+    /* inflict damage and destroy the wand */
+    dmg = d(n, k);
+    obj->in_use = TRUE;                /* in case losehp() is fatal (or --More--^C) */
+    pline("%s %s explodes!", Yname2(obj), expl);
+    losehp(Maybe_Half_Phys(dmg), "exploding wand", KILLED_BY_AN);
     useup(obj);
+    /* obscure side-effect */
     exercise(A_STR, FALSE);
 }