]> granicus.if.org Git - nethack/commitdiff
robustness of #timeout and #wizintrinsic
authorPatR <rankin@nethack.org>
Fri, 30 Jun 2017 00:54:01 +0000 (17:54 -0700)
committerPatR <rankin@nethack.org>
Fri, 30 Jun 2017 00:54:01 +0000 (17:54 -0700)
Remove the assumption of property index values from the list of
property names.  Move the properties that can't have timed values
in normal play to after those which can.  (Mainly only matters for
the #wizintrinsic command.)

Bug fix: #wizintrinsic variable 'any' wasn't initialized properly
if 'a_int' is smaller than a long or a pointer.  The separator line
I've added was ending up as a menu choice.

include/prop.h
src/cmd.c
src/timeout.c

index cb4cd3fde97418df504ea5621ff5fd66e478cad8..3bbc7182f0674401d1c9c59b0bb30c291dca952d 100644 (file)
@@ -7,7 +7,7 @@
 
 /*** What the properties are ***
  *
- * note:  propertynames[] array in timeout.c must be kept in synch with these.
+ * note:  propertynames[] array in timeout.c has string values for these.
  *        Property #0 is not used.
  */
 /* Resistances to troubles */
index 2ec304a8a7b09fbeec428b548baf9edc7e120b84..ade3352cd3e47a007ab5d22fdf01e4c8a9627664 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -135,6 +135,7 @@ STATIC_PTR int NDECL(wiz_level_change);
 STATIC_PTR int NDECL(wiz_show_seenv);
 STATIC_PTR int NDECL(wiz_show_vision);
 STATIC_PTR int NDECL(wiz_smell);
+STATIC_PTR int NDECL(wiz_intrinsic);
 STATIC_PTR int NDECL(wiz_mon_polycontrol);
 STATIC_PTR int NDECL(wiz_show_wmodes);
 STATIC_DCL void NDECL(wiz_map_levltyp);
@@ -1157,29 +1158,37 @@ STATIC_PTR int
 wiz_intrinsic(VOID_ARGS)
 {
     if (wizard) {
-        extern const char *const propertynames[]; /* timeout.c */
+        extern const struct propname {
+            int prop_num;
+            const char *prop_name;
+        } propertynames[]; /* timeout.c */
         static const char wizintrinsic[] = "#wizintrinsic";
         static const char fmt[] = "You are%s %s.";
         winid win;
         anything any;
         char buf[BUFSZ];
-        int i, n, p, amt, typ;
+        int i, j, n, p, amt, typ;
         long oldtimeout, newtimeout;
         const char *propname;
         menu_item *pick_list = (menu_item *) 0;
 
+        any = zeroany;
         win = create_nhwindow(NHW_MENU);
         start_menu(win);
-
-        for (i = 1; (propname = propertynames[i]) != 0; ++i) {
-            if (i == HALLUC_RES) {
+        for (i = 0; (propname = propertynames[i].prop_name) != 0; ++i) {
+            p = propertynames[i].prop_num;
+            if (p == HALLUC_RES) {
                 /* Grayswandir vs hallucination; ought to be redone to
                    use u.uprops[HALLUC].blocked instead of being treated
                    as a separate property; letting in be manually toggled
                    even only in wizard mode would be asking for trouble... */
                 continue;
             }
-            any.a_int = i;
+            if (p == FIRE_RES) {
+                any.a_int = 0;
+                add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, "--", FALSE);
+            }
+            any.a_int = i + 1; /* +1: avoid 0 */
             add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, propname, FALSE);
         }
         end_menu(win, "Which intrinsics?");
@@ -1187,8 +1196,9 @@ wiz_intrinsic(VOID_ARGS)
         destroy_nhwindow(win);
 
         amt = 30; /* TODO: prompt for duration */
-        for (i = 0; i < n; ++i) {
-            p = pick_list[i].item.a_int;
+        for (j = 0; j < n; ++j) {
+            i = pick_list[j].item.a_int - 1; /* -1: reverse +1 above */
+            p = propertynames[i].prop_num;
             oldtimeout = u.uprops[p].intrinsic & TIMEOUT;
             newtimeout = oldtimeout + (long) amt;
             switch (p) {
@@ -1204,9 +1214,12 @@ wiz_intrinsic(VOID_ARGS)
             case BLINDED:
                 make_blinded(newtimeout, TRUE);
                 break;
+#if 0       /* make_confused() only gives feedback when confusion is
+             * ending so use the 'default' case for it instead */
             case CONFUSION:
                 make_confused(newtimeout, TRUE);
                 break;
+#endif /*0*/
             case DEAF:
                 make_deaf(newtimeout, TRUE);
                 break;
@@ -1236,7 +1249,7 @@ wiz_intrinsic(VOID_ARGS)
                 pline1(buf);
                 break;
             default:
-                pline("Timeout for %s %s %d.", propertynames[p],
+                pline("Timeout for %s %s %d.", propertynames[i].prop_name,
                       oldtimeout ? "increased by" : "set to", amt);
                 incr_itimeout(&u.uprops[p].intrinsic, amt);
                 break;
index 66add4ec8d3d5c73a981e55aa6fabec7c5025663..81285fc37b3089ca812c88e9fcef910a4e35d49f 100644 (file)
@@ -15,43 +15,83 @@ STATIC_DCL void FDECL(see_lamp_flicker, (struct obj *, const char *));
 STATIC_DCL void FDECL(lantern_message, (struct obj *));
 STATIC_DCL void FDECL(cleanup_burn, (ANY_P *, long));
 
-/* the order of these must match their numerical sequence in prop.h
-   because the property number is inferred from the array index;
-   used by wizard mode #timeout and #wizintrinsic */
-const char *const propertynames[] = {
-               "0: not used",
-/* Resistances */
-  /*  1..2  */ "fire resistance", "cold resistance",
-  /*  3..4  */ "sleep resistance", "disintegration resistance",
-  /*  5..6  */ "shock resistance", "poison resistance",
-  /*  7..8  */ "acid resistance", "stoning resistance",
-  /*  9..10 */ "drain resistance", "sickness resistance",
-  /* 11..12 */ "invulnerable", "magic resistance",
-/* Troubles */
-  /* 13..16 */ "stunned", "confused", "blinded", "deafness",
-  /* 17..20 */ "fatally sick", "petrifying", "strangling", "vomiting",
-  /* 21..22 */ "slippery fingers", "becoming slime",
-  /* 23..24 */ "hallucinating", "halluicination resistance",
-  /* 25..28 */ "fumbling", "wounded legs", "sleepy", "voracious hunger",
-/* Vision and senses */
-  /* 29..30 */ "see invisible", "telepathic",
-  /* 31..33 */ "warning", "warn:monster", "warn:undead",
-  /* 34..37 */ "searching", "clairvoyant", "infravision", "monster detection",
-/* Appearance and behavior */
-  /* 38..41 */ "adorned (+/-Cha)", "invisible", "displaced", "stealthy",
-  /* 42..43 */ "monster aggrevation", "conflict",
-/* Transportation */
-  /* 44..46 */ "jumping", "teleporting", "teleport control",
-  /* 47..49 */ "levitating", "flying", "water walking",
-  /* 50..52 */ "swimming", "magical breathing", "pass thru walls",
-/* Physical attributes */
-  /* 53..55 */ "slow digestion", "half spell damage", "half physical damage",
-  /* 56..58 */ "HP regeneration", "energy regeneration", "extra protection",
-  /* 59     */ "protection from shape changers",
-  /* 60..62 */ "polymorphing", "polymorph control", "unchanging",
-  /* 63..66 */ "fast", "reflecting", "free action", "fixed abilites",
-  /* 67     */ "life will be saved",
-               0 /* sentinel */
+/* used by wizard mode #timeout and #wizintrinsic; order by 'interest'
+   for timeout countdown, where most won't occur in normal play */
+const struct propname {
+    int prop_num;
+    const char *prop_name;
+} propertynames[] = {
+    { INVULNERABLE, "invulnerable" },
+    { STONED, "petrifying" },
+    { SLIMED, "becoming slime" },
+    { STRANGLED, "strangling" },
+    { SICK, "fatally sick" },
+    { STUNNED, "stunned" },
+    { CONFUSION, "confused" },
+    { HALLUC, "hallucinating" },
+    { BLINDED, "blinded" },
+    { DEAF, "deafness" },
+    { VOMITING, "vomiting" },
+    { GLIB, "slippery fingers" },
+    { WOUNDED_LEGS, "wounded legs" },
+    { SLEEPY, "sleepy" },
+    { TELEPORT, "teleporting" },
+    { POLYMORPH, "polymorphing" },
+    { LEVITATION, "levitating" },
+    { FAST, "very fast" }, /* timed 'FAST' is very fast */
+    { CLAIRVOYANT, "clairvoyant" },
+    { DETECT_MONSTERS, "monster detection" },
+    { SEE_INVIS, "see invisible" },
+    { INVIS, "invisible" },
+    /* properties beyond here don't have timed values during normal play,
+       so there's no much point in trying to order them sensibly;
+       they're either on or off based on equipment, role, actions, &c */
+    { FIRE_RES, "fire resistance" },
+    { COLD_RES, "cold resistance" },
+    { SLEEP_RES, "sleep resistance" },
+    { DISINT_RES, "disintegration resistance" },
+    { SHOCK_RES, "shock resistance" },
+    { POISON_RES, "poison resistance" },
+    { ACID_RES, "acid resistance" },
+    { STONE_RES, "stoning resistance" },
+    { DRAIN_RES, "drain resistance" },
+    { SICK_RES, "sickness resistance" },
+    { ANTIMAGIC, "magic resistance" },
+    { HALLUC_RES, "hallucination resistance" },
+    { FUMBLING, "fumbling" },
+    { HUNGER, "voracious hunger" },
+    { TELEPAT, "telepathic" },
+    { WARNING, "warning" },
+    { WARN_OF_MON, "warn: monster type or class" },
+    { WARN_UNDEAD, "warn: undead" },
+    { SEARCHING, "searching" },
+    { INFRAVISION, "infravision" },
+    { ADORNED, "adorned (+/- Cha)" },
+    { DISPLACED, "displaced" },
+    { STEALTH, "stealthy" },
+    { AGGRAVATE_MONSTER, "monster aggravation" },
+    { CONFLICT, "conflict" },
+    { JUMPING, "jumping" },
+    { TELEPORT_CONTROL, "teleport control" },
+    { FLYING, "flying" },
+    { WWALKING, "water walking" },
+    { SWIMMING, "swimming" },
+    { MAGICAL_BREATHING, "magical breathing" },
+    { PASSES_WALLS, "pass thru walls" },
+    { SLOW_DIGESTION, "slow digestion" },
+    { HALF_SPDAM, "half spell damage" },
+    { HALF_PHDAM, "half physical damage" },
+    { REGENERATION, "HP regeneration" },
+    { ENERGY_REGENERATION, "energy regeneration" },
+    { PROTECTION, "extra protection" },
+    { PROT_FROM_SHAPE_CHANGERS, "protection from shape changers" },
+    { POLYMORPH_CONTROL, "polymorph control" },
+    { UNCHANGING, "unchanging" },
+    { REFLECTING, "reflecting" },
+    { FREE_ACTION, "free action" },
+    { FIXED_ABIL, "fixed abilites" },
+    { LIFESAVED, "life will be saved" },
+    {  0, 0 },
 };
 
 /* He is being petrified - dialogue by inmet!tower */
@@ -1544,7 +1584,7 @@ wiz_timeout_queue()
     char buf[BUFSZ];
     const char *propname;
     long intrinsic;
-    int i, count, longestlen, ln;
+    int i, p, count, longestlen, ln, specindx = 0;
 
     win = create_nhwindow(NHW_MENU); /* corner text window */
     if (win == WIN_ERR)
@@ -1562,13 +1602,16 @@ wiz_timeout_queue()
      * normal play but those can be forced via the #wizintrinsic command.
      */
     count = longestlen = 0;
-    for (i = 1; (propname = propertynames[i]) != 0; ++i) { /* [0] not used */
-        intrinsic = u.uprops[i].intrinsic;
+    for (i = 0; (propname = propertynames[i].prop_name) != 0; ++i) {
+        p = propertynames[i].prop_num;
+        intrinsic = u.uprops[p].intrinsic;
         if (intrinsic & TIMEOUT) {
             ++count;
             if ((ln = (int) strlen(propname)) > longestlen)
                 longestlen = ln;
         }
+        if (specindx == 0 && p == FIRE_RES)
+            specindx = i;
     }
     putstr(win, 0, "");
     if (!count) {
@@ -1576,9 +1619,14 @@ wiz_timeout_queue()
     } else {
         putstr(win, 0, "Timed properties:");
         putstr(win, 0, "");
-        for (i = 1; (propname = propertynames[i]) != 0; ++i) {
-            intrinsic = u.uprops[i].intrinsic;
+        for (i = 0; (propname = propertynames[i].prop_name) != 0; ++i) {
+            p = propertynames[i].prop_num;
+            intrinsic = u.uprops[p].intrinsic;
             if (intrinsic & TIMEOUT) {
+                if (specindx > 0 && i >= specindx) {
+                    putstr(win, 0, " -- settable via #wizinstrinc only --");
+                    specindx = 0;
+                }
                 /* timeout value can be up to 16777215 (0x00ffffff) but
                    width of 4 digits should result in values lining up
                    almost all the time (if/when they don't, it won't