From b3d9ab51830544bb7fc7cdfb97ec7f45c6593a99 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 24 Apr 2026 11:14:53 -0400 Subject: [PATCH 001/702] revisit the "Welcome back" message Also takes helm into consideration now Closes #537 --- src/allmain.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/allmain.c b/src/allmain.c index 5a05add72..e9865e73e 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -858,7 +858,8 @@ void welcome(boolean new_game) /* false => restoring an old game */ { char buf[BUFSZ]; - boolean currentgend = Upolyd ? u.mfemale : flags.female; + boolean currentgend = Upolyd ? u.mfemale : flags.female, + adrift = (u.ualign.type != u.ualignbase[A_CURRENT]); l_nhcore_call(new_game ? NHCORE_START_NEW_GAME : NHCORE_RESTORE_OLD_GAME); @@ -881,8 +882,30 @@ welcome(boolean new_game) /* false => restoring an old game */ * restores it's only shown if different from its original value. */ *buf = '\0'; +#if 0 if (new_game || u.ualignbase[A_ORIGINAL] != u.ualignbase[A_CURRENT]) Sprintf(eos(buf), " %s", align_str(u.ualignbase[A_ORIGINAL])); +#else + /* + * 2026-04-24 + * GitHub issue https://github.com/NetHack/NetHack/issues/537 + * "Judging by the comment above, it should display your new alignment + * if it was changed, so align_str(u.ualignbase[A_CURRENT]) would + * probably be more appropriate. This won't affect the new game message." + * + * That is followed by a suggestion to revisit the matter (paraphrased): + * "That's actually intentional; the comment oversimplifies. + * When it was implemented, it may have been the only way to tell that + * you had converted alignment. Now ^X mentions your starting alignment + * if base alignment has been changed, so revisiting this welcome back + * message." + */ + if (new_game || u.ualignbase[A_ORIGINAL] != u.ualignbase[A_CURRENT] || adrift) + Sprintf(eos(buf), " %s%s", + adrift ? "adrift " : "", + adrift ? align_str(u.ualign.type) + : align_str(u.ualignbase[A_CURRENT])); +#endif if (!gu.urole.name.f && (new_game ? (gu.urole.allow & ROLE_GENDMASK) == (ROLE_MALE | ROLE_FEMALE) From 88a47cc7b67b9330b0e8bf6aea6292b6efe9dd5e Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 24 Apr 2026 20:13:01 -0400 Subject: [PATCH 002/702] colortable[] formatting remove unused hexval field (show it in a comment) The rgb values should be the same as they were previously, just expressed with hex values on the table initialization. --- include/color.h | 1 - src/coloratt.c | 323 +++++++++++++++++++++++++----------------------- 2 files changed, 167 insertions(+), 157 deletions(-) diff --git a/include/color.h b/include/color.h index a1fa5327b..60e4dcb6c 100644 --- a/include/color.h +++ b/include/color.h @@ -65,7 +65,6 @@ struct nethack_color { int tableindex; int rgbindex; const char *name; - const char *hexval; long r, g, b; }; diff --git a/src/coloratt.c b/src/coloratt.c index 436e9274e..d6adf6673 100644 --- a/src/coloratt.c +++ b/src/coloratt.c @@ -58,166 +58,177 @@ static const struct attr_names attrnames[] = { { "reverse", ATR_INVERSE }, }; -/* { colortyp, tableindex, rgbindx, name, hexval, r, g, b }, */ +/* { colortyp, tableindex, rgbindx, name, r, g, b }, */ + +#define NHC nh_color +#define NOC no_color +#define RGBC rgb_color static struct nethack_color colortable[] = { - { nh_color, 0, 0, "black", "", 0, 0, 0 }, - { nh_color, 1, 0, "red", "", 255, 0, 0 }, - { nh_color, 2, 0, "green", "", 34, 139, 34 }, - { nh_color, 3, 0, "brown", "", 165, 42, 42 }, - { nh_color, 4, 0, "blue", "", 0, 0, 255 }, - { nh_color, 5, 0, "magenta", "", 255, 0, 255 }, - { nh_color, 6, 0, "cyan", "", 0, 255, 255 }, - { nh_color, 7, 0, "gray", "", 128, 128, 128 }, - { no_color, 8, 0, "nocolor", "", 0, 0, 0 }, - { nh_color, 9, 0, "orange", "", 255, 165, 0 }, - { nh_color, 10, 0, "bright-green", "", 0, 128, 0 }, - { nh_color, 11, 0, "yellow", "", 255, 255, 0 }, - { nh_color, 12, 0, "bright-blue", "", 173, 216, 230 }, - { nh_color, 13, 0, "bright-magenta", "", 147, 112, 219 }, - { nh_color, 14, 0, "light-cyan", "", 224, 255, 255 }, - { nh_color, 15, 0, "white", "", 255, 255, 255 }, - { rgb_color, 16, 0, "maroon", "#800000", 128, 0, 0 }, - { rgb_color, 17, 1, "dark-red", "#8B0000", 139, 0, 0 }, - { rgb_color, 18, 2, "brown", "#A52A2A", 165, 42, 42 }, - { rgb_color, 19, 3, "firebrick", "#B22222", 178, 34, 34 }, - { rgb_color, 20, 4, "crimson", "#DC143C", 220, 20, 60 }, - { rgb_color, 21, 5, "red", "#FF0000", 255, 0, 0 }, - { rgb_color, 22, 6, "tomato", "#FF6347", 255, 99, 71 }, - { rgb_color, 23, 7, "coral", "#FF7F50", 255, 127, 80 }, - { rgb_color, 24, 8, "indian-red", "#CD5C5C", 205, 92, 92 }, - { rgb_color, 25, 9, "light-coral", "#F08080", 240, 128, 128 }, - { rgb_color, 26, 10, "dark-salmon", "#E9967A", 233, 150, 122 }, - { rgb_color, 27, 11, "salmon", "#FA8072", 250, 128, 114 }, - { rgb_color, 28, 12, "light-salmon", "#FFA07A", 255, 160, 122 }, - { rgb_color, 29, 13, "orange-red", "#FF4500", 255, 69, 0 }, - { rgb_color, 30, 14, "dark-orange", "#FF8C00", 255, 140, 0 }, - { rgb_color, 31, 15, "orange", "#FFA500", 255, 165, 0 }, - { rgb_color, 32, 16, "gold", "#FFD700", 255, 215, 0 }, - { rgb_color, 33, 17, "dark-golden-rod", "#B8860B", 184, 134, 11 }, - { rgb_color, 34, 18, "golden-rod", "#DAA520", 218, 165, 32 }, - { rgb_color, 35, 19, "pale-golden-rod", "#EEE8AA", 238, 232, 170 }, - { rgb_color, 36, 20, "dark-khaki", "#BDB76B", 189, 183, 107 }, - { rgb_color, 37, 21, "khaki", "#F0E68C", 240, 230, 140 }, - { rgb_color, 38, 22, "olive", "#808000", 128, 128, 0 }, - { rgb_color, 39, 23, "yellow", "#FFFF00", 255, 255, 0 }, - { rgb_color, 40, 24, "yellow-green", "#9ACD32", 154, 205, 50 }, - { rgb_color, 41, 25, "dark-olive-green", "#556B2F", 85, 107, 47 }, - { rgb_color, 42, 26, "olive-drab", "#6B8E23", 107, 142, 35 }, - { rgb_color, 43, 27, "lawn-green", "#7CFC00", 124, 252, 0 }, - { rgb_color, 44, 28, "chart-reuse", "#7FFF00", 127, 255, 0 }, - { rgb_color, 45, 29, "green-yellow", "#ADFF2F", 173, 255, 47 }, - { rgb_color, 46, 30, "dark-green", "#006400", 0, 100, 0 }, - { rgb_color, 47, 31, "green", "#008000", 0, 128, 0 }, - { rgb_color, 48, 32, "forest-green", "#228B22", 34, 139, 34 }, - { rgb_color, 49, 33, "lime", "#00FF00", 0, 255, 0 }, - { rgb_color, 50, 34, "lime-green", "#32CD32", 50, 205, 50 }, - { rgb_color, 51, 35, "light-green", "#90EE90", 144, 238, 144 }, - { rgb_color, 52, 36, "pale-green", "#98FB98", 152, 251, 152 }, - { rgb_color, 53, 37, "dark-sea-green", "#8FBC8F", 143, 188, 143 }, - { rgb_color, 54, 38, "medium-spring-green", "#00FA9A", 0, 250, 154 }, - { rgb_color, 55, 39, "spring-green", "#00FF7F", 0, 255, 127 }, - { rgb_color, 56, 40, "sea-green", "#2E8B57", 46, 139, 87 }, - { rgb_color, 57, 41, "medium-aqua-marine", "#66CDAA", 102, 205, 170 }, - { rgb_color, 58, 42, "medium-sea-green", "#3CB371", 60, 179, 113 }, - { rgb_color, 59, 43, "light-sea-green", "#20B2AA", 32, 178, 170 }, - { rgb_color, 60, 44, "dark-slate-gray", "#2F4F4F", 47, 79, 79 }, - { rgb_color, 61, 45, "teal", "#008080", 0, 128, 128 }, - { rgb_color, 62, 46, "dark-cyan", "#008B8B", 0, 139, 139 }, - { rgb_color, 63, 47, "aqua", "#00FFFF", 0, 255, 255 }, - { rgb_color, 64, 48, "cyan", "#00FFFF", 0, 255, 255 }, - { rgb_color, 65, 49, "light-cyan", "#E0FFFF", 224, 255, 255 }, - { rgb_color, 66, 50, "dark-turquoise", "#00CED1", 0, 206, 209 }, - { rgb_color, 67, 51, "turquoise", "#40E0D0", 64, 224, 208 }, - { rgb_color, 68, 52, "medium-turquoise", "#48D1CC", 72, 209, 204 }, - { rgb_color, 69, 53, "pale-turquoise", "#AFEEEE", 175, 238, 238 }, - { rgb_color, 70, 54, "aqua-marine", "#7FFFD4", 127, 255, 212 }, - { rgb_color, 71, 55, "powder-blue", "#B0E0E6", 176, 224, 230 }, - { rgb_color, 72, 56, "cadet-blue", "#5F9EA0", 95, 158, 160 }, - { rgb_color, 73, 57, "steel-blue", "#4682B4", 70, 130, 180 }, - { rgb_color, 74, 58, "corn-flower-blue", "#6495ED", 100, 149, 237 }, - { rgb_color, 75, 59, "deep-sky-blue", "#00BFFF", 0, 191, 255 }, - { rgb_color, 76, 60, "dodger-blue", "#1E90FF", 30, 144, 255 }, - { rgb_color, 77, 61, "light-blue", "#ADD8E6", 173, 216, 230 }, - { rgb_color, 78, 62, "sky-blue", "#87CEEB", 135, 206, 235 }, - { rgb_color, 79, 63, "light-sky-blue", "#87CEFA", 135, 206, 250 }, - { rgb_color, 80, 64, "midnight-blue", "#191970", 25, 25, 112 }, - { rgb_color, 81, 65, "navy", "#000080", 0, 0, 128 }, - { rgb_color, 82, 66, "dark-blue", "#00008B", 0, 0, 139 }, - { rgb_color, 83, 67, "medium-blue", "#0000CD", 0, 0, 205 }, - { rgb_color, 84, 68, "blue", "#0000FF", 0, 0, 255 }, - { rgb_color, 85, 69, "royal-blue", "#4169E1", 65, 105, 225 }, - { rgb_color, 86, 70, "blue-violet", "#8A2BE2", 138, 43, 226 }, - { rgb_color, 87, 71, "indigo", "#4B0082", 75, 0, 130 }, - { rgb_color, 88, 72, "dark-slate-blue", "#483D8B", 72, 61, 139 }, - { rgb_color, 89, 73, "slate-blue", "#6A5ACD", 106, 90, 205 }, - { rgb_color, 90, 74, "medium-slate-blue", "#7B68EE", 123, 104, 238 }, - { rgb_color, 91, 75, "medium-purple", "#9370DB", 147, 112, 219 }, - { rgb_color, 92, 76, "dark-magenta", "#8B008B", 139, 0, 139 }, - { rgb_color, 93, 77, "dark-violet", "#9400D3", 148, 0, 211 }, - { rgb_color, 94, 78, "dark-orchid", "#9932CC", 153, 50, 204 }, - { rgb_color, 95, 79, "medium-orchid", "#BA55D3", 186, 85, 211 }, - { rgb_color, 96, 80, "purple", "#800080", 128, 0, 128 }, - { rgb_color, 97, 81, "thistle", "#D8BFD8", 216, 191, 216 }, - { rgb_color, 98, 82, "plum", "#DDA0DD", 221, 160, 221 }, - { rgb_color, 99, 83, "violet", "#EE82EE", 238, 130, 238 }, - { rgb_color, 100, 84, "magenta", "#FF00FF", 255, 0, 255 }, - { rgb_color, 101, 85, "orchid", "#DA70D6", 218, 112, 214 }, - { rgb_color, 102, 86, "medium-violet-red", "#C71585", 199, 21, 133 }, - { rgb_color, 103, 87, "pale-violet-red", "#DB7093", 219, 112, 147 }, - { rgb_color, 104, 88, "deep-pink", "#FF1493", 255, 20, 147 }, - { rgb_color, 105, 89, "hot-pink", "#FF69B4", 255, 105, 180 }, - { rgb_color, 106, 90, "light-pink", "#FFB6C1", 255, 182, 193 }, - { rgb_color, 107, 91, "pink", "#FFC0CB", 255, 192, 203 }, - { rgb_color, 108, 92, "antique-white", "#FAEBD7", 250, 235, 215 }, - { rgb_color, 109, 93, "beige", "#F5F5DC", 245, 245, 220 }, - { rgb_color, 110, 94, "bisque", "#FFE4C4", 255, 228, 196 }, - { rgb_color, 111, 95, "blanched-almond", "#FFEBCD", 255, 235, 205 }, - { rgb_color, 112, 96, "wheat", "#F5DEB3", 245, 222, 179 }, - { rgb_color, 113, 97, "corn-silk", "#FFF8DC", 255, 248, 220 }, - { rgb_color, 114, 98, "lemon-chiffon", "#FFFACD", 255, 250, 205 }, - { rgb_color, 115, 99, "light-golden-rod-yellow", "#FAFAD2", 250, 250, 210 }, - { rgb_color, 116, 100, "light-yellow", "#FFFFE0", 255, 255, 224 }, - { rgb_color, 117, 101, "saddle-brown", "#8B4513", 139, 69, 19 }, - { rgb_color, 118, 102, "sienna", "#A0522D", 160, 82, 45 }, - { rgb_color, 119, 103, "chocolate", "#D2691E", 210, 105, 30 }, - { rgb_color, 120, 104, "peru", "#CD853F", 205, 133, 63 }, - { rgb_color, 121, 105, "sandy-brown", "#F4A460", 244, 164, 96 }, - { rgb_color, 122, 106, "burly-wood", "#DEB887", 222, 184, 135 }, - { rgb_color, 123, 107, "tan", "#D2B48C", 210, 180, 140 }, - { rgb_color, 124, 108, "rosy-brown", "#BC8F8F", 188, 143, 143 }, - { rgb_color, 125, 109, "moccasin", "#FFE4B5", 255, 228, 181 }, - { rgb_color, 126, 110, "navajo-white", "#FFDEAD", 255, 222, 173 }, - { rgb_color, 127, 111, "peach-puff", "#FFDAB9", 255, 218, 185 }, - { rgb_color, 128, 112, "misty-rose", "#FFE4E1", 255, 228, 225 }, - { rgb_color, 129, 113, "lavender-blush", "#FFF0F5", 255, 240, 245 }, - { rgb_color, 130, 114, "linen", "#FAF0E6", 250, 240, 230 }, - { rgb_color, 131, 115, "old-lace", "#FDF5E6", 253, 245, 230 }, - { rgb_color, 132, 116, "papaya-whip", "#FFEFD5", 255, 239, 213 }, - { rgb_color, 133, 117, "sea-shell", "#FFF5EE", 255, 245, 238 }, - { rgb_color, 134, 118, "mint-cream", "#F5FFFA", 245, 255, 250 }, - { rgb_color, 135, 119, "slate-gray", "#708090", 112, 128, 144 }, - { rgb_color, 136, 120, "light-slate-gray", "#778899", 119, 136, 153 }, - { rgb_color, 137, 121, "light-steel-blue", "#B0C4DE", 176, 196, 222 }, - { rgb_color, 138, 122, "lavender", "#E6E6FA", 230, 230, 250 }, - { rgb_color, 139, 123, "floral-white", "#FFFAF0", 255, 250, 240 }, - { rgb_color, 140, 124, "alice-blue", "#F0F8FF", 240, 248, 255 }, - { rgb_color, 141, 125, "ghost-white", "#F8F8FF", 248, 248, 255 }, - { rgb_color, 142, 126, "honeydew", "#F0FFF0", 240, 255, 240 }, - { rgb_color, 143, 127, "ivory", "#FFFFF0", 255, 255, 240 }, - { rgb_color, 144, 128, "azure", "#F0FFFF", 240, 255, 255 }, - { rgb_color, 145, 129, "snow", "#FFFAFA", 255, 250, 250 }, - { rgb_color, 146, 130, "black", "#000000", 0, 0, 0 }, - { rgb_color, 147, 131, "dim-gray", "#696969", 105, 105, 105 }, - { rgb_color, 148, 132, "gray", "#808080", 128, 128, 128 }, - { rgb_color, 149, 133, "dark-gray", "#A9A9A9", 169, 169, 169 }, - { rgb_color, 150, 134, "silver", "#C0C0C0", 192, 192, 192 }, - { rgb_color, 151, 135, "light-gray", "#D3D3D3", 211, 211, 211 }, - { rgb_color, 152, 136, "gainsboro", "#DCDCDC", 220, 220, 220 }, - { rgb_color, 153, 137, "white-smoke", "#F5F5F5", 245, 245, 245 }, - { rgb_color, 154, 138, "white", "#FFFFFF", 255, 255, 255 }, + { NHC, 0, 0, "black", 0x00, 0x00, 0x00 }, /* CLR_BLACK */ + { NHC, 1, 0, "red", 0xFF, 0x00, 0x00 }, /* CLR_RED */ + { NHC, 2, 0, "green", 0x22, 0x8B, 0x22 }, /* CLR_GREEN */ + { NHC, 3, 0, "brown", 0xA5, 0x2A, 0x2A }, /* CLR_BROWN */ + { NHC, 4, 0, "blue", 0x00, 0x00, 0xFF }, /* CLR_BLUE */ + { NHC, 5, 0, "magenta", 0xFF, 0x00, 0xFF }, /* CLR_MAGENTA */ + { NHC, 6, 0, "cyan", 0x00, 0xFF, 0xFF }, /* CLR_CYAN */ + { NHC, 7, 0, "gray", 0x80, 0x80, 0x80 }, /* CLR_GRAY */ + { NOC, 8, 0, "nocolor", 0x00, 0x00, 0x00 }, /* NO_COLOR */ + { NHC, 9, 0, "orange", 0xFF, 0xA5, 0x00 }, /* CLR_ORANGE */ + { NHC, 10, 0, "bright-green", + 0x00, 0x80, 0x00 }, /* CLR_BRIGHT_GREEN */ + { NHC, 11, 0, "yellow", 0xFF, 0xFF, 0x00 }, /* CLR_YELLOW */ + { NHC, 12, 0, "bright-blue", 0xAD, 0xD8, 0xE6 }, /* CLR_BRIGHT_BLUE */ + { NHC, 13, 0, "bright-magenta", + 0x93, 0x70, 0xDB }, /* CLR_BRIGHT_MAGENTA */ + { NHC, 14, 0, "light-cyan", 0xE0, 0xFF, 0xFF }, /* CLR_BRIGHT_CYAN */ + { NHC, 15, 0, "white", 0xFF, 0xFF, 0xFF }, /* CLR_WHITE */ + { RGBC, 16, 0, "maroon", 0x80, 0x00, 0x00 }, /* #800000 */ + { RGBC, 17, 1, "dark-red", 0x8B, 0x00, 0x00 }, /* #8B0000 */ + { RGBC, 18, 2, "brown", 0xA5, 0x2A, 0x2A }, /* #A52A2A */ + { RGBC, 19, 3, "firebrick", 0xB2, 0x22, 0x22 }, /* #B22222 */ + { RGBC, 20, 4, "crimson", 0xDC, 0x14, 0x3C }, /* #DC143C */ + { RGBC, 21, 5, "red", 0xFF, 0x00, 0x00 }, /* #FF0000 */ + { RGBC, 22, 6, "tomato", 0xFF, 0x63, 0x47 }, /* #FF6347 */ + { RGBC, 23, 7, "coral", 0xFF, 0x7F, 0x50 }, /* #FF7F50 */ + { RGBC, 24, 8, "indian-red", 0xCD, 0x5C, 0x5C }, /* #CD5C5C */ + { RGBC, 25, 9, "light-coral", 0xF0, 0x80, 0x80 }, /* #F08080 */ + { RGBC, 26, 10, "dark-salmon", 0xE9, 0x96, 0x7A }, /* #E9967A */ + { RGBC, 27, 11, "salmon", 0xFA, 0x80, 0x72 }, /* #FA8072 */ + { RGBC, 28, 12, "light-salmon", 0xFF, 0xA0, 0x7A }, /* #FFA07A */ + { RGBC, 29, 13, "orange-red", 0xFF, 0x45, 0x00 }, /* #FF4500 */ + { RGBC, 30, 14, "dark-orange", 0xFF, 0x8C, 0x00 }, /* #FF8C00 */ + { RGBC, 31, 15, "orange", 0xFF, 0xA5, 0x00 }, /* #FFA500 */ + { RGBC, 32, 16, "gold", 0xFF, 0xD7, 0x00 }, /* #FFD700 */ + { RGBC, 33, 17, "dark-golden-rod", 0xB8, 0x86, 0x0B }, /* #B8860B */ + { RGBC, 34, 18, "golden-rod", 0xDA, 0xA5, 0x20 }, /* #DAA520 */ + { RGBC, 35, 19, "pale-golden-rod", 0xEE, 0xE8, 0xAA }, /* #EEE8AA */ + { RGBC, 36, 20, "dark-khaki", 0xBD, 0xB7, 0x6B }, /* #BDB76B */ + { RGBC, 37, 21, "khaki", 0xF0, 0xE6, 0x8C }, /* #F0E68C */ + { RGBC, 38, 22, "olive", 0x80, 0x80, 0x00 }, /* #808000 */ + { RGBC, 39, 23, "yellow", 0xFF, 0xFF, 0x00 }, /* #FFFF00 */ + { RGBC, 40, 24, "yellow-green", 0x9A, 0xCD, 0x32 }, /* #9ACD32 */ + { RGBC, 41, 25, "dark-olive-green", 0x55, 0x6B, 0x2F }, /* #556B2F */ + { RGBC, 42, 26, "olive-drab", 0x6B, 0x8E, 0x23 }, /* #6B8E23 */ + { RGBC, 43, 27, "lawn-green", 0x7C, 0xFC, 0x00 }, /* #7CFC00 */ + { RGBC, 44, 28, "chart-reuse", 0x7F, 0xFF, 0x00 }, /* #7FFF00 */ + { RGBC, 45, 29, "green-yellow", 0xAD, 0xFF, 0x2F }, /* #ADFF2F */ + { RGBC, 46, 30, "dark-green", 0x00, 0x64, 0x00 }, /* #006400 */ + { RGBC, 47, 31, "green", 0x00, 0x80, 0x00 }, /* #008000 */ + { RGBC, 48, 32, "forest-green", 0x22, 0x8B, 0x22 }, /* #228B22 */ + { RGBC, 49, 33, "lime", 0x00, 0xFF, 0x00 }, /* #00FF00 */ + { RGBC, 50, 34, "lime-green", 0x32, 0xCD, 0x32 }, /* #32CD32 */ + { RGBC, 51, 35, "light-green", 0x90, 0xEE, 0x90 }, /* #90EE90 */ + { RGBC, 52, 36, "pale-green", 0x98, 0xFB, 0x98 }, /* #98FB98 */ + { RGBC, 53, 37, "dark-sea-green", 0x8F, 0xBC, 0x8F }, /* #8FBC8F */ + { RGBC, 54, 38, "medium-spring-green", 0x00, 0xFA, 0x9A }, /* #00FA9A */ + { RGBC, 55, 39, "spring-green", 0x00, 0xFF, 0x7F }, /* #00FF7F */ + { RGBC, 56, 40, "sea-green", 0x2E, 0x8B, 0x57 }, /* #2E8B57 */ + { RGBC, 57, 41, "medium-aqua-marine", 0x66, 0xCD, 0xAA }, /* #66CDAA */ + { RGBC, 58, 42, "medium-sea-green", 0x3C, 0xB3, 0x71 }, /* #3CB371 */ + { RGBC, 59, 43, "light-sea-green", 0x20, 0xB2, 0xAA }, /* #20B2AA */ + { RGBC, 60, 44, "dark-slate-gray", 0x2F, 0x4F, 0x4F }, /* #2F4F4F */ + { RGBC, 61, 45, "teal", 0x00, 0x80, 0x80 }, /* #008080 */ + { RGBC, 62, 46, "dark-cyan", 0x00, 0x8B, 0x8B }, /* #008B8B */ + { RGBC, 63, 47, "aqua", 0x00, 0xFF, 0xFF }, /* #00FFFF */ + { RGBC, 64, 48, "cyan", 0x00, 0xFF, 0xFF }, /* #00FFFF */ + { RGBC, 65, 49, "light-cyan", 0xE0, 0xFF, 0xFF }, /* #E0FFFF */ + { RGBC, 66, 50, "dark-turquoise", 0x00, 0xCE, 0xD1 }, /* #00CED1 */ + { RGBC, 67, 51, "turquoise", 0x40, 0xE0, 0xD0 }, /* #40E0D0 */ + { RGBC, 68, 52, "medium-turquoise", 0x48, 0xD1, 0xCC }, /* #48D1CC */ + { RGBC, 69, 53, "pale-turquoise", 0xAF, 0xEE, 0xEE }, /* #AFEEEE */ + { RGBC, 70, 54, "aqua-marine", 0x7F, 0xFF, 0xD4 }, /* #7FFFD4 */ + { RGBC, 71, 55, "powder-blue", 0xB0, 0xE0, 0xE6 }, /* #B0E0E6 */ + { RGBC, 72, 56, "cadet-blue", 0x5F, 0x9E, 0xA0 }, /* #5F9EA0 */ + { RGBC, 73, 57, "steel-blue", 0x46, 0x82, 0xB4 }, /* #4682B4 */ + { RGBC, 74, 58, "corn-flower-blue", 0x64, 0x95, 0xED }, /* #6495ED */ + { RGBC, 75, 59, "deep-sky-blue", 0x00, 0xBF, 0xFF }, /* #00BFFF */ + { RGBC, 76, 60, "dodger-blue", 0x1E, 0x90, 0xFF }, /* #1E90FF */ + { RGBC, 77, 61, "light-blue", 0xAD, 0xD8, 0xE6 }, /* #ADD8E6 */ + { RGBC, 78, 62, "sky-blue", 0x87, 0xCE, 0xEB }, /* #87CEEB */ + { RGBC, 79, 63, "light-sky-blue", 0x87, 0xCE, 0xFA }, /* #87CEFA */ + { RGBC, 80, 64, "midnight-blue", 0x19, 0x19, 0x70 }, /* #191970 */ + { RGBC, 81, 65, "navy", 0x00, 0x00, 0x80 }, /* #000080 */ + { RGBC, 82, 66, "dark-blue", 0x00, 0x00, 0x8B }, /* #00008B */ + { RGBC, 83, 67, "medium-blue", 0x00, 0x00, 0xCD }, /* #0000CD */ + { RGBC, 84, 68, "blue", 0x00, 0x00, 0xFF }, /* #0000FF */ + { RGBC, 85, 69, "royal-blue", 0x41, 0x69, 0xE1 }, /* #4169E1 */ + { RGBC, 86, 70, "blue-violet", 0x8A, 0x2B, 0xE2 }, /* #8A2BE2 */ + { RGBC, 87, 71, "indigo", 0x4B, 0x00, 0x82 }, /* #4B0082 */ + { RGBC, 88, 72, "dark-slate-blue", 0x48, 0x3D, 0x8B }, /* #483D8B */ + { RGBC, 89, 73, "slate-blue", 0x6A, 0x5A, 0xCD }, /* #6A5ACD */ + { RGBC, 90, 74, "medium-slate-blue", 0x7B, 0x68, 0xEE }, /* #7B68EE */ + { RGBC, 91, 75, "medium-purple", 0x93, 0x70, 0xDB }, /* #9370DB */ + { RGBC, 92, 76, "dark-magenta", 0x8B, 0x00, 0x8B }, /* #8B008B */ + { RGBC, 93, 77, "dark-violet", 0x94, 0x00, 0xD3 }, /* #9400D3 */ + { RGBC, 94, 78, "dark-orchid", 0x99, 0x32, 0xCC }, /* #9932CC */ + { RGBC, 95, 79, "medium-orchid", 0xBA, 0x55, 0xD3 }, /* #BA55D3 */ + { RGBC, 96, 80, "purple", 0x80, 0x00, 0x80 }, /* #800080 */ + { RGBC, 97, 81, "thistle", 0xD8, 0xBF, 0xD8 }, /* #D8BFD8 */ + { RGBC, 98, 82, "plum", 0xDD, 0xA0, 0xDD }, /* #DDA0DD */ + { RGBC, 99, 83, "violet", 0xEE, 0x82, 0xEE }, /* #EE82EE */ + { RGBC, 100, 84, "magenta", 0xFF, 0x00, 0xFF }, /* #FF00FF */ + { RGBC, 101, 85, "orchid", 0xDA, 0x70, 0xD6 }, /* #DA70D6 */ + { RGBC, 102, 86, "medium-violet-red", 0xC7, 0x15, 0x85 }, /* #C71585 */ + { RGBC, 103, 87, "pale-violet-red", 0xDB, 0x70, 0x93 }, /* #DB7093 */ + { RGBC, 104, 88, "deep-pink", 0xFF, 0x14, 0x93 }, /* #FF1493 */ + { RGBC, 105, 89, "hot-pink", 0xFF, 0x69, 0xB4 }, /* #FF69B4 */ + { RGBC, 106, 90, "light-pink", 0xFF, 0xB6, 0xC1 }, /* #FFB6C1 */ + { RGBC, 107, 91, "pink", 0xFF, 0xC0, 0xCB }, /* #FFC0CB */ + { RGBC, 108, 92, "antique-white", 0xFA, 0xEB, 0xD7 }, /* #FAEBD7 */ + { RGBC, 109, 93, "beige", 0xF5, 0xF5, 0xDC }, /* #F5F5DC */ + { RGBC, 110, 94, "bisque", 0xFF, 0xE4, 0xC4 }, /* #FFE4C4 */ + { RGBC, 111, 95, "blanched-almond", 0xFF, 0xEB, 0xCD }, /* #FFEBCD */ + { RGBC, 112, 96, "wheat", 0xF5, 0xDE, 0xB3 }, /* #F5DEB3 */ + { RGBC, 113, 97, "corn-silk", 0xFF, 0xF8, 0xDC }, /* #FFF8DC */ + { RGBC, 114, 98, "lemon-chiffon", 0xFF, 0xFA, 0xCD }, /* #FFFACD */ + { RGBC, 115, 99, "light-golden-rod-yellow", + 0xFA, 0xFA, 0xD2 }, /* #FAFAD2 */ + { RGBC, 116, 100, "light-yellow", 0xFF, 0xFF, 0xE0 }, /* #FFFFE0 */ + { RGBC, 117, 101, "saddle-brown", 0x8B, 0x45, 0x13 }, /* #8B4513 */ + { RGBC, 118, 102, "sienna", 0xA0, 0x52, 0x2D }, /* #A0522D */ + { RGBC, 119, 103, "chocolate", 0xD2, 0x69, 0x1E }, /* #D2691E */ + { RGBC, 120, 104, "peru", 0xCD, 0x85, 0x3F }, /* #CD853F */ + { RGBC, 121, 105, "sandy-brown", 0xF4, 0xA4, 0x60 }, /* #F4A460 */ + { RGBC, 122, 106, "burly-wood", 0xDE, 0xB8, 0x87 }, /* #DEB887 */ + { RGBC, 123, 107, "tan", 0xD2, 0xB4, 0x8C }, /* #D2B48C */ + { RGBC, 124, 108, "rosy-brown", 0xBC, 0x8F, 0x8F }, /* #BC8F8F */ + { RGBC, 125, 109, "moccasin", 0xFF, 0xE4, 0xB5 }, /* #FFE4B5 */ + { RGBC, 126, 110, "navajo-white", 0xFF, 0xDE, 0xAD }, /* #FFDEAD */ + { RGBC, 127, 111, "peach-puff", 0xFF, 0xDA, 0xB9 }, /* #FFDAB9 */ + { RGBC, 128, 112, "misty-rose", 0xFF, 0xE4, 0xE1 }, /* #FFE4E1 */ + { RGBC, 129, 113, "lavender-blush", 0xFF, 0xF0, 0xF5 }, /* #FFF0F5 */ + { RGBC, 130, 114, "linen", 0xFA, 0xF0, 0xE6 }, /* #FAF0E6 */ + { RGBC, 131, 115, "old-lace", 0xFD, 0xF5, 0xE6 }, /* #FDF5E6 */ + { RGBC, 132, 116, "papaya-whip", 0xFF, 0xEF, 0xD5 }, /* #FFEFD5 */ + { RGBC, 133, 117, "sea-shell", 0xFF, 0xF5, 0xEE }, /* #FFF5EE */ + { RGBC, 134, 118, "mint-cream", 0xF5, 0xFF, 0xFA }, /* #F5FFFA */ + { RGBC, 135, 119, "slate-gray", 0x70, 0x80, 0x90 }, /* #708090 */ + { RGBC, 136, 120, "light-slate-gray", 0x77, 0x88, 0x99 }, /* #778899 */ + { RGBC, 137, 121, "light-steel-blue", 0xB0, 0xC4, 0xDE }, /* #B0C4DE */ + { RGBC, 138, 122, "lavender", 0xE6, 0xE6, 0xFA }, /* #E6E6FA */ + { RGBC, 139, 123, "floral-white", 0xFF, 0xFA, 0xF0 }, /* #FFFAF0 */ + { RGBC, 140, 124, "alice-blue", 0xF0, 0xF8, 0xFF }, /* #F0F8FF */ + { RGBC, 141, 125, "ghost-white", 0xF8, 0xF8, 0xFF }, /* #F8F8FF */ + { RGBC, 142, 126, "honeydew", 0xF0, 0xFF, 0xF0 }, /* #F0FFF0 */ + { RGBC, 143, 127, "ivory", 0xFF, 0xFF, 0xF0 }, /* #FFFFF0 */ + { RGBC, 144, 128, "azure", 0xF0, 0xFF, 0xFF }, /* #F0FFFF */ + { RGBC, 145, 129, "snow", 0xFF, 0xFA, 0xFA }, /* #FFFAFA */ + { RGBC, 146, 130, "black", 0x00, 0x00, 0x00 }, /* #000000 */ + { RGBC, 147, 131, "dim-gray", 0x69, 0x69, 0x69 }, /* #696969 */ + { RGBC, 148, 132, "gray", 0x80, 0x80, 0x80 }, /* #808080 */ + { RGBC, 149, 133, "dark-gray", 0xA9, 0xA9, 0xA9 }, /* #A9A9A9 */ + { RGBC, 150, 134, "silver", 0xC0, 0xC0, 0xC0 }, /* #C0C0C0 */ + { RGBC, 151, 135, "light-gray", 0xD3, 0xD3, 0xD3 }, /* #D3D3D3 */ + { RGBC, 152, 136, "gainsboro", 0xDC, 0xDC, 0xDC }, /* #DCDCDC */ + { RGBC, 153, 137, "white-smoke", 0xF5, 0xF5, 0xF5 }, /* #F5F5F5 */ + { RGBC, 154, 138, "white", 0xFF, 0xFF, 0xFF }, /* #FFFFFF */ }; +#undef NHC +#undef NOC +#undef RGBC + #ifdef CHANGE_COLOR staticfn int32 alt_color_spec(const char *cp); #endif From 15a9acbefba3c0e52b9740ab868f657a5cafd761 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 24 Apr 2026 21:15:48 -0400 Subject: [PATCH 003/702] more colortable[] updates declare colortable[] const and no longer static so it can be shared by code in window ports.. get rid of the Windows console port rgbtable and use the core colortable[] instead. utilize function colortable_to_int32() in Windows console instead of the rgbtable_to_long() in the Windows port. delete the Windows rgbtable_to_long() function. --- include/color.h | 2 + include/extern.h | 2 +- src/coloratt.c | 4 +- sys/windows/consoletty.c | 189 ++++----------------------------------- 4 files changed, 23 insertions(+), 174 deletions(-) diff --git a/include/color.h b/include/color.h index 60e4dcb6c..3efcfc022 100644 --- a/include/color.h +++ b/include/color.h @@ -72,6 +72,8 @@ typedef struct color_and_attr { int color, attr; } color_attr; +extern const struct nethack_color colortable[]; + #endif /* COLOR_H */ /*color.h*/ diff --git a/include/extern.h b/include/extern.h index c8140e68e..c5cac33cf 100644 --- a/include/extern.h +++ b/include/extern.h @@ -351,7 +351,7 @@ extern void set_ignore_errors_on_unmatched(void); extern char *color_attr_to_str(color_attr *); extern boolean color_attr_parse_str(color_attr *, char *); -extern int32 colortable_to_int32(struct nethack_color *); +extern int32 colortable_to_int32(const struct nethack_color *); extern int query_color(const char *, int) NO_NNARGS; extern int query_attr(const char *, int) NO_NNARGS; extern boolean query_color_attr(color_attr *, const char *) NONNULLARG1; diff --git a/src/coloratt.c b/src/coloratt.c index d6adf6673..a929417fb 100644 --- a/src/coloratt.c +++ b/src/coloratt.c @@ -64,7 +64,7 @@ static const struct attr_names attrnames[] = { #define NOC no_color #define RGBC rgb_color -static struct nethack_color colortable[] = { +const struct nethack_color colortable[] = { { NHC, 0, 0, "black", 0x00, 0x00, 0x00 }, /* CLR_BLACK */ { NHC, 1, 0, "red", 0xFF, 0x00, 0x00 }, /* CLR_RED */ { NHC, 2, 0, "green", 0x22, 0x8B, 0x22 }, /* CLR_GREEN */ @@ -234,7 +234,7 @@ staticfn int32 alt_color_spec(const char *cp); #endif int32 -colortable_to_int32(struct nethack_color *cte) +colortable_to_int32(const struct nethack_color *cte) { int32 clr = NO_COLOR | NH_BASIC_COLOR; diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index c048a65b6..034e69884 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -343,160 +343,12 @@ WHITE 255,255,255 242,242,242 */ #ifdef VIRTUAL_TERMINAL_SEQUENCES -long customcolors[CLR_MAX]; +int32 customcolors[CLR_MAX]; const char *esc_seq_colors[CLR_MAX] = { 0 }; const char *esc_seq_bkcolors[CLR_MAX] = { 0 }; -struct rgbvalues { - int idx; - const char *name; - const char *hexval; - long r, gn, b; -} rgbtable[] = { - { 0, "maroon", "#800000", 128, 0, 0 }, - { 1, "dark red", "#8B0000", 139, 0, 0 }, - { 2, "brown", "#A52A2A", 165, 42, 42 }, - { 3, "firebrick", "#B22222", 178, 34, 34 }, - { 4, "crimson", "#DC143C", 220, 20, 60 }, - { 5, "red", "#FF0000", 255, 0, 0 }, - { 6, "tomato", "#FF6347", 255, 99, 71 }, - { 7, "coral", "#FF7F50", 255, 127, 80 }, - { 8, "indian red", "#CD5C5C", 205, 92, 92 }, - { 9, "light coral", "#F08080", 240, 128, 128 }, - { 10, "dark salmon", "#E9967A", 233, 150, 122 }, - { 11, "salmon", "#FA8072", 250, 128, 114 }, - { 12, "light salmon", "#FFA07A", 255, 160, 122 }, - { 13, "orange red", "#FF4500", 255, 69, 0 }, - { 14, "dark orange", "#FF8C00", 255, 140, 0 }, - { 15, "orange", "#FFA500", 255, 165, 0 }, - { 16, "gold", "#FFD700", 255, 215, 0 }, - { 17, "dark golden rod", "#B8860B", 184, 134, 11 }, - { 18, "golden rod", "#DAA520", 218, 165, 32 }, - { 19, "pale golden rod", "#EEE8AA", 238, 232, 170 }, - { 20, "dark khaki", "#BDB76B", 189, 183, 107 }, - { 21, "khaki", "#F0E68C", 240, 230, 140 }, - { 22, "olive", "#808000", 128, 128, 0 }, - { 23, "yellow", "#FFFF00", 255, 255, 0 }, - { 24, "yellow green", "#9ACD32", 154, 205, 50 }, - { 25, "dark olive green", "#556B2F", 85, 107, 47 }, - { 26, "olive drab", "#6B8E23", 107, 142, 35 }, - { 27, "lawn green", "#7CFC00", 124, 252, 0 }, - { 28, "chart reuse", "#7FFF00", 127, 255, 0 }, - { 29, "green yellow", "#ADFF2F", 173, 255, 47 }, - { 30, "dark green", "#006400", 0, 100, 0 }, - { 31, "green", "#008000", 0, 128, 0 }, - { 32, "forest green", "#228B22", 34, 139, 34 }, - { 33, "lime", "#00FF00", 0, 255, 0 }, - { 34, "lime green", "#32CD32", 50, 205, 50 }, - { 35, "light green", "#90EE90", 144, 238, 144 }, - { 36, "pale green", "#98FB98", 152, 251, 152 }, - { 37, "dark sea green", "#8FBC8F", 143, 188, 143 }, - { 38, "medium spring green", "#00FA9A", 0, 250, 154 }, - { 39, "spring green", "#00FF7F", 0, 255, 127 }, - { 40, "sea green", "#2E8B57", 46, 139, 87 }, - { 41, "medium aqua marine", "#66CDAA", 102, 205, 170 }, - { 42, "medium sea green", "#3CB371", 60, 179, 113 }, - { 43, "light sea green", "#20B2AA", 32, 178, 170 }, - { 44, "dark slate gray", "#2F4F4F", 47, 79, 79 }, - { 45, "teal", "#008080", 0, 128, 128 }, - { 46, "dark cyan", "#008B8B", 0, 139, 139 }, - { 47, "aqua", "#00FFFF", 0, 255, 255 }, - { 48, "cyan", "#00FFFF", 0, 255, 255 }, - { 49, "light cyan", "#E0FFFF", 224, 255, 255 }, - { 50, "dark turquoise", "#00CED1", 0, 206, 209 }, - { 51, "turquoise", "#40E0D0", 64, 224, 208 }, - { 52, "medium turquoise", "#48D1CC", 72, 209, 204 }, - { 53, "pale turquoise", "#AFEEEE", 175, 238, 238 }, - { 54, "aqua marine", "#7FFFD4", 127, 255, 212 }, - { 55, "powder blue", "#B0E0E6", 176, 224, 230 }, - { 56, "cadet blue", "#5F9EA0", 95, 158, 160 }, - { 57, "steel blue", "#4682B4", 70, 130, 180 }, - { 58, "corn flower blue", "#6495ED", 100, 149, 237 }, - { 59, "deep sky blue", "#00BFFF", 0, 191, 255 }, - { 60, "dodger blue", "#1E90FF", 30, 144, 255 }, - { 61, "light blue", "#ADD8E6", 173, 216, 230 }, - { 62, "sky blue", "#87CEEB", 135, 206, 235 }, - { 63, "light sky blue", "#87CEFA", 135, 206, 250 }, - { 64, "midnight blue", "#191970", 25, 25, 112 }, - { 65, "navy", "#000080", 0, 0, 128 }, - { 66, "dark blue", "#00008B", 0, 0, 139 }, - { 67, "medium blue", "#0000CD", 0, 0, 205 }, - { 68, "blue", "#0000FF", 0, 0, 255 }, - { 69, "royal blue", "#4169E1", 65, 105, 225 }, - { 70, "blue violet", "#8A2BE2", 138, 43, 226 }, - { 71, "indigo", "#4B0082", 75, 0, 130 }, - { 72, "dark slate blue", "#483D8B", 72, 61, 139 }, - { 73, "slate blue", "#6A5ACD", 106, 90, 205 }, - { 74, "medium slate blue", "#7B68EE", 123, 104, 238 }, - { 75, "medium purple", "#9370DB", 147, 112, 219 }, - { 76, "dark magenta", "#8B008B", 139, 0, 139 }, - { 77, "dark violet", "#9400D3", 148, 0, 211 }, - { 78, "dark orchid", "#9932CC", 153, 50, 204 }, - { 79, "medium orchid", "#BA55D3", 186, 85, 211 }, - { 80, "purple", "#800080", 128, 0, 128 }, - { 81, "thistle", "#D8BFD8", 216, 191, 216 }, - { 82, "plum", "#DDA0DD", 221, 160, 221 }, - { 83, "violet", "#EE82EE", 238, 130, 238 }, - { 84, "magenta / fuchsia", "#FF00FF", 255, 0, 255 }, - { 85, "orchid", "#DA70D6", 218, 112, 214 }, - { 86, "medium violet red", "#C71585", 199, 21, 133 }, - { 87, "pale violet red", "#DB7093", 219, 112, 147 }, - { 88, "deep pink", "#FF1493", 255, 20, 147 }, - { 89, "hot pink", "#FF69B4", 255, 105, 180 }, - { 90, "light pink", "#FFB6C1", 255, 182, 193 }, - { 91, "pink", "#FFC0CB", 255, 192, 203 }, - { 92, "antique white", "#FAEBD7", 250, 235, 215 }, - { 93, "beige", "#F5F5DC", 245, 245, 220 }, - { 94, "bisque", "#FFE4C4", 255, 228, 196 }, - { 95, "blanched almond", "#FFEBCD", 255, 235, 205 }, - { 96, "wheat", "#F5DEB3", 245, 222, 179 }, - { 97, "corn silk", "#FFF8DC", 255, 248, 220 }, - { 98, "lemon chiffon", "#FFFACD", 255, 250, 205 }, - { 99, "light golden rod yellow", "#FAFAD2", 250, 250, 210 }, - { 100, "light yellow", "#FFFFE0", 255, 255, 224 }, - { 101, "saddle brown", "#8B4513", 139, 69, 19 }, - { 102, "sienna", "#A0522D", 160, 82, 45 }, - { 103, "chocolate", "#D2691E", 210, 105, 30 }, - { 104, "peru", "#CD853F", 205, 133, 63 }, - { 105, "sandy brown", "#F4A460", 244, 164, 96 }, - { 106, "burly wood", "#DEB887", 222, 184, 135 }, - { 107, "tan", "#D2B48C", 210, 180, 140 }, - { 108, "rosy brown", "#BC8F8F", 188, 143, 143 }, - { 109, "moccasin", "#FFE4B5", 255, 228, 181 }, - { 110, "navajo white", "#FFDEAD", 255, 222, 173 }, - { 111, "peach puff", "#FFDAB9", 255, 218, 185 }, - { 112, "misty rose", "#FFE4E1", 255, 228, 225 }, - { 113, "lavender blush", "#FFF0F5", 255, 240, 245 }, - { 114, "linen", "#FAF0E6", 250, 240, 230 }, - { 115, "old lace", "#FDF5E6", 253, 245, 230 }, - { 116, "papaya whip", "#FFEFD5", 255, 239, 213 }, - { 117, "sea shell", "#FFF5EE", 255, 245, 238 }, - { 118, "mint cream", "#F5FFFA", 245, 255, 250 }, - { 119, "slate gray", "#708090", 112, 128, 144 }, - { 120, "light slate gray", "#778899", 119, 136, 153 }, - { 121, "light steel blue", "#B0C4DE", 176, 196, 222 }, - { 122, "lavender", "#E6E6FA", 230, 230, 250 }, - { 123, "floral white", "#FFFAF0", 255, 250, 240 }, - { 124, "alice blue", "#F0F8FF", 240, 248, 255 }, - { 125, "ghost white", "#F8F8FF", 248, 248, 255 }, - { 126, "honeydew", "#F0FFF0", 240, 255, 240 }, - { 127, "ivory", "#FFFFF0", 255, 255, 240 }, - { 128, "azure", "#F0FFFF", 240, 255, 255 }, - { 129, "snow", "#FFFAFA", 255, 250, 250 }, - { 130, "black", "#000000", 0, 0, 0 }, - { 131, "dim gray / dim grey", "#696969", 105, 105, 105 }, - { 132, "gray / grey", "#808080", 128, 128, 128 }, - { 133, "dark gray / dark grey", "#A9A9A9", 169, 169, 169 }, - { 134, "silver", "#C0C0C0", 192, 192, 192 }, - { 135, "light gray / light grey", "#D3D3D3", 211, 211, 211 }, - { 136, "gainsboro", "#DCDCDC", 220, 220, 220 }, - { 137, "white smoke", "#F5F5F5", 245, 245, 245 }, - { 138, "white", "#FFFFFF", 255, 255, 255 }, -}; - void buffer_fill_to_end(cell_t * buffer, cell_t * fill, int x, int y); void buffer_write(cell_t * buffer, cell_t * cell, COORD pos); -static long rgbtable_to_long(struct rgbvalues *); void term_start_256color(int idx); void set_cp_map(void); #ifdef PORT_DEBUG @@ -504,34 +356,29 @@ void win32con_debug_keystrokes(void); void win32con_toggle_cursor_info(void); #endif -static long -rgbtable_to_long(struct rgbvalues *tbl) -{ - long rgblong = (tbl->r << 0) | (tbl->gn << 8) | (tbl->b << 16); - return rgblong; -} +#define rgbtable_offset 16 static void init_custom_colors(void) { char bkcolorbuf[32]; - customcolors[CLR_BLACK] = rgbtable_to_long(&rgbtable[131]); - customcolors[CLR_RED] = rgbtable_to_long(&rgbtable[5]); - customcolors[CLR_GREEN] = rgbtable_to_long(&rgbtable[31]); - customcolors[CLR_BROWN] = rgbtable_to_long(&rgbtable[104]); - customcolors[CLR_BLUE] = rgbtable_to_long(&rgbtable[58]); - customcolors[CLR_MAGENTA] = rgbtable_to_long(&rgbtable[76]); - customcolors[CLR_CYAN] = rgbtable_to_long(&rgbtable[48]); - customcolors[CLR_GRAY] = rgbtable_to_long(&rgbtable[73]); - customcolors[NO_COLOR] = rgbtable_to_long(&rgbtable[137]); - customcolors[CLR_ORANGE] = rgbtable_to_long(&rgbtable[15]); - customcolors[CLR_BRIGHT_GREEN] = rgbtable_to_long(&rgbtable[34]); - customcolors[CLR_YELLOW] = rgbtable_to_long(&rgbtable[18]); - customcolors[CLR_BRIGHT_BLUE] = rgbtable_to_long(&rgbtable[69]); - customcolors[CLR_BRIGHT_MAGENTA] = rgbtable_to_long(&rgbtable[84]); - customcolors[CLR_BRIGHT_CYAN] = rgbtable_to_long(&rgbtable[49]); - customcolors[CLR_WHITE] = rgbtable_to_long(&rgbtable[138]); + customcolors[CLR_BLACK] = colortable_to_int32(&colortable[rgbtable_offset + 131]); + customcolors[CLR_RED] = colortable_to_int32(&colortable[rgbtable_offset + 5]); + customcolors[CLR_GREEN] = colortable_to_int32(&colortable[rgbtable_offset + 31]); + customcolors[CLR_BROWN] = colortable_to_int32(&colortable[rgbtable_offset + 104]); + customcolors[CLR_BLUE] = colortable_to_int32(&colortable[rgbtable_offset + 58]); + customcolors[CLR_MAGENTA] = colortable_to_int32(&colortable[rgbtable_offset + 76]); + customcolors[CLR_CYAN] = colortable_to_int32(&colortable[rgbtable_offset + 48]); + customcolors[CLR_GRAY] = colortable_to_int32(&colortable[rgbtable_offset + 73]); + customcolors[NO_COLOR] = colortable_to_int32(&colortable[rgbtable_offset + 137]); + customcolors[CLR_ORANGE] = colortable_to_int32(&colortable[rgbtable_offset + 15]); + customcolors[CLR_BRIGHT_GREEN] = colortable_to_int32(&colortable[rgbtable_offset + 34]); + customcolors[CLR_YELLOW] = colortable_to_int32(&colortable[rgbtable_offset + 18]); + customcolors[CLR_BRIGHT_BLUE] = colortable_to_int32(&colortable[rgbtable_offset + 69]); + customcolors[CLR_BRIGHT_MAGENTA] = colortable_to_int32(&colortable[rgbtable_offset + 84]); + customcolors[CLR_BRIGHT_CYAN] = colortable_to_int32(&colortable[rgbtable_offset + 49]); + customcolors[CLR_WHITE] = colortable_to_int32(&colortable[rgbtable_offset + 138]); /* esc_seq_colors[CLR_BLACK] = "\x1b[30m"; */ esc_seq_colors[CLR_BLACK] = "\x1b[38;2;47;79;79m"; From 8982addb9d6f875e46294a0a0fb4dc45c5eb2663 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 24 Apr 2026 21:44:48 -0400 Subject: [PATCH 004/702] revert one Windows change Windows stores things a bit differently. Use a static function in consoletty.c to preserve that behavior, but still utilize the core colortable[] array. --- sys/windows/consoletty.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index 034e69884..ea74ee2af 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -349,6 +349,7 @@ const char *esc_seq_bkcolors[CLR_MAX] = { 0 }; void buffer_fill_to_end(cell_t * buffer, cell_t * fill, int x, int y); void buffer_write(cell_t * buffer, cell_t * cell, COORD pos); +static int32 rgbtable_to_int32(const struct nethack_color *tbl); void term_start_256color(int idx); void set_cp_map(void); #ifdef PORT_DEBUG @@ -356,6 +357,13 @@ void win32con_debug_keystrokes(void); void win32con_toggle_cursor_info(void); #endif +static int32 +rgbtable_to_int32(const struct nethack_color *tbl) +{ + int32 rgbint32 = (tbl->r << 0) | (tbl->g << 8) | (tbl->b << 16); + return rgbint32; +} + #define rgbtable_offset 16 static void @@ -363,22 +371,22 @@ init_custom_colors(void) { char bkcolorbuf[32]; - customcolors[CLR_BLACK] = colortable_to_int32(&colortable[rgbtable_offset + 131]); - customcolors[CLR_RED] = colortable_to_int32(&colortable[rgbtable_offset + 5]); - customcolors[CLR_GREEN] = colortable_to_int32(&colortable[rgbtable_offset + 31]); - customcolors[CLR_BROWN] = colortable_to_int32(&colortable[rgbtable_offset + 104]); - customcolors[CLR_BLUE] = colortable_to_int32(&colortable[rgbtable_offset + 58]); - customcolors[CLR_MAGENTA] = colortable_to_int32(&colortable[rgbtable_offset + 76]); - customcolors[CLR_CYAN] = colortable_to_int32(&colortable[rgbtable_offset + 48]); - customcolors[CLR_GRAY] = colortable_to_int32(&colortable[rgbtable_offset + 73]); - customcolors[NO_COLOR] = colortable_to_int32(&colortable[rgbtable_offset + 137]); - customcolors[CLR_ORANGE] = colortable_to_int32(&colortable[rgbtable_offset + 15]); - customcolors[CLR_BRIGHT_GREEN] = colortable_to_int32(&colortable[rgbtable_offset + 34]); - customcolors[CLR_YELLOW] = colortable_to_int32(&colortable[rgbtable_offset + 18]); - customcolors[CLR_BRIGHT_BLUE] = colortable_to_int32(&colortable[rgbtable_offset + 69]); - customcolors[CLR_BRIGHT_MAGENTA] = colortable_to_int32(&colortable[rgbtable_offset + 84]); - customcolors[CLR_BRIGHT_CYAN] = colortable_to_int32(&colortable[rgbtable_offset + 49]); - customcolors[CLR_WHITE] = colortable_to_int32(&colortable[rgbtable_offset + 138]); + customcolors[CLR_BLACK] = rgbtable_to_int32(&colortable[rgbtable_offset + 131]); + customcolors[CLR_RED] = rgbtable_to_int32(&colortable[rgbtable_offset + 5]); + customcolors[CLR_GREEN] = rgbtable_to_int32(&colortable[rgbtable_offset + 31]); + customcolors[CLR_BROWN] = rgbtable_to_int32(&colortable[rgbtable_offset + 104]); + customcolors[CLR_BLUE] = rgbtable_to_int32(&colortable[rgbtable_offset + 58]); + customcolors[CLR_MAGENTA] = rgbtable_to_int32(&colortable[rgbtable_offset + 76]); + customcolors[CLR_CYAN] = rgbtable_to_int32(&colortable[rgbtable_offset + 48]); + customcolors[CLR_GRAY] = rgbtable_to_int32(&colortable[rgbtable_offset + 73]); + customcolors[NO_COLOR] = rgbtable_to_int32(&colortable[rgbtable_offset + 137]); + customcolors[CLR_ORANGE] = rgbtable_to_int32(&colortable[rgbtable_offset + 15]); + customcolors[CLR_BRIGHT_GREEN] = rgbtable_to_int32(&colortable[rgbtable_offset + 34]); + customcolors[CLR_YELLOW] = rgbtable_to_int32(&colortable[rgbtable_offset + 18]); + customcolors[CLR_BRIGHT_BLUE] = rgbtable_to_int32(&colortable[rgbtable_offset + 69]); + customcolors[CLR_BRIGHT_MAGENTA] = rgbtable_to_int32(&colortable[rgbtable_offset + 84]); + customcolors[CLR_BRIGHT_CYAN] = rgbtable_to_int32(&colortable[rgbtable_offset + 49]); + customcolors[CLR_WHITE] = rgbtable_to_int32(&colortable[rgbtable_offset + 138]); /* esc_seq_colors[CLR_BLACK] = "\x1b[30m"; */ esc_seq_colors[CLR_BLACK] = "\x1b[38;2;47;79;79m"; From 36df2315c9cea968015ad336566d29187901b9c8 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 24 Apr 2026 21:58:33 -0400 Subject: [PATCH 005/702] another Windows console follow-up --- sys/windows/consoletty.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index ea74ee2af..1c748b60c 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -357,8 +357,9 @@ void win32con_debug_keystrokes(void); void win32con_toggle_cursor_info(void); #endif +/* GDI typically represents color as BGR (Blue-Green-Red) in memory */ static int32 -rgbtable_to_int32(const struct nethack_color *tbl) +colortable_to_bgr_int32(const struct nethack_color *tbl) { int32 rgbint32 = (tbl->r << 0) | (tbl->g << 8) | (tbl->b << 16); return rgbint32; @@ -371,22 +372,22 @@ init_custom_colors(void) { char bkcolorbuf[32]; - customcolors[CLR_BLACK] = rgbtable_to_int32(&colortable[rgbtable_offset + 131]); - customcolors[CLR_RED] = rgbtable_to_int32(&colortable[rgbtable_offset + 5]); - customcolors[CLR_GREEN] = rgbtable_to_int32(&colortable[rgbtable_offset + 31]); - customcolors[CLR_BROWN] = rgbtable_to_int32(&colortable[rgbtable_offset + 104]); - customcolors[CLR_BLUE] = rgbtable_to_int32(&colortable[rgbtable_offset + 58]); - customcolors[CLR_MAGENTA] = rgbtable_to_int32(&colortable[rgbtable_offset + 76]); - customcolors[CLR_CYAN] = rgbtable_to_int32(&colortable[rgbtable_offset + 48]); - customcolors[CLR_GRAY] = rgbtable_to_int32(&colortable[rgbtable_offset + 73]); - customcolors[NO_COLOR] = rgbtable_to_int32(&colortable[rgbtable_offset + 137]); - customcolors[CLR_ORANGE] = rgbtable_to_int32(&colortable[rgbtable_offset + 15]); - customcolors[CLR_BRIGHT_GREEN] = rgbtable_to_int32(&colortable[rgbtable_offset + 34]); - customcolors[CLR_YELLOW] = rgbtable_to_int32(&colortable[rgbtable_offset + 18]); - customcolors[CLR_BRIGHT_BLUE] = rgbtable_to_int32(&colortable[rgbtable_offset + 69]); - customcolors[CLR_BRIGHT_MAGENTA] = rgbtable_to_int32(&colortable[rgbtable_offset + 84]); - customcolors[CLR_BRIGHT_CYAN] = rgbtable_to_int32(&colortable[rgbtable_offset + 49]); - customcolors[CLR_WHITE] = rgbtable_to_int32(&colortable[rgbtable_offset + 138]); + customcolors[CLR_BLACK] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 131]); + customcolors[CLR_RED] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 5]); + customcolors[CLR_GREEN] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 31]); + customcolors[CLR_BROWN] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 104]); + customcolors[CLR_BLUE] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 58]); + customcolors[CLR_MAGENTA] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 76]); + customcolors[CLR_CYAN] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 48]); + customcolors[CLR_GRAY] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 73]); + customcolors[NO_COLOR] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 137]); + customcolors[CLR_ORANGE] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 15]); + customcolors[CLR_BRIGHT_GREEN] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 34]); + customcolors[CLR_YELLOW] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 18]); + customcolors[CLR_BRIGHT_BLUE] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 69]); + customcolors[CLR_BRIGHT_MAGENTA] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 84]); + customcolors[CLR_BRIGHT_CYAN] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 49]); + customcolors[CLR_WHITE] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 138]); /* esc_seq_colors[CLR_BLACK] = "\x1b[30m"; */ esc_seq_colors[CLR_BLACK] = "\x1b[38;2;47;79;79m"; From 80c08334ab805b3a17a462666a079ec497fe408a Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 24 Apr 2026 22:02:15 -0400 Subject: [PATCH 006/702] yet another Windows follow-up --- sys/windows/consoletty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index 1c748b60c..9ffdc5880 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -361,8 +361,8 @@ void win32con_toggle_cursor_info(void); static int32 colortable_to_bgr_int32(const struct nethack_color *tbl) { - int32 rgbint32 = (tbl->r << 0) | (tbl->g << 8) | (tbl->b << 16); - return rgbint32; + int32 bgrint32 = (tbl->r << 0) | (tbl->g << 8) | (tbl->b << 16); + return bgrint32; } #define rgbtable_offset 16 From 5b66ba4c993882303d3b38c8006d9227e184b86b Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 25 Apr 2026 14:41:39 -0400 Subject: [PATCH 007/702] change gy.youmonst Add a pointer to struct you, and put umonst there. Eliminate the youmonst struct in gy. The naming convention better matches the other u related fields, and u.umonst has the same level of indirection as other monst pointers. The u.umonst pointer is cleared prior to saving the parent u (struct you), and u.umonst is reestablished upon restore. Invalidates existing saves and bones due to the presence of the added pointer field in struct you. --- include/decl.h | 1 - include/display.h | 6 +- include/hack.h | 4 +- include/monst.h | 4 +- include/you.h | 3 +- include/youprop.h | 8 +- src/allmain.c | 10 +- src/apply.c | 36 +++--- src/artifact.c | 40 +++--- src/attrib.c | 4 +- src/botl.c | 6 +- src/cmd.c | 8 +- src/dbridge.c | 6 +- src/decl.c | 1 - src/detect.c | 6 +- src/dig.c | 26 ++-- src/do.c | 10 +- src/do_name.c | 6 +- src/do_wear.c | 56 ++++----- src/dog.c | 6 +- src/dogmove.c | 10 +- src/dokick.c | 22 ++-- src/dothrow.c | 58 ++++----- src/eat.c | 112 ++++++++--------- src/end.c | 2 +- src/engrave.c | 12 +- src/exper.c | 6 +- src/explode.c | 20 +-- src/fountain.c | 2 +- src/hack.c | 124 +++++++++---------- src/iactions.c | 4 +- src/insight.c | 44 +++---- src/invent.c | 16 +-- src/light.c | 10 +- src/lock.c | 28 ++--- src/mcastu.c | 12 +- src/mhitm.c | 32 ++--- src/mhitu.c | 128 +++++++++---------- src/minion.c | 2 +- src/mon.c | 22 ++-- src/mondata.c | 34 +++--- src/monmove.c | 22 ++-- src/mthrowu.c | 40 +++--- src/muse.c | 14 +-- src/music.c | 14 +-- src/pager.c | 8 +- src/pickup.c | 30 ++--- src/pline.c | 2 +- src/polyself.c | 170 +++++++++++++------------- src/potion.c | 48 ++++---- src/pray.c | 30 ++--- src/read.c | 34 +++--- src/region.c | 10 +- src/restore.c | 74 ++++++----- src/save.c | 36 ++++-- src/shk.c | 10 +- src/sit.c | 34 +++--- src/sounds.c | 18 +-- src/spell.c | 6 +- src/steal.c | 4 +- src/steed.c | 18 +-- src/teleport.c | 24 ++-- src/timeout.c | 28 ++--- src/trap.c | 188 ++++++++++++++-------------- src/u_init.c | 3 + src/uhitm.c | 306 +++++++++++++++++++++++----------------------- src/vault.c | 8 +- src/weapon.c | 2 +- src/were.c | 4 +- src/wield.c | 10 +- src/wizcmds.c | 4 +- src/worn.c | 4 +- src/write.c | 2 +- src/zap.c | 86 ++++++------- 74 files changed, 1136 insertions(+), 1102 deletions(-) diff --git a/include/decl.h b/include/decl.h index f66c0f5a8..7a34be6f1 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1082,7 +1082,6 @@ struct instance_globals_y { /* decl.c */ int y_maze_max; - struct monst youmonst; /* pline.c */ /* work buffer for You(), &c and verbalize() */ diff --git a/include/display.h b/include/display.h index fc52eac41..beac064c0 100644 --- a/include/display.h +++ b/include/display.h @@ -253,11 +253,11 @@ ((int) U_AP_TYPE == M_AP_NOTHING) \ ? hero_glyph \ : ((int) U_AP_TYPE == M_AP_FURNITURE) \ - ? cmap_to_glyph((int) gy.youmonst.mappearance) \ + ? cmap_to_glyph((int) u.umonst->mappearance) \ : ((int) U_AP_TYPE == M_AP_OBJECT) \ - ? objnum_to_glyph((int) gy.youmonst.mappearance) \ + ? objnum_to_glyph((int) u.umonst->mappearance) \ /* else U_AP_TYPE == M_AP_MONSTER */ \ - : monnum_to_glyph((int) gy.youmonst.mappearance, Ugender))) + : monnum_to_glyph((int) u.umonst->mappearance, Ugender))) /* * NetHack glyphs diff --git a/include/hack.h b/include/hack.h index f655a8961..1a8e07f14 100644 --- a/include/hack.h +++ b/include/hack.h @@ -464,7 +464,7 @@ enum encumbrance_types { }; struct entity { - struct monst *emon; /* youmonst for the player */ + struct monst *emon; /* u.umonst for the player */ struct permonst *edata; /* must be non-zero for record to be valid */ int ex, ey; }; @@ -1284,7 +1284,7 @@ typedef uint32_t mmflags_nht; /* makemon MM_ flags */ #define FM_FMON 0x01 /* search the fmon chain */ #define FM_MIGRATE 0x02 /* search the migrating monster chain */ #define FM_MYDOGS 0x04 /* search gm.mydogs */ -#define FM_YOU 0x08 /* check for gy.youmonst */ +#define FM_YOU 0x08 /* check for u.umonst */ #define FM_EVERYWHERE (FM_YOU | FM_FMON | FM_MIGRATE | FM_MYDOGS) /* Flags to control pick_[race,role,gend,align] routines in role.c */ diff --git a/include/monst.h b/include/monst.h index 8f189b4b7..6b3262706 100644 --- a/include/monst.h +++ b/include/monst.h @@ -67,8 +67,8 @@ enum m_ap_types { #define M_AP_TYPMASK 0x7 #define M_AP_F_DKNOWN 0x8 -#define U_AP_TYPE (gy.youmonst.m_ap_type & M_AP_TYPMASK) -#define U_AP_FLAG (gy.youmonst.m_ap_type & ~M_AP_TYPMASK) +#define U_AP_TYPE (u.umonst->m_ap_type & M_AP_TYPMASK) +#define U_AP_FLAG (u.umonst->m_ap_type & ~M_AP_TYPMASK) #define M_AP_TYPE(m) ((m)->m_ap_type & M_AP_TYPMASK) #define M_AP_FLAG(m) ((m)->m_ap_type & ~M_AP_TYPMASK) diff --git a/include/you.h b/include/you.h index a073e5c57..1f4b9c592 100644 --- a/include/you.h +++ b/include/you.h @@ -496,8 +496,9 @@ struct you { struct skills weapon_skills[P_NUM_SKILLS]; boolean twoweap; /* KMH -- Using two-weapon combat */ short mcham; /* vampire mndx if shapeshifted to bat/cloud */ - short umovement; /* instead of youmonst.movement */ + short umovement; /* instead of u.umonst->movement */ schar uachieved[N_ACH]; /* list of achievements in the order attained */ + struct monst *umonst; }; /* end of `struct you' */ diff --git a/include/youprop.h b/include/youprop.h index f2c166606..98862dead 100644 --- a/include/youprop.h +++ b/include/youprop.h @@ -67,7 +67,7 @@ #define HSick_resistance u.uprops[SICK_RES].intrinsic #define ESick_resistance u.uprops[SICK_RES].extrinsic #define Sick_resistance (HSick_resistance || ESick_resistance \ - || defended(&gy.youmonst, AD_DISE)) + || defended(u.umonst, AD_DISE)) /* Intrinsics only */ #define Invulnerable u.uprops[INVULNERABLE].intrinsic /* [Tom] */ @@ -270,11 +270,11 @@ #define HMagical_breathing u.uprops[MAGICAL_BREATHING].intrinsic #define EMagical_breathing u.uprops[MAGICAL_BREATHING].extrinsic #define Amphibious \ - (HMagical_breathing || EMagical_breathing || amphibious(gy.youmonst.data)) + (HMagical_breathing || EMagical_breathing || amphibious(u.umonst->data)) /* Get wet, may go under surface */ #define Breathless \ - (HMagical_breathing || EMagical_breathing || breathless(gy.youmonst.data)) + (HMagical_breathing || EMagical_breathing || breathless(u.umonst->data)) #define Underwater (u.uinwater) /* Note that Underwater and u.uinwater are both used in code. @@ -398,7 +398,7 @@ redundant but allows the function calls to be skipped most of the time */ #define Unaware (gm.multi < 0 && (unconscious() || is_fainted())) -#define Hate_silver (u.ulycn >= LOW_PM || hates_silver(gy.youmonst.data)) +#define Hate_silver (u.ulycn >= LOW_PM || hates_silver(u.umonst->data)) /* _The_Hitchhikers_Guide_to_the_Galaxy_ on uses for 'towel': "wrap it round your head to ward off noxious fumes" [we require it to be damp or wet] */ diff --git a/src/allmain.c b/src/allmain.c index e9865e73e..4ac564c87 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -120,7 +120,7 @@ u_calc_moveamt(int wtcap) /* your speed doesn't augment steed's speed */ moveamt = mcalcmove(u.usteed, TRUE); } else { - moveamt = gy.youmonst.data->mmove; + moveamt = u.umonst->data->mmove; if (Very_fast) { /* speed boots, potion, or spell */ /* gain a free action on 2/3 of turns */ @@ -292,7 +292,7 @@ moveloop_core(void) mvl_wtcap = UNENCUMBERED; } else if (!Upolyd ? (u.uhp < u.uhpmax) : (u.mh < u.mhmax - || gy.youmonst.data->mlet == S_EEL)) { + || u.umonst->data->mlet == S_EEL)) { /* maybe heal */ regen_hp(mvl_wtcap); } @@ -483,7 +483,7 @@ moveloop_core(void) curs_on_u(); } - m_everyturn_effect(&gy.youmonst); + m_everyturn_effect(u.umonst); svc.context.move = 1; @@ -636,7 +636,7 @@ regen_hp(int wtcap) if (Upolyd) { if (u.mh < 1) { /* shouldn't happen... */ rehumanize(); - } else if (gy.youmonst.data->mlet == S_EEL + } else if (u.umonst->data->mlet == S_EEL && !is_pool(u.ux, u.uy) && !Is_waterlevel(&u.uz) && !Breathless) { /* eel out of water loses hp, similar to monster eels; @@ -775,7 +775,7 @@ newgame(void) /* make sure welcome messages are given before noticing monsters */ notice_mon_off(); disp.botlx = TRUE; - svc.context.ident = 2; /* id 1 is reserved for gy.youmonst */ + svc.context.ident = 2; /* id 1 is reserved for u.umonst->m_id */ svc.context.warnlevel = 1; svc.context.next_attrib_check = 600L; /* arbitrary first setting */ svc.context.tribute.enabled = TRUE; /* turn on 3.6 tributes */ diff --git a/src/apply.c b/src/apply.c index 40aefc3d9..7f0d4320e 100644 --- a/src/apply.c +++ b/src/apply.c @@ -324,7 +324,7 @@ use_stethoscope(struct obj *obj) boolean interference = (u.uswallow && is_whirly(u.ustuck->data) && !rn2(Role_if(PM_HEALER) ? 10 : 3)); - if (nohands(gy.youmonst.data)) { + if (nohands(u.umonst->data)) { You("have no hands!"); /* not `body_part(HAND)' */ return ECMD_OK; } else if (Deaf) { @@ -475,7 +475,7 @@ static const char whistle_str[] = "produce a %s whistling sound.", staticfn void use_whistle(struct obj *obj) { - if (!can_blow(&gy.youmonst)) { + if (!can_blow(u.umonst)) { You("are incapable of using the whistle."); } else if (Underwater) { You("blow bubbles through %s.", yname(obj)); @@ -494,13 +494,13 @@ use_whistle(struct obj *obj) staticfn void use_magic_whistle(struct obj *obj) { - if (!can_blow(&gy.youmonst)) { + if (!can_blow(u.umonst)) { You("are incapable of using the whistle."); } else if (obj->cursed && !rn2(2)) { You("produce a %shigh-%s.", Underwater ? "very " : "", Deaf ? "frequency vibration" : "pitched humming noise"); wake_nearby(TRUE); - if (!rn2(2) && !noteleport_level(&gy.youmonst)) + if (!rn2(2) && !noteleport_level(u.umonst)) tele_to_rnd_pet(); } else { /* it's magic! it works underwater too (at a higher pitch) */ @@ -1054,8 +1054,8 @@ use_mirror(struct obj *obj) } gn.nomovemsg = 0; /* default, "you can move again" */ } - } else if (is_vampire(gy.youmonst.data) - || is_vampshifter(&gy.youmonst)) { + } else if (is_vampire(u.umonst->data) + || is_vampshifter(u.umonst)) { You("don't have a reflection."); } else if (u.umonnum == PM_UMBER_HULK) { pline("Huh? That doesn't look like you!"); @@ -1786,7 +1786,7 @@ dorub(void) { struct obj *obj; - if (nohands(gy.youmonst.data)) { + if (nohands(u.umonst->data)) { You("aren't able to rub anything without hands."); return ECMD_OK; } @@ -1884,7 +1884,7 @@ check_jump(genericptr arg, coordxy x, coordxy y) /* let giants jump over boulders (what about Flying? and is there really enough head room for giants to jump at all, let alone over something tall?) */ - if (sobj_at(BOULDER, x, y) && !throws_rocks(gy.youmonst.data)) + if (sobj_at(BOULDER, x, y) && !throws_rocks(u.umonst->data)) return FALSE; return TRUE; } @@ -1993,7 +1993,7 @@ jump(int magic) /* 0=Physical, otherwise skill level */ if (!magic && !Jumping && known_spell(SPE_JUMPING) >= spe_Fresh) return spelleffects(SPE_JUMPING, FALSE, FALSE); - if (!magic && (nolimbs(gy.youmonst.data) || slithy(gy.youmonst.data))) { + if (!magic && (nolimbs(u.umonst->data) || slithy(u.umonst->data))) { /* normally (nolimbs || slithy) implies !Jumping, but that isn't necessarily the case for knights */ You_cant("jump; you have no legs!"); @@ -2197,7 +2197,7 @@ use_tinning_kit(struct obj *obj) char kbuf[BUFSZ]; const char *corpse_name = an(cxname(corpse)); - if (poly_when_stoned(gy.youmonst.data)) { + if (poly_when_stoned(u.umonst->data)) { You("tin %s without wearing gloves.", corpse_name); kbuf[0] = '\0'; } else { @@ -2634,7 +2634,7 @@ use_grease(struct obj *obj) if (otmp != &hands_obj) { You("cover %s with a thick layer of grease.", yname(otmp)); otmp->greased = 1; - if (obj->cursed && !nohands(gy.youmonst.data)) { + if (obj->cursed && !nohands(u.umonst->data)) { make_glib(oldglib + rn1(6, 10)); /* + 10..15 */ pline("Some of the grease gets all over your %s.", fingers_or_gloves(TRUE)); @@ -2826,7 +2826,7 @@ use_trap(struct obj *otmp) int levtyp = levl[u.ux][u.uy].typ; const char *occutext = "setting the trap"; - if (nohands(gy.youmonst.data)) + if (nohands(u.umonst->data)) what = "without hands"; else if (Stunned) what = "while stunned"; @@ -3108,7 +3108,7 @@ use_whip(struct obj *obj) cc.y = ry; You("wrap your bullwhip around %s.", wrapped_what); if (proficient && rn2(proficient + 2)) { - if (!mtmp || enexto(&cc, rx, ry, gy.youmonst.data)) { + if (!mtmp || enexto(&cc, rx, ry, u.umonst->data)) { You("yank yourself out of the pit!"); reset_utrap(TRUE); /* [was after teleds(); do this before * in case it has no alternative other @@ -3192,7 +3192,7 @@ use_whip(struct obj *obj) so proficient at catching weapons */ int dam, hitvalu, hitu; - dam = dmgval(otmp, &gy.youmonst); + dam = dmgval(otmp, u.umonst); hitvalu = 8 + otmp->spe; hitu = thitu(hitvalu, Maybe_Half_Phys(dam), &otmp, (char *) 0); @@ -3210,7 +3210,7 @@ use_whip(struct obj *obj) if (otmp->otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm]) && !uarmg && !Stone_resistance - && !(poly_when_stoned(gy.youmonst.data) + && !(poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM))) { char kbuf[BUFSZ]; @@ -3581,7 +3581,7 @@ use_cream_pie(struct obj *obj) You("immerse your %s in %s%s.", body_part(FACE), several ? "one of " : "", several ? makeplural(the(xname(obj))) : the(xname(obj))); - if (can_blnd((struct monst *) 0, &gy.youmonst, AT_WEAP, obj)) { + if (can_blnd((struct monst *) 0, u.umonst, AT_WEAP, obj)) { int blindinc = rnd(25); u.ucreamed += blindinc; @@ -3921,7 +3921,7 @@ do_break_wand(struct obj *obj) boolean is_fragile = (objdescr_is(obj, "balsa") || objdescr_is(obj, "glass")); - if (nohands(gy.youmonst.data)) { + if (nohands(u.umonst->data)) { You_cant("break %s without hands!", yname(obj)); return ECMD_OK; } else if (!freehand()) { @@ -4216,7 +4216,7 @@ doapply(void) struct obj *obj; int res = ECMD_TIME; - if (nohands(gy.youmonst.data)) { + if (nohands(u.umonst->data)) { You("aren't able to use or apply tools in your current form."); return ECMD_OK; } diff --git a/src/artifact.c b/src/artifact.c index e0e3df173..17715e10c 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -914,7 +914,7 @@ touch_artifact(struct obj *obj, struct monst *mon) if (oart == &artilist[ART_NONARTIFACT]) return 1; - yours = (mon == &gy.youmonst); + yours = (mon == u.umonst); /* all quest artifacts are self-willed; if this ever changes, `badclass' will have to be extended to explicitly include quest artifacts */ self_willed = ((oart->spfx & SPFX_INTEL) != 0); @@ -1014,7 +1014,7 @@ spec_applies(const struct artifact *weap, struct monst *mtmp) if (!(weap->spfx & (SPFX_DBONUS | SPFX_ATTK))) return (weap->attk.adtyp == AD_PHYS); - yours = (mtmp == &gy.youmonst); + yours = (mtmp == u.umonst); ptr = mtmp->data; if (weap->spfx & SPFX_DMONS) { @@ -1256,8 +1256,8 @@ Mb_hit(struct monst *magr, /* attacker */ { struct permonst *old_mdat; const char *verb; - boolean youattack = (magr == &gy.youmonst), - youdefend = (mdef == &gy.youmonst), + boolean youattack = (magr == u.umonst), + youdefend = (mdef == u.umonst), resisted = FALSE, do_stun, do_confuse, result; int attack_indx, fakeidx, scare_dieroll = MB_MAX_DIEROLL / 2; @@ -1313,7 +1313,7 @@ Mb_hit(struct monst *magr, /* attacker */ /* now perform special effects */ switch (attack_indx) { case MB_INDEX_CANCEL: - old_mdat = youdefend ? gy.youmonst.data : mdef->data; + old_mdat = youdefend ? u.umonst->data : mdef->data; /* No mdef->mcan check: even a cancelled monster can be polymorphed * into a golem, and the "cancel" effect acts as if some magical * energy remains in spellcasting defenders to be absorbed later. @@ -1323,7 +1323,7 @@ Mb_hit(struct monst *magr, /* attacker */ } else { do_stun = FALSE; if (youdefend) { - if (gy.youmonst.data != old_mdat) + if (u.umonst->data != old_mdat) *dmgptr = 0; /* rehumanized, so no more damage */ if (u.uenmax > 0) { u.uenmax--; @@ -1359,7 +1359,7 @@ Mb_hit(struct monst *magr, /* attacker */ nomul(-3); gm.multi_reason = "being scared stiff"; gn.nomovemsg = ""; - if (magr && magr == u.ustuck && sticks(gy.youmonst.data)) { + if (magr && magr == u.ustuck && sticks(u.umonst->data)) { set_ustuck((struct monst *) 0); You("release %s!", mon_nam(magr)); } @@ -1445,14 +1445,14 @@ DISABLE_WARNING_FORMAT_NONLITERAL */ boolean artifact_hit( - struct monst *magr, /* attacker; might be Null if 'mdef' is youmonst */ + struct monst *magr, /* attacker; might be Null if 'mdef' is u.umonst */ struct monst *mdef, /* defender */ struct obj *otmp, /* artifact weapon */ int *dmgptr, /* output */ int dieroll) /* needed for Magicbane and vorpal blades */ { - boolean youattack = (magr == &gy.youmonst); - boolean youdefend = (mdef == &gy.youmonst); + boolean youattack = (magr == u.umonst); + boolean youdefend = (mdef == u.umonst); boolean vis = (!youattack && magr && cansee(magr->mx, magr->my)) || (!youdefend && cansee(mdef->mx, mdef->my)) || (youattack && engulfing_u(mdef) && !Blind); @@ -1575,7 +1575,7 @@ artifact_hit( observe_object(otmp); return TRUE; } else { - if (bigmonst(gy.youmonst.data)) { + if (bigmonst(u.umonst->data)) { pline("%s cuts deeply into you!", magr ? Monnam(magr) : wepdesc); *dmgptr *= 2; @@ -1622,14 +1622,14 @@ artifact_hit( observe_object(otmp); return TRUE; } else { - if (!has_head(gy.youmonst.data)) { + if (!has_head(u.umonst->data)) { pline("Somehow, %s misses you wildly.", magr ? mon_nam(magr) : wepdesc); *dmgptr = 0; return TRUE; } - if (noncorporeal(gy.youmonst.data) - || amorphous(gy.youmonst.data)) { + if (noncorporeal(u.umonst->data) + || amorphous(u.umonst->data)) { pline("%s slices through your %s.", wepdesc, body_part(NECK)); return TRUE; @@ -2517,11 +2517,11 @@ retouch_object( return 1; } - if (touch_artifact(obj, &gy.youmonst)) { + if (touch_artifact(obj, u.umonst)) { char buf[BUFSZ]; int dmg = 0, tmp; boolean ag = (objects[obj->otyp].oc_material == SILVER && Hate_silver), - bane = bane_applies(get_artifact(obj), &gy.youmonst); + bane = bane_applies(get_artifact(obj), u.umonst); /* nothing else to do if hero can successfully handle this object */ if (!ag && !bane) @@ -2776,7 +2776,7 @@ is_magic_key(struct monst *mon, /* if null, non-rogue is assumed */ struct obj *obj) { if (is_art(obj, ART_MASTER_KEY_OF_THIEVERY)) { - if ((mon == &gy.youmonst) ? Role_if(PM_ROGUE) + if ((mon == u.umonst) ? Role_if(PM_ROGUE) : (mon && mon->data == &mons[PM_ROGUE])) return !obj->cursed; /* a rogue; non-cursed suffices for magic */ /* not a rogue; key must be blessed to behave as a magic one */ @@ -2785,7 +2785,7 @@ is_magic_key(struct monst *mon, /* if null, non-rogue is assumed */ return FALSE; } -/* figure out whether 'mon' (usually youmonst) is carrying the magic key */ +/* figure out whether 'mon' (usually u.umonst) is carrying the magic key */ struct obj * has_magic_key(struct monst *mon) /* if null, hero assumed */ { @@ -2793,8 +2793,8 @@ has_magic_key(struct monst *mon) /* if null, hero assumed */ short key = artilist[ART_MASTER_KEY_OF_THIEVERY].otyp; if (!mon) - mon = &gy.youmonst; - for (o = ((mon == &gy.youmonst) ? gi.invent : mon->minvent); o; + mon = u.umonst; + for (o = ((mon == u.umonst) ? gi.invent : mon->minvent); o; o = nxtobj(o, key, FALSE)) { if (is_magic_key(mon, o)) return o; diff --git a/src/attrib.c b/src/attrib.c index 27f454fd8..bebb46327 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -893,7 +893,7 @@ is_innate(int propidx) ignore innateness if equipment is going to claim responsibility */ && !u.uprops[propidx].extrinsic) return FROM_ROLE; - if ((propidx == BLINDED && !haseyes(gy.youmonst.data)) + if ((propidx == BLINDED && !haseyes(u.umonst->data)) || (propidx == BLND_RES && (HBlnd_resist & FROMFORM) != 0)) return FROM_FORM; return FROM_NONE; @@ -1219,7 +1219,7 @@ acurr(int chridx) there would limit Str to 18/07 [18 + 7] */ result = max(tmp, 3); } else if (chridx == A_CHA) { - if (tmp < 18 && (gy.youmonst.data->mlet == S_NYMPH + if (tmp < 18 && (u.umonst->data->mlet == S_NYMPH || u.umonnum == PM_AMOROUS_DEMON)) result = 18; } else if (chridx == A_CON) { diff --git a/src/botl.c b/src/botl.c index 66c4b8950..b6e72c896 100644 --- a/src/botl.c +++ b/src/botl.c @@ -256,7 +256,7 @@ bot(void) return; /* dosave() flags completion by setting u.uhp to -1; suppress_map_output() covers program_state.restoring and is used for status as well as map */ - if (u.uhp != -1 && gy.youmonst.data + if (u.uhp != -1 && u.umonst->data && iflags.status_updates && !suppress_map_output()) { if (VIA_WINDOWPORT()) { bot_via_windowport(); @@ -487,7 +487,7 @@ weapon_status(char *outbuf) /* no weapon; gloves imply hands; humanoid also implies hands; otherwise make no assumptions */ res = uarmg ? "Empty-hnd" /* empty handed means "gloves only" */ - : humanoid(gy.youmonst.data) ? "Bare-hnds" /* bare hands */ + : humanoid(u.umonst->data) ? "Bare-hnds" /* bare hands */ : "No-weapon"; } else if (u.twoweap) { /* two-weaponing implies hands and a weapon or wep-tool @@ -1179,7 +1179,7 @@ bot_via_windowport(void) #else test_if_enabled(bl_held) = TRUE; #endif - } else if (Upolyd && sticks(gy.youmonst.data)) { + } else if (Upolyd && sticks(u.umonst->data)) { test_if_enabled(bl_holding) = TRUE; } else { /* grab == hero is held by sea monster and about to be drowned; diff --git a/src/cmd.c b/src/cmd.c index de20c283b..93edbe4b9 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -889,7 +889,7 @@ RESTORE_WARNING_FORMAT_NONLITERAL int domonability(void) { - struct permonst *uptr = gy.youmonst.data; + struct permonst *uptr = u.umonst->data; boolean might_hide = (is_hider(uptr) || hides_under(uptr)); char c = '\0'; @@ -917,12 +917,12 @@ domonability(void) return domindblast(); else if (u.umonnum == PM_GREMLIN) { if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)) { - if (split_mon(&gy.youmonst, (struct monst *) 0)) + if (split_mon(u.umonst, (struct monst *) 0)) dryup(u.ux, u.uy, TRUE); } else if (is_pool(u.ux, u.uy)) { /* is_pool: might be wearing water walking boots or amulet of magical breathing */ - (void) split_mon(&gy.youmonst, (struct monst *) 0); + (void) split_mon(u.umonst, (struct monst *) 0); } else { There("is no fountain here."); } @@ -935,7 +935,7 @@ domonability(void) pline("Unfortunately sound does not carry well through rock."); else aggravate(); - } else if (is_vampire(uptr) || is_vampshifter(&gy.youmonst)) { + } else if (is_vampire(uptr) || is_vampshifter(u.umonst)) { return dopoly(); } else if (u.usteed && can_breathe(u.usteed->data)) { (void) pet_ranged_attk(u.usteed, TRUE); diff --git a/src/dbridge.c b/src/dbridge.c index 72d39be82..6afcac7d5 100644 --- a/src/dbridge.c +++ b/src/dbridge.c @@ -320,10 +320,10 @@ m_to_e(struct monst *mtmp, coordxy x, coordxy y, struct entity *etmp) staticfn void u_to_e(struct entity *etmp) { - etmp->emon = &gy.youmonst; + etmp->emon = u.umonst; etmp->ex = u.ux; etmp->ey = u.uy; - etmp->edata = gy.youmonst.data; + etmp->edata = u.umonst->data; } staticfn void @@ -337,7 +337,7 @@ set_entity( m_to_e(m_at(x, y), x, y, etmp); } -#define is_u(etmp) (etmp->emon == &gy.youmonst) +#define is_u(etmp) (etmp->emon == u.umonst) #define e_canseemon(etmp) (is_u(etmp) || canseemon(etmp->emon)) /* diff --git a/src/decl.c b/src/decl.c index 66f3d060e..14a92abb3 100644 --- a/src/decl.c +++ b/src/decl.c @@ -842,7 +842,6 @@ static const struct instance_globals_x g_init_x = { static const struct instance_globals_y g_init_y = { /* decl.c */ (ROWNO - 1) & ~1, /* y_maze_max */ - DUMMY, /* youmonst */ /* pline.c */ NULL, /* you_buf */ 0, /* you_buf_siz */ diff --git a/src/detect.c b/src/detect.c index bf536e127..ea077b91a 100644 --- a/src/detect.c +++ b/src/detect.c @@ -386,7 +386,7 @@ gold_detect(struct obj *sobj) adjust message if you have gold in your inventory */ char buf[BUFSZ]; - if (gy.youmonst.data == &mons[PM_GOLD_GOLEM]) + if (u.umonst->data == &mons[PM_GOLD_GOLEM]) Sprintf(buf, "You feel like a million %s!", currency(2L)); else if (money_cnt(gi.invent) || hidden_gold(TRUE)) Strcpy(buf, @@ -1227,7 +1227,7 @@ use_crystal_ball(struct obj **optr) make_confused((HConfusion & TIMEOUT) + impair, FALSE); break; case 3: - if (!resists_blnd(&gy.youmonst)) { + if (!resists_blnd(u.umonst)) { pline("%s your vision!", Tobjnam(obj, "damage")); make_blinded(BlindedTimeout + impair, FALSE); if (!Blind) @@ -1776,7 +1776,7 @@ openone(coordxy zx, coordxy zy, genericptr_t num) newsym(zx, zy); (*num_p)++; } - mon = u_at(zx, zy) ? &gy.youmonst : m_at(zx, zy); + mon = u_at(zx, zy) ? u.umonst : m_at(zx, zy); if (openholdingtrap(mon, &dummy) || openfallingtrap(mon, TRUE, &dummy)) (*num_p)++; diff --git a/src/dig.c b/src/dig.c index 5e5fc1a74..1c0ff6ceb 100644 --- a/src/dig.c +++ b/src/dig.c @@ -200,7 +200,7 @@ is_digging(void) return FALSE; } -#define BY_YOU (&gy.youmonst) +#define BY_YOU (u.umonst) #define BY_OBJECT ((struct monst *) 0) enum digcheck_result @@ -392,7 +392,7 @@ dig(void) } else if (ttmp && ttmp->ttyp == BEAR_TRAP && u.utrap) { if (rnl(7) > (Fumbling ? 1 : 4)) { char kbuf[BUFSZ]; - int dmg = dmgval(uwep, &gy.youmonst) + dbon(); + int dmg = dmgval(uwep, u.umonst) + dbon(); if (dmg < 1) dmg = 1; @@ -2181,8 +2181,8 @@ rot_corpse(anything *arg, long timeout) && hides_under(mtmp->data)) { mtmp->mundetected = 0; } else if (u_at(x, y) - && u.uundetected && hides_under(gy.youmonst.data)) - (void) hideunder(&gy.youmonst); + && u.uundetected && hides_under(u.umonst->data)) + (void) hideunder(u.umonst); newsym(x, y); } else if (in_invent) update_inventory(); @@ -2241,27 +2241,27 @@ void escape_tomb(void) { debugpline0("escape_tomb"); - if ((Teleportation || can_teleport(gy.youmonst.data)) + if ((Teleportation || can_teleport(u.umonst->data)) && (Teleport_control || rn2(3) < Luck+2)) { You("attempt a teleport spell."); (void) dotele(FALSE); /* calls unearth_you() */ } else if (u.uburied) { /* still buried after 'port attempt */ boolean good; - if (amorphous(gy.youmonst.data) || Passes_walls - || noncorporeal(gy.youmonst.data) - || (unsolid(gy.youmonst.data) - && gy.youmonst.data != &mons[PM_WATER_ELEMENTAL]) - || (tunnels(gy.youmonst.data) && !needspick(gy.youmonst.data))) { + if (amorphous(u.umonst->data) || Passes_walls + || noncorporeal(u.umonst->data) + || (unsolid(u.umonst->data) + && u.umonst->data != &mons[PM_WATER_ELEMENTAL]) + || (tunnels(u.umonst->data) && !needspick(u.umonst->data))) { You("%s up through the %s.", - (tunnels(gy.youmonst.data) && !needspick(gy.youmonst.data)) + (tunnels(u.umonst->data) && !needspick(u.umonst->data)) ? "try to tunnel" - : (amorphous(gy.youmonst.data)) + : (amorphous(u.umonst->data)) ? "ooze" : "phase", surface(u.ux, u.uy)); - good = (tunnels(gy.youmonst.data) && !needspick(gy.youmonst.data)) + good = (tunnels(u.umonst->data) && !needspick(u.umonst->data)) ? dighole(TRUE, FALSE, (coord *) 0) : TRUE; if (good) unearth_you(); diff --git a/src/do.c b/src/do.c index cacab11c7..b5aac1445 100644 --- a/src/do.c +++ b/src/do.c @@ -228,7 +228,7 @@ flooreffects( } mtmp->mtrapped = 0; } else { - if (!Passes_walls && !throws_rocks(gy.youmonst.data)) { + if (!Passes_walls && !throws_rocks(u.umonst->data)) { losehp(Maybe_Half_Phys(rnd(15)), "squished under a boulder", NO_KILLER_PREFIX); goto deletedwithboulder; @@ -1110,7 +1110,7 @@ staticfn boolean u_stuck_cannot_go(const char *updn) { if (u.ustuck) { - if (u.uswallow || !sticks(gy.youmonst.data)) { + if (u.uswallow || !sticks(u.umonst->data)) { You("are %s, and cannot go %s.", !u.uswallow ? "being held" : digests(u.ustuck->data) ? "swallowed" @@ -1257,7 +1257,7 @@ dodown(void) const char *down_or_thru = trap->ttyp == HOLE ? "down" : "through"; const char *actn = u_locomotion("jump"); - if (gy.youmonst.data->msize >= MZ_HUGE) { + if (u.umonst->data->msize >= MZ_HUGE) { char qbuf[QBUFSZ]; You("don't fit %s easily.", down_or_thru); @@ -1426,7 +1426,7 @@ u_collide_m(struct monst *mtmp) it was already here. Randomly move you to an adjacent spot or else the monster to any nearby location. Prior to 3.3.0 the latter was done unconditionally. */ - if (!rn2(2) && enexto(&cc, u.ux, u.uy, gy.youmonst.data) + if (!rn2(2) && enexto(&cc, u.ux, u.uy, u.umonst->data) && next2u(cc.x, cc.y)) u_on_newpos(cc.x, cc.y); /*[maybe give message here?]*/ else @@ -2008,7 +2008,7 @@ hellish_smoke_mesg(void) if (In_hell(&u.uz) && svl.level.flags.temperature > 0) You("%s smoke...", - olfaction(gy.youmonst.data) ? "smell" : "sense"); + olfaction(u.umonst->data) ? "smell" : "sense"); } /* give a message when the level temperature is different from previous */ diff --git a/src/do_name.c b/src/do_name.c index c27396343..b69b56e4d 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -689,7 +689,7 @@ namefloorobj(void) been moved off the hero's '@' yet, but there's no way to adjust the help text once getpos() has started */ Sprintf(buf, "object on map (or '.' for one %s you)", - (u.uundetected && hides_under(gy.youmonst.data)) + (u.uundetected && hides_under(u.umonst->data)) ? "over" : "under"); if (getpos(&cc, FALSE, buf) < 0 || cc.x <= 0) return; @@ -840,7 +840,7 @@ x_monnam( mappear_as_mon = (M_AP_TYPE(mtmp) == M_AP_MONSTER); char *bp, buf2[BUFSZ]; - if (mtmp == &gy.youmonst) + if (mtmp == u.umonst) return strcpy(buf, "you"); /* ignore article, "invisible", &c */ if (program_state.gameover) @@ -1290,7 +1290,7 @@ Mgender(struct monst *mtmp) { int mgender = MALE; - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { if (Upolyd ? u.mfemale : flags.female) mgender = FEMALE; } else if (mtmp->female) { diff --git a/src/do_wear.c b/src/do_wear.c index 382b17741..59e62927d 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -281,7 +281,7 @@ Boots_off(void) /* check for lava since fireproofed boots make it viable */ if ((is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) && !Levitation && !Flying - && !(is_clinger(gy.youmonst.data) && has_ceiling(&u.uz)) + && !(is_clinger(u.umonst->data) && has_ceiling(&u.uz)) && !svc.context.takeoff.cancelled_don /* avoid recursive call to lava_effects() */ && !iflags.in_lava_effects) { @@ -1035,7 +1035,7 @@ Amulet_on(struct obj *amul) } case AMULET_OF_STRANGULATION: /* note: might already be Strangled (via #wizintrinsic) */ - if (can_be_strangled(&gy.youmonst) && !Strangled) { + if (can_be_strangled(u.umonst) && !Strangled) { makeknown(AMULET_OF_STRANGULATION); Strangled = 6L; disp.botl = TRUE; @@ -1118,7 +1118,7 @@ Amulet_off(void) early_off_msg = TRUE; if (Underwater) { - if (!cant_drown(gy.youmonst.data) && !Swimming) { + if (!cant_drown(u.umonst->data) && !Swimming) { You("suddenly inhale an unhealthy amount of %s!", hliquid("water")); mkn = TRUE; /* in case of life-saving */ @@ -2034,7 +2034,7 @@ canwearobj(struct obj *otmp, long *mask, boolean noisy) /* this is the same check as for 'W' (dowear), but different message, in case we get here via 'P' (doputon) */ - if (verysmall(gy.youmonst.data) || nohands(gy.youmonst.data)) { + if (verysmall(u.umonst->data) || nohands(u.umonst->data)) { if (noisy) You("can't wear any armor in your current form."); return 0; @@ -2044,13 +2044,13 @@ canwearobj(struct obj *otmp, long *mask, boolean noisy) : is_shirt(otmp) ? c_shirt : is_suit(otmp) ? c_suit : 0; - if (which && cantweararm(gy.youmonst.data) + if (which && cantweararm(u.umonst->data) /* same exception for cloaks as used in m_dowear() */ && (which != c_cloak || ((otmp->otyp != MUMMY_WRAPPING) - ? gy.youmonst.data->msize != MZ_SMALL - : !WrappingAllowed(gy.youmonst.data))) - && (racial_exception(&gy.youmonst, otmp) < 1)) { + ? u.umonst->data->msize != MZ_SMALL + : !WrappingAllowed(u.umonst->data))) + && (racial_exception(u.umonst, otmp) < 1)) { if (noisy) pline_The("%s will not fit on your body.", which); return 0; @@ -2072,12 +2072,12 @@ canwearobj(struct obj *otmp, long *mask, boolean noisy) if (noisy) already_wearing(an(helm_simple_name(uarmh))); err++; - } else if (Upolyd && has_horns(gy.youmonst.data) && !is_flimsy(otmp)) { + } else if (Upolyd && has_horns(u.umonst->data) && !is_flimsy(otmp)) { /* (flimsy exception matches polyself handling) */ if (noisy) pline_The("%s won't fit over your horn%s.", helm_simple_name(otmp), - plur(num_horns(gy.youmonst.data))); + plur(num_horns(u.umonst->data))); err++; } else *mask = W_ARMH; @@ -2104,11 +2104,11 @@ canwearobj(struct obj *otmp, long *mask, boolean noisy) if (noisy) already_wearing(c_boots); err++; - } else if (Upolyd && slithy(gy.youmonst.data)) { + } else if (Upolyd && slithy(u.umonst->data)) { if (noisy) You("have no feet..."); /* not body_part(FOOT) */ err++; - } else if (Upolyd && gy.youmonst.data->mlet == S_CENTAUR) { + } else if (Upolyd && u.umonst->data->mlet == S_CENTAUR) { /* break_armor() pushes boots off for centaurs, so don't let dowear() put them back on; makeplural(body_part(FOOT)) would yield "rear hooves" here, @@ -2251,13 +2251,13 @@ accessory_or_armor_on(struct obj *obj) char answer, qbuf[QBUFSZ]; int res = 0; - if (nolimbs(gy.youmonst.data)) { + if (nolimbs(u.umonst->data)) { You("cannot make the ring stick to your body."); return ECMD_OK; } if (uleft && uright) { There("are no more %s%s to fill.", - humanoid(gy.youmonst.data) ? "ring-" : "", + humanoid(u.umonst->data) ? "ring-" : "", fingers_or_gloves(FALSE)); return ECMD_OK; } @@ -2268,7 +2268,7 @@ accessory_or_armor_on(struct obj *obj) } else { do { Sprintf(qbuf, "Which %s%s, Right or Left?", - humanoid(gy.youmonst.data) ? "ring-" : "", + humanoid(u.umonst->data) ? "ring-" : "", body_part(FINGER)); answer = yn_function(qbuf, rightleftchars, '\0', TRUE); switch (answer) { @@ -2321,7 +2321,7 @@ accessory_or_armor_on(struct obj *obj) return ECMD_OK; } } else if (eyewear) { - if (!has_head(gy.youmonst.data)) { + if (!has_head(u.umonst->data)) { You("have no head to wear %s on.", ansimpleoname(obj)); return ECMD_OK; } @@ -2435,7 +2435,7 @@ dowear(void) /* cantweararm() checks for suits of armor, not what we want here; verysmall() or nohands() checks for shields, gloves, etc... */ - if (verysmall(gy.youmonst.data) || nohands(gy.youmonst.data)) { + if (verysmall(u.umonst->data) || nohands(u.umonst->data)) { pline("Don't even bother."); return ECMD_OK; } @@ -2459,7 +2459,7 @@ doputon(void) && uarm && uarmu && uarmc && uarmh && uarms && uarmg && uarmf) { /* 'P' message doesn't mention armor */ Your("%s%s are full, and you're already wearing an amulet and %s.", - humanoid(gy.youmonst.data) ? "ring-" : "", + humanoid(u.umonst->data) ? "ring-" : "", fingers_or_gloves(FALSE), (ublindf->otyp == LENSES) ? "some lenses" : "a blindfold"); return ECMD_OK; @@ -2544,7 +2544,7 @@ glibr(void) rightfall = (uright && !uright->cursed && (!welded(uwep))); */ - if (!uarmg && (leftfall || rightfall) && !nolimbs(gy.youmonst.data)) { + if (!uarmg && (leftfall || rightfall) && !nolimbs(u.umonst->data)) { /* changed so cursed rings don't fall off, GAN 10/30/86 */ Your("%s off your %s.", (leftfall && rightfall) ? "rings slip" : "ring slips", @@ -2631,22 +2631,22 @@ some_armor(struct monst *victim) { struct obj *otmph, *otmp; - otmph = (victim == &gy.youmonst) ? uarmc : which_armor(victim, W_ARMC); + otmph = (victim == u.umonst) ? uarmc : which_armor(victim, W_ARMC); if (!otmph) - otmph = (victim == &gy.youmonst) ? uarm : which_armor(victim, W_ARM); + otmph = (victim == u.umonst) ? uarm : which_armor(victim, W_ARM); if (!otmph) - otmph = (victim == &gy.youmonst) ? uarmu : which_armor(victim, W_ARMU); + otmph = (victim == u.umonst) ? uarmu : which_armor(victim, W_ARMU); - otmp = (victim == &gy.youmonst) ? uarmh : which_armor(victim, W_ARMH); + otmp = (victim == u.umonst) ? uarmh : which_armor(victim, W_ARMH); if (otmp && (!otmph || !rn2(4))) otmph = otmp; - otmp = (victim == &gy.youmonst) ? uarmg : which_armor(victim, W_ARMG); + otmp = (victim == u.umonst) ? uarmg : which_armor(victim, W_ARMG); if (otmp && (!otmph || !rn2(4))) otmph = otmp; - otmp = (victim == &gy.youmonst) ? uarmf : which_armor(victim, W_ARMF); + otmp = (victim == u.umonst) ? uarmf : which_armor(victim, W_ARMF); if (otmp && (!otmph || !rn2(4))) otmph = otmp; - otmp = (victim == &gy.youmonst) ? uarms : which_armor(victim, W_ARMS); + otmp = (victim == u.umonst) ? uarms : which_armor(victim, W_ARMS); if (otmp && (!otmph || !rn2(4))) otmph = otmp; return otmph; @@ -2664,7 +2664,7 @@ stuck_ring(struct obj *ring, int otyp) if (ring && ring->otyp == otyp) { /* reasons ring can't be removed match those checked by select_off(); limbless case has extra checks because ordinarily it's temporary */ - if (nolimbs(gy.youmonst.data) && uamul + if (nolimbs(u.umonst->data) && uamul && uamul->otyp == AMULET_OF_UNCHANGING && uamul->cursed) return uamul; if (welded(uwep) && ((ring == RING_ON_PRIMARY) || bimanual(uwep))) @@ -2706,7 +2706,7 @@ select_off(struct obj *otmp) if (otmp == uright || otmp == uleft) { struct obj glibdummy; - if (nolimbs(gy.youmonst.data)) { + if (nolimbs(u.umonst->data)) { pline_The("ring is stuck."); return 0; } diff --git a/src/dog.c b/src/dog.c index a583de705..f9676050c 100644 --- a/src/dog.c +++ b/src/dog.c @@ -1181,7 +1181,7 @@ tamedog( if (mtmp == u.ustuck) { if (u.uswallow) expels(mtmp, mtmp->data, TRUE); - else if (!(Upolyd && sticks(gy.youmonst.data))) + else if (!(Upolyd && sticks(u.umonst->data))) unstuck(mtmp); } @@ -1239,7 +1239,7 @@ tamedog( with each other anymore] */ || mtmp->isshk || mtmp->isgd || mtmp->ispriest || mtmp->isminion || is_covetous(mtmp->data) || is_human(mtmp->data) - || (is_demon(mtmp->data) && !is_demon(gy.youmonst.data)) + || (is_demon(mtmp->data) && !is_demon(u.umonst->data)) || (obj && dogfood(mtmp, obj) >= MANFOOD)) return FALSE; @@ -1309,7 +1309,7 @@ wary_dog(struct monst *mtmp, boolean was_dead) if (!rn2(edog->abuse + 1)) mtmp->mpeaceful = 1; if (!quietly && cansee(mtmp->mx, mtmp->my)) { - if (haseyes(gy.youmonst.data)) { + if (haseyes(u.umonst->data)) { if (haseyes(mtmp->data)) pline_mon(mtmp, "%s %s to look you in the %s.", Monnam(mtmp), diff --git a/src/dogmove.c b/src/dogmove.c index 1218c305e..fa209f1d3 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -675,7 +675,7 @@ find_targ( break; if (curx == mtmp->mux && cury == mtmp->muy) - return &gy.youmonst; + return u.umonst; if ((targ = m_at(curx, cury)) != 0) { /* Is the monster visible to the pet? */ @@ -778,7 +778,7 @@ score_targ(struct monst *mtmp, struct monst *mtarg) return score; } /* Is the monster peaceful or tame? */ - if (/*mtarg->mpeaceful ||*/ mtarg->mtame || mtarg == &gy.youmonst) { + if (/*mtarg->mpeaceful ||*/ mtarg->mtame || mtarg == u.umonst) { /* Pets will never be targeted */ score -= 3000L; return score; @@ -907,7 +907,7 @@ pet_ranged_attk(struct monst *mtmp, boolean forced) if (mtarg && (!hungry || !rn2(5))) { int mstatus = M_ATTK_MISS; - if (mtarg == &gy.youmonst) { + if (mtarg == u.umonst) { if (mattacku(mtmp)) return MMOVE_DIED; /* Treat this as the pet having initiated an attack even if it @@ -931,7 +931,7 @@ pet_ranged_attk(struct monst *mtmp, boolean forced) * nothing will happen. */ if ((mstatus & M_ATTK_HIT) && !(mstatus & M_ATTK_DEF_DIED) - && rn2(4) && mtarg != &gy.youmonst) { + && rn2(4) && mtarg != u.umonst) { /* Can monster see? If it can, it can retaliate * even if the pet is invisible, since it'll see @@ -1054,7 +1054,7 @@ dog_move( } #if 0 /* [this is now handled in dochug()] */ if (!Conflict && !mtmp->mconf - && mtmp == u.ustuck && !sticks(gy.youmonst.data)) { + && mtmp == u.ustuck && !sticks(u.umonst->data)) { unstuck(mtmp); /* swallowed case handled above */ You("get released!"); } diff --git a/src/dokick.c b/src/dokick.c index 45d0b097c..e20f83100 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -6,7 +6,7 @@ #define is_bigfoot(x) ((x) == &mons[PM_SASQUATCH]) #define martial() \ - (martial_bonus() || is_bigfoot(gy.youmonst.data) \ + (martial_bonus() || is_bigfoot(u.umonst->data) \ || (uarmf && uarmf->otyp == KICKING_BOOTS)) /* gk.kickedobj (decl.c) tracks a kicked object until placed or destroyed */ @@ -53,7 +53,7 @@ kickdmg(struct monst *mon, boolean clumsy) if (mon->data == &mons[PM_SHADE]) dmg = 0; - specialdmg = special_dmgval(&gy.youmonst, mon, W_ARMF, (long *) 0); + specialdmg = special_dmgval(u.umonst, mon, W_ARMF, (long *) 0); if (mon->data == &mons[PM_SHADE] && !specialdmg) { pline_The("%s.", kick_passes_thru); @@ -180,7 +180,7 @@ kick_monster(struct monst *mon, coordxy x, coordxy y) * normally, getting all your attacks _including_ all your kicks. * If you have >1 kick attack, you get all of them. */ - if (Upolyd && attacktype(gy.youmonst.data, AT_KICK)) { + if (Upolyd && attacktype(u.umonst->data, AT_KICK)) { struct attack *uattk; int sum, kickdieroll, armorpenalty, specialdmg, attknum = 0, @@ -194,13 +194,13 @@ kick_monster(struct monst *mon, coordxy x, coordxy y) if (gm.multi < 0) break; - uattk = &gy.youmonst.data->mattk[i]; + uattk = &u.umonst->data->mattk[i]; /* we only care about kicking attacks here */ if (uattk->aatyp != AT_KICK) continue; kickdieroll = rnd(20); - specialdmg = special_dmgval(&gy.youmonst, mon, W_ARMF, + specialdmg = special_dmgval(u.umonst, mon, W_ARMF, (long *) 0); if (mon->data == &mons[PM_SHADE] && !specialdmg) { /* doesn't matter whether it would have hit or missed, @@ -545,7 +545,7 @@ really_kick_object(coordxy x, coordxy y) You("kick %s with your bare %s.", corpse_xname(gk.kickedobj, (const char *) 0, CXN_PFX_THE), makeplural(body_part(FOOT))); - if (poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM)) { + if (poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM)) { ; /* hero has been transformed but kick continues */ } else { /* normalize body shape here; foot, not body_part(FOOT) */ @@ -924,7 +924,7 @@ kick_door(coordxy x, coordxy y, int avrg_attrib) } exercise(A_DEX, TRUE); - doorbuster = Upolyd && is_giant(gy.youmonst.data); + doorbuster = Upolyd && is_giant(u.umonst->data); /* door is known to be CLOSED or LOCKED */ if (doorbuster || (rnl(35) < avrg_attrib + (!martial() ? 0 : ACURR(A_DEX)))) { @@ -1262,10 +1262,10 @@ dokick(void) struct monst *mtmp; boolean no_kick = FALSE; - if (nolimbs(gy.youmonst.data) || slithy(gy.youmonst.data)) { + if (nolimbs(u.umonst->data) || slithy(u.umonst->data)) { You("have no legs to kick with."); no_kick = TRUE; - } else if (verysmall(gy.youmonst.data)) { + } else if (verysmall(u.umonst->data)) { You("are too small to do any kicking."); no_kick = TRUE; } else if (u.usteed) { @@ -1282,7 +1282,7 @@ dokick(void) } else if (near_capacity() > SLT_ENCUMBER) { Your("load is too heavy to balance yourself for a kick."); no_kick = TRUE; - } else if (gy.youmonst.data->mlet == S_LIZARD) { + } else if (u.umonst->data->mlet == S_LIZARD) { Your("legs cannot kick effectively."); no_kick = TRUE; } else if (u.uinwater && !rn2(2)) { @@ -1429,7 +1429,7 @@ dokick(void) int range; range = - ((int) gy.youmonst.data->cwt + (weight_cap() + inv_weight())); + ((int) u.umonst->data->cwt + (weight_cap() + inv_weight())); if (range < 1) range = 1; /* divide by zero avoidance */ range = (3 * (int) mdat->cwt) / range; diff --git a/src/dothrow.c b/src/dothrow.c index 952913a43..e3ff3457c 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -125,7 +125,7 @@ throw_obj(struct obj *obj, int shotlimit) goto unsplit_stack; } if ((is_art(obj, ART_MJOLLNIR) && ACURR(A_STR) < STR19(25)) - || (obj->otyp == BOULDER && !throws_rocks(gy.youmonst.data))) { + || (obj->otyp == BOULDER && !throws_rocks(u.umonst->data))) { pline("It's too heavy."); res = ECMD_TIME; goto unsplit_stack; @@ -299,10 +299,10 @@ ok_to_throw(int *shotlimit_p) /* (see dothrow()) */ *shotlimit_p = LIMIT_TO_RANGE_INT(0, LARGEST_INT, gc.command_count); gm.multi = 0; /* reset; it's been used up */ - if (notake(gy.youmonst.data)) { + if (notake(u.umonst->data)) { You("are physically incapable of throwing or shooting anything."); return FALSE; - } else if (nohands(gy.youmonst.data)) { + } else if (nohands(u.umonst->data)) { You_cant("throw or shoot without hands."); /* not body_part(HAND) */ return FALSE; /*[what about !freehand(), aside from cursed missile launcher?]*/ @@ -341,7 +341,7 @@ throw_ok(struct obj *obj) if (uslinging() && obj->oclass == GEM_CLASS) return GETOBJ_SUGGEST; - if (throws_rocks(gy.youmonst.data) && obj->otyp == BOULDER) + if (throws_rocks(u.umonst->data) && obj->otyp == BOULDER) return GETOBJ_SUGGEST; return GETOBJ_DOWNPLAY; @@ -820,12 +820,12 @@ hurtle_step(genericptr_t arg, coordxy x, coordxy y) why = "touching the edge of the universe"; You("smack into something!"); } else if (diagonal - && bad_rock(gy.youmonst.data, u.ux, y) - && bad_rock(gy.youmonst.data, x, u.uy)) { + && bad_rock(u.umonst->data, u.ux, y) + && bad_rock(u.umonst->data, x, u.uy)) { boolean too_much = (gi.invent && (inv_weight() + weight_cap() > WT_TOOMUCH_DIAGONAL)); - if (bigmonst(gy.youmonst.data) || too_much) { + if (bigmonst(u.umonst->data) || too_much) { why = "wedging into a narrow crevice"; You("%sget forcefully wedged into a crevice.", too_much ? "and all your belongings " : ""); @@ -874,7 +874,7 @@ hurtle_step(genericptr_t arg, coordxy x, coordxy y) an(pmname(mon->data, NEUTRAL))); instapetrify(svk.killer.name); } - if (touch_petrifies(gy.youmonst.data) + if (touch_petrifies(u.umonst->data) && !which_armor(mon, W_ARMU | W_ARM | W_ARMC)) { minstapetrify(mon, TRUE); } @@ -883,8 +883,8 @@ hurtle_step(genericptr_t arg, coordxy x, coordxy y) } if ((u.ux - x) && (u.uy - y) - && bad_rock(gy.youmonst.data, u.ux, y) - && bad_rock(gy.youmonst.data, x, u.uy)) { + && bad_rock(u.umonst->data, u.ux, y) + && bad_rock(u.umonst->data, x, u.uy)) { /* Move at a diagonal. */ if (Sokoban) { You("come to an abrupt halt!"); @@ -1045,7 +1045,7 @@ mhurtle_step(genericptr_t arg, coordxy x, coordxy y) pline("%s bumps into you.", Some_Monnam(mon)); stop_occupation(); /* check whether 'mon' is turned to stone by touching poly'd hero */ - if (Upolyd && touch_petrifies(gy.youmonst.data) + if (Upolyd && touch_petrifies(u.umonst->data) && !which_armor(mon, W_ARMU | W_ARM | W_ARMC)) { /* give poly'd hero credit/blame despite a monster causing it */ minstapetrify(mon, TRUE); @@ -1287,14 +1287,14 @@ toss_up(struct obj *obj, boolean hitsroof) /* object now hits you */ if (obj->oclass == POTION_CLASS) { - potionhit(&gy.youmonst, obj, POTHIT_HERO_THROW); + potionhit(u.umonst, obj, POTHIT_HERO_THROW); } else if (breaktest(obj)) { int blindinc; /* need to check for blindness result prior to destroying obj */ blindinc = ((otyp == CREAM_PIE || otyp == BLINDING_VENOM) /* AT_WEAP is ok here even if attack type was AT_SPIT */ - && can_blnd(&gy.youmonst, &gy.youmonst, AT_WEAP, obj)) + && can_blnd(u.umonst, u.umonst, AT_WEAP, obj)) ? rnd(25) : 0; breakmsg(obj, !Blind); @@ -1304,7 +1304,7 @@ toss_up(struct obj *obj, boolean hitsroof) switch (otyp) { case EGG: if (petrifier && !Stone_resistance - && !(poly_when_stoned(gy.youmonst.data) + && !(poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM))) { /* egg ends up "all over your face"; perhaps visored helmet should still save you here */ @@ -1344,13 +1344,13 @@ toss_up(struct obj *obj, boolean hitsroof) less_damage = (hard_helmet(uarmh) && (!is_silver || !Hate_silver)), harmless = (stone_missile(obj) - && passes_rocks(gy.youmonst.data)), + && passes_rocks(u.umonst->data)), artimsg = FALSE; - int dmg = dmgval(obj, &gy.youmonst); + int dmg = dmgval(obj, u.umonst); if (obj->oartifact && !harmless) /* need a fake die roll here; rn1(18,2) avoids 1 and 20 */ - artimsg = artifact_hit((struct monst *) 0, &gy.youmonst, obj, + artimsg = artifact_hit((struct monst *) 0, u.umonst, obj, &dmg, rn1(18, 2)); if (!dmg) { /* probably wasn't a weapon; base damage on weight */ @@ -1364,9 +1364,9 @@ toss_up(struct obj *obj, boolean hitsroof) dmgval()'s artifact light against gremlin or axe against woody creature since both involve weapons; hero-as-shade is hypothetical because hero can't polymorph into that form */ - if (gy.youmonst.data == &mons[PM_SHADE] && !is_silver) + if (u.umonst->data == &mons[PM_SHADE] && !is_silver) dmg = 0; - if (obj->blessed && mon_hates_blessings(&gy.youmonst)) + if (obj->blessed && mon_hates_blessings(u.umonst)) dmg += rnd(4); if (is_silver && Hate_silver) dmg += rnd(20); @@ -1399,7 +1399,7 @@ toss_up(struct obj *obj, boolean hitsroof) harmless, but hitting a worn helmet negates that */ harmless = FALSE; } else if (petrifier && !Stone_resistance - && !(poly_when_stoned(gy.youmonst.data) + && !(poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM))) { petrify: svk.killer.format = KILLED_BY; @@ -1415,7 +1415,7 @@ toss_up(struct obj *obj, boolean hitsroof) if (is_silver && Hate_silver) pline_The("silver sears you!"); if (harmless) - hit(thesimpleoname(obj), &gy.youmonst, " but doesn't hurt."); + hit(thesimpleoname(obj), u.umonst, " but doesn't hurt."); hitfloor(obj, TRUE); gt.thrownobj = 0; @@ -1603,7 +1603,7 @@ throwit( hurtle(-u.dx, -u.dy, 1, TRUE); mon = boomhit(obj, u.dx, u.dy); iflags.returning_missile = 0; /* has returned or isn't going to */ - if (mon == &gy.youmonst) { /* the thing was caught */ + if (mon == u.umonst) { /* the thing was caught */ exercise(A_DEX, TRUE); obj = return_throw_to_inv(obj, wep_mask, twoweap, oldslot); throwit_return(TRUE); @@ -1743,7 +1743,7 @@ throwit( body_part(ARM)); if (obj->oartifact) (void) artifact_hit((struct monst *) 0, - &gy.youmonst, obj, &dmg, 0); + u.umonst, obj, &dmg, 0); losehp(Maybe_Half_Phys(dmg), killer_xname(obj), KILLED_BY); } @@ -2034,7 +2034,7 @@ thitmonst( * Distance and monster size affect chance to hit. */ tmp = -1 + Luck + find_mac(mon) + u.uhitinc - + maybe_polyd(gy.youmonst.data->mlevel, u.ulevel); + + maybe_polyd(u.umonst->data->mlevel, u.ulevel); if (ACURR(A_DEX) < 4) tmp -= 3; else if (ACURR(A_DEX) < 6) @@ -2073,7 +2073,7 @@ thitmonst( tmp += omon_adj(mon, obj, TRUE); if (is_orc(mon->data) - && maybe_polyd(is_elf(gy.youmonst.data), Race_if(PM_ELF))) + && maybe_polyd(is_elf(u.umonst->data), Race_if(PM_ELF))) tmp++; if (guaranteed_hit) { tmp += 1000; /* Guaranteed hit */ @@ -2170,7 +2170,7 @@ thitmonst( * Polymorphing won't make you a bow expert. */ if ((Race_if(PM_ELF) || Role_if(PM_SAMURAI)) - && (!Upolyd || your_race(gy.youmonst.data)) + && (!Upolyd || your_race(u.umonst->data)) && objects[uwep->otyp].oc_skill == P_BOW) { ++tmp; if ((Race_if(PM_ELF) && uwep->otyp == ELVEN_BOW) @@ -2500,16 +2500,16 @@ breakobj( if (obj->otyp == POT_OIL && obj->lamplit) { explode_oil(obj, x, y); } else if (next2u(x, y)) { - if (!breathless(gy.youmonst.data) || haseyes(gy.youmonst.data)) { + if (!breathless(u.umonst->data) || haseyes(u.umonst->data)) { /* wet towel protects both eyes and breathing */ if (obj->otyp != POT_WATER && !Half_gas_damage) { - if (!breathless(gy.youmonst.data)) { + if (!breathless(u.umonst->data)) { /* [what about "familiar odor" when known?] */ You("smell a peculiar odor..."); } else { const char *eyes = body_part(EYE); - if (eyecount(gy.youmonst.data) != 1) + if (eyecount(u.umonst->data) != 1) eyes = makeplural(eyes); Your("%s %s.", eyes, vtense(eyes, "water")); } diff --git a/src/eat.c b/src/eat.c index e62a2ffea..1b58c316f 100644 --- a/src/eat.c +++ b/src/eat.c @@ -97,12 +97,12 @@ is_edible(struct obj *obj) /* above also prevents the Amulet from being eaten, so we must never allow fake amulets to be eaten either [which is already the case] */ - if (gy.youmonst.data == &mons[PM_FIRE_ELEMENTAL] + if (u.umonst->data == &mons[PM_FIRE_ELEMENTAL] && is_flammable(obj)) return TRUE; - if (metallivorous(gy.youmonst.data) && is_metallic(obj) - && (gy.youmonst.data != &mons[PM_RUST_MONSTER] || is_rustprone(obj))) + if (metallivorous(u.umonst->data) && is_metallic(obj) + && (u.umonst->data != &mons[PM_RUST_MONSTER] || is_rustprone(obj))) return TRUE; /* Ghouls only eat non-veggy corpses or eggs (see dogfood()) */ @@ -170,7 +170,7 @@ eatmdone(void) } /* update display */ if (U_AP_TYPE) { - gy.youmonst.m_ap_type = M_AP_NOTHING; + u.umonst->m_ap_type = M_AP_NOTHING; newsym(u.ux, u.uy); } return 0; @@ -186,11 +186,11 @@ eatmupdate(void) if (!ge.eatmbuf || gn.nomovemsg != ge.eatmbuf) return; - if (is_obj_mappear(&gy.youmonst,ORANGE) && !Hallucination) { + if (is_obj_mappear(u.umonst,ORANGE) && !Hallucination) { /* revert from hallucinatory to "normal" mimicking */ altmsg = "You now prefer mimicking yourself."; altapp = GOLD_PIECE; - } else if (is_obj_mappear(&gy.youmonst,GOLD_PIECE) && Hallucination) { + } else if (is_obj_mappear(u.umonst,GOLD_PIECE) && Hallucination) { /* won't happen; anything which might make immobilized hero begin hallucinating (black light attack, theft of Grayswandir) will terminate the mimicry first */ @@ -207,7 +207,7 @@ eatmupdate(void) } gn.nomovemsg = strcpy(ge.eatmbuf, altmsg); /* update current image */ - gy.youmonst.mappearance = altapp; + u.umonst->mappearance = altapp; newsym(u.ux, u.uy); } } @@ -343,12 +343,12 @@ adj_victual_nutrition(void) assert(nut > 0); if (otyp == LEMBAS_WAFER) { - if (maybe_polyd(is_elf(gy.youmonst.data), Race_if(PM_ELF))) + if (maybe_polyd(is_elf(u.umonst->data), Race_if(PM_ELF))) nut += (nut + 2) / 4; /* 800 -> 1000 */ - else if (maybe_polyd(is_orc(gy.youmonst.data), Race_if(PM_ORC))) + else if (maybe_polyd(is_orc(u.umonst->data), Race_if(PM_ORC))) nut -= (nut + 2) / 4; /* 800 -> 600 */ } else if (otyp == CRAM_RATION) { - if (maybe_polyd(is_dwarf(gy.youmonst.data), Race_if(PM_DWARF))) + if (maybe_polyd(is_dwarf(u.umonst->data), Race_if(PM_DWARF))) nut += (nut + 3) / 6; /* 600 -> 700 */ } nut = max(nut, 1); @@ -554,7 +554,7 @@ done_eating(boolean message) gn.nomovemsg = 0; } else if (message) { You("finish %s %s.", - (gy.youmonst.data == &mons[PM_FIRE_ELEMENTAL]) ? "consuming" + (u.umonst->data == &mons[PM_FIRE_ELEMENTAL]) ? "consuming" : "eating", food_xname(piece, TRUE)); } @@ -612,18 +612,18 @@ eat_brains( /* previous tentacle attack might have triggered fatal passive counterattack [callers ought to be updated to avoid this situation] */ - if (magr != &gy.youmonst && DEADMONSTER(magr)) { + if (magr != u.umonst && DEADMONSTER(magr)) { return M_ATTK_AGR_DIED; } if (noncorporeal(pd)) { if (visflag) pline("%s brain is unharmed.", - (mdef == &gy.youmonst) ? "Your" : s_suffix(Monnam(mdef))); + (mdef == u.umonst) ? "Your" : s_suffix(Monnam(mdef))); return M_ATTK_MISS; /* side-effects can't occur */ - } else if (magr == &gy.youmonst) { + } else if (magr == u.umonst) { You("eat %s brain!", s_suffix(mon_nam(mdef))); - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { Your("brain is eaten!"); } else { /* monster against monster */ if (visflag && canspotmon(mdef)) @@ -634,7 +634,7 @@ eat_brains( /* mind flayer has attempted to eat the brains of a petrification inducing critter (most likely Medusa; attacking a cockatrice via tentacle-touch should have been caught before reaching this far) */ - if (magr == &gy.youmonst) { + if (magr == u.umonst) { if (!Stone_resistance && !Stoned) make_stoned(5L, (char *) 0, KILLED_BY_AN, pmname(pd, Mgender(mdef))); @@ -656,7 +656,7 @@ eat_brains( } } - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* * player mind flayer is eating something's brain */ @@ -690,7 +690,7 @@ eat_brains( is cannibalism */ (void) maybe_cannibal(monsndx(pd), TRUE); - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* * monster mind flayer is eating hero's brain */ @@ -773,7 +773,7 @@ maybe_cannibal(int pm, boolean allowmsg) (even if having the form of something which doesn't care about cannibalism--hero's innate traits aren't altered) */ && (your_race(fptr) - || (Upolyd && same_race(gy.youmonst.data, fptr)) + || (Upolyd && same_race(u.umonst->data, fptr)) || (ismnum(u.ulycn) && were_beastie(pm) == u.ulycn))) { if (allowmsg) { if (Upolyd && your_race(fptr)) @@ -793,7 +793,7 @@ cprefx(int pm) (void) maybe_cannibal(pm, TRUE); if (flesh_petrifies(&mons[pm])) { if (!Stone_resistance - && !(poly_when_stoned(gy.youmonst.data) + && !(poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM))) { /* if food was a tin, use it up early to keep it out of bones */ if (svc.context.tin.tin) @@ -849,7 +849,7 @@ cprefx(int pm) return; } case PM_GREEN_SLIME: - if (!Slimed && !Unchanging && !slimeproof(gy.youmonst.data)) { + if (!Slimed && !Unchanging && !slimeproof(u.umonst->data)) { You("don't feel very well."); make_slimed(10L, (char *) 0); delayed_killer(SLIMED, KILLED_BY_AN, ""); @@ -1191,7 +1191,7 @@ cpostfx(int pm) /*FALLTHRU*/ case PM_SMALL_MIMIC: tmp += 20; - if (gy.youmonst.data->mlet != S_MIMIC && !Unchanging) { + if (u.umonst->data->mlet != S_MIMIC && !Unchanging) { char buf[BUFSZ]; const char *tempshape = !Hallucination ? "a pile of gold" : "an orange"; @@ -1210,14 +1210,14 @@ cpostfx(int pm) Hallucination ? "You suddenly dread being peeled and mimic %s again!" : "You now prefer mimicking %s again.", - an(Upolyd ? pmname(gy.youmonst.data, Ugender) + an(Upolyd ? pmname(u.umonst->data, Ugender) : gu.urace.noun)); ge.eatmbuf = dupstr(buf); gn.nomovemsg = ge.eatmbuf; ga.afternmv = eatmdone; /* ??? what if this was set before? */ - gy.youmonst.m_ap_type = M_AP_OBJECT; - gy.youmonst.mappearance = Hallucination ? ORANGE : GOLD_PIECE; + u.umonst->m_ap_type = M_AP_OBJECT; + u.umonst->mappearance = Hallucination ? ORANGE : GOLD_PIECE; newsym(u.ux, u.uy); curs_on_u(); /* make gold symbol show up now */ @@ -1253,7 +1253,7 @@ cpostfx(int pm) if (svc.context.tin.tin) { use_up_tin(svc.context.tin.tin); /* most tin effects end up being skipped */ - lesshungry(200 + (metallivorous(gy.youmonst.data) ? 5 : 0)); + lesshungry(200 + (metallivorous(u.umonst->data) ? 5 : 0)); } You("%s.", (pm == PM_GENETIC_ENGINEER) @@ -1530,7 +1530,7 @@ consume_tin(const char *mesg) const char *what; int which, mnum, r, nutamt; /* if you've eaten tin itself, chance to not eat contents gets bypassed */ - boolean always_eat = metallivorous(gy.youmonst.data); + boolean always_eat = metallivorous(u.umonst->data); struct obj *tin = svc.context.tin.tin; r = tin_variety(tin, FALSE); @@ -1725,10 +1725,10 @@ start_tin(struct obj *otmp) const char *mesg = 0; int tmp; - if (metallivorous(gy.youmonst.data)) { + if (metallivorous(u.umonst->data)) { mesg = "You bite right into the metal tin..."; tmp = 0; - } else if (cantwield(gy.youmonst.data)) { /* nohands || verysmall */ + } else if (cantwield(u.umonst->data)) { /* nohands || verysmall */ You("cannot handle the tin properly to open it."); return; } else if (otmp->blessed) { @@ -1859,12 +1859,12 @@ eatcorpse(struct obj *otmp) int ll_conduct = 0; boolean stoneable, slimeable = (mnum == PM_GREEN_SLIME && !Slimed && !Unchanging - && !slimeproof(gy.youmonst.data)), + && !slimeproof(u.umonst->data)), glob = otmp->globby ? TRUE : FALSE; assert(ismnum(mnum)); stoneable = (flesh_petrifies(&mons[mnum]) && !Stone_resistance - && !poly_when_stoned(gy.youmonst.data)); + && !poly_when_stoned(u.umonst->data)); /* KMH, conduct */ if (!vegan(&mons[mnum])) @@ -1978,13 +1978,13 @@ eatcorpse(struct obj *otmp) } else { /* yummy is always False for omnivores, palatable always True */ boolean yummy = (vegan(&mons[mnum]) - ? (!carnivorous(gy.youmonst.data) - && herbivorous(gy.youmonst.data)) - : (carnivorous(gy.youmonst.data) - && !herbivorous(gy.youmonst.data))), + ? (!carnivorous(u.umonst->data) + && herbivorous(u.umonst->data)) + : (carnivorous(u.umonst->data) + && !herbivorous(u.umonst->data))), palatable = ((vegetarian(&mons[mnum]) - ? herbivorous(gy.youmonst.data) - : carnivorous(gy.youmonst.data)) + ? herbivorous(u.umonst->data) + : carnivorous(u.umonst->data)) && rn2(10) && (rotted < 1 || !rn2((int) rotted + 1))); const char *pmxnam = food_xname(otmp, FALSE); @@ -2129,9 +2129,9 @@ fprefx(struct obj *otmp) /* [satiation message may be inaccurate if eating gets interrupted] */ break; case TRIPE_RATION: - if (carnivorous(gy.youmonst.data) && !humanoid(gy.youmonst.data)) { + if (carnivorous(u.umonst->data) && !humanoid(u.umonst->data)) { pline("This tripe ration is surprisingly good!"); - } else if (maybe_polyd(is_orc(gy.youmonst.data), Race_if(PM_ORC))) { + } else if (maybe_polyd(is_orc(u.umonst->data), Race_if(PM_ORC))) { pline(Hallucination ? "Tastes great! Less filling!" : "Mmm, tripe... not bad!"); } else { @@ -2146,10 +2146,10 @@ fprefx(struct obj *otmp) } break; case LEMBAS_WAFER: - if (maybe_polyd(is_orc(gy.youmonst.data), Race_if(PM_ORC))) { + if (maybe_polyd(is_orc(u.umonst->data), Race_if(PM_ORC))) { pline("%s", "!#?&* elf kibble!"); break; - } else if (maybe_polyd(is_elf(gy.youmonst.data), Race_if(PM_ELF))) { + } else if (maybe_polyd(is_elf(u.umonst->data), Race_if(PM_ELF))) { pline("A little goes a long way."); break; } @@ -2160,7 +2160,7 @@ fprefx(struct obj *otmp) case MEAT_RING: goto give_feedback; case CLOVE_OF_GARLIC: - if (is_undead(gy.youmonst.data)) { + if (is_undead(u.umonst->data)) { make_vomiting((long) rn1(svc.context.victual.reqtime, 5), FALSE); break; } @@ -2293,7 +2293,7 @@ eataccessory(struct obj *otmp) set_mimic_blocking(); see_monsters(); if (Invis && !oldprop && !ESee_invisible - && !perceives(gy.youmonst.data) && !Blind) { + && !perceives(u.umonst->data) && !Blind) { newsym(u.ux, u.uy); pline("Suddenly you can see yourself."); makeknown(typ); @@ -2511,7 +2511,7 @@ fpostfx(struct obj *otmp) { switch (otmp->otyp) { case SPRIG_OF_WOLFSBANE: - if (ismnum(u.ulycn) || is_were(gy.youmonst.data)) + if (ismnum(u.ulycn) || is_were(u.umonst->data)) you_unwere(TRUE); break; case CARROT: @@ -2527,7 +2527,7 @@ fpostfx(struct obj *otmp) "became literate by reading the fortune inside a cookie"); break; case LUMP_OF_ROYAL_JELLY: - if (gy.youmonst.data == &mons[PM_KILLER_BEE] && !Unchanging + if (u.umonst->data == &mons[PM_KILLER_BEE] && !Unchanging && polymon(PM_QUEEN_BEE)) break; @@ -2561,7 +2561,7 @@ fpostfx(struct obj *otmp) if (ismnum(otmp->corpsenm) && flesh_petrifies(&mons[otmp->corpsenm])) { if (!Stone_resistance - && !(poly_when_stoned(gy.youmonst.data) + && !(poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM))) { if (!Stoned) { Sprintf(svk.killer.name, "%s egg", @@ -2646,10 +2646,10 @@ edibility_prompts(struct obj *otmp) stoneorslime = (ismnum(mnum) && flesh_petrifies(&mons[mnum]) && !Stone_resistance - && !poly_when_stoned(gy.youmonst.data)); + && !poly_when_stoned(u.umonst->data)); if (mnum == PM_GREEN_SLIME || otmp->otyp == GLOB_OF_GREEN_SLIME) - stoneorslime = (!Unchanging && !slimeproof(gy.youmonst.data)); + stoneorslime = (!Unchanging && !slimeproof(u.umonst->data)); if (cadaver && !nonrotting_corpse(mnum)) { long age = peek_at_iced_corpse_age(otmp); @@ -2870,7 +2870,7 @@ doeat(void) You_cant("eat %s you're wearing.", something); return ECMD_OK; } else if (!(carried(otmp) ? retouch_object(&otmp, FALSE) - : touch_artifact(otmp, &gy.youmonst))) { + : touch_artifact(otmp, u.umonst))) { return ECMD_TIME; /* got blasted so use a turn */ } if (is_metallic(otmp) && u.umonnum == PM_RUST_MONSTER @@ -3172,9 +3172,9 @@ gethungry(void) will need to wear an Amulet of Unchanging so still burn a small amount of nutrition in the 'moves % 20' ring/amulet check below */ if ((!Unaware || !rn2(10)) /* slow metabolic rate while asleep */ - && (carnivorous(gy.youmonst.data) - || herbivorous(gy.youmonst.data) - || metallivorous(gy.youmonst.data)) + && (carnivorous(u.umonst->data) + || herbivorous(u.umonst->data) + || metallivorous(u.umonst->data)) && !Slow_digestion) u.uhunger--; /* ordinary food consumption */ @@ -3583,7 +3583,7 @@ floorfood( struct obj *otmp; char qbuf[QBUFSZ]; char c; - struct permonst *uptr = gy.youmonst.data; + struct permonst *uptr = u.umonst->data; boolean feeding = !strcmp(verb, "eat"), /* corpsecheck==0 */ offering = !strcmp(verb, "sacrifice"); /* corpsecheck==1 */ @@ -3737,7 +3737,7 @@ vomit(void) /* A good idea from David Neves */ { boolean spewed = FALSE; - if (cantvomit(gy.youmonst.data)) { + if (cantvomit(u.umonst->data)) { /* doesn't cure food poisoning; message assumes that we aren't dealing with some esoteric body_part() */ Your("jaw gapes convulsively."); @@ -3764,7 +3764,7 @@ vomit(void) /* A good idea from David Neves */ if (spewed) { struct attack - *mattk = attacktype_fordmg(gy.youmonst.data, AT_BREA, AD_ACID); + *mattk = attacktype_fordmg(u.umonst->data, AT_BREA, AD_ACID); /* currently, only yellow dragons can breathe acid */ if (mattk) { @@ -3775,7 +3775,7 @@ vomit(void) /* A good idea from David Neves */ if (IS_ALTAR(levl[u.ux][u.uy].typ)) altar_wrath(u.ux, u.uy); /* if poly'd into acidic form, stomach acid is stronger than normal */ - if (acidic(gy.youmonst.data)) { + if (acidic(u.umonst->data)) { /* TODO: if there's a web here, destroy that too (before ice) */ if (is_ice(u.ux, u.uy)) melt_ice(u.ux, u.uy, diff --git a/src/end.c b/src/end.c index 389d8f548..ff67412eb 100644 --- a/src/end.c +++ b/src/end.c @@ -747,7 +747,7 @@ savelife(int how) /* might drop hero onto a trap that kills her all over again */ expels(u.ustuck, u.ustuck->data, TRUE); } else if (u.ustuck) { - if (Upolyd && sticks(gy.youmonst.data)) + if (Upolyd && sticks(u.umonst->data)) You("release %s.", mon_nam(u.ustuck)); else pline("%s releases you.", Monnam(u.ustuck)); diff --git a/src/engrave.c b/src/engrave.c index 22ca30aaf..9768b00b6 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -189,7 +189,7 @@ can_reach_floor(boolean check_pit) struct trap *t; if (u.uswallow - || (u.ustuck && !sticks(gy.youmonst.data) + || (u.ustuck && !sticks(u.umonst->data) /* assume that arms are pinned rather than that the hero has been lifted up above the floor [doesn't explain how hero can attack the creature holding him or her; @@ -200,10 +200,10 @@ can_reach_floor(boolean check_pit) /* Restricted/unskilled riders can't reach the floor */ if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) return FALSE; - if (u.uundetected && ceiling_hider(gy.youmonst.data)) + if (u.uundetected && ceiling_hider(u.umonst->data)) return FALSE; - if (Flying || gy.youmonst.data->msize >= MZ_HUGE) + if (Flying || u.umonst->data->msize >= MZ_HUGE) return TRUE; if (check_pit && (t = t_at(u.ux, u.uy)) != 0 @@ -531,7 +531,7 @@ u_can_engrave(void) return FALSE; } - if (cantwield(gy.youmonst.data)) { + if (cantwield(u.umonst->data)) { You_cant("even hold anything!"); return FALSE; } @@ -570,7 +570,7 @@ doengrave_ctx_init(struct _doengrave_ctx *de) if (de->oep) de->oetype = de->oep->engr_type; - if (is_demon(gy.youmonst.data) || is_vampire(gy.youmonst.data)) + if (is_demon(u.umonst->data) || is_vampire(u.umonst->data)) de->type = ENGR_BLOOD; de->jello = (u.uswallow && !(is_animal(u.ustuck->data) @@ -1245,7 +1245,7 @@ doengrave(void) if (de->post_engr_text[0]) pline("%s", de->post_engr_text); - if (de->doblind && !resists_blnd(&gy.youmonst)) { + if (de->doblind && !resists_blnd(u.umonst)) { You("are blinded by the flash!"); make_blinded((long) rnd(50), FALSE); if (!Blind) diff --git a/src/exper.c b/src/exper.c index aee851126..14312e691 100644 --- a/src/exper.c +++ b/src/exper.c @@ -213,7 +213,7 @@ losexp( wizard mode request to reduce level; never fatal though */ if (drainer && !strcmp(drainer, "#levelchange")) drainer = 0; - else if (resists_drli(&gy.youmonst)) + else if (resists_drli(u.umonst)) return; /* level-loss message; "Goodbye level 1." is fatal; divine anger @@ -280,7 +280,7 @@ losexp( u.uexp = newuexp(u.ulevel) - 1; if (Upolyd) { - num = monhp_per_lvl(&gy.youmonst); + num = monhp_per_lvl(u.umonst); u.mhmax -= num; u.mh -= num; if (u.mh <= 0) @@ -317,7 +317,7 @@ pluslvl( /* increase hit points (when polymorphed, do monster form first in order to retain normal human/whatever increase for later) */ if (Upolyd) { - hpinc = monhp_per_lvl(&gy.youmonst); + hpinc = monhp_per_lvl(u.umonst); u.mh += hpinc; setuhpmax(u.mhmax, FALSE); /* acts as setmhmax() when Upolyd */ } diff --git a/src/explode.c b/src/explode.c index 70f4c8307..41ef8a4df 100644 --- a/src/explode.c +++ b/src/explode.c @@ -24,13 +24,13 @@ enum explode_action { /* check if shield effects are needed for location affected by explosion */ staticfn int explosionmask( - struct monst *m, /* target monster (might be youmonst) */ + struct monst *m, /* target monster (might be u.umonst) */ uchar adtyp, /* damage type */ char olet) /* object class (only matters for AD_DISN) */ { int res = EXPL_NONE; - if (m == &gy.youmonst) { + if (m == u.umonst) { switch (adtyp) { case AD_PHYS: /* leave 'res' with EXPL_NONE */ @@ -274,7 +274,7 @@ explode( so might get hit by double damage */ grabbed = grabbing = FALSE; if (u.ustuck && !u.uswallow) { - if (Upolyd && sticks(gy.youmonst.data)) + if (Upolyd && sticks(u.umonst->data)) grabbing = TRUE; else grabbed = TRUE; @@ -363,7 +363,7 @@ explode( explmask[i][j] = EXPL_NONE; if (u_at(xx, yy)) { - explmask[i][j] = explosionmask(&gy.youmonst, adtyp, olet); + explmask[i][j] = explosionmask(u.umonst, adtyp, olet); } /* can be both you and mtmp if you're swallowed or riding */ mtmp = m_at(xx, yy); @@ -611,10 +611,10 @@ explode( } else if (adtyp == AD_PHYS || adtyp == AD_ACID) damu = Maybe_Half_Phys(damu); if (adtyp == AD_FIRE) { - (void) burnarmor(&gy.youmonst); + (void) burnarmor(u.umonst); ignite_items(gi.invent); } - (void) destroy_items(&gy.youmonst, (int) adtyp, dam); + (void) destroy_items(u.umonst, (int) adtyp, dam); ugolemeffects((int) adtyp, damu); if (uhurt == 2) { @@ -869,9 +869,9 @@ scatter( if (gm.multi) nomul(0); - dam = dmgval(stmp->obj, &gy.youmonst); + dam = dmgval(stmp->obj, u.umonst); hitvalu = 8 + stmp->obj->spe; - if (bigmonst(gy.youmonst.data)) + if (bigmonst(u.umonst->data)) hitvalu++; hitu = thitu(hitvalu, Maybe_Half_Phys(dam), &stmp->obj, (char *) 0); @@ -936,8 +936,8 @@ scatter( newsym(x, y); } newsym(sx, sy); - if (u_at(sx, sy) && u.uundetected && hides_under(gy.youmonst.data)) - (void) hideunder(&gy.youmonst); + if (u_at(sx, sy) && u.uundetected && hides_under(u.umonst->data)) + (void) hideunder(u.umonst); if (((mtmp = m_at(sx, sy)) != 0) && mtmp->mtrapped) mtmp->mtrapped = 0; maybe_unhide_at(sx, sy); diff --git a/src/fountain.c b/src/fountain.c index 78925b04c..aeef118bb 100644 --- a/src/fountain.c +++ b/src/fountain.c @@ -791,7 +791,7 @@ dipsink(struct obj *obj) breathless for this message */ pline("A wisp of vapor rises up..."); /* NB: potionbreathe calls trycall or makeknown as appropriate */ - if (!breathless(gy.youmonst.data) || haseyes(gy.youmonst.data)) + if (!breathless(u.umonst->data) || haseyes(u.umonst->data)) potionbreathe(obj); break; } diff --git a/src/hack.c b/src/hack.c index 367591eff..4e5ff410b 100644 --- a/src/hack.c +++ b/src/hack.c @@ -152,11 +152,11 @@ could_move_onto_boulder(coordxy sx, coordxy sy) return FALSE; /* can if a giant, unless doing so allows hero to pass into a diagonal squeeze at the same time */ - if (throws_rocks(gy.youmonst.data)) + if (throws_rocks(u.umonst->data)) return (!u.dx || !u.dy || !(IS_OBSTRUCTED(levl[u.ux][sy].typ) && IS_OBSTRUCTED(levl[sx][u.uy].typ))); /* can if tiny (implies carrying very little else couldn't move at all) */ - if (verysmall(gy.youmonst.data)) + if (verysmall(u.umonst->data)) return TRUE; /* can squeeze to spot if carrying extremely little, otherwise can't */ return squeezeablylightinvent(); @@ -189,7 +189,7 @@ dopush( || svm.moves < gb.bldrpushtime); what = givemesg ? the(xname(otmp)) : 0; if (!u.usteed) { - easypush = throws_rocks(gy.youmonst.data); + easypush = throws_rocks(u.umonst->data); if (givemesg) pline("With %s effort you move %s.", easypush ? "little" : "great", what); @@ -261,7 +261,7 @@ cannot_push_msg(struct obj *otmp, coordxy sx, coordxy sy) staticfn int cannot_push(struct obj *otmp, coordxy sx, coordxy sy) { - if (throws_rocks(gy.youmonst.data)) { + if (throws_rocks(u.umonst->data)) { boolean canpickup = (!Sokoban /* similar exception as in can_lift(): @@ -388,7 +388,7 @@ moverock_core(coordxy sx, coordxy sy) int res; feel_location(sx, sy); /* same for all 3 if/else-if/else cases */ - if (throws_rocks(gy.youmonst.data)) { + if (throws_rocks(u.umonst->data)) { /* player has used 'm' to move, so step to boulder's spot without pushing it; hero is poly'd into a giant, so exotic forms of locomotion are out, but might be @@ -423,7 +423,7 @@ moverock_core(coordxy sx, coordxy sy) /* Give them a chance to climb over it? */ return -1; } - if (verysmall(gy.youmonst.data) && !u.usteed) { + if (verysmall(u.umonst->data) && !u.usteed) { if (Blind) feel_location(sx, sy); pline("You're too small to push that %s.", xname(otmp)); @@ -667,7 +667,7 @@ still_chewing(coordxy x, coordxy y) nomul(0); return 1; } else if (lev->typ == IRONBARS - && metallivorous(gy.youmonst.data) && u.uhunger > 1500) { + && metallivorous(u.umonst->data) && u.uhunger > 1500) { /* finishing eating via 'morehungry()' doesn't handle choking */ You("are too full to eat the bars."); nomul(0); @@ -767,7 +767,7 @@ still_chewing(coordxy x, coordxy y) digtxt = "chew through the tree."; lev->typ = ROOM; } else if (lev->typ == IRONBARS) { - if (metallivorous(gy.youmonst.data)) { /* should always be True here */ + if (metallivorous(u.umonst->data)) { /* should always be True here */ /* arbitrary amount; unlike proper eating, nutrition is bestowed in a lump sum at the end */ int nut = (int) objects[HEAVY_IRON_BALL].oc_weight; @@ -955,7 +955,7 @@ cant_squeeze_thru(struct monst *mon) int amt; struct permonst *ptr = mon->data; - if ((mon == &gy.youmonst) ? Passes_walls : passes_walls(ptr)) + if ((mon == u.umonst) ? Passes_walls : passes_walls(ptr)) return 0; /* too big? */ @@ -965,13 +965,13 @@ cant_squeeze_thru(struct monst *mon) return 1; /* lugging too much junk? */ - amt = (mon == &gy.youmonst) ? inv_weight() + weight_cap() + amt = (mon == u.umonst) ? inv_weight() + weight_cap() : curr_mon_load(mon); if (amt > WT_TOOMUCH_DIAGONAL) return 2; /* Sokoban restriction applies to hero only */ - if (mon == &gy.youmonst && Sokoban) + if (mon == u.umonst && Sokoban) return 3; /* can squeeze through */ @@ -1023,19 +1023,19 @@ test_move( return FALSE; } else if (tmpr->typ == IRONBARS) { if (mode == DO_MOVE - && (dmgtype(gy.youmonst.data, AD_RUST) - || dmgtype(gy.youmonst.data, AD_CORR) - || metallivorous(gy.youmonst.data)) + && (dmgtype(u.umonst->data, AD_RUST) + || dmgtype(u.umonst->data, AD_CORR) + || metallivorous(u.umonst->data)) && still_chewing(x, y)) { return FALSE; } - if (!(Passes_walls || passes_bars(gy.youmonst.data))) { + if (!(Passes_walls || passes_bars(u.umonst->data))) { if (mode == DO_MOVE && flags.mention_walls) You("cannot pass through the bars."); return FALSE; } - } else if (tunnels(gy.youmonst.data) - && !needspick(gy.youmonst.data)) { + } else if (tunnels(u.umonst->data) + && !needspick(u.umonst->data)) { /* Eat the rock. */ if (mode == DO_MOVE && still_chewing(x, y)) return FALSE; @@ -1077,21 +1077,21 @@ test_move( feel_location(x, y); if (Passes_walls) { ; /* do nothing */ - } else if (can_ooze(&gy.youmonst)) { + } else if (can_ooze(u.umonst)) { if (mode == DO_MOVE) You("ooze under the door."); } else if (Underwater) { if (mode == DO_MOVE) pline("There is an obstacle there."); return FALSE; - } else if (tunnels(gy.youmonst.data) - && !needspick(gy.youmonst.data)) { + } else if (tunnels(u.umonst->data) + && !needspick(u.umonst->data)) { /* Eat the door. */ if (mode == DO_MOVE && still_chewing(x, y)) return FALSE; } else { if (mode == DO_MOVE) { - if (amorphous(gy.youmonst.data)) + if (amorphous(u.umonst->data)) You("try to ooze under the door," " but can't squeeze your possessions through."); if (flags.autoopen && !svc.context.run @@ -1150,10 +1150,10 @@ test_move( } } } - if (dx && dy && bad_rock(gy.youmonst.data, ux, y) - && bad_rock(gy.youmonst.data, x, uy)) { + if (dx && dy && bad_rock(u.umonst->data, ux, y) + && bad_rock(u.umonst->data, x, uy)) { /* Move at a diagonal. */ - switch (cant_squeeze_thru(&gy.youmonst)) { + switch (cant_squeeze_thru(u.umonst)) { case 3: if (mode == DO_MOVE) You("cannot pass that way."); @@ -1222,7 +1222,7 @@ test_move( } if (mode == DO_MOVE) { /* tunneling monsters will chew before pushing */ - if (tunnels(gy.youmonst.data) && !needspick(gy.youmonst.data) + if (tunnels(u.umonst->data) && !needspick(u.umonst->data) && !Sokoban) { if (still_chewing(x, y)) return FALSE; @@ -1239,8 +1239,8 @@ test_move( if (sobj_at(BOULDER, ux, uy) && !Sokoban) { if (!Passes_walls && !could_move_onto_boulder(ux, uy) - && !(tunnels(gy.youmonst.data) - && !needspick(gy.youmonst.data)) + && !(tunnels(u.umonst->data) + && !needspick(u.umonst->data)) && !carrying(PICK_AXE) && !carrying(DWARVISH_MATTOCK) && !((obj = carrying(WAN_DIGGING)) && !objects[obj->otyp].oc_name_known)) @@ -1372,7 +1372,7 @@ findtravelpath(int mode) if (!isok(nx, ny) || ((mode == TRAVP_GUESS) && !couldsee(nx, ny))) continue; - if ((!Passes_walls && !can_ooze(&gy.youmonst) + if ((!Passes_walls && !can_ooze(u.umonst) && closed_door(x, y)) || (sobj_at(BOULDER, x, y) && !could_move_onto_boulder(x, y)) @@ -1693,7 +1693,7 @@ trapmove( boolean u_rooted(void) { - if (!gy.youmonst.data->mmove) { + if (!u.umonst->data->mmove) { You("are rooted %s.", Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) ? "in place" @@ -1825,14 +1825,14 @@ u_locomotion(const char *def) or boots/ring/spell of levitation */ return Levitation ? (capitalize ? "Float" : "float") : Flying ? (capitalize ? "Fly" : "fly") - : locomotion(gy.youmonst.data, def); + : locomotion(u.umonst->data, def); } /* Return a simplified floor solid/liquid state based on hero's state */ staticfn schar u_simple_floortyp(coordxy x, coordxy y) { - boolean u_in_air = (Levitation || Flying || !grounded(gy.youmonst.data)); + boolean u_in_air = (Levitation || Flying || !grounded(u.umonst->data)); if (is_waterwall(x, y)) return WATER; /* wall of water, fly/lev does not matter */ @@ -1978,8 +1978,8 @@ domove_attackmon_at( && (NODIAG(u.umonnum) || (bad_rock(mtmp->data, x, u.uy0) && bad_rock(mtmp->data, u.ux0, y)) - || (bad_rock(gy.youmonst.data, u.ux0, y) - && bad_rock(gy.youmonst.data, x, u.uy0)))) + || (bad_rock(u.umonst->data, u.ux0, y) + && bad_rock(u.umonst->data, x, u.uy0)))) && goodpos(u.ux0, u.uy0, mtmp, GP_ALLOW_U)); /* if not displacing, try to attack; note that it might evade; also, we don't attack tame or peaceful when safemon() */ @@ -2244,7 +2244,7 @@ domove_fight_empty(coordxy x, coordxy y) || (glyph_is_invisible(glyph) && !m_at(x, y) && !svc.context.nopick)) { struct obj *boulder = 0; - boolean explo = (Upolyd && attacktype(gy.youmonst.data, AT_EXPL)), + boolean explo = (Upolyd && attacktype(u.umonst->data, AT_EXPL)), solid = (off_edge || (!accessible(x, y) || IS_FURNITURE(levl[x][y].typ))); char buf[BUFSZ]; @@ -2323,7 +2323,7 @@ domove_fight_empty(coordxy x, coordxy y) nomul(0); if (explo) { struct attack *attk - = attacktype_fordmg(gy.youmonst.data, AT_EXPL, AD_ANY); + = attacktype_fordmg(u.umonst->data, AT_EXPL, AD_ANY); /* no monster has been attacked so we have bypassed explum() */ wake_nearto(u.ux, u.uy, 7 * 7); /* same radius as explum() */ @@ -2396,7 +2396,7 @@ staticfn void slippery_ice_fumbling(void) { boolean on_ice = !Levitation && is_ice(u.ux, u.uy); - struct monst *iceskater = u.usteed ? u.usteed : &gy.youmonst; + struct monst *iceskater = u.usteed ? u.usteed : u.umonst; if (on_ice) { if ((uarmf && objdescr_is(uarmf, "snow boots")) @@ -2435,7 +2435,7 @@ impaired_movement(coordxy *x, coordxy *y) confdir(TRUE); *x = u.ux + u.dx; *y = u.uy + u.dy; - } while (!isok(*x, *y) || bad_rock(gy.youmonst.data, *x, *y)); + } while (!isok(*x, *y) || bad_rock(u.umonst->data, *x, *y)); } return FALSE; } @@ -2475,7 +2475,7 @@ avoid_moving_on_liquid( /* and you know you won't fall in */ && (in_air || Known_lwalking || (is_pool(x, y) && Known_wwalking)) && !(IS_WATERWALL(levl[x][y].typ) || levl[x][y].typ == LAVAWALL)) { - /* XXX: should send 'is_clinger(gy.youmonst.data)' here once clinging + /* XXX: should send 'is_clinger(u.umonst->data)' here once clinging polyforms are allowed to move over water */ return FALSE; /* liquid is safe to traverse */ } else if (is_pool_or_lava(x, y) && levl[x][y].seenv) { @@ -2558,7 +2558,7 @@ avoid_trap_andor_region(coordxy x, coordxy y) /* check whether attempted move will be viable */ && test_move(u.ux, u.uy, u.dx, u.dy, TEST_MOVE) /* override confirmation if the trap is harmless to the hero */ - && (immune_to_trap(&gy.youmonst, trap->ttyp) != TRAP_CLEARLY_IMMUNE + && (immune_to_trap(u.umonst, trap->ttyp) != TRAP_CLEARLY_IMMUNE /* Hallucination: all traps still show as ^, but the hero can't tell what they are, so treat as dangerous */ || Hallucination)) { @@ -2644,7 +2644,7 @@ escape_from_sticky_mon(coordxy x, coordxy y) if (!m_next2u(u.ustuck)) { /* perhaps it fled (or was teleported or ... ) */ set_ustuck((struct monst *) 0); - } else if (sticks(gy.youmonst.data)) { + } else if (sticks(u.umonst->data)) { /* When polymorphed into a sticking monster, * u.ustuck means it's stuck to you, not you to it. */ @@ -2874,7 +2874,7 @@ domove_core(void) u.ux += u.dx; u.uy += u.dy; - m_postmove_effect(&gy.youmonst); + m_postmove_effect(u.umonst); if (u.usteed) { u.usteed->mx = u.ux; @@ -2943,12 +2943,12 @@ domove_core(void) /* your tread on the ground may disturb the slumber of nearby zombies */ if (!Levitation && !Flying && !Stealth - && gy.youmonst.data->cwt >= (WT_ELF / 2)) + && u.umonst->data->cwt >= (WT_ELF / 2)) disturb_buried_zombies(u.ux, u.uy); - if (hides_under(gy.youmonst.data) || gy.youmonst.data->mlet == S_EEL + if (hides_under(u.umonst->data) || u.umonst->data->mlet == S_EEL || u.dx || u.dy) - (void) hideunder(&gy.youmonst); + (void) hideunder(u.umonst); /* * Mimics (or whatever) become noticeable if they move and are @@ -2957,7 +2957,7 @@ domove_core(void) */ if ((u.dx || u.dy) && (U_AP_TYPE == M_AP_OBJECT || U_AP_TYPE == M_AP_FURNITURE)) - gy.youmonst.m_ap_type = M_AP_NOTHING; + u.umonst->m_ap_type = M_AP_NOTHING; check_leash(u.ux0, u.uy0); @@ -3804,8 +3804,8 @@ pickup_checks(void) } } if (is_pool(u.ux, u.uy)) { - if (Wwalking || is_floater(gy.youmonst.data) - || is_clinger(gy.youmonst.data) || (Flying && !Breathless)) { + if (Wwalking || is_floater(u.umonst->data) + || is_clinger(u.umonst->data) || (Flying && !Breathless)) { You("cannot dive into the %s to pick things up.", hliquid("water")); return 0; @@ -3815,11 +3815,11 @@ pickup_checks(void) } } if (is_lava(u.ux, u.uy)) { - if (Wwalking || is_floater(gy.youmonst.data) - || is_clinger(gy.youmonst.data) || (Flying && !Breathless)) { + if (Wwalking || is_floater(u.umonst->data) + || is_clinger(u.umonst->data) || (Flying && !Breathless)) { You_cant("reach the bottom to pick things up."); return 0; - } else if (!likes_lava(gy.youmonst.data)) { + } else if (!likes_lava(u.umonst->data)) { You("would burn to a crisp trying to pick things up."); return 0; } @@ -4079,7 +4079,7 @@ boolean crawl_destination(coordxy x, coordxy y) { /* is location ok in general? */ - if (!goodpos(x, y, &gy.youmonst, 0)) + if (!goodpos(x, y, u.umonst, 0)) return FALSE; /* orthogonal movement is unrestricted when destination is ok */ @@ -4095,9 +4095,9 @@ crawl_destination(coordxy x, coordxy y) if (IS_DOOR(levl[x][y].typ) && (!doorless_door(x, y) || block_door(x, y))) return FALSE; /* finally, are we trying to squeeze through a too-narrow gap? */ - return !(bad_rock(gy.youmonst.data, u.ux, y) - && bad_rock(gy.youmonst.data, x, u.uy) - && cant_squeeze_thru(&gy.youmonst)); + return !(bad_rock(u.umonst->data, u.ux, y) + && bad_rock(u.umonst->data, x, u.uy) + && cant_squeeze_thru(u.umonst)); } /* something like lookaround, but we are not running */ @@ -4367,14 +4367,14 @@ weight_cap(void) + WT_WEIGHTCAP_SPARE; if (Upolyd) { /* consistent with can_carry() in mon.c */ - if (gy.youmonst.data->mlet == S_NYMPH) + if (u.umonst->data->mlet == S_NYMPH) carrcap = MAX_CARR_CAP; - else if (!gy.youmonst.data->cwt) - carrcap = (carrcap * (long) gy.youmonst.data->msize) / MZ_HUMAN; - else if (!strongmonst(gy.youmonst.data) - || (strongmonst(gy.youmonst.data) - && (gy.youmonst.data->cwt > WT_HUMAN))) - carrcap = (carrcap * (long) gy.youmonst.data->cwt / WT_HUMAN); + else if (!u.umonst->data->cwt) + carrcap = (carrcap * (long) u.umonst->data->msize) / MZ_HUMAN; + else if (!strongmonst(u.umonst->data) + || (strongmonst(u.umonst->data) + && (u.umonst->data->cwt > WT_HUMAN))) + carrcap = (carrcap * (long) u.umonst->data->cwt / WT_HUMAN); } if (Levitation || Is_airlevel(&u.uz) /* pugh@cornell */ @@ -4411,7 +4411,7 @@ inv_weight(void) while (otmp) { if (otmp->oclass == COIN_CLASS) wt += (int) (((long) otmp->quan + 50L) / 100L); - else if (otmp->otyp != BOULDER || !throws_rocks(gy.youmonst.data)) + else if (otmp->otyp != BOULDER || !throws_rocks(u.umonst->data)) wt += otmp->owt; otmp = otmp->nobj; } diff --git a/src/iactions.c b/src/iactions.c index ca00a2be6..b12b61c18 100644 --- a/src/iactions.c +++ b/src/iactions.c @@ -605,7 +605,7 @@ itemactions(struct obj *otmp) /* w: wield, hold in hands, works on everything but with different advice text; not mentioned for things that are already wielded */ - if (otmp == uwep || cantwield(gy.youmonst.data)) { + if (otmp == uwep || cantwield(u.umonst->data)) { ; /* either already wielded or can't wield anything; skip 'w' */ } else if (otmp->oclass == WEAPON_CLASS || is_weptool(otmp) || is_wet_towel(otmp) || otmp->otyp == HEAVY_IRON_BALL) { @@ -674,7 +674,7 @@ itemactions(struct obj *otmp) /* if already two-weaponing, no special checks needed to toggle off */ && (u.twoweap /* but if not, try to filter most "you can't do that" here */ - || (could_twoweap(gy.youmonst.data) && !uarms + || (could_twoweap(u.umonst->data) && !uarms && uwep && MAYBETWOWEAPON(uwep) && uswapwep && MAYBETWOWEAPON(uswapwep)))) { Sprintf(buf, "Toggle two-weapon combat %s", u.twoweap ? "off" : "on"); diff --git a/src/insight.c b/src/insight.c index ab2bcd1a1..12fc1e773 100644 --- a/src/insight.c +++ b/src/insight.c @@ -489,8 +489,8 @@ background_enlightenment(int unused_mode UNUSED, int final) the player to know he's not a samurai at the moment... */ if (Upolyd) { char anbuf[20]; /* includes trailing space; [4] suffices */ - struct permonst *uasmon = gy.youmonst.data; - boolean altphrasing = vampshifted(&gy.youmonst); + struct permonst *uasmon = u.umonst->data; + boolean altphrasing = vampshifted(u.umonst); tmpbuf[0] = '\0'; /* here we always use current gender, not saved role gender */ @@ -498,7 +498,7 @@ background_enlightenment(int unused_mode UNUSED, int final) Sprintf(tmpbuf, "%s ", genders[flags.female ? 1 : 0].adj); if (altphrasing) Sprintf(eos(tmpbuf), "%s in ", - pmname(&mons[gy.youmonst.cham], + pmname(&mons[u.umonst->cham], flags.female ? FEMALE : MALE)); Snprintf(buf, sizeof(buf), "%s%s%s%s form", !final ? "currently " : "", @@ -1068,7 +1068,7 @@ status_enlightenment(int mode, int final) if (wizard && (HBlinded == BlindedTimeout && !Blindfolded)) Sprintf(eos(buf), " (%ld)", BlindedTimeout); /* !haseyes: avoid "you are innately blind innately" */ - you_are(buf, !haseyes(gy.youmonst.data) ? "" : from_what(BLINDED)); + you_are(buf, !haseyes(u.umonst->data) ? "" : from_what(BLINDED)); } if (Deaf) you_are("deaf", from_what(DEAF)); @@ -1122,7 +1122,7 @@ status_enlightenment(int mode, int final) Sprintf(eos(buf), " (%u)", u.uswldtim); you_are(buf, ""); } else if (u.ustuck) { - boolean ustick = (Upolyd && sticks(gy.youmonst.data)); + boolean ustick = (Upolyd && sticks(u.umonst->data)); int dx = u.ustuck->mx - u.ux, dy = u.ustuck->my - u.uy; Snprintf(buf, sizeof buf, "%s %s (%s)", @@ -1736,7 +1736,7 @@ attributes_enlightenment( } /* including this might bring attention to the fact that ceiling clinging has inconsistencies... */ - if (is_clinger(gy.youmonst.data)) { + if (is_clinger(u.umonst->data)) { boolean has_lid = has_ceiling(&u.uz); if (has_lid && !u.uinwater) { @@ -1797,7 +1797,7 @@ attributes_enlightenment( if (prot) you_have(enlght_combatinc("defense", prot, final, buf), ""); } - if ((armpro = magic_negation(&gy.youmonst)) > 0) { + if ((armpro = magic_negation(u.umonst)) > 0) { /* magic cancellation factor, conferred by worn armor */ static const char *const mc_types[] = { "" /*ordinary*/, "warded", "guarded", "protected", @@ -1863,20 +1863,20 @@ attributes_enlightenment( && !(final == ENL_GAMEOVERDEAD && u.umonnum == PM_GREEN_SLIME && !Unchanging)) { /* foreign shape (except were-form which is handled below) */ - if (!vampshifted(&gy.youmonst)) + if (!vampshifted(u.umonst)) Sprintf(buf, "polymorphed into %s", - an(pmname(gy.youmonst.data, + an(pmname(u.umonst->data, flags.female ? FEMALE : MALE))); else Sprintf(buf, "polymorphed into %s in %s form", - an(pmname(&mons[gy.youmonst.cham], + an(pmname(&mons[u.umonst->cham], flags.female ? FEMALE : MALE)), - pmname(gy.youmonst.data, flags.female ? FEMALE : MALE)); + pmname(u.umonst->data, flags.female ? FEMALE : MALE)); if (wizard) Sprintf(eos(buf), " (%d)", u.mtimedone); you_are(buf, ""); } - if (lays_eggs(gy.youmonst.data) && flags.female) /* Upolyd */ + if (lays_eggs(u.umonst->data) && flags.female) /* Upolyd */ you_can("lay eggs", ""); if (ismnum(u.ulycn)) { /* "you are a werecreature [in beast form]" */ @@ -2046,7 +2046,7 @@ youhiding(boolean via_enlghtmt, /* enlightenment line vs topl message */ for the hypothetical furniture and monster cases */ bp = eos(strcpy(buf, "mimicking")); if (U_AP_TYPE == M_AP_OBJECT) { - Sprintf(bp, " %s", an(simple_typename(gy.youmonst.mappearance))); + Sprintf(bp, " %s", an(simple_typename(u.umonst->mappearance))); } else if (U_AP_TYPE == M_AP_FURNITURE) { Strcpy(bp, " something"); } else if (U_AP_TYPE == M_AP_MONSTER) { @@ -2056,15 +2056,15 @@ youhiding(boolean via_enlghtmt, /* enlightenment line vs topl message */ } } else if (u.uundetected) { bp = eos(buf); /* points past "hiding" */ - if (gy.youmonst.data->mlet == S_EEL) { + if (u.umonst->data->mlet == S_EEL) { if (is_pool(u.ux, u.uy)) Sprintf(bp, " in the %s", waterbody_name(u.ux, u.uy)); - } else if (hides_under(gy.youmonst.data)) { + } else if (hides_under(u.umonst->data)) { struct obj *o = svl.level.objects[u.ux][u.uy]; if (o) Sprintf(bp, " underneath %s", ansimpleoname(o)); - } else if (is_clinger(gy.youmonst.data) || Flying) { + } else if (is_clinger(u.umonst->data) || Flying) { /* Flying: 'lurker above' hides on ceiling but doesn't cling */ Sprintf(bp, " on the %s", ceiling(u.ux, u.uy)); } else { @@ -3368,7 +3368,7 @@ mstatusline(struct monst *mtmp) if (mtmp == u.ustuck) { struct permonst *pm = u.ustuck->data; - /* being swallowed/engulfed takes priority over sticks(youmonst); + /* being swallowed/engulfed takes priority over sticks(u.umonst); this used to have that backwards and checked sticks() first */ Strcat(info, u.uswallow ? (digests(pm) ? ", digesting you" @@ -3380,9 +3380,9 @@ mstatusline(struct monst *mtmp) : (is_animal(pm) && !enfolds(pm)) ? ", swallowing you" : ", engulfing you") - /* !u.uswallow; if both youmonst and ustuck are holders, - youmonst wins */ - : (!sticks(gy.youmonst.data) ? ", holding you" + /* !u.uswallow; if both u.umonst and ustuck are holders, + u.umonst wins */ + : (!sticks(u.umonst->data) ? ", holding you" : ", held by you")); } if (mtmp == u.usteed) { @@ -3445,7 +3445,7 @@ ustatusline(void) Strcat(info, ", blind"); if (u.ucreamed) { if ((long) u.ucreamed < BlindedTimeout || Blindfolded - || !haseyes(gy.youmonst.data)) + || !haseyes(u.umonst->data)) Strcat(info, ", cover"); Strcat(info, "ed by sticky goop"); } /* note: "goop" == "glop"; variation is intentional */ @@ -3481,7 +3481,7 @@ ustatusline(void) if (u.uswallow) Strcat(info, digests(u.ustuck->data) ? ", being digested by " : ", engulfed by "); - else if (!sticks(gy.youmonst.data)) + else if (!sticks(u.umonst->data)) Strcat(info, ", held by "); else Strcat(info, ", holding "); diff --git a/src/invent.c b/src/invent.c index a34517acf..6995bfd4e 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1224,7 +1224,7 @@ hold_another_object( /* in case touching this object turns out to be fatal */ place_object(obj, u.ux, u.uy); - if (!touch_artifact(obj, &gy.youmonst)) { + if (!touch_artifact(obj, u.umonst)) { obj_extract_self(obj); /* remove it from the floor */ dropy(obj); /* now put it back again :-) */ return obj; @@ -1496,7 +1496,7 @@ carrying(int type) { struct obj *otmp; - /* this could be replaced by 'return m_carrying(&gy.youmonst, type);' */ + /* this could be replaced by 'return m_carrying(u.umonst, type);' */ for (otmp = gi.invent; otmp; otmp = otmp->nobj) if (otmp->otyp == type) break; @@ -4269,7 +4269,7 @@ look_here( : (otmp->quan > 1L) ? "They're" : "It's", corpse_xname(otmp, (const char *) 0, CXN_ARTICLE), - poly_when_stoned(gy.youmonst.data) ? "" + poly_when_stoned(u.umonst->data) ? "" : ", unfortunately"); feel_cockatrice(otmp, FALSE); break; @@ -4348,7 +4348,7 @@ feel_cockatrice(struct obj *otmp, boolean force_touch) /* "the corpse" */ Strcpy(kbuf, corpse_xname(otmp, (const char *) 0, CXN_PFX_THE)); - if (poly_when_stoned(gy.youmonst.data)) + if (poly_when_stoned(u.umonst->data)) You("touched %s with your bare %s.", kbuf, makeplural(body_part(HAND))); else @@ -4778,8 +4778,8 @@ useupf(struct obj *obj, long numused) (void) stolen_value(otmp, otmp->ox, otmp->oy, FALSE, FALSE); } delobj(otmp); - if (at_u && u.uundetected && hides_under(gy.youmonst.data)) - (void) hideunder(&gy.youmonst); + if (at_u && u.uundetected && hides_under(u.umonst->data)) + (void) hideunder(u.umonst); } /* @@ -5360,7 +5360,7 @@ display_minventory( /* Fool the 'weapon in hand' routine into * displaying 'weapon in claw', etc. properly. */ - gy.youmonst.data = mon->data; + u.umonst->data = mon->data; /* in case inside a shop, don't append "for sale" prices */ iflags.suppress_price++; @@ -5371,7 +5371,7 @@ display_minventory( iflags.suppress_price--; /* was 'set_uasmon();' but that potentially has side-effects */ - gy.youmonst.data = &mons[u.umonnum]; /* basic part of set_uasmon() */ + u.umonst->data = &mons[u.umonnum]; /* basic part of set_uasmon() */ } else { invdisp_nothing(title ? title : tmp, "(none)"); n = 0; diff --git a/src/light.c b/src/light.c index 93f7ea50a..640ed312a 100644 --- a/src/light.c +++ b/src/light.c @@ -13,8 +13,8 @@ * Light sources are "things" that have a physical position and range. * They have a type, which gives us information about them. Currently * they are only attached to objects and monsters. Note well: the - * polymorphed-player handling assumes that gy.youmonst.m_id will - * always remain 1 and gy.youmonst.mx will always remain 0. + * polymorphed-player handling assumes that u.umonst->m_id will + * always remain 1 and u.umonst->mx will always remain 0. * * Light sources, like timers, either follow game play (RANGE_GLOBAL) or * stay on a level (RANGE_LEVEL). Light sources are unique by their @@ -378,7 +378,7 @@ find_mid(unsigned nid, unsigned fmflags) struct monst *mtmp; if ((fmflags & FM_YOU) && nid == 1) - return &gy.youmonst; + return u.umonst; if (fmflags & FM_FMON) for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) if (!DEADMONSTER(mtmp) && mtmp->m_id == nid) @@ -399,7 +399,7 @@ whereis_mon(struct monst *mon, unsigned fmflags) { struct monst *mtmp; - if ((fmflags & FM_YOU) && mon == &gy.youmonst) + if ((fmflags & FM_YOU) && mon == u.umonst) return FM_YOU; if (fmflags & FM_FMON) for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) @@ -957,7 +957,7 @@ wiz_light_sources(void) : ls->type == LS_MONSTER ? (mon_is_local(ls->id.a_monst) ? "mon" - : (ls->id.a_monst == &gy.youmonst) + : (ls->id.a_monst == u.umonst) ? "you" /* migrating monster */ : "") diff --git a/src/lock.c b/src/lock.c index 2e8851754..cc3183d00 100644 --- a/src/lock.c +++ b/src/lock.c @@ -89,7 +89,7 @@ picklock(void) } } - if (gx.xlock.usedtime++ >= 50 || nohands(gy.youmonst.data)) { + if (gx.xlock.usedtime++ >= 50 || nohands(u.umonst->data)) { You("give up your attempt at %s.", lock_action()); exercise(A_DEX, TRUE); /* even if you don't succeed */ return ((gx.xlock.usedtime = 0)); @@ -218,7 +218,7 @@ forcelock(void) if ((gx.xlock.box->ox != u.ux) || (gx.xlock.box->oy != u.uy)) return ((gx.xlock.usedtime = 0)); /* you or it moved */ - if (gx.xlock.usedtime++ >= 50 || !uwep || nohands(gy.youmonst.data)) { + if (gx.xlock.usedtime++ >= 50 || !uwep || nohands(u.umonst->data)) { You("give up your attempt to force the lock."); if (gx.xlock.usedtime >= 50) /* you made the effort */ exercise((gx.xlock.picktyp) ? A_DEX : A_STR, TRUE); @@ -315,7 +315,7 @@ autokey(boolean opening) /* True: key, pick, or card; False: key or pick */ } else { switch (o->otyp) { case SKELETON_KEY: - if (!key || is_magic_key(&gy.youmonst, o)) + if (!key || is_magic_key(u.umonst, o)) key = o; break; case LOCK_PICK: @@ -380,7 +380,7 @@ pick_lock( if (gx.xlock.usedtime && picktyp == gx.xlock.picktyp) { static char no_longer[] = "Unfortunately, you can no longer %s %s."; - if (nohands(gy.youmonst.data)) { + if (nohands(u.umonst->data)) { const char *what = (picktyp == LOCK_PICK) ? "pick" : "key"; if (picktyp == CREDIT_CARD) @@ -396,13 +396,13 @@ pick_lock( const char *action = lock_action(); You("resume your attempt at %s.", action); - gx.xlock.magic_key = is_magic_key(&gy.youmonst, pick); + gx.xlock.magic_key = is_magic_key(u.umonst, pick); set_occupation(picklock, action, 0); return PICKLOCK_DID_SOMETHING; } } - if (nohands(gy.youmonst.data)) { + if (nohands(u.umonst->data)) { You_cant("hold %s -- you have no hands!", doname(pick)); return PICKLOCK_DID_NOTHING; } else if (u.uswallow) { @@ -513,7 +513,7 @@ pick_lock( an(simple_typename(picktyp))); return PICKLOCK_LEARNED_SOMETHING; } else if (autounlock - && !touch_artifact(pick, &gy.youmonst)) { + && !touch_artifact(pick, u.umonst)) { /* note: for !autounlock, apply already did touch check */ return PICKLOCK_DID_SOMETHING; } @@ -626,7 +626,7 @@ pick_lock( return PICKLOCK_DID_NOTHING; /* note: for !autounlock, 'apply' already did touch check */ - if (autounlock && !touch_artifact(pick, &gy.youmonst)) + if (autounlock && !touch_artifact(pick, u.umonst)) return PICKLOCK_DID_SOMETHING; switch (picktyp) { @@ -649,7 +649,7 @@ pick_lock( svc.context.move = 0; gx.xlock.chance = ch; gx.xlock.picktyp = picktyp; - gx.xlock.magic_key = is_magic_key(&gy.youmonst, pick); + gx.xlock.magic_key = is_magic_key(u.umonst, pick); gx.xlock.usedtime = 0; set_occupation(picklock, lock_action(), 0); return PICKLOCK_DID_SOMETHING; @@ -785,7 +785,7 @@ doopen_indir(coordxy x, coordxy y) const char *dirprompt; int res = ECMD_OK; - if (nohands(gy.youmonst.data)) { + if (nohands(u.umonst->data)) { You_cant("open anything -- you have no hands!"); return ECMD_OK; } @@ -895,7 +895,7 @@ doopen_indir(coordxy x, coordxy y) return res; } - if (verysmall(gy.youmonst.data)) { + if (verysmall(u.umonst->data)) { pline("You're too small to pull the door open."); return res; } @@ -961,7 +961,7 @@ doclose(void) boolean portcullis; int res = ECMD_OK; - if (nohands(gy.youmonst.data)) { + if (nohands(u.umonst->data)) { You_cant("close anything -- you have no hands!"); return ECMD_OK; } @@ -1031,7 +1031,7 @@ doclose(void) } if (door->doormask == D_ISOPEN) { - if (verysmall(gy.youmonst.data) && !u.usteed) { + if (verysmall(u.umonst->data) && !u.usteed) { pline("You're too small to push the door closed."); return res; } @@ -1281,7 +1281,7 @@ chest_shatter_msg(struct obj *otmp) if (otmp->oclass == POTION_CLASS) { You("%s %s shatter!", Blind ? "hear" : "see", an(bottlename())); - if (!breathless(gy.youmonst.data) || haseyes(gy.youmonst.data)) + if (!breathless(u.umonst->data) || haseyes(u.umonst->data)) potionbreathe(otmp); return; } diff --git a/src/mcastu.c b/src/mcastu.c index 34d839906..c6f5bc3bb 100644 --- a/src/mcastu.c +++ b/src/mcastu.c @@ -69,7 +69,7 @@ cursetxt(struct monst *mtmp, boolean undirected) point_msg = "all around, then curses"; else if ((Invis && !perceives(mtmp->data) && (mtmp->mux != u.ux || mtmp->muy != u.uy)) - || is_obj_mappear(&gy.youmonst, STRANGE_OBJECT) + || is_obj_mappear(u.umonst, STRANGE_OBJECT) || u.uundetected) point_msg = "and curses in your general direction"; else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy)) @@ -389,7 +389,7 @@ staticfn void mcast_death_touch(struct monst *mtmp) { pline("Oh no, %s's using the touch of death!", mhe(mtmp)); - if (nonliving(gy.youmonst.data) || is_demon(gy.youmonst.data)) { + if (nonliving(u.umonst->data) || is_demon(u.umonst->data)) { You("seem no deader than before."); } else if (!Antimagic && rn2(mtmp->m_lev) > 12) { if (Hallucination) { @@ -553,9 +553,9 @@ mcast_fire_pillar(struct monst *mtmp, int dmg) if (Half_spell_damage) dmg = (dmg + 1) / 2; burn_away_slime(); - (void) burnarmor(&gy.youmonst); + (void) burnarmor(u.umonst); /* item destruction dmg */ - (void) destroy_items(&gy.youmonst, AD_FIRE, orig_dmg); + (void) destroy_items(u.umonst, AD_FIRE, orig_dmg); ignite_items(gi.invent); /* burn up flammable items on the floor, melt ice terrain */ mon_spell_hits_spot(mtmp, AD_FIRE, u.ux, u.uy); @@ -586,7 +586,7 @@ mcast_lightning(struct monst *mtmp, int dmg) } if (Half_spell_damage) dmg = (dmg + 1) / 2; - (void) destroy_items(&gy.youmonst, AD_ELEC, orig_dmg); + (void) destroy_items(u.umonst, AD_ELEC, orig_dmg); /* lightning might destroy iron bars if hero is on such a spot; reflection protects terrain here [execution won't get here due to 'if (reflects) break' above] but hero resistance doesn't; @@ -730,7 +730,7 @@ mcast_blind_you(void) { /* note: resists_blnd() doesn't apply here */ if (!Blinded) { - int num_eyes = eyecount(gy.youmonst.data); + int num_eyes = eyecount(u.umonst->data); pline("Scales cover your %s!", (num_eyes == 1) ? body_part(EYE) diff --git a/src/mhitm.c b/src/mhitm.c index 5e8bb928e..c6db44600 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -607,7 +607,7 @@ failed_grab( && (mattk->aatyp == AT_HUGS || mattk->adtyp == AD_WRAP || mattk->adtyp == AD_STCK || mattk->adtyp == AD_DGST)) { if ((gv.vis && canspotmon(mdef)) /* mon-vs-mon */ - || magr == &gy.youmonst || mdef == &gy.youmonst) { + || magr == u.umonst || mdef == u.umonst) { char magrnam[BUFSZ], mdefnam[BUFSZ]; boolean tailmiss = gn.notonhead; const char *verb = (mattk->adtyp == AD_DGST) ? "gulp" @@ -618,14 +618,14 @@ failed_grab( mon_nam(x_monnam) calls s_suffix() for named ghosts and s_suffix() uses a single static buffer; make copies of both names to overcome that [note: comment predates 'tailmiss'] */ - Strcpy(magrnam, (magr == &gy.youmonst) ? "Your" + Strcpy(magrnam, (magr == u.umonst) ? "Your" : s_suffix(Monnam(magr))); if (!tailmiss) { - Strcpy(mdefnam, (mdef == &gy.youmonst) ? "you" + Strcpy(mdefnam, (mdef == u.umonst) ? "you" : mon_nam(mdef)); } else { /* hero poly'd into long worm can't grow tail - so no 'youmonst' handling is needed here */ + so no 'u.umonst' handling is needed here */ Sprintf(mdefnam, "%s tail", s_suffix(some_mon_nam(mdef))); } /* unsolid grab misses are actually somewhat iffy--how come @@ -808,8 +808,8 @@ engulf_target(struct monst *magr, struct monst *mdef) { struct rm *lev; int ax, ay, dx, dy; - boolean uatk = (magr == &gy.youmonst), - udef = (mdef == &gy.youmonst); + boolean uatk = (magr == u.umonst), + udef = (mdef == u.umonst); /* can't swallow something that's too big */ if (mdef->data->msize >= MZ_HUGE @@ -825,16 +825,16 @@ engulf_target(struct monst *magr, struct monst *mdef) might not be able to place attacker and defender both back on map; when defender is the hero, a sanity_check complaint about placing the hero on top of a monster can occur */ - dx = (mdef == &gy.youmonst) ? u.ux : mdef->mx; - dy = (mdef == &gy.youmonst) ? u.uy : mdef->my; + dx = (mdef == u.umonst) ? u.ux : mdef->mx; + dy = (mdef == u.umonst) ? u.uy : mdef->my; lev = &levl[dx][dy]; if (!(udef ? Passes_walls : passes_walls(mdef->data)) && (IS_OBSTRUCTED(lev->typ) || closed_door(dx, dy) || IS_TREE(lev->typ) /* not passes_bars(); engulfer isn't squeezing through */ || (lev->typ == IRONBARS && !is_whirly(magr->data)))) return FALSE; - ax = (magr == &gy.youmonst) ? u.ux : magr->mx; - ay = (magr == &gy.youmonst) ? u.uy : magr->my; + ax = (magr == u.umonst) ? u.ux : magr->mx; + ay = (magr == u.umonst) ? u.uy : magr->my; lev = &levl[ax][ay]; if (!(uatk ? Passes_walls : passes_walls(magr->data)) && (IS_OBSTRUCTED(lev->typ) || closed_door(ax, ay) || IS_TREE(lev->typ) @@ -1124,7 +1124,7 @@ mon_poly(struct monst *magr, struct monst *mdef, int dmg) static const char freaky[] = " undergoes a freakish metamorphosis"; struct permonst *oldform = mdef->data; - if (mdef == &gy.youmonst) { + if (mdef == u.umonst) { if (Antimagic) { shieldeff(u.ux, u.uy); } else if (Unchanging) { @@ -1166,7 +1166,7 @@ mon_poly(struct monst *magr, struct monst *mdef, int dmg) mdef->mhp -= dmg; dmg = 0; if (DEADMONSTER(mdef)) { - if (magr == &gy.youmonst) + if (magr == u.umonst) xkilled(mdef, XKILL_GIVEMSG | XKILL_NOCORPSE); else monkilled(mdef, "", AD_RBRE); @@ -1182,13 +1182,13 @@ mon_poly(struct monst *magr, struct monst *mdef, int dmg) x_monnam(mdef, ARTICLE_A, (char *) 0, (SUPPRESS_NAME | SUPPRESS_IT | SUPPRESS_INVISIBLE), FALSE)); - else if (was_seen || magr == &gy.youmonst) + else if (was_seen || magr == u.umonst) pline("%s%s%s.", Before, freaky, !was_seen ? "" : " and disappears"); } dmg = 0; if (can_teleport(magr->data)) { - if (magr == &gy.youmonst) + if (magr == u.umonst) tele(); else if (!tele_restrict(magr)) (void) rloc(magr, RLOC_MSG); @@ -1200,7 +1200,7 @@ mon_poly(struct monst *magr, struct monst *mdef, int dmg) } /* when a transformation has happened, can't attack again for poly effect during next turn or two; not enforced for poly'd hero */ - if (mdef->data != oldform && magr != &gy.youmonst) + if (mdef->data != oldform && magr != u.umonst) magr->mspec_used += rnd(2); return dmg; @@ -1250,7 +1250,7 @@ void slept_monst(struct monst *mon) { if (helpless(mon) && mon == u.ustuck - && !sticks(gy.youmonst.data) && !u.uswallow) { + && !sticks(u.umonst->data) && !u.uswallow) { pline_mon(mon, "%s grip relaxes.", s_suffix(Monnam(mon))); unstuck(mon); } diff --git a/src/mhitu.c b/src/mhitu.c index 71d90a8ec..b71104cb9 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -34,7 +34,7 @@ hitmsg(struct monst *mtmp, struct attack *mattk) /* Note: if opposite gender, "seductively"; if same gender, "engagingly" for nymph, normal msg for others. */ - if ((compat = could_seduce(mtmp, &gy.youmonst, mattk)) != 0 + if ((compat = could_seduce(mtmp, u.umonst, mattk)) != 0 && !mtmp->mcan && !mtmp->mspec_used) { pline_mon(mtmp, "%s %s you %s.", Monst_name, !Blind ? "smiles at" : !Deaf ? "talks to" : "touches", @@ -45,7 +45,7 @@ hitmsg(struct monst *mtmp, struct attack *mattk) verb = "bites"; break; case AT_KICK: - if (thick_skinned(gy.youmonst.data)) + if (thick_skinned(u.umonst->data)) punct = "."; verb = "kicks"; break; @@ -90,7 +90,7 @@ missmu(struct monst *mtmp, boolean nearmiss, struct attack *mattk) if (!canspotmon(mtmp)) map_invisible(mtmp->mx, mtmp->my); - if (could_seduce(mtmp, &gy.youmonst, mattk) && !mtmp->mcan) + if (could_seduce(mtmp, u.umonst, mattk) && !mtmp->mcan) pline_mon(mtmp, "%s pretends to be friendly.", Monnam(mtmp)); else pline_mon(mtmp, "%s %smisses!", Monnam(mtmp), @@ -147,7 +147,7 @@ mpoisons_subj( struct attack *mattk) { if (mattk->aatyp == AT_WEAP) { - struct obj *mwep = (mtmp == &gy.youmonst) ? uwep : MON_WEP(mtmp); + struct obj *mwep = (mtmp == u.umonst) ? uwep : MON_WEP(mtmp); /* "Foo's attack was poisoned." is pretty lame, but at least it's better than "sting" when not a stinging attack... */ return (!mwep || !mwep->opoisoned) ? "attack" : "weapon"; @@ -200,7 +200,7 @@ wildmiss(struct monst *mtmp, struct attack *mattk) /* maybe it's attacking an image around the corner? */ compat = ((mattk->adtyp == AD_SEDU || mattk->adtyp == AD_SSEX) - ? could_seduce(mtmp, &gy.youmonst, mattk) : 0); + ? could_seduce(mtmp, u.umonst, mattk) : 0); Monst_name = Monnam(mtmp); set_msg_xy(mtmp->mx, mtmp->my); @@ -314,8 +314,8 @@ getmattk( { struct permonst *mptr = magr->data; struct attack *attk = &mptr->mattk[indx]; - struct obj *weap = (magr == &gy.youmonst) ? uwep : MON_WEP(magr); - boolean udefend = mdef == &gy.youmonst; + struct obj *weap = (magr == u.umonst) ? uwep : MON_WEP(magr); + boolean udefend = mdef == u.umonst; /* honor SEDUCE=0 */ if (!SYSOPT_SEDUCE) { @@ -396,7 +396,7 @@ getmattk( if weapon is sufficiently interesting; a few unique creatures have two weapon attacks where one does physical damage and other doesn't--avoid forcing physical damage for those */ - } else if (indx == 0 && magr != &gy.youmonst + } else if (indx == 0 && magr != u.umonst && attk->aatyp == AT_WEAP && attk->adtyp != AD_PHYS && !(mptr->mattk[1].aatyp == AT_WEAP && mptr->mattk[1].adtyp == AD_PHYS) @@ -468,7 +468,7 @@ mtrapped_in_pit(struct monst *mtmp) { struct trap *ttmp = 0; - if (mtmp == &gy.youmonst) + if (mtmp == u.umonst) ttmp = (u.utrap && u.utraptype == TT_PIT) ? t_at(u.ux, u.uy) : 0; else ttmp = mtmp->mtrapped ? t_at(mtmp->mx, mtmp->my) : 0; @@ -552,7 +552,7 @@ mattacku(struct monst *mtmp) if (!canspotmon(mtmp)) map_invisible(mtmp->mx, mtmp->my); u.uundetected = 0; - if (is_hider(gy.youmonst.data) && u.umonnum != PM_TRAPPER) { + if (is_hider(u.umonst->data) && u.umonnum != PM_TRAPPER) { /* ceiling hider */ coord cc; /* maybe we need a unexto() function? */ struct obj *obj; @@ -562,7 +562,7 @@ mattacku(struct monst *mtmp) is eligible for placing hero; we assume that a removed monster remembers its old spot */ remove_monster(mtmp->mx, mtmp->my); - if (!enexto(&cc, u.ux, u.uy, gy.youmonst.data) + if (!enexto(&cc, u.ux, u.uy, u.umonst->data) /* a fish won't voluntarily swap positions when it's in water and hero is over land */ || (mtmp->data->mlet == S_EEL @@ -587,13 +587,13 @@ mattacku(struct monst *mtmp) /* tail hasn't grown, so if it now occupies then one of its original spots must be free */ if (m_at(cc.x, cc.y)) - (void) enexto(&cc, u.ux, u.uy, gy.youmonst.data); + (void) enexto(&cc, u.ux, u.uy, u.umonst->data); } teleds(cc.x, cc.y, TELEDS_ALLOW_DRAG); /* move hero */ set_apparxy(mtmp); newsym(u.ux, u.uy); - if (gy.youmonst.data->mlet != S_PIERCER) + if (u.umonst->data->mlet != S_PIERCER) return 0; /* lurkers don't attack */ obj = which_armor(mtmp, WORN_HELMET); @@ -625,7 +625,7 @@ mattacku(struct monst *mtmp) struct obj *obj = svl.level.objects[u.ux][u.uy]; if (obj || u.umonnum == PM_TRAPPER - || (gy.youmonst.data->mlet == S_EEL + || (u.umonst->data->mlet == S_EEL && is_pool(u.ux, u.uy))) { int save_spe = 0; /* suppress warning */ @@ -636,17 +636,17 @@ mattacku(struct monst *mtmp) } /* note that m_monnam() overrides hallucination, which is what we want when message is from mtmp's perspective */ - if (gy.youmonst.data->mlet == S_EEL + if (u.umonst->data->mlet == S_EEL || u.umonnum == PM_TRAPPER) pline( "Wait, %s! There's a hidden %s named %s there!", m_monnam(mtmp), - pmname(gy.youmonst.data, Ugender), svp.plname); + pmname(u.umonst->data, Ugender), svp.plname); else pline( "Wait, %s! There's a %s named %s hiding under %s!", m_monnam(mtmp), - pmname(gy.youmonst.data, Ugender), + pmname(u.umonst->data, Ugender), svp.plname, doname(svl.level.objects[u.ux][u.uy])); if (obj) @@ -660,9 +660,9 @@ mattacku(struct monst *mtmp) } /* hero might be a mimic, concealed via #monster */ - if (gy.youmonst.data->mlet == S_MIMIC && U_AP_TYPE && !range2 + if (u.umonst->data->mlet == S_MIMIC && U_AP_TYPE && !range2 && foundyou && !u.uswallow) { - boolean sticky = sticks(gy.youmonst.data); + boolean sticky = sticks(u.umonst->data); if (!canspotmon(mtmp)) map_invisible(mtmp->mx, mtmp->my); @@ -670,11 +670,11 @@ mattacku(struct monst *mtmp) pline("It gets stuck on you."); else /* see note about m_monnam() above */ pline("Wait, %s! That's a %s named %s!", m_monnam(mtmp), - pmname(gy.youmonst.data, Ugender), svp.plname); + pmname(u.umonst->data, Ugender), svp.plname); if (sticky) set_ustuck(mtmp); - gy.youmonst.m_ap_type = M_AP_NOTHING; - gy.youmonst.mappearance = 0; + u.umonst->m_ap_type = M_AP_NOTHING; + u.umonst->mappearance = 0; newsym(u.ux, u.uy); return 0; } @@ -686,18 +686,18 @@ mattacku(struct monst *mtmp) if (!youseeit) pline("%s %s!", Something, (likes_gold(mtmp->data) - && gy.youmonst.mappearance == GOLD_PIECE) + && u.umonst->mappearance == GOLD_PIECE) ? "tries to pick you up" : "disturbs you"); else /* see note about m_monnam() above */ pline("Wait, %s! That %s is really %s named %s!", m_monnam(mtmp), - mimic_obj_name(&gy.youmonst), + mimic_obj_name(u.umonst), an(pmname(&mons[u.umonnum], Ugender)), svp.plname); if (gm.multi < 0) { /* this should always be the case */ char buf[BUFSZ]; Sprintf(buf, "You appear to be %s again.", - Upolyd ? (const char *) an(pmname(gy.youmonst.data, + Upolyd ? (const char *) an(pmname(u.umonst->data, flags.female)) : (const char *) "yourself"); unmul(buf); /* immediately stop mimicking */ @@ -783,7 +783,7 @@ mattacku(struct monst *mtmp) continue; } mon_currwep = (struct obj *) 0; - mattk = getmattk(mtmp, &gy.youmonst, i, sum, &alt_attk); + mattk = getmattk(mtmp, u.umonst, i, sum, &alt_attk); if ((u.uswallow && mattk->aatyp != AT_ENGL) || (skipnonmagc && mattk->aatyp != AT_MAGC) || (gs.skipdrin && mattk->aatyp == AT_TENT @@ -801,14 +801,14 @@ mattacku(struct monst *mtmp) if (mattk->aatyp == AT_KICK && mtrapped_in_pit(mtmp)) continue; if (!range2 && (!MON_WEP(mtmp) || mtmp->mconf || Conflict - || !touch_petrifies(gy.youmonst.data))) { + || !touch_petrifies(u.umonst->data))) { if (foundyou) { if (tmp > (j = rnd(20 + i))) { - if (unsolid(gy.youmonst.data) - && failed_grab(mtmp, &gy.youmonst, mattk)) + if (unsolid(u.umonst->data) + && failed_grab(mtmp, u.umonst, mattk)) continue; if (mattk->aatyp != AT_KICK - || !thick_skinned(gy.youmonst.data)) + || !thick_skinned(u.umonst->data)) sum[i] = hitmu(mtmp, mattk); } else missmu(mtmp, (tmp == j), mattk); @@ -824,7 +824,7 @@ mattacku(struct monst *mtmp) /* Note: if displaced, prev attacks never succeeded */ if ((!range2 && i >= 2 && sum[i - 1] && sum[i - 2]) || mtmp == u.ustuck) { - if (!failed_grab(mtmp, &gy.youmonst, mattk)) + if (!failed_grab(mtmp, u.umonst, mattk)) sum[i] = hitmu(mtmp, mattk); } break; @@ -905,7 +905,7 @@ mattacku(struct monst *mtmp) ART_SNICKERSNEE) && m_next2u(mtmp)); - hittmp = hitval(mon_currwep, &gy.youmonst); + hittmp = hitval(mon_currwep, u.umonst); tmp += hittmp; mswings(mtmp, mon_currwep, bash); } @@ -1091,7 +1091,7 @@ magic_negation(struct monst *mon) struct obj *o; long wearmask; int armpro, mc = 0; - boolean is_you = (mon == &gy.youmonst), + boolean is_you = (mon == u.umonst), via_amul = FALSE, gotprot = is_you ? (EProtection != 0L) /* high priests have innate protection */ @@ -1144,7 +1144,7 @@ staticfn int hitmu(struct monst *mtmp, struct attack *mattk) { struct permonst *mdat = mtmp->data; - struct permonst *olduasmon = gy.youmonst.data; + struct permonst *olduasmon = u.umonst->data; int res; struct mhitm_data mhm; mhm.hitflags = M_ATTK_MISS; @@ -1188,9 +1188,9 @@ hitmu(struct monst *mtmp, struct attack *mattk) if ((is_undead(mdat) || is_vampshifter(mtmp)) && midnight()) mhm.damage += d((int) mattk->damn, (int) mattk->damd); /* extra dmg */ - mhitm_adtyping(mtmp, mattk, &gy.youmonst, &mhm); + mhitm_adtyping(mtmp, mattk, u.umonst, &mhm); - (void) mhitm_knockback(mtmp, &gy.youmonst, mattk, &mhm.hitflags, + (void) mhitm_knockback(mtmp, u.umonst, mattk, &mhm.hitflags, (MON_WEP(mtmp) != 0)); if (mhm.done) @@ -1240,8 +1240,8 @@ hitmu(struct monst *mtmp, struct attack *mattk) if (Upolyd) { hpmax_p = &u.mhmax; - /* [can't use gy.youmonst.m_lev] */ - lowerlimit = min((int) gy.youmonst.data->mlevel, u.ulevel); + /* [can't use u.umonst->m_lev] */ + lowerlimit = min((int) u.umonst->data->mlevel, u.ulevel); } else { hpmax_p = &u.uhpmax; lowerlimit = minuhpmax(1); @@ -1276,7 +1276,7 @@ gulp_blnd_check(void) if (!Blinded && u.uswallow && (mattk = attacktype_fordmg(u.ustuck->data, AT_ENGL, AD_BLND)) - && can_blnd(u.ustuck, &gy.youmonst, mattk->aatyp, (struct obj *) 0)) { + && can_blnd(u.ustuck, u.umonst, mattk->aatyp, (struct obj *) 0)) { ++u.uswldtim; /* compensate for gulpmu change */ (void) gulpmu(u.ustuck, mattk); return TRUE; @@ -1298,11 +1298,11 @@ gulpmu(struct monst *mtmp, struct attack *mattk) if (!u.uswallow) { /* swallows you */ int omx = mtmp->mx, omy = mtmp->my; - if (!engulf_target(mtmp, &gy.youmonst)) + if (!engulf_target(mtmp, u.umonst)) return M_ATTK_MISS; if ((t && is_pit(t->ttyp)) && sobj_at(BOULDER, u.ux, u.uy)) return M_ATTK_MISS; - if (failed_grab(mtmp, &gy.youmonst, mattk)) + if (failed_grab(mtmp, u.umonst, mattk)) return M_ATTK_MISS; if (Punished) @@ -1354,7 +1354,7 @@ gulpmu(struct monst *mtmp, struct attack *mattk) unleash_all(); } - if (touch_petrifies(gy.youmonst.data) && !resists_ston(mtmp)) { + if (touch_petrifies(u.umonst->data) && !resists_ston(mtmp)) { /* put the attacker back where it started; the resulting statue will end up there [note: if poly'd hero could ride or non-poly'd hero could @@ -1438,13 +1438,13 @@ gulpmu(struct monst *mtmp, struct attack *mattk) physical_damage = TRUE; if (mtmp->data == &mons[PM_FOG_CLOUD]) { You("are laden with moisture and %s", - flaming(gy.youmonst.data) + flaming(u.umonst->data) ? "are smoldering out!" : Breathless ? "find it mildly uncomfortable." - : amphibious(gy.youmonst.data) + : amphibious(u.umonst->data) ? "feel comforted." : "can barely breathe!"); - if ((Amphibious || Breathless) && !flaming(gy.youmonst.data)) + if ((Amphibious || Breathless) && !flaming(u.umonst->data)) tmp = 0; } else { You("are %s!", enfolds(mtmp->data) ? "being squashed" @@ -1469,7 +1469,7 @@ gulpmu(struct monst *mtmp, struct attack *mattk) } break; case AD_BLND: - if (can_blnd(mtmp, &gy.youmonst, mattk->aatyp, (struct obj *) 0)) { + if (can_blnd(mtmp, u.umonst, mattk->aatyp, (struct obj *) 0)) { if (!Blind) { long was_blinded = Blinded; @@ -1564,13 +1564,13 @@ gulpmu(struct monst *mtmp, struct attack *mattk) if (!u.uswallow) { ; /* life-saving has already expelled swallowed hero */ - } else if (touch_petrifies(gy.youmonst.data) && !resists_ston(mtmp)) { + } else if (touch_petrifies(u.umonst->data) && !resists_ston(mtmp)) { pline("%s very hurriedly %s you!", Monnam(mtmp), digests(mtmp->data) ? "regurgitates" : enfolds(mtmp->data) ? "releases" : "expels"); expels(mtmp, mtmp->data, FALSE); - } else if (!u.uswldtim || gy.youmonst.data->msize >= MZ_HUGE) { + } else if (!u.uswldtim || u.umonst->data->msize >= MZ_HUGE) { /* As of 3.6.2: u.uswldtim used to be set to 0 by life-saving but it expels now so the !u.uswldtim case is no longer possible; however, polymorphing into a huge form while already @@ -1621,7 +1621,7 @@ explmu( kill_agr = FALSE; /* lifesaving? */ break; case AD_BLND: - not_affected = resists_blnd(&gy.youmonst); + not_affected = resists_blnd(u.umonst); if (ufound && !not_affected) { /* sometimes you're affected even if it's invisible */ if (mon_visible(mtmp) || (rnd(tmp /= 2) > u.ulevel)) { @@ -1636,7 +1636,7 @@ explmu( case AD_HALU: not_affected |= Blind || (u.umonnum == PM_BLACK_LIGHT || u.umonnum == PM_VIOLET_FUNGUS - || dmgtype(gy.youmonst.data, AD_STUN)); + || dmgtype(u.umonst->data, AD_STUN)); if (ufound && !not_affected) { boolean chg; if (!Hallucination) @@ -1748,7 +1748,7 @@ gazemu(struct monst *mtmp, struct attack *mattk) && !Stone_resistance && !Unaware) { You("meet %s gaze.", s_suffix(mon_nam(mtmp))); stop_occupation(); - if (poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM)) + if (poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM)) break; urgent_pline("You turn to stone..."); svk.killer.format = KILLED_BY; @@ -1791,7 +1791,7 @@ gazemu(struct monst *mtmp, struct attack *mattk) } break; case AD_BLND: - if (canseemon(mtmp) && !resists_blnd(&gy.youmonst) + if (canseemon(mtmp) && !resists_blnd(u.umonst) && mdistu(mtmp) <= BOLT_LIM * BOLT_LIM) { if (cancelled) { react = rn1(2, 2); /* "puzzled" || "dazzled" */ @@ -1842,9 +1842,9 @@ gazemu(struct monst *mtmp, struct attack *mattk) } burn_away_slime(); if (lev > rn2(20)) - (void) burnarmor(&gy.youmonst); + (void) burnarmor(u.umonst); if (lev > rn2(20)) { - (void) destroy_items(&gy.youmonst, AD_FIRE, orig_dmg); + (void) destroy_items(u.umonst, AD_FIRE, orig_dmg); ignite_items(gi.invent); } if (dmg) @@ -1943,8 +1943,8 @@ could_seduce( if (is_animal(magr->data)) return 0; - if (magr == &gy.youmonst) { - pagr = gy.youmonst.data; + if (magr == u.umonst) { + pagr = u.umonst->data; agrinvis = (Invis != 0); genagr = poly_gender(); } else { @@ -1952,7 +1952,7 @@ could_seduce( agrinvis = magr->minvis; genagr = gender(magr); } - if (mdef == &gy.youmonst) { + if (mdef == u.umonst) { defperc = (See_invisible != 0); gendef = poly_gender(); } else { @@ -2202,7 +2202,7 @@ doseduce(struct monst *mon) disp.botl = TRUE; break; case 3: - if (!resists_drli(&gy.youmonst)) { + if (!resists_drli(u.umonst)) { You_feel("out of shape."); losexp("overexertion"); } else { @@ -2541,7 +2541,7 @@ passiveum( && (perceives(mtmp->data) || !Invis)) { if (Blind) { pline("As a blind %s, you cannot defend yourself.", - pmname(gy.youmonst.data, + pmname(u.umonst->data, flags.female ? FEMALE : MALE)); } else { if (mon_reflects(mtmp, @@ -2571,8 +2571,8 @@ passiveum( u.mh += (tmp + rn2(2)) / 2; if (u.mhmax < u.mh) u.mhmax = u.mh; - if (u.mhmax > (((int) gy.youmonst.data->mlevel + 1) * 8)) - (void) split_mon(&gy.youmonst, mtmp); + if (u.mhmax > (((int) u.umonst->data->mlevel + 1) * 8)) + (void) split_mon(u.umonst, mtmp); break; case AD_STUN: /* Yellow mold */ if (!mtmp->mstun) { @@ -2617,20 +2617,20 @@ struct monst * cloneu(void) { struct monst *mon; - int mndx = monsndx(gy.youmonst.data); + int mndx = monsndx(u.umonst->data); if (u.mh <= 1) return (struct monst *) 0; if (svm.mvitals[mndx].mvflags & G_EXTINCT) return (struct monst *) 0; - mon = makemon(gy.youmonst.data, u.ux, u.uy, + mon = makemon(u.umonst->data, u.ux, u.uy, NO_MINVENT | MM_EDOG | MM_NOMSG); if (!mon) return NULL; mon->mcloned = 1; mon = christen_monst(mon, svp.plname); initedog(mon, TRUE); - mon->m_lev = gy.youmonst.data->mlevel; + mon->m_lev = u.umonst->data->mlevel; mon->mhpmax = u.mhmax; mon->mhp = u.mh / 2; u.mh -= mon->mhp; diff --git a/src/minion.c b/src/minion.c index 96f9ffe1c..833e5597f 100644 --- a/src/minion.c +++ b/src/minion.c @@ -296,7 +296,7 @@ demon_talk(struct monst *mtmp) } newsym(mtmp->mx, mtmp->my); } - if (gy.youmonst.data->mlet == S_DEMON) { /* Won't blackmail their own. */ + if (u.umonst->data->mlet == S_DEMON) { /* Won't blackmail their own. */ if (!Deaf) pline("%s says, \"Good hunting, %s.\"", Amonnam(mtmp), flags.female ? "Sister" : "Brother"); diff --git a/src/mon.c b/src/mon.c index 789ca8276..2452813e4 100644 --- a/src/mon.c +++ b/src/mon.c @@ -330,7 +330,7 @@ int m_poisongas_ok(struct monst *mtmp) { int px, py; - boolean is_you = (mtmp == &gy.youmonst); + boolean is_you = (mtmp == u.umonst); /* Non living, non breathing, immune monsters are not concerned */ if (nonliving(mtmp->data) || is_vampshifter(mtmp) @@ -2104,8 +2104,8 @@ mon_allowflags(struct monst *mtmp) if (passes_bars(mtmp->data) /* restrict engulfer or holder who might try to pass iron bars while carrying hero; accept small subset for poly'd hero passes_bars() */ - && (mtmp != u.ustuck || (unsolid(gy.youmonst.data) - || verysmall(gy.youmonst.data)))) + && (mtmp != u.ustuck || (unsolid(u.umonst->data) + || verysmall(u.umonst->data)))) allowflags |= ALLOW_BARS; #if 0 /* can't do this here; leave it for mfndpos() */ if (is_displacer(mtmp->data)) @@ -3209,7 +3209,7 @@ corpse_chance( if (was_swallowed && magr) { /* mdef is a gas spore (AT_BOOM) that is exploding inside an engulfer; suppress usual explosion since it's contained */ - if (magr == &gy.youmonst) { + if (magr == u.umonst) { There("is an explosion in your %s!", body_part(STOMACH)); Sprintf(svk.killer.name, "%s explosion", s_suffix(pmname(mdat, Mgender(mon)))); @@ -3617,7 +3617,7 @@ xkilled( /* corpse--none if hero was inside the monster */ if (!wasinside && corpse_chance(mtmp, (struct monst *) 0, FALSE)) { gz.zombify = (!gt.thrownobj && !gs.stoned && !uwep - && zombie_maker(&gy.youmonst) + && zombie_maker(u.umonst) && zombie_form(mtmp->data) != NON_PM); cadaver = make_corpse(mtmp, burycorpse ? CORPSTAT_BURIED : CORPSTAT_NONE); @@ -4595,7 +4595,7 @@ get_iter_mons_xy( int healmon(struct monst *mtmp, int amt, int overheal) { - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { int oldhp = Upolyd ? u.mh : u.uhp; healup(amt, 0, 0, 0); return (Upolyd ? u.mh : u.uhp) - oldhp; @@ -4704,7 +4704,7 @@ maybe_unhide_at(coordxy x, coordxy y) undetected = mtmp->mundetected; trapped = mtmp->mtrapped; } else if (u_at(x, y)) { - mtmp = &gy.youmonst; + mtmp = u.umonst; undetected = u.uundetected; trapped = u.utrap; } else { @@ -4730,7 +4730,7 @@ hideunder(struct monst *mtmp) const char *seenmon = (char *) 0, *seenobj = (char *) 0, *locomo = (char *) 0; int seeit = gi.in_mklev ? 0 : canseemon(mtmp); - boolean oldundetctd, undetected = FALSE, is_u = (mtmp == &gy.youmonst); + boolean oldundetctd, undetected = FALSE, is_u = (mtmp == u.umonst); coordxy x = is_u ? u.ux : mtmp->mx, y = is_u ? u.uy : mtmp->my; if (mtmp == u.ustuck) { @@ -5437,7 +5437,7 @@ newcham( /* update swallow glyphs for new monster */ swallowed(0); } - } else if ((!sticks(mdat) && !sticks(gy.youmonst.data)) + } else if ((!sticks(mdat) && !sticks(u.umonst->data)) /* sticky hero can't continue to hold mtmp if it has turned into a non-solid creature; we don't use uunstick() for that because its message would be @@ -5800,7 +5800,7 @@ usmellmon(struct permonst *mdat) boolean msg_given = FALSE; if (mdat) { - if (!olfaction(gy.youmonst.data)) + if (!olfaction(u.umonst->data)) return FALSE; mndx = monsndx(mdat); switch (mndx) { @@ -5895,7 +5895,7 @@ usmellmon(struct permonst *mdat) msg_given = TRUE; break; case S_ORC: - if (maybe_polyd(is_orc(gy.youmonst.data), Race_if(PM_ORC))) + if (maybe_polyd(is_orc(u.umonst->data), Race_if(PM_ORC))) You("notice an attractive smell."); else pline("A foul stench makes you feel a little nauseated."); diff --git a/src/mondata.c b/src/mondata.c index d7ea80245..2e6d049a2 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -13,7 +13,7 @@ void set_mon_data(struct monst *mon, struct permonst *ptr) { int new_speed, old_speed = mon->data ? mon->data->mmove : 0; - short *movement_p = (mon == &gy.youmonst) ? &u.umovement : &mon->movement; + short *movement_p = (mon == u.umonst) ? &u.umovement : &mon->movement; mon->data = ptr; mon->mnum = (short) monsndx(ptr); @@ -85,14 +85,14 @@ poly_when_stoned(struct permonst *ptr) /* allow G_EXTINCT */ } -/* is 'mon' (possibly youmonst) protected against damage type 'adtype' via +/* is 'mon' (possibly u.umonst) protected against damage type 'adtype' via wielded weapon or worn dragon scales? [or by virtue of being a dragon?] */ boolean defended(struct monst *mon, int adtyp) { struct obj *o, otemp; int mndx; - boolean is_you = (mon == &gy.youmonst); + boolean is_you = (mon == u.umonst); /* is 'mon' wielding an artifact that protects against 'adtyp'? */ o = is_you ? uwep : MON_WEP(mon); @@ -130,7 +130,7 @@ Resists_Elem(struct monst *mon, int propindx) { struct obj *o; long slotmask; - boolean is_you = (mon == &gy.youmonst); + boolean is_you = (mon == u.umonst); int u_resist = 0, damgtype = 0, rsstmask = 0; /* @@ -204,7 +204,7 @@ resists_drli(struct monst *mon) if (is_undead(ptr) || is_demon(ptr) || is_were(ptr) /* is_were() doesn't handle hero in human form */ - || (mon == &gy.youmonst && u.ulycn >= LOW_PM) + || (mon == u.umonst && u.ulycn >= LOW_PM) || ptr == &mons[PM_DEATH] || is_vampshifter(mon)) return TRUE; return defended(mon, AD_DRLI); @@ -215,7 +215,7 @@ boolean resists_magm(struct monst *mon) { struct permonst *ptr = mon->data; - boolean is_you = (mon == &gy.youmonst); + boolean is_you = (mon == u.umonst); long slotmask; struct obj *o; @@ -248,7 +248,7 @@ boolean resists_blnd(struct monst *mon) { struct permonst *ptr = mon->data; - boolean is_you = (mon == &gy.youmonst); + boolean is_you = (mon == u.umonst); if (is_you ? (Blind || Unaware) : (mon->mblinded || !mon->mcansee || !haseyes(ptr) @@ -278,7 +278,7 @@ boolean resists_blnd_by_arti(struct monst *mon) { struct obj *o; - boolean is_you = (mon == &gy.youmonst); + boolean is_you = (mon == u.umonst); o = is_you ? uwep : MON_WEP(mon); if (o && o->oartifact && defends(AD_BLND, o)) @@ -308,7 +308,7 @@ can_blnd( uchar aatyp, struct obj *obj) /* aatyp == AT_WEAP, AT_SPIT */ { - boolean is_you = (mdef == &gy.youmonst); + boolean is_you = (mdef == u.umonst); boolean check_visor = FALSE; struct obj *o; @@ -354,7 +354,7 @@ can_blnd( return TRUE; /* no defense */ } else return FALSE; /* other objects cannot cause blindness yet */ - if ((magr == &gy.youmonst) && u.uswallow) + if ((magr == u.umonst) && u.uswallow) return FALSE; /* can't affect eyes while inside monster */ break; @@ -369,7 +369,7 @@ can_blnd( /* e.g. raven: all ublindf, including LENSES, protect */ if (is_you && ublindf) return FALSE; - if ((magr == &gy.youmonst) && u.uswallow) + if ((magr == u.umonst) && u.uswallow) return FALSE; /* can't affect eyes while inside monster */ check_visor = TRUE; break; @@ -387,7 +387,7 @@ can_blnd( /* check if wearing a visor (only checked if visor might help) */ if (check_visor) { - o = (mdef == &gy.youmonst) ? gi.invent : mdef->minvent; + o = (mdef == u.umonst) ? gi.invent : mdef->minvent; for (; o; o = o->nobj) if ((o->owornmask & W_ARMH) && objdescr_is(o, "visored helmet")) @@ -570,7 +570,7 @@ can_blow(struct monst *mtmp) && (breathless(mtmp->data) || verysmall(mtmp->data) || !has_head(mtmp->data) || mtmp->data->mlet == S_EEL)) return FALSE; - if ((mtmp == &gy.youmonst) && Strangled) + if ((mtmp == u.umonst) && Strangled) return FALSE; return TRUE; } @@ -579,7 +579,7 @@ can_blow(struct monst *mtmp) boolean can_chant(struct monst *mtmp) { - if ((mtmp == &gy.youmonst && Strangled) + if ((mtmp == u.umonst && Strangled) || is_silent(mtmp->data) || !has_head(mtmp->data) || mtmp->data->msound == MS_BUZZ || mtmp->data->msound == MS_BURBLE) return FALSE; @@ -602,10 +602,10 @@ can_be_strangled(struct monst *mon) are non-breathing creatures which have higher brain function. */ if (!has_head(mon->data)) return FALSE; - if (mon == &gy.youmonst) { + if (mon == u.umonst) { /* hero can't be mindless but poly'ing into mindless form can confer strangulation protection */ - nobrainer = mindless(gy.youmonst.data); + nobrainer = mindless(u.umonst->data); nonbreathing = Breathless; } else { nobrainer = mindless(mon->data); @@ -1358,7 +1358,7 @@ big_little_match(int montyp1, int montyp2) const struct permonst * raceptr(struct monst *mtmp) { - if (mtmp == &gy.youmonst && !Upolyd) + if (mtmp == u.umonst && !Upolyd) return &mons[gu.urace.mnum]; return mtmp->data; } diff --git a/src/monmove.c b/src/monmove.c index 6489d19d4..fe3040da3 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -364,7 +364,7 @@ release_hero(struct monst *mon) if (mon == u.ustuck) { if (u.uswallow) { expels(mon, mon->data, TRUE); - } else if (!sticks(gy.youmonst.data)) { + } else if (!sticks(u.umonst->data)) { unstuck(mon); /* let go */ You("get released!"); } @@ -608,8 +608,8 @@ mind_blast(struct monst *mtmp) /* hero has no way to hide as monster but check for that theoretical case anyway */ && U_AP_TYPE != M_AP_MONSTER) { - gy.youmonst.m_ap_type = M_AP_NOTHING; - gy.youmonst.mappearance = 0; + u.umonst->m_ap_type = M_AP_NOTHING; + u.umonst->mappearance = 0; newsym(u.ux, u.uy); } pline("It locks on to your %s!", @@ -649,7 +649,7 @@ mind_blast(struct monst *mtmp) void m_everyturn_effect(struct monst *mtmp) { - boolean is_u = (mtmp == &gy.youmonst) ? TRUE : FALSE; + boolean is_u = (mtmp == u.umonst) ? TRUE : FALSE; coordxy x = is_u ? u.ux : mtmp->mx, y = is_u ? u.uy : mtmp->my; @@ -671,7 +671,7 @@ m_everyturn_effect(struct monst *mtmp) void m_postmove_effect(struct monst *mtmp) { - boolean is_u = (mtmp == &gy.youmonst) ? TRUE : FALSE; + boolean is_u = (mtmp == u.umonst) ? TRUE : FALSE; coordxy x = is_u ? u.ux0 : mtmp->mx, y = is_u ? u.uy0 : mtmp->my; @@ -806,7 +806,7 @@ dochug(struct monst *mtmp) pline("%s whispers at thin air.", cansee(mtmp->mux, mtmp->muy) ? Monnam(mtmp) : "It"); - if (is_demon(gy.youmonst.data)) { + if (is_demon(u.umonst->data)) { /* "Good hunting, brother" */ if (!tele_restrict(mtmp)) (void) rloc(mtmp, RLOC_MSG); @@ -1052,7 +1052,7 @@ mon_would_consume_item(struct monst *mtmp, struct obj *otmp) boolean itsstuck(struct monst *mtmp) { - if (sticks(gy.youmonst.data) && mtmp == u.ustuck && !u.uswallow) { + if (sticks(u.umonst->data) && mtmp == u.ustuck && !u.uswallow) { pline_mon(mtmp, "%s cannot escape from you!", Monnam(mtmp)); return TRUE; } @@ -1862,8 +1862,8 @@ m_move(struct monst *mtmp, int after) if (!mtmp->mcansee || (should_see && Invis && !perceives(ptr) && rn2(11)) - || is_obj_mappear(&gy.youmonst, STRANGE_OBJECT) || u.uundetected - || (is_obj_mappear(&gy.youmonst, GOLD_PIECE) && !likes_gold(ptr)) + || is_obj_mappear(u.umonst, STRANGE_OBJECT) || u.uundetected + || (is_obj_mappear(u.umonst, GOLD_PIECE) && !likes_gold(ptr)) || (mtmp->mpeaceful && !mtmp->isshk) /* allow shks to follow */ || ((monsndx(ptr) == PM_STALKER || ptr->mlet == S_BAT || ptr->mlet == S_LIGHT) && !rn2(3))) @@ -1889,7 +1889,7 @@ m_move(struct monst *mtmp, int after) if ((!mtmp->mpeaceful || !rn2(10)) && (!Is_rogue_level(&u.uz))) { boolean in_line = (lined_up(mtmp) && (distmin(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) - <= (throws_rocks(gy.youmonst.data) ? 20 + <= (throws_rocks(u.umonst->data) ? 20 : (ACURRSTR / 2 + 1)))); if (appr != 1 || !in_line) { @@ -2318,7 +2318,7 @@ stuff_prevents_passage(struct monst *mtmp) { struct obj *chain, *obj; - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { chain = gi.invent; } else { chain = mtmp->minvent; diff --git a/src/mthrowu.c b/src/mthrowu.c index 6f8ed721c..850abac8a 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -124,7 +124,7 @@ thitu( pline("It doesn't seem to hurt you."); monstseesu(M_SEEN_ACID); } else if (obj && stone_missile(obj) - && passes_rocks(gy.youmonst.data)) { + && passes_rocks(u.umonst->data)) { /* use 'named' as an approximation for "hitting from above"; we avoid "passes through you" for horizontal flight path because missile stops and that wording would suggest that @@ -134,7 +134,7 @@ thitu( } else if (obj && obj->oclass == POTION_CLASS) { /* an explosion which scatters objects might hit hero with one (potions deliberately thrown at hero are handled by m_throw) */ - potionhit(&gy.youmonst, obj, POTHIT_OTHER_THROW); + potionhit(u.umonst, obj, POTHIT_OTHER_THROW); *objp = obj = 0; /* potionhit() uses up the potion */ } else { if (obj && objects[obj->otyp].oc_material == SILVER @@ -184,7 +184,7 @@ drop_throw( if (!(broken = flooreffects(obj, x, y, "fall"))) { place_object(obj, x, y); if (!mtmp && u_at(x, y)) - mtmp = &gy.youmonst; + mtmp = u.umonst; if (mtmp && ohit) passive_obj(mtmp, obj, (struct attack *) 0); stackobj(obj); @@ -508,7 +508,7 @@ ucatchgem( struct monst *mon) { /* won't catch rock or gray stone; catch (then drop) worthless glass */ - if (gem->otyp <= LAST_GLASS_GEM && is_unicorn(gy.youmonst.data)) { + if (gem->otyp <= LAST_GLASS_GEM && is_unicorn(u.umonst->data)) { char *gem_xname = xname(gem), *mon_s_name = s_suffix(mon_nam(mon)); @@ -537,7 +537,7 @@ u_catch_thrown_obj(struct obj *otmp) if (!Blind && !Confusion && !Stunned && !Fumbling && otmp->oclass != VENOM_CLASS - && !nohands(gy.youmonst.data) && freehand() + && !nohands(u.umonst->data) && freehand() && calc_capacity(otmp->owt) <= SLT_ENCUMBER && !rn2(catch_chance)) { char buf[BUFSZ]; @@ -696,7 +696,7 @@ m_throw( break; if (singleobj->oclass == POTION_CLASS) { - potionhit(&gy.youmonst, singleobj, POTHIT_MONST_THROW); + potionhit(u.umonst, singleobj, POTHIT_MONST_THROW); break; } oldumort = u.umortality; @@ -719,7 +719,7 @@ m_throw( { int dam, hitv; - dam = dmgval(singleobj, &gy.youmonst); + dam = dmgval(singleobj, u.umonst); hitv = 3 - distmin(u.ux, u.uy, mon->mx, mon->my); if (hitv < -4) hitv = -4; @@ -732,7 +732,7 @@ m_throw( if (singleobj->otyp == ELVEN_ARROW) dam++; } - if (bigmonst(gy.youmonst.data)) + if (bigmonst(u.umonst->data)) hitv++; hitv += 8 + singleobj->spe; if (dam < 1) @@ -752,7 +752,7 @@ m_throw( poison is limited to attrib loss */ (u.umortality > oldumort) ? 0 : 10, TRUE); } - if (hitu && can_blnd((struct monst *) 0, &gy.youmonst, + if (hitu && can_blnd((struct monst *) 0, u.umonst, (uchar) ((singleobj->otyp == BLINDING_VENOM) ? AT_SPIT : AT_WEAP), @@ -767,7 +767,7 @@ m_throw( } else if (singleobj->otyp == BLINDING_VENOM) { const char *eyes = body_part(EYE); - if (eyecount(gy.youmonst.data) != 1) + if (eyecount(u.umonst->data) != 1) eyes = makeplural(eyes); /* venom in the eyes */ if (!Blind) @@ -778,7 +778,7 @@ m_throw( } if (hitu && singleobj->otyp == EGG) { if (!Stoned && !Stone_resistance - && !(poly_when_stoned(gy.youmonst.data) + && !(poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM))) { make_stoned(5L, (char *) 0, KILLED_BY, ""); } @@ -1030,7 +1030,7 @@ spitmm(struct monst *mtmp, struct attack *mattk, struct monst *mtarg) return M_ATTK_MISS; } if (m_lined_up(mtarg, mtmp)) { - boolean utarg = (mtarg == &gy.youmonst); + boolean utarg = (mtarg == u.umonst); coordxy tx = utarg ? mtmp->mux : mtarg->mx; coordxy ty = utarg ? mtmp->muy : mtarg->my; @@ -1093,7 +1093,7 @@ int breamm(struct monst *mtmp, struct attack *mattk, struct monst *mtarg) { int typ = get_atkdam_type(mattk->adtyp); - boolean utarget = (mtarg == &gy.youmonst); + boolean utarget = (mtarg == u.umonst); if (m_lined_up(mtarg, mtmp)) { if (mtmp->mcan) { @@ -1225,11 +1225,11 @@ thrwmu(struct monst *mtmp) obj_is_pname(otmp) ? the(onm) : an(onm)); } - dam = dmgval(otmp, &gy.youmonst); + dam = dmgval(otmp, u.umonst); hitv = 3 - distmin(u.ux, u.uy, mtmp->mx, mtmp->my); if (hitv < -4) hitv = -4; - if (bigmonst(gy.youmonst.data)) + if (bigmonst(u.umonst->data)) hitv++; hitv += 8 + otmp->spe; if (dam < 1) @@ -1267,14 +1267,14 @@ thrwmu(struct monst *mtmp) int spitmu(struct monst *mtmp, struct attack *mattk) { - return spitmm(mtmp, mattk, &gy.youmonst); + return spitmm(mtmp, mattk, u.umonst); } /* monster breathes at you (ranged) */ int breamu(struct monst *mtmp, struct attack *mattk) { - return breamm(mtmp, mattk, &gy.youmonst); + return breamm(mtmp, mattk, u.umonst); } /* return TRUE if terrain at x,y blocks linedup checks */ @@ -1375,7 +1375,7 @@ linedup( staticfn int m_lined_up(struct monst *mtarg, struct monst *mtmp) { - boolean utarget = (mtarg == &gy.youmonst); + boolean utarget = (mtarg == u.umonst); coordxy tx = utarget ? mtmp->mux : mtarg->mx; coordxy ty = utarget ? mtmp->muy : mtarg->my; boolean ignore_boulders = utarget && (throws_rocks(mtmp->data) @@ -1397,7 +1397,7 @@ m_lined_up(struct monst *mtarg, struct monst *mtmp) boolean lined_up(struct monst *mtmp) { - return m_lined_up(&gy.youmonst, mtmp) ? TRUE : FALSE; + return m_lined_up(u.umonst, mtmp) ? TRUE : FALSE; } /* check if a monster is carrying an item of a particular type */ @@ -1406,7 +1406,7 @@ m_carrying(struct monst *mtmp, int type) { struct obj *otmp; - for (otmp = (mtmp == &gy.youmonst) ? gi.invent : mtmp->minvent; otmp; + for (otmp = (mtmp == u.umonst) ? gi.invent : mtmp->minvent; otmp; otmp = otmp->nobj) if (otmp->otyp == type) break; diff --git a/src/muse.c b/src/muse.c index 78b61c10b..07cc865da 100644 --- a/src/muse.c +++ b/src/muse.c @@ -252,7 +252,7 @@ mreadmsg(struct monst *mtmp, struct obj *otmp) pline_mon(mtmp, "%s reads %s!", Monnam(mtmp), onambuf); } else { /* !Deaf, otherwise we wouldn't reach here */ char blindbuf[BUFSZ]; - boolean similar = same_race(gy.youmonst.data, mtmp->data), + boolean similar = same_race(u.umonst->data, mtmp->data), uniqmon = ((mtmp->data->geno & G_UNIQ) != 0 /* shopkeepers aren't unique monsters but since they have distinct names, treat them as such */ @@ -1565,8 +1565,8 @@ find_offensive(struct monst *mtmp) } nomore(MUSE_CAMERA); if (obj->otyp == EXPENSIVE_CAMERA - && ((!Blind && !resists_blnd(&gy.youmonst)) - || hates_light(gy.youmonst.data)) + && ((!Blind && !resists_blnd(u.umonst)) + || hates_light(u.umonst->data)) && dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 2 && obj->spe > 0 && !rn2(6)) { gm.m.offensive = obj; @@ -1598,7 +1598,7 @@ mbhitm(struct monst *mtmp, struct obj *otmp) { int tmp; boolean reveal_invis = FALSE, learnit = FALSE, - hits_you = (mtmp == &gy.youmonst); + hits_you = (mtmp == u.umonst); if (!hits_you && otmp->otyp != WAN_UNDEAD_TURNING) { mtmp->msleeping = 0; @@ -1761,7 +1761,7 @@ mbhit( break; } if (u_at(gb.bhitpos.x, gb.bhitpos.y)) { - (*fhitm)(&gy.youmonst, obj); + (*fhitm)(u.umonst, obj); range -= 3; } else if ((mtmp = m_at(gb.bhitpos.x, gb.bhitpos.y)) != 0) { if (cansee(gb.bhitpos.x, gb.bhitpos.y) && !canspotmon(mtmp)) @@ -1944,7 +1944,7 @@ use_offensive(struct monst *mtmp) Monnam(mtmp), an(xname(otmp))); } gm.m_using = TRUE; - if (!Blind && !resists_blnd(&gy.youmonst)) { + if (!Blind && !resists_blnd(u.umonst)) { You("are blinded by the flash of light!"); make_blinded(BlindedTimeout + (long) rnd(1 + 50), FALSE); } @@ -2857,7 +2857,7 @@ ureflects(const char *fmt, const char *str) if (fmt && str) pline(fmt, str, uskin ? "luster" : "armor"); return TRUE; - } else if (gy.youmonst.data == &mons[PM_SILVER_DRAGON]) { + } else if (u.umonst->data == &mons[PM_SILVER_DRAGON]) { if (fmt && str) pline(fmt, str, "scales"); return TRUE; diff --git a/src/music.c b/src/music.c index 21614860d..7034577a5 100644 --- a/src/music.c +++ b/src/music.c @@ -165,7 +165,7 @@ awaken_soldiers(struct monst *bugler /* monster that played instrument */) int distance, distm; /* distance of affected non-soldier monsters to bugler */ - distance = ((bugler == &gy.youmonst) ? u.ulevel + distance = ((bugler == u.umonst) ? u.ulevel : bugler->data->mlevel) * 30; for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { @@ -182,7 +182,7 @@ awaken_soldiers(struct monst *bugler /* monster that played instrument */) else if (!Deaf) Norep("%s the rattle of battle gear being readied.", "You hear"); /* Deaf-aware */ - } else if ((distm = ((bugler == &gy.youmonst) + } else if ((distm = ((bugler == u.umonst) ? mdistu(mtmp) : dist2(bugler->mx, bugler->my, mtmp->mx, mtmp->my))) < distance) { @@ -301,7 +301,7 @@ do_pit(coordxy x, coordxy y, unsigned tu_pit) Your("chain breaks!"); reset_utrap(TRUE); } - if (Levitation || Flying || is_clinger(gy.youmonst.data)) { + if (Levitation || Flying || is_clinger(u.umonst->data)) { if (!tu_pit) { /* no pit here previously */ pline("A chasm opens up under you!"); You("don't fall in!"); @@ -327,8 +327,8 @@ do_pit(coordxy x, coordxy y, unsigned tu_pit) if (keepfooting) exercise(A_DEX, TRUE); else - selftouch((Upolyd && (slithy(gy.youmonst.data) - || nolimbs(gy.youmonst.data))) + selftouch((Upolyd && (slithy(u.umonst->data) + || nolimbs(u.umonst->data))) ? "Shaken, you" : "Falling down, you"); } @@ -653,7 +653,7 @@ do_improvisation(struct obj *instr) else You("blow into the bugle."); Hero_playnotes(obj_to_instr(&itmp), improvisation, 80); - awaken_soldiers(&gy.youmonst); + awaken_soldiers(u.umonst); exercise(A_WIS, FALSE); break; case MAGIC_HARP: /* Charm monsters */ @@ -769,7 +769,7 @@ do_play_instrument(struct obj *instr) } else if ((instr->otyp == WOODEN_FLUTE || instr->otyp == MAGIC_FLUTE || instr->otyp == TOOLED_HORN || instr->otyp == FROST_HORN || instr->otyp == FIRE_HORN || instr->otyp == BUGLE) - && !can_blow(&gy.youmonst)) { + && !can_blow(u.umonst)) { You("are incapable of playing %s.", thesimpleoname(instr)); return ECMD_OK; } diff --git a/src/pager.c b/src/pager.c index 82b8bc7eb..ac8b5f61e 100644 --- a/src/pager.c +++ b/src/pager.c @@ -121,7 +121,7 @@ self_lookat(char *outbuf) Sprintf(eos(outbuf), ", mounted on %s", y_monnam(u.usteed)); if (u.uundetected || (Upolyd && U_AP_TYPE) || visible_region_at(u.ux, u.uy)) - mhidden_description(&gy.youmonst, + mhidden_description(u.umonst, MHID_PREFIX | MHID_ARTICLE | MHID_REGION, eos(outbuf)); if (Punished) @@ -196,7 +196,7 @@ mhidden_description( incl_article = (mhid_flags & MHID_ARTICLE) != 0, show_altmon = (mhid_flags & MHID_ALTMON) != 0, force_region = (mhid_flags & MHID_REGION) != 0; - boolean fakeobj, isyou = (mon == &gy.youmonst); + boolean fakeobj, isyou = (mon == u.umonst); coordxy x = isyou ? u.ux : mon->mx, y = isyou ? u.uy : mon->my; int glyph = (svl.level.flags.hero_memory && !isyou) ? levl[x][y].glyph : glyph_at(x, y); @@ -446,7 +446,7 @@ look_at_monster( Strcat(buf, digests(mtmp->data) ? ", swallowing you" : ", engulfing you"); else - Strcat(buf, (Upolyd && sticks(gy.youmonst.data)) + Strcat(buf, (Upolyd && sticks(u.umonst->data)) ? ", being held" : ", holding you"); } /* if mtmp isn't able to move (other than because it is a type of @@ -1167,7 +1167,7 @@ add_cmap_descr( /* grab a scratch buffer we can safely return (via *firstmatch when applicable) */ - mbuf = mon_nam(&gy.youmonst); + mbuf = mon_nam(u.umonst); if (absidx == S_pool) { levl[cc.x][cc.y].typ = (idx == S_pool) ? POOL : MOAT; diff --git a/src/pickup.c b/src/pickup.c index 331933137..5f6e55de8 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -287,7 +287,7 @@ fatal_corpse_mistake(struct obj *obj, boolean remotely) if (u_safe_from_fatal_corpse(obj, st_all) || remotely) return FALSE; - if (poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM)) { + if (poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM)) { display_nhwindow(WIN_MESSAGE, FALSE); /* --More-- */ return FALSE; } @@ -723,9 +723,9 @@ pickup(int what) /* should be a long */ */ if ((gm.multi && !svc.context.run) || (autopickup && !flags.pickup) - || notake(gy.youmonst.data)) { + || notake(u.umonst->data)) { check_here(FALSE); - if (notake(gy.youmonst.data) && OBJ_AT(u.ux, u.uy) + if (notake(u.umonst->data) && OBJ_AT(u.ux, u.uy) && (autopickup || flags.pickup)) You("are physically incapable of picking anything up."); return 0; @@ -892,8 +892,8 @@ pickup(int what) /* should be a long */ } if (!u.uswallow) { - if (hides_under(gy.youmonst.data)) - (void) hideunder(&gy.youmonst); + if (hides_under(u.umonst->data)) + (void) hideunder(u.umonst); /* position may need updating (invisible hero) */ if (n_picked) @@ -1155,7 +1155,7 @@ query_objlist(const char *qstr, /* query string */ fake_hero_object = cg.zeroobj; fake_hero_object.quan = 1L; /* not strictly necessary... */ any.a_obj = &fake_hero_object; - tmpglyph = mon_to_glyph(&gy.youmonst, rn2_on_display_rng); + tmpglyph = mon_to_glyph(u.umonst, rn2_on_display_rng); map_glyphinfo(0, 0, tmpglyph, 0U, &tmpglyphinfo); add_menu(win, &tmpglyphinfo, &any, /* fake inventory letter, no group accelerator */ @@ -1719,7 +1719,7 @@ lift_object( and for boulder picked up by hero poly'd into a giant; override availability of open inventory slot iff not already carrying one */ if (obj->otyp == LOADSTONE - || (obj->otyp == BOULDER && throws_rocks(gy.youmonst.data))) { + || (obj->otyp == BOULDER && throws_rocks(u.umonst->data))) { if (inv_cnt(FALSE) < invlet_basic || !carrying(obj->otyp) || merge_choice(gi.invent, obj)) return 1; /* lift regardless of current situation */ @@ -1823,7 +1823,7 @@ pickup_object( && engulfing_u(obj->ocarry)) { You_cant("pick %s up.", ysimple_name(obj)); return 0; - } else if (obj->oartifact && !touch_artifact(obj, &gy.youmonst)) { + } else if (obj->oartifact && !touch_artifact(obj, u.umonst)) { return 0; } else if (obj->otyp == CORPSE) { if (fatal_corpse_mistake(obj, telekinesis) @@ -1983,7 +1983,7 @@ encumber_msg(void) break; case 3: You("%s under your heavy load. Movement is very hard.", - stagger(gy.youmonst.data, "stagger")); + stagger(u.umonst->data, "stagger")); break; default: You("%s move a handspan with this load!", @@ -2004,7 +2004,7 @@ encumber_msg(void) break; case 3: You("%s under your load. Movement is still very hard.", - stagger(gy.youmonst.data, "stagger")); + stagger(u.umonst->data, "stagger")); break; } disp.botl = TRUE; @@ -2051,7 +2051,7 @@ able_to_loot( You("cannot %s things that are deep in the %s.", verb, hliquid(is_lava(x, y) ? "lava" : "water")); return FALSE; - } else if (nolimbs(gy.youmonst.data)) { + } else if (nolimbs(u.umonst->data)) { pline("Without limbs, you cannot %s anything.", verb); return FALSE; } else if (looting && !freehand()) { @@ -2189,7 +2189,7 @@ doloot_core(void) /* "Can't do that while carrying so much stuff." */ return ECMD_OK; } - if (nohands(gy.youmonst.data)) { + if (nohands(u.umonst->data)) { You("have no hands!"); /* not `body_part(HAND)' */ return ECMD_OK; } @@ -2440,7 +2440,7 @@ loot_mon(struct monst *mtmp, int *passed_info, boolean *prev_loot) x_monnam(mtmp, ARTICLE_THE, (char *) 0, SUPPRESS_SADDLE, FALSE)); if ((c = yn_function(qbuf, ynqchars, 'n', TRUE)) == 'y') { - if (nolimbs(gy.youmonst.data)) { + if (nolimbs(u.umonst->data)) { You_cant("do that without limbs."); /* not body_part(HAND) */ return 0; } @@ -2732,7 +2732,7 @@ out_container(struct obj *obj) obj->owt = weight(obj); } - if (obj->oartifact && !touch_artifact(obj, &gy.youmonst)) + if (obj->oartifact && !touch_artifact(obj, u.umonst)) return 0; if (fatal_corpse_mistake(obj, FALSE)) @@ -2936,7 +2936,7 @@ explain_container_prompt(boolean more_containers) boolean u_handsy(void) { - if (nohands(gy.youmonst.data)) { + if (nohands(u.umonst->data)) { You("have no hands!"); /* not `body_part(HAND)' */ return FALSE; } else if (!freehand()) { diff --git a/src/pline.c b/src/pline.c index 79dd8b28b..c8d61b09d 100644 --- a/src/pline.c +++ b/src/pline.c @@ -139,7 +139,7 @@ pline_mon(struct monst *mtmp, const char *line, ...) { va_list the_args; - if (mtmp == &gy.youmonst) + if (mtmp == u.umonst) set_msg_xy(0, 0); else set_msg_xy(mtmp->mx, mtmp->my); diff --git a/src/polyself.c b/src/polyself.c index 43c76cf40..2461a1b79 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -5,8 +5,8 @@ /* * Polymorph self routine. * - * Note: the light source handling code assumes that gy.youmonst.m_id - * always remains 1 and gy.youmonst.mx will always remain 0 when it handles + * Note: the light source handling code assumes that u.umonst->m_id + * always remains 1 and u.umonst->mx will always remain 0 when it handles * the case of the player polymorphed into a light-emitting monster. * * Transformation sequences: @@ -33,24 +33,24 @@ staticfn void polysense(void); static const char no_longer_petrify_resistant[] = "No longer petrify-resistant, you"; -/* update the gy.youmonst.data structure pointer and intrinsics */ +/* update the u.umonst->data structure pointer and intrinsics */ void set_uasmon(void) { struct permonst *mdat = &mons[u.umonnum]; - boolean was_vampshifter = valid_vampshiftform(gy.youmonst.cham, u.umonnum); + boolean was_vampshifter = valid_vampshiftform(u.umonst->cham, u.umonnum); - set_mon_data(&gy.youmonst, mdat); - gy.youmonst.m_id = 1; + set_mon_data(u.umonst, mdat); + u.umonst->m_id = 1; if (Protection_from_shape_changers) - gy.youmonst.cham = NON_PM; - else if (is_vampire(gy.youmonst.data)) - gy.youmonst.cham = gy.youmonst.mnum; + u.umonst->cham = NON_PM; + else if (is_vampire(u.umonst->data)) + u.umonst->cham = u.umonst->mnum; /* assume hero-as-chameleon/doppelganger/sandestin doesn't change shape */ else if (!was_vampshifter) - gy.youmonst.cham = NON_PM; - u.mcham = gy.youmonst.cham; /* for save/restore since youmonst isn't */ + u.umonst->cham = NON_PM; + u.mcham = u.umonst->cham; /* for save/restore since u.umonst isn't */ #define PROPSET(PropIndx, ON) \ do { \ @@ -59,7 +59,7 @@ set_uasmon(void) else \ u.uprops[PropIndx].intrinsic &= ~FROMFORM; \ } while (0) -#define resist_from_form(MRtyp) ((gy.youmonst.data->mresists & (MRtyp)) != 0) +#define resist_from_form(MRtyp) ((u.umonst->data->mresists & (MRtyp)) != 0) PROPSET(FIRE_RES, resist_from_form(MR_FIRE)); PROPSET(COLD_RES, resist_from_form( MR_COLD)); @@ -74,7 +74,7 @@ set_uasmon(void) struct obj *save_uwep = uwep; uwep = 0; - PROPSET(DRAIN_RES, resists_drli(&gy.youmonst)); + PROPSET(DRAIN_RES, resists_drli(u.umonst)); uwep = save_uwep; } /* resists_magm() takes wielded, worn, and carried equipment into @@ -174,7 +174,7 @@ check_strangling(boolean on) /* when Strangled is already set, polymorphing from one vulnerable form into another causes the counter to be reset */ if (uamul && uamul->otyp == AMULET_OF_STRANGULATION - && can_be_strangled(&gy.youmonst)) { + && can_be_strangled(u.umonst)) { Strangled = 6L; disp.botl = TRUE; Your("%s %s your %s!", simpleonames(uamul), @@ -185,7 +185,7 @@ check_strangling(boolean on) /* off -- maybe block strangling */ } else { - if (Strangled && !can_be_strangled(&gy.youmonst)) { + if (Strangled && !can_be_strangled(u.umonst)) { Strangled = 0L; disp.botl = TRUE; You("are no longer being strangled."); @@ -199,7 +199,7 @@ DISABLE_WARNING_FORMAT_NONLITERAL staticfn void polyman(const char *fmt, const char *arg) { - boolean sticking = (sticks(gy.youmonst.data) && u.ustuck && !u.uswallow), + boolean sticking = (sticks(u.umonst->data) && u.ustuck && !u.uswallow), was_mimicking = (U_AP_TYPE != M_AP_NOTHING); boolean was_blind = !!Blind, had_see_invis = !!See_invisible; @@ -223,8 +223,8 @@ polyman(const char *fmt, const char *arg) if (was_mimicking) { if (gm.multi < 0) unmul(""); - gy.youmonst.m_ap_type = M_AP_NOTHING; - gy.youmonst.mappearance = 0; + u.umonst->m_ap_type = M_AP_NOTHING; + u.umonst->mappearance = 0; } newsym(u.ux, u.uy); @@ -249,7 +249,7 @@ polyman(const char *fmt, const char *arg) if (!!See_invisible ^ had_see_invis) set_mimic_blocking(); /* See_invisible just toggled */ - if (u.twoweap && !could_twoweap(gy.youmonst.data)) + if (u.twoweap && !could_twoweap(u.umonst->data)) untwoweapon(); if (u.utrap && u.utraptype == TT_PIT) { @@ -279,8 +279,8 @@ change_sex(void) * may be true for certain roles */ if (!Upolyd - || (!is_male(gy.youmonst.data) && !is_female(gy.youmonst.data) - && !is_neuter(gy.youmonst.data))) + || (!is_male(u.umonst->data) && !is_female(u.umonst->data) + && !is_neuter(u.umonst->data))) flags.female = !flags.female; if (Upolyd) /* poly'd: also change saved sex */ u.mfemale = !u.mfemale; @@ -476,8 +476,8 @@ polyself(int psflags) formrevert = ((psflags & POLY_REVERT) != 0), draconian = (uarm && Is_dragon_armor(uarm)), iswere = (ismnum(u.ulycn)), - isvamp = (is_vampire(gy.youmonst.data) - || is_vampshifter(&gy.youmonst)), + isvamp = (is_vampire(u.umonst->data) + || is_vampshifter(u.umonst)), controllable_poly = Polymorph_control && !(Stunned || Unaware); if (Unchanging) { @@ -494,11 +494,11 @@ polyself(int psflags) return; } } - old_light = emits_light(gy.youmonst.data); + old_light = emits_light(u.umonst->data); mntmp = NON_PM; if (formrevert) { - mntmp = gy.youmonst.cham; + mntmp = u.umonst->cham; monsterpoly = TRUE; controllable_poly = FALSE; } @@ -670,13 +670,13 @@ polyself(int psflags) } else if (isvamp) { do_vampyr: if (mntmp < LOW_PM || (mons[mntmp].geno & G_UNIQ)) { - mntmp = (gy.youmonst.data == &mons[PM_VAMPIRE_LEADER] + mntmp = (u.umonst->data == &mons[PM_VAMPIRE_LEADER] && !rn2(10)) ? PM_WOLF : !rn2(4) ? PM_FOG_CLOUD : PM_VAMPIRE_BAT; - if (ismnum(gy.youmonst.cham) - && !is_vampire(gy.youmonst.data) && !rn2(2)) - mntmp = gy.youmonst.cham; + if (ismnum(u.umonst->cham) + && !is_vampire(u.umonst->data) && !rn2(2)) + mntmp = u.umonst->cham; } if (controllable_poly) { Sprintf(buf, "Become %s?", @@ -718,15 +718,15 @@ polyself(int psflags) gs.sex_change_ok--; /* reset */ made_change: - new_light = emits_light(gy.youmonst.data); + new_light = emits_light(u.umonst->data); if (old_light != new_light) { if (old_light) - del_light_source(LS_MONSTER, monst_to_any(&gy.youmonst)); + del_light_source(LS_MONSTER, monst_to_any(u.umonst)); if (new_light == 1) ++new_light; /* otherwise it's undetectable */ if (new_light) new_light_source(u.ux, u.uy, new_light, LS_MONSTER, - monst_to_any(&gy.youmonst)); + monst_to_any(u.umonst)); } } @@ -735,9 +735,9 @@ int polymon(int mntmp) { char buf[BUFSZ], ustuckNam[BUFSZ]; - boolean sticking = sticks(gy.youmonst.data) && u.ustuck && !u.uswallow, + boolean sticking = sticks(u.umonst->data) && u.ustuck && !u.uswallow, was_blind = !!Blind, dochange = FALSE, was_expelled = FALSE, - was_hiding_under = u.uundetected && hides_under(gy.youmonst.data); + was_hiding_under = u.uundetected && hides_under(u.umonst->data); int mlvl, newMaxStr; if (svm.mvitals[mntmp].mvflags & G_GENOD) { /* allow G_EXTINCT */ @@ -774,13 +774,13 @@ polymon(int mntmp) /* if stuck mimicking gold, stop immediately */ if (gm.multi < 0 && U_AP_TYPE == M_AP_OBJECT - && gy.youmonst.data->mlet != S_MIMIC) + && u.umonst->data->mlet != S_MIMIC) unmul(""); /* if becoming a non-mimic, stop mimicking anything */ if (mons[mntmp].mlet != S_MIMIC) { /* as in polyman() */ - gy.youmonst.m_ap_type = M_AP_NOTHING; - gy.youmonst.mappearance = 0; + u.umonst->m_ap_type = M_AP_NOTHING; + u.umonst->mappearance = 0; } if (is_male(&mons[mntmp])) { if (flags.female) @@ -840,7 +840,7 @@ polymon(int mntmp) You("no longer feel sick."); } if (Slimed) { - if (flaming(gy.youmonst.data)) { + if (flaming(u.umonst->data)) { make_slimed(0L, "The slime burns away!"); } else if (mntmp == PM_GREEN_SLIME) { /* do it silently */ @@ -848,7 +848,7 @@ polymon(int mntmp) } } check_strangling(FALSE); /* maybe stop strangling */ - if (nohands(gy.youmonst.data)) + if (nohands(u.umonst->data)) make_glib(0); /* @@ -857,9 +857,9 @@ polymon(int mntmp) * "experience level of you as a monster" for a polymorphed character. */ mlvl = (int) mons[mntmp].mlevel; - if (gy.youmonst.data->mlet == S_DRAGON && mntmp >= PM_GRAY_DRAGON) { + if (u.umonst->data->mlet == S_DRAGON && mntmp >= PM_GRAY_DRAGON) { u.mhmax = In_endgame(&u.uz) ? (8 * mlvl) : (4 * mlvl + d(mlvl, 4)); - } else if (is_golem(gy.youmonst.data)) { + } else if (is_golem(u.umonst->data)) { u.mhmax = golemhp(mntmp); } else { if (!mlvl) @@ -891,7 +891,7 @@ polymon(int mntmp) /* if hiding under something and can't hide anymore, unhide now; but don't auto-hide when not already hiding-under */ if (was_hiding_under) - (void) hideunder(&gy.youmonst); + (void) hideunder(u.umonst); if (u.utrap && u.utraptype == TT_PIT) { set_utrap(rn1(6, 2), TT_PIT); /* time to escape resets */ @@ -904,7 +904,7 @@ polymon(int mntmp) /* you now know what an egg of your type looks like; [moved from below in case expels() -> spoteffects() drops hero onto any eggs] */ - if (lays_eggs(gy.youmonst.data)) { + if (lays_eggs(u.umonst->data)) { learn_egg_type(u.umonnum); /* make queen bees recognize killer bee eggs */ learn_egg_type(egg_type_from_parent(u.umonnum, TRUE)); @@ -914,13 +914,13 @@ polymon(int mntmp) uchar usiz; /* if new form can't be swallowed, make engulfer expel hero */ - if (unsolid(gy.youmonst.data) + if (unsolid(u.umonst->data) /* subset of engulf_target() */ - || (usiz = gy.youmonst.data->msize) >= MZ_HUGE + || (usiz = u.umonst->data->msize) >= MZ_HUGE || (u.ustuck->data->msize < usiz && !is_whirly(u.ustuck->data))) { boolean expels_mesg = TRUE; - if (unsolid(gy.youmonst.data)) { + if (unsolid(u.umonst->data)) { if (canspotmon(u.ustuck)) /* [see below for explanation] */ Strcpy(ustuckNam, Monnam(u.ustuck)); pline("%s can no longer contain you.", ustuckNam); @@ -939,7 +939,7 @@ polymon(int mntmp) /* being held; if now capable of holding, make holder release so that hero doesn't automagically start holding it; or, release if no longer capable of being held */ - && (sticks(gy.youmonst.data) || unsolid(gy.youmonst.data))) { + && (sticks(u.umonst->data) || unsolid(u.umonst->data))) { /* u.ustuck name was saved above in case we're changing from can-see to can't-see; but might have changed from can't-see to can-see so override here if hero knows who u.ustuck is */ @@ -947,7 +947,7 @@ polymon(int mntmp) Strcpy(ustuckNam, Monnam(u.ustuck)); set_ustuck((struct monst *) 0); pline("%s loses its grip on you.", ustuckNam); - } else if (sticking && !sticks(gy.youmonst.data)) { + } else if (sticking && !sticks(u.umonst->data)) { /* was holding onto u.ustuck but no longer capable of that */ uunstick(); } @@ -982,13 +982,13 @@ polymon(int mntmp) buried_ball_to_freedom(); } reset_utrap(TRUE); - } else if (likes_lava(gy.youmonst.data) && u.utrap + } else if (likes_lava(u.umonst->data) && u.utrap && u.utraptype == TT_LAVA) { pline_The("%s now feels soothing.", hliquid("lava")); reset_utrap(TRUE); } - if (amorphous(gy.youmonst.data) || is_whirly(gy.youmonst.data) - || unsolid(gy.youmonst.data)) { + if (amorphous(u.umonst->data) || is_whirly(u.umonst->data) + || unsolid(u.umonst->data)) { if (Punished) { You("slip out of the iron chain."); unpunish(); @@ -998,16 +998,16 @@ polymon(int mntmp) } } if (u.utrap && (u.utraptype == TT_WEB || u.utraptype == TT_BEARTRAP) - && (amorphous(gy.youmonst.data) || is_whirly(gy.youmonst.data) - || unsolid(gy.youmonst.data) - || (gy.youmonst.data->msize <= MZ_SMALL + && (amorphous(u.umonst->data) || is_whirly(u.umonst->data) + || unsolid(u.umonst->data) + || (u.umonst->data->msize <= MZ_SMALL && u.utraptype == TT_BEARTRAP))) { You("are no longer stuck in the %s.", u.utraptype == TT_WEB ? "web" : "bear trap"); /* probably should burn webs too if PM_FIRE_ELEMENTAL */ reset_utrap(TRUE); } - if (webmaker(gy.youmonst.data) && u.utrap && u.utraptype == TT_WEB) { + if (webmaker(u.umonst->data) && u.utrap && u.utraptype == TT_WEB) { You("orient yourself on the web."); reset_utrap(TRUE); } @@ -1031,7 +1031,7 @@ polymon(int mntmp) if (flags.verbose) { static const char use_thec[] = "Use the command #%s to %s."; static const char monsterc[] = "monster"; - struct permonst *uptr = gy.youmonst.data; + struct permonst *uptr = u.umonst->data; boolean might_hide = (is_hider(uptr) || hides_under(uptr)); if (can_breathe(uptr)) @@ -1058,7 +1058,7 @@ polymon(int mntmp) pline(use_thec, monsterc, "emit a mental blast"); if (uptr->msound == MS_SHRIEK) /* worthless, actually */ pline(use_thec, monsterc, "shriek"); - if (is_vampire(uptr) || is_vampshifter(&gy.youmonst)) + if (is_vampire(uptr) || is_vampshifter(u.umonst)) pline(use_thec, monsterc, "change shape"); if (lays_eggs(uptr) && flags.female @@ -1157,7 +1157,7 @@ staticfn void break_armor(void) { struct obj *otmp; - struct permonst *uptr = gy.youmonst.data; + struct permonst *uptr = u.umonst->data; if (breakarm(uptr)) { if ((otmp = uarm) != 0) { @@ -1196,7 +1196,7 @@ break_armor(void) useup(uarmu); } } else if (sliparm(uptr)) { - if ((otmp = uarm) != 0 && racial_exception(&gy.youmonst, otmp) < 1) { + if ((otmp = uarm) != 0 && racial_exception(u.umonst, otmp) < 1) { if (donning(otmp)) cancel_don(); Your("armor falls around you!"); @@ -1313,7 +1313,7 @@ drop_weapon(int alone) * future it might not be so if there are monsters which cannot * wear gloves but can wield weapons */ - if (!alone || cantwield(gy.youmonst.data)) { + if (!alone || cantwield(u.umonst->data)) { candropwep = canletgo(uwep, ""); candropswapwep = !u.twoweap || canletgo(uswapwep, ""); if (alone) { @@ -1355,7 +1355,7 @@ drop_weapon(int alone) if (updateinv) update_inventory(); - } else if (!could_twoweap(gy.youmonst.data)) { + } else if (!could_twoweap(u.umonst->data)) { untwoweapon(); } } @@ -1390,8 +1390,8 @@ rehumanize(void) * reverts to human rather than to vampire. */ - if (emits_light(gy.youmonst.data)) - del_light_source(LS_MONSTER, monst_to_any(&gy.youmonst)); + if (emits_light(u.umonst->data)) + del_light_source(LS_MONSTER, monst_to_any(u.umonst)); polyman("You return to %s form!", gu.urace.adj); if (u.uhp < 1) { @@ -1435,7 +1435,7 @@ dobreathe(void) if (!getdir((char *) 0)) return ECMD_CANCEL; - mattk = attacktype_fordmg(gy.youmonst.data, AT_BREA, AD_ANY); + mattk = attacktype_fordmg(u.umonst->data, AT_BREA, AD_ANY); if (!mattk) impossible("bad breath attack?"); /* mouthwash needed... */ else if (!u.dx && !u.dy && !u.dz) @@ -1453,7 +1453,7 @@ dospit(void) if (!getdir((char *) 0)) return ECMD_CANCEL; - mattk = attacktype_fordmg(gy.youmonst.data, AT_SPIT, AD_ANY); + mattk = attacktype_fordmg(u.umonst->data, AT_SPIT, AD_ANY); if (!mattk) { impossible("bad spit attack?"); } else { @@ -1632,7 +1632,7 @@ dosummon(void) You("call upon your brethren for help!"); exercise(A_WIS, TRUE); - if (!were_summon(gy.youmonst.data, TRUE, &placeholder, (char *) 0)) + if (!were_summon(u.umonst->data, TRUE, &placeholder, (char *) 0)) pline("But none arrive."); return ECMD_TIME; } @@ -1647,8 +1647,8 @@ dogaze(void) uchar adtyp = 0; for (i = 0; i < NATTK; i++) { - if (gy.youmonst.data->mattk[i].aatyp == AT_GAZE) { - adtyp = gy.youmonst.data->mattk[i].adtyp; + if (u.umonst->data->mattk[i].aatyp == AT_GAZE) { + adtyp = u.umonst->data->mattk[i].adtyp; break; } } @@ -1775,8 +1775,8 @@ dogaze(void) int dohide(void) { - boolean ismimic = gy.youmonst.data->mlet == S_MIMIC, - on_ceiling = is_clinger(gy.youmonst.data) || Flying; + boolean ismimic = u.umonst->data->mlet == S_MIMIC, + on_ceiling = is_clinger(u.umonst->data) || Flying; /* can't hide while being held (or holding) or while trapped (except for floor hiders [trapper or mimic] in pits) */ @@ -1785,19 +1785,19 @@ dohide(void) !u.ustuck ? "trapped" : u.uswallow ? (digests(u.ustuck->data) ? "swallowed" : "engulfed") - : !sticks(gy.youmonst.data) ? "being held" + : !sticks(u.umonst->data) ? "being held" : (humanoid(u.ustuck->data) ? "holding someone" : "holding that creature")); if (u.uundetected || (ismimic && U_AP_TYPE != M_AP_NOTHING)) { u.uundetected = 0; - gy.youmonst.m_ap_type = M_AP_NOTHING; + u.umonst->m_ap_type = M_AP_NOTHING; newsym(u.ux, u.uy); } return ECMD_OK; } /* note: hero-as-eel handling is incomplete but unnecessary; such critters aren't offered the option of hiding via #monster */ - if (gy.youmonst.data->mlet == S_EEL && !is_pool(u.ux, u.uy)) { + if (u.umonst->data->mlet == S_EEL && !is_pool(u.ux, u.uy)) { if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)) pline_The("fountain is not deep enough to hide in."); else @@ -1805,7 +1805,7 @@ dohide(void) u.uundetected = 0; return ECMD_OK; } - if (hides_under(gy.youmonst.data)) { + if (hides_under(u.umonst->data)) { long ct = 0L; struct obj *otmp, *otop = svl.level.objects[u.ux][u.uy]; @@ -1846,7 +1846,7 @@ dohide(void) u.uundetected = 0; return ECMD_OK; } - if ((is_hider(gy.youmonst.data) && !Flying) /* floor hider */ + if ((is_hider(u.umonst->data) && !Flying) /* floor hider */ && (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz))) { There("is nowhere to hide beneath you."); u.uundetected = 0; @@ -1863,8 +1863,8 @@ dohide(void) if (ismimic) { /* should bring up a dialog "what would you like to imitate?" */ - gy.youmonst.m_ap_type = M_AP_OBJECT; - gy.youmonst.mappearance = STRANGE_OBJECT; + u.umonst->m_ap_type = M_AP_OBJECT; + u.umonst->mappearance = STRANGE_OBJECT; } else u.uundetected = 1; newsym(u.ux, u.uy); @@ -1875,13 +1875,13 @@ dohide(void) int dopoly(void) { - struct permonst *savedat = gy.youmonst.data; + struct permonst *savedat = u.umonst->data; - if (is_vampire(gy.youmonst.data) || is_vampshifter(&gy.youmonst)) { + if (is_vampire(u.umonst->data) || is_vampshifter(u.umonst)) { polyself(POLY_MONSTER); - if (savedat != gy.youmonst.data) { + if (savedat != u.umonst->data) { You("transform into %s.", - an(pmname(gy.youmonst.data, Ugender))); + an(pmname(u.umonst->data, Ugender))); newsym(u.ux, u.uy); } } @@ -2141,7 +2141,7 @@ mbodypart(struct monst *mon, int part) const char * body_part(int part) { - return mbodypart(&gy.youmonst, part); + return mbodypart(u.umonst, part); } int @@ -2150,7 +2150,7 @@ poly_gender(void) /* Returns gender of polymorphed player; * 0/1=same meaning as flags.female, 2=none. */ - if (is_neuter(gy.youmonst.data) || !humanoid(gy.youmonst.data)) + if (is_neuter(u.umonst->data) || !humanoid(u.umonst->data)) return 2; return flags.female; } @@ -2275,9 +2275,9 @@ udeadinside(void) seems silly when you're polymorphed into something undead; monkilled() distinguishes between living (killed) and non (destroyed) for monster death message; we refine the nonliving aspect a bit */ - return !nonliving(gy.youmonst.data) + return !nonliving(u.umonst->data) ? "dead" /* living, including demons */ - : !weirdnonliving(gy.youmonst.data) + : !weirdnonliving(u.umonst->data) ? "condemned" /* undead plus manes */ : "empty"; /* golems plus vortices */ } diff --git a/src/potion.c b/src/potion.c index d56b64155..3ac39333a 100644 --- a/src/potion.c +++ b/src/potion.c @@ -121,7 +121,7 @@ make_stunned(long xtime, boolean talk) if (u.usteed) You("wobble in the saddle."); else - You("%s...", stagger(gy.youmonst.data, "stagger")); + You("%s...", stagger(u.umonst->data, "stagger")); } } if ((!xtime && old) || (xtime && !old)) @@ -210,9 +210,9 @@ make_slimed(long xtime, const char *msg) dealloc_killer(find_delayed_killer(SLIMED)); /* fake appearance is set late in turn-to-slime countdown */ if (U_AP_TYPE == M_AP_MONSTER - && gy.youmonst.mappearance == PM_GREEN_SLIME) { - gy.youmonst.m_ap_type = M_AP_NOTHING; - gy.youmonst.mappearance = 0; + && u.umonst->mappearance == PM_GREEN_SLIME) { + u.umonst->m_ap_type = M_AP_NOTHING; + u.umonst->mappearance = 0; } } } @@ -284,11 +284,11 @@ make_blinded(long xtime, boolean talk) } else if (old && !xtime) { /* clearing temporary blindness without toggling blindness */ if (talk) { - if (!haseyes(gy.youmonst.data) || PermaBlind) { + if (!haseyes(u.umonst->data) || PermaBlind) { strange_feeling((struct obj *) 0, (char *) 0); } else if (Blindfolded) { eyes = body_part(EYE); - if (eyecount(gy.youmonst.data) != 1) + if (eyecount(u.umonst->data) != 1) eyes = makeplural(eyes); Your(eyemsg, eyes, vtense(eyes, "itch")); } else { /* Eyes of the Overworld */ @@ -310,11 +310,11 @@ make_blinded(long xtime, boolean talk) } else if (!old && xtime) { /* setting temporary blindness without toggling blindness */ if (talk) { - if (!haseyes(gy.youmonst.data) || PermaBlind) { + if (!haseyes(u.umonst->data) || PermaBlind) { strange_feeling((struct obj *) 0, (char *) 0); } else if (Blindfolded) { eyes = body_part(EYE); - if (eyecount(gy.youmonst.data) != 1) + if (eyecount(u.umonst->data) != 1) eyes = makeplural(eyes); Your(eyemsg, eyes, vtense(eyes, "twitch")); } else { /* Eyes of the Overworld */ @@ -397,12 +397,12 @@ make_hallucinated( /* clearing temporary hallucination without toggling vision */ if (!changed && !HHallucination && old && talk) { - if (!haseyes(gy.youmonst.data)) { + if (!haseyes(u.umonst->data)) { strange_feeling((struct obj *) 0, (char *) 0); } else if (Blind) { const char *eyes = body_part(EYE); - if (eyecount(gy.youmonst.data) != 1) + if (eyecount(u.umonst->data) != 1) eyes = makeplural(eyes); Your(eyemsg, eyes, vtense(eyes, "itch")); } else { /* Grayswandir */ @@ -723,7 +723,7 @@ peffect_water(struct obj *otmp) return; } gp.potion_unkn++; - if (mon_hates_blessings(&gy.youmonst) /* undead or demon */ + if (mon_hates_blessings(u.umonst) /* undead or demon */ || u.ualign.type == A_CHAOTIC) { if (otmp->blessed) { pline("This burns like %s!", hliquid("acid")); @@ -731,7 +731,7 @@ peffect_water(struct obj *otmp) if (ismnum(u.ulycn)) { Your("affinity to %s disappears!", makeplural(mons[u.ulycn].pmnames[NEUTRAL])); - if (gy.youmonst.data == &mons[u.ulycn]) + if (u.umonst->data == &mons[u.ulycn]) you_unwere(FALSE); set_ulycn(NON_PM); /* cure lycanthropy */ } @@ -1262,7 +1262,7 @@ peffect_oil(struct obj *otmp) boolean good_for_you = FALSE, vulnerable; if (otmp->lamplit) { - if (likes_fire(gy.youmonst.data)) { + if (likes_fire(u.umonst->data)) { pline("Ahh, a refreshing drink."); good_for_you = TRUE; } else { @@ -1620,12 +1620,12 @@ impact_arti_light( return; } -/* potion obj hits monster mon, which might be youmonst; obj always used up */ +/* potion obj hits monster mon, which might be u.umonst; obj always used up */ void potionhit(struct monst *mon, struct obj *obj, int how) { const char *botlnam = bottlename(); - boolean isyou = (mon == &gy.youmonst); + boolean isyou = (mon == u.umonst); int distance, tx, ty; struct obj *saddle = (struct obj *) 0; boolean hit_saddle = FALSE, your_fault = (how <= POTHIT_HERO_THROW); @@ -1905,7 +1905,7 @@ potionhit(struct monst *mon, struct obj *obj, int how) /* Note: potionbreathe() does its own docall() */ if ((distance == 0 || (distance < 3 && !rn2((1+ACURR(A_DEX))/2))) - && (!breathless(gy.youmonst.data) || haseyes(gy.youmonst.data))) + && (!breathless(u.umonst->data) || haseyes(u.umonst->data))) potionbreathe(obj); else if (obj->dknown && cansee(tx, ty)) trycall(obj); @@ -1950,12 +1950,12 @@ potionbreathe(struct obj *obj) case POT_RESTORE_ABILITY: case POT_GAIN_ABILITY: if (obj->cursed) { - if (!breathless(gy.youmonst.data)) { + if (!breathless(u.umonst->data)) { pline("Ulch! That potion smells terrible!"); - } else if (haseyes(gy.youmonst.data)) { + } else if (haseyes(u.umonst->data)) { const char *eyes = body_part(EYE); - if (eyecount(gy.youmonst.data) != 1) + if (eyecount(u.umonst->data) != 1) eyes = makeplural(eyes); Your("%s %s!", eyes, vtense(eyes, "sting")); } @@ -2079,11 +2079,11 @@ potionbreathe(struct obj *obj) break; case POT_WATER: if (u.umonnum == PM_GREMLIN) { - (void) split_mon(&gy.youmonst, (struct monst *) 0); + (void) split_mon(u.umonst, (struct monst *) 0); } else if (ismnum(u.ulycn)) { /* vapor from [un]holy water will trigger transformation but won't cure lycanthropy */ - if (obj->blessed && gy.youmonst.data == &mons[u.ulycn]) + if (obj->blessed && u.umonst->data == &mons[u.ulycn]) you_unwere(FALSE); else if (obj->cursed && !Upolyd) you_were(); @@ -2427,7 +2427,7 @@ dip_potion_explosion(struct obj *obj, int dmg) pline("%sThey explode!", !Deaf ? "BOOM! " : ""); wake_nearto(u.ux, u.uy, (BOLT_LIM + 1) * (BOLT_LIM + 1)); exercise(A_STR, FALSE); - if (!breathless(gy.youmonst.data) || haseyes(gy.youmonst.data)) + if (!breathless(u.umonst->data) || haseyes(u.umonst->data)) potionbreathe(obj); useupall(obj); losehp(dmg, /* not physical damage */ @@ -2880,10 +2880,10 @@ split_mon( reason[0] = '\0'; if (mtmp) Sprintf(reason, " from %s heat", - (mtmp == &gy.youmonst) ? the_your[1] + (mtmp == u.umonst) ? the_your[1] : (const char *) s_suffix(mon_nam(mtmp))); - if (mon == &gy.youmonst) { + if (mon == u.umonst) { if (u.mh > u.mhmax) /* sanity precaution */ u.mh = u.mhmax; mtmp2 = (u.mh > 1) ? cloneu() : (struct monst *) 0; diff --git a/src/pray.c b/src/pray.c index 55e95e096..c008e3205 100644 --- a/src/pray.c +++ b/src/pray.c @@ -173,7 +173,7 @@ stuck_in_wall(void) if (!isok(x, y) || (IS_OBSTRUCTED(levl[x][y].typ) && (levl[x][y].typ != SDOOR && levl[x][y].typ != SCORR)) - || (blocked_boulder(i, j) && !throws_rocks(gy.youmonst.data))) + || (blocked_boulder(i, j) && !throws_rocks(u.umonst->data))) ++count; } } @@ -229,13 +229,13 @@ in_trouble(void) || stuck_ring(uleft, RIN_LEVITATION) || stuck_ring(uright, RIN_LEVITATION)) return TROUBLE_CURSED_LEVITATION; - if (nohands(gy.youmonst.data) || !freehand()) { + if (nohands(u.umonst->data) || !freehand()) { /* for bag/box access [cf use_container()]... make sure it's a case that we know how to handle; otherwise "fix all troubles" would get stuck in a loop */ if (welded(uwep)) return TROUBLE_UNUSEABLE_HANDS; - if (Upolyd && nohands(gy.youmonst.data) + if (Upolyd && nohands(u.umonst->data) && (!Unchanging || ((otmp = unchanger()) != 0 && otmp->cursed))) return TROUBLE_UNUSEABLE_HANDS; } @@ -494,7 +494,7 @@ fix_worst_trouble(int trouble) fix_curse_trouble(otmp, what); break; } - if (Upolyd && nohands(gy.youmonst.data)) { + if (Upolyd && nohands(u.umonst->data)) { if (!Unchanging) { Your("shape becomes uncertain."); rehumanize(); /* "You return to {normal} form." */ @@ -504,7 +504,7 @@ fix_worst_trouble(int trouble) break; } } - if (nohands(gy.youmonst.data) || !freehand()) + if (nohands(u.umonst->data) || !freehand()) impossible("fix_worst_trouble: couldn't cure hands."); break; case TROUBLE_CURSED_BLINDFOLD: @@ -559,7 +559,7 @@ fix_worst_trouble(int trouble) msgbuf[0] = '\0'; if (Blinded) { - if (eyecount(gy.youmonst.data) != 1) + if (eyecount(u.umonst->data) != 1) eyes = makeplural(eyes); Sprintf(msgbuf, "Your %s %s better", eyes, vtense(eyes, "feel")); u.ucreamed = 0; @@ -735,7 +735,7 @@ angrygods(aligntyp resp_god) (ugod_is_angry() && resp_god == u.ualign.type) ? "hast strayed from the path" : "art arrogant", - gy.youmonst.data->mlet == S_HUMAN ? "mortal" : "creature"); + u.umonst->data->mlet == S_HUMAN ? "mortal" : "creature"); SetVoice((struct monst *) 0, 0, 80, voice_deity); verbalize("Thou must relearn thy lessons!"); (void) adjattrib(A_WIS, -1, FALSE); @@ -767,7 +767,7 @@ angrygods(aligntyp resp_god) : "call upon"); /* [why isn't this using verbalize()?] */ pline("\"Then die, %s!\"", - (gy.youmonst.data->mlet == S_HUMAN) ? "mortal" : "creature"); + (u.umonst->data->mlet == S_HUMAN) ? "mortal" : "creature"); summon_minion(resp_god, FALSE); break; @@ -1224,7 +1224,7 @@ pleased(aligntyp g_align) if (u.uevent.uheard_tune < 1) { godvoice(g_align, (char *) 0); SetVoice((struct monst *) 0, 0, 80, voice_deity); - verbalize("Hark, %s!", is_human(gy.youmonst.data) + verbalize("Hark, %s!", is_human(u.umonst->data) ? "mortal" : "creature"); SetVoice((struct monst *) 0, 0, 80, voice_deity); @@ -1702,7 +1702,7 @@ sacrifice_your_race( { int pm; - if (is_demon(gy.youmonst.data)) { + if (is_demon(u.umonst->data)) { You("find the idea very satisfying."); exercise(A_WIS, TRUE); } else if (u.ualign.type != A_CHAOTIC) { @@ -2128,7 +2128,7 @@ can_pray(boolean praying) /* false means no messages should be given */ gp.p_aligntyp = on_altar() ? a_align(u.ux, u.uy) : u.ualign.type; gp.p_trouble = in_trouble(); - if (is_demon(gy.youmonst.data) /* ok if chaotic or none (Moloch) */ + if (is_demon(u.umonst->data) /* ok if chaotic or none (Moloch) */ && (gp.p_aligntyp == A_LAWFUL || gp.p_aligntyp != A_NEUTRAL)) { if (praying) pline_The("very idea of praying to a %s god is repugnant to you.", @@ -2161,7 +2161,7 @@ can_pray(boolean praying) /* false means no messages should be given */ gp.p_type = 3; } - if (is_undead(gy.youmonst.data) && !Inhell + if (is_undead(u.umonst->data) && !Inhell && (gp.p_aligntyp == A_LAWFUL || (gp.p_aligntyp == A_NEUTRAL && !rn2(10)))) gp.p_type = -1; @@ -2429,7 +2429,7 @@ doturn(void) Gname = halu_gname(u.ualign.type); /* [What about needing free hands (does #turn involve any gesturing)?] */ - if (!can_chant(&gy.youmonst)) { + if (!can_chant(u.umonst)) { /* "evilness": "demons and undead" is too verbose and too precise */ You("are %s upon %s to turn aside evilness.", Strangled ? "not able to call" : "incapable of calling", Gname); @@ -2439,8 +2439,8 @@ doturn(void) return (u.uconduct.gnostic == 1) ? ECMD_TIME : ECMD_OK; } if ((u.ualign.type != A_CHAOTIC - && (is_demon(gy.youmonst.data) - || is_undead(gy.youmonst.data) || is_vampshifter(&gy.youmonst))) + && (is_demon(u.umonst->data) + || is_undead(u.umonst->data) || is_vampshifter(u.umonst))) || u.ugangr > 6) { /* "Die, mortal!" */ pline("For some reason, %s seems to ignore you.", Gname); aggravate(); diff --git a/src/read.c b/src/read.c index b422ee082..e9b98eb31 100644 --- a/src/read.c +++ b/src/read.c @@ -610,7 +610,7 @@ doread(void) } scroll->in_use = TRUE; /* scroll, not spellbook, now being read */ if (otyp != SCR_BLANK_PAPER) { - boolean silently = !can_chant(&gy.youmonst); + boolean silently = !can_chant(u.umonst); /* a few scroll feedback messages describe something happening to the scroll itself, so avoid "it disappears" for those */ @@ -1118,7 +1118,7 @@ seffect_enchant_armor(struct obj **sobjp) schar s; boolean special_armor; boolean same_color; - struct obj *otmp = some_armor(&gy.youmonst); + struct obj *otmp = some_armor(u.umonst); boolean sblessed = sobj->blessed; boolean scursed = sobj->cursed; boolean confused = (Confusion != 0); @@ -1324,7 +1324,7 @@ staticfn void seffect_destroy_armor(struct obj **sobjp) { struct obj *sobj = *sobjp; - struct obj *otmp = some_armor(&gy.youmonst); + struct obj *otmp = some_armor(u.umonst); boolean scursed = sobj->cursed; boolean confused = (Confusion != 0); boolean old_erodeproof, new_erodeproof; @@ -1405,7 +1405,7 @@ seffect_confuse_monster(struct obj **sobjp) altfeedback = (Blind || Invisible); const char *const hands = makeplural(body_part(HAND)); - if (gy.youmonst.data->mlet != S_HUMAN || scursed) { + if (u.umonst->data->mlet != S_HUMAN || scursed) { if (!HConfusion) You_feel("confused."); make_confused(HConfusion + rnd(100), FALSE); @@ -2311,10 +2311,10 @@ drop_boulder_on_player( return; otmp2->quan = confused ? rn1(5, 2) : 1; otmp2->owt = weight(otmp2); - if (!amorphous(gy.youmonst.data) && !Passes_walls - && !noncorporeal(gy.youmonst.data) && !unsolid(gy.youmonst.data)) { + if (!amorphous(u.umonst->data) && !Passes_walls + && !noncorporeal(u.umonst->data) && !unsolid(u.umonst->data)) { You("are hit by %s!", doname(otmp2)); - dmg = (int) (dmgval(otmp2, &gy.youmonst) * otmp2->quan); + dmg = (int) (dmgval(otmp2, u.umonst) * otmp2->quan); if (uarmh && helmet_protects) { if (hard_helmet(uarmh)) { pline("Fortunately, you are wearing a hard helmet."); @@ -2749,9 +2749,9 @@ do_class_genocide(void) kill_genocided_monsters(); update_inventory(); /* eggs & tins */ pline("Wiped out all %s.", nam); - if (Upolyd && vampshifted(&gy.youmonst) + if (Upolyd && vampshifted(u.umonst) /* current shifted form or base vampire form */ - && (i == u.umonnum || i == gy.youmonst.cham)) + && (i == u.umonnum || i == u.umonst->cham)) polyself(POLY_REVERT); /* vampshifter to vampire */ if (Upolyd && i == u.umonnum) { u.mh = -1; @@ -2895,8 +2895,8 @@ do_genocide( } ptr = &mons[mndx]; /* first revert if current shifted form or base vampire form */ - if (Upolyd && vampshifted(&gy.youmonst) - && (mndx == u.umonnum || mndx == gy.youmonst.cham)) + if (Upolyd && vampshifted(u.umonst) + && (mndx == u.umonnum || mndx == u.umonst->cham)) polyself(POLY_REVERT); /* vampshifter (bat, &c) to vampire */ /* Although "genus" is Latin for race, the hero benefits * from both race and role; thus genocide affects either. @@ -2926,7 +2926,7 @@ do_genocide( continue; } /* KMH -- Unchanging prevents rehumanization */ - if (Unchanging && ptr == gy.youmonst.data) + if (Unchanging && ptr == u.umonst->data) killplayer++; break; } @@ -2938,7 +2938,7 @@ do_genocide( if (Hallucination) { /* hallucinate hero's type */ if (Upolyd) { - Strcpy(buf, pmname(gy.youmonst.data, + Strcpy(buf, pmname(u.umonst->data, flags.female ? FEMALE : MALE)); } else { Strcpy(buf, (flags.female && gu.urole.name.f) ? gu.urole.name.f @@ -2981,13 +2981,13 @@ do_genocide( /* Polymorphed characters will die as soon as they're rehumanized. KMH -- Unchanging prevents rehumanization. */ - if (Upolyd && ptr != gy.youmonst.data) { + if (Upolyd && ptr != u.umonst->data) { delayed_killer(POLYMORPH, svk.killer.format, svk.killer.name); You_feel("%s inside.", udeadinside()); } else { done(GENOCIDED); } - } else if (ptr == gy.youmonst.data) { + } else if (ptr == u.umonst->data) { rehumanize(); } kill_genocided_monsters(); @@ -3033,8 +3033,8 @@ punish(struct obj *sobj) uball->owt += WT_IRON_BALL_INCR * (1 + cursed_levy); return; } - if (amorphous(gy.youmonst.data) || is_whirly(gy.youmonst.data) - || unsolid(gy.youmonst.data)) { + if (amorphous(u.umonst->data) || is_whirly(u.umonst->data) + || unsolid(u.umonst->data)) { if (!reuse_ball) { pline("A ball and chain appears, then falls away."); dropy(mkobj(BALL_CLASS, TRUE)); diff --git a/src/region.c b/src/region.c index 796d48fc1..938a3e2bf 100644 --- a/src/region.c +++ b/src/region.c @@ -1092,7 +1092,7 @@ inside_gas_cloud(genericptr_t p1, genericptr_t p2) { NhRegion *reg = (NhRegion *) p1; struct monst *mtmp = (struct monst *) p2; - struct monst *umon = mtmp ? mtmp : &gy.youmonst; + struct monst *umon = mtmp ? mtmp : u.umonst; int dam = reg->arg.a_int; /* @@ -1107,8 +1107,8 @@ inside_gas_cloud(genericptr_t p1, genericptr_t p2) if (dam < 1) return FALSE; /* if no damage then there's nothing to do here... */ - if (!mtmp) { /* hero is indicated by Null rather than by &youmonst */ - if (m_poisongas_ok(&gy.youmonst) == M_POISONGAS_OK) + if (!mtmp) { /* hero is indicated by Null rather than by u.umonst */ + if (m_poisongas_ok(u.umonst) == M_POISONGAS_OK) return FALSE; if (!Blind) { Your("%s sting.", makeplural(body_part(EYE))); @@ -1232,7 +1232,7 @@ create_gas_cloud( probably a natural cause of being polyed. don't message about it */ if (!svc.context.mon_moving && u_at(x, y) && cloudsize == 1 && (!damage - || (damage && m_poisongas_ok(&gy.youmonst) == M_POISONGAS_OK))) + || (damage && m_poisongas_ok(u.umonst) == M_POISONGAS_OK))) inside_cloud = TRUE; if (cloudsize > MAX_CLOUD_SIZE) { @@ -1350,7 +1350,7 @@ region_danger(void) /* the only type of region we understand is gas_cloud */ if (f_indx == INSIDE_GAS_CLOUD) { /* completely harmless if you don't need to breathe */ - if (nonliving(gy.youmonst.data) || Breathless) + if (nonliving(u.umonst->data) || Breathless) continue; /* minor inconvenience if you're poison resistant; not harmful enough to be a prayer-level trouble */ diff --git a/src/restore.c b/src/restore.c index 33066d662..83e2ca546 100644 --- a/src/restore.c +++ b/src/restore.c @@ -22,6 +22,7 @@ staticfn struct fruit *loadfruitchn(NHFILE *); staticfn void freefruitchn(struct fruit *); staticfn void rest_levl(NHFILE *); staticfn void rest_stairs(NHFILE *); +staticfn void rest_u(NHFILE *, boolean); #ifndef SFCTOOL staticfn void ghostfruit(struct obj *); staticfn boolean restgamestate(NHFILE *); @@ -527,11 +528,11 @@ restgamestate(NHFILE *nhfp) int i; struct flag newgameflags; struct context_info newgamecontext; /* all 0, but has some pointers */ - struct obj *bc_obj; - char timebuf[15]; unsigned long uid = 0; + struct obj *bc_obj; + boolean restoring_special = (wizard || discover); #ifndef SFCTOOL - boolean defer_perm_invent, restoring_special; + boolean defer_perm_invent; struct obj *otmp; #endif @@ -583,7 +584,6 @@ restgamestate(NHFILE *nhfp) in the discover case, we don't want to set that for a normal game until after the save file has been removed */ iflags.deferred_X = (newgameflags.explore && !discover); - restoring_special = (wizard || discover); if (newgameflags.debug) { /* authorized by startup code; wizard mode exists and is allowed */ wizard = TRUE, discover = iflags.deferred_X = FALSE; @@ -596,31 +596,9 @@ restgamestate(NHFILE *nhfp) amii_setpens(amii_numcolors); /* use colors from save file */ #endif #endif /* !SFCTOOL */ - Sfi_you(nhfp, &u, "gamestate-you"); - gy.youmonst.cham = u.mcham; + rest_u(nhfp, restoring_special); #ifndef SFCTOOL - if (restoring_special && iflags.explore_error_flag) { - /* savefile has wizard or explore mode, but player is no longer - authorized to access either; can't downgrade mode any further, so - fail restoration. */ - u.uhp = 0; - } -#endif - - Sfi_char(nhfp, timebuf, "gamestate-ubirthday", 14); - timebuf[14] = '\0'; - ubirthday = time_from_yyyymmddhhmmss(timebuf); - Sfi_long(nhfp, &urealtime.realtime, "gamestate-realtime"); - Sfi_char(nhfp, timebuf, "gamestate-start_timing", 14); - timebuf[14] = '\0'; -#ifndef SFCTOOL - urealtime.start_timing = time_from_yyyymmddhhmmss(timebuf); - - /* current time is the time to use for next urealtime.realtime update */ - urealtime.start_timing = getnow(); - - set_uasmon(); #ifdef CLIPPING cliparound(u.ux, u.uy); #endif @@ -638,7 +616,7 @@ restgamestate(NHFILE *nhfp) iflags.perm_invent = defer_perm_invent; flags = newgameflags; svc.context = newgamecontext; - gy.youmonst = cg.zeromonst; + free((genericptr_t) u.umonst), u.umonst = 0; return FALSE; } /* in case hangup save occurred in midst of level change */ @@ -663,7 +641,8 @@ restgamestate(NHFILE *nhfp) setworn(bc_obj, bc_obj->owornmask); bc_obj = nobj; } -#endif +#endif /* !SFCTOOL */ + gm.migrating_objs = restobjchn(nhfp, FALSE); gm.migrating_mons = restmonchn(nhfp); @@ -732,6 +711,43 @@ restgamestate(NHFILE *nhfp) return TRUE; } +void +rest_u(NHFILE *nhfp, boolean restoring_special) +{ + char timebuf[15]; + + Sfi_you(nhfp, &u, "gamestate-you"); +#ifndef SFCTOOL + if (restoring_special && iflags.explore_error_flag) { + /* savefile has wizard or explore mode, but player is no longer + authorized to access either; can't downgrade mode any further, so + fail restoration. */ + u.uhp = 0; + } +#endif + + Sfi_char(nhfp, timebuf, "gamestate-ubirthday", 14); + timebuf[14] = '\0'; + ubirthday = time_from_yyyymmddhhmmss(timebuf); + Sfi_long(nhfp, &urealtime.realtime, "gamestate-realtime"); + Sfi_char(nhfp, timebuf, "gamestate-start_timing", 14); + timebuf[14] = '\0'; +#ifndef SFCTOOL + urealtime.start_timing = time_from_yyyymmddhhmmss(timebuf); + + /* current time is the time to use for next urealtime.realtime update */ + urealtime.start_timing = getnow(); + + u.umonst = newmonst(); + *u.umonst = cg.zeromonst; + u.umonst->cham = u.mcham; + set_uasmon(); +#else + nhUse(restoring_special); +#endif /* !SFCTOOL */ +} + + #ifndef SFCTOOL /* update game state pointers to those valid for the current level (so we don't dereference a wild u.ustuck when saving game state, for instance) */ diff --git a/src/save.c b/src/save.c index fd6dfae2f..a93ae35a4 100644 --- a/src/save.c +++ b/src/save.c @@ -31,6 +31,7 @@ staticfn void save_gamelog(NHFILE *); staticfn void savegamestate(NHFILE *); staticfn void savelev_core(NHFILE *, xint8); staticfn void save_msghistory(NHFILE *); +staticfn void save_u(NHFILE *); staticfn void save_adjust_levelflags(void); #if defined(HANGUPHANDLING) #define HUP if (!program_state.done_hup) @@ -261,6 +262,27 @@ save_gamelog(NHFILE *nhfp) gg.gamelog = NULL; } +staticfn void +save_u(NHFILE *nhfp) +{ + struct monst *save_umonst; + + urealtime.finish_time = getnow(); + urealtime.realtime += timet_delta(urealtime.finish_time, + urealtime.start_timing); + + save_umonst = u.umonst; + u.umonst = (struct monst *) 0; + Sfo_you(nhfp, &u, "gamestate-you"); + u.umonst = save_umonst; + + Sfo_char(nhfp, yyyymmddhhmmss(ubirthday), "gamestate-ubirthday", 14); + Sfo_long(nhfp, &urealtime.realtime, "gamestate-realtime"); + Sfo_char(nhfp, yyyymmddhhmmss(urealtime.start_timing), "gamestate-start_timing", 14); + /* this is the value to use for the next update of urealtime.realtime */ + urealtime.start_timing = urealtime.finish_time; +} + staticfn void savegamestate(NHFILE *nhfp) { @@ -275,17 +297,8 @@ savegamestate(NHFILE *nhfp) Sfo_context_info(nhfp, &svc.context, "gamestate-context"); relative_time_to_moves(&svc.context.seer_turn); relative_time_to_moves(&svc.context.digging.lastdigtime); - Sfo_flag(nhfp, &flags, "gamestate-flags"); - urealtime.finish_time = getnow(); - urealtime.realtime += timet_delta(urealtime.finish_time, - urealtime.start_timing); - Sfo_you(nhfp, &u, "gamestate-you"); - Sfo_char(nhfp, yyyymmddhhmmss(ubirthday), "gamestate-ubirthday", 14); - Sfo_long(nhfp, &urealtime.realtime, "gamestate-realtime"); - Sfo_char(nhfp, yyyymmddhhmmss(urealtime.start_timing), "gamestate-start_timing", 14); - /* this is the value to use for the next update of urealtime.realtime */ - urealtime.start_timing = urealtime.finish_time; + save_u(nhfp); save_killers(nhfp); /* must come before gm.migrating_objs and gm.migrating_mons are freed */ @@ -1171,6 +1184,9 @@ freedynamicdata(void) if (options_set_window_colors_flag) options_free_window_colors(); + if (u.umonst) + free((genericptr_t) u.umonst), u.umonst = 0; + if (glyphid_cache_status()) free_glyphid_cache(); diff --git a/src/shk.c b/src/shk.c index 927352971..69a716df7 100644 --- a/src/shk.c +++ b/src/shk.c @@ -3609,12 +3609,12 @@ append_honorific(char *buf) }; Strcat(buf, honored[rn2(SIZE(honored) - 1) + u.uevent.udemigod]); - if (is_vampire(gy.youmonst.data)) + if (is_vampire(u.umonst->data)) Strcat(buf, (flags.female) ? " dark lady" : " dark lord"); - else if (maybe_polyd(is_elf(gy.youmonst.data), Race_if(PM_ELF))) + else if (maybe_polyd(is_elf(u.umonst->data), Race_if(PM_ELF))) Strcat(buf, (flags.female) ? " hiril" : " hir"); else - Strcat(buf, !is_human(gy.youmonst.data) ? " creature" + Strcat(buf, !is_human(u.umonst->data) ? " creature" : (flags.female) ? " lady" : " sir"); } @@ -5910,7 +5910,7 @@ cad( { const char *res = 0; - switch (is_demon(gy.youmonst.data) ? 3 : poly_gender()) { + switch (is_demon(u.umonst->data) ? 3 : poly_gender()) { case 0: res = "cad"; break; @@ -5929,7 +5929,7 @@ cad( break; } if (altusage) { - char *cadbuf = mon_nam(&gy.youmonst); /* snag an output buffer */ + char *cadbuf = mon_nam(u.umonst); /* snag an output buffer */ /* alternate usage adds a leading double quote and trailing exclamation point plus sentence separating spaces */ diff --git a/src/sit.c b/src/sit.c index 15c16dbdf..8f355d95a 100644 --- a/src/sit.c +++ b/src/sit.c @@ -157,7 +157,7 @@ throne_sit_effect(void) if (!Blind) { Your("vision becomes clear."); } else { - int num_of_eyes = eyecount(gy.youmonst.data); + int num_of_eyes = eyecount(u.umonst->data); const char *eye = body_part(EYE); /* note: 1 eye case won't actually happen--can't @@ -208,7 +208,7 @@ throne_sit_effect(void) break; } } else { - if (is_prince(gy.youmonst.data) || u.uevent.uhand_of_elbereth) + if (is_prince(u.umonst->data) || u.uevent.uhand_of_elbereth) You_feel("very comfortable here."); else You_feel("somehow out of place..."); @@ -325,7 +325,7 @@ special_throne_effect(int effect) { case 11: /* polymorph effect (not blocked by magic resistance, but other things that protect from polymorphs work) */ - if (is_vampire(gy.youmonst.data)) { + if (is_vampire(u.umonst->data)) { You_feel("unworthy."); } else { pline("This throne was not meant for those such as you!"); @@ -368,14 +368,14 @@ lay_an_egg(void) } else if (u.uhunger < (int) objects[EGG].oc_nutrition) { You("don't have enough energy to lay an egg."); return ECMD_OK; - } else if (eggs_in_water(gy.youmonst.data)) { + } else if (eggs_in_water(u.umonst->data)) { if (!(Underwater || Is_waterlevel(&u.uz))) { pline("A splash tetra you are not."); return ECMD_OK; } if (Upolyd - && (gy.youmonst.data == &mons[PM_GIANT_EEL] - || gy.youmonst.data == &mons[PM_ELECTRIC_EEL])) { + && (u.umonst->data == &mons[PM_GIANT_EEL] + || u.umonst->data == &mons[PM_ELECTRIC_EEL])) { You("yearn for the Sargasso Sea."); return ECMD_OK; } @@ -388,7 +388,7 @@ lay_an_egg(void) set_corpsenm(uegg, egg_type_from_parent(u.umonnum, FALSE)); uegg->known = 1; observe_object(uegg); - You("%s an egg.", eggs_in_water(gy.youmonst.data) ? "spawn" : "lay"); + You("%s an egg.", eggs_in_water(u.umonst->data) ? "spawn" : "lay"); dropy(uegg); stackobj(uegg); morehungry((int) objects[EGG].oc_nutrition); @@ -407,7 +407,7 @@ dosit(void) You("are already sitting on %s.", mon_nam(u.usteed)); return ECMD_OK; } - if (u.uundetected && is_hider(gy.youmonst.data) + if (u.uundetected && is_hider(u.umonst->data) && u.umonnum != PM_TRAPPER) /* trapper can stay hidden on floor */ u.uundetected = 0; /* no longer on the ceiling */ @@ -419,7 +419,7 @@ dosit(void) else You("are sitting on air."); return ECMD_OK; - } else if (u.ustuck && !sticks(gy.youmonst.data)) { + } else if (u.ustuck && !sticks(u.umonst->data)) { /* holding monster is next to hero rather than beneath, but hero is in no condition to actually sit at has/her own spot */ if (humanoid(u.ustuck->data)) @@ -440,14 +440,14 @@ dosit(void) struct obj *obj; obj = svl.level.objects[u.ux][u.uy]; - if (gy.youmonst.data->mlet == S_DRAGON && obj->oclass == COIN_CLASS) { + if (u.umonst->data->mlet == S_DRAGON && obj->oclass == COIN_CLASS) { You("coil up around your %shoard.", (obj->quan + money_cnt(gi.invent) < u.ulevel * 1000) ? "meager " : ""); } else if (obj->otyp == TOWEL) { pline("It's probably not a good time for a picnic..."); } else { - if (slithy(gy.youmonst.data)) + if (slithy(u.umonst->data)) You("coil up around %s.", the(xname(obj))); else You("sit on %s.", the(xname(obj))); @@ -503,16 +503,16 @@ dosit(void) dotrap(trap, VIASITTING); } } else if ((Underwater || Is_waterlevel(&u.uz)) - && !eggs_in_water(gy.youmonst.data)) { + && !eggs_in_water(u.umonst->data)) { if (Is_waterlevel(&u.uz)) There("are no cushions floating nearby."); else You("sit down on the muddy bottom."); - } else if (is_pool(u.ux, u.uy) && !eggs_in_water(gy.youmonst.data)) { + } else if (is_pool(u.ux, u.uy) && !eggs_in_water(u.umonst->data)) { in_water: You("sit in the %s.", hliquid("water")); if (Upolyd && u.umonnum == PM_GREMLIN) { - if (split_mon(&gy.youmonst, (struct monst *) 0)) { + if (split_mon(u.umonst, (struct monst *) 0)) { if (levl[u.ux][u.uy].typ == FOUNTAIN) dryup(u.ux, u.uy, TRUE); } @@ -526,7 +526,7 @@ dosit(void) } else if (IS_SINK(typ)) { You(sit_message, defsyms[S_sink].explanation); Your("%s gets wet.", - humanoid(gy.youmonst.data) ? "rump" : "underside"); + humanoid(u.umonst->data) ? "rump" : "underside"); } else if (IS_ALTAR(typ)) { You(sit_message, defsyms[S_altar].explanation); altar_wrath(u.ux, u.uy); @@ -540,7 +540,7 @@ dosit(void) /* must be WWalking */ You(sit_message, hliquid("lava")); burn_away_slime(); - if (likes_lava(gy.youmonst.data)) { + if (likes_lava(u.umonst->data)) { pline_The("%s feels warm.", hliquid("lava")); return ECMD_TIME; } @@ -556,7 +556,7 @@ dosit(void) } else if (IS_THRONE(typ)) { You(sit_message, defsyms[S_throne].explanation); throne_sit_effect(); - } else if (lays_eggs(gy.youmonst.data)) { + } else if (lays_eggs(u.umonst->data)) { return lay_an_egg(); } else { pline("Having fun sitting on the %s?", surface(u.ux, u.uy)); diff --git a/src/sounds.c b/src/sounds.c index 5e4a0e1cd..002cd8854 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -591,7 +591,7 @@ maybe_gasp(struct monst *mon) case MS_VAMPIRE: /* vampire in its own form */ case MS_WERE: /* lycanthrope in human form */ case MS_SPELL: /* titan, barrow wight, Nazgul, nalfeshnee */ - dogasp = (mptr->mlet == gy.youmonst.data->mlet); + dogasp = (mptr->mlet == u.umonst->data->mlet); break; /* capable of speech but don't care if you attack peacefuls */ case MS_BRIBE: @@ -703,7 +703,7 @@ domonnoise(struct monst *mtmp) msound = MS_SELL; /* some normally non-speaking types can/will speak if hero is similar */ else if (msound == MS_ORC - && ((same_race(ptr, gy.youmonst.data) /* current form, */ + && ((same_race(ptr, u.umonst->data) /* current form, */ || same_race(ptr, &mons[Race_switch])) /* unpoly'd form */ || Hallucination)) msound = MS_HUMANOID; @@ -794,12 +794,12 @@ domonnoise(struct monst *mtmp) if (kindred) { verbl_msg = "This is my hunting ground" " that you dare to prowl!"; - } else if (gy.youmonst.data == &mons[PM_SILVER_DRAGON] - || gy.youmonst.data == &mons[PM_BABY_SILVER_DRAGON]) { + } else if (u.umonst->data == &mons[PM_SILVER_DRAGON] + || u.umonst->data == &mons[PM_BABY_SILVER_DRAGON]) { /* Silver dragons are silver in color, not made of silver */ Sprintf(verbuf, "%s! Your silver sheen"" does not frighten me!", - (gy.youmonst.data == &mons[PM_SILVER_DRAGON]) + (u.umonst->data == &mons[PM_SILVER_DRAGON]) ? "Fool" : "Young Fool"); verbl_msg = verbuf; @@ -1107,7 +1107,7 @@ domonnoise(struct monst *mtmp) if (SYSOPT_SEDUCE) { if (ptr->mlet != S_NYMPH - && (could_seduce(mtmp, &gy.youmonst, (struct attack *) 0) + && (could_seduce(mtmp, u.umonst, (struct attack *) 0) == 1)) { (void) doseduce(mtmp); break; @@ -1260,9 +1260,9 @@ dochat(void) int tx, ty; struct obj *otmp; - if (is_silent(gy.youmonst.data)) { + if (is_silent(u.umonst->data)) { pline("As %s, you cannot speak.", - an(pmname(gy.youmonst.data, flags.female ? FEMALE : MALE))); + an(pmname(u.umonst->data, flags.female ? FEMALE : MALE))); return ECMD_OK; } if (Strangled) { @@ -1395,7 +1395,7 @@ dochat(void) return ECMD_OK; } if (Deaf) { - const char *xresponse = humanoid(gy.youmonst.data) + const char *xresponse = humanoid(u.umonst->data) ? "falls on deaf ears" : "is inaudible"; diff --git a/src/spell.c b/src/spell.c index 43c2acd51..4d489a123 100644 --- a/src/spell.c +++ b/src/spell.c @@ -316,7 +316,7 @@ deadbook(struct obj *book2) set_malign(mtmp); } /* next handle the affect on things you're carrying */ - (void) unturn_dead(&gy.youmonst); + (void) unturn_dead(u.umonst); /* last place some monsters around you */ mm.x = u.ux; mm.y = u.uy; @@ -483,7 +483,7 @@ study_book(struct obj *spellbook) if (dullbook > 0) { eyes = body_part(EYE); - if (eyecount(gy.youmonst.data) > 1) + if (eyecount(u.umonst->data) > 1) eyes = makeplural(eyes); pline("This book is so dull that you can't keep your %s open.", eyes); @@ -690,7 +690,7 @@ rejectcasting(void) if (Stunned) { You("are too impaired to cast a spell."); return TRUE; - } else if (!can_chant(&gy.youmonst)) { + } else if (!can_chant(u.umonst)) { You("are unable to chant the incantation."); return TRUE; } else if (!freehand() && !(uwep && uwep->otyp == QUARTERSTAFF)) { diff --git a/src/steal.c b/src/steal.c index fd53ff1b7..1c9fcb305 100644 --- a/src/steal.c +++ b/src/steal.c @@ -79,7 +79,7 @@ stealgold(struct monst *mtmp) whose = s_suffix(y_monnam(who)); what = makeplural(mbodypart(who, FOOT)); } else { - who = &gy.youmonst; + who = u.umonst; whose = "your"; what = makeplural(body_part(FOOT)); } @@ -387,7 +387,7 @@ steal(struct monst *mtmp, char *objnambuf) /* buried ball is not tracked via 'uball' and there is no chain at all (hence no uchain to take off) */ pline("%s takes off your unseen chain.", Monnambuf); - (void) openholdingtrap(&gy.youmonst, &dummy); + (void) openholdingtrap(u.umonst, &dummy); } else if (Blind) { pline("Somebody tries to rob you, but finds nothing to steal."); } else if (inv_cnt(TRUE) > inv_cnt(FALSE)) { diff --git a/src/steed.c b/src/steed.c index 835a8562f..553e1df3a 100644 --- a/src/steed.c +++ b/src/steed.c @@ -68,7 +68,7 @@ use_saddle(struct obj *otmp) char kbuf[BUFSZ]; You("touch %s.", mon_nam(mtmp)); - if (!(poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM))) { + if (!(poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM))) { Sprintf(kbuf, "attempting to saddle %s", an(pmname(mtmp->data, Mgender(mtmp)))); instapetrify(kbuf); @@ -168,8 +168,8 @@ put_saddle_on_mon(struct obj *saddle, struct monst *mtmp) boolean can_ride(struct monst *mtmp) { - return (mtmp->mtame && humanoid(gy.youmonst.data) - && !verysmall(gy.youmonst.data) && !bigmonst(gy.youmonst.data) + return (mtmp->mtame && humanoid(u.umonst->data) + && !verysmall(u.umonst->data) && !bigmonst(u.umonst->data) && (!Underwater || is_swimmer(mtmp->data))); } @@ -238,10 +238,10 @@ mount_steed( return (FALSE); } - if (Upolyd && (!humanoid(gy.youmonst.data) - || verysmall(gy.youmonst.data) - || bigmonst(gy.youmonst.data) - || slithy(gy.youmonst.data))) { + if (Upolyd && (!humanoid(u.umonst->data) + || verysmall(u.umonst->data) + || bigmonst(u.umonst->data) + || slithy(u.umonst->data))) { You("won't fit on a saddle."); return (FALSE); } @@ -545,7 +545,7 @@ landing_spot( kn_trap = i == 0 && ((t = t_at(x, y)) != 0 && t->tseen && t->ttyp != VIBRATING_SQUARE); boulder = i <= 1 && (sobj_at(BOULDER, x, y) - && !throws_rocks(gy.youmonst.data)); + && !throws_rocks(u.umonst->data)); if (!kn_trap && !boulder) { spot->x = x; spot->y = y; @@ -566,7 +566,7 @@ landing_spot( /* If we didn't find a good spot and forceit is on, try enexto(). */ if (forceit && !found) - found = enexto(spot, u.ux, u.uy, gy.youmonst.data); + found = enexto(spot, u.ux, u.uy, u.umonst->data); return found; } diff --git a/src/teleport.c b/src/teleport.c index b235cb238..48fa7da78 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -105,7 +105,7 @@ goodpos( * oh well. */ if (!allow_u) { - if (u_at(x, y) && mtmp != &gy.youmonst + if (u_at(x, y) && mtmp != u.umonst && (mtmp != u.ustuck || !u.uswallow) && (!u.usteed || mtmp != u.usteed)) return FALSE; @@ -133,7 +133,7 @@ goodpos( mdat = mtmp->data; if (is_pool(x, y) && !ignorewater) { /* [what about Breathless?] */ - if (mtmp == &gy.youmonst) + if (mtmp == u.umonst) return (Swimming || Amphibious || (!Is_waterlevel(&u.uz) && !is_waterwall(x, y) @@ -152,11 +152,11 @@ goodpos( that due the effect of the heat causing it to dry out */ if (mdat == &mons[PM_FLOATING_EYE]) return FALSE; - else if (mtmp == &gy.youmonst) + else if (mtmp == u.umonst) return (Levitation || Flying || (Fire_resistance && Wwalking && uarmf && uarmf->oerodeproof) - || (Upolyd && likes_lava(gy.youmonst.data))); + || (Upolyd && likes_lava(u.umonst->data))); else return (m_in_air(mtmp) || likes_lava(mdat)); } @@ -435,7 +435,7 @@ teleok(coordxy x, coordxy y, boolean trapok) if (!trapok) return FALSE; } - if (!goodpos(x, y, &gy.youmonst, 0)) + if (!goodpos(x, y, u.umonst, 0)) return FALSE; if (!tele_jump_ok(u.ux, u.uy, x, y)) return FALSE; @@ -490,9 +490,9 @@ teleds(coordxy nux, coordxy nuy, int teleds_flags) u.ux0 = u.ux; u.uy0 = u.uy; - if (!hideunder(&gy.youmonst) && gy.youmonst.data->mlet == S_MIMIC) { + if (!hideunder(u.umonst) && u.umonst->data->mlet == S_MIMIC) { /* mimics stop being unnoticed */ - gy.youmonst.m_ap_type = M_AP_NOTHING; + u.umonst->m_ap_type = M_AP_NOTHING; } if (was_swallowed) { @@ -816,7 +816,7 @@ tele_to_rnd_pet(void) struct monst *mtmp, *pet = (struct monst *) 0; int cnt = 0; - if (noteleport_level(&gy.youmonst)) { + if (noteleport_level(u.umonst)) { impossible("%s", "attempt to teleport hero to be near a pet" " on no-teleport level"); return; @@ -851,7 +851,7 @@ scrolltele(struct obj *scroll) coord cc; /* Disable teleportation in stronghold && Vlad's Tower */ - if (noteleport_level(&gy.youmonst) && !wizard) { + if (noteleport_level(u.umonst) && !wizard) { pline("A mysterious force prevents you from teleporting!"); if (scroll) learnscroll(scroll); /* this is obviously a teleport scroll */ @@ -1072,7 +1072,7 @@ dotele( int energy = 0; if (!Teleportation || (u.ulevel < (Role_if(PM_WIZARD) ? 8 : 12) - && !can_teleport(gy.youmonst.data))) { + && !can_teleport(u.umonst->data))) { /* Try to use teleport away spell. */ int knownsp = known_spell(SPE_TELEPORT_AWAY); @@ -1257,7 +1257,7 @@ level_tele(void) if (ynq("Go to Nowhere. Are you sure?") != 'y') return; You("%s in agony as your body begins to warp...", - is_silent(gy.youmonst.data) ? "writhe" : "scream"); + is_silent(u.umonst->data) ? "writhe" : "scream"); display_nhwindow(WIN_MESSAGE, FALSE); You("cease to exist."); if (gi.invent) @@ -1499,7 +1499,7 @@ tele_trap(struct trap *trap) return; in_tele_trap = TRUE; - if (In_endgame(&u.uz) || Antimagic || noteleport_level(&gy.youmonst)) { + if (In_endgame(&u.uz) || Antimagic || noteleport_level(u.umonst)) { if (Antimagic) shieldeff(u.ux, u.uy); You_feel("a wrenching sensation."); diff --git a/src/timeout.c b/src/timeout.c index af974c84e..34d11d601 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -142,7 +142,7 @@ stoned_dialogue(void) char buf[BUFSZ]; Strcpy(buf, stoned_texts[SIZE(stoned_texts) - i]); - if (nolimbs(gy.youmonst.data) && strstri(buf, "limbs")) + if (nolimbs(u.umonst->data) && strstri(buf, "limbs")) (void) strsubst(buf, "limbs", "extremities"); urgent_pline("%s", buf); } @@ -232,7 +232,7 @@ vomiting_dialogue(void) break; case 2: txt = vomiting_texts[4]; - if (cantvomit(gy.youmonst.data)) + if (cantvomit(u.umonst->data)) txt = "gag uncontrollably."; else if (Hallucination) /* "hurl" is short for "hurl chunks" which is slang for @@ -241,7 +241,7 @@ vomiting_dialogue(void) break; case 0: stop_occupation(); - if (!cantvomit(gy.youmonst.data)) { + if (!cantvomit(u.umonst->data)) { morehungry(20); /* case 2 used to be "You suddenly vomit!" but it wasn't sudden since you've just been through the earlier messages of the @@ -332,8 +332,8 @@ sickness_dialogue(void) if ((u.usick_type & SICK_NONVOMITABLE) == 0) (void) strsubst(buf, "illness", "sickness"); if (Hallucination && strstri(buf, "Death's door")) { - /* youmonst: for Hallucination, mhe()'s mon argument isn't used */ - Strcpy(pronounbuf, mhe(&gy.youmonst)); + /* u.umonst: for Hallucination, mhe()'s mon argument isn't used */ + Strcpy(pronounbuf, mhe(u.umonst)); Sprintf(eos(buf), " %s %s inviting you in.", /* upstart() modifies its argument but vtense() doesn't care whether or not that has already happened */ @@ -394,8 +394,8 @@ slime_dialogue(void) /* display as green slime during "You have become green slime." but don't worry about not being able to see self; if already mimicking something else at the time, implicitly be revealed */ - gy.youmonst.m_ap_type = M_AP_MONSTER; - gy.youmonst.mappearance = PM_GREEN_SLIME; + u.umonst->m_ap_type = M_AP_MONSTER; + u.umonst->mappearance = PM_GREEN_SLIME; /* no message given when 't' is odd, so no automatic update of self; force one */ newsym(u.ux, u.uy); @@ -405,7 +405,7 @@ slime_dialogue(void) char buf[BUFSZ]; Strcpy(buf, slime_texts[SIZE(slime_texts) - i - 1L]); - if (nolimbs(gy.youmonst.data) && strstri(buf, "limbs")) + if (nolimbs(u.umonst->data) && strstri(buf, "limbs")) (void) strsubst(buf, "limbs", "extremities"); if (strchr(buf, '%')) { @@ -459,7 +459,7 @@ slimed_to_death(struct kinfo *kptr) uchar save_mvflags; /* redundant: polymon() cures sliming when polying into green slime */ - if (Upolyd && gy.youmonst.data == &mons[PM_GREEN_SLIME]) { + if (Upolyd && u.umonst->data == &mons[PM_GREEN_SLIME]) { dealloc_killer(kptr); return; } @@ -485,11 +485,11 @@ slimed_to_death(struct kinfo *kptr) * [formerly implicit] change of form; polymon() takes care of that. * Temporarily ungenocide if necessary. */ - if (emits_light(gy.youmonst.data)) - del_light_source(LS_MONSTER, monst_to_any(&gy.youmonst)); + if (emits_light(u.umonst->data)) + del_light_source(LS_MONSTER, monst_to_any(u.umonst)); save_mvflags = svm.mvitals[PM_GREEN_SLIME].mvflags; svm.mvitals[PM_GREEN_SLIME].mvflags = save_mvflags & ~G_GENOD; - /* become a green slime; also resets youmonst.m_ap_type+.mappearance */ + /* become a green slime; also resets u.umonst.m_ap_type+.mappearance */ (void) polymon(PM_GREEN_SLIME); svm.mvitals[PM_GREEN_SLIME].mvflags = save_mvflags; done_timeout(TURNED_SLIME, SLIMED); @@ -640,8 +640,8 @@ nh_timeout(void) sleep_dialogue(); if (u.mtimedone && !--u.mtimedone) { if (Unchanging) - u.mtimedone = rnd(100 * gy.youmonst.data->mlevel + 1); - else if (is_were(gy.youmonst.data)) + u.mtimedone = rnd(100 * u.umonst->data->mlevel + 1); + else if (is_were(u.umonst->data)) you_unwere(FALSE); /* if polycontrl, asks whether to rehumanize */ else rehumanize(); diff --git a/src/trap.c b/src/trap.c index c6b5d7227..cc62fdd3e 100644 --- a/src/trap.c +++ b/src/trap.c @@ -94,7 +94,7 @@ burnarmor(struct monst *victim) if (!victim) return 0; - hitting_u = (victim == &gy.youmonst); + hitting_u = (victim == u.umonst); /* burning damage may dry wet towel */ item = hitting_u ? carrying(TOWEL) : m_carrying(victim, TOWEL); @@ -190,11 +190,11 @@ erode_obj( if (!otmp) return ER_NOTHING; - victim = carried(otmp) ? &gy.youmonst + victim = carried(otmp) ? u.umonst : mcarried(otmp) ? otmp->ocarry : (struct monst *) 0; - uvictim = (victim == &gy.youmonst); - vismon = victim && (victim != &gy.youmonst) && canseemon(victim); + uvictim = (victim == u.umonst); + vismon = victim && (victim != u.umonst) && canseemon(victim); /* Is gb.bhitpos correct here? Ugh. */ visobj = (!victim && cansee(gb.bhitpos.x, gb.bhitpos.y) && (!is_pool(gb.bhitpos.x, gb.bhitpos.y) @@ -269,7 +269,7 @@ erode_obj( */ if (otmp->oerodeproof) { otmp->rknown = TRUE; - if (victim == &gy.youmonst) + if (victim == u.umonst) update_inventory(); } @@ -294,7 +294,7 @@ erode_obj( else otmp->oeroded2++; - if (victim == &gy.youmonst) + if (victim == u.umonst) update_inventory(); return ER_DAMAGED; @@ -363,15 +363,15 @@ grease_protect( struct monst *victim) { static const char txt[] = "protected by the layer of grease!"; - boolean vismon = victim && (victim != &gy.youmonst) && canseemon(victim); + boolean vismon = victim && (victim != u.umonst) && canseemon(victim); if (ostr) { - if (victim == &gy.youmonst) + if (victim == u.umonst) Your("%s %s %s", ostr, vtense(ostr, "are"), txt); else if (vismon) pline("%s's %s %s %s", Monnam(victim), ostr, vtense(ostr, "are"), txt); - } else if (victim == &gy.youmonst || vismon) { + } else if (victim == u.umonst || vismon) { pline("%s %s", Yobjnam2(otmp, "are"), txt); } if (!rn2(2)) { @@ -634,11 +634,11 @@ fall_through( ; /* KMH -- You can't escape the Sokoban level traps */ } else if (Levitation || u.ustuck || (!Can_fall_thru(&u.uz) && !levl[u.ux][u.uy].candig) - || ((Flying || is_clinger(gy.youmonst.data) - || (ceiling_hider(gy.youmonst.data) && u.uundetected)) + || ((Flying || is_clinger(u.umonst->data) + || (ceiling_hider(u.umonst->data) && u.uundetected)) && !(ftflags & TOOKPLUNGE))) { dont_fall = "don't fall in."; - } else if (gy.youmonst.data->msize >= MZ_HUGE) { + } else if (u.umonst->data->msize >= MZ_HUGE) { dont_fall = "don't fit through."; } else if (!next_to_u()) { dont_fall = "are jerked back by your pet!"; @@ -653,7 +653,7 @@ fall_through( } return; } - if ((Flying || is_clinger(gy.youmonst.data)) + if ((Flying || is_clinger(u.umonst->data)) && (ftflags & TOOKPLUNGE) && td && t) { if (Flying) controlled_flight = TRUE; @@ -890,7 +890,7 @@ animate_statue( delobj(statue); /* avoid hiding under nothing */ - if (u_at(x, y) && Upolyd && hides_under(gy.youmonst.data) + if (u_at(x, y) && Upolyd && hides_under(u.umonst->data) && !OBJ_AT(x, y)) u.uundetected = 0; @@ -974,7 +974,7 @@ mu_maybe_destroy_web( boolean domsg, struct trap *trap) { - boolean isyou = (mtmp == &gy.youmonst); + boolean isyou = (mtmp == u.umonst); struct permonst *mptr = mtmp->data; if (amorphous(mptr) || is_whirly(mptr) || flaming(mptr) @@ -1085,7 +1085,7 @@ floor_trigger(int ttyp) staticfn boolean check_in_air(struct monst *mtmp, unsigned trflags) { - boolean is_you = mtmp == &gy.youmonst, + boolean is_you = mtmp == u.umonst, plunged = (trflags & (TOOKPLUNGE | VIASITTING)) != 0; return ((trflags & HURTLING) != 0 @@ -1195,7 +1195,7 @@ trapeffect_arrow_trap( struct obj *otmp; int dam; - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { if (trap->once && trap->tseen && !rn2(15)) { Soundeffect(se_loud_click, 100); You_hear("a loud click!"); @@ -1207,7 +1207,7 @@ trapeffect_arrow_trap( seetrap(trap); pline("An arrow shoots out at you!"); otmp = t_missile(ARROW, trap); - dam = dmgval(otmp, &gy.youmonst); + dam = dmgval(otmp, u.umonst); if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { ; /* nothing */ } else if (thitu(8, Maybe_Half_Phys(dam), &otmp, "arrow")) { @@ -1256,7 +1256,7 @@ trapeffect_dart_trap( struct obj *otmp; int dam; - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { int oldumort = u.umortality; if (trap->once && trap->tseen && !rn2(15)) { @@ -1272,7 +1272,7 @@ trapeffect_dart_trap( otmp = t_missile(DART, trap); if (!rn2(6)) otmp->opoisoned = 1; - dam = dmgval(otmp, &gy.youmonst); + dam = dmgval(otmp, u.umonst); if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { ; /* nothing */ } else if (thitu(7, Maybe_Half_Phys(dam), &otmp, "little dart")) { @@ -1329,7 +1329,7 @@ trapeffect_rocktrap( struct obj *otmp; boolean harmless = FALSE; - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { if (trap->once && trap->tseen && !rn2(15)) { pline("A trap door in %s opens, but nothing falls out!", the(ceiling(u.ux, u.uy))); @@ -1348,7 +1348,7 @@ trapeffect_rocktrap( if (uarmh) { /* normally passes_rocks() would protect against a falling rock, but not when wearing a helmet */ - if (passes_rocks(gy.youmonst.data)) { + if (passes_rocks(u.umonst->data)) { pline("Unfortunately, you are wearing %s.", an(helm_simple_name(uarmh))); /* helm or hat */ dmg = 2; @@ -1358,7 +1358,7 @@ trapeffect_rocktrap( } else if (flags.verbose) { pline("%s does not protect you.", Yname2(uarmh)); } - } else if (passes_rocks(gy.youmonst.data)) { + } else if (passes_rocks(u.umonst->data)) { pline("It passes harmlessly through you."); harmless = TRUE; } @@ -1415,7 +1415,7 @@ trapeffect_sqky_board( || (trflags & FAILEDUNTRAP) != 0 || (Flying && (trflags & VIASITTING) != 0)); - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { if ((Levitation || Flying) && !forcetrap) { if (!Blind) { seetrap(trap); @@ -1481,7 +1481,7 @@ trapeffect_bear_trap( struct trap *trap, unsigned trflags) { - boolean is_you = mtmp == &gy.youmonst, + boolean is_you = mtmp == u.umonst, forcetrap = ((trflags & FORCETRAP) != 0 || (trflags & FAILEDUNTRAP) != 0 || (is_you && (trflags & VIASITTING) != 0)); @@ -1492,13 +1492,13 @@ trapeffect_bear_trap( if ((Levitation || Flying) && !forcetrap) return Trap_Effect_Finished; feeltrap(trap); - if (amorphous(gy.youmonst.data) || is_whirly(gy.youmonst.data) - || unsolid(gy.youmonst.data)) { + if (amorphous(u.umonst->data) || is_whirly(u.umonst->data) + || unsolid(u.umonst->data)) { pline("%s bear trap closes harmlessly through you.", A_Your[trap->madeby_u]); return Trap_Effect_Finished; } - if (!u.usteed && gy.youmonst.data->msize <= MZ_SMALL) { + if (!u.usteed && u.umonst->data->msize <= MZ_SMALL) { pline("%s bear trap closes harmlessly over you.", A_Your[trap->madeby_u]); return Trap_Effect_Finished; @@ -1565,9 +1565,9 @@ trapeffect_slp_gas_trap( struct trap *trap, unsigned int trflags UNUSED) { - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { seetrap(trap); - if (Sleep_resistance || breathless(gy.youmonst.data)) { + if (Sleep_resistance || breathless(u.umonst->data)) { You("are enveloped in a cloud of gas!"); monstseesu(M_SEEN_SLEEP); } else { @@ -1599,7 +1599,7 @@ trapeffect_rust_trap( { struct obj *otmp, *nextobj; - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { seetrap(trap); /* Unlike monsters, traps cannot aim their rust attacks at @@ -1650,7 +1650,7 @@ trapeffect_rust_trap( You("are covered with rust!"); losehp(Maybe_Half_Phys(dam), "rusting away", KILLED_BY); } else if (u.umonnum == PM_GREMLIN && rn2(3)) { - (void) split_mon(&gy.youmonst, (struct monst *) 0); + (void) split_mon(u.umonst, (struct monst *) 0); } } else { boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); @@ -1732,7 +1732,7 @@ trapeffect_fire_trap( struct trap *trap, unsigned int trflags UNUSED) { - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { seetrap(trap); dofiretrap((struct obj *) 0); } else { @@ -1832,7 +1832,7 @@ trapeffect_pit( set to false if the spikes are found to not be relevant */ boolean relevant_spikes = ttype == SPIKED_PIT; - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { boolean plunged = (trflags & TOOKPLUNGE) != 0; boolean viasitting = (trflags & VIASITTING) != 0; boolean conj_pit = conjoined_pits(trap, t_at(u.ux0, u.uy0), TRUE); @@ -1850,7 +1850,7 @@ trapeffect_pit( if (!Sokoban && (Levitation || (Flying && !plunged && !viasitting))) return Trap_Effect_Finished; feeltrap(trap); - if (!Sokoban && is_clinger(gy.youmonst.data) && !plunged) { + if (!Sokoban && is_clinger(u.umonst->data) && !plunged) { if (already_known) { You_see("%s %spit below you.", a_your[trap->madeby_u], ttype == SPIKED_PIT ? "spiked " : ""); @@ -1946,7 +1946,7 @@ trapeffect_pit( } else { /* plunging flyers take spike damage but not pit damage */ if (!conj_pit && !deliberate - && !(plunged && (Flying || is_clinger(gy.youmonst.data)))) + && !(plunged && (Flying || is_clinger(u.umonst->data)))) losehp(Maybe_Half_Phys(rnd(adj_pit ? 3 : 6)), plunged ? "deliberately plunged into a pit" : "fell into a pit", @@ -2015,7 +2015,7 @@ trapeffect_hole( struct trap *trap, unsigned int trflags) { - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { if (!Can_fall_thru(&u.uz)) { seetrap(trap); /* normally done in fall_through */ impossible("dotrap: %ss cannot exist on this level.", @@ -2072,7 +2072,7 @@ trapeffect_telep_trap( struct trap *trap, unsigned int trflags UNUSED) { - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { seetrap(trap); tele_trap(trap); } else { @@ -2090,7 +2090,7 @@ trapeffect_level_telep( struct trap *trap, unsigned int trflags) { - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { seetrap(trap); level_tele_trap(trap, trflags); } else { @@ -2108,7 +2108,7 @@ trapeffect_web( struct trap *trap, unsigned int trflags) { - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { boolean webmsgok = (trflags & NOWEBMSG) == 0; boolean forcetrap = ((trflags & FORCETRAP) != 0 || (trflags & FAILEDUNTRAP) != 0); @@ -2121,9 +2121,9 @@ trapeffect_web( steed_article = ARTICLE_NONE; feeltrap(trap); - if (mu_maybe_destroy_web(&gy.youmonst, webmsgok, trap)) + if (mu_maybe_destroy_web(u.umonst, webmsgok, trap)) return Trap_Effect_Finished; - if (webmaker(gy.youmonst.data)) { + if (webmaker(u.umonst->data)) { if (webmsgok) pline(trap->madeby_u ? "You take a walk on your web." : "There is a spider web here."); @@ -2281,7 +2281,7 @@ trapeffect_statue_trap( struct trap *trap, unsigned int trflags UNUSED) { - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { (void) activate_statue_trap(trap, u.ux, u.uy, FALSE); } else { /* monsters don't trigger statue traps */ @@ -2295,7 +2295,7 @@ trapeffect_magic_trap( struct trap *trap, unsigned int trflags) { - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { seetrap(trap); if (!rn2(30)) { deltrap(trap); @@ -2332,7 +2332,7 @@ trapeffect_anti_magic( rather than the wearer */ if (shoes->spe > 0) { /* no message if a monster does this, it isn't visible enough */ - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { seetrap(trap); pline("A lethargic aura surrounds %s.", yname(shoes)); costly_alteration(shoes, COST_DECHNT); @@ -2343,7 +2343,7 @@ trapeffect_anti_magic( } } - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { int drain, halfd; boolean exclaim_it = FALSE; @@ -2455,7 +2455,7 @@ trapeffect_poly_trap( struct trap *trap, unsigned int trflags) { - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { boolean viasitting = (trflags & VIASITTING) != 0; int steed_article = ARTICLE_THE; char verbbuf[BUFSZ]; @@ -2537,7 +2537,7 @@ trapeffect_landmine( if (wearing_iron_shoes(mtmp)) damage = (damage + 3) / 4; - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { boolean already_seen = trap->tseen; boolean forcetrap = ((trflags & FORCETRAP) != 0 || (trflags & FAILEDUNTRAP) != 0); @@ -2663,7 +2663,7 @@ trapeffect_rolling_boulder_trap( struct trap *trap, unsigned int trflags UNUSED) { - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { int style = ROLL | (trap->tseen ? LAUNCH_KNOWN : 0); feeltrap(trap); @@ -2715,7 +2715,7 @@ trapeffect_magic_portal( struct trap *trap, unsigned int trflags) { - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { feeltrap(trap); domagicportal(trap); } else { @@ -2730,7 +2730,7 @@ trapeffect_vibrating_square( struct trap *trap, unsigned int trflags UNUSED) { - if (mtmp == &gy.youmonst) { + if (mtmp == u.umonst) { feeltrap(trap); /* messages handled elsewhere; the trap symbol is merely to mark the square for future reference */ @@ -2794,7 +2794,7 @@ immune_to_trap(struct monst *mon, unsigned ttype) return TRAP_NOT_IMMUNE; } pm = mon->data; - is_you = (mon == &gy.youmonst); + is_you = (mon == u.umonst); switch (ttype) { case ARROW_TRAP: @@ -2989,7 +2989,7 @@ trapeffect_selector( return trapeffect_vibrating_square(mtmp, trap, trflags); default: impossible("%s encountered a strange trap of type %d.", - (mtmp == &gy.youmonst) ? "You" : "Some monster", + (mtmp == u.umonst) ? "You" : "Some monster", trap->ttyp); } return Trap_Effect_Finished; @@ -3026,7 +3026,7 @@ dotrap(struct trap *trap, unsigned trflags) trapname(ttype, TRUE)); /* do force "pit" while hallucinating */ /* then proceed to normal trap effect */ } else if (!forcetrap) { - if (floor_trigger(ttype) && check_in_air(&gy.youmonst, trflags)) { + if (floor_trigger(ttype) && check_in_air(u.umonst, trflags)) { if (already_seen) { You("%s over %s %s.", u_locomotion("step"), (ttype == ARROW_TRAP && !trap->madeby_u) @@ -3038,7 +3038,7 @@ dotrap(struct trap *trap, unsigned trflags) if (already_seen && !Fumbling && !undestroyable_trap(ttype) && ttype != ANTI_MAGIC && !forcebungle && !plunged && !conj_pit && !adj_pit - && (!rn2(5) || (is_pit(ttype) && is_clinger(gy.youmonst.data)))) { + && (!rn2(5) || (is_pit(ttype) && is_clinger(u.umonst->data)))) { You("escape %s %s.", (ttype == ARROW_TRAP && !trap->madeby_u) ? "an" : a_your[trap->madeby_u], @@ -3059,7 +3059,7 @@ dotrap(struct trap *trap, unsigned trflags) * would be somewhat harsh for what's usually a minor impairment. */ - (void) trapeffect_selector(&gy.youmonst, trap, trflags); + (void) trapeffect_selector(u.umonst, trap, trflags); } staticfn char * @@ -3398,7 +3398,7 @@ launch_obj( break; } } else if (u_at(x, y)) { - int dam = dmgval(singleobj, &gy.youmonst); + int dam = dmgval(singleobj, u.umonst); if (gm.multi) nomul(0); @@ -3831,7 +3831,7 @@ instapetrify(const char *str) { if (Stone_resistance) return; - if (poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM)) + if (poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM)) return; urgent_pline("You turn to stone..."); svk.killer.format = KILLED_BY; @@ -4071,7 +4071,7 @@ float_down( /* check for falling into pool - added by GAN 10/20/86 */ if (!Flying) { if (!u.uswallow && u.ustuck) { - if (sticks(gy.youmonst.data)) + if (sticks(u.umonst->data)) You("aren't able to maintain your hold on %s.", mon_nam(u.ustuck)); else @@ -4185,14 +4185,14 @@ climb_pit(void) display_nhwindow(WIN_MESSAGE, FALSE); clear_nhwindow(WIN_MESSAGE); You("free your %s.", body_part(LEG)); - } else if ((Flying || is_clinger(gy.youmonst.data)) && !Sokoban) { + } else if ((Flying || is_clinger(u.umonst->data)) && !Sokoban) { /* eg fell in pit, then poly'd to a flying monster; or used '>' to deliberately enter it */ You("%s from the %s.", u_locomotion("climb"), pitname); reset_utrap(FALSE); fill_pit(u.ux, u.uy); gv.vision_full_recalc = 1; /* vision limits change */ - } else if (!(--u.utrap) || m_easy_escape_pit(&gy.youmonst)) { + } else if (!(--u.utrap) || m_easy_escape_pit(u.umonst)) { reset_utrap(FALSE); You("%s to the edge of the %s.", (Sokoban && Levitation) @@ -4289,8 +4289,8 @@ dofiretrap( losehp(num, tower_of_flame, KILLED_BY_AN); /* fire damage */ burn_away_slime(); - if (burnarmor(&gy.youmonst) || rn2(3)) { - (void) destroy_items(&gy.youmonst, AD_FIRE, orig_dmg); + if (burnarmor(u.umonst) || rn2(3)) { + (void) destroy_items(u.umonst, AD_FIRE, orig_dmg); ignite_items(gi.invent); } if (!box && burn_floor_objects(u.ux, u.uy, see_it, TRUE) && !see_it) @@ -4311,7 +4311,7 @@ domagictrap(void) int cnt = rnd(4); /* blindness effects */ - if (!resists_blnd(&gy.youmonst)) { + if (!resists_blnd(u.umonst)) { You("are momentarily blinded by a flash of light!"); make_blinded((long) rn1(5, 10), FALSE); if (!Blind) @@ -4348,7 +4348,7 @@ domagictrap(void) if (!Invis) { if (!Blind) self_invis_message(); - } else if (!EInvis && !pm_invisible(gy.youmonst.data)) { + } else if (!EInvis && !pm_invisible(u.umonst->data)) { if (!Blind) { if (!See_invisible) You("can see yourself again!"); @@ -4379,7 +4379,7 @@ domagictrap(void) if (on_level(&u.uz, &qstart_level)) You_feel( "%slike the prodigal son.", - (flags.female || (Upolyd && is_neuter(gy.youmonst.data))) + (flags.female || (Upolyd && is_neuter(u.umonst->data))) ? "oddly " : ""); else @@ -4610,10 +4610,10 @@ acid_damage(struct obj *obj) if (!obj) return; - victim = carried(obj) ? &gy.youmonst : mcarried(obj) ? obj->ocarry : NULL; - vismon = victim && (victim != &gy.youmonst) && canseemon(victim); + victim = carried(obj) ? u.umonst : mcarried(obj) ? obj->ocarry : NULL; + vismon = victim && (victim != u.umonst) && canseemon(victim); - if (victim == &gy.youmonst && inventory_resistance_check(AD_ACID)) + if (victim == u.umonst && inventory_resistance_check(AD_ACID)) return; if (obj->greased) { @@ -4625,7 +4625,7 @@ acid_damage(struct obj *obj) #endif ) { if (!Blind) { - if (victim == &gy.youmonst) + if (victim == u.umonst) Your("%s.", aobjnam(obj, "fade")); else if (vismon) pline("%s %s.", s_suffix(Monnam(victim)), @@ -4927,13 +4927,13 @@ emergency_disrobe(boolean *lostsome) } /* pick a random goodpos() next to x,y for monster mtmp. - mtmp could be &gy.youmonst, uses then crawl_destination(). + mtmp could be u.umonst, uses then crawl_destination(). returns TRUE if any good position found, with the coord in x,y */ boolean rnd_nextto_goodpos(coordxy *x, coordxy *y, struct monst *mtmp) { int i, j; - boolean is_u = (mtmp == &gy.youmonst); + boolean is_u = (mtmp == u.umonst); coordxy nx, ny, k, dirs[N_DIRS]; for (i = 0; i < N_DIRS; ++i) @@ -5072,7 +5072,7 @@ drown(void) water_damage_chain(gi.invent, FALSE); if (u.umonnum == PM_GREMLIN && rn2(3)) { - (void) split_mon(&gy.youmonst, (struct monst *) 0); + (void) split_mon(u.umonst, (struct monst *) 0); } else if (u.umonnum == PM_IRON_GOLEM) { You("rust!"); i = Maybe_Half_Phys(d(2, 6)); @@ -5110,10 +5110,10 @@ drown(void) gv.vision_full_recalc = 1; return FALSE; } - if ((Teleportation || can_teleport(gy.youmonst.data)) && !Unaware + if ((Teleportation || can_teleport(u.umonst->data)) && !Unaware && (Teleport_control || rn2(3) < Luck + 2)) { You("attempt a teleport spell."); /* utcsri!carroll */ - if (!noteleport_level(&gy.youmonst)) { + if (!noteleport_level(u.umonst)) { (void) dotele(FALSE); if (!is_pool(u.ux, u.uy)) return TRUE; @@ -5136,8 +5136,8 @@ drown(void) x = u.ux, y = u.uy; /* have to be able to move in order to crawl */ - if (gm.multi >= 0 && gy.youmonst.data->mmove - && rnd_nextto_goodpos(&x, &y, &gy.youmonst)) { + if (gm.multi >= 0 && u.umonst->data->mmove + && rnd_nextto_goodpos(&x, &y, u.umonst)) { boolean lost = FALSE; /* time to do some strip-tease... */ boolean succ = Is_waterlevel(&u.uz) ? TRUE : emergency_disrobe(&lost); @@ -5248,10 +5248,10 @@ could_untrap(boolean verbosely, boolean check_floor) buf[0] = '\0'; if (near_capacity() >= HVY_ENCUMBER) { Strcpy(buf, "You're too strained to do that."); - } else if ((nohands(gy.youmonst.data) && !webmaker(gy.youmonst.data)) - || !gy.youmonst.data->mmove) { + } else if ((nohands(u.umonst->data) && !webmaker(u.umonst->data)) + || !u.umonst->data->mmove) { Strcpy(buf, "And just how do you expect to do that?"); - } else if (u.ustuck && sticks(gy.youmonst.data)) { + } else if (u.ustuck && sticks(u.umonst->data)) { Sprintf(buf, "You'll have to let go of %s first.", mon_nam(u.ustuck)); } else if (u.ustuck || (welded(uwep) && bimanual(uwep))) { Sprintf(buf, "Your %s seem to be too busy for that.", @@ -5293,7 +5293,7 @@ untrap_prob( if (u_wield_art(ART_STING) || attacks(AD_FIRE, wep)) chance = 1; /* else chance stays 3 */ - } else if (!webmaker(gy.youmonst.data)) { + } else if (!webmaker(u.umonst->data)) { chance = 7; /* 3.7: used to be 30 */ } } @@ -5444,10 +5444,10 @@ try_disarm( return 0; } /* duplicate tight-space checks from test_move */ - if (u.dx && u.dy && bad_rock(gy.youmonst.data, u.ux, ttmp->ty) - && bad_rock(gy.youmonst.data, ttmp->tx, u.uy)) { + if (u.dx && u.dy && bad_rock(u.umonst->data, u.ux, ttmp->ty) + && bad_rock(u.umonst->data, ttmp->tx, u.uy)) { if ((gi.invent && (inv_weight() + weight_cap() > WT_TOOMUCH_DIAGONAL)) - || bigmonst(gy.youmonst.data)) { + || bigmonst(u.umonst->data)) { /* don't allow untrap if they can't get thru to it */ You("are unable to reach the %s!", trapname(ttype, FALSE)); return 0; @@ -5476,7 +5476,7 @@ try_disarm( } else if (ttype == WEB) { struct trap *ttmp2 = t_at(u.ux, u.uy); - if (!webmaker(gy.youmonst.data) + if (!webmaker(u.umonst->data) /* don't always try to spread the web */ && !rn2(3) /* is there already a trap at hero's spot? @@ -5722,7 +5722,7 @@ help_monster_out( You("grab the trapped %s using your bare %s.", mtmp_pmname, makeplural(body_part(HAND))); - if (poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM)) { + if (poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM)) { display_nhwindow(WIN_MESSAGE, FALSE); } else { char kbuf[BUFSZ]; @@ -5850,7 +5850,7 @@ untrap( /* 'force' is true for #invoke; if carrying MKoT, make it be true for #untrap or autounlock */ - if (!force && has_magic_key(&gy.youmonst)) + if (!force && has_magic_key(u.umonst)) force = TRUE; if (!rx && !container) { @@ -6092,7 +6092,7 @@ openholdingtrap( struct trap *t, tdummy; char buf[BUFSZ], whichbuf[20]; const char *trapdescr = 0, *which = 0; - boolean ishero = (mon == &gy.youmonst); + boolean ishero = (mon == u.umonst); if (!mon) return FALSE; @@ -6200,7 +6200,7 @@ closeholdingtrap( { struct trap *t; unsigned dotrapflags; - boolean ishero = (mon == &gy.youmonst), result; + boolean ishero = (mon == u.umonst), result; if (!mon) return FALSE; @@ -6241,7 +6241,7 @@ openfallingtrap( boolean *noticed) /* set to true iff hero notices the effect; */ { /* otherwise left with its previous value intact */ struct trap *t; - boolean ishero = (mon == &gy.youmonst), result; + boolean ishero = (mon == u.umonst), result; if (!mon) return FALSE; @@ -6437,7 +6437,7 @@ chest_trap( } else { monstunseesu(M_SEEN_ELEC); } - (void) destroy_items(&gy.youmonst, AD_ELEC, orig_dmg); + (void) destroy_items(u.umonst, AD_ELEC, orig_dmg); if (dmg) losehp(dmg, "electric shock", KILLED_BY_AN); break; @@ -6464,7 +6464,7 @@ chest_trap( if (Hallucination) pline("What a groovy feeling!"); else - You("%s%s...", stagger(gy.youmonst.data, "stagger"), + You("%s%s...", stagger(u.umonst->data, "stagger"), Halluc_resistance ? "" : Blind ? " and get dizzy" : " and your vision blurs"); @@ -6791,7 +6791,7 @@ lava_effects(void) } feel_newsym(u.ux, u.uy); /* in case Blind, map the lava here */ burn_away_slime(); - if (likes_lava(gy.youmonst.data)) + if (likes_lava(u.umonst->data)) return FALSE; usurvive = Fire_resistance || (Wwalking && dmg < u.uhp); @@ -6967,7 +6967,7 @@ lava_effects(void) } burn_stuff: - (void) destroy_items(&gy.youmonst, AD_FIRE, dmg); + (void) destroy_items(u.umonst, AD_FIRE, dmg); ignite_items(gi.invent); return FALSE; } diff --git a/src/u_init.c b/src/u_init.c index 2b322b497..1d5a5c80f 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -956,6 +956,9 @@ u_init_misc(void) (void) memset((genericptr_t) &ubirthday, 0, sizeof(ubirthday)); (void) memset((genericptr_t) &urealtime, 0, sizeof(urealtime)); + u.umonst = newmonst(); + *u.umonst = cg.zeromonst; + u.umonst->cham = u.mcham = NON_PM; u.uroleplay = tmpuroleplay; /* restore options set via rcfile */ #if 0 /* documentation of more zero values as desirable */ diff --git a/src/uhitm.c b/src/uhitm.c index 00858508e..eb04e0d1a 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -79,8 +79,8 @@ mhitm_mgc_atk_negated( int armpro; boolean negated; - /* mcan doesn't apply to youmonst; hero can't be cancelled */ - if (magr != &gy.youmonst && magr->mcan) + /* mcan doesn't apply to u.umonst; hero can't be cancelled */ + if (magr != u.umonst && magr->mcan) return TRUE; /* no message if attacker has been cancelled */ armpro = magic_negation(mdef); @@ -88,7 +88,7 @@ mhitm_mgc_atk_negated( if (negated) { /* attack has been thwarted by negation, aka magical cancellation */ if (verbosely) { - if (mdef == &gy.youmonst) + if (mdef == u.umonst) You("avoid harm."); else if (gv.vis && canseemon(mdef)) pline_mon(mdef, "%s avoids harm.", Monnam(mdef)); @@ -375,7 +375,7 @@ find_roll_to_hit( tmp = 1 + abon() + find_mac(mtmp) + u.uhitinc + (sgn(Luck) * ((abs(Luck) + 2) / 3)) - + maybe_polyd(gy.youmonst.data->mlevel, u.ulevel); + + maybe_polyd(u.umonst->data->mlevel, u.ulevel); /* some actions should occur only once during multiple attacks */ if (!(*attk_count)++) { @@ -401,7 +401,7 @@ find_roll_to_hit( tmp += (u.ulevel / 3) + 2; } if (is_orc(mtmp->data) - && maybe_polyd(is_elf(gy.youmonst.data), Race_if(PM_ELF))) + && maybe_polyd(is_elf(u.umonst->data), Race_if(PM_ELF))) tmp++; /* encumbrance: with a lot of luggage, your agility diminishes */ @@ -521,7 +521,7 @@ do_attack(struct monst *mtmp) if (attack_checks(mtmp, uwep)) return TRUE; - if (Upolyd && noattacks(gy.youmonst.data)) { + if (Upolyd && noattacks(u.umonst->data)) { /* certain "pacifist" monsters don't attack */ You("have no way to attack monsters physically."); mtmp->mstrategy &= ~STRAT_WAITMASK; @@ -541,7 +541,7 @@ do_attack(struct monst *mtmp) if (flags.verbose) { if (uwep) You("begin bashing monsters with %s.", yname(uwep)); - else if (!cantwield(gy.youmonst.data)) + else if (!cantwield(u.umonst->data)) You("begin %s monsters with your %s %s.", ing_suffix(Role_if(PM_MONK) ? "strike" : "bash"), uarmg ? "gloved" : "bare", /* Del Lamb */ @@ -565,7 +565,7 @@ do_attack(struct monst *mtmp) if (Upolyd) (void) hmonas(mtmp); else - (void) hitum(mtmp, gy.youmonst.data->mattk); + (void) hitum(mtmp, u.umonst->data->mattk); mtmp->mstrategy &= ~STRAT_WAITMASK; atk_done: @@ -628,7 +628,7 @@ known_hitum( monflee(mon, !rn2(3) ? rnd(100) : 0, FALSE, TRUE); if (u.ustuck == mon && !u.uswallow - && !sticks(gy.youmonst.data)) + && !sticks(u.umonst->data)) set_ustuck((struct monst *) 0); } /* Vorpal Blade hit converted to miss */ @@ -858,7 +858,7 @@ hmon_hitmon_barehands(struct _hitmon_data *hmd, struct monst *mon) spcdmgflg = uarmg ? W_ARMG : (((hmd->twohits == 0 || hmd->twohits == 1) ? W_RINGR : 0L) | ((hmd->twohits == 0 || hmd->twohits == 2) ? W_RINGL : 0L)); - hmd->dmg += special_dmgval(&gy.youmonst, mon, spcdmgflg, &silverhit); + hmd->dmg += special_dmgval(u.umonst, mon, spcdmgflg, &silverhit); /* copy silverhit info back into struct _hitmon_data *hmd */ switch (hmd->twohits) { @@ -1013,7 +1013,7 @@ hmon_hitmon_weapon_melee( } if (obj->oartifact - && artifact_hit(&gy.youmonst, mon, obj, &hmd->dmg, hmd->dieroll)) { + && artifact_hit(u.umonst, mon, obj, &hmd->dmg, hmd->dieroll)) { /* artifact_hit updates 'tmp' but doesn't inflict any damage; however, it might cause carried items to be destroyed and they might do so */ @@ -1265,7 +1265,7 @@ hmon_hitmon_misc_obj( case CREAM_PIE: case BLINDING_VENOM: mon->msleeping = 0; - if (can_blnd(&gy.youmonst, mon, + if (can_blnd(u.umonst, mon, (uchar) ((obj->otyp == BLINDING_VENOM) ? AT_SPIT : AT_WEAP), @@ -1819,7 +1819,7 @@ hmon_hitmon( && thrown != HMON_THROWN && thrown != HMON_KICKED) /* this gives "harmlessly passes through" feedback even when hero doesn't see it happen; presumably sensed by touch? */ - hmd.hittxt = shade_miss(&gy.youmonst, mon, obj, FALSE, TRUE); + hmd.hittxt = shade_miss(u.umonst, mon, obj, FALSE, TRUE); } if (hmd.jousting) { @@ -1925,7 +1925,7 @@ hmon_hitmon( wakeup(mon, TRUE); if (maybe_knockback - && mhitm_knockback(&gy.youmonst, mon, gy.youmonst.data->mattk, + && mhitm_knockback(u.umonst, mon, u.umonst->data->mattk, &hitflags, TRUE)) { if ((hitflags & M_ATTK_DEF_DIED) != 0) hmd.destroyed = TRUE; @@ -2021,7 +2021,7 @@ shade_miss( boolean verbose) { const char *what, *whose, *target; - boolean youagr = (magr == &gy.youmonst), youdef = (mdef == &gy.youmonst); + boolean youagr = (magr == u.umonst), youdef = (mdef == u.umonst); /* we're using dmgval() for zero/not-zero, not for actual damage amount */ if (mdef->data != &mons[PM_SHADE] || (obj && dmgval(obj, mdef))) @@ -2029,7 +2029,7 @@ shade_miss( if (verbose && ((youdef || cansee(mdef->mx, mdef->my) || sensemon(mdef)) - || (magr == &gy.youmonst && m_next2u(mdef)))) { + || (magr == u.umonst && m_next2u(mdef)))) { static const char harmlessly_thru[] = " harmlessly through "; what = (!obj || shade_aware(obj)) ? "attack" : cxname(obj); @@ -2138,7 +2138,7 @@ demonpet(void) pline("Some hell-p has arrived!"); i = !rn2(6) ? ndemon(u.ualign.type) : NON_PM; - pm = i != NON_PM ? &mons[i] : gy.youmonst.data; + pm = i != NON_PM ? &mons[i] : u.umonst->data; if ((dtmp = makemon(pm, u.ux, u.uy, NO_MM_FLAGS)) != 0) (void) tamedog(dtmp, (struct obj *) 0, FALSE); exercise(A_WIS, TRUE); @@ -2152,7 +2152,7 @@ theft_petrifies(struct obj *otmp) return FALSE; #if 0 /* no poly_when_stoned() critter has theft capability */ - if (poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM)) { + if (poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM)) { display_nhwindow(WIN_MESSAGE, FALSE); /* --More-- */ return TRUE; } @@ -2182,7 +2182,7 @@ steal_it(struct monst *mdef, struct attack *mattk) /* look for worn body armor */ ustealo = (struct obj *) 0; - if (could_seduce(&gy.youmonst, mdef, mattk) && mdef->mcanmove) { + if (could_seduce(u.umonst, mdef, mattk) && mdef->mcanmove) { /* find armor, and move it to end of inventory in the process */ minvent_ptr = &mdef->minvent; while ((otmp = *minvent_ptr) != 0) @@ -2206,7 +2206,7 @@ steal_it(struct monst *mdef, struct attack *mattk) but was using hardcoded pronouns She/her for target monster; switch to dynamic pronoun */ if (gender(mdef) == (int) u.mfemale - && gy.youmonst.data->mlet == S_NYMPH) + && u.umonst->data->mlet == S_NYMPH) You("charm %s. %s gladly hands over %s%s possessions.", mon_nam(mdef), upstart(strcpy(heshe, mhe(mdef))), !gold ? "" : "most of ", mhis(mdef)); @@ -2284,7 +2284,7 @@ mhitm_ad_rust( { struct permonst *pd = mdef->data; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (completelyrusts(pd)) { /* iron golem */ /* note: the life-saved case is hypothetical because @@ -2296,7 +2296,7 @@ mhitm_ad_rust( } erode_armor(mdef, ERODE_RUST); mhm->damage = 0; /* damageum(), int tmp */ - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (magr->mcan) { @@ -2308,7 +2308,7 @@ mhitm_ad_rust( rehumanize(); return; } - erode_armor(&gy.youmonst, ERODE_RUST); + erode_armor(u.umonst, ERODE_RUST); } else { /* mhitm */ if (magr->mcan) @@ -2339,11 +2339,11 @@ mhitm_ad_corr( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ erode_armor(mdef, ERODE_CORRODE); mhm->damage = 0; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (magr->mcan) @@ -2366,7 +2366,7 @@ mhitm_ad_dcay( { struct permonst *pd = mdef->data; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (completelyrots(pd)) { /* wood golem or leather golem */ pline("%s %s to pieces!", Monnam(mdef), @@ -2375,7 +2375,7 @@ mhitm_ad_dcay( } erode_armor(mdef, ERODE_ROT); mhm->damage = 0; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (magr->mcan) @@ -2421,12 +2421,12 @@ mhitm_ad_dren( { boolean negated = mhitm_mgc_atk_negated(magr, mdef, FALSE); - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (!negated && !rn2(4)) xdrainenergym(mdef, TRUE); mhm->damage = 0; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (!negated && !rn2(4)) /* 25% chance */ @@ -2446,7 +2446,7 @@ mhitm_ad_drli( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (!rn2(3) && !(resists_drli(mdef) || defended(mdef, AD_DRLI)) && !mhitm_mgc_atk_negated(magr, mdef, TRUE)) { @@ -2476,7 +2476,7 @@ mhitm_ad_drli( /* unlike hitting with Stormbringer, wounded hero doesn't heal any from the drained life */ } - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (!rn2(3) && !Drain_resistance @@ -2525,7 +2525,7 @@ mhitm_ad_fire( struct permonst *pd = mdef->data; const int orig_dmg = mhm->damage; /* damage coming into the function */ - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (mhitm_mgc_atk_negated(magr, mdef, TRUE)) { mhm->damage = 0; @@ -2558,7 +2558,7 @@ mhitm_ad_fire( } mhm->damage += destroy_items(mdef, AD_FIRE, orig_dmg); ignite_items(mdef->minvent); - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (!mhitm_mgc_atk_negated(magr, mdef, TRUE)) { @@ -2577,7 +2577,7 @@ mhitm_ad_fire( monstunseesu(M_SEEN_FIRE); } if ((int) magr->m_lev > rn2(20)) { - (void) destroy_items(&gy.youmonst, AD_FIRE, orig_dmg); + (void) destroy_items(u.umonst, AD_FIRE, orig_dmg); ignite_items(gi.invent); } burn_away_slime(); @@ -2629,7 +2629,7 @@ mhitm_ad_cold( { const int orig_dmg = mhm->damage; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (mhitm_mgc_atk_negated(magr, mdef, TRUE)) { mhm->damage = 0; @@ -2645,7 +2645,7 @@ mhitm_ad_cold( mhm->damage = 0; } mhm->damage += destroy_items(mdef, AD_COLD, orig_dmg); - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (!mhitm_mgc_atk_negated(magr, mdef, TRUE)) { @@ -2658,7 +2658,7 @@ mhitm_ad_cold( monstunseesu(M_SEEN_COLD); } if ((int) magr->m_lev > rn2(20)) - (void) destroy_items(&gy.youmonst, AD_COLD, orig_dmg); + (void) destroy_items(u.umonst, AD_COLD, orig_dmg); } else mhm->damage = 0; } else { @@ -2687,7 +2687,7 @@ mhitm_ad_elec( { const int orig_dmg = mhm->damage; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (mhitm_mgc_atk_negated(magr, mdef, TRUE)) { mhm->damage = 0; @@ -2703,7 +2703,7 @@ mhitm_ad_elec( mhm->damage = 0; } mhm->damage += destroy_items(mdef, AD_ELEC, orig_dmg); - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (!mhitm_mgc_atk_negated(magr, mdef, TRUE)) { @@ -2716,7 +2716,7 @@ mhitm_ad_elec( monstunseesu(M_SEEN_ELEC); } if ((int) magr->m_lev > rn2(20)) - (void) destroy_items(&gy.youmonst, AD_ELEC, orig_dmg); + (void) destroy_items(u.umonst, AD_ELEC, orig_dmg); } else mhm->damage = 0; } else { @@ -2743,11 +2743,11 @@ mhitm_ad_acid( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (resists_acid(mdef) || defended(mdef, AD_ACID)) mhm->damage = 0; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (!magr->mcan && !rn2(3)) @@ -2794,7 +2794,7 @@ mhitm_ad_sgld( struct permonst *pa = magr->data; struct permonst *pd = mdef->data; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ struct obj *mongold = findgold(mdef->minvent); @@ -2812,7 +2812,7 @@ mhitm_ad_sgld( } exercise(A_DEX, TRUE); mhm->damage = 0; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (pd->mlet == pa->mlet) @@ -2860,7 +2860,7 @@ mhitm_ad_tlpt( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (mhm->damage <= 0) mhm->damage = 1; @@ -2881,7 +2881,7 @@ mhitm_ad_tlpt( mhm->damage = mdef->mhp - 1; } } - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ int tmphp; @@ -2961,7 +2961,7 @@ mhitm_ad_blnd( struct monst *mdef, /* defender */ struct mhitm_data *mhm) /* optional for monster vs monster */ { - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (can_blnd(magr, mdef, mattk->aatyp, (struct obj *) 0)) { if (!Blind && mdef->mcansee) @@ -2973,7 +2973,7 @@ mhitm_ad_blnd( mdef->mblinded = mhm->damage; } mhm->damage = 0; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ if (can_blnd(magr, mdef, mattk->aatyp, (struct obj *) 0)) { if (!Blind) @@ -3019,7 +3019,7 @@ mhitm_ad_curs( struct permonst *pa = magr->data; struct permonst *pd = mdef->data; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (night() && !rn2(10) && !mdef->mcan) { if (pd == &mons[PM_CLAY_GOLEM]) { @@ -3034,7 +3034,7 @@ mhitm_ad_curs( } } mhm->damage = 0; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (!night() && pa == &mons[PM_GREMLIN]) @@ -3126,7 +3126,7 @@ mhitm_ad_drst( boolean negated = mhitm_mgc_atk_negated(magr, mdef, FALSE); struct permonst *pa = magr->data; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (!negated && !rn2(8)) { Your("%s was poisoned!", mpoisons_subj(magr, mattk)); @@ -3140,7 +3140,7 @@ mhitm_ad_drst( mhm->damage += rn1(10, 6); } } - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ int ptmp = A_STR; /* A_STR == 0 */ char buf[BUFSZ]; @@ -3182,7 +3182,7 @@ mhitm_ad_drin( * attack and no longer wearing any amulet after the attack. */ - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ struct obj *helmet; @@ -3213,13 +3213,13 @@ mhitm_ad_drin( amu = which_armor(mdef, W_AMUL); lifsav = amu && amu->otyp == AMULET_OF_LIFE_SAVING; - (void) eat_brains(&gy.youmonst, mdef, TRUE, &mhm->damage); + (void) eat_brains(u.umonst, mdef, TRUE, &mhm->damage); /* skip further AD_DRIN if amulet of life-saving got used up */ if (lifsav && !which_armor(mdef, W_AMUL)) gs.skipdrin = TRUE; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (defends(AD_DRIN, uwep) || !has_head(pd)) { @@ -3311,14 +3311,14 @@ mhitm_ad_stck( struct permonst *pd = mdef->data; boolean barbs = (magr->data == &mons[PM_BARBED_DEVIL]); - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (!negated && !sticks(pd) && m_next2u(mdef)) { set_ustuck(mdef); /* it's now stuck to you */ if (barbs) Your("barbs stick to %s!", y_monnam(mdef)); } - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (!negated && !u.ustuck && !sticks(pd)) { @@ -3341,7 +3341,7 @@ mhitm_ad_wrap( struct permonst *pd = mdef->data, *pa = magr->data; boolean coil = slithy(pa) && (pa->mlet == S_SNAKE || pa->mlet == S_NAGA); - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (!sticks(pd)) { boolean tailmiss = !gn.notonhead; @@ -3373,7 +3373,7 @@ mhitm_ad_wrap( } } else mhm->damage = 0; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ if ((!magr->mcan || u.ustuck == magr) && !sticks(pd)) { if (!u.ustuck && !rn2(10)) { @@ -3432,7 +3432,7 @@ mhitm_ad_plys( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (!rn2(3) && mhm->damage < mdef->mhp && !mhitm_mgc_atk_negated(magr, mdef, TRUE)) { @@ -3440,7 +3440,7 @@ mhitm_ad_plys( pline("%s is frozen by you!", Monnam(mdef)); paralyze_monst(mdef, rnd(10)); } - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (gm.multi >= 0 && !rn2(3) @@ -3481,7 +3481,7 @@ mhitm_ad_slee( struct monst *mdef, struct mhitm_data *mhm UNUSED) { - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (!mdef->msleeping && !mhitm_mgc_atk_negated(magr, mdef, FALSE) && sleep_monst(mdef, rnd(10), -1)) { @@ -3489,7 +3489,7 @@ mhitm_ad_slee( pline("%s is put to sleep by you!", Monnam(mdef)); slept_monst(mdef); } - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (gm.multi >= 0 && !rn2(5) @@ -3530,7 +3530,7 @@ mhitm_ad_slim( boolean negated = mhitm_mgc_atk_negated(magr, mdef, FALSE); struct permonst *pd = mdef->data; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (negated) return; /* physical damage only */ @@ -3550,7 +3550,7 @@ mhitm_ad_slim( } mhm->damage = 0; } - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (negated) { @@ -3605,10 +3605,10 @@ mhitm_ad_ench( struct monst *mdef, struct mhitm_data *mhm UNUSED) { - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ /* there's no msomearmor() function, so just do damage */ - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ boolean negated = mhitm_mgc_atk_negated(magr, mdef, FALSE); @@ -3659,7 +3659,7 @@ mhitm_ad_slow( if (defended(mdef, AD_SLOW)) return; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (!negated && mdef->mspeed != MSLOW) { unsigned int oldspeed = mdef->mspeed; @@ -3668,7 +3668,7 @@ mhitm_ad_slow( if (mdef->mspeed != oldspeed && canseemon(mdef)) pline("%s slows down.", Monnam(mdef)); } - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (!negated && HFast && !rn2(4)) @@ -3691,14 +3691,14 @@ mhitm_ad_conf( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (!mdef->mconf) { if (canseemon(mdef)) pline("%s looks confused.", Monnam(mdef)); mdef->mconf = 1; } - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (!magr->mcan && !rn2(4) && !magr->mspec_used) { @@ -3733,7 +3733,7 @@ mhitm_ad_poly( boolean negated = (mhitm_mgc_atk_negated(magr, mdef, FALSE) || magr->mspec_used); - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ /* require weaponless attack in order to honor AD_POLY */ if (!uwep && mhm->damage < mdef->mhp) { @@ -3741,14 +3741,14 @@ mhitm_ad_poly( /* assume that you can tell by touch if blinded */ pline("%s is not transformed.", Monnam(mdef)); } else { - mhm->damage = mon_poly(&gy.youmonst, mdef, mhm->damage); + mhm->damage = mon_poly(u.umonst, mdef, mhm->damage); if (DEADMONSTER(mdef)) mhm->hitflags |= M_ATTK_DEF_DIED; mhm->hitflags |= M_ATTK_HIT; mhm->done = TRUE; } } - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (Maybe_Half_Phys(mhm->damage) < (Upolyd ? u.mh : u.uhp)) { @@ -3756,7 +3756,7 @@ mhitm_ad_poly( if (magr->mcan) You("aren't transformed."); } else { - mhm->damage = mon_poly(magr, &gy.youmonst, mhm->damage); + mhm->damage = mon_poly(magr, u.umonst, mhm->damage); mhm->hitflags |= M_ATTK_HIT; mhm->done = TRUE; } @@ -3781,12 +3781,12 @@ mhitm_ad_famn( { struct permonst *pd = mdef->data; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm; hero can't polymorph into anything with this attack so this won't happen; if it could, it would be the same as the mhitm case except for messaging */ goto mhitm_famn; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ pline_mon(magr, "%s reaches out, and your body shrivels.", Monnam(magr)); @@ -3812,12 +3812,12 @@ mhitm_ad_pest( struct attack alt_attk; struct permonst *pa = magr->data; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm; hero can't polymorph into anything with this attack so this won't happen; if it could, it would be the same as the mhitm case except for messaging */ goto mhitm_pest; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ pline_mon(magr, "%s reaches out, and you feel fever and chills.", Monnam(magr)); @@ -3841,12 +3841,12 @@ mhitm_ad_deth( { struct permonst *pd = mdef->data; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm; hero can't polymorph into anything with this attack so this won't happen; if it could, it would be the same as the mhitm case except for messaging */ goto mhitm_deth; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ pline_mon(magr, "%s reaches out with its deadly touch.", Monnam(magr)); if (is_undead(pd)) { @@ -3901,10 +3901,10 @@ mhitm_ad_halu( { struct permonst *pd = mdef->data; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ mhm->damage = 0; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ mhm->damage = 0; } else { @@ -3924,7 +3924,7 @@ boolean do_stone_u(struct monst *mtmp) { if (!Stoned && !Stone_resistance - && !(poly_when_stoned(gy.youmonst.data) + && !(poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM))) { int kformat = KILLED_BY_AN; const char *kname = pmname(mtmp->data, Mgender(mtmp)); @@ -3985,7 +3985,7 @@ mhitm_ad_phys( struct permonst *pa = magr->data; struct permonst *pd = mdef->data; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (pd == &mons[PM_SHADE]) { mhm->damage = 0; @@ -4018,7 +4018,7 @@ mhitm_ad_phys( mhm->damage = 1; } } - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ if (mattk->aatyp == AT_HUGS && !sticks(pd)) { if (!u.ustuck && rn2(2)) { @@ -4103,7 +4103,7 @@ mhitm_ad_phys( if (cloneu()) You("divide as %s hits you!", mon_nam(magr)); } - rustm(&gy.youmonst, otmp); + rustm(u.umonst, otmp); if (was_poisoned && gm.mhitu_dieroll <= 5) { char buf[BUFSZ]; @@ -4204,12 +4204,12 @@ mhitm_ad_ston( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (!munstone(mdef, TRUE)) minstapetrify(mdef, TRUE); mhm->damage = 0; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (!rn2(3)) { @@ -4268,12 +4268,12 @@ mhitm_ad_were( { struct permonst *pa = magr->data; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ mhitm_ad_phys(magr, mattk, mdef, mhm); if (mhm->done) return; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (!rn2(4) && u.ulycn == NON_PM @@ -4299,12 +4299,12 @@ mhitm_ad_heal( { struct permonst *pd = mdef->data; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ mhitm_ad_phys(magr, mattk, mdef, mhm); if (mhm->done) return; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ /* a cancelled nurse is just an ordinary monster, * nurses don't heal those that cause petrification */ @@ -4391,7 +4391,7 @@ mhitm_ad_stun( { struct permonst *pd = mdef->data; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ if (!Blind) pline("%s %s for a moment.", Monnam(mdef), @@ -4400,7 +4400,7 @@ mhitm_ad_stun( mhitm_ad_phys(magr, mattk, mdef, mhm); if (mhm->done) return; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (!magr->mcan && !rn2(4)) { @@ -4426,7 +4426,7 @@ mhitm_ad_legs( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ #if 0 if (u.ucancelled) { @@ -4437,7 +4437,7 @@ mhitm_ad_legs( mhitm_ad_phys(magr, mattk, mdef, mhm); if (mhm->done) return; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; const char *sidestr = (side == RIGHT_SIDE) ? "right" : "left", @@ -4496,10 +4496,10 @@ mhitm_ad_dgst( { struct permonst *pd = mdef->data; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ mhm->damage = 0; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ mhm->damage = 0; } else { @@ -4571,10 +4571,10 @@ mhitm_ad_samu( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ mhm->damage = 0; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); /* when the Wizard or quest nemesis hits, there's a 1/20 chance @@ -4596,12 +4596,12 @@ mhitm_ad_dise( { struct permonst *pa = magr->data, *pd = mdef->data; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm; hero can't polymorph into anything with this attack so this won't happen; if it could, it would be the same as the mhitm case except for messaging */ goto mhitm_dise; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ hitmsg(magr, mattk); if (!diseasemu(pa)) @@ -4626,11 +4626,11 @@ mhitm_ad_sedu( { struct permonst *pa = magr->data; - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ steal_it(mdef, mattk); mhm->damage = 0; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ char buf[BUFSZ]; @@ -4639,11 +4639,11 @@ mhitm_ad_sedu( if (magr->mcan) return; /* Continue below */ - } else if (dmgtype(gy.youmonst.data, AD_SEDU) + } else if (dmgtype(u.umonst->data, AD_SEDU) /* !SYSOPT_SEDUCE: when hero is attacking and AD_SSEX is disabled, it would be changed to another damage type, but when defending, it remains as-is */ - || dmgtype(gy.youmonst.data, AD_SSEX)) { + || dmgtype(u.umonst->data, AD_SSEX)) { pline_mon(magr, "%s %s.", Monnam(magr), Deaf ? "says something but you can't hear it" : magr->minvent @@ -4751,12 +4751,12 @@ void mhitm_ad_ssex(struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == &gy.youmonst) { + if (magr == u.umonst) { /* uhitm */ mhitm_ad_sedu(magr, mattk, mdef, mhm); if (mhm->done) return; - } else if (mdef == &gy.youmonst) { + } else if (mdef == u.umonst) { /* mhitu */ if (SYSOPT_SEDUCE) { if (could_seduce(magr, mdef, mattk) == 1 && !magr->mcan) @@ -4845,13 +4845,13 @@ damageum( mhm.specialdmg = specialdmg; mhm.done = FALSE; - if (is_demon(gy.youmonst.data) && !rn2(13) && !uwep + if (is_demon(u.umonst->data) && !rn2(13) && !uwep && u.umonnum != PM_AMOROUS_DEMON && u.umonnum != PM_BALROG) { demonpet(); return M_ATTK_MISS; } - mhitm_adtyping(&gy.youmonst, mattk, mdef, &mhm); + mhitm_adtyping(u.umonst, mattk, mdef, &mhm); if (mhm.done) return mhm.hitflags; @@ -4930,12 +4930,12 @@ explum(struct monst *mdef, struct attack *mattk) staticfn void start_engulf(struct monst *mdef) { - boolean u_digest = digests(gy.youmonst.data), - u_enfold = enfolds(gy.youmonst.data); + boolean u_digest = digests(u.umonst->data), + u_enfold = enfolds(u.umonst->data); if (!Invisible) { map_location(u.ux, u.uy, TRUE); - tmp_at(DISP_ALWAYS, mon_to_glyph(&gy.youmonst, rn2_on_display_rng)); + tmp_at(DISP_ALWAYS, mon_to_glyph(u.umonst, rn2_on_display_rng)); tmp_at(mdef->mx, mdef->my); } You("%s %s%s!", @@ -4961,8 +4961,8 @@ gulpum(struct monst *mdef, struct attack *mattk) int tmp; int dam = d((int) mattk->damn, (int) mattk->damd); boolean fatal_gulp, - u_digest = digests(gy.youmonst.data), - u_enfold = enfolds(gy.youmonst.data); + u_digest = digests(u.umonst->data), + u_enfold = enfolds(u.umonst->data); struct obj *otmp; struct permonst *pd = mdef->data; const char *expel_verb = u_digest ? "regurgitate" @@ -4977,11 +4977,11 @@ gulpum(struct monst *mdef, struct attack *mattk) * after exactly 1 round of attack otherwise. -KAA */ - if (!engulf_target(&gy.youmonst, mdef)) + if (!engulf_target(u.umonst, mdef)) return M_ATTK_MISS; if (!(u_digest && u.uhunger >= 1500) && !u.uswallow) { - if (!flaming(gy.youmonst.data)) { + if (!flaming(u.umonst->data)) { for (otmp = mdef->minvent; otmp; otmp = otmp->nobj) (void) snuff_lit(otmp); } @@ -5060,14 +5060,14 @@ gulpum(struct monst *mdef, struct attack *mattk) "you totally digest " will be coming soon (after several turns) but the level-gain message seems out of order if the kill message is left implicit */ - gm.mswallower = &gy.youmonst; + gm.mswallower = u.umonst; xkilled(mdef, XKILL_GIVEMSG | XKILL_NOCORPSE); if (!DEADMONSTER(mdef)) { /* monster lifesaved */ You("hurriedly regurgitate the sizzling in your %s.", body_part(STOMACH)); } else { tmp = 1 + (pd->cwt >> 8); - if (corpse_chance(mdef, &gy.youmonst, TRUE) + if (corpse_chance(mdef, u.umonst, TRUE) && !(svm.mvitals[monsndx(pd)].mvflags & G_NOCORPSE)) { /* nutrition only if there can be a corpse */ u.uhunger += (pd->cnutrit + 1) / 2; @@ -5105,7 +5105,7 @@ gulpum(struct monst *mdef, struct attack *mattk) end_engulf(); return M_ATTK_DEF_DIED; case AD_PHYS: - if (gy.youmonst.data == &mons[PM_FOG_CLOUD]) { + if (u.umonst->data == &mons[PM_FOG_CLOUD]) { pline("%s is laden with your moisture.", Monnam(mdef)); if ((breathless(pd) || amphibious(pd)) && !flaming(pd)) { dam = 0; @@ -5113,7 +5113,7 @@ gulpum(struct monst *mdef, struct attack *mattk) } } else { pline("%s is %s!", Monnam(mdef), - enfolds(gy.youmonst.data) ? "being squashed" + enfolds(u.umonst->data) ? "being squashed" : "pummeled with your debris"); } break; @@ -5125,7 +5125,7 @@ gulpum(struct monst *mdef, struct attack *mattk) } break; case AD_BLND: - if (can_blnd(&gy.youmonst, mdef, mattk->aatyp, + if (can_blnd(u.umonst, mdef, mattk->aatyp, (struct obj *) 0)) { if (mdef->mcansee) pline("%s can't see in there!", Monnam(mdef)); @@ -5185,7 +5185,7 @@ gulpum(struct monst *mdef, struct attack *mattk) return M_ATTK_DEF_DIED; } You("%s %s!", expel_verb, mon_nam(mdef)); - if ((Slow_digestion || is_animal(gy.youmonst.data)) && u_digest) { + if ((Slow_digestion || is_animal(u.umonst->data)) && u_digest) { pline("Obviously, you didn't like %s taste.", s_suffix(mon_nam(mdef))); } @@ -5203,7 +5203,7 @@ missum( if (wouldhavehit) /* monk is missing due to penalty for wearing suit */ Your("armor is rather cumbersome..."); - if (could_seduce(&gy.youmonst, mdef, mattk)) + if (could_seduce(u.umonst, mdef, mattk)) You("pretend to be friendly to %s.", mon_nam(mdef)); else if (canspotmon(mdef) && flags.verbose) You("miss %s.", mon_nam(mdef)); @@ -5217,7 +5217,7 @@ missum( boolean m_is_steadfast(struct monst *mtmp) { - boolean is_u = (mtmp == &gy.youmonst); + boolean is_u = (mtmp == u.umonst); struct obj *otmp = is_u ? uwep : MON_WEP(mtmp); /* must be on the ground (or in water) */ @@ -5231,7 +5231,7 @@ m_is_steadfast(struct monst *mtmp) return TRUE; /* steadfast if carrying any loadstone (and not floating or flying); - 'is_u' test not needed here; m_carrying() is 'youmonst' aware */ + 'is_u' test not needed here; m_carrying() is 'u.umonst' aware */ if (m_carrying(mtmp, LOADSTONE)) return TRUE; /* when mounted and steed is target of knockback, check the rider for @@ -5257,8 +5257,8 @@ mhitm_knockback( coordxy dx, dy, defx, defy; int knockdistance = rn2(3) ? 1 : 2; /* 67%: 1 step, 33%: 2 steps */ int chance = 6; /* 1/6 chance of attack knocking back a monster */ - boolean u_agr = (magr == &gy.youmonst); - boolean u_def = (mdef == &gy.youmonst); + boolean u_agr = (magr == u.umonst); + boolean u_def = (mdef == u.umonst); boolean was_u = FALSE, dismount = FALSE; struct obj *wep = weapon_used ? (u_agr ? uwep : MON_WEP(magr)) : (struct obj *) 0; @@ -5438,7 +5438,7 @@ hmonas(struct monst *mon) whether silver ring causes successful hit */ for (i = 0; i < NATTK; i++) { sum[i] = M_ATTK_MISS; - mattk = getmattk(&gy.youmonst, mon, i, sum, &alt_attk); + mattk = getmattk(u.umonst, mon, i, sum, &alt_attk); if (mattk->aatyp == AT_WEAP) ++multi_weap; if (mattk->aatyp == AT_WEAP @@ -5460,7 +5460,7 @@ hmonas(struct monst *mon) || DEADMONSTER(mon))) continue; - mattk = getmattk(&gy.youmonst, mon, i, sum, &alt_attk); + mattk = getmattk(u.umonst, mon, i, sum, &alt_attk); if (gs.skipdrin && mattk->aatyp == AT_TENT && mattk->adtyp == AD_DRIN) continue; weapon = 0; @@ -5546,17 +5546,17 @@ hmonas(struct monst *mon) sum[i] = damageum(mon, mattk, 0); break; case AT_CLAW: - if (uwep && !cantwield(gy.youmonst.data) && !weapon_used) + if (uwep && !cantwield(u.umonst->data) && !weapon_used) goto use_weapon; FALLTHROUGH; /*FALLTHRU*/ case AT_TUCH: - if (uwep && gy.youmonst.data->mlet == S_LICH && !weapon_used) + if (uwep && u.umonst->data->mlet == S_LICH && !weapon_used) goto use_weapon; FALLTHROUGH; /*FALLTHRU*/ case AT_KICK: - if (mattk->aatyp == AT_KICK && mtrapped_in_pit(&gy.youmonst)) + if (mattk->aatyp == AT_KICK && mtrapped_in_pit(u.umonst)) continue; FALLTHROUGH; /*FALLTHRU*/ @@ -5576,7 +5576,7 @@ hmonas(struct monst *mon) const char *verb = 0; /* verb or body part */ if (!u.uswallow - && (compat = could_seduce(&gy.youmonst, mon, mattk)) + && (compat = could_seduce(u.umonst, mon, mattk)) != 0) { You("%s %s %s.", (mon->mcansee && haseyes(mon->data)) ? "smile at" @@ -5604,7 +5604,7 @@ hmonas(struct monst *mon) {bite,claw,claw} instead of {claw,claw,bite} doesn't make poly'd hero mysteriously switch handedness */ odd_claw = !odd_claw; - specialdmg = special_dmgval(&gy.youmonst, mon, + specialdmg = special_dmgval(u.umonst, mon, W_ARMG | ((odd_claw || !multi_claw) ? W_RINGL : 0L) @@ -5619,7 +5619,7 @@ hmonas(struct monst *mon) break; case AT_KICK: verb = "kick"; - specialdmg = special_dmgval(&gy.youmonst, mon, W_ARMF, + specialdmg = special_dmgval(u.umonst, mon, W_ARMF, &silverhit); break; case AT_BUTT: @@ -5627,7 +5627,7 @@ hmonas(struct monst *mon) /* hypothetical; if any form with a head-butt attack could wear a helmet, it would hit shades when wearing a blessed (or silver) one */ - specialdmg = special_dmgval(&gy.youmonst, mon, W_ARMH, + specialdmg = special_dmgval(u.umonst, mon, W_ARMH, &silverhit); break; case AT_BITE: @@ -5649,7 +5649,7 @@ hmonas(struct monst *mon) } else { /* either not a shade or no special silver/blessed damage, other unsolid monsters are immune to AT_TUCH+AD_WRAP */ - if (failed_grab(&gy.youmonst, mon, mattk)) + if (failed_grab(u.umonst, mon, mattk)) break; /* miss; message already given */ if (mattk->aatyp == AT_TENT) { @@ -5659,7 +5659,7 @@ hmonas(struct monst *mon) verb = "hit"; /* not "claws" */ You("%s %s.", verb, mon_nam(mon)); if (silverhit && flags.verbose) - silver_sears(&gy.youmonst, mon, silverhit); + silver_sears(u.umonst, mon, silverhit); } sum[i] = damageum(mon, mattk, specialdmg); } @@ -5694,7 +5694,7 @@ hmonas(struct monst *mon) wakeup(mon, TRUE); /* choking hug/throttling grab uses hands (gloves or rings); normal hug uses outermost of cloak/suit/shirt */ - specialdmg = special_dmgval(&gy.youmonst, mon, + specialdmg = special_dmgval(u.umonst, mon, byhand ? (W_ARMG | W_RINGL | W_RINGR) : (W_ARMC | W_ARM | W_ARMU), &silverhit); @@ -5723,7 +5723,7 @@ hmonas(struct monst *mon) if (specialdmg) { You("%s %s%s", verb, mon_nam(mon), exclam(specialdmg)); if (silverhit && flags.verbose) - silver_sears(&gy.youmonst, mon, silverhit); + silver_sears(u.umonst, mon, silverhit); sum[i] = damageum(mon, mattk, specialdmg); } else { Your("%s passes harmlessly through %s.", @@ -5732,7 +5732,7 @@ hmonas(struct monst *mon) break; } /* can't grab unsolid creatures (checked after shade handling) */ - if (failed_grab(&gy.youmonst, mon, mattk)) + if (failed_grab(u.umonst, mon, mattk)) break; /* hug attack against ordinary foe */ if (mon == u.ustuck) { @@ -5741,7 +5741,7 @@ hmonas(struct monst *mon) /* extra feedback for non-breather being choked */ unconcerned ? " but doesn't seem concerned" : ""); if (silverhit && flags.verbose) - silver_sears(&gy.youmonst, mon, silverhit); + silver_sears(u.umonst, mon, silverhit); sum[i] = damageum(mon, mattk, specialdmg); } else if (i >= 2 && (sum[i - 1] > M_ATTK_MISS) && (sum[i - 2] > M_ATTK_MISS)) { @@ -5753,7 +5753,7 @@ hmonas(struct monst *mon) You("grab %s!", mon_nam(mon)); set_ustuck(mon); if (silverhit && flags.verbose) - silver_sears(&gy.youmonst, mon, silverhit); + silver_sears(u.umonst, mon, silverhit); sum[i] = damageum(mon, mattk, specialdmg); } break; /* AT_HUGS */ @@ -5776,7 +5776,7 @@ hmonas(struct monst *mon) if (mon->data == &mons[PM_SHADE]) { /* no specialdmg check needed */ Your("attempt to surround %s is harmless.", mon_nam(mon)); - } else if (failed_grab(&gy.youmonst, mon, mattk)) { + } else if (failed_grab(u.umonst, mon, mattk)) { ; /* non-shade miss; message already given */ } else { sum[i] = gulpum(mon, mattk); @@ -5797,9 +5797,9 @@ hmonas(struct monst *mon) /* No check for uwep; if wielding nothing we want to * do the normal 1-2 points bare hand damage... */ - if ((gy.youmonst.data->mlet == S_KOBOLD - || gy.youmonst.data->mlet == S_ORC - || gy.youmonst.data->mlet == S_GNOME) && !weapon_used) + if ((u.umonst->data->mlet == S_KOBOLD + || u.umonst->data->mlet == S_ORC + || u.umonst->data->mlet == S_GNOME) && !weapon_used) goto use_weapon; FALLTHROUGH; /*FALLTHRU*/ @@ -5830,7 +5830,7 @@ hmonas(struct monst *mon) mattk->aatyp, FALSE); } - if (mhitm_knockback(&gy.youmonst, mon, mattk, &sum[i], weapon_used)) + if (mhitm_knockback(u.umonst, mon, mattk, &sum[i], weapon_used)) break; /* don't use sum[i] beyond this point; @@ -5918,7 +5918,7 @@ passive( monstseesu(M_SEEN_ACID); } if (!rn2(30)) - erode_armor(&gy.youmonst, ERODE_CORRODE); + erode_armor(u.umonst, ERODE_CORRODE); } if (mhitb && weapon) { if (aatyp == AT_KICK) { @@ -5947,7 +5947,7 @@ passive( || (protector == W_ARMH && !uarmh) || (protector == (W_ARMC | W_ARMG) && (!uarmc || !uarmg))) { if (!Stone_resistance - && !(poly_when_stoned(gy.youmonst.data) + && !(poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM))) { done_in_by(mon, STONING); /* "You turn to stone..." */ return M_ATTK_DEF_DIED; @@ -6079,7 +6079,7 @@ passive( healmon(mon, (tmp + rn2(2)) / 2, (tmp + 1) / 2); /* at a certain point, the monster will reproduce! */ if (mon->mhpmax > (((int) mon->m_lev) + 1) * 8) - (void) split_mon(mon, &gy.youmonst); + (void) split_mon(mon, u.umonst); } break; case AD_STUN: /* specifically yellow mold */ diff --git a/src/vault.c b/src/vault.c index 90157b7fa..ef4065805 100644 --- a/src/vault.c +++ b/src/vault.c @@ -466,18 +466,18 @@ invault(void) } if (U_AP_TYPE == M_AP_OBJECT || u.uundetected) { if (U_AP_TYPE == M_AP_OBJECT - && gy.youmonst.mappearance != GOLD_PIECE) + && u.umonst->mappearance != GOLD_PIECE) if (!Deaf) { SetVoice(guard, 0, 80, 0); verbalize("Hey! Who left that %s in here?", - mimic_obj_name(&gy.youmonst)); + mimic_obj_name(u.umonst)); } /* You're mimicking some object or you're hidden. */ pline("Puzzled, %s turns around and leaves.", mhe(guard)); mongone(guard); return; } - if (Strangled || is_silent(gy.youmonst.data) || gm.multi < 0) { + if (Strangled || is_silent(u.umonst->data) || gm.multi < 0) { /* [we ought to record whether this message has already been given in order to vary it upon repeat visits, but discarding the monster and its egd data renders that hard] */ @@ -1065,7 +1065,7 @@ gd_move(struct monst *grd) } if (um_dist(grd->mx, grd->my, 1) || egrd->gddone) { if (!egrd->gddone && !rn2(10) && !Deaf && !u.uswallow - && !(u.ustuck && !sticks(gy.youmonst.data))) { + && !(u.ustuck && !sticks(u.umonst->data))) { SetVoice(grd, 0, 80, 0); verbalize("Move along!"); } diff --git a/src/weapon.c b/src/weapon.c index 81da05613..b400ac91c 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -405,7 +405,7 @@ special_dmgval( } /* when no gloves we check for silver rings (blessed rings ignored) */ - } else if ((left_ring || right_ring) && magr == &gy.youmonst) { + } else if ((left_ring || right_ring) && magr == u.umonst) { if (left_ring && uleft) { if (objects[uleft->otyp].oc_material == SILVER && mon_hates_silver(mdef)) { diff --git a/src/were.c b/src/were.c index 59197177f..df6ebc15c 100644 --- a/src/were.c +++ b/src/were.c @@ -218,12 +218,12 @@ you_unwere(boolean purify) You_feel("purified."); set_ulycn(NON_PM); /* cure lycanthropy */ } - if (!Unchanging && is_were(gy.youmonst.data) + if (!Unchanging && is_were(u.umonst->data) && !monster_nearby() && (!controllable_poly || !paranoid_query(ParanoidWerechange, "Remain in beast form?"))) rehumanize(); - else if (is_were(gy.youmonst.data) && !u.mtimedone) + else if (is_were(u.umonst->data) && !u.mtimedone) u.mtimedone = rn1(200, 200); /* 40% of initial were change */ } diff --git a/src/wield.c b/src/wield.c index 21aad53c4..b6fbdc83a 100644 --- a/src/wield.c +++ b/src/wield.c @@ -158,7 +158,7 @@ const char * empty_handed(void) { return uarmg ? "empty handed" /* gloves imply hands */ - : humanoid(gy.youmonst.data) + : humanoid(u.umonst->data) /* hands but no weapon and no gloves */ ? "bare handed" /* alternate phrasing for paws or lack of hands */ @@ -360,7 +360,7 @@ dowield(void) /* May we attempt this? */ gm.multi = 0; - if (cantwield(gy.youmonst.data)) { + if (cantwield(u.umonst->data)) { pline("Don't be ridiculous!"); return ECMD_FAIL; } @@ -465,7 +465,7 @@ doswapweapon(void) /* May we attempt this? */ gm.multi = 0; - if (cantwield(gy.youmonst.data)) { + if (cantwield(u.umonst->data)) { pline("Don't be ridiculous!"); return ECMD_FAIL; } @@ -716,7 +716,7 @@ wield_tool(struct obj *obj, } return FALSE; } - if (cantwield(gy.youmonst.data)) { + if (cantwield(u.umonst->data)) { You_cant("hold %s strongly enough.", more_than_1 ? "them" : "it"); return FALSE; } @@ -762,7 +762,7 @@ can_twoweapon(void) { struct obj *otmp; - if (!could_twoweap(gy.youmonst.data)) { + if (!could_twoweap(u.umonst->data)) { if (Upolyd) You_cant("use two weapons in your current form."); else diff --git a/src/wizcmds.c b/src/wizcmds.c index b045578b8..0bee2da86 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -892,7 +892,7 @@ wiz_smell(void) cc.x = u.ux; cc.y = u.uy; - if (!olfaction(gy.youmonst.data)) { + if (!olfaction(u.umonst->data)) { You("are incapable of detecting odors in your present form."); return ECMD_OK; } @@ -909,7 +909,7 @@ wiz_smell(void) if (u.usteed) { mptr = u.usteed->data; } else { - mptr = gy.youmonst.data; + mptr = u.umonst->data; is_you = TRUE; } } else if ((mtmp = m_at(cc.x, cc.y)) != (struct monst *) 0) { diff --git a/src/worn.c b/src/worn.c index a481f3372..9ffcb8c24 100644 --- a/src/worn.c +++ b/src/worn.c @@ -459,7 +459,7 @@ check_wornmask_slots(void) why = "uswapwep is not a melee weapon"; else if (bimanual(uswapwep)) why = "uswapwep is two-handed"; - else if (!could_twoweap(gy.youmonst.data)) + else if (!could_twoweap(u.umonst->data)) why = "without two weapon attacks"; if (why) @@ -1005,7 +1005,7 @@ m_dowear_type( struct obj * which_armor(struct monst *mon, long flag) { - if (mon == &gy.youmonst) { + if (mon == u.umonst) { switch (flag) { case W_ARM: return uarm; diff --git a/src/write.c b/src/write.c index d7a1eddb4..dc7ccbd36 100644 --- a/src/write.c +++ b/src/write.c @@ -84,7 +84,7 @@ dowrite(struct obj *pen) const char *typeword; int spell_knowledge; - if (nohands(gy.youmonst.data)) { + if (nohands(u.umonst->data)) { You("need hands to be able to write!"); return ECMD_OK; } else if (Glib) { diff --git a/src/zap.c b/src/zap.c index bdaa54cec..163ee6c38 100644 --- a/src/zap.c +++ b/src/zap.c @@ -590,7 +590,7 @@ release_hold(void) } /* gives "you get regurgitated" or "you get expelled from " */ expels(mtmp, mtmp->data, TRUE); - } else if (sticks(gy.youmonst.data)) { + } else if (sticks(u.umonst->data)) { /* order matters if 'holding' status condition is enabled; set_ustuck() will set flag for botl update, You() pline will trigger a status update with "UHold" removed */ @@ -694,7 +694,7 @@ get_mon_location( coordxy *xp, coordxy *yp, int locflags) /* non-zero means get location even if monster is buried */ { - if (mon == &gy.youmonst || (u.usteed && mon == u.usteed)) { + if (mon == u.umonst || (u.usteed && mon == u.usteed)) { *xp = u.ux; *yp = u.uy; return TRUE; @@ -1159,7 +1159,7 @@ unturn_dead(struct monst *mon) struct monst *mtmp2; char owner[BUFSZ], corpse[BUFSZ]; unsigned save_norevive; - boolean youseeit, different_type, is_u = (mon == &gy.youmonst); + boolean youseeit, different_type, is_u = (mon == u.umonst); int corpsenm, res = 0; youseeit = is_u ? TRUE : canseemon(mon); @@ -1224,9 +1224,9 @@ unturn_dead(struct monst *mon) void unturn_you(void) { - (void) unturn_dead(&gy.youmonst); /* hit carried corpses and eggs */ + (void) unturn_dead(u.umonst); /* hit carried corpses and eggs */ - if (is_undead(gy.youmonst.data)) { + if (is_undead(u.umonst->data)) { You_feel("frightened and %sstunned.", Stunned ? "even more " : ""); make_stunned((HStun & TIMEOUT) + (long) rnd(30), FALSE); } else { @@ -2102,7 +2102,7 @@ stone_to_flesh_obj(struct obj *obj) /* nonnull */ non-omnivorous form, regardless of whether it's herbivorous, non-eating, or something stranger) */ if (Role_if(PM_MONK) || !u.uconduct.unvegetarian - || !carnivorous(gy.youmonst.data)) + || !carnivorous(u.umonst->data)) Norep("You smell the odor of meat."); else Norep("You smell a delicious smell."); @@ -2206,14 +2206,14 @@ bhito(struct obj *obj, struct obj *otmp) if (obj_shudders(obj)) { boolean cover = ((obj == svl.level.objects[u.ux][u.uy]) && u.uundetected - && hides_under(gy.youmonst.data)); + && hides_under(u.umonst->data)); if (cansee(obj->ox, obj->oy)) learn_it = TRUE; do_osshock(obj); /* eek - your cover might have been blown */ if (cover) - (void) hideunder(&gy.youmonst); + (void) hideunder(u.umonst); break; } obj = poly_obj(obj, STRANGE_OBJECT); @@ -2440,7 +2440,7 @@ bhitpile( /* if hiding underneath an object and zapping up or down, the top item is either the only thing hit (up) or is skipped (down) */ - hidingunder = (zz != 0 && u.uundetected && hides_under(gy.youmonst.data)); + hidingunder = (zz != 0 && u.uundetected && hides_under(u.umonst->data)); first = TRUE; if (obj->otyp == SPE_FORCE_BOLT || obj->otyp == WAN_STRIKING) { @@ -2629,7 +2629,7 @@ dozap(void) struct obj *obj; int damage, need_dir; - if (nohands(gy.youmonst.data)) { + if (nohands(u.umonst->data)) { You("aren't able to zap anything in your current form."); return ECMD_OK; } @@ -2741,7 +2741,7 @@ zapyourself(struct obj *obj, boolean ordinary) monstseesu(M_SEEN_ELEC); ugolemeffects(AD_ELEC, orig_dmg); } - (void) destroy_items(&gy.youmonst, AD_ELEC, orig_dmg); + (void) destroy_items(u.umonst, AD_ELEC, orig_dmg); (void) flashburn((long) rnd(100), TRUE); break; @@ -2764,8 +2764,8 @@ zapyourself(struct obj *obj, boolean ordinary) monstunseesu(M_SEEN_FIRE); } burn_away_slime(); - (void) burnarmor(&gy.youmonst); - (void) destroy_items(&gy.youmonst, AD_FIRE, orig_dmg); + (void) burnarmor(u.umonst); + (void) destroy_items(u.umonst, AD_FIRE, orig_dmg); ignite_items(gi.invent); break; @@ -2784,7 +2784,7 @@ zapyourself(struct obj *obj, boolean ordinary) damage = orig_dmg; monstunseesu(M_SEEN_COLD); } - (void) destroy_items(&gy.youmonst, AD_COLD, orig_dmg); + (void) destroy_items(u.umonst, AD_COLD, orig_dmg); break; case WAN_MAGIC_MISSILE: @@ -2811,7 +2811,7 @@ zapyourself(struct obj *obj, boolean ordinary) case WAN_CANCELLATION: case SPE_CANCELLATION: - (void) cancel_monst(&gy.youmonst, obj, TRUE, TRUE, TRUE); + (void) cancel_monst(u.umonst, obj, TRUE, TRUE, TRUE); break; case SPE_DRAIN_LIFE: @@ -2884,7 +2884,7 @@ zapyourself(struct obj *obj, boolean ordinary) case WAN_DEATH: case SPE_FINGER_OF_DEATH: - if (nonliving(gy.youmonst.data) || is_demon(gy.youmonst.data)) { + if (nonliving(u.umonst->data) || is_demon(u.umonst->data)) { pline((obj->otyp == WAN_DEATH) ? "The wand shoots an apparently harmless beam at you." : "You seem no deader than before."); @@ -2939,16 +2939,16 @@ zapyourself(struct obj *obj, boolean ordinary) unpunish(); } /* invent is hit iff hero doesn't escape from a trap */ - if (!u.utrap || !openholdingtrap(&gy.youmonst, &learn_it)) { + if (!u.utrap || !openholdingtrap(u.umonst, &learn_it)) { boxlock_invent(obj); /* trigger previously escaped trapdoor */ - (void) openfallingtrap(&gy.youmonst, TRUE, &learn_it); + (void) openfallingtrap(u.umonst, TRUE, &learn_it); } break; case WAN_LOCKING: case SPE_WIZARD_LOCK: /* similar logic to opening; invent is hit iff no trap triggered */ - if (u.utrap || !closeholdingtrap(&gy.youmonst, &learn_it)) { + if (u.utrap || !closeholdingtrap(u.umonst, &learn_it)) { boxlock_invent(obj); } break; @@ -3032,7 +3032,7 @@ lightdamage( const char *how; int dmg = amt; - if (dmg && gy.youmonst.data == &mons[PM_GREMLIN]) { + if (dmg && u.umonst->data == &mons[PM_GREMLIN]) { /* reduce high values (from destruction of wand with many charges) */ dmg = rnd(dmg); if (dmg > 10) @@ -3059,7 +3059,7 @@ lightdamage( boolean flashburn(long duration, boolean via_lightning) { - if (!resists_blnd(&gy.youmonst)) { + if (!resists_blnd(u.umonst)) { You(are_blinded_by_the_flash); make_blinded(duration, FALSE); if (!Blind) @@ -3072,7 +3072,7 @@ flashburn(long duration, boolean via_lightning) if hero is both lightning resistant and blindness resistant, or worse, have a single sparkle where the player confuses blindness resistance for lightning resistance */ - if (!via_lightning && resists_blnd_by_arti(&gy.youmonst)) { + if (!via_lightning && resists_blnd_by_arti(u.umonst)) { shieldeff(u.ux, u.uy); return TRUE; } @@ -3153,7 +3153,7 @@ cancel_monst(struct monst *mdef, struct obj *obj, boolean youattack, static const char writing_vanishes[] = "Some writing vanishes from %s head!", your[] = "your"; /* should be extern */ - boolean youdefend = (mdef == &gy.youmonst); + boolean youdefend = (mdef == u.umonst); if (youdefend ? (!youattack && Antimagic) : resist(mdef, obj->oclass, 0, NOTELL)) @@ -3281,10 +3281,10 @@ zap_updown(struct obj *obj) /* wand or spell, nonnull */ } /* down will release you from bear trap or web */ if (u.dz > 0 && u.utrap) { - (void) openholdingtrap(&gy.youmonst, &disclose); + (void) openholdingtrap(u.umonst, &disclose); /* down will trigger trapdoor, hole, or [spiked-] pit */ } else if (u.dz > 0 && !u.utrap) { - (void) openfallingtrap(&gy.youmonst, FALSE, &disclose); + (void) openfallingtrap(u.umonst, FALSE, &disclose); } break; case WAN_STRIKING: @@ -3319,7 +3319,7 @@ zap_updown(struct obj *obj) /* wand or spell, nonnull */ } newsym(x, y); } else if (u.dz > 0 && ttmp) { - if (!striking && closeholdingtrap(&gy.youmonst, &disclose)) { + if (!striking && closeholdingtrap(u.umonst, &disclose)) { ; /* now stuck in web or bear trap */ } else if (striking && ttmp->ttyp == TRAPDOOR) { /* striking transforms trapdoor into hole */ @@ -3394,14 +3394,14 @@ zap_updown(struct obj *obj) /* wand or spell, nonnull */ /* game flavor: if you're hiding under "something" * a zap upward should hit that "something". */ - if (u.uundetected && hides_under(gy.youmonst.data)) { + if (u.uundetected && hides_under(u.umonst->data)) { int hitit = 0; otmp = svl.level.objects[u.ux][u.uy]; if (otmp) hitit = bhito(otmp, obj); if (hitit) { - (void) hideunder(&gy.youmonst); + (void) hideunder(u.umonst); disclose = TRUE; } } @@ -3558,7 +3558,7 @@ hit( struct monst *mtmp, /* target; for missile, might be hero */ const char *force) /* usually either "." or "!" via exclam() */ { - boolean verbosely = (mtmp == &gy.youmonst + boolean verbosely = (mtmp == u.umonst || (flags.verbose && (cansee(gb.bhitpos.x, gb.bhitpos.y) || canspotmon(mtmp) || engulfing_u(mtmp)))); @@ -3982,7 +3982,7 @@ bhit( they will be aiming at the monster */ xyglyph = glyph_at(x, y); if (mtmp && (((weapon == THROWN_WEAPON || weapon == KICKED_WEAPON) - && (shade_miss(&gy.youmonst, mtmp, obj, TRUE, TRUE) + && (shade_miss(u.umonst, mtmp, obj, TRUE, TRUE) || (M_AP_TYPE(mtmp) == M_AP_OBJECT && !glyph_is_monster(xyglyph) && !glyph_is_warning(xyglyph) @@ -4201,7 +4201,7 @@ boomhit(struct obj *obj, int dx, int dy) } if (u_at(gb.bhitpos.x, gb.bhitpos.y)) { /* ct == 9 */ if (Fumbling || rn2(20) >= ACURR(A_DEX)) { - int dam = dmgval(obj, &gy.youmonst); + int dam = dmgval(obj, u.umonst); /* we hit ourselves */ (void) thitu(10 + obj->spe, Maybe_Half_Phys(dam), &obj, @@ -4211,7 +4211,7 @@ boomhit(struct obj *obj, int dx, int dy) } else { /* we catch it */ tmp_at(DISP_END, 0); You("skillfully catch the boomerang."); - return &gy.youmonst; + return u.umonst; } } tmp_at(gb.bhitpos.x, gb.bhitpos.y); @@ -4430,9 +4430,9 @@ zhitu( monstunseesu(M_SEEN_FIRE); } burn_away_slime(); - if (burnarmor(&gy.youmonst)) { /* "body hit" */ + if (burnarmor(u.umonst)) { /* "body hit" */ if (!rn2(3)) - (void) destroy_items(&gy.youmonst, AD_FIRE, orig_dam); + (void) destroy_items(u.umonst, AD_FIRE, orig_dam); if (!rn2(3)) ignite_items(gi.invent); } @@ -4449,7 +4449,7 @@ zhitu( monstunseesu(M_SEEN_COLD); } if (!rn2(3)) - (void) destroy_items(&gy.youmonst, AD_COLD, orig_dam); + (void) destroy_items(u.umonst, AD_COLD, orig_dam); break; case ZT_SLEEP: if (Sleep_resistance) { @@ -4490,7 +4490,7 @@ zhitu( (void) disintegrate_arm(uarmc); if (uarmu) (void) disintegrate_arm(uarmu); - } else if (nonliving(gy.youmonst.data) || is_demon(gy.youmonst.data)) { + } else if (nonliving(u.umonst->data) || is_demon(u.umonst->data)) { shieldeff(sx, sy); You("seem unaffected."); break; @@ -4520,7 +4520,7 @@ zhitu( monstunseesu(M_SEEN_ELEC); } if (!rn2(3)) - (void) destroy_items(&gy.youmonst, AD_ELEC, orig_dam); + (void) destroy_items(u.umonst, AD_ELEC, orig_dam); break; case ZT_POISON_GAS: poisoned("blast", A_DEX, "poisoned blast", 15, FALSE); @@ -4542,7 +4542,7 @@ zhitu( if (u.twoweap && !rn2(3)) acid_damage(uswapwep); if (!rn2(6)) - erode_armor(&gy.youmonst, ERODE_CORRODE); + erode_armor(u.umonst, ERODE_CORRODE); break; } @@ -4891,7 +4891,7 @@ dobuzz( pline("%s disintegrates.", Monnam(mon)); pline("%s body reintegrates before your %s!", s_suffix(Monnam(mon)), - (eyecount(gy.youmonst.data) == 1) + (eyecount(u.umonst->data) == 1) ? body_part(EYE) : makeplural(body_part(EYE))); pline("%s resurrects!", Monnam(mon)); @@ -5803,7 +5803,7 @@ maybe_destroy_item( long i, cnt, quan; int dmg, xresist, skip, dindx; const char *mult; - boolean u_carry = (carrier == &gy.youmonst); + boolean u_carry = (carrier == u.umonst); boolean vis = !u_carry && canseemon(carrier); boolean chargeit = FALSE; @@ -5912,8 +5912,8 @@ maybe_destroy_item( } if (u_carry) { /* effects that happen only to the player */ if (osym == POTION_CLASS && dmgtyp != AD_COLD - && (!breathless(gy.youmonst.data) - || haseyes(gy.youmonst.data))) { + && (!breathless(u.umonst->data) + || haseyes(u.umonst->data))) { potionbreathe(obj); } if (obj->owornmask) { /* m_useup handles these for monster */ @@ -5977,7 +5977,7 @@ destroy_items( boolean deferred; } items_to_destroy[MAX_ITEMS_DESTROYED]; int elig_stacks = 0; /* number of destroyable objects found so far */ - boolean u_carry = (mon == &gy.youmonst); + boolean u_carry = (mon == u.umonst); /* this is a struct obj** because we might destroy the first item in it */ struct obj **objchn = u_carry ? &gi.invent : &mon->minvent; int dmg_out = 0; /* damage caused by items getting destroyed */ From 309afb2eb2ec507f680fcac1a4aa20df578c6456 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 25 Apr 2026 14:48:49 -0400 Subject: [PATCH 008/702] add support for a unique game identifier A 37 character field for holding a unique identifier is added to the save file, as well as to an ancestor field in bones files. Since it requires installation of libuuid package on Linux, it requires an exlicit WANT_NHUUID=1 on the Make command line there. Without the libuuid support, the saved nhuuid is empty, which should be harmless. This also moves the save and restore of gm.moves higher up so that it already has a value the first time it is used against a relative saved timestamp. Invalidates savefiles and bones files due to new fields. I need to get this committed before I can test out the macOS portion, so there may be some build issues there briefly (hopefully), and follow-up commits to resolve them. Increments EDITLEVEL. --- include/decl.h | 2 ++ include/extern.h | 4 +++ include/patchlevel.h | 2 +- src/allmain.c | 1 + src/bones.c | 4 +++ src/decl.c | 5 ++++ src/files.c | 1 + src/restore.c | 3 +- src/save.c | 4 ++- sys/share/pcsys.c | 24 +++++++++++++++ sys/unix/hints/include/multiw-2.370 | 4 +++ sys/unix/hints/linux.370 | 4 +++ sys/unix/unixmain.c | 38 ++++++++++++++++++++++++ sys/vms/vmsmain.c | 24 +++++++++++++++ sys/windows/vs/NetHack/NetHack.vcxproj | 2 +- sys/windows/vs/NetHackW/NetHackW.vcxproj | 2 +- sys/windows/windsys.c | 31 +++++++++++++++++++ 17 files changed, 150 insertions(+), 5 deletions(-) diff --git a/include/decl.h b/include/decl.h index 7a34be6f1..1ea39d6f9 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1174,6 +1174,8 @@ struct instance_globals_saved_m { struct instance_globals_saved_n { /* dungeon.c */ int n_dgns; /* number of dungeons (also used in mklev.c and do.c) */ + /* files.c */ + char nhuuid[37]; /* mkroom.c */ int nroom; /* region.c */ diff --git a/include/extern.h b/include/extern.h index c5cac33cf..d17497325 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1128,6 +1128,8 @@ extern boolean Death_quote(char *, int) NONNULLARG1; extern void livelog_add(long ll_type, const char *) NONNULLARG2; ATTRNORETURN extern void do_deferred_showpaths(int) NORETURN; extern boolean contains_directory(const char *); +extern void get_nhuuid(void); +extern void free_nhuuid(void); /* ### fountain.c ### */ @@ -4031,6 +4033,8 @@ extern char *get_port_id(char *); #ifdef RUNTIME_PASTEBUF_SUPPORT extern void port_insert_pastebuf(char *); #endif +extern void get_nhuuid(void); +extern void free_nhuuid(void); #endif /* !MAKEDEFS_C && !MDLIB_C */ diff --git a/include/patchlevel.h b/include/patchlevel.h index 75e1d3311..d9f25fea4 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -17,7 +17,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 140 +#define EDITLEVEL 141 /* * Development status possibilities. diff --git a/src/allmain.c b/src/allmain.c index 4ac564c87..530840a1a 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -780,6 +780,7 @@ newgame(void) svc.context.next_attrib_check = 600L; /* arbitrary first setting */ svc.context.tribute.enabled = TRUE; /* turn on 3.6 tributes */ svc.context.tribute.tributesz = sizeof(struct tribute_info); + get_nhuuid(); for (i = LOW_PM; i < NUMMONS; i++) svm.mvitals[i].mvflags = mons[i].geno & G_NOCORPSE; diff --git a/src/bones.c b/src/bones.c index 5afb0cbcd..2a3358678 100644 --- a/src/bones.c +++ b/src/bones.c @@ -611,6 +611,7 @@ savebones(int how, time_t when, struct obj *corpse) nhfp->mode = WRITING; store_version(nhfp); + Sfo_char(nhfp, &svn.nhuuid[0], "ancestor-nhuuid", sizeof svn.nhuuid); /* if a bones pool digit is in use, it precedes the bonesid string and isn't recorded in the file */ Sfo_char(nhfp, &c, "bones_count", 1); @@ -632,6 +633,7 @@ getbones(void) NHFILE *nhfp = (NHFILE *) 0; char c = 0, *bonesid, oldbonesid[40] = { 0 }; /* was [10]; more should be safer */ + char ancestor_nhuuid[SIZE(svn.nhuuid)]; #ifndef SFCTOOL if (discover) /* save bones files for real games */ @@ -670,6 +672,8 @@ getbones(void) return 0; } } + Sfi_char(nhfp, &ancestor_nhuuid[0], "ancestor-nhuuid", + sizeof ancestor_nhuuid); Sfi_char(nhfp, &c, "bones_count", 1); /* length incl. '\0' */ if ((unsigned) c <= sizeof oldbonesid) { Sfi_char(nhfp, oldbonesid, "bonesid", (int) c); diff --git a/src/decl.c b/src/decl.c index 14a92abb3..43d7143b9 100644 --- a/src/decl.c +++ b/src/decl.c @@ -929,6 +929,11 @@ static const struct instance_globals_saved_m init_svm = { static const struct instance_globals_saved_n init_svn = { /* dungeon.c */ 0, /* n_dgns */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0 + }, /* nhuuid */ /* mkroom.c */ 0, /* nroom */ /* region.c */ diff --git a/src/files.c b/src/files.c index ae45f6c07..74f600ef2 100644 --- a/src/files.c +++ b/src/files.c @@ -1529,6 +1529,7 @@ free_saved_games(char **saved) free((genericptr_t) saved); } } + #endif /* !SFCTOOL */ /* ---------- END SAVE FILE HANDLING ----------- */ diff --git a/src/restore.c b/src/restore.c index 83e2ca546..35ebaee10 100644 --- a/src/restore.c +++ b/src/restore.c @@ -537,6 +537,8 @@ restgamestate(NHFILE *nhfp) #endif Sfi_ulong(nhfp, &uid, "gamestate-uid"); + Sfi_char(nhfp, &svn.nhuuid[0], "nhuuid", sizeof svn.nhuuid); + Sfi_long(nhfp, &svm.moves, "gamestate-moves"); #ifndef SFCTOOL if (SYSOPT_CHECK_SAVE_UID && uid != (unsigned long) getuid()) { /* strange ... */ @@ -676,7 +678,6 @@ restgamestate(NHFILE *nhfp) restore_dungeon(nhfp); restlevchn(nhfp); - Sfi_long(nhfp, &svm.moves, "gamestate-moves"); /* hero_seq isn't saved and restored because it can be recalculated */ gh.hero_seq = svm.moves << 3; /* normally handled in moveloop() */ Sfi_q_score(nhfp, &svq.quest_status, "gamestate-quest_status"); diff --git a/src/save.c b/src/save.c index a93ae35a4..b6d09f432 100644 --- a/src/save.c +++ b/src/save.c @@ -292,6 +292,8 @@ savegamestate(NHFILE *nhfp) program_state.saving++; /* caller should/did already set this... */ uid = (unsigned long) getuid(); Sfo_ulong(nhfp, &uid, "gamestate-uid"); + Sfo_char(nhfp, &svn.nhuuid[0], "nhuuid", sizeof svn.nhuuid); + Sfo_long(nhfp, &svm.moves, "gamestate-moves"); moves_to_relative_time(&svc.context.seer_turn); moves_to_relative_time(&svc.context.digging.lastdigtime); Sfo_context_info(nhfp, &svc.context, "gamestate-context"); @@ -322,7 +324,6 @@ savegamestate(NHFILE *nhfp) save_dungeon(nhfp, (boolean) !!update_file(nhfp), (boolean) !!release_data(nhfp)); savelevchn(nhfp); - Sfo_long(nhfp, &svm.moves, "gamestate-moves"); Sfo_q_score(nhfp, &svq.quest_status, "gamestate-quest_status"); for (i = 0; i < (MAXSPELL + 1); ++i) { Sfo_spell(nhfp, &svs.spl_book[i], "gamestate-spl_book"); @@ -1177,6 +1178,7 @@ freedynamicdata(void) release_runtime_info(); /* build-time options and version stuff */ free_convert_filenames(); #endif /* FREE_ALL_MEMORY */ + free_nhuuid(); if (VIA_WINDOWPORT()) status_finish(); diff --git a/sys/share/pcsys.c b/sys/share/pcsys.c index 07cab8e42..c2f3aa2dd 100644 --- a/sys/share/pcsys.c +++ b/sys/share/pcsys.c @@ -143,6 +143,30 @@ append_slash(char *name) return; } +void +get_nhuuid(void) +{ + unsigned char stmp[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + if (svn.nhuuid[0]) + return; + + /* FIXME: fill in a useful valie UUID somehow */ + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", (char *) stmp); +} + +void +free_nhuuid(void) +{ + int i; + + for (i = 0; i < SIZE(svn.nhuuid); i++) { + svn.nhuuid[i] = 0; + } +} + void getreturn(const char *str) { diff --git a/sys/unix/hints/include/multiw-2.370 b/sys/unix/hints/include/multiw-2.370 index e1cf1633d..ca732f6c8 100644 --- a/sys/unix/hints/include/multiw-2.370 +++ b/sys/unix/hints/include/multiw-2.370 @@ -168,6 +168,10 @@ CPLUSPLUS_NEED_DEPSUPPRESS = 1 endif # WANT_WIN_QT6 endif # WANT_WIN_QT +ifdef WANT_NHUUID +USE_UUIDLIB=1 +endif + ifeq "$(GIT)" "1" ifndef GITSUBMODULES GITSUBMODULES=1 diff --git a/sys/unix/hints/linux.370 b/sys/unix/hints/linux.370 index 8b402350c..ea239260e 100755 --- a/sys/unix/hints/linux.370 +++ b/sys/unix/hints/linux.370 @@ -227,6 +227,10 @@ ifdef MAKEFILE_SRC ifdef CURSESLIB WINLIB += $(CURSESLIB) endif #CURSESLIB +ifdef WANT_NHUUID +CFLAGS+= -DNHUUID +LIBS+=-luuid +endif #NHUUID endif #MAKEFILE_SRC ifdef WANT_WIN_X11 diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index ad2cef7de..90577fde0 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -15,6 +15,13 @@ #include #endif +#ifdef NHUUID +/* for uuid */ +#ifdef LINUX +#include +#endif +#endif /* NHUUID */ + #if !defined(_BULL_SOURCE) && !defined(__sgi) && !defined(_M_UNIX) #if !defined(SUNOS4) && !(defined(ULTRIX) && defined(__GNUC__)) #if defined(POSIX_TYPES) || defined(SVR4) || defined(HPUX) @@ -833,5 +840,36 @@ sys_random_seed(void) } return seed; } +void +get_nhuuid(void) +{ + char struuid[37] = { 0 }; +#if defined(LINUX) && defined(NHUUID) + uuid_t binuuid; +#endif +#if defined(MACOS) && defined(NHUUID) + extern char *get_mac_uuid(char **); /* sys/unix/macuuid.m */ +#endif + if (svn.nhuuid[0]) + return; + +#if defined(MACOS) && defined(NHUUID) + get_mac_uuid(&struuid[0]); +#elif defined(LINUX) && defined(NHUUID) + uuid_generate_random(binuuid); + uuid_unparse(binuuid, struuid); +#endif /* MACOS || LINUX */ + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", &struuid[0]); +} + +void +free_nhuuid(void) +{ + int i; + + for (i = 0; i < SIZE(svn.nhuuid); i++) { + svn.nhuuid[i] = 0; + } +} /*unixmain.c*/ diff --git a/sys/vms/vmsmain.c b/sys/vms/vmsmain.c index f540d3190..d69c4de4d 100644 --- a/sys/vms/vmsmain.c +++ b/sys/vms/vmsmain.c @@ -513,4 +513,28 @@ sys_random_seed(void) return seed; } +void +get_nhuuid(void) +{ + unsigned char stmp[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + if (svn.nhuuid[0]) + return; + + /* FIXME: fill in a useful valie UUID somehow */ + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", (char *) stmp); +} + +void +free_nhuuid(void) +{ + int i; + + for (i = 0; i < SIZE(svn.nhuuid); i++) { + svn.nhuuid[i] = 0; + } +} + /*vmsmain.c*/ diff --git a/sys/windows/vs/NetHack/NetHack.vcxproj b/sys/windows/vs/NetHack/NetHack.vcxproj index c6f2df87c..fc2604af1 100644 --- a/sys/windows/vs/NetHack/NetHack.vcxproj +++ b/sys/windows/vs/NetHack/NetHack.vcxproj @@ -78,7 +78,7 @@ stdclatest - hacklib.lib;lualib.lib;kernel32.lib;dbghelp.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;Winmm.lib;UserEnv.lib;bcrypt.lib;%(AdditionalDependencies) + hacklib.lib;lualib.lib;kernel32.lib;dbghelp.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;Winmm.lib;UserEnv.lib;Rpcrt4.lib;bcrypt.lib;%(AdditionalDependencies) $(SndWavDir);$(SysWindDir);%(AdditionalIncludeDirectories) diff --git a/sys/windows/vs/NetHackW/NetHackW.vcxproj b/sys/windows/vs/NetHackW/NetHackW.vcxproj index cc3ec2563..6b7ecc097 100644 --- a/sys/windows/vs/NetHackW/NetHackW.vcxproj +++ b/sys/windows/vs/NetHackW/NetHackW.vcxproj @@ -100,7 +100,7 @@ Windows - hacklib.lib;lualib.lib;dbghelp.lib;comctl32.lib;winmm.lib;UserEnv.lib;bcrypt.lib;%(AdditionalDependencies) + hacklib.lib;lualib.lib;dbghelp.lib;comctl32.lib;winmm.lib;UserEnv.lib;Rpcrt4.lib;bcrypt.lib;%(AdditionalDependencies) $(WinWin32Dir)NethackW.exe.manifest;%(AdditionalManifestFiles) diff --git a/sys/windows/windsys.c b/sys/windows/windsys.c index 83e63d608..8826c33e4 100644 --- a/sys/windows/windsys.c +++ b/sys/windows/windsys.c @@ -28,6 +28,7 @@ #include #ifdef WIN32 +#include #include #include @@ -530,6 +531,36 @@ nethack_exit(int code) exit(code); } +void +get_nhuuid(void) +{ + UUID binuuid; + unsigned char *stmp; + RPC_STATUS rpcstatus; + + if (svn.nhuuid[0]) + return; + + rpcstatus = UuidCreate(&binuuid); + if (rpcstatus == RPC_S_OK) { + rpcstatus = UuidToStringA(&binuuid, &stmp); + if (rpcstatus == RPC_S_OK) { + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", (char *) stmp); + RpcStringFree(&stmp); + } + } +} + +void +free_nhuuid(void) +{ + int i; + + for (i = 0; i < SIZE(svn.nhuuid); i++) { + svn.nhuuid[i] = 0; + } +} + #ifdef WIN32CON #undef kbhit #include From b9a46107efba6398d6ab6745a83b654274666be2 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 25 Apr 2026 15:05:08 -0400 Subject: [PATCH 009/702] fix up some odd indentation in mcastu.c --- src/mcastu.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mcastu.c b/src/mcastu.c index c6f5bc3bb..4b40fa2ff 100644 --- a/src/mcastu.c +++ b/src/mcastu.c @@ -389,7 +389,7 @@ staticfn void mcast_death_touch(struct monst *mtmp) { pline("Oh no, %s's using the touch of death!", mhe(mtmp)); - if (nonliving(u.umonst->data) || is_demon(u.umonst->data)) { + if (nonliving(u.umonst->data) || is_demon(u.umonst->data)) { You("seem no deader than before."); } else if (!Antimagic && rn2(mtmp->m_lev) > 12) { if (Hallucination) { @@ -553,9 +553,9 @@ mcast_fire_pillar(struct monst *mtmp, int dmg) if (Half_spell_damage) dmg = (dmg + 1) / 2; burn_away_slime(); - (void) burnarmor(u.umonst); + (void) burnarmor(u.umonst); /* item destruction dmg */ - (void) destroy_items(u.umonst, AD_FIRE, orig_dmg); + (void) destroy_items(u.umonst, AD_FIRE, orig_dmg); ignite_items(gi.invent); /* burn up flammable items on the floor, melt ice terrain */ mon_spell_hits_spot(mtmp, AD_FIRE, u.ux, u.uy); @@ -586,7 +586,7 @@ mcast_lightning(struct monst *mtmp, int dmg) } if (Half_spell_damage) dmg = (dmg + 1) / 2; - (void) destroy_items(u.umonst, AD_ELEC, orig_dmg); + (void) destroy_items(u.umonst, AD_ELEC, orig_dmg); /* lightning might destroy iron bars if hero is on such a spot; reflection protects terrain here [execution won't get here due to 'if (reflects) break' above] but hero resistance doesn't; @@ -730,7 +730,7 @@ mcast_blind_you(void) { /* note: resists_blnd() doesn't apply here */ if (!Blinded) { - int num_eyes = eyecount(u.umonst->data); + int num_eyes = eyecount(u.umonst->data); pline("Scales cover your %s!", (num_eyes == 1) ? body_part(EYE) From 4cf78d8f312820259ac4440bc5e94f4552037e67 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 25 Apr 2026 15:44:53 -0400 Subject: [PATCH 010/702] add macuuid.m --- sys/unix/macuuid.m | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 sys/unix/macuuid.m diff --git a/sys/unix/macuuid.m b/sys/unix/macuuid.m new file mode 100644 index 000000000..c2e742340 --- /dev/null +++ b/sys/unix/macuuid.m @@ -0,0 +1,41 @@ +/* macuuid.m */ +/* Copyright Michael Allison, 2023 */ +/* NetHack may be freely redistributed. See license for details. */ + +#include "hack.h" + +#ifdef DEBUG +#undef DEBUG +#endif + +/* #import */ +#import + +static const char *macos_uuid = 0; + +void +free_macos_uuid(void) +{ + if (macos_uuid) { + free((genericptr_t) macos_uuid); + macos_uuid = 0; + } +} + +const char * +get_macos_uuid(void) +{ + NSString *uuidString = [[NSUUID UUID] UUIDString]; + const char *str_uuid; + + if (macos_uuid) + free_macos_uuid(); + + /* str_uuid = [uuidString cStringUsingEncoding:NSUTF8StringEncoding]; */ + str_uuid = [uuidString cStringUsingEncoding:NSASCIIStringEncoding]; + macos_uuid = dupstr(str_uuid); + return macos_uuid; +} + + +/* end of macuuid.m */ From 89c7435b7ac16f8318e0c9ef36f2db28b81f12de Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 25 Apr 2026 15:57:36 -0400 Subject: [PATCH 011/702] attempt macOS fix --- sys/unix/unixmain.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 90577fde0..084811d85 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -843,11 +843,11 @@ sys_random_seed(void) void get_nhuuid(void) { - char struuid[37] = { 0 }; #if defined(LINUX) && defined(NHUUID) + char struuid[37] = { 0 }; uuid_t binuuid; -#endif -#if defined(MACOS) && defined(NHUUID) +#elif defined(MACOS) && defined(NHUUID) + char *struuid = NULL; extern char *get_mac_uuid(char **); /* sys/unix/macuuid.m */ #endif @@ -855,12 +855,16 @@ get_nhuuid(void) return; #if defined(MACOS) && defined(NHUUID) - get_mac_uuid(&struuid[0]); + get_mac_uuid(&struuid); #elif defined(LINUX) && defined(NHUUID) uuid_generate_random(binuuid); uuid_unparse(binuuid, struuid); #endif /* MACOS || LINUX */ - Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", &struuid[0]); + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", struuid); + +#if defined(MACOS) && defined(NHUUID) + free_macos_uuid(); +#endif } void From 27f6ae340bf030166184e38cfe6198d5e0186d2e Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 25 Apr 2026 13:14:33 -0700 Subject: [PATCH 012/702] address issue #1490 - rolling boulder segfault Issue reported by BartekCupial: segfault occurred and was tracked to behavior of a rolling boulder trap. Suggested fix was included, but it assumes that the destination spot is valid so is suspect. A comment pointed out that the path is validated when a rolling boulder trap is created so the segfault should be impossible. I didn't find an explanation but am adding a fix based on the one in the issue report. Closes #1490 --- doc/fixes3-7-0.txt | 1 + src/trap.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 1f281f47c..aa27902a7 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1602,6 +1602,7 @@ when starting a new game as a monk, newsym(0,0) was being called (adjabil -> postadjabil -> see_monsters when initializing See_invisible as hero became level 1; seen 'monster' was the hero who hadn't been placed on the map yet) +incorporate a fix to prevent segfault due to rolling boulder trap Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/src/trap.c b/src/trap.c index cc62fdd3e..a97706fe8 100644 --- a/src/trap.c +++ b/src/trap.c @@ -3375,6 +3375,23 @@ launch_obj( while (tmp-- > 0) nh_delay_output(); + /* + * TEMPORARY? github issue #1490 by BartekCupial reports a + * segfault when boulder rolls out of bounds. That should be + * impossible because trap creation validates the path that + * the boulder will traverse. + * + * The suggested fix increments bhitpos, verifies with isok(), + * then undoes the increment if not ok. This is simpler. + */ + if (!isok(gb.bhitpos.x + dx, gb.bhitpos.y + dy)) { + x2 = x, y2 = y; /* use current spot for final boulder placement */ + break; + } + /* + * end TEMPORARY? + */ + x = (gb.bhitpos.x += dx); y = (gb.bhitpos.y += dy); From 98308a8a7df816033f752535390e6c6a2662c54d Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 25 Apr 2026 16:19:24 -0400 Subject: [PATCH 013/702] thinko while looking into macOS --- sys/unix/unixmain.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 084811d85..7adf9b601 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -843,12 +843,13 @@ sys_random_seed(void) void get_nhuuid(void) { -#if defined(LINUX) && defined(NHUUID) char struuid[37] = { 0 }; +#if defined(LINUX) && defined(NHUUID) uuid_t binuuid; #elif defined(MACOS) && defined(NHUUID) char *struuid = NULL; extern char *get_mac_uuid(char **); /* sys/unix/macuuid.m */ + extern void free_macos_uuid(void); /* sys/unix/macuuid.m */ #endif if (svn.nhuuid[0]) From 532152ffc0d4dc33169b319def6119a784c10738 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 25 Apr 2026 16:41:16 -0400 Subject: [PATCH 014/702] macOS follow-up --- sys/unix/Makefile.src | 4 +++- sys/unix/hints/macOS.370 | 12 ++++++++++++ sys/unix/macuuid.m | 3 +++ sys/unix/unixmain.c | 19 +++++++++++++------ 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 46dca7f71..29338e374 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -632,7 +632,8 @@ HOBJ = $(TARGETPFX)allmain.o $(TARGETPFX)alloc.o \ $(TARGETPFX)wield.o $(TARGETPFX)windows.o $(TARGETPFX)wizard.o \ $(TARGETPFX)wizcmds.o $(TARGETPFX)worm.o $(TARGETPFX)worn.o \ $(TARGETPFX)write.o $(TARGETPFX)zap.o \ - $(REGEXOBJ) $(RANDOBJ) $(SYSOBJ) $(WINOBJ) $(HINTOBJ) $(SNDLIBOBJ) \ + $(REGEXOBJ) $(RANDOBJ) $(SYSOBJ) $(WINOBJ) \ + $(HINTOBJ) $(SNDLIBOBJ) $(UUIDOBJ) \ $(TARGETPFX)version.o DATE_O = $(TARGETPFX)date.o @@ -879,6 +880,7 @@ depend2: $(WINQTMOC) @rm -f Makefile.bak @rm -f ../include/nhlua.h tile.c + # DO NOT DELETE THIS LINE OR CHANGE ANYTHING BEYOND IT # config.h timestamp diff --git a/sys/unix/hints/macOS.370 b/sys/unix/hints/macOS.370 index 02e5dbba6..9d09fed2e 100755 --- a/sys/unix/hints/macOS.370 +++ b/sys/unix/hints/macOS.370 @@ -215,6 +215,13 @@ LFLAGS += -framework AVFoundation #endif endif +ifdef MAKEFILE_SRC +ifdef WANT_NHUUID +CFLAGS += -DNHUUID +UUIDOBJ = macuuid.o +endif +endif + # #-INCLUDE multisnd1-pre.370 # @@ -547,6 +554,11 @@ checkmakefiles: endif endif +ifdef WANT_NHUUID +$(TARGETPFX)macuuid.o: ../sys/unix/macuuid.m + $(CC) $(CFLAGS) -c -o$@ $< +endif + ifdef WANT_LIBNH $(TARGETPFX)libnh.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua-$(LUA_VERSION).a $(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua-$(LUA_VERSION).a diff --git a/sys/unix/macuuid.m b/sys/unix/macuuid.m index c2e742340..67a4f2486 100644 --- a/sys/unix/macuuid.m +++ b/sys/unix/macuuid.m @@ -4,6 +4,9 @@ #include "hack.h" +void free_macos_uuid(void); +const char *get_macos_uuid(void); + #ifdef DEBUG #undef DEBUG #endif diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 7adf9b601..9f3507c53 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -840,28 +840,35 @@ sys_random_seed(void) } return seed; } + +#if defined(MACOS) && defined(NHUUID) +extern char *get_macos_uuid(char **); /* sys/unix/macuuid.m */ +extern void free_macos_uuid(void); /* sys/unix/macuuid.m */ +#endif + void get_nhuuid(void) { +#if !defined(MACOS) char struuid[37] = { 0 }; +#endif + char *struuidptr = NULL; #if defined(LINUX) && defined(NHUUID) uuid_t binuuid; -#elif defined(MACOS) && defined(NHUUID) - char *struuid = NULL; - extern char *get_mac_uuid(char **); /* sys/unix/macuuid.m */ - extern void free_macos_uuid(void); /* sys/unix/macuuid.m */ #endif if (svn.nhuuid[0]) return; #if defined(MACOS) && defined(NHUUID) - get_mac_uuid(&struuid); + get_macos_uuid(&struuidptr); #elif defined(LINUX) && defined(NHUUID) uuid_generate_random(binuuid); uuid_unparse(binuuid, struuid); + struuidptr = &struuid[0]; #endif /* MACOS || LINUX */ - Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", struuid); + + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", struuidptr); #if defined(MACOS) && defined(NHUUID) free_macos_uuid(); From a906ed823633237ecc945536cc7ce93f3bcfb1fa Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 25 Apr 2026 16:47:12 -0400 Subject: [PATCH 015/702] another follow-up --- sys/unix/unixmain.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 9f3507c53..a197056cc 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -850,7 +850,9 @@ void get_nhuuid(void) { #if !defined(MACOS) +#if defined(NHUUID) char struuid[37] = { 0 }; +#endif #endif char *struuidptr = NULL; #if defined(LINUX) && defined(NHUUID) @@ -868,7 +870,8 @@ get_nhuuid(void) struuidptr = &struuid[0]; #endif /* MACOS || LINUX */ - Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", struuidptr); + if (struuidptr) + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", struuidptr); #if defined(MACOS) && defined(NHUUID) free_macos_uuid(); From f4f085891d76ac321e7835c24bdca1fec7a4fc20 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sat, 25 Apr 2026 16:16:07 -0400 Subject: [PATCH 016/702] This is cron-daily v1-Jan-12-2026. 000files updated: Files --- Files | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Files b/Files index a91ef523d..37f8904b4 100644 --- a/Files +++ b/Files @@ -394,8 +394,9 @@ sys/unix: Install.unx Makefile.check Makefile.dat Makefile.doc Makefile.src Makefile.top Makefile.utl NewInstall.unx README-hints README.xcode XCode.xcconfig depend.awk -gitinfo.sh mkmkfile.sh nethack.sh setup.sh -sysconf unixmain.c unixres.c unixunix.c +gitinfo.sh macuuid.m mkmkfile.sh nethack.sh +setup.sh sysconf unixmain.c unixres.c +unixunix.c sys/unix/NetHack.xcodeproj: (file for macOS Xcode) From e08fdc2d1f9f0643566d7c0a92f963e8a25b4d5a Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 25 Apr 2026 20:08:43 -0400 Subject: [PATCH 017/702] move the stub routines from pcsys.c to pcmain.c Fixes broken Amiga build --- sys/share/pcmain.c | 25 +++++++++++++++++++++++++ sys/share/pcsys.c | 24 ------------------------ 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index 39e5aec4e..fcdfc9180 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -750,6 +750,31 @@ exepath(char *str) #endif /* EXEPATH */ #ifdef CROSS_TO_AMIGA + +void +get_nhuuid(void) +{ + unsigned char stmp[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + if (svn.nhuuid[0]) + return; + + /* FIXME: fill in a useful valid UUID somehow */ + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", (char *) stmp); +} + +void +free_nhuuid(void) +{ + int i; + + for (i = 0; i < SIZE(svn.nhuuid); i++) { + svn.nhuuid[i] = 0; + } +} + void msmsg VA_DECL(const char *, fmt) { diff --git a/sys/share/pcsys.c b/sys/share/pcsys.c index c2f3aa2dd..07cab8e42 100644 --- a/sys/share/pcsys.c +++ b/sys/share/pcsys.c @@ -143,30 +143,6 @@ append_slash(char *name) return; } -void -get_nhuuid(void) -{ - unsigned char stmp[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - if (svn.nhuuid[0]) - return; - - /* FIXME: fill in a useful valie UUID somehow */ - Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", (char *) stmp); -} - -void -free_nhuuid(void) -{ - int i; - - for (i = 0; i < SIZE(svn.nhuuid); i++) { - svn.nhuuid[i] = 0; - } -} - void getreturn(const char *str) { From 535494330080be7bb13b5c99cf87d529f80447f4 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 25 Apr 2026 20:15:48 -0400 Subject: [PATCH 018/702] pcmain() follow-up --- sys/share/pcmain.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index fcdfc9180..c321e90db 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -749,7 +749,7 @@ exepath(char *str) } #endif /* EXEPATH */ -#ifdef CROSS_TO_AMIGA +#if defined(CROSS_TO_AMIGA) || defined(CROSS_TO_MSDOS) void get_nhuuid(void) @@ -774,7 +774,9 @@ free_nhuuid(void) svn.nhuuid[i] = 0; } } +#endif +#if defined(CROSS_TO_AMIGA) void msmsg VA_DECL(const char *, fmt) { From b6503fa52e9650bcc350e343eae96d976c2bf883 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 25 Apr 2026 20:22:12 -0400 Subject: [PATCH 019/702] update README-hints --- sys/unix/README-hints | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/unix/README-hints b/sys/unix/README-hints index 03c3fd893..e56dfca7f 100644 --- a/sys/unix/README-hints +++ b/sys/unix/README-hints @@ -78,6 +78,11 @@ make WANT_SHARE_INSTALL=1 Place the results of the install/update portion make WANT_SOURCE_INSTALL=1 Place the results of the install/update portion of the build into a subfolder of the source tree, rather than in a system-wide shared area. + +make WANT_NHUUID=1 Include support for a unique game identifier. + On Linux, libuuid must be installed for this + to build and link correctly. + make VIEWDEPRECATIONS=1 Turn off the suppression of -Wdeprecated and -Wdeprecated-declarations warnings From 1d5397d35b271f3cfd668247080f9e2cc86b15b5 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 25 Apr 2026 20:28:07 -0400 Subject: [PATCH 020/702] follow-up with how-to for two Linux distros --- sys/unix/README-hints | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sys/unix/README-hints b/sys/unix/README-hints index e56dfca7f..72f60f469 100644 --- a/sys/unix/README-hints +++ b/sys/unix/README-hints @@ -80,8 +80,11 @@ make WANT_SOURCE_INSTALL=1 Place the results of the install/update portion tree, rather than in a system-wide shared area. make WANT_NHUUID=1 Include support for a unique game identifier. - On Linux, libuuid must be installed for this - to build and link correctly. + On Linux, libuuid and headers ust be installed + and available for this to build and link correctly. + sudo apt install uuid-dev on Debian/Ubuntu + or + sudo dnf install libuuid-devel on Fedora make VIEWDEPRECATIONS=1 Turn off the suppression of -Wdeprecated and -Wdeprecated-declarations warnings From a3fa63f444727888aa02ba57f8f123d32a52c155 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 25 Apr 2026 20:34:24 -0400 Subject: [PATCH 021/702] typo fix --- sys/unix/README-hints | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/unix/README-hints b/sys/unix/README-hints index 72f60f469..87e08e6d4 100644 --- a/sys/unix/README-hints +++ b/sys/unix/README-hints @@ -80,7 +80,7 @@ make WANT_SOURCE_INSTALL=1 Place the results of the install/update portion tree, rather than in a system-wide shared area. make WANT_NHUUID=1 Include support for a unique game identifier. - On Linux, libuuid and headers ust be installed + On Linux, libuuid and its headers must be installed and available for this to build and link correctly. sudo apt install uuid-dev on Debian/Ubuntu or From 831251016dfd9c817d9bfe18bc7132c66bd11e08 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 25 Apr 2026 21:17:05 -0700 Subject: [PATCH 022/702] vision fix I have no idea whether this prevents the newly discovered impossible(). However, it does fix an obvious typo--in hindsight--that I made 6 years ago (dealing with temporary lighting for camera flashes). --- src/vision.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vision.c b/src/vision.c index 709f54d02..90bd965a9 100644 --- a/src/vision.c +++ b/src/vision.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vision.c $NHDT-Date: 1724939600 2024/08/29 13:53:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ */ +/* NetHack 3.7 vision.c $NHDT-Date: 1777205478 2026/04/26 04:11:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.75 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ @@ -58,7 +58,7 @@ const coordxy circle_start[] = { /* 4*/ 10, /* 5*/ 15, /* 6*/ 21, - /* 7*/ 38, + /* 7*/ 28, /* 8*/ 36, /* 9*/ 45, /*10*/ 55, From f9ccf24b0b830fff8ee58d684ae0dbeaea2fd761 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 07:28:04 -0400 Subject: [PATCH 023/702] date update --- sys/unix/hints/macOS.370 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/unix/hints/macOS.370 b/sys/unix/hints/macOS.370 index 9d09fed2e..006c54a45 100755 --- a/sys/unix/hints/macOS.370 +++ b/sys/unix/hints/macOS.370 @@ -665,7 +665,7 @@ $(BUNDLE_INFOPLIST): @echo 'CFBundleShortVersionString' >>$@ @echo '3.7.0' >>$@ @echo 'NSHumanReadableCopyright' >>$@ - @echo '©By Stichting Mathematisch Centrum and M. Stephenson 1985-2023' >>$@ + @echo '©By Stichting Mathematisch Centrum and M. Stephenson 1985-2026' >>$@ @echo 'LSApplicationCategoryType' >>$@ @echo 'public.app-category.adventure-games' >>$@ @echo '' >>$@ From 99525ea7b7855a5bfcf78779d574e2d4c807d7fd Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 08:15:08 -0400 Subject: [PATCH 024/702] hints files from .370 to .500 --- .../include/{compiler.370 => compiler.500} | 4 +- .../{cross-post.370 => cross-post.500} | 0 .../{cross-pre1.370 => cross-pre1.500} | 0 .../{cross-pre2.370 => cross-pre2.500} | 4 +- .../{gbdates-post.370 => gbdates-post.500} | 2 +- .../{gbdates-pre.370 => gbdates-pre.500} | 2 +- sys/unix/hints/include/{misc.370 => misc.500} | 10 ++--- .../{multisnd-post.370 => multisnd-post.500} | 4 +- .../{multisnd1-pre.370 => multisnd1-pre.500} | 10 ++--- .../{multisnd2-pre.370 => multisnd2-pre.500} | 4 +- .../include/{multiw-1.370 => multiw-1.500} | 4 +- .../include/{multiw-2.370 => multiw-2.500} | 8 ++-- .../include/{response.370 => response.500} | 4 +- sys/unix/hints/{linux.370 => linux.500} | 44 +++++++++---------- sys/unix/hints/{macOS.370 => macOS.500} | 42 +++++++++--------- 15 files changed, 71 insertions(+), 71 deletions(-) rename sys/unix/hints/include/{compiler.370 => compiler.500} (98%) rename sys/unix/hints/include/{cross-post.370 => cross-post.500} (100%) rename sys/unix/hints/include/{cross-pre1.370 => cross-pre1.500} (100%) rename sys/unix/hints/include/{cross-pre2.370 => cross-pre2.500} (99%) rename sys/unix/hints/include/{gbdates-post.370 => gbdates-post.500} (90%) rename sys/unix/hints/include/{gbdates-pre.370 => gbdates-pre.500} (91%) rename sys/unix/hints/include/{misc.370 => misc.500} (94%) rename sys/unix/hints/include/{multisnd-post.370 => multisnd-post.500} (89%) rename sys/unix/hints/include/{multisnd1-pre.370 => multisnd1-pre.500} (81%) rename sys/unix/hints/include/{multisnd2-pre.370 => multisnd2-pre.500} (94%) rename sys/unix/hints/include/{multiw-1.370 => multiw-1.500} (90%) rename sys/unix/hints/include/{multiw-2.370 => multiw-2.500} (96%) rename sys/unix/hints/include/{response.370 => response.500} (91%) rename sys/unix/hints/{linux.370 => linux.500} (94%) rename sys/unix/hints/{macOS.370 => macOS.500} (97%) diff --git a/sys/unix/hints/include/compiler.370 b/sys/unix/hints/include/compiler.500 similarity index 98% rename from sys/unix/hints/include/compiler.370 rename to sys/unix/hints/include/compiler.500 index 70f9eadeb..fde7ca00f 100755 --- a/sys/unix/hints/include/compiler.370 +++ b/sys/unix/hints/include/compiler.500 @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 compiler.370 $NHDT-Date: 1668359835 2022/11/13 17:17:15 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 3.7 compiler.500 $NHDT-Date: 1668359835 2022/11/13 17:17:15 $ $NHDT-Branch: NetHack-3.7 $ # compiler flags: CCFLAGS is used to construct a value for CFLAGS with # various -I, -D, and -W settings appended below; @@ -262,5 +262,5 @@ ifneq "$(HAVECSTD)" "" CSTD = -std=$(HAVECSTD) endif -#end of compiler.370 +#end of compiler.500 #------------------------------------------------------------------------------ diff --git a/sys/unix/hints/include/cross-post.370 b/sys/unix/hints/include/cross-post.500 similarity index 100% rename from sys/unix/hints/include/cross-post.370 rename to sys/unix/hints/include/cross-post.500 diff --git a/sys/unix/hints/include/cross-pre1.370 b/sys/unix/hints/include/cross-pre1.500 similarity index 100% rename from sys/unix/hints/include/cross-pre1.370 rename to sys/unix/hints/include/cross-pre1.500 diff --git a/sys/unix/hints/include/cross-pre2.370 b/sys/unix/hints/include/cross-pre2.500 similarity index 99% rename from sys/unix/hints/include/cross-pre2.370 rename to sys/unix/hints/include/cross-pre2.500 index 3476682ad..8c6dbe64d 100644 --- a/sys/unix/hints/include/cross-pre2.370 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -328,7 +328,7 @@ WASM_CFLAGS += -Wshadow # WASM_CFLAGS += -Wwrite-strings # WASM_CFLAGS += -Werror # Nethack C flags -WASM_CFLAGS += $(WINCFLAGS) #WINCFLAGS set from multiw-2.370 +WASM_CFLAGS += $(WINCFLAGS) #WINCFLAGS set from multiw-2.500 WASM_CFLAGS += -DSYSCF -DSYSCF_FILE=\"/sysconf\" -DSECURE #WASM_CFLAGS += -g -I../include -DNOTPARMDECL WASM_CFLAGS += -I../include -DNOTPARMDECL @@ -470,7 +470,7 @@ ifdef CROSS_TO_AMIGA # # Cross-compiler: https://franke.ms/git/bebbo/amiga-gcc # Install to /opt/amiga, then: -# sys/unix/setup.sh sys/unix/hints/linux.370 +# sys/unix/setup.sh sys/unix/hints/linux.500 # make fetch-lua # make CROSS_TO_AMIGA=1 fetch-regex # make CROSS_TO_AMIGA=1 all diff --git a/sys/unix/hints/include/gbdates-post.370 b/sys/unix/hints/include/gbdates-post.500 similarity index 90% rename from sys/unix/hints/include/gbdates-post.370 rename to sys/unix/hints/include/gbdates-post.500 index 9809a6df9..94451d337 100755 --- a/sys/unix/hints/include/gbdates-post.370 +++ b/sys/unix/hints/include/gbdates-post.500 @@ -1,4 +1,4 @@ -# NetHack 3.7 gbdates-post.370 $NHDT-Date: 1599687610 2020/09/09 21:40:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ +# NetHack 3.7 gbdates-post.500 $NHDT-Date: 1599687610 2020/09/09 21:40:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ ifdef MAKEFILE_DOC ifdef GB_DATESTAMP Guidebook.dated.mn: $(GUIDEBOOK_MN_SRC) diff --git a/sys/unix/hints/include/gbdates-pre.370 b/sys/unix/hints/include/gbdates-pre.500 similarity index 91% rename from sys/unix/hints/include/gbdates-pre.370 rename to sys/unix/hints/include/gbdates-pre.500 index a9420cd6b..8ba189cdb 100755 --- a/sys/unix/hints/include/gbdates-pre.370 +++ b/sys/unix/hints/include/gbdates-pre.500 @@ -1,4 +1,4 @@ -# NetHack 3.7 gbdates-pre.370 $NHDT-Date: 1599687610 2020/09/09 21:40:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ +# NetHack 3.7 gbdates-pre.500 $NHDT-Date: 1599687610 2020/09/09 21:40:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ ifdef MAKEFILE_DOC ifneq "$(GIT)" "0" diff --git a/sys/unix/hints/include/misc.370 b/sys/unix/hints/include/misc.500 similarity index 94% rename from sys/unix/hints/include/misc.370 rename to sys/unix/hints/include/misc.500 index 7f57697b4..63d983715 100644 --- a/sys/unix/hints/include/misc.370 +++ b/sys/unix/hints/include/misc.500 @@ -1,11 +1,11 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 misc.370 $NHDT-Date: 1668359836 2022/11/13 17:17:16 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 3.7 misc.500 $NHDT-Date: 1668359836 2022/11/13 17:17:16 $ $NHDT-Branch: NetHack-3.7 $ # -# Further set-up for miscellaneous odds and ends (after compiler.370) +# Further set-up for miscellaneous odds and ends (after compiler.500) # # Included from: -# hints/linux.370 -# hints/macOS.370 +# hints/linux.500 +# hints/macOS.500 # # This ensures that .moc files are compatible with the version of Qt chosen. @@ -105,6 +105,6 @@ endif # end groff less than 1.23 endif # end groff-specific endif # not USE_MANDOC -#end of hints/include/misc.370 +#end of hints/include/misc.500 #------------------------------------------------------------------------------ diff --git a/sys/unix/hints/include/multisnd-post.370 b/sys/unix/hints/include/multisnd-post.500 similarity index 89% rename from sys/unix/hints/include/multisnd-post.370 rename to sys/unix/hints/include/multisnd-post.500 index 431745dab..e6e764c2e 100644 --- a/sys/unix/hints/include/multisnd-post.370 +++ b/sys/unix/hints/include/multisnd-post.500 @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 multisnd-post.370 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 3.7 multisnd-post.500 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ ifeq "$(HAVE_SNDLIB)" "1" # note: one possible value for $(SNDLIBSRC) is 'macsound.m' which is written @@ -21,6 +21,6 @@ $(WAVDIR)/%.wav: ../util/uudecode $(WAVDIR)/%.uu endif # NEEDS_WAV endif # HAVE_SNDLIB -# end of multisnd-post.370 +# end of multisnd-post.500 #------------------------------------------------------------------------------ diff --git a/sys/unix/hints/include/multisnd1-pre.370 b/sys/unix/hints/include/multisnd1-pre.500 similarity index 81% rename from sys/unix/hints/include/multisnd1-pre.370 rename to sys/unix/hints/include/multisnd1-pre.500 index 909a02fef..8c89c5977 100644 --- a/sys/unix/hints/include/multisnd1-pre.370 +++ b/sys/unix/hints/include/multisnd1-pre.500 @@ -1,9 +1,9 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 multisnd1-pre.370 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 3.7 multisnd1-pre.500 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ # # If it's cross-platform it belongs in this file. -# If it's macOS-only, it belongs in macOS.370. -# If it's linux-only, it belongs in linux.370. +# If it's macOS-only, it belongs in macOS.500. +# If it's linux-only, it belongs in linux.500. # #ifdef WANT_TESTSOUND @@ -26,8 +26,8 @@ endif # HAVE_SNDLIB # HAVE_SNDLIB or NEEDS_SND_USERSOUNDS or NEEDS_SND_SEAUTOMAP # would have to be set prior to this. Any of them could have # been set just above, or they could have been set in -# multiw-2 for Qt, or they could have been set in macOS.370 -# or linux.370 for something platform-specific. +# multiw-2 for Qt, or they could have been set in macOS.500 +# or linux.500 for something platform-specific. # Regardless, if one of those is set, the related preprocessor # defines need to be added to SNDCFLAGS here. # diff --git a/sys/unix/hints/include/multisnd2-pre.370 b/sys/unix/hints/include/multisnd2-pre.500 similarity index 94% rename from sys/unix/hints/include/multisnd2-pre.370 rename to sys/unix/hints/include/multisnd2-pre.500 index 2970a4c7a..3fe11fa19 100644 --- a/sys/unix/hints/include/multisnd2-pre.370 +++ b/sys/unix/hints/include/multisnd2-pre.500 @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 multisnd2-pre.370 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 3.7 multisnd2-pre.500 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ # ifdef NEEDS_WAV @@ -27,6 +27,6 @@ SNDWAVS = se_squeak_A se_squeak_B se_squeak_B_flat se_squeak_C se_squeak_D \ WAVS = $(addprefix $(WAVDIR)/, $(addsuffix .wav, $(SNDWAVS))) endif # NEEDS_WAV -# end of multisnd2-pre.370 +# end of multisnd2-pre.500 #------------------------------------------------------------------------------ diff --git a/sys/unix/hints/include/multiw-1.370 b/sys/unix/hints/include/multiw-1.500 similarity index 90% rename from sys/unix/hints/include/multiw-1.370 rename to sys/unix/hints/include/multiw-1.500 index cd7651730..521e71883 100644 --- a/sys/unix/hints/include/multiw-1.370 +++ b/sys/unix/hints/include/multiw-1.500 @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 multiw-1.370 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 3.7 multiw-1.500 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ # 1. Which windowing interface(s) should be included in this binary? # One or more of these can be manually uncommented and/or can be specified @@ -19,5 +19,5 @@ #WANT_DEFAULT=Qt #WANT_DEFAULT=X11 -#end of multiw-1.370 +#end of multiw-1.500 #------------------------------------------------------------------------------ diff --git a/sys/unix/hints/include/multiw-2.370 b/sys/unix/hints/include/multiw-2.500 similarity index 96% rename from sys/unix/hints/include/multiw-2.370 rename to sys/unix/hints/include/multiw-2.500 index ca732f6c8..8cf1d2f2d 100644 --- a/sys/unix/hints/include/multiw-2.370 +++ b/sys/unix/hints/include/multiw-2.500 @@ -1,11 +1,11 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 multiw-2.370 $NHDT-Date: 1599337709 2020/09/05 20:28:29 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 3.7 multiw-2.500 $NHDT-Date: 1599337709 2020/09/05 20:28:29 $ $NHDT-Branch: NetHack-3.7 $ # # Sorts out support for multiple window ports (interfaces) to included in the build. # # Included from: -# hints/linux.370 -# hints/macOS.370 +# hints/linux.500 +# hints/macOS.500 # # The following will be set appropriately following this: # - WANT_WIN_XXX (at least one will be set; default is TTY) @@ -217,6 +217,6 @@ ifeq "$(NOCRASHREPORT)" "1" WINCFLAGS += -DNOCRASHREPORT endif -#end of hints/include/multiw-2.370 +#end of hints/include/multiw-2.500 #------------------------------------------------------------------------------ diff --git a/sys/unix/hints/include/response.370 b/sys/unix/hints/include/response.500 similarity index 91% rename from sys/unix/hints/include/response.370 rename to sys/unix/hints/include/response.500 index 4e893ea3e..0e842fba3 100644 --- a/sys/unix/hints/include/response.370 +++ b/sys/unix/hints/include/response.500 @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 response.370 $NHDT-Date: 1668359835 2022/11/13 17:17:15 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 3.7 response.500 $NHDT-Date: 1668359835 2022/11/13 17:17:15 $ $NHDT-Branch: NetHack-3.7 $ ifeq "$(RESP)" "1" USE_RESPONSEFILE=1 @@ -29,5 +29,5 @@ CLEAN_CC_RESPONSEFILE=rm -f $(CC_RESPONSEFILE); CLEAN_CXX_RESPONSEFILE=rm -f $(CXX_RESPONSEFILE); endif -#end of response.370 +#end of response.500 #------------------------------------------------------------------------------ diff --git a/sys/unix/hints/linux.370 b/sys/unix/hints/linux.500 similarity index 94% rename from sys/unix/hints/linux.370 rename to sys/unix/hints/linux.500 index ea239260e..e8ee0e2ff 100755 --- a/sys/unix/hints/linux.370 +++ b/sys/unix/hints/linux.500 @@ -1,4 +1,4 @@ -# NetHack 3.7 linux.370 $NHDT-Date: 1693519390 2023/08/31 22:03:10 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.61 $ +# NetHack 3.7 linux.500 $NHDT-Date: 1693519390 2023/08/31 22:03:10 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.61 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # @@ -13,12 +13,12 @@ # #-PRE -# linux.370 hints file provides a single-user build for Linux (such +# linux.500 hints file provides a single-user build for Linux (such # as Ubuntu focal). # note: '#-INCLUDE' is not just a comment -# multiw-1.370 contains sections 1 to 2 -#-INCLUDE multiw-1.370 +# multiw-1.500 contains sections 1 to 2 +#-INCLUDE multiw-1.500 HINTSVERSION := 370 @@ -52,7 +52,7 @@ USE_NOSTATICFN = 1 #USE_NONOSTATICFN = 1 #----------------------------------------------------------------------------- -#-INCLUDE cross-pre1.370 +#-INCLUDE cross-pre1.500 #----------------------------------------------------------------------------- @@ -60,12 +60,12 @@ USE_NOSTATICFN = 1 # you're reading this in Makefile augmented by hints, that may not be true). # -#-INCLUDE multiw-2.370 +#-INCLUDE multiw-2.500 -# compiler.370 contains compiler detection and adjustments common +# compiler.500 contains compiler detection and adjustments common # to both linux and macOS -#-INCLUDE compiler.370 +#-INCLUDE compiler.500 ifdef WANT_WIN_QT ifdef WANT_WIN_QT5 @@ -80,10 +80,10 @@ endif # g++ greater than or equal to 14 endif # WANT_WIN_QT6 endif # WANT_WIN_QT -# misc.370 must come after compiler.370 +# misc.500 must come after compiler.500 # and after QTDIR is defined. # -#-INCLUDE misc.370 +#-INCLUDE misc.500 ifeq "$(USE_ASAN)" "1" CFLAGS+=-fsanitize=address @@ -189,7 +189,7 @@ endif #HAVE_NCURSESW endif #WANT_WIN_CURSES # -#-INCLUDE multisnd1-pre.370 +#-INCLUDE multisnd1-pre.500 # ifeq "$(CCISCLANG)" "1" @@ -201,15 +201,15 @@ LIBCFLAGS+=-DSIG_RET_TYPE=__sighandler_t # gcc-specific ends endif -# WINCFLAGS set from multiw-2.370 -# SNDCFLAGS set from multisnd-pre.370 +# WINCFLAGS set from multiw-2.500 +# SNDCFLAGS set from multisnd-pre.500 CFLAGS+= $(WINCFLAGS) CFLAGS+= $(SNDCFLAGS) CFLAGS+= $(NHCFLAGS) CFLAGS+= $(LIBCFLAGS) -# WINCFLAGS set from multiw-2.370 -# SNDCFLAGS set from multisnd-pre.370 +# WINCFLAGS set from multiw-2.500 +# SNDCFLAGS set from multisnd-pre.500 CCXXFLAGS+= $(WINCFLAGS) CCXXFLAGS+= $(SNDCFLAGS) CCXXFLAGS+= $(NHCFLAGS) @@ -443,28 +443,28 @@ CHGRP=true # manpages directory MANDIR=/usr/share/man/man6 # -#-INCLUDE cross-pre2.370 +#-INCLUDE cross-pre2.500 # # -#-INCLUDE gbdates-pre.370 +#-INCLUDE gbdates-pre.500 # # -#-INCLUDE multisnd2-pre.370 +#-INCLUDE multisnd2-pre.500 # # -#-INCLUDE response.370 +#-INCLUDE response.500 # #-POST # -#-INCLUDE gbdates-post.370 +#-INCLUDE gbdates-post.500 # # -#-INCLUDE multisnd-post.370 +#-INCLUDE multisnd-post.500 # ifdef MAKEFILE_TOP @@ -488,6 +488,6 @@ $(TARGETPFX)libnhmain.o : ../sys/libnh/libnhmain.c $(HACK_H) endif # WANT_LIBNH # -#-INCLUDE cross-post.370 +#-INCLUDE cross-post.500 # diff --git a/sys/unix/hints/macOS.370 b/sys/unix/hints/macOS.500 similarity index 97% rename from sys/unix/hints/macOS.370 rename to sys/unix/hints/macOS.500 index 006c54a45..1bf55870e 100755 --- a/sys/unix/hints/macOS.370 +++ b/sys/unix/hints/macOS.500 @@ -1,4 +1,4 @@ -# NetHack 3.7 macOS.370 $NHDT-Date: 1693359574 2023/08/30 01:39:34 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.138 $ +# NetHack 3.7 macOS.500 $NHDT-Date: 1693359574 2023/08/30 01:39:34 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.138 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # @@ -18,7 +18,7 @@ # # note: '#-INCLUDE' is not just a comment; multiw-1 contains sections 1 to 2 -#-INCLUDE multiw-1.370 +#-INCLUDE multiw-1.500 HINTSVERSION := 370 @@ -55,14 +55,14 @@ endif # you're reading this in Makefile augmented by hints, that may not be true). # -#-INCLUDE cross-pre1.370 +#-INCLUDE cross-pre1.500 -#-INCLUDE multiw-2.370 +#-INCLUDE multiw-2.500 -# compiler.370 contains compiler detection and adjustments common +# compiler.500 contains compiler detection and adjustments common # to both linux and macOS -#-INCLUDE compiler.370 +#-INCLUDE compiler.500 ifdef WANT_WIN_QT ifeq "$(HAVE_HOMEBREW)" "1" @@ -94,10 +94,10 @@ CCXXFLAGS +=-Wno-c++20-attribute-extensions endif endif -# misc.370 must come after compiler.370 +# misc.500 must come after compiler.500 # and after QTDIR is defined -#-INCLUDE misc.370 +#-INCLUDE misc.500 # manpages directory MANDIR=/usr/local/share/man/man6 @@ -223,11 +223,11 @@ endif endif # -#-INCLUDE multisnd1-pre.370 +#-INCLUDE multisnd1-pre.500 # # although not currently doing anything for macOS, this is -# kept in for consistency with layout of linux.370 +# kept in for consistency with layout of linux.500 ifeq "$(CCISCLANG)" "1" # clang-specific starts # clang-specific ends @@ -237,15 +237,15 @@ else # gcc-specific ends endif -# WINCFLAGS set from multiw-2.370 -# SNDCFLAGS set from multisnd-pre.370 +# WINCFLAGS set from multiw-2.500 +# SNDCFLAGS set from multisnd-pre.500 CFLAGS+= $(PKGCFLAGS) $(WINCFLAGS) CFLAGS+= $(SNDCFLAGS) CFLAGS+= $(NHCFLAGS) CFLAGS+= $(LIBCFLAGS) -# WINCFLAGS set from multiw-2.370 -# SNDCFLAGS set from multisnd-pre.370 +# WINCFLAGS set from multiw-2.500 +# SNDCFLAGS set from multisnd-pre.500 CCXXFLAGS+= $(WINCFLAGS) CCXXFLAGS+= $(SNDCFLAGS) CCXXFLAGS+= $(NHCFLAGS) @@ -460,16 +460,16 @@ SYSCONFENSURE = (if ! test -f $(INSTDIR)/sysconf ; then \ # Install.Qt mentions a patch for macos - it's not there (it seems to be in the Qt binary # package under the docs directory). # -#-INCLUDE cross-pre2.370 +#-INCLUDE cross-pre2.500 # # -#-INCLUDE gbdates-pre.370 +#-INCLUDE gbdates-pre.500 # # -#-INCLUDE multisnd2-pre.370 +#-INCLUDE multisnd2-pre.500 # # -#-INCLUDE response.370 +#-INCLUDE response.500 # ifdef MAKEFILE_TOP @@ -539,10 +539,10 @@ endif # MAKEFILE_SRC #-POST # -#-INCLUDE gbdates-post.370 +#-INCLUDE gbdates-post.500 # # -#-INCLUDE multisnd-post.370 +#-INCLUDE multisnd-post.500 # ifdef MAKEFILE_TOP @@ -702,7 +702,7 @@ endif # WANT_BUNDLE # --- end of bundle --- # # -#-INCLUDE cross-post.370 +#-INCLUDE cross-post.500 # ifdef MAKEFILE_TOP From 7fc9baa8516ef9b19974156e93be1ee524464f66 Mon Sep 17 00:00:00 2001 From: Patric Mueller Date: Fri, 24 Apr 2026 15:00:53 +0200 Subject: [PATCH 025/702] Update wall colors for Enhanced symsets Making the walls in the mines brown and the walls in Fort Ludios light blue. --- dat/symbols | 88 ++++++++++++++++++++++++++--------------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/dat/symbols b/dat/symbols index 6233c83f5..58bb8d3fa 100644 --- a/dat/symbols +++ b/dat/symbols @@ -894,28 +894,28 @@ start: Enhanced1 G_tdwall_gehennom: U+252C/red # ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL G_tlwall_gehennom: U+2524/red # ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT G_trwall_gehennom: U+251C/red # ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT - G_vwall_knox: U+2502/150-75-0 # │ BOX DRAWINGS LIGHT VERTICAL - G_hwall_knox: U+2500/150-75-0 # ─ BOX DRAWINGS LIGHT HORIZONTAL - G_tlcorn_knox: U+250c/150-75-0 # ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT - G_trcorn_knox: U+2510/150-75-0 # ┠BOX DRAWINGS LIGHT DOWN AND LEFT - G_blcorn_knox: U+2514/150-75-0 # └ BOX DRAWINGS LIGHT UP AND RIGHT - G_brcorn_knox: U+2518/150-75-0 # ┘ BOX DRAWINGS LIGHT UP AND LEFT - G_crwall_knox: U+253C/150-75-0 # ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - G_tuwall_knox: U+2534/150-75-0 # ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL - G_tdwall_knox: U+252C/150-75-0 # ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - G_tlwall_knox: U+2524/150-75-0 # ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT - G_trwall_knox: U+251C/150-75-0 # ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT - G_vwall_mines: U+2502/113-126-142 # │ BOX DRAWINGS LIGHT VERTICAL - G_hwall_mines: U+2500/113-126-142 # ─ BOX DRAWINGS LIGHT HORIZONTAL - G_tlcorn_mines: U+250c/113-126-142 # ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT - G_trcorn_mines: U+2510/113-126-142 # ┠BOX DRAWINGS LIGHT DOWN AND LEFT - G_blcorn_mines: U+2514/113-126-142 # └ BOX DRAWINGS LIGHT UP AND RIGHT - G_brcorn_mines: U+2518/113-126-142 # ┘ BOX DRAWINGS LIGHT UP AND LEFT - G_crwall_mines: U+253C/113-126-142 # ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - G_tuwall_mines: U+2534/113-126-142 # ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL - G_tdwall_mines: U+252C/113-126-142 # ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - G_tlwall_mines: U+2524/113-126-142 # ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT - G_trwall_mines: U+251C/113-126-142 # ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT + G_vwall_knox: U+2502/126-230-230 # │ BOX DRAWINGS LIGHT VERTICAL + G_hwall_knox: U+2500/126-230-230 # ─ BOX DRAWINGS LIGHT HORIZONTAL + G_tlcorn_knox: U+250c/126-230-230 # ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT + G_trcorn_knox: U+2510/126-230-230 # ┠BOX DRAWINGS LIGHT DOWN AND LEFT + G_blcorn_knox: U+2514/126-230-230 # └ BOX DRAWINGS LIGHT UP AND RIGHT + G_brcorn_knox: U+2518/126-230-230 # ┘ BOX DRAWINGS LIGHT UP AND LEFT + G_crwall_knox: U+253C/126-230-230 # ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + G_tuwall_knox: U+2534/126-230-230 # ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL + G_tdwall_knox: U+252C/126-230-230 # ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + G_tlwall_knox: U+2524/126-230-230 # ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT + G_trwall_knox: U+251C/126-230-230 # ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT + G_vwall_mines: U+2502/190-126-0 # │ BOX DRAWINGS LIGHT VERTICAL + G_hwall_mines: U+2500/190-126-0 # ─ BOX DRAWINGS LIGHT HORIZONTAL + G_tlcorn_mines: U+250c/190-126-0 # ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT + G_trcorn_mines: U+2510/190-126-0 # ┠BOX DRAWINGS LIGHT DOWN AND LEFT + G_blcorn_mines: U+2514/190-126-0 # └ BOX DRAWINGS LIGHT UP AND RIGHT + G_brcorn_mines: U+2518/190-126-0 # ┘ BOX DRAWINGS LIGHT UP AND LEFT + G_crwall_mines: U+253C/190-126-0 # ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + G_tuwall_mines: U+2534/190-126-0 # ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL + G_tdwall_mines: U+252C/190-126-0 # ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + G_tlwall_mines: U+2524/190-126-0 # ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT + G_trwall_mines: U+251C/190-126-0 # ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT finish start: Enhanced2 @@ -997,28 +997,28 @@ start: Enhanced2 G_tdwall_gehennom: U+252C/red G_tlwall_gehennom: U+2524/red G_trwall_gehennom: U+251C/red - G_vwall_knox: U+2502/150-75-0 - G_hwall_knox: U+2500/150-75-0 - G_tlcorn_knox: U+250c/150-75-0 - G_trcorn_knox: U+2510/150-75-0 - G_blcorn_knox: U+2514/150-75-0 - G_brcorn_knox: U+2518/150-75-0 - G_crwall_knox: U+253C/150-75-0 - G_tuwall_knox: U+2534/150-75-0 - G_tdwall_knox: U+252C/150-75-0 - G_tlwall_knox: U+2524/150-75-0 - G_trwall_knox: U+251C/150-75-0 - G_vwall_mines: U+2502/113-126-142 - G_hwall_mines: U+2500/113-126-142 - G_tlcorn_mines: U+250c/113-126-142 - G_trcorn_mines: U+2510/113-126-142 - G_blcorn_mines: U+2514/113-126-142 - G_brcorn_mines: U+2518/113-126-142 - G_crwall_mines: U+253C/113-126-142 - G_tuwall_mines: U+2534/113-126-142 - G_tdwall_mines: U+252C/113-126-142 - G_tlwall_mines: U+2524/113-126-142 - G_trwall_mines: U+251C/113-126-142 + G_vwall_knox: U+2502/126-230-230 + G_hwall_knox: U+2500/126-230-230 + G_tlcorn_knox: U+250c/126-230-230 + G_trcorn_knox: U+2510/126-230-230 + G_blcorn_knox: U+2514/126-230-230 + G_brcorn_knox: U+2518/126-230-230 + G_crwall_knox: U+253C/126-230-230 + G_tuwall_knox: U+2534/126-230-230 + G_tdwall_knox: U+252C/126-230-230 + G_tlwall_knox: U+2524/126-230-230 + G_trwall_knox: U+251C/126-230-230 + G_vwall_mines: U+2502/190-126-0 + G_hwall_mines: U+2500/190-126-0 + G_tlcorn_mines: U+250c/190-126-0 + G_trcorn_mines: U+2510/190-126-0 + G_blcorn_mines: U+2514/190-126-0 + G_brcorn_mines: U+2518/190-126-0 + G_crwall_mines: U+253C/190-126-0 + G_tuwall_mines: U+2534/190-126-0 + G_tdwall_mines: U+252C/190-126-0 + G_tlwall_mines: U+2524/190-126-0 + G_trwall_mines: U+251C/190-126-0 finish start: AmigaFont From c25528dafe036a57817aa6b6fe0740a2876bc733 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 08:51:33 -0400 Subject: [PATCH 026/702] try to prevent panic encountering empty bones file --- src/bones.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bones.c b/src/bones.c index 2a3358678..3e484279f 100644 --- a/src/bones.c +++ b/src/bones.c @@ -659,16 +659,19 @@ getbones(void) return 0; } + restoreinfo.mread_flags = 1; /* return despite error for a bones file */ if (validate(nhfp, gb.bones, FALSE) != SF_UPTODATE) { if (!wizard) pline("Discarding unusable bones; no need to panic..."); ok = FALSE; + restoreinfo.mread_flags = 0; } else { ok = TRUE; if (wizard) { if (y_n("Get bones?") == 'n') { close_nhfile(nhfp); compress_bonesfile(); + restoreinfo.mread_flags = 0; return 0; } } @@ -684,6 +687,7 @@ getbones(void) close_nhfile(nhfp); compress_bonesfile(); /* ToDo: maybe unlink these problematic bones? */ + restoreinfo.mread_flags = 0; return 0; } if (strcmp(bonesid, oldbonesid) != 0) { @@ -695,6 +699,7 @@ getbones(void) pline1(errbuf); ok = FALSE; /* won't die of trickery */ } + restoreinfo.mread_flags = 0; trickery(errbuf); } else { struct monst *mtmp; @@ -726,6 +731,7 @@ getbones(void) fix_shop_damage(); } } + restoreinfo.mread_flags = 0; close_nhfile(nhfp); sanitize_engravings(); u.uroleplay.numbones++; From afefa38ddae021d400cf30064c56fd625cf3af25 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 08:56:11 -0400 Subject: [PATCH 027/702] update a couple of documentation files --- Cross-compiling | 42 +++++++++++++++++++++--------------------- doc/sound.txt | 2 +- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Cross-compiling b/Cross-compiling index 285e824b5..03f8ad207 100644 --- a/Cross-compiling +++ b/Cross-compiling @@ -1,6 +1,6 @@ -Cross-compiling NetHack 3.7 Last edit: February 18, 2023 +Cross-compiling NetHack 5.0 Last edit: April 26, 2026 -The NetHack 3.7 build process differs from the build process of previous +The NetHack 5.0 build process differs from the build process of previous versions in some important ways. Those differences make it possible to use a cross-compiler running on one platform (the "host" platform of the build) to produce a binary NetHack package that can execute on an entirely different @@ -9,7 +9,7 @@ platform. Part A Contents: A1. Why cross-compile? A2. Building NetHack 3.6 (before) - A3. Building NetHack 3.7 (going forward) + A3. Building NetHack 5.0 (going forward) A4. How was the build procedure reduced to 5 steps? A5. How can I help with the cross-compiling initiative? @@ -118,10 +118,10 @@ might, just might, be usable across platforms, but the chances are against it, and that certainly cannot be counted on. +------------------------------------------+ - | A3. Building NetHack 3.7 (going forward) | + | A3. Building NetHack 5.0 (going forward) | +------------------------------------------+ -Again, very generally, the build of NetHack in 3.7 requires the following +Again, very generally, the build of NetHack in 5.0 requires the following steps to be carried out: 1. Compile and link util/makedefs. @@ -152,7 +152,7 @@ executing the native compiler. | A4. How was the build procedure reduced to 5 steps? | +-----------------------------------------------------+ -The following are among several design changes planned in NetHack 3.7, +The following are among several design changes planned in NetHack 5.0, and these specific changes are what altered the build process to make cross-compiling possible: @@ -412,7 +412,7 @@ Using the cross-compiler, build the following targets: system support in *sys.c as well as others sources pertaining to your specific target platform(s). - b) Lua (mandatory in 3.7) + b) Lua (mandatory in 5.0) lib/lua-5.4.8/src @@ -479,7 +479,7 @@ Cross-compiler pre-built binary downloads: bash sys/msdos/fetch-cross-compiler.sh That script won't install anything, it just does file fetches and stores - them in subfolders of lib. The linux.370 and macOS.370 hints files are + them in subfolders of lib. The linux.500 and macOS.500 hints files are configured to find the cross-compiler there if you add CROSS_TO_MSDOS=1 on your make command line. @@ -490,12 +490,12 @@ Cross-compiler pre-built binary downloads: On your linux host: - cd sys/unix ; sh setup.sh hints/linux.370 ; cd ../.. + cd sys/unix ; sh setup.sh hints/linux.500 ; cd ../.. make fetch-lua On your macOS host: - cd sys/unix ; sh setup.sh hints/macOS.370 ; cd ../.. + cd sys/unix ; sh setup.sh hints/macOS.500 ; cd ../.. make fetch-lua The MSDOS cross-compile can then be carried out by specifying @@ -532,7 +532,7 @@ Disclaimer: This is a minimal recipe, just to help someone else get Cross-compiler used: bebbo's amiga-gcc Cross-compiler url: https://github.com/AmigaPorts/m68k-amigaos-gcc -Author of 3.7 support: Ingo Paschke +Author of 5.0 support: Ingo Paschke To our knowledge, a pre-built copy of the cross-compiler isn't available, so you will likely have to obtain the cross-compiler sources via git and @@ -577,22 +577,22 @@ Author of 3.7 support: Ingo Paschke On your linux host: - # Clone NetHack 3.7 source + # Clone NetHack 5.0 source cd NetHack - sys/unix/setup.sh sys/unix/hints/linux.370 + sys/unix/setup.sh sys/unix/hints/linux.500 make fetch-lua make CROSS_TO_AMIGA=1 fetch-regex make CROSS_TO_AMIGA=1 all make CROSS_TO_AMIGA=1 package - The distribution ZIP is created at targets/amiga/NH370AMI.ZIP. + The distribution ZIP is created at targets/amiga/NH500AMI.ZIP. On your macOS host, the Amiga cross-compile can be carried out by specifying CROSS_TO_AMIGA=1 on the make command line: - # Clone NetHack 3.7 source + # Clone NetHack 5.0 source cd NetHack - sys/unix/setup.sh sys/unix/hints/macOS.370 + sys/unix/setup.sh sys/unix/hints/macOS.500 make fetch-lua make CROSS_TO_AMIGA=1 fetch-regex make CROSS_TO_AMIGA=1 all @@ -665,12 +665,12 @@ Cross-compiler url: https://emscripten.org/docs/getting_started/downloads.html On your linux host, prepare to cross-compile NetHack as follows: - cd sys/unix ; sh setup.sh hints/linux.370 ; cd ../.. + cd sys/unix ; sh setup.sh hints/linux.500 ; cd ../.. make fetch-lua On your macOS host, prepare to cross-compile NetHack as follows: - cd sys/unix ; sh setup.sh hints/macOS.370 ; cd ../.. + cd sys/unix ; sh setup.sh hints/macOS.500 ; cd ../.. make fetch-lua Then, cross-compile to targets/wasm as follows: @@ -693,7 +693,7 @@ Cross-compiler url: https://emscripten.org/docs/getting_started/downloads.html The cross-compiler hints additions are enclosed inside ifdef sections and shouldn't interfere with the non-cross-compile builds using - hints/linux.370 or hints/macOS.370. + hints/linux.500 or hints/macOS.500. +--------------------------------+ @@ -712,7 +712,7 @@ Cross-compiler url: sudo apt install g++-mipsel-linux-gnu On your linux host, prepare to cross-compile NetHack as follows: - cd sys/unix ; sh setup.sh hints/linux.370 ; cd ../.. + cd sys/unix ; sh setup.sh hints/linux.500 ; cd ../.. make fetch-lua Then, cross-compile to targets/mips as follows: @@ -725,7 +725,7 @@ Cross-compiler url: The cross-compiler hints additions are enclosed inside ifdef sections and shouldn't interfere with the non-cross-compile builds using - hints/linux.370 or hints/macOS.370. + hints/linux.500 or hints/macOS.500. --- diff --git a/doc/sound.txt b/doc/sound.txt index 66ff2d0d0..dd302bac9 100644 --- a/doc/sound.txt +++ b/doc/sound.txt @@ -495,7 +495,7 @@ use the following guidelines: These hints files might require updates to include your new soundlib addition. You can look at what was done for macsound support - in sys/unix/hints/macOS.370 for inspiration. + in sys/unix/hints/macOS.500 for inspiration. sys/unix/NetHack.xcodeproj/project.pbxproj From 8ddfa958b172b4c548c1997a26426951f883ab19 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 09:09:14 -0400 Subject: [PATCH 028/702] HINTSVERSION --- sys/unix/Makefile.check | 2 +- sys/unix/hints/linux.500 | 4 ++-- sys/unix/hints/macOS.500 | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/unix/Makefile.check b/sys/unix/Makefile.check index 4265e5f5a..a2f32c78e 100755 --- a/sys/unix/Makefile.check +++ b/sys/unix/Makefile.check @@ -8,7 +8,7 @@ MKINCLPATH := $(SUPATH)hints/include/ # Expectations: # # HINTSFILE and HINTSINCLFILES are passed from the calling Makefile -# which is the case with the hints/*.370 and hints/include/*.370 +# which is the case with the hints/*.500 and hints/include/*.500 # set. # ifneq ("$(HINTSFILE)","") diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index e8ee0e2ff..c551c5279 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -1,4 +1,4 @@ -# NetHack 3.7 linux.500 $NHDT-Date: 1693519390 2023/08/31 22:03:10 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.61 $ +# NetHack 5.0 linux.500 $NHDT-Date: 1693519390 2023/08/31 22:03:10 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.61 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # @@ -20,7 +20,7 @@ # multiw-1.500 contains sections 1 to 2 #-INCLUDE multiw-1.500 -HINTSVERSION := 370 +HINTSVERSION := 500 ifdef MAKEFILE_TOP ifeq ($(MAKELEVEL),0) diff --git a/sys/unix/hints/macOS.500 b/sys/unix/hints/macOS.500 index 1bf55870e..e6f9db253 100755 --- a/sys/unix/hints/macOS.500 +++ b/sys/unix/hints/macOS.500 @@ -1,4 +1,4 @@ -# NetHack 3.7 macOS.500 $NHDT-Date: 1693359574 2023/08/30 01:39:34 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.138 $ +# NetHack 5.0 macOS.500 $NHDT-Date: 1693359574 2023/08/30 01:39:34 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.138 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # @@ -20,7 +20,7 @@ # note: '#-INCLUDE' is not just a comment; multiw-1 contains sections 1 to 2 #-INCLUDE multiw-1.500 -HINTSVERSION := 370 +HINTSVERSION := 500 ifdef MAKEFILE_TOP ifeq ($(MAKELEVEL),0) From 97b6fad509876e4220245bea4f287ff8a13e8e8b Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 09:25:42 -0400 Subject: [PATCH 029/702] "NetHack 3.7" to "NetHack 5.0" in doc include src sys win --- doc/Guidebook.mn | 2 +- doc/Guidebook.tex | 2 +- doc/config.nh | 2 +- doc/sound.txt | 2 +- doc/window.txt | 2 +- include/align.h | 2 +- include/artifact.h | 2 +- include/artilist.h | 2 +- include/attrib.h | 2 +- include/botl.h | 2 +- include/color.h | 2 +- include/config.h | 2 +- include/config1.h | 2 +- include/context.h | 2 +- include/coord.h | 2 +- include/cstd.h | 2 +- include/decl.h | 2 +- include/defsym.h | 2 +- include/dgn_file.h | 2 +- include/display.h | 2 +- include/dlb.h | 2 +- include/dungeon.h | 2 +- include/engrave.h | 2 +- include/extern.h | 2 +- include/flag.h | 2 +- include/fnamesiz.h | 2 +- include/func_tab.h | 2 +- include/global.h | 2 +- include/hack.h | 2 +- include/hacklib.h | 2 +- include/integer.h | 2 +- include/lint.h | 2 +- include/mail.h | 2 +- include/mextra.h | 2 +- include/mfndpos.h | 2 +- include/micro.h | 2 +- include/mkroom.h | 2 +- include/monattk.h | 2 +- include/mondata.h | 2 +- include/monflag.h | 2 +- include/monst.h | 2 +- include/monsters.h | 2 +- include/nhmd4.h | 2 +- include/nhregex.h | 2 +- include/obj.h | 2 +- include/objclass.h | 2 +- include/objects.h | 2 +- include/optlist.h | 2 +- include/patchlevel.h | 6 +++--- include/pcconf.h | 2 +- include/permonst.h | 2 +- include/prop.h | 2 +- include/quest.h | 2 +- include/rect.h | 2 +- include/region.h | 2 +- include/rm.h | 2 +- include/savefile.h | 2 +- include/seffects.h | 2 +- include/selvar.h | 2 +- include/sfmacros.h | 2 +- include/skills.h | 2 +- include/sndprocs.h | 2 +- include/sp_lev.h | 2 +- include/spell.h | 2 +- include/stairs.h | 2 +- include/sys.h | 2 +- include/tcap.h | 2 +- include/tile2x11.h | 2 +- include/tileset.h | 2 +- include/timeout.h | 2 +- include/tradstdc.h | 8 ++++---- include/trap.h | 2 +- include/unixconf.h | 2 +- include/vision.h | 2 +- include/vmsconf.h | 2 +- include/warnings.h | 2 +- include/weight.h | 2 +- include/winX.h | 2 +- include/winami.h | 2 +- include/wincurs.h | 2 +- include/windconf.h | 2 +- include/winprocs.h | 2 +- include/wintty.h | 2 +- include/wintype.h | 2 +- include/xwindow.h | 2 +- include/xwindowp.h | 2 +- include/you.h | 2 +- include/youprop.h | 2 +- src/allmain.c | 2 +- src/alloc.c | 2 +- src/apply.c | 2 +- src/artifact.c | 2 +- src/attrib.c | 2 +- src/ball.c | 2 +- src/bones.c | 2 +- src/botl.c | 2 +- src/calendar.c | 2 +- src/cfgfiles.c | 2 +- src/cmd.c | 2 +- src/coloratt.c | 2 +- src/date.c | 2 +- src/dbridge.c | 2 +- src/decl.c | 2 +- src/detect.c | 2 +- src/dig.c | 2 +- src/display.c | 2 +- src/dlb.c | 2 +- src/do.c | 2 +- src/do_name.c | 2 +- src/do_wear.c | 2 +- src/dog.c | 2 +- src/dogmove.c | 2 +- src/dokick.c | 2 +- src/dothrow.c | 2 +- src/drawing.c | 2 +- src/dungeon.c | 2 +- src/earlyarg.c | 2 +- src/eat.c | 2 +- src/end.c | 2 +- src/engrave.c | 2 +- src/exper.c | 2 +- src/explode.c | 2 +- src/extralev.c | 2 +- src/files.c | 2 +- src/fountain.c | 2 +- src/getpos.c | 2 +- src/glyphs.c | 2 +- src/hack.c | 2 +- src/hacklib.c | 2 +- src/iactions.c | 2 +- src/insight.c | 2 +- src/invent.c | 2 +- src/light.c | 2 +- src/lock.c | 2 +- src/mail.c | 2 +- src/makemon.c | 2 +- src/mcastu.c | 2 +- src/mdlib.c | 4 ++-- src/mhitm.c | 2 +- src/mhitu.c | 2 +- src/minion.c | 2 +- src/mklev.c | 2 +- src/mkmap.c | 2 +- src/mkmaze.c | 2 +- src/mkobj.c | 2 +- src/mkroom.c | 2 +- src/mon.c | 2 +- src/mondata.c | 2 +- src/monmove.c | 2 +- src/monst.c | 2 +- src/mplayer.c | 2 +- src/mthrowu.c | 2 +- src/muse.c | 2 +- src/music.c | 2 +- src/nhlobj.c | 2 +- src/nhlsel.c | 2 +- src/nhlua.c | 2 +- src/nhmd4.c | 2 +- src/o_init.c | 2 +- src/objects.c | 2 +- src/objnam.c | 2 +- src/options.c | 2 +- src/pager.c | 2 +- src/pickup.c | 2 +- src/pline.c | 2 +- src/polyself.c | 2 +- src/potion.c | 2 +- src/pray.c | 2 +- src/priest.c | 2 +- src/quest.c | 2 +- src/questpgr.c | 2 +- src/read.c | 2 +- src/rect.c | 2 +- src/region.c | 2 +- src/report.c | 2 +- src/restore.c | 2 +- src/rip.c | 2 +- src/rnd.c | 2 +- src/role.c | 2 +- src/rumors.c | 2 +- src/save.c | 2 +- src/selvar.c | 2 +- src/sfbase.c | 2 +- src/sfstruct.c | 2 +- src/shk.c | 2 +- src/shknam.c | 2 +- src/sit.c | 2 +- src/sounds.c | 2 +- src/sp_lev.c | 2 +- src/spell.c | 2 +- src/stairs.c | 2 +- src/steal.c | 2 +- src/steed.c | 2 +- src/strutil.c | 2 +- src/symbols.c | 2 +- src/sys.c | 2 +- src/teleport.c | 2 +- src/timeout.c | 2 +- src/topten.c | 2 +- src/track.c | 2 +- src/trap.c | 2 +- src/u_init.c | 2 +- src/uhitm.c | 2 +- src/utf8map.c | 2 +- src/vault.c | 2 +- src/version.c | 2 +- src/vision.c | 2 +- src/weapon.c | 2 +- src/were.c | 2 +- src/wield.c | 2 +- src/windows.c | 2 +- src/wizard.c | 2 +- src/wizcmds.c | 2 +- src/worm.c | 2 +- src/worn.c | 2 +- src/write.c | 2 +- src/zap.c | 2 +- sys/msdos/pctiles.h | 2 +- sys/msdos/pcvideo.h | 2 +- sys/msdos/portio.h | 2 +- sys/msdos/vesa.h | 2 +- sys/vms/Makefile.src | 2 +- sys/windows/GNUmakefile | 16 ++++++++-------- sys/windows/Makefile.nmake | 2 +- sys/windows/win10.h | 2 +- sys/windows/win32api.h | 2 +- sys/windows/winos.h | 2 +- util/mdgrep.h | 2 +- win/Qt/qt_post.h | 2 +- win/Qt/qt_pre.h | 2 +- win/Qt/qt_win.h | 2 +- win/curses/cursdial.h | 2 +- win/curses/cursinit.h | 2 +- win/curses/cursinvt.h | 2 +- win/curses/cursmesg.h | 2 +- win/curses/cursmisc.h | 2 +- win/curses/cursstat.h | 2 +- win/curses/curswins.h | 2 +- win/share/tile.h | 2 +- win/win32/mhaskyn.h | 2 +- win/win32/mhdlg.h | 2 +- win/win32/mhfont.h | 2 +- win/win32/mhinput.h | 2 +- win/win32/mhmain.h | 2 +- win/win32/mhmap.h | 2 +- win/win32/mhmenu.h | 2 +- win/win32/mhmsg.h | 2 +- win/win32/mhmsgwnd.h | 2 +- win/win32/mhrip.h | 2 +- win/win32/mhstatus.h | 2 +- win/win32/mhtext.h | 2 +- win/win32/winMS.h | 2 +- 252 files changed, 265 insertions(+), 265 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index cb9b023c2..5ed40d031 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -56,7 +56,7 @@ .ds h0 NetHack Guidebook .ds h1 \" empty .ds h2 % -.ds vr NetHack 3.7.0 +.ds vr NetHack 5.0.0 .ds f0 \*(vr .ds f1 \" empty .\"DO NOT REMOVE NH_DATESUB .ds f2 Date(%B %-d, %Y) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 54807f77d..28443d737 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -1,4 +1,4 @@ -% NetHack 3.7 Guidebook.tex $NHDT-Date: 1770881338 2026/02/11 23:28:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.596 $ */ +% NetHack 5.0 Guidebook.tex $NHDT-Date: 1770881338 2026/02/11 23:28:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.596 $ */ \documentclass[titlepage]{article} \usepackage[hidelinks]{hyperref} \usepackage{longtable} diff --git a/doc/config.nh b/doc/config.nh index 920074b3e..69c722135 100644 --- a/doc/config.nh +++ b/doc/config.nh @@ -2,7 +2,7 @@ # Copyright (c) 2016 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. # -# Sample run-time configuration file for NetHack 3.7.0 +# Sample run-time configuration file for NetHack 5.0.0 # usually named ".nethackrc" (note leading dot; location # depends upon the type of system nethack is running on). # diff --git a/doc/sound.txt b/doc/sound.txt index dd302bac9..608237c68 100644 --- a/doc/sound.txt +++ b/doc/sound.txt @@ -1,4 +1,4 @@ -NetHack 3.7 sound.txt $NHDT-Date: 1693253363 2023/08/28 20:09:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ +NetHack 5.0 sound.txt $NHDT-Date: 1693253363 2023/08/28 20:09:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ Introduction diff --git a/doc/window.txt b/doc/window.txt index d2f55793a..de0613ce4 100644 --- a/doc/window.txt +++ b/doc/window.txt @@ -1,4 +1,4 @@ -NetHack 3.7 window.txt $NHDT-Date: 1666390558 2022/10/21 22:15:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ +NetHack 5.0 window.txt $NHDT-Date: 1666390558 2022/10/21 22:15:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ Introduction diff --git a/include/align.h b/include/align.h index 0ccaf0e4d..9890ae41b 100644 --- a/include/align.h +++ b/include/align.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 align.h $NHDT-Date: 1604269810 2020/11/01 22:30:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 align.h $NHDT-Date: 1604269810 2020/11/01 22:30:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ /* Copyright (c) Mike Stephenson, Izchak Miller 1991. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/artifact.h b/include/artifact.h index 2db7270fb..fd55ff7a1 100644 --- a/include/artifact.h +++ b/include/artifact.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 artifact.h $NHDT-Date: 1602692711 2020/10/14 16:25:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 artifact.h $NHDT-Date: 1602692711 2020/10/14 16:25:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/artilist.h b/include/artilist.h index 0dd2181a8..53caaa7c0 100644 --- a/include/artilist.h +++ b/include/artilist.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 artilist.h $NHDT-Date: 1710957374 2024/03/20 17:56:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ +/* NetHack 5.0 artilist.h $NHDT-Date: 1710957374 2024/03/20 17:56:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/attrib.h b/include/attrib.h index 47ede7a3f..a5299f423 100644 --- a/include/attrib.h +++ b/include/attrib.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 attrib.h $NHDT-Date: 1596498527 2020/08/03 23:48:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 attrib.h $NHDT-Date: 1596498527 2020/08/03 23:48:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ /* Copyright 1988, Mike Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/botl.h b/include/botl.h index ad09d51ba..87fc7cdbd 100644 --- a/include/botl.h +++ b/include/botl.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 botl.h $NHDT-Date: 1694893330 2023/09/16 19:42:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.37 $ */ +/* NetHack 5.0 botl.h $NHDT-Date: 1694893330 2023/09/16 19:42:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.37 $ */ /* Copyright (c) Michael Allison, 2003 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/color.h b/include/color.h index 3efcfc022..3ad090346 100644 --- a/include/color.h +++ b/include/color.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 color.h $NHDT-Date: 1682205020 2023/04/22 23:10:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ */ +/* NetHack 5.0 color.h $NHDT-Date: 1682205020 2023/04/22 23:10:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ */ /* Copyright (c) Steve Linhart, Eric Raymond, 1989. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/config.h b/include/config.h index 5016c6702..83f0245c2 100644 --- a/include/config.h +++ b/include/config.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 config.h $NHDT-Date: 1710344316 2024/03/13 15:38:36 $ $NHDT-Branch: keni-staticfn $:$NHDT-Revision: 1.188 $ */ +/* NetHack 5.0 config.h $NHDT-Date: 1710344316 2024/03/13 15:38:36 $ $NHDT-Branch: keni-staticfn $:$NHDT-Revision: 1.188 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/config1.h b/include/config1.h index 402e0e73c..82650e9b6 100644 --- a/include/config1.h +++ b/include/config1.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 config1.h $NHDT-Date: 1596498530 2020/08/03 23:48:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.23 $ */ +/* NetHack 5.0 config1.h $NHDT-Date: 1596498530 2020/08/03 23:48:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.23 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/context.h b/include/context.h index c207c5a8d..1593d23ca 100644 --- a/include/context.h +++ b/include/context.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 context.h $NHDT-Date: 1753856387 2025/07/29 22:19:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.58 $ */ +/* NetHack 5.0 context.h $NHDT-Date: 1753856387 2025/07/29 22:19:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.58 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/coord.h b/include/coord.h index f20f74dd7..ba8867ccd 100644 --- a/include/coord.h +++ b/include/coord.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 coord.h $NHDT-Date: 1596498531 2020/08/03 23:48:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 coord.h $NHDT-Date: 1596498531 2020/08/03 23:48:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/cstd.h b/include/cstd.h index 54c950a40..7b7a71497 100644 --- a/include/cstd.h +++ b/include/cstd.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 cstd.h $NHDT-Date: 1725652996 2024/09/06 20:03:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ */ +/* NetHack 5.0 cstd.h $NHDT-Date: 1725652996 2024/09/06 20:03:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/decl.h b/include/decl.h index 1ea39d6f9..aa02c64f7 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.h $NHDT-Date: 1725653004 2024/09/06 20:03:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.377 $ */ +/* NetHack 5.0 decl.h $NHDT-Date: 1725653004 2024/09/06 20:03:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.377 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/defsym.h b/include/defsym.h index 8229ab400..598b2871b 100644 --- a/include/defsym.h +++ b/include/defsym.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 defsym.h $NHDT-Date: 1725653007 2024/09/06 20:03:27 $ $NHDT-Branch: NetHack-3.7 $ $NHDT-Revision: 1.25 $ */ +/* NetHack 5.0 defsym.h $NHDT-Date: 1725653007 2024/09/06 20:03:27 $ $NHDT-Branch: NetHack-3.7 $ $NHDT-Revision: 1.25 $ */ /* Copyright (c) 2016 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/dgn_file.h b/include/dgn_file.h index 4a94e0cdc..1a214e7c9 100644 --- a/include/dgn_file.h +++ b/include/dgn_file.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 dgn_file.h $NHDT-Date: 1596498533 2020/08/03 23:48:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 dgn_file.h $NHDT-Date: 1596498533 2020/08/03 23:48:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) 1989 by M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/display.h b/include/display.h index beac064c0..da8009f26 100644 --- a/include/display.h +++ b/include/display.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 display.h $NHDT-Date: 1725653008 2024/09/06 20:03:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.106 $ */ +/* NetHack 5.0 display.h $NHDT-Date: 1725653008 2024/09/06 20:03:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.106 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */ /* and Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/dlb.h b/include/dlb.h index 2fff03046..5be1bcc19 100644 --- a/include/dlb.h +++ b/include/dlb.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 dlb.h $NHDT-Date: 1596498534 2020/08/03 23:48:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 dlb.h $NHDT-Date: 1596498534 2020/08/03 23:48:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1993. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/dungeon.h b/include/dungeon.h index f364bcd8e..a19e6e40e 100644 --- a/include/dungeon.h +++ b/include/dungeon.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 dungeon.h $NHDT-Date: 1685863327 2023/06/04 07:22:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ +/* NetHack 5.0 dungeon.h $NHDT-Date: 1685863327 2023/06/04 07:22:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/engrave.h b/include/engrave.h index 33ee19c80..2437d4e44 100644 --- a/include/engrave.h +++ b/include/engrave.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 engrave.h $NHDT-Date: 1596498535 2020/08/03 23:48:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 engrave.h $NHDT-Date: 1596498535 2020/08/03 23:48:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/extern.h b/include/extern.h index d17497325..d59035f37 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1523 $ */ +/* NetHack 5.0 extern.h $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1523 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/flag.h b/include/flag.h index f48b4693c..9e849478e 100644 --- a/include/flag.h +++ b/include/flag.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 flag.h $NHDT-Date: 1744860497 2025/04/16 19:28:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.251 $ */ +/* NetHack 5.0 flag.h $NHDT-Date: 1744860497 2025/04/16 19:28:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.251 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/fnamesiz.h b/include/fnamesiz.h index ed2d264b8..338f55292 100644 --- a/include/fnamesiz.h +++ b/include/fnamesiz.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 fnamesiz.h $NHDT-Date: 1580310580 2020/01/29 15:09:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ */ +/* NetHack 5.0 fnamesiz.h $NHDT-Date: 1580310580 2020/01/29 15:09:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ */ /*-Copyright (c) Michael Allison, 2020. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/func_tab.h b/include/func_tab.h index e5438ce58..7992a55c0 100644 --- a/include/func_tab.h +++ b/include/func_tab.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 func_tab.h $NHDT-Date: 1684791775 2023/05/22 21:42:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 5.0 func_tab.h $NHDT-Date: 1684791775 2023/05/22 21:42:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/global.h b/include/global.h index 47e783742..88168858e 100644 --- a/include/global.h +++ b/include/global.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 global.h $NHDT-Date: 1704225560 2024/01/02 19:59:20 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.159 $ */ +/* NetHack 5.0 global.h $NHDT-Date: 1704225560 2024/01/02 19:59:20 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.159 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/hack.h b/include/hack.h index 1a8e07f14..64027849c 100644 --- a/include/hack.h +++ b/include/hack.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 hack.h $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.266 $ */ +/* NetHack 5.0 hack.h $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.266 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/hacklib.h b/include/hacklib.h index 18630e1b1..2e3ac679a 100644 --- a/include/hacklib.h +++ b/include/hacklib.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 hacklib.h $NHDT-Date: 1725653010 2024/09/06 20:03:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 hacklib.h $NHDT-Date: 1725653010 2024/09/06 20:03:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/integer.h b/include/integer.h index f12cf21bf..479ccc9bd 100644 --- a/include/integer.h +++ b/include/integer.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 integer.h $NHDT-Date: 1720397754 2024/07/08 00:15:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 integer.h $NHDT-Date: 1720397754 2024/07/08 00:15:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) 2016 by Michael Allison */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/lint.h b/include/lint.h index 76d9aee7a..235f05fc2 100644 --- a/include/lint.h +++ b/include/lint.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 lint.h $NHDT-Date: 1655631029 2022/06/19 09:30:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ */ +/* NetHack 5.0 lint.h $NHDT-Date: 1655631029 2022/06/19 09:30:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ */ /* Copyright (c) 2016 by Robert Patrick Rankin */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/mail.h b/include/mail.h index 4b3ec2d05..3564c020f 100644 --- a/include/mail.h +++ b/include/mail.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mail.h $NHDT-Date: 1596498544 2020/08/03 23:49:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 mail.h $NHDT-Date: 1596498544 2020/08/03 23:49:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) 2015 by Kenneth Lorber */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/mextra.h b/include/mextra.h index 8472a5ad2..546c94c71 100644 --- a/include/mextra.h +++ b/include/mextra.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mextra.h $NHDT-Date: 1720717969 2024/07/11 17:12:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ */ +/* NetHack 5.0 mextra.h $NHDT-Date: 1720717969 2024/07/11 17:12:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/mfndpos.h b/include/mfndpos.h index a1ec75461..d4eac8da5 100644 --- a/include/mfndpos.h +++ b/include/mfndpos.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mfndpos.h $NHDT-Date: 1596498546 2020/08/03 23:49:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 mfndpos.h $NHDT-Date: 1596498546 2020/08/03 23:49:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2005. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/micro.h b/include/micro.h index fd10be51b..02067b063 100644 --- a/include/micro.h +++ b/include/micro.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 micro.h $NHDT-Date: 1596498546 2020/08/03 23:49:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 micro.h $NHDT-Date: 1596498546 2020/08/03 23:49:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) 2015 by Kenneth Lorber */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/mkroom.h b/include/mkroom.h index 883d97020..9b82807e8 100644 --- a/include/mkroom.h +++ b/include/mkroom.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mkroom.h $NHDT-Date: 1725653011 2024/09/06 20:03:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.33 $ */ +/* NetHack 5.0 mkroom.h $NHDT-Date: 1725653011 2024/09/06 20:03:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.33 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/monattk.h b/include/monattk.h index 912d93284..3e2d65690 100644 --- a/include/monattk.h +++ b/include/monattk.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 monattk.h $NHDT-Date: 1596498548 2020/08/03 23:49:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 monattk.h $NHDT-Date: 1596498548 2020/08/03 23:49:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ /* NetHack may be freely redistributed. See license for details. */ /* Copyright 1988, M. Stephenson */ diff --git a/include/mondata.h b/include/mondata.h index 430b5e83d..05f276fa8 100644 --- a/include/mondata.h +++ b/include/mondata.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mondata.h $NHDT-Date: 1703845738 2023/12/29 10:28:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.63 $ */ +/* NetHack 5.0 mondata.h $NHDT-Date: 1703845738 2023/12/29 10:28:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.63 $ */ /* Copyright (c) 1989 Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/monflag.h b/include/monflag.h index 18c2e4256..602588b54 100644 --- a/include/monflag.h +++ b/include/monflag.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 monflag.h $NHDT-Date: 1596498549 2020/08/03 23:49:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ +/* NetHack 5.0 monflag.h $NHDT-Date: 1596498549 2020/08/03 23:49:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ /* Copyright (c) 1989 Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/monst.h b/include/monst.h index 6b3262706..d73afd868 100644 --- a/include/monst.h +++ b/include/monst.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 monst.h $NHDT-Date: 1738640524 2025/02/03 19:42:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.67 $ */ +/* NetHack 5.0 monst.h $NHDT-Date: 1738640524 2025/02/03 19:42:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.67 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/monsters.h b/include/monsters.h index c7605d3b6..01bc6cc3a 100644 --- a/include/monsters.h +++ b/include/monsters.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 monsters.h $NHDT-Date: 1723945838 2024/08/18 01:50:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.124 $ */ +/* NetHack 5.0 monsters.h $NHDT-Date: 1723945838 2024/08/18 01:50:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.124 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/nhmd4.h b/include/nhmd4.h index f235a1bb7..d9751b56d 100644 --- a/include/nhmd4.h +++ b/include/nhmd4.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 nhmd4.h $NHDT-Date: 1708811386 2024/02/24 21:49:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 nhmd4.h $NHDT-Date: 1708811386 2024/02/24 21:49:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ /*- Copyright (c) Kenneth Lorber, Kensington, Maryland, 2024 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/nhregex.h b/include/nhregex.h index 6dc989213..5f6c4c2ca 100644 --- a/include/nhregex.h +++ b/include/nhregex.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 nhregex.h $NHDT-Date: $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: $ */ +/* NetHack 5.0 nhregex.h $NHDT-Date: $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: $ */ /* NetHack may be freely redistributed. See license for details. */ #ifndef NHREGEX_H diff --git a/include/obj.h b/include/obj.h index d9ef83d21..8d95bb007 100644 --- a/include/obj.h +++ b/include/obj.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 obj.h $NHDT-Date: 1718999845 2024/06/21 19:57:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ +/* NetHack 5.0 obj.h $NHDT-Date: 1718999845 2024/06/21 19:57:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/objclass.h b/include/objclass.h index fa210f519..96468187a 100644 --- a/include/objclass.h +++ b/include/objclass.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 objclass.h $NHDT-Date: 1596498553 2020/08/03 23:49:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.22 $ */ +/* NetHack 5.0 objclass.h $NHDT-Date: 1596498553 2020/08/03 23:49:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.22 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/objects.h b/include/objects.h index 41076db28..d9ae062c5 100644 --- a/include/objects.h +++ b/include/objects.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 objects.h $NHDT-Date: 1749097644 2025/06/04 20:27:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ +/* NetHack 5.0 objects.h $NHDT-Date: 1749097644 2025/06/04 20:27:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ /* Copyright (c) Mike Threepoint, 1989. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/optlist.h b/include/optlist.h index 4d3474a4b..935d5943a 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 optlist.h */ +/* NetHack 5.0 optlist.h */ /* NetHack may be freely redistributed. See license for details. */ #ifndef OPTLIST_H diff --git a/include/patchlevel.h b/include/patchlevel.h index d9f25fea4..68e54dbf5 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 patchlevel.h $NHDT-Date: 1753856387 2025/07/29 22:19:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.288 $ */ +/* NetHack 5.0 patchlevel.h $NHDT-Date: 1753856387 2025/07/29 22:19:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.288 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -6,7 +6,7 @@ #ifndef PATCHLEVEL_H #define PATCHLEVEL_H -/* NetHack 3.7.x */ +/* NetHack 5.0.x */ #define VERSION_MAJOR 3 #define VERSION_MINOR 7 /* @@ -65,7 +65,7 @@ /* Version 3.7.x */ /* - * NetHack 3.7.0, + * NetHack 5.0.0, * */ diff --git a/include/pcconf.h b/include/pcconf.h index 6736d8d9d..e1fd14cfe 100644 --- a/include/pcconf.h +++ b/include/pcconf.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 pcconf.h $NHDT-Date: 1596498554 2020/08/03 23:49:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.28 $ */ +/* NetHack 5.0 pcconf.h $NHDT-Date: 1596498554 2020/08/03 23:49:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.28 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/permonst.h b/include/permonst.h index fbc135c41..895e4f964 100644 --- a/include/permonst.h +++ b/include/permonst.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 permonst.h $NHDT-Date: 1725653014 2024/09/06 20:03:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ */ +/* NetHack 5.0 permonst.h $NHDT-Date: 1725653014 2024/09/06 20:03:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/prop.h b/include/prop.h index 16b7efd50..5b846698e 100644 --- a/include/prop.h +++ b/include/prop.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 prop.h $NHDT-Date: 1702274027 2023/12/11 05:53:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 5.0 prop.h $NHDT-Date: 1702274027 2023/12/11 05:53:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ /* Copyright (c) 1989 Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/quest.h b/include/quest.h index 77af3049f..5ab48a756 100644 --- a/include/quest.h +++ b/include/quest.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 quest.h $NHDT-Date: 1596498556 2020/08/03 23:49:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 quest.h $NHDT-Date: 1596498556 2020/08/03 23:49:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) Mike Stephenson 1991. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/rect.h b/include/rect.h index 5544db272..b8395c5f4 100644 --- a/include/rect.h +++ b/include/rect.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 rect.h $NHDT-Date: 1596498557 2020/08/03 23:49:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 rect.h $NHDT-Date: 1596498557 2020/08/03 23:49:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) 1990 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/region.h b/include/region.h index b9b7ced43..ba82dd710 100644 --- a/include/region.h +++ b/include/region.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 region.h $NHDT-Date: 1596498557 2020/08/03 23:49:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 region.h $NHDT-Date: 1596498557 2020/08/03 23:49:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ /* Copyright (c) 1996 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/rm.h b/include/rm.h index 0819b4d52..e97822b4c 100644 --- a/include/rm.h +++ b/include/rm.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 rm.h $NHDT-Date: 1745114235 2025/04/19 17:57:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.120 $ */ +/* NetHack 5.0 rm.h $NHDT-Date: 1745114235 2025/04/19 17:57:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.120 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/savefile.h b/include/savefile.h index dc569c771..bfaea951d 100644 --- a/include/savefile.h +++ b/include/savefile.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 savefile.h $NHDT-Date: 1738638877 2025/02/03 19:14:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1476 $ */ +/* NetHack 5.0 savefile.h $NHDT-Date: 1738638877 2025/02/03 19:14:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1476 $ */ /* Copyright (c) Michael Allison, 2025. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/seffects.h b/include/seffects.h index 0774209b0..bd62c9543 100644 --- a/include/seffects.h +++ b/include/seffects.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 seffects.h $NHDT-Date: 1693253118 2023/08/28 20:05:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ */ +/* NetHack 5.0 seffects.h $NHDT-Date: 1693253118 2023/08/28 20:05:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ */ /* Copyright (c) Michael Allison, 2023 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/selvar.h b/include/selvar.h index 2551efa34..2854173f4 100644 --- a/include/selvar.h +++ b/include/selvar.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 selvar.h $NHDT-Date: 1709677544 2024/03/05 22:25:44 $ $NHDT-Branch: keni-mdlib-followup $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 selvar.h $NHDT-Date: 1709677544 2024/03/05 22:25:44 $ $NHDT-Branch: keni-mdlib-followup $:$NHDT-Revision: 1.0 $ */ /* Copyright (c) 2024 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/sfmacros.h b/include/sfmacros.h index 752b74978..d0bedf69f 100644 --- a/include/sfmacros.h +++ b/include/sfmacros.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 sfmacros.h $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ +/* NetHack 5.0 sfmacros.h $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ /* Copyright (c) Michael Allison, 2025. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/skills.h b/include/skills.h index 307694cfb..40204aa4f 100644 --- a/include/skills.h +++ b/include/skills.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 skills.h $NHDT-Date: 1596498559 2020/08/03 23:49:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.16 $ */ +/* NetHack 5.0 skills.h $NHDT-Date: 1596498559 2020/08/03 23:49:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.16 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985-1999. */ /*-Copyright (c) Pasi Kallinen, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/sndprocs.h b/include/sndprocs.h index e27793e45..d09e4e1e7 100755 --- a/include/sndprocs.h +++ b/include/sndprocs.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 sndprocs.h $NHDT-Date: 1725653015 2024/09/06 20:03:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ */ +/* NetHack 5.0 sndprocs.h $NHDT-Date: 1725653015 2024/09/06 20:03:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ */ /* Copyright (c) Michael Allison, 2022 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/sp_lev.h b/include/sp_lev.h index 52e89978c..3aec7c2cf 100644 --- a/include/sp_lev.h +++ b/include/sp_lev.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 sp_lev.h $NHDT-Date: 1622361649 2021/05/30 08:00:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ +/* NetHack 5.0 sp_lev.h $NHDT-Date: 1622361649 2021/05/30 08:00:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/spell.h b/include/spell.h index 9299282e2..8f68f5c94 100644 --- a/include/spell.h +++ b/include/spell.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 spell.h $NHDT-Date: 1646838388 2022/03/09 15:06:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 spell.h $NHDT-Date: 1646838388 2022/03/09 15:06:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ /* Copyright 1986, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/stairs.h b/include/stairs.h index bb37a4dee..e52ad7075 100644 --- a/include/stairs.h +++ b/include/stairs.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 stairs.h $NHDT-Date: 1685863327 2023/06/04 07:22:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ +/* NetHack 5.0 stairs.h $NHDT-Date: 1685863327 2023/06/04 07:22:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ /* Copyright (c) 2024 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/sys.h b/include/sys.h index 63f7f5394..2ea704cdb 100644 --- a/include/sys.h +++ b/include/sys.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 sys.h $NHDT-Date: 1693083207 2023/08/26 20:53:27 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.41 $ */ +/* NetHack 5.0 sys.h $NHDT-Date: 1693083207 2023/08/26 20:53:27 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.41 $ */ /* Copyright (c) Kenneth Lorber, Kensington, Maryland, 2008. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/tcap.h b/include/tcap.h index 896c00e6f..47cfd95fc 100644 --- a/include/tcap.h +++ b/include/tcap.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 tcap.h $NHDT-Date: 1596498562 2020/08/03 23:49:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 tcap.h $NHDT-Date: 1596498562 2020/08/03 23:49:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1989. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/tile2x11.h b/include/tile2x11.h index 2839e8946..ffdfda291 100644 --- a/include/tile2x11.h +++ b/include/tile2x11.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 tile2x11.h $NHDT-Date: 1597274123 2020/08/12 23:15:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 tile2x11.h $NHDT-Date: 1597274123 2020/08/12 23:15:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) 2002 by David Cohrs */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/tileset.h b/include/tileset.h index d4422203d..ef432732f 100644 --- a/include/tileset.h +++ b/include/tileset.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 tileset.h $NHDT-Date: 1596498564 2020/08/03 23:49:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ */ +/* NetHack 5.0 tileset.h $NHDT-Date: 1596498564 2020/08/03 23:49:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ */ /* Copyright (c) Ray Chason, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/timeout.h b/include/timeout.h index 0712c2e93..946959ae9 100644 --- a/include/timeout.h +++ b/include/timeout.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 timeout.h $NHDT-Date: 1705087443 2024/01/12 19:24:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.23 $ */ +/* NetHack 5.0 timeout.h $NHDT-Date: 1705087443 2024/01/12 19:24:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.23 $ */ /* Copyright 1994, Dean Luick */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/tradstdc.h b/include/tradstdc.h index 4c304b625..f4532aeba 100644 --- a/include/tradstdc.h +++ b/include/tradstdc.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 tradstdc.h $NHDT-Date: 1744938651 2025/04/17 17:10:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.67 $ */ +/* NetHack 5.0 tradstdc.h $NHDT-Date: 1744938651 2025/04/17 17:10:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.67 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -317,7 +317,7 @@ typedef genericptr genericptr_t; /* (void *) or (char *) */ * Language * Standard * - * NetHack 3.7 range + * NetHack 5.0 range * / * / * C2y X NetHack 3.6 and earlier range @@ -328,7 +328,7 @@ typedef genericptr genericptr_t; /* (void *) or (char *) */ * C89 X * * - * The NetHack 3.7 source code currently makes use of the following + * The NetHack 5.0 source code currently makes use of the following * C99 (and above) language features: * * commas at the end of enumerator lists @@ -337,7 +337,7 @@ typedef genericptr genericptr_t; /* (void *) or (char *) */ * variadic macros * 'long long' * - * The NetHack 3.7 source code adheres to the following greater-than C99 + * The NetHack 5.0 source code adheres to the following greater-than C99 * language restrictions: * * Removal of K&R function definitions diff --git a/include/trap.h b/include/trap.h index 206951baa..d756cde03 100644 --- a/include/trap.h +++ b/include/trap.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 trap.h $NHDT-Date: 1670316586 2022/12/06 08:49:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.31 $ */ +/* NetHack 5.0 trap.h $NHDT-Date: 1670316586 2022/12/06 08:49:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.31 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/unixconf.h b/include/unixconf.h index 1e346d3d5..e7ee91565 100644 --- a/include/unixconf.h +++ b/include/unixconf.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 unixconf.h $NHDT-Date: 1711213886 2024/03/23 17:11:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.57 $ */ +/* NetHack 5.0 unixconf.h $NHDT-Date: 1711213886 2024/03/23 17:11:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.57 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/vision.h b/include/vision.h index a9be002dc..b0728f763 100644 --- a/include/vision.h +++ b/include/vision.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 vision.h $NHDT-Date: 1666478832 2022/10/22 22:47:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 vision.h $NHDT-Date: 1666478832 2022/10/22 22:47:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/vmsconf.h b/include/vmsconf.h index 57b8a7b05..4fb77d24c 100644 --- a/include/vmsconf.h +++ b/include/vmsconf.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 vmsconf.h $NHDT-Date: 1596498569 2020/08/03 23:49:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.33 $ */ +/* NetHack 5.0 vmsconf.h $NHDT-Date: 1596498569 2020/08/03 23:49:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.33 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/warnings.h b/include/warnings.h index b35a037ae..9f2858a3d 100644 --- a/include/warnings.h +++ b/include/warnings.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 warnings.h $NHDT-Date: 1596498562 2020/08/03 23:49:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 5.0 warnings.h $NHDT-Date: 1596498562 2020/08/03 23:49:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ /* Copyright (c) Michael Allison, 2021. */ #ifndef WARNINGS_H diff --git a/include/weight.h b/include/weight.h index a404eb1af..967ba0f0e 100644 --- a/include/weight.h +++ b/include/weight.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 weight.h $NHDT-Date: 1742427965 2025/03/19 23:46:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ */ +/* NetHack 5.0 weight.h $NHDT-Date: 1742427965 2025/03/19 23:46:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ */ /* Copyright (c) Michael Allison, 2025. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/winX.h b/include/winX.h index 295abaa8d..495a2d29f 100644 --- a/include/winX.h +++ b/include/winX.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 winX.h $NHDT-Date: 1740795096 2025/02/28 18:11:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.65 $ */ +/* NetHack 5.0 winX.h $NHDT-Date: 1740795096 2025/02/28 18:11:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.65 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/winami.h b/include/winami.h index 1cfd85078..525f53d6d 100644 --- a/include/winami.h +++ b/include/winami.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 winami.h $NHDT-Date: 1596498569 2020/08/03 23:49:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 winami.h $NHDT-Date: 1596498569 2020/08/03 23:49:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1991. */ /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1992, 1993. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/wincurs.h b/include/wincurs.h index ad1a333fa..0911cf11c 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 wincurs.h */ +/* NetHack 5.0 wincurs.h */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/windconf.h b/include/windconf.h index 81ad8baeb..c82b1c8f4 100644 --- a/include/windconf.h +++ b/include/windconf.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 windconf.h $NHDT-Date: 1596498552 2020/08/03 23:49:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.89 $ */ +/* NetHack 5.0 windconf.h $NHDT-Date: 1596498552 2020/08/03 23:49:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.89 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/winprocs.h b/include/winprocs.h index a60a00c77..bbf97c91d 100644 --- a/include/winprocs.h +++ b/include/winprocs.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 winprocs.h $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.83 $ */ +/* NetHack 5.0 winprocs.h $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.83 $ */ /* Copyright (c) David Cohrs, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/wintty.h b/include/wintty.h index c0c5d842e..9d9e32eef 100644 --- a/include/wintty.h +++ b/include/wintty.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 wintty.h $NHDT-Date: 1656014599 2022/06/23 20:03:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.55 $ */ +/* NetHack 5.0 wintty.h $NHDT-Date: 1656014599 2022/06/23 20:03:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.55 $ */ /* Copyright (c) David Cohrs, 1991,1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/wintype.h b/include/wintype.h index 6b94bef64..3ec938d30 100644 --- a/include/wintype.h +++ b/include/wintype.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 wintype.h $NHDT-Date: 1717880364 2024/06/08 20:59:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.52 $ */ +/* NetHack 5.0 wintype.h $NHDT-Date: 1717880364 2024/06/08 20:59:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.52 $ */ /* Copyright (c) David Cohrs, 1991 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/xwindow.h b/include/xwindow.h index c388fb54b..72edd084f 100644 --- a/include/xwindow.h +++ b/include/xwindow.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 xwindow.h $NHDT-Date: 1596498574 2020/08/03 23:49:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 xwindow.h $NHDT-Date: 1596498574 2020/08/03 23:49:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/xwindowp.h b/include/xwindowp.h index 8aa0fb37f..6eb8bfdda 100644 --- a/include/xwindowp.h +++ b/include/xwindowp.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 xwindowp.h $NHDT-Date: 1596498575 2020/08/03 23:49:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 xwindowp.h $NHDT-Date: 1596498575 2020/08/03 23:49:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/you.h b/include/you.h index 1f4b9c592..0c9368b76 100644 --- a/include/you.h +++ b/include/you.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 you.h $NHDT-Date: 1702349061 2023/12/12 02:44:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.75 $ */ +/* NetHack 5.0 you.h $NHDT-Date: 1702349061 2023/12/12 02:44:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.75 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/youprop.h b/include/youprop.h index 98862dead..777fc6538 100644 --- a/include/youprop.h +++ b/include/youprop.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 youprop.h $NHDT-Date: 1725653018 2024/09/06 20:03:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.45 $ */ +/* NetHack 5.0 youprop.h $NHDT-Date: 1725653018 2024/09/06 20:03:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.45 $ */ /* Copyright (c) 1989 Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/allmain.c b/src/allmain.c index 530840a1a..95de81a1e 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 allmain.c $NHDT-Date: 1771213100 2026/02/15 19:38:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.286 $ */ +/* NetHack 5.0 allmain.c $NHDT-Date: 1771213100 2026/02/15 19:38:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.286 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/alloc.c b/src/alloc.c index 05dfb502f..84ee660f9 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 alloc.c $NHDT-Date: 1737281026 2025/01/19 02:03:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.38 $ */ +/* NetHack 5.0 alloc.c $NHDT-Date: 1737281026 2025/01/19 02:03:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.38 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/apply.c b/src/apply.c index 7f0d4320e..606d31054 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 apply.c $NHDT-Date: 1769342601 2026/01/25 04:03:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.475 $ */ +/* NetHack 5.0 apply.c $NHDT-Date: 1769342601 2026/01/25 04:03:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.475 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/artifact.c b/src/artifact.c index 17715e10c..77f3b20dd 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 artifact.c $NHDT-Date: 1715889721 2024/05/16 20:02:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.236 $ */ +/* NetHack 5.0 artifact.c $NHDT-Date: 1715889721 2024/05/16 20:02:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.236 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/attrib.c b/src/attrib.c index bebb46327..cd33557ad 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 attrib.c $NHDT-Date: 1777000050 2026/04/23 19:07:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.137 $ */ +/* NetHack 5.0 attrib.c $NHDT-Date: 1777000050 2026/04/23 19:07:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.137 $ */ /* Copyright 1988, 1989, 1990, 1992, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/ball.c b/src/ball.c index 069a71ce4..b622cb691 100644 --- a/src/ball.c +++ b/src/ball.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 ball.c $NHDT-Date: 1596498150 2020/08/03 23:42:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.51 $ */ +/* NetHack 5.0 ball.c $NHDT-Date: 1596498150 2020/08/03 23:42:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.51 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) David Cohrs, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/bones.c b/src/bones.c index 3e484279f..e6d67d229 100644 --- a/src/bones.c +++ b/src/bones.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 bones.c $NHDT-Date: 1701500709 2023/12/02 07:05:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.129 $ */ +/* NetHack 5.0 bones.c $NHDT-Date: 1701500709 2023/12/02 07:05:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.129 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/botl.c b/src/botl.c index b6e72c896..85e5b7700 100644 --- a/src/botl.c +++ b/src/botl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 botl.c $NHDT-Date: 1769839231 2026/01/30 22:00:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.277 $ */ +/* NetHack 5.0 botl.c $NHDT-Date: 1769839231 2026/01/30 22:00:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.277 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/calendar.c b/src/calendar.c index 5a5287b2a..deea28daf 100644 --- a/src/calendar.c +++ b/src/calendar.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 calendar.c $NHDT-Date: 1706213796 2024/01/25 20:16:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ +/* NetHack 5.0 calendar.c $NHDT-Date: 1706213796 2024/01/25 20:16:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* Copyright (c) Robert Patrick Rankin, 1991 */ diff --git a/src/cfgfiles.c b/src/cfgfiles.c index 2ba0c2fde..5a7d767b7 100644 --- a/src/cfgfiles.c +++ b/src/cfgfiles.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cfgfiles.c $NHDT-Date: 1740532826 2025/02/25 17:20:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.417 $ */ +/* NetHack 5.0 cfgfiles.c $NHDT-Date: 1740532826 2025/02/25 17:20:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.417 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/cmd.c b/src/cmd.c index 93edbe4b9..3bcc3f3c4 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1762680996 2025/11/09 01:36:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.755 $ */ +/* NetHack 5.0 cmd.c $NHDT-Date: 1762680996 2025/11/09 01:36:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.755 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/coloratt.c b/src/coloratt.c index a929417fb..bb67056ca 100644 --- a/src/coloratt.c +++ b/src/coloratt.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 coloratt.c $NHDT-Date: 1737286550 2025/01/19 03:35:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 coloratt.c $NHDT-Date: 1737286550 2025/01/19 03:35:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Pasi Kallinen, 2024 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/date.c b/src/date.c index 3ec4fbb3d..a1c80a385 100644 --- a/src/date.c +++ b/src/date.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 date.c $NHDT-Date: 1655402414 2022/06/16 18:00:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ */ +/* NetHack 5.0 date.c $NHDT-Date: 1655402414 2022/06/16 18:00:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ */ /* Copyright (c) Michael Allison, 2021. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/dbridge.c b/src/dbridge.c index 6afcac7d5..f500dbc0c 100644 --- a/src/dbridge.c +++ b/src/dbridge.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dbridge.c $NHDT-Date: 1772771734 2026/03/05 20:35:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ */ +/* NetHack 5.0 dbridge.c $NHDT-Date: 1772771734 2026/03/05 20:35:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/decl.c b/src/decl.c index 43d7143b9..5e4a74379 100644 --- a/src/decl.c +++ b/src/decl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.341 $ */ +/* NetHack 5.0 decl.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.341 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/detect.c b/src/detect.c index ea077b91a..6565a0365 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 detect.c $NHDT-Date: 1763708572 2025/11/20 23:02:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.191 $ */ +/* NetHack 5.0 detect.c $NHDT-Date: 1763708572 2025/11/20 23:02:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.191 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/dig.c b/src/dig.c index 1c0ff6ceb..df27bb73d 100644 --- a/src/dig.c +++ b/src/dig.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dig.c $NHDT-Date: 1740629713 2025/02/26 20:15:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.227 $ */ +/* NetHack 5.0 dig.c $NHDT-Date: 1740629713 2025/02/26 20:15:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.227 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/display.c b/src/display.c index d3241ce9f..437d74154 100644 --- a/src/display.c +++ b/src/display.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 display.c $NHDT-Date: 1777000050 2026/04/23 19:07:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.263 $ */ +/* NetHack 5.0 display.c $NHDT-Date: 1777000050 2026/04/23 19:07:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.263 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */ /* and Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/dlb.c b/src/dlb.c index d6551fe06..a68126dca 100644 --- a/src/dlb.c +++ b/src/dlb.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dlb.c $NHDT-Date: 1596498157 2020/08/03 23:42:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.20 $ */ +/* NetHack 5.0 dlb.c $NHDT-Date: 1596498157 2020/08/03 23:42:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.20 $ */ /* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1993. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/do.c b/src/do.c index b5aac1445..ae39a0137 100644 --- a/src/do.c +++ b/src/do.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do.c $NHDT-Date: 1774269965 2026/03/23 04:46:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.404 $ */ +/* NetHack 5.0 do.c $NHDT-Date: 1774269965 2026/03/23 04:46:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.404 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/do_name.c b/src/do_name.c index b69b56e4d..0fd1e98a0 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do_name.c $NHDT-Date: 1737013431 2025/01/15 23:43:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.326 $ */ +/* NetHack 5.0 do_name.c $NHDT-Date: 1737013431 2025/01/15 23:43:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.326 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/do_wear.c b/src/do_wear.c index 59e62927d..6b24c426a 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do_wear.c $NHDT-Date: 1737343372 2025/01/19 19:22:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.201 $ */ +/* NetHack 5.0 do_wear.c $NHDT-Date: 1737343372 2025/01/19 19:22:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.201 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/dog.c b/src/dog.c index f9676050c..e5ed65996 100644 --- a/src/dog.c +++ b/src/dog.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dog.c $NHDT-Date: 1753856387 2025/07/29 22:19:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.190 $ */ +/* NetHack 5.0 dog.c $NHDT-Date: 1753856387 2025/07/29 22:19:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.190 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/dogmove.c b/src/dogmove.c index fa209f1d3..617d768ce 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dogmove.c $NHDT-Date: 1725733007 2024/09/07 18:16:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.156 $ */ +/* NetHack 5.0 dogmove.c $NHDT-Date: 1725733007 2024/09/07 18:16:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.156 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/dokick.c b/src/dokick.c index e20f83100..4e531a016 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dokick.c $NHDT-Date: 1712453347 2024/04/07 01:29:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.223 $ */ +/* NetHack 5.0 dokick.c $NHDT-Date: 1712453347 2024/04/07 01:29:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.223 $ */ /* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/dothrow.c b/src/dothrow.c index e3ff3457c..c63ad6412 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dothrow.c $NHDT-Date: 1737343372 2025/01/19 19:22:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.300 $ */ +/* NetHack 5.0 dothrow.c $NHDT-Date: 1737343372 2025/01/19 19:22:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.300 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/drawing.c b/src/drawing.c index 587489053..375db072b 100644 --- a/src/drawing.c +++ b/src/drawing.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 drawing.c $NHDT-Date: 1596498163 2020/08/03 23:42:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.78 $ */ +/* NetHack 5.0 drawing.c $NHDT-Date: 1596498163 2020/08/03 23:42:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.78 $ */ /* Copyright (c) NetHack Development Team 1992. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/dungeon.c b/src/dungeon.c index 72bb26206..89afa002b 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dungeon.c $NHDT-Date: 1737343478 2025/01/19 19:24:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.228 $ */ +/* NetHack 5.0 dungeon.c $NHDT-Date: 1737343478 2025/01/19 19:24:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.228 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/earlyarg.c b/src/earlyarg.c index 352a9cf46..e8009a57e 100755 --- a/src/earlyarg.c +++ b/src/earlyarg.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 earlyarg.c $NHDT-Date: 1771213100 2026/02/15 19:38:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.286 $ */ +/* NetHack 5.0 earlyarg.c $NHDT-Date: 1771213100 2026/02/15 19:38:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.286 $ */ /* Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/eat.c b/src/eat.c index 1b58c316f..179b44b0b 100644 --- a/src/eat.c +++ b/src/eat.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 eat.c $NHDT-Date: 1740534854 2025/02/25 17:54:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.344 $ */ +/* NetHack 5.0 eat.c $NHDT-Date: 1740534854 2025/02/25 17:54:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.344 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/end.c b/src/end.c index ff67412eb..06be7bcc0 100644 --- a/src/end.c +++ b/src/end.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 end.c $NHDT-Date: 1720397752 2024/07/08 00:15:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.315 $ */ +/* NetHack 5.0 end.c $NHDT-Date: 1720397752 2024/07/08 00:15:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.315 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/engrave.c b/src/engrave.c index 9768b00b6..8ed7d57ba 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 engrave.c $NHDT-Date: 1737345573 2025/01/19 19:59:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.165 $ */ +/* NetHack 5.0 engrave.c $NHDT-Date: 1737345573 2025/01/19 19:59:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.165 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/exper.c b/src/exper.c index 14312e691..bb424e6f8 100644 --- a/src/exper.c +++ b/src/exper.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 exper.c $NHDT-Date: 1706133782 2024/01/24 22:03:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.62 $ */ +/* NetHack 5.0 exper.c $NHDT-Date: 1706133782 2024/01/24 22:03:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.62 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2007. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/explode.c b/src/explode.c index 41ef8a4df..2ad009077 100644 --- a/src/explode.c +++ b/src/explode.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 explode.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.122 $ */ +/* NetHack 5.0 explode.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.122 $ */ /* Copyright (C) 1990 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/extralev.c b/src/extralev.c index e0c2afc84..a7cdccaa9 100644 --- a/src/extralev.c +++ b/src/extralev.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 extralev.c $NHDT-Date: 1737345573 2025/01/19 19:59:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.28 $ */ +/* NetHack 5.0 extralev.c $NHDT-Date: 1737345573 2025/01/19 19:59:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.28 $ */ /* Copyright 1988, 1989 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/files.c b/src/files.c index 74f600ef2..3b9a02505 100644 --- a/src/files.c +++ b/src/files.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 files.c $NHDT-Date: 1740532826 2025/02/25 17:20:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.417 $ */ +/* NetHack 5.0 files.c $NHDT-Date: 1740532826 2025/02/25 17:20:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.417 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/fountain.c b/src/fountain.c index aeef118bb..d419f060e 100644 --- a/src/fountain.c +++ b/src/fountain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 fountain.c $NHDT-Date: 1699582923 2023/11/10 02:22:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.100 $ */ +/* NetHack 5.0 fountain.c $NHDT-Date: 1699582923 2023/11/10 02:22:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.100 $ */ /* Copyright Scott R. Turner, srt@ucla, 10/27/86 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/getpos.c b/src/getpos.c index ed53d334b..edc4adf73 100644 --- a/src/getpos.c +++ b/src/getpos.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 getpos.c $NHDT-Date: 1763708572 2025/11/20 23:02:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ */ +/* NetHack 5.0 getpos.c $NHDT-Date: 1763708572 2025/11/20 23:02:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ */ /*-Copyright (c) Pasi Kallinen, 2023. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/glyphs.c b/src/glyphs.c index 778cb4aeb..53235659d 100644 --- a/src/glyphs.c +++ b/src/glyphs.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 glyphs.c TODO: add NHDT branch/date/revision tags */ +/* NetHack 5.0 glyphs.c TODO: add NHDT branch/date/revision tags */ /* Copyright (c) Michael Allison, 2021. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/hack.c b/src/hack.c index 4e5ff410b..3017eb2c7 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 hack.c $NHDT-Date: 1763708572 2025/11/20 23:02:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.494 $ */ +/* NetHack 5.0 hack.c $NHDT-Date: 1763708572 2025/11/20 23:02:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.494 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/hacklib.c b/src/hacklib.c index 25891684e..103443c0d 100644 --- a/src/hacklib.c +++ b/src/hacklib.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 hacklib.c $NHDT-Date: 1706213796 2024/01/25 20:16:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ +/* NetHack 5.0 hacklib.c $NHDT-Date: 1706213796 2024/01/25 20:16:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* Copyright (c) Robert Patrick Rankin, 1991 */ diff --git a/src/iactions.c b/src/iactions.c index b12b61c18..b0eb47ccb 100644 --- a/src/iactions.c +++ b/src/iactions.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 iactions.c $NHDT-Date: 1762680996 2025/11/09 01:36:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.543 $ */ +/* NetHack 5.0 iactions.c $NHDT-Date: 1762680996 2025/11/09 01:36:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.543 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2026. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/insight.c b/src/insight.c index 12fc1e773..87373ebbd 100644 --- a/src/insight.c +++ b/src/insight.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 insight.c $NHDT-Date: 1777004419 2026/04/23 20:20:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.134 $ */ +/* NetHack 5.0 insight.c $NHDT-Date: 1777004419 2026/04/23 20:20:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.134 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/invent.c b/src/invent.c index 6995bfd4e..1263ea8c7 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 invent.c $NHDT-Date: 1762680996 2025/11/09 01:36:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.543 $ */ +/* NetHack 5.0 invent.c $NHDT-Date: 1762680996 2025/11/09 01:36:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.543 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/light.c b/src/light.c index 640ed312a..a4a3c1862 100644 --- a/src/light.c +++ b/src/light.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 light.c $NHDT-Date: 1773375430 2026/03/12 20:17:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.82 $ */ +/* NetHack 5.0 light.c $NHDT-Date: 1773375430 2026/03/12 20:17:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.82 $ */ /* Copyright (c) Dean Luick, 1994 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/lock.c b/src/lock.c index cc3183d00..0d14f982e 100644 --- a/src/lock.c +++ b/src/lock.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 lock.c $NHDT-Date: 1741793439 2025/03/12 07:30:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.145 $ */ +/* NetHack 5.0 lock.c $NHDT-Date: 1741793439 2025/03/12 07:30:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.145 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mail.c b/src/mail.c index 96735abe5..2f9528188 100644 --- a/src/mail.c +++ b/src/mail.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mail.c $NHDT-Date: 1762750699 2025/11/09 20:58:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.77 $ */ +/* NetHack 5.0 mail.c $NHDT-Date: 1762750699 2025/11/09 20:58:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.77 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/makemon.c b/src/makemon.c index 6f158ee01..5a8c7db77 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 makemon.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.271 $ */ +/* NetHack 5.0 makemon.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.271 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mcastu.c b/src/mcastu.c index 4b40fa2ff..85afb191b 100644 --- a/src/mcastu.c +++ b/src/mcastu.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mcastu.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.111 $ */ +/* NetHack 5.0 mcastu.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.111 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mdlib.c b/src/mdlib.c index fb4155dab..873922fc1 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mdlib.c $NHDT-Date: 1701499945 2023/12/02 06:52:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.51 $ */ +/* NetHack 5.0 mdlib.c $NHDT-Date: 1701499945 2023/12/02 06:52:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.51 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* Copyright (c) M. Stephenson, 1990, 1991. */ @@ -798,7 +798,7 @@ build_options(void) #if defined(MAKEDEFS_C) || defined(FOR_RUNTIME) { static const char *const lua_info[] = { - "", "NetHack 3.7.* uses the 'Lua' interpreter to process some data:", "", + "", "NetHack 5.0.* uses the 'Lua' interpreter to process some data:", "", " :LUACOPYRIGHT:", "", /* 1 2 3 4 5 6 7 1234567890123456789012345678901234567890123456789012345678901234567890123456 diff --git a/src/mhitm.c b/src/mhitm.c index c6db44600..1508937e9 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhitm.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.253 $ */ +/* NetHack 5.0 mhitm.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.253 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mhitu.c b/src/mhitu.c index b71104cb9..05e6f38aa 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhitu.c $NHDT-Date: 1775259433 2026/04/03 15:37:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.341 $ */ +/* NetHack 5.0 mhitu.c $NHDT-Date: 1775259433 2026/04/03 15:37:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.341 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/minion.c b/src/minion.c index 833e5597f..d3a894634 100644 --- a/src/minion.c +++ b/src/minion.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 minion.c $NHDT-Date: 1762727599 2025/11/09 14:33:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.81 $ */ +/* NetHack 5.0 minion.c $NHDT-Date: 1762727599 2025/11/09 14:33:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.81 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2008. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mklev.c b/src/mklev.c index 2ddeefae9..f11c2b1e8 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mklev.c $NHDT-Date: 1737387068 2025/01/20 07:31:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.194 $ */ +/* NetHack 5.0 mklev.c $NHDT-Date: 1737387068 2025/01/20 07:31:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.194 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Alex Smith, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mkmap.c b/src/mkmap.c index fdf50649c..3ed81f14f 100644 --- a/src/mkmap.c +++ b/src/mkmap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mkmap.c $NHDT-Date: 1717432093 2024/06/03 16:28:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ */ +/* NetHack 5.0 mkmap.c $NHDT-Date: 1717432093 2024/06/03 16:28:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ */ /* Copyright (c) J. C. Collet, M. Stephenson and D. Cohrs, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mkmaze.c b/src/mkmaze.c index 573eada04..bba58e294 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mkmaze.c $NHDT-Date: 1745114235 2025/04/19 17:57:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.179 $ */ +/* NetHack 5.0 mkmaze.c $NHDT-Date: 1745114235 2025/04/19 17:57:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.179 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mkobj.c b/src/mkobj.c index eb55a0802..650b1502f 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mkobj.c $NHDT-Date: 1764044196 2025/11/24 20:16:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.326 $ */ +/* NetHack 5.0 mkobj.c $NHDT-Date: 1764044196 2025/11/24 20:16:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.326 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mkroom.c b/src/mkroom.c index c859b1c0e..dd9fa8468 100644 --- a/src/mkroom.c +++ b/src/mkroom.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mkroom.c $NHDT-Date: 1613086701 2021/02/11 23:38:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.52 $ */ +/* NetHack 5.0 mkroom.c $NHDT-Date: 1613086701 2021/02/11 23:38:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.52 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mon.c b/src/mon.c index 2452813e4..2361fe741 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.621 $ */ +/* NetHack 5.0 mon.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.621 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mondata.c b/src/mondata.c index 2e6d049a2..44d1f2841 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mondata.c $NHDT-Date: 1738638877 2025/02/03 19:14:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.140 $ */ +/* NetHack 5.0 mondata.c $NHDT-Date: 1738638877 2025/02/03 19:14:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.140 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/monmove.c b/src/monmove.c index fe3040da3..1c6242896 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 monmove.c $NHDT-Date: 1737392015 2025/01/20 08:53:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.266 $ */ +/* NetHack 5.0 monmove.c $NHDT-Date: 1737392015 2025/01/20 08:53:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.266 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/monst.c b/src/monst.c index b5864ecdb..ef794c4c3 100644 --- a/src/monst.c +++ b/src/monst.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 monst.c $NHDT-Date: 1705092160 2024/01/12 20:42:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.100 $ */ +/* NetHack 5.0 monst.c $NHDT-Date: 1705092160 2024/01/12 20:42:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.100 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mplayer.c b/src/mplayer.c index 041a997ec..267ab0d39 100644 --- a/src/mplayer.c +++ b/src/mplayer.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mplayer.c $NHDT-Date: 1596498188 2020/08/03 23:43:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ +/* NetHack 5.0 mplayer.c $NHDT-Date: 1596498188 2020/08/03 23:43:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ /* Copyright (c) Izchak Miller, 1992. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mthrowu.c b/src/mthrowu.c index 850abac8a..d830bfbef 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mthrowu.c $NHDT-Date: 1737392015 2025/01/20 08:53:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.173 $ */ +/* NetHack 5.0 mthrowu.c $NHDT-Date: 1737392015 2025/01/20 08:53:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.173 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/muse.c b/src/muse.c index 07cc865da..78a2e9970 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 muse.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.241 $ */ +/* NetHack 5.0 muse.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.241 $ */ /* Copyright (C) 1990 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/music.c b/src/music.c index 7034577a5..844350f78 100644 --- a/src/music.c +++ b/src/music.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 music.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.120 $ */ +/* NetHack 5.0 music.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.120 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/nhlobj.c b/src/nhlobj.c index a0535074c..f4fa7dcf1 100644 --- a/src/nhlobj.c +++ b/src/nhlobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 nhlobj.c $NHDT-Date: 1576097301 2019/12/11 20:48:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 nhlobj.c $NHDT-Date: 1576097301 2019/12/11 20:48:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ /* Copyright (c) 2019 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/nhlsel.c b/src/nhlsel.c index 9b5ef24c4..cbaf6f9b8 100644 --- a/src/nhlsel.c +++ b/src/nhlsel.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 nhlua.c $NHDT-Date: 1769840272 2026/01/30 22:17:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.69 $ */ +/* NetHack 5.0 nhlua.c $NHDT-Date: 1769840272 2026/01/30 22:17:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.69 $ */ /* Copyright (c) 2018 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/nhlua.c b/src/nhlua.c index 96970f73c..314e51f07 100644 --- a/src/nhlua.c +++ b/src/nhlua.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 nhlua.c $NHDT-Date: 1744963460 2025/04/18 00:04:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.153 $ */ +/* NetHack 5.0 nhlua.c $NHDT-Date: 1744963460 2025/04/18 00:04:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.153 $ */ /* Copyright (c) 2018 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/nhmd4.c b/src/nhmd4.c index 02d9aa74e..580d8e49f 100644 --- a/src/nhmd4.c +++ b/src/nhmd4.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 nhmd4.c $NHDT-Date: 1708811387 2024/02/24 21:49:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 nhmd4.c $NHDT-Date: 1708811387 2024/02/24 21:49:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2024 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/o_init.c b/src/o_init.c index 5bb82d2e2..f6ede4dab 100644 --- a/src/o_init.c +++ b/src/o_init.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 o_init.c $NHDT-Date: 1771216675 2026/02/15 20:37:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.101 $ */ +/* NetHack 5.0 o_init.c $NHDT-Date: 1771216675 2026/02/15 20:37:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.101 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/objects.c b/src/objects.c index 9389e3863..b6bbaa3dd 100644 --- a/src/objects.c +++ b/src/objects.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 objects.c $NHDT-Date: 1596498192 2020/08/03 23:43:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.66 $ */ +/* NetHack 5.0 objects.c $NHDT-Date: 1596498192 2020/08/03 23:43:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.66 $ */ /* Copyright (c) Mike Threepoint, 1989. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/objnam.c b/src/objnam.c index 1246029fd..032c6c0e6 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 objnam.c $NHDT-Date: 1745114235 2025/04/19 17:57:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.453 $ */ +/* NetHack 5.0 objnam.c $NHDT-Date: 1745114235 2025/04/19 17:57:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.453 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/options.c b/src/options.c index 786c5757e..cdf29ed20 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 options.c $NHDT-Date: 1737556914 2025/01/22 06:41:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.753 $ */ +/* NetHack 5.0 options.c $NHDT-Date: 1737556914 2025/01/22 06:41:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.753 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/pager.c b/src/pager.c index ac8b5f61e..4c40594de 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pager.c $NHDT-Date: 1774846177 2026/03/29 20:49:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.296 $ */ +/* NetHack 5.0 pager.c $NHDT-Date: 1774846177 2026/03/29 20:49:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.296 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/pickup.c b/src/pickup.c index 5f6e55de8..cc2c9baec 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pickup.c $NHDT-Date: 1773373633 2026/03/12 19:47:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.386 $ */ +/* NetHack 5.0 pickup.c $NHDT-Date: 1773373633 2026/03/12 19:47:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.386 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/pline.c b/src/pline.c index c8d61b09d..9a164fc06 100644 --- a/src/pline.c +++ b/src/pline.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pline.c $NHDT-Date: 1719819280 2024/07/01 07:34:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.130 $ */ +/* NetHack 5.0 pline.c $NHDT-Date: 1719819280 2024/07/01 07:34:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.130 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/polyself.c b/src/polyself.c index 2461a1b79..64e27d26d 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 polyself.c $NHDT-Date: 1772101811 2026/02/26 02:30:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.227 $ */ +/* NetHack 5.0 polyself.c $NHDT-Date: 1772101811 2026/02/26 02:30:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.227 $ */ /* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/potion.c b/src/potion.c index 3ac39333a..f289c1d7b 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 potion.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.279 $ */ +/* NetHack 5.0 potion.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.279 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/pray.c b/src/pray.c index c008e3205..85fbc0859 100644 --- a/src/pray.c +++ b/src/pray.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pray.c $NHDT-Date: 1762680996 2025/11/09 01:36:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.244 $ */ +/* NetHack 5.0 pray.c $NHDT-Date: 1762680996 2025/11/09 01:36:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.244 $ */ /* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/priest.c b/src/priest.c index cb480a757..643fe425d 100644 --- a/src/priest.c +++ b/src/priest.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 priest.c $NHDT-Date: 1764567778 2025/11/30 21:42:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.106 $ */ +/* NetHack 5.0 priest.c $NHDT-Date: 1764567778 2025/11/30 21:42:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.106 $ */ /* Copyright (c) Izchak Miller, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/quest.c b/src/quest.c index 2b54baa86..d57f1712b 100644 --- a/src/quest.c +++ b/src/quest.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 quest.c $NHDT-Date: 1774269965 2026/03/23 04:46:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.46 $ */ +/* NetHack 5.0 quest.c $NHDT-Date: 1774269965 2026/03/23 04:46:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.46 $ */ /* Copyright 1991, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/questpgr.c b/src/questpgr.c index 707846e90..96a3c5ad7 100644 --- a/src/questpgr.c +++ b/src/questpgr.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 questpgr.c $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.87 $ */ +/* NetHack 5.0 questpgr.c $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.87 $ */ /* Copyright 1991, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/read.c b/src/read.c index e9b98eb31..967824df2 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 read.c $NHDT-Date: 1762577372 2025/11/07 20:49:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.323 $ */ +/* NetHack 5.0 read.c $NHDT-Date: 1762577372 2025/11/07 20:49:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.323 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/rect.c b/src/rect.c index 1fb0f2b82..aebd8216b 100644 --- a/src/rect.c +++ b/src/rect.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 rect.c $NHDT-Date: 1596498203 2020/08/03 23:43:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 rect.c $NHDT-Date: 1596498203 2020/08/03 23:43:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) 1990 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/region.c b/src/region.c index 938a3e2bf..2790204b4 100644 --- a/src/region.c +++ b/src/region.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 region.c $NHDT-Date: 1727251269 2024/09/25 08:01:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.104 $ */ +/* NetHack 5.0 region.c $NHDT-Date: 1727251269 2024/09/25 08:01:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.104 $ */ /* Copyright (c) 1996 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/report.c b/src/report.c index ecfa0ad17..2ec645b44 100644 --- a/src/report.c +++ b/src/report.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 report.c $NHDT-Date: 1741406837 2025/03/07 20:07:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.16 $ */ +/* NetHack 5.0 report.c $NHDT-Date: 1741406837 2025/03/07 20:07:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.16 $ */ /* Copyright (c) Kenneth Lorber, Kensington, Maryland, 2024 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/restore.c b/src/restore.c index 35ebaee10..c84e91cd5 100644 --- a/src/restore.c +++ b/src/restore.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 restore.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.234 $ */ +/* NetHack 5.0 restore.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.234 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/rip.c b/src/rip.c index c9c64dfae..b7c7fbd72 100644 --- a/src/rip.c +++ b/src/rip.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 rip.c $NHDT-Date: 1597967808 2020/08/20 23:56:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.33 $ */ +/* NetHack 5.0 rip.c $NHDT-Date: 1597967808 2020/08/20 23:56:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.33 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/rnd.c b/src/rnd.c index beb4992ed..1994120af 100644 --- a/src/rnd.c +++ b/src/rnd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 rnd.c $NHDT-Date: 1596498205 2020/08/03 23:43:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ +/* NetHack 5.0 rnd.c $NHDT-Date: 1596498205 2020/08/03 23:43:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ /* Copyright (c) 2004 by Robert Patrick Rankin */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/role.c b/src/role.c index 8d4feaab2..ee3e9a836 100644 --- a/src/role.c +++ b/src/role.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 role.c $NHDT-Date: 1737607158 2025/01/22 20:39:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.107 $ */ +/* NetHack 5.0 role.c $NHDT-Date: 1737607158 2025/01/22 20:39:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.107 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985-1999. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/rumors.c b/src/rumors.c index 5aac3bd40..9d4ada852 100644 --- a/src/rumors.c +++ b/src/rumors.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 rumors.c $NHDT-Date: 1594370241 2020/07/10 08:37:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.56 $ */ +/* NetHack 5.0 rumors.c $NHDT-Date: 1594370241 2020/07/10 08:37:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.56 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/save.c b/src/save.c index b6d09f432..47cfb023d 100644 --- a/src/save.c +++ b/src/save.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 save.c $NHDT-Date: 1737610109 2025/01/22 21:28:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.232 $ */ +/* NetHack 5.0 save.c $NHDT-Date: 1737610109 2025/01/22 21:28:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.232 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/selvar.c b/src/selvar.c index a35b9f7bd..e1dad31af 100644 --- a/src/selvar.c +++ b/src/selvar.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 selvar.c $NHDT-Date: 1769840272 2026/01/30 22:17:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ */ +/* NetHack 5.0 selvar.c $NHDT-Date: 1769840272 2026/01/30 22:17:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ */ /* Copyright (c) 2024 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/sfbase.c b/src/sfbase.c index 0cd70af4e..00c165c68 100644 --- a/src/sfbase.c +++ b/src/sfbase.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sfbase.c.template $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ +/* NetHack 5.0 sfbase.c.template $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ /* Copyright (c) Michael Allison, 2025. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/sfstruct.c b/src/sfstruct.c index 8a15a0c17..a58de75eb 100644 --- a/src/sfstruct.c +++ b/src/sfstruct.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sfstruct.c $NHDT-Date: 1606765215 2020/11/30 19:40:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ */ +/* NetHack 5.0 sfstruct.c $NHDT-Date: 1606765215 2020/11/30 19:40:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2025. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/shk.c b/src/shk.c index 69a716df7..4180ec670 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 shk.c $NHDT-Date: 1736516428 2025/01/10 05:40:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.306 $ */ +/* NetHack 5.0 shk.c $NHDT-Date: 1736516428 2025/01/10 05:40:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.306 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/shknam.c b/src/shknam.c index 657487ed8..276417af0 100644 --- a/src/shknam.c +++ b/src/shknam.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 shknam.c $NHDT-Date: 1764109114 2025/11/25 22:18:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.86 $ */ +/* NetHack 5.0 shknam.c $NHDT-Date: 1764109114 2025/11/25 22:18:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.86 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/sit.c b/src/sit.c index 8f355d95a..5857dec28 100644 --- a/src/sit.c +++ b/src/sit.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sit.c $NHDT-Date: 1718136168 2024/06/11 20:02:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.95 $ */ +/* NetHack 5.0 sit.c $NHDT-Date: 1718136168 2024/06/11 20:02:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.95 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/sounds.c b/src/sounds.c index 002cd8854..d7652d62a 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sounds.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.165 $ */ +/* NetHack 5.0 sounds.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.165 $ */ /* Copyright (c) 1989 Janet Walz, Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/sp_lev.c b/src/sp_lev.c index 007d65404..ab86cd3a5 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sp_lev.c $NHDT-Date: 1737610109 2025/01/22 21:28:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.373 $ */ +/* NetHack 5.0 sp_lev.c $NHDT-Date: 1737610109 2025/01/22 21:28:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.373 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/spell.c b/src/spell.c index 4d489a123..e79f9a521 100644 --- a/src/spell.c +++ b/src/spell.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 spell.c $NHDT-Date: 1769498874 2026/01/26 23:27:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.185 $ */ +/* NetHack 5.0 spell.c $NHDT-Date: 1769498874 2026/01/26 23:27:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.185 $ */ /* Copyright (c) M. Stephenson 1988 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/stairs.c b/src/stairs.c index 89b9ff3e8..bf052aaf9 100644 --- a/src/stairs.c +++ b/src/stairs.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 stairs.c $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.207 $ */ +/* NetHack 5.0 stairs.c $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.207 $ */ /* Copyright (c) 2024 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/steal.c b/src/steal.c index 1c9fcb305..b3ca54382 100644 --- a/src/steal.c +++ b/src/steal.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 steal.c $NHDT-Date: 1720895742 2024/07/13 18:35:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.132 $ */ +/* NetHack 5.0 steal.c $NHDT-Date: 1720895742 2024/07/13 18:35:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.132 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/steed.c b/src/steed.c index 553e1df3a..a3e3f2bd6 100644 --- a/src/steed.c +++ b/src/steed.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 steed.c $NHDT-Date: 1720128167 2024/07/04 21:22:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.121 $ */ +/* NetHack 5.0 steed.c $NHDT-Date: 1720128167 2024/07/04 21:22:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.121 $ */ /* Copyright (c) Kevin Hugo, 1998-1999. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/strutil.c b/src/strutil.c index c35d22182..8047281b6 100644 --- a/src/strutil.c +++ b/src/strutil.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 strutil.c $NHDT-Date: 1709571807 2024/03/04 17:03:27 $ $NHDT-Branch: keni-mdlib-followup $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 strutil.c $NHDT-Date: 1709571807 2024/03/04 17:03:27 $ $NHDT-Branch: keni-mdlib-followup $:$NHDT-Revision: 1.0 $ */ /* Copyright (c) Robert Patrick Rankin, 1991 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/symbols.c b/src/symbols.c index 0d60df7b2..428c354d4 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 symbols.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.123 $ */ +/* NetHack 5.0 symbols.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.123 $ */ /* Copyright (c) NetHack Development Team 2020. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/sys.c b/src/sys.c index 4d8ad2dcf..758a93667 100644 --- a/src/sys.c +++ b/src/sys.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sys.c $NHDT-Date: 1717449153 2024/06/03 21:12:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.64 $ */ +/* NetHack 5.0 sys.c $NHDT-Date: 1717449153 2024/06/03 21:12:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.64 $ */ /* Copyright (c) Kenneth Lorber, Kensington, Maryland, 2008. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/teleport.c b/src/teleport.c index 48fa7da78..fc1d3ce28 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 teleport.c $NHDT-Date: 1769342601 2026/01/25 04:03:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.239 $ */ +/* NetHack 5.0 teleport.c $NHDT-Date: 1769342601 2026/01/25 04:03:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.239 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/timeout.c b/src/timeout.c index 34d11d601..83d1aaf9a 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 timeout.c $NHDT-Date: 1776080125 2026/04/13 03:35:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.207 $ */ +/* NetHack 5.0 timeout.c $NHDT-Date: 1776080125 2026/04/13 03:35:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.207 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/topten.c b/src/topten.c index f7770791a..97391b091 100644 --- a/src/topten.c +++ b/src/topten.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 topten.c $NHDT-Date: 1606009004 2020/11/22 01:36:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.74 $ */ +/* NetHack 5.0 topten.c $NHDT-Date: 1606009004 2020/11/22 01:36:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.74 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/track.c b/src/track.c index 178e5a6f9..660e900c7 100644 --- a/src/track.c +++ b/src/track.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 track.c $NHDT-Date: 1596498219 2020/08/03 23:43:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 track.c $NHDT-Date: 1596498219 2020/08/03 23:43:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/trap.c b/src/trap.c index a97706fe8..7915cee7c 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 trap.c $NHDT-Date: 1741926700 2025/03/13 20:31:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.621 $ */ +/* NetHack 5.0 trap.c $NHDT-Date: 1741926700 2025/03/13 20:31:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.621 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/u_init.c b/src/u_init.c index 1d5a5c80f..2d10a4ddf 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 u_init.c $NHDT-Date: 1769398807 2026/01/25 19:40:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.121 $ */ +/* NetHack 5.0 u_init.c $NHDT-Date: 1769398807 2026/01/25 19:40:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.121 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/uhitm.c b/src/uhitm.c index eb04e0d1a..c5a18a000 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 uhitm.c $NHDT-Date: 1752823766 2025/07/17 23:29:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.477 $ */ +/* NetHack 5.0 uhitm.c $NHDT-Date: 1752823766 2025/07/17 23:29:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.477 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/utf8map.c b/src/utf8map.c index 19f3b18e4..f85226ad1 100644 --- a/src/utf8map.c +++ b/src/utf8map.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 utf8map.c */ +/* NetHack 5.0 utf8map.c */ /* Copyright (c) Michael Allison, 2021. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/vault.c b/src/vault.c index ef4065805..618a8f4eb 100644 --- a/src/vault.c +++ b/src/vault.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vault.c $NHDT-Date: 1737622664 2025/01/23 00:57:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.113 $ */ +/* NetHack 5.0 vault.c $NHDT-Date: 1737622664 2025/01/23 00:57:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.113 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/version.c b/src/version.c index 0b82963b8..d3b6ecfc8 100644 --- a/src/version.c +++ b/src/version.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 version.c $NHDT-Date: 1737622664 2025/01/23 00:57:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.105 $ */ +/* NetHack 5.0 version.c $NHDT-Date: 1737622664 2025/01/23 00:57:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.105 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/vision.c b/src/vision.c index 90bd965a9..785962a9f 100644 --- a/src/vision.c +++ b/src/vision.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vision.c $NHDT-Date: 1777205478 2026/04/26 04:11:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.75 $ */ +/* NetHack 5.0 vision.c $NHDT-Date: 1777205478 2026/04/26 04:11:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.75 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/weapon.c b/src/weapon.c index b400ac91c..0aeeb526e 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 weapon.c $NHDT-Date: 1725227810 2024/09/01 21:56:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.128 $ */ +/* NetHack 5.0 weapon.c $NHDT-Date: 1725227810 2024/09/01 21:56:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.128 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/were.c b/src/were.c index df6ebc15c..aa9e0863f 100644 --- a/src/were.c +++ b/src/were.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 were.c $NHDT-Date: 1766588485 2025/12/24 07:01:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.41 $ */ +/* NetHack 5.0 were.c $NHDT-Date: 1766588485 2025/12/24 07:01:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.41 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/wield.c b/src/wield.c index b6fbdc83a..0454a912f 100644 --- a/src/wield.c +++ b/src/wield.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wield.c $NHDT-Date: 1707525193 2024/02/10 00:33:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.110 $ */ +/* NetHack 5.0 wield.c $NHDT-Date: 1707525193 2024/02/10 00:33:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.110 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2009. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/windows.c b/src/windows.c index a36b0eaa4..b6c61f2c9 100644 --- a/src/windows.c +++ b/src/windows.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 windows.c $NHDT-Date: 1737345149 2025/01/19 19:52:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.138 $ */ +/* NetHack 5.0 windows.c $NHDT-Date: 1737345149 2025/01/19 19:52:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.138 $ */ /* Copyright (c) D. Cohrs, 1993. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/wizard.c b/src/wizard.c index c89e3296f..16dc405c9 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wizard.c $NHDT-Date: 1741407262 2025/03/07 20:14:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ +/* NetHack 5.0 wizard.c $NHDT-Date: 1741407262 2025/03/07 20:14:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/wizcmds.c b/src/wizcmds.c index 0bee2da86..0c9e78719 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wizcmds.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ +/* NetHack 5.0 wizcmds.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ /*-Copyright (c) Robert Patrick Rankin, 2024. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/worm.c b/src/worm.c index a74b81ac8..23e908942 100644 --- a/src/worm.c +++ b/src/worm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 worm.c $NHDT-Date: 1652689653 2022/05/16 08:27:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.56 $ */ +/* NetHack 5.0 worm.c $NHDT-Date: 1652689653 2022/05/16 08:27:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.56 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2009. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/worn.c b/src/worn.c index 9ffcb8c24..fccea6fc0 100644 --- a/src/worn.c +++ b/src/worn.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 worn.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.119 $ */ +/* NetHack 5.0 worn.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.119 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/write.c b/src/write.c index dc7ccbd36..8f0aa7d43 100644 --- a/src/write.c +++ b/src/write.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 write.c $NHDT-Date: 1702023275 2023/12/08 08:14:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.41 $ */ +/* NetHack 5.0 write.c $NHDT-Date: 1702023275 2023/12/08 08:14:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.41 $ */ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" diff --git a/src/zap.c b/src/zap.c index 163ee6c38..e26c22fcf 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 zap.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.584 $ */ +/* NetHack 5.0 zap.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.584 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/msdos/pctiles.h b/sys/msdos/pctiles.h index eed5a87ec..69c5ff875 100644 --- a/sys/msdos/pctiles.h +++ b/sys/msdos/pctiles.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 pctiles.h $NHDT-Date: 1596498272 2020/08/03 23:44:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 pctiles.h $NHDT-Date: 1596498272 2020/08/03 23:44:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994 */ /* NetHack may be freely redistributed. See license for details. */ /* */ diff --git a/sys/msdos/pcvideo.h b/sys/msdos/pcvideo.h index 1d889a8b2..22a95041a 100644 --- a/sys/msdos/pcvideo.h +++ b/sys/msdos/pcvideo.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 pcvideo.h $NHDT-Date: 1596498273 2020/08/03 23:44:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 pcvideo.h $NHDT-Date: 1596498273 2020/08/03 23:44:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994 */ /* NetHack may be freely redistributed. See license for details. */ /* */ diff --git a/sys/msdos/portio.h b/sys/msdos/portio.h index 8907278b2..0b31d8b00 100644 --- a/sys/msdos/portio.h +++ b/sys/msdos/portio.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 portio.h $NHDT-Date: 1596498273 2020/08/03 23:44:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 portio.h $NHDT-Date: 1596498273 2020/08/03 23:44:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) NetHack PC Development Team 1995 */ /* NetHack may be freely redistributed. See license for details. */ /* */ diff --git a/sys/msdos/vesa.h b/sys/msdos/vesa.h index 3056b07a0..54d5dc12a 100644 --- a/sys/msdos/vesa.h +++ b/sys/msdos/vesa.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 vesa.h $NHDT-Date: 1596498276 2020/08/03 23:44:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 vesa.h $NHDT-Date: 1596498276 2020/08/03 23:44:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ /* VESA structures from the VESA BIOS Specification, retrieved 15 Jan 2016 * from http://flint.cs.yale.edu/cs422/readings/hardware/vbe3.pdf diff --git a/sys/vms/Makefile.src b/sys/vms/Makefile.src index 20ee1643f..31b87d521 100644 --- a/sys/vms/Makefile.src +++ b/sys/vms/Makefile.src @@ -136,7 +136,7 @@ RANDOBJ = isaac64.obj,random.obj # Other things that have to be reconfigured are in vmsconf.h, # and config.h -VERSION = 3.7.0 +VERSION = 5.0.0 MAKEDEFS = $(UTL)makedefs.exe; diff --git a/sys/windows/GNUmakefile b/sys/windows/GNUmakefile index 4bc3df970..258a00120 100644 --- a/sys/windows/GNUmakefile +++ b/sys/windows/GNUmakefile @@ -1,4 +1,4 @@ -# NetHack 3.7 GNUmakefile +# NetHack 5.0 GNUmakefile # Copyright (c) 2022 by Feiyun Wang #-Copyright (c) 2022 by Michael Allison # NetHack may be freely redistributed. See license for details. @@ -172,7 +172,7 @@ $(info GIT=1) $(info or modify your Makefile to set the following:) $(info INTERNET_AVAILABLE=Y) $(info GIT_AVAILABLE=Y) -$(error Stopping because NetHack 3.7 requires Lua for its build.) +$(error Stopping because NetHack 5.0 requires Lua for its build.) endif # LUA_MAY_PROCEED # Now, pdcurses @@ -206,7 +206,7 @@ endif # ADD_CURSES == Y endif # INTERNET_AVAILABLE ifneq "$(ADD_CURSES)" "Y" -$(info NetHack 3.7 will be built without support for the curses window-port.) +$(info NetHack 5.0 will be built without support for the curses window-port.) endif ifeq "$(INTERNET_AVAILABLE)" "Y" @@ -229,7 +229,7 @@ endif #============================================================================== # The version of the game this Makefile was designed for -NETHACK_VERSION="3.7.0" +NETHACK_VERSION="5.0.0" # A brief version for use in macros NHV1=$(subst .,,$(NETHACK_VERSION)) @@ -1282,13 +1282,13 @@ $(GAMEDIR)/NetHackW.exe: $(NHWOBJS) $(NHWRES) $(DATEW_O) \ $(ONHW)/%.o: $(SRC)/%.c $(NHLUAH) | $(ONHW) $(cc) $(CFLAGSW) $< -o$@ -# In NetHack 3.7, date.c must be recompiled after any other file is compiled, +# In NetHack 5.0, date.c must be recompiled after any other file is compiled, # otherwise the game internal build timestamp (and potentially git hash) # will not be accurate. # Therefore, date must not be included in COREOBJS (and by extension # NHWOBJS, NHWONLY). That allows those to be listed as explicit dependencies # to ensure that date.c is always recompiled again after anything else that -# was just recompiled. date.h is not used in the build of NetHack 3.7. +# was just recompiled. date.h is not used in the build of NetHack 5.0. # $(ONHW)/date.o: $(SRC)/date.c $(NHWOBJS) | $(ONHW) $(cc) $(CFLAGSW) $(GITHASH) $(GITBRANCH) $(GITPREFIX) $< -o$@ @@ -1408,13 +1408,13 @@ $(PkgDir): CLEAN_DIR += $(PkgDir) CLEAN_FILE += $(MAINZIP) -# In NetHack 3.7, date.c must be recompiled after any other file is compiled, +# In NetHack 5.0, date.c must be recompiled after any other file is compiled, # otherwise the game internal build timestamp (and potentially git hash) # will not be accurate. # Therefore, date must not be included in COREOBJS (and by extension # NHOBJS). That allows those to be listed as explicit dependencies of date.o # to ensure that date.c is always recompiled again after anything else that -# was just recompiled. date.h is not used in the build of NetHack 3.7. +# was just recompiled. date.h is not used in the build of NetHack 5.0. # $(ONH)/date.o: $(SRC)/date.c $(NHOBJS) $(NHRES) | $(ONH) $(cc) $(CFLAGSNH) $(GITHASH) $(GITBRANCH) $(GITPREFIX) $< -o$@ diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index f4be7a51c..1f9726a3b 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -158,7 +158,7 @@ GIT_AVAILABLE=Y #============================================================================== # # The version of the game this Makefile was designed for -NETHACK_VERSION="3.7.0" +NETHACK_VERSION="5.0.0" # A brief version for use in macros NHV=$(NETHACK_VERSION:.=) diff --git a/sys/windows/win10.h b/sys/windows/win10.h index cc8a0bf48..504db9767 100644 --- a/sys/windows/win10.h +++ b/sys/windows/win10.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 win10.h $NHDT-Date: 1596498319 2020/08/03 23:45:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ */ +/* NetHack 5.0 win10.h $NHDT-Date: 1596498319 2020/08/03 23:45:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ */ /* Copyright (C) 2018 by Bart House */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/windows/win32api.h b/sys/windows/win32api.h index 1089f8b45..e1760e5e1 100644 --- a/sys/windows/win32api.h +++ b/sys/windows/win32api.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 win32api.h $NHDT-Date: 1596498320 2020/08/03 23:45:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 win32api.h $NHDT-Date: 1596498320 2020/08/03 23:45:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ /* Copyright (c) NetHack PC Development Team 1996 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/windows/winos.h b/sys/windows/winos.h index aed062035..a28ab6378 100644 --- a/sys/windows/winos.h +++ b/sys/windows/winos.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 winos.h $NHDT-Date: 1596498322 2020/08/03 23:45:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 winos.h $NHDT-Date: 1596498322 2020/08/03 23:45:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ /* Copyright (c) NetHack PC Development Team 2018 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/util/mdgrep.h b/util/mdgrep.h index 335f018b1..1b64de3db 100644 --- a/util/mdgrep.h +++ b/util/mdgrep.h @@ -1,5 +1,5 @@ /* - * NetHack 3.7 mdgrep.h $NHDT-Date: 1710949914 2024/03/20 15:51:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.20 $ + * NetHack 5.0 mdgrep.h $NHDT-Date: 1710949914 2024/03/20 15:51:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.20 $ * Copyright (c) Kenneth Lorber, Kensington, Maryland, 2008 * NetHack may be freely redistributed. See license for details. * diff --git a/win/Qt/qt_post.h b/win/Qt/qt_post.h index 7c9724473..6c783cf00 100644 --- a/win/Qt/qt_post.h +++ b/win/Qt/qt_post.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 qt_post.h $NHDT-Date: 1597276832 2020/08/13 00:00:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 qt_post.h $NHDT-Date: 1597276832 2020/08/13 00:00:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ /* * qt_post.h -- reverse part of qt_pre.h. diff --git a/win/Qt/qt_pre.h b/win/Qt/qt_pre.h index 22d988297..1dddde25b 100644 --- a/win/Qt/qt_pre.h +++ b/win/Qt/qt_pre.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 qt_pre.h $NHDT-Date: 1597276835 2020/08/13 00:00:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 qt_pre.h $NHDT-Date: 1597276835 2020/08/13 00:00:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ /* * qt_pre.h -- undefine some nethack macros which conflict with Qt headers. diff --git a/win/Qt/qt_win.h b/win/Qt/qt_win.h index 9dce3baec..8edb91974 100644 --- a/win/Qt/qt_win.h +++ b/win/Qt/qt_win.h @@ -2,7 +2,7 @@ // Qt4 conversion copyright (c) Ray Chason, 2012-2014. // NetHack may be freely redistributed. See license for details. -// Qt Binding for NetHack 3.7 +// Qt Binding for NetHack 5.0 // // [original comment from Warwick] // Unfortunately, this doesn't use Qt as well as I would like, diff --git a/win/curses/cursdial.h b/win/curses/cursdial.h index 167ec793e..de3d512fa 100644 --- a/win/curses/cursdial.h +++ b/win/curses/cursdial.h @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursdial.h */ +/* NetHack 5.0 cursdial.h */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursinit.h b/win/curses/cursinit.h index fbc9abe08..f51f1a681 100644 --- a/win/curses/cursinit.h +++ b/win/curses/cursinit.h @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursinit.h */ +/* NetHack 5.0 cursinit.h */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursinvt.h b/win/curses/cursinvt.h index 569b1ccb6..e644c193d 100644 --- a/win/curses/cursinvt.h +++ b/win/curses/cursinvt.h @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursinvt.h */ +/* NetHack 5.0 cursinvt.h */ /* Copyright (c) Fredrik Ljungdahl, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursmesg.h b/win/curses/cursmesg.h index 6653532db..897170b4f 100644 --- a/win/curses/cursmesg.h +++ b/win/curses/cursmesg.h @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursmesg.h */ +/* NetHack 5.0 cursmesg.h */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursmisc.h b/win/curses/cursmisc.h index 8d5becb28..dc79ebfbe 100644 --- a/win/curses/cursmisc.h +++ b/win/curses/cursmisc.h @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursmisc.h */ +/* NetHack 5.0 cursmisc.h */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursstat.h b/win/curses/cursstat.h index 1f2179e7e..4d4ce2ac5 100644 --- a/win/curses/cursstat.h +++ b/win/curses/cursstat.h @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursstat.h */ +/* NetHack 5.0 cursstat.h */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/curswins.h b/win/curses/curswins.h index 5842f52ed..ebf4c9bb5 100644 --- a/win/curses/curswins.h +++ b/win/curses/curswins.h @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 curswins.h */ +/* NetHack 5.0 curswins.h */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/share/tile.h b/win/share/tile.h index 54d1e2a6d..fcb01ece0 100644 --- a/win/share/tile.h +++ b/win/share/tile.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 tile.h $NHDT-Date: 1596498339 2020/08/03 23:45:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 tile.h $NHDT-Date: 1596498339 2020/08/03 23:45:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) 2016 by Michael Allison */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhaskyn.h b/win/win32/mhaskyn.h index 2591f34dd..d81a33698 100644 --- a/win/win32/mhaskyn.h +++ b/win/win32/mhaskyn.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhaskyn.h $NHDT-Date: 1596498347 2020/08/03 23:45:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 mhaskyn.h $NHDT-Date: 1596498347 2020/08/03 23:45:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhdlg.h b/win/win32/mhdlg.h index 7eb0b8eb9..9c3414da4 100644 --- a/win/win32/mhdlg.h +++ b/win/win32/mhdlg.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhdlg.h $NHDT-Date: 1596498348 2020/08/03 23:45:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 mhdlg.h $NHDT-Date: 1596498348 2020/08/03 23:45:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhfont.h b/win/win32/mhfont.h index 5c4c8f4e1..c4f10826f 100644 --- a/win/win32/mhfont.h +++ b/win/win32/mhfont.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhfont.h $NHDT-Date: 1596498350 2020/08/03 23:45:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.17 $ */ +/* NetHack 5.0 mhfont.h $NHDT-Date: 1596498350 2020/08/03 23:45:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.17 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhinput.h b/win/win32/mhinput.h index e94e3dbda..20c7af695 100644 --- a/win/win32/mhinput.h +++ b/win/win32/mhinput.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhinput.h $NHDT-Date: 1596498351 2020/08/03 23:45:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 mhinput.h $NHDT-Date: 1596498351 2020/08/03 23:45:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmain.h b/win/win32/mhmain.h index c4aea5ce2..89c0724b3 100644 --- a/win/win32/mhmain.h +++ b/win/win32/mhmain.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhmain.h $NHDT-Date: 1596498352 2020/08/03 23:45:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 mhmain.h $NHDT-Date: 1596498352 2020/08/03 23:45:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmap.h b/win/win32/mhmap.h index 679e16297..a66041fd1 100644 --- a/win/win32/mhmap.h +++ b/win/win32/mhmap.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhmap.h $NHDT-Date: 1596498354 2020/08/03 23:45:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.17 $ */ +/* NetHack 5.0 mhmap.h $NHDT-Date: 1596498354 2020/08/03 23:45:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.17 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmenu.h b/win/win32/mhmenu.h index 42efb30c8..a2ca7a8c4 100644 --- a/win/win32/mhmenu.h +++ b/win/win32/mhmenu.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhmenu.h $NHDT-Date: 1596498355 2020/08/03 23:45:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 mhmenu.h $NHDT-Date: 1596498355 2020/08/03 23:45:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmsg.h b/win/win32/mhmsg.h index 54a2e4c3d..2f7eff193 100644 --- a/win/win32/mhmsg.h +++ b/win/win32/mhmsg.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhmsg.h $NHDT-Date: 1596498356 2020/08/03 23:45:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ +/* NetHack 5.0 mhmsg.h $NHDT-Date: 1596498356 2020/08/03 23:45:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmsgwnd.h b/win/win32/mhmsgwnd.h index 37a68abc8..614e0e8a2 100644 --- a/win/win32/mhmsgwnd.h +++ b/win/win32/mhmsgwnd.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhmsgwnd.h $NHDT-Date: 1596498358 2020/08/03 23:45:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 mhmsgwnd.h $NHDT-Date: 1596498358 2020/08/03 23:45:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhrip.h b/win/win32/mhrip.h index 54a74fff5..7435294ef 100644 --- a/win/win32/mhrip.h +++ b/win/win32/mhrip.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhrip.h $NHDT-Date: 1596498359 2020/08/03 23:45:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 mhrip.h $NHDT-Date: 1596498359 2020/08/03 23:45:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhstatus.h b/win/win32/mhstatus.h index ec3473334..f4b3d844e 100644 --- a/win/win32/mhstatus.h +++ b/win/win32/mhstatus.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhstatus.h $NHDT-Date: 1596498361 2020/08/03 23:46:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 mhstatus.h $NHDT-Date: 1596498361 2020/08/03 23:46:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhtext.h b/win/win32/mhtext.h index bacc47643..eee831041 100644 --- a/win/win32/mhtext.h +++ b/win/win32/mhtext.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhtext.h $NHDT-Date: 1596498363 2020/08/03 23:46:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 mhtext.h $NHDT-Date: 1596498363 2020/08/03 23:46:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/winMS.h b/win/win32/winMS.h index 1de3db042..2d4deb058 100644 --- a/win/win32/winMS.h +++ b/win/win32/winMS.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 winMS.h $NHDT-Date: 1596498367 2020/08/03 23:46:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.53 $ */ +/* NetHack 5.0 winMS.h $NHDT-Date: 1596498367 2020/08/03 23:46:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.53 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ From 2a6e7c47ec26de46cb638d8bfcbdb3efd4970118 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 09:29:50 -0400 Subject: [PATCH 030/702] leave outdated files as 3.6; more to 5.0 --- outdated/.travis.yml | 4 ++-- outdated/dat/symbols | 2 +- outdated/include/mac-carbon.h | 2 +- outdated/include/mac-qt.h | 2 +- outdated/include/mac-term.h | 2 +- outdated/include/macpopup.h | 2 +- outdated/include/mactty.h | 2 +- outdated/include/macwin.h | 2 +- outdated/include/mttypriv.h | 2 +- outdated/include/system.h | 2 +- outdated/include/trampoli.h | 2 +- outdated/include/winGnome.h | 2 +- outdated/include/wingem.h | 2 +- outdated/sys/unix/hints/cross-amiga | 2 +- outdated/sys/unix/hints/include/cross-amiga-post | 2 +- outdated/sys/unix/hints/include/cross-amiga-pre | 4 ++-- outdated/sys/unix/hints/linux | 2 +- outdated/sys/unix/hints/linux-qt4 | 2 +- outdated/sys/unix/hints/linux-qt5 | 2 +- outdated/sys/unix/hints/linux-x11 | 2 +- outdated/sys/unix/hints/macosx | 2 +- outdated/sys/unix/hints/macosx10.10 | 2 +- outdated/sys/unix/hints/macosx10.10-qt | 2 +- outdated/sys/unix/hints/macosx10.14 | 2 +- outdated/sys/unix/hints/macosx10.5 | 2 +- outdated/sys/unix/hints/macosx10.7 | 2 +- outdated/sys/unix/hints/macosx10.8 | 2 +- outdated/sys/vms/lev_lex.h | 2 +- outdated/sys/wince/winhack.rc | 2 +- outdated/sys/wince/winhcksp.rc | 2 +- sound/windsound/windsound.c | 2 +- sys/amiga/amistack.c | 2 +- sys/libnh/libnhmain.c | 2 +- sys/msdos/msdos.c | 2 +- sys/msdos/pckeys.c | 2 +- sys/msdos/pctiles.c | 2 +- sys/msdos/tile2bin.c | 4 ++-- sys/msdos/video.c | 2 +- sys/msdos/vidtxt.c | 2 +- sys/msdos/vidvga.c | 2 +- sys/share/ioctl.c | 2 +- sys/share/pcmain.c | 2 +- sys/share/pcsys.c | 2 +- sys/share/pctty.c | 2 +- sys/share/pcunix.c | 2 +- sys/share/pmatchregex.c | 2 +- sys/share/posixregex.c | 2 +- sys/share/tclib.c | 2 +- sys/share/unixtty.c | 2 +- sys/unix/unixmain.c | 2 +- sys/unix/unixres.c | 2 +- sys/unix/unixunix.c | 2 +- sys/vms/oldcrtl.c | 2 +- sys/vms/vmsfiles.c | 2 +- sys/vms/vmsmail.c | 2 +- sys/vms/vmsmain.c | 2 +- sys/vms/vmsmisc.c | 2 +- sys/vms/vmstty.c | 2 +- sys/vms/vmsunix.c | 2 +- sys/windows/consoletty.c | 2 +- sys/windows/win10.c | 2 +- sys/windows/windmain.c | 2 +- sys/windows/windsys.c | 2 +- win/X11/Window.c | 2 +- win/X11/winX.c | 2 +- win/X11/winmap.c | 2 +- win/X11/winmenu.c | 2 +- win/X11/winmesg.c | 2 +- win/X11/winmisc.c | 2 +- win/X11/winstat.c | 2 +- win/X11/wintext.c | 2 +- win/X11/winval.c | 2 +- win/chain/wc_chainin.c | 2 +- win/chain/wc_chainout.c | 2 +- win/chain/wc_trace.c | 2 +- win/curses/cursdial.c | 2 +- win/curses/cursinit.c | 2 +- win/curses/cursinvt.c | 2 +- win/curses/cursmain.c | 2 +- win/curses/cursmesg.c | 2 +- win/curses/cursmisc.c | 2 +- win/curses/cursstat.c | 2 +- win/curses/curswins.c | 2 +- win/share/bmptiles.c | 2 +- win/share/giftiles.c | 2 +- win/share/ppmwrite.c | 2 +- win/share/thintile.c | 2 +- win/share/tile2bmp.c | 2 +- win/share/tilemap.c | 2 +- win/share/tileset.c | 2 +- win/share/tiletext.c | 2 +- win/shim/winshim.c | 2 +- win/tty/getline.c | 2 +- win/tty/termcap.c | 2 +- win/tty/topl.c | 2 +- win/tty/wintty.c | 2 +- win/win32/NetHackW.c | 2 +- win/win32/mhaskyn.c | 2 +- win/win32/mhdlg.c | 2 +- win/win32/mhfont.c | 2 +- win/win32/mhinput.c | 2 +- win/win32/mhmain.c | 2 +- win/win32/mhmap.c | 2 +- win/win32/mhmenu.c | 2 +- win/win32/mhmsgwnd.c | 2 +- win/win32/mhrip.c | 2 +- win/win32/mhsplash.c | 2 +- win/win32/mhstatus.c | 2 +- win/win32/mhtext.c | 2 +- win/win32/mswproc.c | 4 ++-- 110 files changed, 114 insertions(+), 114 deletions(-) diff --git a/outdated/.travis.yml b/outdated/.travis.yml index b0f0dfc3b..81e377790 100644 --- a/outdated/.travis.yml +++ b/outdated/.travis.yml @@ -179,5 +179,5 @@ deploy: on: tags: true prerelease: true - name: "Pre-Release build of NetHack 3.7.0" - body: "This is an auto generated Pre-Release build of NetHack 3.7.0" + name: "Pre-Release build of NetHack 3.6.0" + body: "This is an auto generated Pre-Release build of NetHack 3.6.0" diff --git a/outdated/dat/symbols b/outdated/dat/symbols index 6f6824a9c..77d2238fc 100644 --- a/outdated/dat/symbols +++ b/outdated/dat/symbols @@ -1,4 +1,4 @@ -# NetHack 3.7 symbols $NHDT-Date: 1596498253 2020/08/03 23:44:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.22 $ +# NetHack 3.6 symbols $NHDT-Date: 1596498253 2020/08/03 23:44:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.22 $ # Copyright (c) 2006 by Michael Allison # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/include/mac-carbon.h b/outdated/include/mac-carbon.h index b773c732f..25bdbcf90 100644 --- a/outdated/include/mac-carbon.h +++ b/outdated/include/mac-carbon.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mac-carbon.h $NHDT-Date: 1596498540 2020/08/03 23:49:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.6 mac-carbon.h $NHDT-Date: 1596498540 2020/08/03 23:49:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 2003. */ /*-Copyright (c) Kevin Hugo, 2003. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/mac-qt.h b/outdated/include/mac-qt.h index 429106c92..a3a689ea7 100644 --- a/outdated/include/mac-qt.h +++ b/outdated/include/mac-qt.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mac-qt.h $NHDT-Date: 1596498541 2020/08/03 23:49:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.6 mac-qt.h $NHDT-Date: 1596498541 2020/08/03 23:49:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 2003. */ /*-Copyright (c) Kevin Hugo, 2003. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/mac-term.h b/outdated/include/mac-term.h index 8bef72d0b..610f2d214 100644 --- a/outdated/include/mac-term.h +++ b/outdated/include/mac-term.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mac-term.h $NHDT-Date: 1596498541 2020/08/03 23:49:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.6 mac-term.h $NHDT-Date: 1596498541 2020/08/03 23:49:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 2003. */ /*-Copyright (c) Kevin Hugo, 2003. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/macpopup.h b/outdated/include/macpopup.h index 873af3cc6..0e1e72eb4 100644 --- a/outdated/include/macpopup.h +++ b/outdated/include/macpopup.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 macpopup.h $NHDT-Date: 1596498542 2020/08/03 23:49:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 3.6 macpopup.h $NHDT-Date: 1596498542 2020/08/03 23:49:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) Nethack Development Team, 1999. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/mactty.h b/outdated/include/mactty.h index 7f84747bc..fb64887b7 100644 --- a/outdated/include/mactty.h +++ b/outdated/include/mactty.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mactty.h $NHDT-Date: 1596498543 2020/08/03 23:49:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 3.6 mactty.h $NHDT-Date: 1596498543 2020/08/03 23:49:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Jon W{tte 1993. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/macwin.h b/outdated/include/macwin.h index 1e017ae2b..ddf20170f 100644 --- a/outdated/include/macwin.h +++ b/outdated/include/macwin.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 macwin.h $NHDT-Date: 1596498543 2020/08/03 23:49:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 3.6 macwin.h $NHDT-Date: 1596498543 2020/08/03 23:49:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kevin Hugo, 2003. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/mttypriv.h b/outdated/include/mttypriv.h index 5fc90abc4..5720dad94 100644 --- a/outdated/include/mttypriv.h +++ b/outdated/include/mttypriv.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mttypriv.h $NHDT-Date: 1596498551 2020/08/03 23:49:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.6 mttypriv.h $NHDT-Date: 1596498551 2020/08/03 23:49:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) Jon W{tte 1993. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/system.h b/outdated/include/system.h index 2616b07f6..1897dbcd3 100644 --- a/outdated/include/system.h +++ b/outdated/include/system.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 system.h $NHDT-Date: 1596498562 2020/08/03 23:49:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 3.6 system.h $NHDT-Date: 1596498562 2020/08/03 23:49:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/trampoli.h b/outdated/include/trampoli.h index f45d3bb98..5a4af9fcb 100644 --- a/outdated/include/trampoli.h +++ b/outdated/include/trampoli.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 trampoli.h $NHDT-Date: 1596498566 2020/08/03 23:49:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 3.6 trampoli.h $NHDT-Date: 1596498566 2020/08/03 23:49:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) 1989, by Norm Meluch and Stephen Spackman */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/winGnome.h b/outdated/include/winGnome.h index 93bbbeb13..96950fc1e 100644 --- a/outdated/include/winGnome.h +++ b/outdated/include/winGnome.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 winGnome.h $NHDT-Date: 1596498571 2020/08/03 23:49:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.6 winGnome.h $NHDT-Date: 1596498571 2020/08/03 23:49:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ /* Copyright (C) 1998 by Erik Andersen */ /* Copyright (C) 1998 by Anthony Taylor */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/wingem.h b/outdated/include/wingem.h index 4c1378c0e..21be09ce5 100644 --- a/outdated/include/wingem.h +++ b/outdated/include/wingem.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 wingem.h $NHDT-Date: 1596498570 2020/08/03 23:49:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 3.6 wingem.h $NHDT-Date: 1596498570 2020/08/03 23:49:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ /* Copyright (c) Christian Bressler, 1999 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/sys/unix/hints/cross-amiga b/outdated/sys/unix/hints/cross-amiga index ac66b6046..f21e9bfbc 100644 --- a/outdated/sys/unix/hints/cross-amiga +++ b/outdated/sys/unix/hints/cross-amiga @@ -1,4 +1,4 @@ -# NetHack 3.7 cross-amiga +# NetHack 3.6 cross-amiga # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/include/cross-amiga-post b/outdated/sys/unix/hints/include/cross-amiga-post index b3f5baf93..74de334cf 100644 --- a/outdated/sys/unix/hints/include/cross-amiga-post +++ b/outdated/sys/unix/hints/include/cross-amiga-post @@ -1,5 +1,5 @@ #===============-================================================= -# NetHack 3.7 include/cross-amiga-post $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 3.6 include/cross-amiga-post $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ # # Cross-compiling -POST section for Amiga diff --git a/outdated/sys/unix/hints/include/cross-amiga-pre b/outdated/sys/unix/hints/include/cross-amiga-pre index 2d5b24ede..afaadbba2 100644 --- a/outdated/sys/unix/hints/include/cross-amiga-pre +++ b/outdated/sys/unix/hints/include/cross-amiga-pre @@ -1,5 +1,5 @@ #===============-================================================= -# NetHack 3.7 include/cross-amiga-pre +# NetHack 3.6 include/cross-amiga-pre # # Cross-compiling -PRE section for amiga # @@ -141,7 +141,7 @@ override TARGET_CFLAGS = -c -O $(TOOLARCH) \ -I../outdated/sys/amiga -I../win/share \ $(LUAINCL) -DAMIGA -DTILES_IN_GLYPHMAP $(PDCURSESDEF) \ -DCROSSCOMPILE -DCROSSCOMPILE_TARGET -DCROSS_TO_AMIGA \ - -DAMIGA_VERSION_STRING=\""VER: NetHack 3.7.0\"" + -DAMIGA_VERSION_STRING=\""VER: NetHack 3.6.0\"" # -DMICRO -DPATHLEN=31 -DFILENAME=80 override TARGET_CXXFLAGS = $(TARGET_CFLAGS) ifeq "$(REGEXOBJ)" "$(TARGETPFX)cppregex.o" diff --git a/outdated/sys/unix/hints/linux b/outdated/sys/unix/hints/linux index 48ab631c1..73220fce7 100644 --- a/outdated/sys/unix/hints/linux +++ b/outdated/sys/unix/hints/linux @@ -1,5 +1,5 @@ # -# NetHack 3.7 linux $NHDT-Date: 1596498415 2020/08/03 23:46:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ +# NetHack 3.6 linux $NHDT-Date: 1596498415 2020/08/03 23:46:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/linux-qt4 b/outdated/sys/unix/hints/linux-qt4 index 3ef04923d..a199fdaa8 100644 --- a/outdated/sys/unix/hints/linux-qt4 +++ b/outdated/sys/unix/hints/linux-qt4 @@ -1,5 +1,5 @@ # -# NetHack 3.7 linux-qt4 $NHDT-Date: 1596498416 2020/08/03 23:46:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.29 $ +# NetHack 3.6 linux-qt4 $NHDT-Date: 1596498416 2020/08/03 23:46:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.29 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/linux-qt5 b/outdated/sys/unix/hints/linux-qt5 index 7d24406e0..2b30e9690 100644 --- a/outdated/sys/unix/hints/linux-qt5 +++ b/outdated/sys/unix/hints/linux-qt5 @@ -1,5 +1,5 @@ # -# NetHack 3.7 linux-qt5 $NHDT-Date: 1596498417 2020/08/03 23:46:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ +# NetHack 3.6 linux-qt5 $NHDT-Date: 1596498417 2020/08/03 23:46:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/linux-x11 b/outdated/sys/unix/hints/linux-x11 index 64dc9c235..2e8599de1 100644 --- a/outdated/sys/unix/hints/linux-x11 +++ b/outdated/sys/unix/hints/linux-x11 @@ -1,5 +1,5 @@ # -# NetHack 3.7 linux-x11 $NHDT-Date: 1596498418 2020/08/03 23:46:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ +# NetHack 3.6 linux-x11 $NHDT-Date: 1596498418 2020/08/03 23:46:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/macosx b/outdated/sys/unix/hints/macosx index c74742396..2853d5911 100644 --- a/outdated/sys/unix/hints/macosx +++ b/outdated/sys/unix/hints/macosx @@ -1,5 +1,5 @@ # -# NetHack 3.7 macosx $NHDT-Date: 1596498419 2020/08/03 23:46:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ +# NetHack 3.6 macosx $NHDT-Date: 1596498419 2020/08/03 23:46:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/macosx10.10 b/outdated/sys/unix/hints/macosx10.10 index 262a8af33..e87538182 100644 --- a/outdated/sys/unix/hints/macosx10.10 +++ b/outdated/sys/unix/hints/macosx10.10 @@ -1,5 +1,5 @@ # -# NetHack 3.7 macosx10.11 $NHDT-Date: 1596498420 2020/08/03 23:47:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.58 $ +# NetHack 3.6 macosx10.11 $NHDT-Date: 1596498420 2020/08/03 23:47:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.58 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/macosx10.10-qt b/outdated/sys/unix/hints/macosx10.10-qt index 99899ec1e..5c0c4e2af 100644 --- a/outdated/sys/unix/hints/macosx10.10-qt +++ b/outdated/sys/unix/hints/macosx10.10-qt @@ -1,5 +1,5 @@ # -# NetHack 3.7 macosx10.10-qt $NHDT-Date: 1597704795 2020/08/17 22:53:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.63 $ +# NetHack 3.6 macosx10.10-qt $NHDT-Date: 1597704795 2020/08/17 22:53:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.63 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/macosx10.14 b/outdated/sys/unix/hints/macosx10.14 index 79454a7ae..402cd0cc0 100644 --- a/outdated/sys/unix/hints/macosx10.14 +++ b/outdated/sys/unix/hints/macosx10.14 @@ -1,5 +1,5 @@ # -# NetHack 3.7 macosx10.14 $NHDT-Date: 1596498422 2020/08/03 23:47:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.64 $ +# NetHack 3.6 macosx10.14 $NHDT-Date: 1596498422 2020/08/03 23:47:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.64 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/macosx10.5 b/outdated/sys/unix/hints/macosx10.5 index b4a5def41..29eacc428 100644 --- a/outdated/sys/unix/hints/macosx10.5 +++ b/outdated/sys/unix/hints/macosx10.5 @@ -1,5 +1,5 @@ # -# NetHack 3.7 macosx10.5 $NHDT-Date: 1596498424 2020/08/03 23:47:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.34 $ +# NetHack 3.6 macosx10.5 $NHDT-Date: 1596498424 2020/08/03 23:47:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.34 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2009. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/macosx10.7 b/outdated/sys/unix/hints/macosx10.7 index e307e0ec8..3c371c9fb 100644 --- a/outdated/sys/unix/hints/macosx10.7 +++ b/outdated/sys/unix/hints/macosx10.7 @@ -1,5 +1,5 @@ # -# NetHack 3.7 macosx10.7 $NHDT-Date: 1596498424 2020/08/03 23:47:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.38 $ +# NetHack 3.6 macosx10.7 $NHDT-Date: 1596498424 2020/08/03 23:47:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.38 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2009. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/macosx10.8 b/outdated/sys/unix/hints/macosx10.8 index 0961bb198..8f7aea25a 100644 --- a/outdated/sys/unix/hints/macosx10.8 +++ b/outdated/sys/unix/hints/macosx10.8 @@ -1,5 +1,5 @@ # -# NetHack 3.7 macosx10.8 $NHDT-Date: 1596498425 2020/08/03 23:47:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ +# NetHack 3.6 macosx10.8 $NHDT-Date: 1596498425 2020/08/03 23:47:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2009. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/vms/lev_lex.h b/outdated/sys/vms/lev_lex.h index 2198df851..97e688540 100644 --- a/outdated/sys/vms/lev_lex.h +++ b/outdated/sys/vms/lev_lex.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 lev_lex.h $NHDT-Date: 1596498300 2020/08/03 23:45:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.6 lev_lex.h $NHDT-Date: 1596498300 2020/08/03 23:45:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ /* "vms/lev_lex.h" copied into "util/stdio.h" for use in *_lex.c only! * This is an awful kludge to allow util/*_lex.c made by SunOS's `lex' * to be compiled as is. (It isn't needed with `flex' or VMS POSIX diff --git a/outdated/sys/wince/winhack.rc b/outdated/sys/wince/winhack.rc index 504cc228e..99047d98a 100644 --- a/outdated/sys/wince/winhack.rc +++ b/outdated/sys/wince/winhack.rc @@ -300,7 +300,7 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "Comments", "NetHack 3.7.0 for Windows CE\0" + VALUE "Comments", "NetHack 3.6.0 for Windows CE\0" VALUE "CompanyName", " \0" VALUE "FileDescription", "nethackm\0" VALUE "FileVersion", "3, 7, 0, 0\0" diff --git a/outdated/sys/wince/winhcksp.rc b/outdated/sys/wince/winhcksp.rc index 959fba59c..e4b9ac50e 100644 --- a/outdated/sys/wince/winhcksp.rc +++ b/outdated/sys/wince/winhcksp.rc @@ -276,7 +276,7 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "Comments", "NetHack 3.7.0 for Smartphone 2002\0" + VALUE "Comments", "NetHack 3.6.0 for Smartphone 2002\0" VALUE "CompanyName", " \0" VALUE "FileDescription", "nethackm\0" VALUE "FileVersion", "3, 7, 0, 0\0" diff --git a/sound/windsound/windsound.c b/sound/windsound/windsound.c index 0dc486f18..78077f435 100644 --- a/sound/windsound/windsound.c +++ b/sound/windsound/windsound.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 windsound.c $NHDT-Date: $ $NHDT-Branch: $NHDT-Revision: $ */ +/* NetHack 5.0 windsound.c $NHDT-Date: $ $NHDT-Branch: $NHDT-Revision: $ */ /* Copyright (c) Michael Allison, 2022 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/amiga/amistack.c b/sys/amiga/amistack.c index e0ea10a7b..2d38b552a 100644 --- a/sys/amiga/amistack.c +++ b/sys/amiga/amistack.c @@ -16,7 +16,7 @@ /* * Increase stack size to allow deep recursions. - * NetHack 3.7 with Lua needs significantly more stack than 3.6. + * NetHack 5.0 with Lua needs significantly more stack than 3.6. */ #ifdef __SASC_60 diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index 44765987e..f974bc490 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 libnhmain.c $NHDT-Date: 1693359589 2023/08/30 01:39:49 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.106 $ */ +/* NetHack 5.0 libnhmain.c $NHDT-Date: 1693359589 2023/08/30 01:39:49 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.106 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/msdos/msdos.c b/sys/msdos/msdos.c index 86adbd4bb..e73880242 100644 --- a/sys/msdos/msdos.c +++ b/sys/msdos/msdos.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 msdos.c $NHDT-Date: 1596498269 2020/08/03 23:44:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 msdos.c $NHDT-Date: 1596498269 2020/08/03 23:44:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ /* Copyright (c) NetHack PC Development Team 1990 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/msdos/pckeys.c b/sys/msdos/pckeys.c index 5e5c1ee69..068d9d116 100644 --- a/sys/msdos/pckeys.c +++ b/sys/msdos/pckeys.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pckeys.c $NHDT-Date: 1596498270 2020/08/03 23:44:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 pckeys.c $NHDT-Date: 1596498270 2020/08/03 23:44:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) NetHack PC Development Team 1996 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/msdos/pctiles.c b/sys/msdos/pctiles.c index 4e942e534..b675b7d7d 100644 --- a/sys/msdos/pctiles.c +++ b/sys/msdos/pctiles.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pctiles.c $NHDT-Date: 1596498271 2020/08/03 23:44:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 pctiles.c $NHDT-Date: 1596498271 2020/08/03 23:44:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994 */ /* NetHack may be freely redistributed. See license for details. */ /* */ diff --git a/sys/msdos/tile2bin.c b/sys/msdos/tile2bin.c index 0e90935fc..28e0be4c0 100644 --- a/sys/msdos/tile2bin.c +++ b/sys/msdos/tile2bin.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 tile2bin.c $NHDT-Date: 1596498275 2020/08/03 23:44:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 tile2bin.c $NHDT-Date: 1596498275 2020/08/03 23:44:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994, 1995 */ /* NetHack may be freely redistributed. See license for details. */ @@ -185,7 +185,7 @@ main(int argc, char *argv[]) tibheader.compiler = OTHER_COMP; #endif - strncpy(tibheader.ident, "NetHack 3.7 MSDOS Port binary tile file", 80); + strncpy(tibheader.ident, "NetHack 5.0 MSDOS Port binary tile file", 80); #if !defined(NOSTRFTIME) (void) strftime(tibheader.timestamp, sizeof tibheader.timestamp, "%c", newtime); diff --git a/sys/msdos/video.c b/sys/msdos/video.c index 57911edab..5d7f4fb30 100644 --- a/sys/msdos/video.c +++ b/sys/msdos/video.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 video.c $NHDT-Date: 1596498277 2020/08/03 23:44:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.16 $ */ +/* NetHack 5.0 video.c $NHDT-Date: 1596498277 2020/08/03 23:44:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.16 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994, 2001 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/msdos/vidtxt.c b/sys/msdos/vidtxt.c index 990d6d064..37402cc5d 100644 --- a/sys/msdos/vidtxt.c +++ b/sys/msdos/vidtxt.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vidtxt.c $NHDT-Date: 1596498278 2020/08/03 23:44:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 vidtxt.c $NHDT-Date: 1596498278 2020/08/03 23:44:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) NetHack PC Development Team 1993 */ /* NetHack may be freely redistributed. See license for details. */ /* */ diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index 140b816a5..fed1be22f 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vidvga.c $NHDT-Date: 1606765216 2020/11/30 19:40:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ */ +/* NetHack 5.0 vidvga.c $NHDT-Date: 1606765216 2020/11/30 19:40:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ */ /* Copyright (c) NetHack PC Development Team 1995 */ /* NetHack may be freely redistributed. See license for details. */ /* diff --git a/sys/share/ioctl.c b/sys/share/ioctl.c index d6a2468c5..4d92acd15 100644 --- a/sys/share/ioctl.c +++ b/sys/share/ioctl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 ioctl.c $NHDT-Date: 1596498280 2020/08/03 23:44:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 ioctl.c $NHDT-Date: 1596498280 2020/08/03 23:44:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index c321e90db..3ad30b682 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pcmain.c $NHDT-Date: 1693359605 2023/08/30 01:40:05 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.133 $ */ +/* NetHack 5.0 pcmain.c $NHDT-Date: 1693359605 2023/08/30 01:40:05 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.133 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/pcsys.c b/sys/share/pcsys.c index 07cab8e42..c48d79068 100644 --- a/sys/share/pcsys.c +++ b/sys/share/pcsys.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pcsys.c $NHDT-Date: 1596498283 2020/08/03 23:44:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.42 $ */ +/* NetHack 5.0 pcsys.c $NHDT-Date: 1596498283 2020/08/03 23:44:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.42 $ */ /* Copyright (c) 2012 by Michael Allison */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/pctty.c b/sys/share/pctty.c index fee616980..7a8192ca7 100644 --- a/sys/share/pctty.c +++ b/sys/share/pctty.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pctty.c $NHDT-Date: 1596498284 2020/08/03 23:44:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 pctty.c $NHDT-Date: 1596498284 2020/08/03 23:44:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2005. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/pcunix.c b/sys/share/pcunix.c index f95a26a79..48c0da670 100644 --- a/sys/share/pcunix.c +++ b/sys/share/pcunix.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pcunix.c $NHDT-Date: 1596498285 2020/08/03 23:44:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.42 $ */ +/* NetHack 5.0 pcunix.c $NHDT-Date: 1596498285 2020/08/03 23:44:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.42 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/pmatchregex.c b/sys/share/pmatchregex.c index 53c5ef531..cf98672a8 100644 --- a/sys/share/pmatchregex.c +++ b/sys/share/pmatchregex.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pmatchregex.c $NHDT-Date: 1737691300 2025/01/23 20:01:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 pmatchregex.c $NHDT-Date: 1737691300 2025/01/23 20:01:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) Sean Hunt 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/posixregex.c b/sys/share/posixregex.c index d6b3c4845..e5bc92e98 100644 --- a/sys/share/posixregex.c +++ b/sys/share/posixregex.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 posixregex.c $NHDT-Date: 1596498286 2020/08/03 23:44:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ */ +/* NetHack 5.0 posixregex.c $NHDT-Date: 1596498286 2020/08/03 23:44:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ */ /* Copyright (c) Sean Hunt 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/tclib.c b/sys/share/tclib.c index d9ecace06..80bfee0f3 100644 --- a/sys/share/tclib.c +++ b/sys/share/tclib.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 tclib.c $NHDT-Date: 1596498287 2020/08/03 23:44:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 tclib.c $NHDT-Date: 1596498287 2020/08/03 23:44:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) Robert Patrick Rankin, 1995 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/unixtty.c b/sys/share/unixtty.c index 3dce02269..7fdf8e6d3 100644 --- a/sys/share/unixtty.c +++ b/sys/share/unixtty.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 unixtty.c $NHDT-Date: 1596498288 2020/08/03 23:44:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.27 $ */ +/* NetHack 5.0 unixtty.c $NHDT-Date: 1596498288 2020/08/03 23:44:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.27 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index a197056cc..c90385e5f 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 unixmain.c $NHDT-Date: 1711213891 2024/03/23 17:11:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.127 $ */ +/* NetHack 5.0 unixmain.c $NHDT-Date: 1711213891 2024/03/23 17:11:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.127 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/unix/unixres.c b/sys/unix/unixres.c index 538d8bdcc..64006ddf2 100644 --- a/sys/unix/unixres.c +++ b/sys/unix/unixres.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 unixres.c $NHDT-Date: 1596498298 2020/08/03 23:44:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 unixres.c $NHDT-Date: 1596498298 2020/08/03 23:44:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Slash'EM development team, 2001. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/unix/unixunix.c b/sys/unix/unixunix.c index 8450da5f8..9bb5d42a8 100644 --- a/sys/unix/unixunix.c +++ b/sys/unix/unixunix.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 unixunix.c $NHDT-Date: 1711213894 2024/03/23 17:11:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.43 $ */ +/* NetHack 5.0 unixunix.c $NHDT-Date: 1711213894 2024/03/23 17:11:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.43 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/vms/oldcrtl.c b/sys/vms/oldcrtl.c index 2753c7755..f60da1b63 100644 --- a/sys/vms/oldcrtl.c +++ b/sys/vms/oldcrtl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 oldcrtl.c $NHDT-Date: 1596498304 2020/08/03 23:45:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 oldcrtl.c $NHDT-Date: 1596498304 2020/08/03 23:45:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ /* Pat Rankin May'90 */ /* VMS NetHack support, not needed for vms 4.6,4.7,5.x,or later */ diff --git a/sys/vms/vmsfiles.c b/sys/vms/vmsfiles.c index 38a80b9a8..82a12c934 100644 --- a/sys/vms/vmsfiles.c +++ b/sys/vms/vmsfiles.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vmsfiles.c $NHDT-Date: 1685522046 2023/05/31 08:34:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.19 $ */ +/* NetHack 5.0 vmsfiles.c $NHDT-Date: 1685522046 2023/05/31 08:34:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.19 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2007. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/vms/vmsmail.c b/sys/vms/vmsmail.c index 24f9ad5fa..afe279cb4 100644 --- a/sys/vms/vmsmail.c +++ b/sys/vms/vmsmail.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vmsmail.c $NHDT-Date: 1685522048 2023/05/31 08:34:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ */ +/* NetHack 5.0 vmsmail.c $NHDT-Date: 1685522048 2023/05/31 08:34:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ */ /* Copyright (c) Robert Patrick Rankin, 1991. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/vms/vmsmain.c b/sys/vms/vmsmain.c index d69c4de4d..23d80025f 100644 --- a/sys/vms/vmsmain.c +++ b/sys/vms/vmsmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vmsmain.c $NHDT-Date: 1693359633 2023/08/30 01:40:33 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.57 $ */ +/* NetHack 5.0 vmsmain.c $NHDT-Date: 1693359633 2023/08/30 01:40:33 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.57 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/vms/vmsmisc.c b/sys/vms/vmsmisc.c index fa705161c..d84c5c20c 100644 --- a/sys/vms/vmsmisc.c +++ b/sys/vms/vmsmisc.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vmsmisc.c $NHDT-Date: 1685522049 2023/05/31 08:34:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ */ +/* NetHack 5.0 vmsmisc.c $NHDT-Date: 1685522049 2023/05/31 08:34:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ */ /* Copyright (c) 2011 by Robert Patrick Rankin */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/vms/vmstty.c b/sys/vms/vmstty.c index 9b0051c0a..9d1475391 100644 --- a/sys/vms/vmstty.c +++ b/sys/vms/vmstty.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vmstty.c $NHDT-Date: 1596498309 2020/08/03 23:45:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ +/* NetHack 5.0 vmstty.c $NHDT-Date: 1596498309 2020/08/03 23:45:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/vms/vmsunix.c b/sys/vms/vmsunix.c index 89b18a174..56455627d 100644 --- a/sys/vms/vmsunix.c +++ b/sys/vms/vmsunix.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vmsunix.c $NHDT-Date: 1685522050 2023/05/31 08:34:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.31 $ */ +/* NetHack 5.0 vmsunix.c $NHDT-Date: 1685522050 2023/05/31 08:34:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.31 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index 9ffdc5880..cf766ff4a 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 consoletty.c $NHDT-Date: 1596498316 2020/08/03 23:45:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.117 $ */ +/* NetHack 5.0 consoletty.c $NHDT-Date: 1596498316 2020/08/03 23:45:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.117 $ */ /* Copyright (c) NetHack PC Development Team 1993 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/windows/win10.c b/sys/windows/win10.c index 7eeaab811..d9af80b07 100644 --- a/sys/windows/win10.c +++ b/sys/windows/win10.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 win10.c $NHDT-Date: 1596498318 2020/08/03 23:45:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 win10.c $NHDT-Date: 1596498318 2020/08/03 23:45:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ /* Copyright (C) 2018 by Bart House */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/windows/windmain.c b/sys/windows/windmain.c index 99567f9d2..12a321929 100644 --- a/sys/windows/windmain.c +++ b/sys/windows/windmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 windmain.c $NHDT-Date: 1693359653 2023/08/30 01:40:53 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.189 $ */ +/* NetHack 5.0 windmain.c $NHDT-Date: 1693359653 2023/08/30 01:40:53 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.189 $ */ /* Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/windows/windsys.c b/sys/windows/windsys.c index 8826c33e4..245f2681f 100644 --- a/sys/windows/windsys.c +++ b/sys/windows/windsys.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 windsys.c $NHDT-Date: 1710949760 2024/03/20 15:49:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.95 $ */ +/* NetHack 5.0 windsys.c $NHDT-Date: 1710949760 2024/03/20 15:49:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.95 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/Window.c b/win/X11/Window.c index 82cb5a1c6..645193a77 100644 --- a/win/X11/Window.c +++ b/win/X11/Window.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 Window.c $NHDT-Date: 1596498371 2020/08/03 23:46:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 Window.c $NHDT-Date: 1596498371 2020/08/03 23:46:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/winX.c b/win/X11/winX.c index f74408269..24fb4fcff 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 winX.c $NHDT-Date: 1717967337 2024/06/09 21:08:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.136 $ */ +/* NetHack 5.0 winX.c $NHDT-Date: 1717967337 2024/06/09 21:08:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.136 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/winmap.c b/win/X11/winmap.c index 39b980b28..7c2dbfcac 100644 --- a/win/X11/winmap.c +++ b/win/X11/winmap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 winmap.c $NHDT-Date: 1682206649 2023/04/22 23:37:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.59 $ */ +/* NetHack 5.0 winmap.c $NHDT-Date: 1682206649 2023/04/22 23:37:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.59 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index d4188ac22..85deaf56f 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 winmenu.c $NHDT-Date: 1644531504 2022/02/10 22:18:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.50 $ */ +/* NetHack 5.0 winmenu.c $NHDT-Date: 1644531504 2022/02/10 22:18:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.50 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/winmesg.c b/win/X11/winmesg.c index 6c5c01f35..107c37d58 100644 --- a/win/X11/winmesg.c +++ b/win/X11/winmesg.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 winmesg.c $NHDT-Date: 1596498373 2020/08/03 23:46:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 winmesg.c $NHDT-Date: 1596498373 2020/08/03 23:46:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/winmisc.c b/win/X11/winmisc.c index 1fcdf471c..4baae3f49 100644 --- a/win/X11/winmisc.c +++ b/win/X11/winmisc.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 winmisc.c $NHDT-Date: 1596498374 2020/08/03 23:46:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.49 $ */ +/* NetHack 5.0 winmisc.c $NHDT-Date: 1596498374 2020/08/03 23:46:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.49 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 4e520203c..761dd93e9 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 winstat.c $NHDT-Date: 1649269127 2022/04/06 18:18:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.37 $ */ +/* NetHack 5.0 winstat.c $NHDT-Date: 1649269127 2022/04/06 18:18:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.37 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/wintext.c b/win/X11/wintext.c index e401b7018..cf2a1d7eb 100644 --- a/win/X11/wintext.c +++ b/win/X11/wintext.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wintext.c $NHDT-Date: 1597967808 2020/08/20 23:56:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.22 $ */ +/* NetHack 5.0 wintext.c $NHDT-Date: 1597967808 2020/08/20 23:56:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.22 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/winval.c b/win/X11/winval.c index 651ba2cbb..62e3b9937 100644 --- a/win/X11/winval.c +++ b/win/X11/winval.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 winval.c $NHDT-Date: 1611697183 2021/01/26 21:39:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 winval.c $NHDT-Date: 1611697183 2021/01/26 21:39:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/chain/wc_chainin.c b/win/chain/wc_chainin.c index ab63cf3c7..4e05d3933 100644 --- a/win/chain/wc_chainin.c +++ b/win/chain/wc_chainin.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wc_chainin.c $NHDT-Date: 1596498323 2020/08/03 23:45:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 wc_chainin.c $NHDT-Date: 1596498323 2020/08/03 23:45:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) Kenneth Lorber, 2012 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/chain/wc_chainout.c b/win/chain/wc_chainout.c index 72459b883..a330e0efb 100644 --- a/win/chain/wc_chainout.c +++ b/win/chain/wc_chainout.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wc_chainout.c $NHDT-Date: 1596498324 2020/08/03 23:45:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 wc_chainout.c $NHDT-Date: 1596498324 2020/08/03 23:45:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) Kenneth Lorber, 2012 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/chain/wc_trace.c b/win/chain/wc_trace.c index 7287e82a4..936bcf26f 100644 --- a/win/chain/wc_trace.c +++ b/win/chain/wc_trace.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wc_trace.c $NHDT-Date: 1596498324 2020/08/03 23:45:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 wc_trace.c $NHDT-Date: 1596498324 2020/08/03 23:45:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Kenneth Lorber, 2012 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index b6a51eb2a..b317c8543 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursdial.c */ +/* NetHack 5.0 cursdial.c */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 529b46182..5ab7ea198 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursinit.c */ +/* NetHack 5.0 cursinit.c */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursinvt.c b/win/curses/cursinvt.c index 1aadad9f9..3369b2d8c 100644 --- a/win/curses/cursinvt.c +++ b/win/curses/cursinvt.c @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursinvt.c */ +/* NetHack 5.0 cursinvt.c */ /* Copyright (c) Fredrik Ljungdahl, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 4d1923eda..5060c3e85 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursmain.c */ +/* NetHack 5.0 cursmain.c */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index adc039f52..892369f63 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursmesg.c */ +/* NetHack 5.0 cursmesg.c */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 4b4fe97c1..3084d193a 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursmisc.c */ +/* NetHack 5.0 cursmisc.c */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index b44fae883..0abcecdc7 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursstat.c */ +/* NetHack 5.0 cursstat.c */ /* Copyright (c) Andy Thomson, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/curswins.c b/win/curses/curswins.c index 52e21db37..21e1bae09 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 curswins.c */ +/* NetHack 5.0 curswins.c */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/share/bmptiles.c b/win/share/bmptiles.c index 31ea391bb..5c6bd09c8 100644 --- a/win/share/bmptiles.c +++ b/win/share/bmptiles.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 bmptiles.c $NHDT-Date: 1596498334 2020/08/03 23:45:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ */ +/* NetHack 5.0 bmptiles.c $NHDT-Date: 1596498334 2020/08/03 23:45:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ */ /* Copyright (c) Ray Chason, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/share/giftiles.c b/win/share/giftiles.c index bb2db7972..1fdf1a0bc 100644 --- a/win/share/giftiles.c +++ b/win/share/giftiles.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 giftiles.c $NHDT-Date: 1596498335 2020/08/03 23:45:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ */ +/* NetHack 5.0 giftiles.c $NHDT-Date: 1596498335 2020/08/03 23:45:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ */ /* Copyright (c) Ray Chason, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/share/ppmwrite.c b/win/share/ppmwrite.c index 8cd7a09cc..b9f5848e3 100644 --- a/win/share/ppmwrite.c +++ b/win/share/ppmwrite.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 ppmwrite.c $NHDT-Date: 1596498336 2020/08/03 23:45:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ */ +/* NetHack 5.0 ppmwrite.c $NHDT-Date: 1596498336 2020/08/03 23:45:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ */ /* this produces a raw ppm file, with a 15-character header of * "P6 3-digit-width 3-digit-height 255\n" */ diff --git a/win/share/thintile.c b/win/share/thintile.c index 32b2cfa8b..b975c37cf 100644 --- a/win/share/thintile.c +++ b/win/share/thintile.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 thintile.c $NHDT-Date: 1596498337 2020/08/03 23:45:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 thintile.c $NHDT-Date: 1596498337 2020/08/03 23:45:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) NetHack Development Team 1995 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/share/tile2bmp.c b/win/share/tile2bmp.c index 4b7312aff..e875763f9 100644 --- a/win/share/tile2bmp.c +++ b/win/share/tile2bmp.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 tile2bmp.c $NHDT-Date: 1737281026 2025/01/19 02:03:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.51 $ */ +/* NetHack 5.0 tile2bmp.c $NHDT-Date: 1737281026 2025/01/19 02:03:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.51 $ */ /* Copyright (c) NetHack PC Development Team 1995 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/share/tilemap.c b/win/share/tilemap.c index 41583dfa0..5504dd95b 100644 --- a/win/share/tilemap.c +++ b/win/share/tilemap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 tilemap.c $NHDT-Date: 1737720923 2025/01/24 04:15:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.87 $ */ +/* NetHack 5.0 tilemap.c $NHDT-Date: 1737720923 2025/01/24 04:15:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.87 $ */ /* Copyright (c) 2016 by Michael Allison */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/share/tileset.c b/win/share/tileset.c index ce32d6ffa..6a1280fb4 100644 --- a/win/share/tileset.c +++ b/win/share/tileset.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 tileset.c $NHDT-Date: 1596498341 2020/08/03 23:45:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ */ +/* NetHack 5.0 tileset.c $NHDT-Date: 1596498341 2020/08/03 23:45:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ */ /* Copyright (c) Ray Chason, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/share/tiletext.c b/win/share/tiletext.c index ac9a8afd7..80f630f94 100644 --- a/win/share/tiletext.c +++ b/win/share/tiletext.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 tiletext.c $NHDT-Date: 1596498342 2020/08/03 23:45:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.17 $ */ +/* NetHack 5.0 tiletext.c $NHDT-Date: 1596498342 2020/08/03 23:45:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.17 $ */ /* Copyright (c) 2016 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/shim/winshim.c b/win/shim/winshim.c index 5e701c332..a18534d35 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 winshim.c $NHDT-Date: 1596498345 2020/08/03 23:45:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.259 $ */ +/* NetHack 5.0 winshim.c $NHDT-Date: 1596498345 2020/08/03 23:45:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.259 $ */ /* Copyright (c) Adam Powers, 2020 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/tty/getline.c b/win/tty/getline.c index acb3f7f14..17070f0fc 100644 --- a/win/tty/getline.c +++ b/win/tty/getline.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 getline.c $NHDT-Date: 1701285885 2023/11/29 19:24:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.59 $ */ +/* NetHack 5.0 getline.c $NHDT-Date: 1701285885 2023/11/29 19:24:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.59 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/tty/termcap.c b/win/tty/termcap.c index ad8e25764..b5ffcef4e 100644 --- a/win/tty/termcap.c +++ b/win/tty/termcap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 termcap.c $NHDT-Date: 1701946349 2023/12/07 10:52:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.60 $ */ +/* NetHack 5.0 termcap.c $NHDT-Date: 1701946349 2023/12/07 10:52:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.60 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/tty/topl.c b/win/tty/topl.c index c20dfa288..a216b3435 100644 --- a/win/tty/topl.c +++ b/win/tty/topl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 topl.c $NHDT-Date: 1717967339 2024/06/09 21:08:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.89 $ */ +/* NetHack 5.0 topl.c $NHDT-Date: 1717967339 2024/06/09 21:08:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.89 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/tty/wintty.c b/win/tty/wintty.c index b2c6a5c42..e8cc68216 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wintty.c $NHDT-Date: 1737691300 2025/01/23 20:01:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.420 $ */ +/* NetHack 5.0 wintty.c $NHDT-Date: 1737691300 2025/01/23 20:01:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.420 $ */ /* Copyright (c) David Cohrs, 1991 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/NetHackW.c b/win/win32/NetHackW.c index 5a945af5c..bee362598 100644 --- a/win/win32/NetHackW.c +++ b/win/win32/NetHackW.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 NetHackW.c $NHDT-Date: 1693359674 2023/08/30 01:41:14 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.79 $ */ +/* NetHack 5.0 NetHackW.c $NHDT-Date: 1693359674 2023/08/30 01:41:14 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.79 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhaskyn.c b/win/win32/mhaskyn.c index b510c064f..9ed889b9a 100644 --- a/win/win32/mhaskyn.c +++ b/win/win32/mhaskyn.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhaskyn.c $NHDT-Date: 1596498346 2020/08/03 23:45:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 mhaskyn.c $NHDT-Date: 1596498346 2020/08/03 23:45:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhdlg.c b/win/win32/mhdlg.c index 94a7ecf3e..0d48f2531 100644 --- a/win/win32/mhdlg.c +++ b/win/win32/mhdlg.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhdlg.c $NHDT-Date: 1596498347 2020/08/03 23:45:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.36 $ */ +/* NetHack 5.0 mhdlg.c $NHDT-Date: 1596498347 2020/08/03 23:45:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.36 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhfont.c b/win/win32/mhfont.c index 291acacbc..5b39bcbf0 100644 --- a/win/win32/mhfont.c +++ b/win/win32/mhfont.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhfont.c $NHDT-Date: 1596498349 2020/08/03 23:45:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.29 $ */ +/* NetHack 5.0 mhfont.c $NHDT-Date: 1596498349 2020/08/03 23:45:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.29 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhinput.c b/win/win32/mhinput.c index 9ad6c32f0..7f209ea20 100644 --- a/win/win32/mhinput.c +++ b/win/win32/mhinput.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhinput.c $NHDT-Date: 1596498350 2020/08/03 23:45:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 mhinput.c $NHDT-Date: 1596498350 2020/08/03 23:45:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmain.c b/win/win32/mhmain.c index f3eae350c..94f2249bc 100644 --- a/win/win32/mhmain.c +++ b/win/win32/mhmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhmain.c $NHDT-Date: 1596498352 2020/08/03 23:45:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.76 $ */ +/* NetHack 5.0 mhmain.c $NHDT-Date: 1596498352 2020/08/03 23:45:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.76 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmap.c b/win/win32/mhmap.c index 46a7ee1d0..a24e99f0e 100644 --- a/win/win32/mhmap.c +++ b/win/win32/mhmap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhmap.c $NHDT-Date: 1596498353 2020/08/03 23:45:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.85 $ */ +/* NetHack 5.0 mhmap.c $NHDT-Date: 1596498353 2020/08/03 23:45:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.85 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmenu.c b/win/win32/mhmenu.c index d39bdc1b4..3f9b7dfe8 100644 --- a/win/win32/mhmenu.c +++ b/win/win32/mhmenu.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhmenu.c $NHDT-Date: 1596498354 2020/08/03 23:45:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.74 $ */ +/* NetHack 5.0 mhmenu.c $NHDT-Date: 1596498354 2020/08/03 23:45:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.74 $ */ /* Copyright (c) Alex Kompel, 2002 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmsgwnd.c b/win/win32/mhmsgwnd.c index e4d62b5ab..8dc795fba 100644 --- a/win/win32/mhmsgwnd.c +++ b/win/win32/mhmsgwnd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhmsgwnd.c $NHDT-Date: 1596498357 2020/08/03 23:45:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ */ +/* NetHack 5.0 mhmsgwnd.c $NHDT-Date: 1596498357 2020/08/03 23:45:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhrip.c b/win/win32/mhrip.c index 28036307b..45188ac31 100644 --- a/win/win32/mhrip.c +++ b/win/win32/mhrip.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhrip.c $NHDT-Date: 1596498358 2020/08/03 23:45:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 5.0 mhrip.c $NHDT-Date: 1596498358 2020/08/03 23:45:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhsplash.c b/win/win32/mhsplash.c index 5609bab89..da5897978 100644 --- a/win/win32/mhsplash.c +++ b/win/win32/mhsplash.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhsplash.c $NHDT-Date: 1596498360 2020/08/03 23:46:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.36 $ */ +/* NetHack 5.0 mhsplash.c $NHDT-Date: 1596498360 2020/08/03 23:46:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.36 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhstatus.c b/win/win32/mhstatus.c index eee9047f8..d7e66505d 100644 --- a/win/win32/mhstatus.c +++ b/win/win32/mhstatus.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhstatus.c $NHDT-Date: 1596498360 2020/08/03 23:46:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.35 $ */ +/* NetHack 5.0 mhstatus.c $NHDT-Date: 1596498360 2020/08/03 23:46:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.35 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhtext.c b/win/win32/mhtext.c index 8463a187e..72ab526e6 100644 --- a/win/win32/mhtext.c +++ b/win/win32/mhtext.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhtext.c $NHDT-Date: 1596498362 2020/08/03 23:46:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.31 $ */ +/* NetHack 5.0 mhtext.c $NHDT-Date: 1596498362 2020/08/03 23:46:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.31 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index 55ba2f696..9f8bfd68f 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mswproc.c $NHDT-Date: 1717967341 2024/06/09 21:09:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.193 $ */ +/* NetHack 5.0 mswproc.c $NHDT-Date: 1717967341 2024/06/09 21:09:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.193 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ @@ -2365,7 +2365,7 @@ logDebug(const char *fmt, ...) /* Reading and writing settings from the registry. */ #define CATEGORYKEY "Software" #define COMPANYKEY "NetHack" -#define PRODUCTKEY "NetHack 3.7.0" +#define PRODUCTKEY "NetHack 5.0.0" #define SETTINGSKEY "Settings" #define MAINSHOWSTATEKEY "MainShowState" #define MAINMINXKEY "MainMinX" From d5d76f0f140795caf61e8dc0d391d2feede912ff Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 10:10:05 -0400 Subject: [PATCH 031/702] doc util --- doc/Guidebook.mn | 6 +++--- doc/Guidebook.tex | 8 ++++---- util/dlb_main.c | 2 +- util/makedefs.c | 2 +- util/panic.c | 2 +- util/recover.c | 2 +- util/sfctool.c | 2 +- util/sfexpasc.c | 2 +- util/stripbs.c | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 5ed40d031..238d331b7 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -3933,7 +3933,7 @@ and also .op autopickup_exception for ways to refine the behavior. .lp "" -Note: prior to version 3.7.0, the default for +Note: prior to version 5.0.0, the default for .op autopickup was \fIon\fP. .lp autoquiver @@ -5670,7 +5670,7 @@ An entry that maps a sound file to a user-specified message pattern. Each SOUND entry is broken down into the following parts: .PS "sound index" .PL MESG -message window mapping (the only one supported in 3.7.0); +message window mapping (the only one supported in 5.0.0); .PL msgtype optional; message type to use, see \(lqConfiguring Message Types\(rq .PL pattern @@ -6326,7 +6326,7 @@ Allows the following placeholders: .PL \f(CR%%\fP literal \(oq\f(CR%\fP\(cq .PL \f(CR%v\fP -version (eg. \(lq\f(CR3.7.0\-0\fP\(rq) +version (eg. \(lq\f(CR5.0.0\-0\fP\(rq) .PL \f(CR%u\fP game UID .PL \f(CR%t\fP diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 28443d737..825e22b92 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -23,7 +23,7 @@ %.au \author{Original version - Eric S. Raymond\\ -(Edited and expanded for 3.7.0 by Mike Stephenson and others)} +(Edited and expanded for 5.0.0 by Mike Stephenson and others)} %DO NOT REMOVE NH_DATESUB \date{Date(%B %-d, %Y)} \date{April 16, 2026} @@ -4263,7 +4263,7 @@ See ``\textit{pickup\textunderscore types}'' and also ``\textit{autopickup\textunderscore exception}'' for ways to refine the behavior. \\ %.lp "" -Note: prior to version 3.7.0, the default for \textit{autopickup} was \textit{on}. +Note: prior to version 5.0.0, the default for \textit{autopickup} was \textit{on}. %.lp \item[autoquiver] This option controls what happens when you attempt the `\texttt{f}' (fire) @@ -6250,7 +6250,7 @@ Each SOUND entry is broken down into the following parts: %.sd %.si -\texttt{MESG} --- message window mapping (the only one supported in 3.7.0);\\ +\texttt{MESG} --- message window mapping (the only one supported in 5.0.0);\\ \texttt{msgtype} --- optional; message type to use, see ``Configuring User Sounds''\\ \texttt{pattern} --- the pattern to match;\\ \texttt{sound file} --- the sound file to play;\\ @@ -6940,7 +6940,7 @@ Only available if your game is compiled with DUMPLOG. Allows the following placeholders: % FIXME: this should be changed to a nested list or else be forcibly indented \texttt{\%\%} --- literal `\texttt{\%}'\\ -\texttt{\%v} --- version (eg. ``\texttt{3.7.0-0}'')\\ +\texttt{\%v} --- version (eg. ``\texttt{5.0.0-0}'')\\ \texttt{\%u} --- game UID\\ \texttt{\%t} --- game start time, UNIX timestamp format\\ \texttt{\%T} --- current time, UNIX timestamp format\\ diff --git a/util/dlb_main.c b/util/dlb_main.c index 1926b871d..1912d1481 100644 --- a/util/dlb_main.c +++ b/util/dlb_main.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dlb_main.c $NHDT-Date: 1706213798 2024/01/25 20:16:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.27 $ */ +/* NetHack 5.0 dlb_main.c $NHDT-Date: 1706213798 2024/01/25 20:16:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.27 $ */ /* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1993. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/util/makedefs.c b/util/makedefs.c index 53c90c151..a19a5ae5e 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 makedefs.c $NHDT-Date: 1702948590 2023/12/19 01:16:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.233 $ */ +/* NetHack 5.0 makedefs.c $NHDT-Date: 1702948590 2023/12/19 01:16:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.233 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* Copyright (c) M. Stephenson, 1990, 1991. */ diff --git a/util/panic.c b/util/panic.c index 50fe43705..92c921ddb 100644 --- a/util/panic.c +++ b/util/panic.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 panic.c $NHDT-Date: 1596498262 2020/08/03 23:44:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 panic.c $NHDT-Date: 1596498262 2020/08/03 23:44:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/util/recover.c b/util/recover.c index 508263675..a1a7ed70b 100644 --- a/util/recover.c +++ b/util/recover.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 recover.c $NHDT-Date: 1687547437 2023/06/23 19:10:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.33 $ */ +/* NetHack 5.0 recover.c $NHDT-Date: 1687547437 2023/06/23 19:10:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.33 $ */ /* Copyright (c) Janet Walz, 1992. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/util/sfctool.c b/util/sfctool.c index 9c9423861..8d395cbbe 100644 --- a/util/sfctool.c +++ b/util/sfctool.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sfctool.c */ +/* NetHack 5.0 sfctool.c */ /* Copyright (c) Michael Allison, 2025. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/util/sfexpasc.c b/util/sfexpasc.c index 9f390633f..c27878020 100644 --- a/util/sfexpasc.c +++ b/util/sfexpasc.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sfexpasc.c.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ +/* NetHack 5.0 sfexpasc.c.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ /* Copyright (c) Michael Allison, 2025. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/util/stripbs.c b/util/stripbs.c index 15d319566..dd1452027 100644 --- a/util/stripbs.c +++ b/util/stripbs.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 stripbs.c */ +/* NetHack 5.0 stripbs.c */ /* Copyright (c) Michael Allison, 2025. */ /* NetHack may be freely redistributed. See license for details. */ From a6cdb6aefd6e3cb53f2bc8a4477f2f8bd1a1b52e Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 10:41:11 -0400 Subject: [PATCH 032/702] change sys/unix bits and doc --- doc/Guidebook.txt | 236 +++++++++++------------ doc/nethack.txt | 2 +- doc/options.txt | 2 +- doc/recover.txt | 2 +- doc/tmac.nh | 2 +- doc/window.txt | 2 +- sys/unix/Install.unx | 6 +- sys/unix/Makefile.check | 2 +- sys/unix/Makefile.dat | 2 +- sys/unix/Makefile.doc | 2 +- sys/unix/Makefile.src | 4 +- sys/unix/Makefile.top | 2 +- sys/unix/Makefile.utl | 10 +- sys/unix/NewInstall.unx | 4 +- sys/unix/depend.awk | 4 +- sys/unix/gitinfo.sh | 2 +- sys/unix/hints/include/compiler.500 | 2 +- sys/unix/hints/include/cross-post.500 | 2 +- sys/unix/hints/include/cross-pre1.500 | 2 +- sys/unix/hints/include/cross-pre2.500 | 4 +- sys/unix/hints/include/gbdates-post.500 | 2 +- sys/unix/hints/include/gbdates-pre.500 | 2 +- sys/unix/hints/include/misc.500 | 4 +- sys/unix/hints/include/multisnd-post.500 | 2 +- sys/unix/hints/include/multisnd1-pre.500 | 2 +- sys/unix/hints/include/multisnd2-pre.500 | 2 +- sys/unix/hints/include/multiw-1.500 | 2 +- sys/unix/hints/include/multiw-2.500 | 2 +- sys/unix/hints/include/response.500 | 2 +- sys/unix/hints/linux-minimal | 2 +- sys/unix/hints/macOS.500 | 6 +- sys/unix/hints/macosx.sh | 2 +- sys/unix/hints/solaris | 2 +- sys/unix/hints/solaris-playground | 2 +- sys/unix/hints/unix | 2 +- sys/unix/mkmkfile.sh | 2 +- sys/unix/nethack.sh | 2 +- sys/unix/setup.sh | 2 +- sys/unix/sysconf | 4 +- sys/unix/unixmain.c | 2 +- sys/unix/unixres.c | 2 +- sys/unix/unixunix.c | 2 +- 42 files changed, 173 insertions(+), 173 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 885dafdd5..3a2e0ff5f 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -13,7 +13,7 @@ Original version - Eric S. Raymond - (Edited and expanded for NetHack 3.7.0 by Mike Stephenson and others) + (Edited and expanded for NetHack 5.0.0 by Mike Stephenson and others) April 16, 2026 @@ -126,7 +126,7 @@ employ to great advantage. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -192,7 +192,7 @@ NetHack continues this fine tradition. Unlike text adventure games - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -258,7 +258,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -324,7 +324,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -390,7 +390,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -456,7 +456,7 @@ The number of turns elapsed so far, displayed if you have the - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -522,7 +522,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -588,7 +588,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -654,7 +654,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -720,7 +720,7 @@ instead. Only these one-step movement commands cause you to - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -786,7 +786,7 @@ ing . ^ is used as shorthand elsewhere in the - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -852,7 +852,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -918,7 +918,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -984,7 +984,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -1050,7 +1050,7 @@ at an adjacent "remembered, unseen monster" marker. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -1116,7 +1116,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -1182,7 +1182,7 @@ (R)UNIX is a registered trademark of The Open Group. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -1248,7 +1248,7 @@ menu_next_page, and menu_last_page keys (`^', `<', `>', `|' by - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -1314,7 +1314,7 @@ doesn't and give that name to the result, while splitting (count - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -1380,7 +1380,7 @@ Default key is `M-C'. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -1446,7 +1446,7 @@ List any monster types which have been genocided. In explore - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -1512,7 +1512,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -1578,7 +1578,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -1644,7 +1644,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -1710,7 +1710,7 @@ is `C-_'. See also #travel. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -1776,7 +1776,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -1842,7 +1842,7 @@ Swap wielded and secondary weapons. Default key is `x'. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -1908,7 +1908,7 @@ parenthesis, the name of the option to toggle. The option must - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -1974,7 +1974,7 @@ menu. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -2040,7 +2040,7 @@ within a modest radius. No time elapses. Autocompletes. Debug - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -2106,7 +2106,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -2172,7 +2172,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -2238,7 +2238,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -2304,7 +2304,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -2370,7 +2370,7 @@ them). Some monsters who can open doors can also use unlocking tools. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -2436,7 +2436,7 @@ been nullified, giving access to whatever is beyond them. In the - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -2502,7 +2502,7 @@ play. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -2568,7 +2568,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -2634,7 +2634,7 @@ attack, when guessing where an unseen monster is or when deliberately - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -2700,7 +2700,7 @@ noid_confirmation:attack option to require a response of "yes" - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -2766,7 +2766,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -2832,7 +2832,7 @@ are encumbered, one of the conditions Burdened, Stressed, Strained, - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -2898,7 +2898,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -2964,7 +2964,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -3030,7 +3030,7 @@ aklys, lucern hammer, and bec-de-corbin) are defined in an appendix to - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -3096,7 +3096,7 @@ shots by using a numeric prefix before the `t' or `f' command. For - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -3162,7 +3162,7 @@ first you need to have a weapon in each hand. (Note that your two - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -3228,7 +3228,7 @@ even further. Most of these provide a one or two point improvement to - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -3294,7 +3294,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -3360,7 +3360,7 @@ yourself (just give a `.' or `s' for the direction). Be warned, how- - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -3426,7 +3426,7 @@ your ken can be harmful to your health! - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -3492,7 +3492,7 @@ play the entire game without being able to see (a self-imposed chal- - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -3558,7 +3558,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -3624,7 +3624,7 @@ set the goldX option if you prefer to have gold pieces be treated as - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -3690,7 +3690,7 @@ eating such items still counts against foodless conduct. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -3756,7 +3756,7 @@ monster (i.e. if you would get experience for the death). This is a - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -3822,7 +3822,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -3888,7 +3888,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -3954,7 +3954,7 @@ ning NetHack for the first time, you should find a default template - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -4020,7 +4020,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -4086,7 +4086,7 @@ begins; whatever follows will be common to all sections. Otherwise - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -4152,7 +4152,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -4218,7 +4218,7 @@ sign) to let NetHack know that the rest is intended as a file name. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -4284,7 +4284,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -4350,7 +4350,7 @@ weapon or both. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -4416,7 +4416,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -4482,7 +4482,7 @@ extended command, it controls whether the menu shows all available - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -4548,7 +4548,7 @@ might miss some interesting and/or important information. Persis- - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -4614,7 +4614,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -4680,7 +4680,7 @@ class(es). Combination starts with a prompt for object class(es) of - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -4746,7 +4746,7 @@ 5 - One-or-other - show symbols on headers, or on entries if no - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -4812,7 +4812,7 @@ port is the same as specifying 0. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -4878,7 +4878,7 @@ ing 1 and negating number_pad is the same as specifying 0. (Set- - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -4944,7 +4944,7 @@ `y', set Confirm too); - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -5010,7 +5010,7 @@ ing pets on the map. Effectively a superset of the hilite_pet bool- - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -5076,7 +5076,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -5142,7 +5142,7 @@ game). This option exists partly as an acknowledgement that some - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -5208,7 +5208,7 @@ sistent. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -5274,7 +5274,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -5340,7 +5340,7 @@ on). - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -5406,7 +5406,7 @@ when a windowing version of NetHack is started without a parent win- - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -5472,7 +5472,7 @@ on a doorway, it will consider the area on the side of the door you - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -5538,7 +5538,7 @@ right) - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -5604,7 +5604,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -5670,7 +5670,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -5736,7 +5736,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -5802,7 +5802,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -5868,7 +5868,7 @@ strokes that the operating system returns to NetHack to help compen- - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -5934,7 +5934,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -6000,7 +6000,7 @@ The menu control or accelerator keys can also be rebound via OPTIONS - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -6066,7 +6066,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -6132,7 +6132,7 @@ ing for more info, and exit the location asking loop. Default is - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -6198,7 +6198,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -6264,7 +6264,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -6330,7 +6330,7 @@ cause the hitpoints field to display in the color red if your hit- - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -6396,7 +6396,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -6462,7 +6462,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -6528,7 +6528,7 @@ value, and the ^ prefix causes the following character to be treated - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -6594,7 +6594,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -6660,7 +6660,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -6726,7 +6726,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -6792,7 +6792,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -6858,7 +6858,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -6924,7 +6924,7 @@ seen via the "#attributes" command. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -6990,7 +6990,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -7056,7 +7056,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -7122,7 +7122,7 @@ connection between "wizard mode" and the Wizard role). Attempting to - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -7188,7 +7188,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -7254,7 +7254,7 @@ were distinct for specific types of monsters and objects rather than - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -7320,7 +7320,7 @@ file layout which prevented score entries from being read back in cor- - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -7386,7 +7386,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -7452,7 +7452,7 @@ Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir maintained the - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -7518,7 +7518,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -7584,7 +7584,7 @@ sends a particularly intriguing modification to help out with the - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -7650,7 +7650,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -7716,7 +7716,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 @@ -7782,7 +7782,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 April 16, 2026 diff --git a/doc/nethack.txt b/doc/nethack.txt index ca120c3e0..fe59517f2 100644 --- a/doc/nethack.txt +++ b/doc/nethack.txt @@ -279,7 +279,7 @@ BUGS COPYRIGHT This file is Copyright (C) Robert Patrick Rankin, 2024 for version - NetHack-3.7:1.31. NetHack may be freely redistributed. See license + NetHack-5.0:1.31. NetHack may be freely redistributed. See license for details. Dungeons & Dragons is a Trademark of Wizards of the Coast, Inc. diff --git a/doc/options.txt b/doc/options.txt index 71a4dd6bc..54c654161 100644 --- a/doc/options.txt +++ b/doc/options.txt @@ -1,5 +1,5 @@ The definition for each OPTIONS= option resides in include/optlist.h as of -February 2020 in 3.7 WIP. +February 2020 in the WIP branch. Boolean and compound options are combined into a single allopt[] array. diff --git a/doc/recover.txt b/doc/recover.txt index e13d2995f..fcefe12db 100644 --- a/doc/recover.txt +++ b/doc/recover.txt @@ -74,7 +74,7 @@ BUGS COPYRIGHT This file is Copyright (C) Kenneth Lorber, 2024 for version - NetHack-3.7:1.12. NetHack may be freely redistributed. See license + NetHack-5.0:1.12. NetHack may be freely redistributed. See license for details. diff --git a/doc/tmac.nh b/doc/tmac.nh index f8c30c2d0..a109c66af 100644 --- a/doc/tmac.nh +++ b/doc/tmac.nh @@ -1,4 +1,4 @@ -.\" NetHack 3.7 tmac.nh $NHDT-Date: $ $NHDT-Branch: $:$NHDT-Revision: $ +.\" NetHack 5.0 tmac.nh $NHDT-Date: $ $NHDT-Branch: $:$NHDT-Revision: $ . .\" Miscellaneous tmac.n-style macros specifically for nethack's Guidebook. .\" diff --git a/doc/window.txt b/doc/window.txt index de0613ce4..ae69d4f00 100644 --- a/doc/window.txt +++ b/doc/window.txt @@ -227,7 +227,7 @@ print_glyph(window, x, y, glyphinfo, bkglyphinfo) int ttychar; /* the character mapping for the original tty * interface. Most or all window ports wanted * and used this for various things so it is - * provided in 3.7+ */ + * provided in 5.0+ */ short int symidx; /* offset into syms array */ unsigned glyphflags; /* more detail about the entity */ diff --git a/sys/unix/Install.unx b/sys/unix/Install.unx index 60596cbed..b257ff164 100644 --- a/sys/unix/Install.unx +++ b/sys/unix/Install.unx @@ -1,4 +1,4 @@ - Instructions for installing NetHack 3.7 + Instructions for installing NetHack 5.0 on a UNIX system ======================================= NB: We are gradually replacing this process with the process documented in @@ -109,7 +109,7 @@ the file NewInstall.unx. Notes: 1. Save files and bones files from previous versions will not work with - NetHack 3.7. Don't bother trying to keep them. + NetHack 5.0. Don't bother trying to keep them. 2. To install an update of this version of NetHack after changing something, type 'make update' from the main directory. If you created the new @@ -251,6 +251,6 @@ Notes: to CFLAGS in src/Makefile. (The hints files for Mac OSX already do the latter.) -# NetHack 3.7 Install.unx $NHDT-Date: 1577568915 2019/12/28 21:35:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ +# NetHack 5.0 Install.unx $NHDT-Date: 1577568915 2019/12/28 21:35:15 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ # Copyright (c) 2012 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/sys/unix/Makefile.check b/sys/unix/Makefile.check index a2f32c78e..f22458ee7 100755 --- a/sys/unix/Makefile.check +++ b/sys/unix/Makefile.check @@ -1,4 +1,4 @@ -# NetHack 3.7 Makefile.check $NHDT-Date: 1599687610 2020/09/09 21:40:10 $ $NHDT-Branch: NetHack-3.7 +# NetHack 5.0 Makefile.check $NHDT-Date: 1599687610 2020/09/09 21:40:10 $ $NHDT-Branch: NetHack-5.0 SUPATH := sys/unix/ MKHINTSPATH := $(SUPATH)hints/ diff --git a/sys/unix/Makefile.dat b/sys/unix/Makefile.dat index 43c61537d..85d40ef53 100644 --- a/sys/unix/Makefile.dat +++ b/sys/unix/Makefile.dat @@ -1,4 +1,4 @@ -# NetHack Datafiles Makefile.dat $NHDT-Date: 1596486993 2020/08/03 20:36:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ +# NetHack Datafiles Makefile.dat $NHDT-Date: 1596486993 2020/08/03 20:36:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.32 $ # Copyright (c) 2018 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. diff --git a/sys/unix/Makefile.doc b/sys/unix/Makefile.doc index 56d6818c3..f2f42502a 100644 --- a/sys/unix/Makefile.doc +++ b/sys/unix/Makefile.doc @@ -1,5 +1,5 @@ # NetHack Documentation Makefile. -# NetHack 3.7 Makefile.doc $NHDT-Date: 1700788000 2023/11/24 01:06:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.28 $ +# NetHack 5.0 Makefile.doc $NHDT-Date: 1700788000 2023/11/24 01:06:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.28 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 29338e374..863fa096c 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -1,5 +1,5 @@ # NetHack Makefile. -# NetHack 3.7 Makefile.src $NHDT-Date: 1697316523 2023/10/14 20:48:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.164 $ +# NetHack 5.0 Makefile.src $NHDT-Date: 1697316523 2023/10/14 20:48:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.164 $ # Copyright (c) 2018 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. @@ -68,7 +68,7 @@ SYSOBJ = $(TARGETPFX)ioctl.o $(TARGETPFX)unixmain.o $(TARGETPFX)unixtty.o \ #SYSOBJ = $(TARGETPFX)bemain.o $(TARGETPFX)unixtty.o $(TARGETPFX)ioctl.o -# NetHack 3.7 began introducing C99 code. +# NetHack 5.0 began introducing C99 code. # # If your compiler needs an appropriate switch to accept C99 code. # CSTD = -std=c99 diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index c108f3552..5ecca3232 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -1,5 +1,5 @@ # NetHack Top-level Makefile. -# NetHack 3.7 Makefile.top $NHDT-Date: 1722119081 2024/07/27 22:24:41 $ $NHDT-Branch: keni-fetchlua $:$NHDT-Revision: 1.109 $ +# NetHack 5.0 Makefile.top $NHDT-Date: 1722119081 2024/07/27 22:24:41 $ $NHDT-Branch: keni-fetchlua $:$NHDT-Revision: 1.109 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/sys/unix/Makefile.utl b/sys/unix/Makefile.utl index 862a319da..ff064a5d7 100644 --- a/sys/unix/Makefile.utl +++ b/sys/unix/Makefile.utl @@ -1,10 +1,10 @@ # Makefile for NetHack's utility programs. -# NetHack 3.7 Makefile.utl $NHDT-Date: 1693334279 2023/08/29 18:37:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.68 $ +# NetHack 5.0 Makefile.utl $NHDT-Date: 1693334279 2023/08/29 18:37:59 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.68 $ # Copyright (c) 2018 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. # -# Note: as of nethack 3.7, 'lev_comp' and 'dgn_comp' are no longer present +# Note: as of NetHack 5.0, 'lev_comp' and 'dgn_comp' are no longer present # so use of yacc and lex to build them is no longer required. # @@ -23,7 +23,7 @@ NHSROOT=.. # execute things like 'foo.o') # MAKE = make -# NetHack 3.7 began introducing C99 code. +# NetHack 5.0 began introducing C99 code. # # If your compiler needs an appropriate switch to accept C99 code. # CSTD = -std=c99 @@ -612,10 +612,10 @@ tags: $(UTILSRCS) @ctags -tw $(UTILSRCS) # note: 3.6 copied tile.h from win/share/ to include/ and if someone -# switches branches from 3.6 to 3.7 without executing 'make spotless' +# switches branches from 3.6 to 5.0 without executing 'make spotless' # first, the old tile.h sticks around and gets found during compile # instead of current one; various tile utilities won't build in that -# mis-configuration so allow 'make clean' and 'make spotless' in 3.7 +# mis-configuration so allow 'make clean' and 'make spotless' in 5.0 # to fix things up by deleting the out of date file (if present) clean-fixup: -rm -f ../include/tile.h diff --git a/sys/unix/NewInstall.unx b/sys/unix/NewInstall.unx index 831b1b870..fe1ebaf83 100644 --- a/sys/unix/NewInstall.unx +++ b/sys/unix/NewInstall.unx @@ -1,5 +1,5 @@ - Instructions for installing NetHack 3.7 + Instructions for installing NetHack 5.0 using the new hints system ======================================= @@ -155,6 +155,6 @@ additional interfaces. See below. | | | | qt6-multimedia-dev | +----------+-------+-----------------+--------------------------------------+ -# NetHack 3.7 NewInstall.unx $NHDT-Date: 1652276817 2022/05/11 13:46:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ +# NetHack 5.0 NewInstall.unx $NHDT-Date: 1652276817 2022/05/11 13:46:57 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ # Copyright (c) 2009 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/sys/unix/depend.awk b/sys/unix/depend.awk index afe86a0ad..edb8fb4e7 100644 --- a/sys/unix/depend.awk +++ b/sys/unix/depend.awk @@ -1,6 +1,6 @@ # depend.awk -- awk script used to construct makefile dependencies # for nethack's source files (`make depend' support for Makefile.src). -# $NHDT-Date: 1709577497 2024/03/04 18:38:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ +# $NHDT-Date: 1709577497 2024/03/04 18:38:17 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.18 $ # # usage: # awk -f depend.awk ../include/*.h list-of-.c/.cpp-files @@ -54,7 +54,7 @@ FNR == 1 { output_dep() #finish previous file #[3.4.0: gnomehack headers currently aren't in include] #[3.6.2: Qt4 headers aren't in include either] #[3.6.2: curses headers likewise] - #[3.7.0: Qt headers have moved; process 'moc' files] + #[NetHack 5.0.0: Qt headers have moved; process 'moc' files] if (incl ~ /[.]h$/) { if (incl ~ "curses[.]h") incl = "" # skip "curses.h"; it should be diff --git a/sys/unix/gitinfo.sh b/sys/unix/gitinfo.sh index d087272a2..817a7f310 100755 --- a/sys/unix/gitinfo.sh +++ b/sys/unix/gitinfo.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.7 gitinfo.sh $NHDT-Date: 1596498289 2020/08/03 23:44:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +# NetHack 5.0 gitinfo.sh $NHDT-Date: 1596498289 2020/08/03 23:44:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ # Copyright (c) 2018 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. diff --git a/sys/unix/hints/include/compiler.500 b/sys/unix/hints/include/compiler.500 index fde7ca00f..d04b06381 100755 --- a/sys/unix/hints/include/compiler.500 +++ b/sys/unix/hints/include/compiler.500 @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 compiler.500 $NHDT-Date: 1668359835 2022/11/13 17:17:15 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 compiler.500 $NHDT-Date: 1668359835 2022/11/13 17:17:15 $ $NHDT-Branch: NetHack-5.0 $ # compiler flags: CCFLAGS is used to construct a value for CFLAGS with # various -I, -D, and -W settings appended below; diff --git a/sys/unix/hints/include/cross-post.500 b/sys/unix/hints/include/cross-post.500 index f28ec0fe1..28b73c8be 100644 --- a/sys/unix/hints/include/cross-post.500 +++ b/sys/unix/hints/include/cross-post.500 @@ -1,5 +1,5 @@ #===============-================================================= -# NetHack 3.7 include/cross-post $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 include/cross-post $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-5.0 $ # # Cross-compiling -POST section diff --git a/sys/unix/hints/include/cross-pre1.500 b/sys/unix/hints/include/cross-pre1.500 index 867886d9b..b252f0843 100644 --- a/sys/unix/hints/include/cross-pre1.500 +++ b/sys/unix/hints/include/cross-pre1.500 @@ -1,5 +1,5 @@ #===============-================================================= -# NetHack 3.7 include/cross-pre1. $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 include/cross-pre1. $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-5.0 $ # # Cross-compiling -PRE section 1 # diff --git a/sys/unix/hints/include/cross-pre2.500 b/sys/unix/hints/include/cross-pre2.500 index 8c6dbe64d..ddc3ba765 100644 --- a/sys/unix/hints/include/cross-pre2.500 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -1,5 +1,5 @@ #===============-================================================= -# NetHack 3.7 include/cross-pre2 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 include/cross-pre2 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-5.0 $ # # Cross-compiling -PRE section 2 # @@ -499,7 +499,7 @@ override TARGET_CFLAGS = -c -O2 -noixemul $(TOOLARCH) \ $(LUAINCL) -DAMIGA -DNOTTYGRAPHICS -DNO_TERMS -DNO_SIGNAL \ -DTILES_IN_GLYPHMAP $(PDCURSESDEF) \ -DCROSSCOMPILE -DCROSSCOMPILE_TARGET -DCROSS_TO_AMIGA \ - -DAMIGA_VERSION_STRING=\""VER: NetHack 3.7.0"\" + -DAMIGA_VERSION_STRING=\""VER: NetHack 5.0.0"\" override TARGET_CXXFLAGS = $(TARGET_CFLAGS) LUA_TARGET_CFLAGS = $(TARGET_CFLAGS) ifeq "$(REGEXOBJ)" "$(TARGETPFX)cppregex.o" diff --git a/sys/unix/hints/include/gbdates-post.500 b/sys/unix/hints/include/gbdates-post.500 index 94451d337..f16070c64 100755 --- a/sys/unix/hints/include/gbdates-post.500 +++ b/sys/unix/hints/include/gbdates-post.500 @@ -1,4 +1,4 @@ -# NetHack 3.7 gbdates-post.500 $NHDT-Date: 1599687610 2020/09/09 21:40:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ +# NetHack 5.0 gbdates-post.500 $NHDT-Date: 1599687610 2020/09/09 21:40:10 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ ifdef MAKEFILE_DOC ifdef GB_DATESTAMP Guidebook.dated.mn: $(GUIDEBOOK_MN_SRC) diff --git a/sys/unix/hints/include/gbdates-pre.500 b/sys/unix/hints/include/gbdates-pre.500 index 8ba189cdb..2c62af079 100755 --- a/sys/unix/hints/include/gbdates-pre.500 +++ b/sys/unix/hints/include/gbdates-pre.500 @@ -1,4 +1,4 @@ -# NetHack 3.7 gbdates-pre.500 $NHDT-Date: 1599687610 2020/09/09 21:40:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ +# NetHack 5.0 gbdates-pre.500 $NHDT-Date: 1599687610 2020/09/09 21:40:10 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ ifdef MAKEFILE_DOC ifneq "$(GIT)" "0" diff --git a/sys/unix/hints/include/misc.500 b/sys/unix/hints/include/misc.500 index 63d983715..ae7c282a0 100644 --- a/sys/unix/hints/include/misc.500 +++ b/sys/unix/hints/include/misc.500 @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 misc.500 $NHDT-Date: 1668359836 2022/11/13 17:17:16 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 misc.500 $NHDT-Date: 1668359836 2022/11/13 17:17:16 $ $NHDT-Branch: NetHack-5.0 $ # # Further set-up for miscellaneous odds and ends (after compiler.500) # @@ -21,7 +21,7 @@ ifdef WANT_WIN_QT6 # Qt 6 builds and runs (with a couple of warnings) but needs more testing QTn_H = Qt6.h-t else -# Qt 5 is currently the default version for nethack 3.7.x's Qt interface +# Qt 5 is currently the default version for nethack NetHack 5.0.x's Qt interface QTn_H = Qt5.h-t endif $(QTn_H) :: diff --git a/sys/unix/hints/include/multisnd-post.500 b/sys/unix/hints/include/multisnd-post.500 index e6e764c2e..c524db078 100644 --- a/sys/unix/hints/include/multisnd-post.500 +++ b/sys/unix/hints/include/multisnd-post.500 @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 multisnd-post.500 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 multisnd-post.500 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-5.0 $ ifeq "$(HAVE_SNDLIB)" "1" # note: one possible value for $(SNDLIBSRC) is 'macsound.m' which is written diff --git a/sys/unix/hints/include/multisnd1-pre.500 b/sys/unix/hints/include/multisnd1-pre.500 index 8c89c5977..6c04f01b9 100644 --- a/sys/unix/hints/include/multisnd1-pre.500 +++ b/sys/unix/hints/include/multisnd1-pre.500 @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 multisnd1-pre.500 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 multisnd1-pre.500 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-5.0 $ # # If it's cross-platform it belongs in this file. # If it's macOS-only, it belongs in macOS.500. diff --git a/sys/unix/hints/include/multisnd2-pre.500 b/sys/unix/hints/include/multisnd2-pre.500 index 3fe11fa19..77d993333 100644 --- a/sys/unix/hints/include/multisnd2-pre.500 +++ b/sys/unix/hints/include/multisnd2-pre.500 @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 multisnd2-pre.500 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 multisnd2-pre.500 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-5.0 $ # ifdef NEEDS_WAV diff --git a/sys/unix/hints/include/multiw-1.500 b/sys/unix/hints/include/multiw-1.500 index 521e71883..df89d95a5 100644 --- a/sys/unix/hints/include/multiw-1.500 +++ b/sys/unix/hints/include/multiw-1.500 @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 multiw-1.500 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 multiw-1.500 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-5.0 $ # 1. Which windowing interface(s) should be included in this binary? # One or more of these can be manually uncommented and/or can be specified diff --git a/sys/unix/hints/include/multiw-2.500 b/sys/unix/hints/include/multiw-2.500 index 8cf1d2f2d..832c3b7ab 100644 --- a/sys/unix/hints/include/multiw-2.500 +++ b/sys/unix/hints/include/multiw-2.500 @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 multiw-2.500 $NHDT-Date: 1599337709 2020/09/05 20:28:29 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 multiw-2.500 $NHDT-Date: 1599337709 2020/09/05 20:28:29 $ $NHDT-Branch: NetHack-5.0 $ # # Sorts out support for multiple window ports (interfaces) to included in the build. # diff --git a/sys/unix/hints/include/response.500 b/sys/unix/hints/include/response.500 index 0e842fba3..0781323e0 100644 --- a/sys/unix/hints/include/response.500 +++ b/sys/unix/hints/include/response.500 @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 response.500 $NHDT-Date: 1668359835 2022/11/13 17:17:15 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 response.500 $NHDT-Date: 1668359835 2022/11/13 17:17:15 $ $NHDT-Branch: NetHack-5.0 $ ifeq "$(RESP)" "1" USE_RESPONSEFILE=1 diff --git a/sys/unix/hints/linux-minimal b/sys/unix/hints/linux-minimal index 003d69fe1..0d4b569b1 100644 --- a/sys/unix/hints/linux-minimal +++ b/sys/unix/hints/linux-minimal @@ -1,5 +1,5 @@ # -# NetHack 3.7 linux $NHDT-Date: 1596498416 2020/08/03 23:46:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +# NetHack 5.0 linux $NHDT-Date: 1596498416 2020/08/03 23:46:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ # Copyright (c) Patric Mueller # NetHack may be freely redistributed. See license for details. # diff --git a/sys/unix/hints/macOS.500 b/sys/unix/hints/macOS.500 index e6f9db253..77d78b9bf 100755 --- a/sys/unix/hints/macOS.500 +++ b/sys/unix/hints/macOS.500 @@ -649,7 +649,7 @@ $(BUNDLE_INFOPLIST): @echo 'CFBundlePackageType' >>$@ @echo 'APPL' >>$@ @echo 'CFBundleGetInfoString' >>$@ - @echo '$(BUNDLE_GAMENAME) 3.7 for MacOS' >>$@ + @echo '$(BUNDLE_GAMENAME) 5.0 for MacOS' >>$@ @echo 'CFBundleIdentifier' >>$@ @echo 'org.nethack.macos' >>$@ @echo 'CFBundleExecutable' >>$@ @@ -661,9 +661,9 @@ $(BUNDLE_INFOPLIST): @echo 'CFBundleName' >>$@ @echo '$(BUNDLE_NAME)' >>$@ @echo 'CFBundleVersion' >>$@ - @echo '3.7.0b73' >>$@ + @echo 'NetHack 5.0.0b73' >>$@ @echo 'CFBundleShortVersionString' >>$@ - @echo '3.7.0' >>$@ + @echo 'NetHack 5.0.0' >>$@ @echo 'NSHumanReadableCopyright' >>$@ @echo '©By Stichting Mathematisch Centrum and M. Stephenson 1985-2026' >>$@ @echo 'LSApplicationCategoryType' >>$@ diff --git a/sys/unix/hints/macosx.sh b/sys/unix/hints/macosx.sh index 544eefbd1..4c306e85e 100755 --- a/sys/unix/hints/macosx.sh +++ b/sys/unix/hints/macosx.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.7 macosx.sh $NHDT-Date: 1597332920 2020/08/13 15:35:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ +# NetHack 5.0 macosx.sh $NHDT-Date: 1597332920 2020/08/13 15:35:20 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.24 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/sys/unix/hints/solaris b/sys/unix/hints/solaris index 1f3e22e64..6c80e5e3d 100644 --- a/sys/unix/hints/solaris +++ b/sys/unix/hints/solaris @@ -1,5 +1,5 @@ # -# NetHack 3.7 unix $NHDT-Date: 1596498426 2020/08/03 23:47:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ +# NetHack 5.0 unix $NHDT-Date: 1596498426 2020/08/03 23:47:06 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.0 $ # Copyright (c) Kevin Smolkowski "Snivik", Elgin Oregon 2019. # NetHack may be freely redistributed. See license for details. # diff --git a/sys/unix/hints/solaris-playground b/sys/unix/hints/solaris-playground index 1c75b0766..080639f50 100644 --- a/sys/unix/hints/solaris-playground +++ b/sys/unix/hints/solaris-playground @@ -1,5 +1,5 @@ # -# NetHack 3.7 unix $NHDT-Date: 1596498427 2020/08/03 23:47:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ +# NetHack 5.0 unix $NHDT-Date: 1596498427 2020/08/03 23:47:07 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.0 $ # Copyright (c) Kevin Smolkowski "Snivik", Elgin Oregon 2019. # NetHack may be freely redistributed. See license for details. # diff --git a/sys/unix/hints/unix b/sys/unix/hints/unix index 7b937c45f..e6d9da942 100644 --- a/sys/unix/hints/unix +++ b/sys/unix/hints/unix @@ -1,5 +1,5 @@ # -# NetHack 3.7 unix $NHDT-Date: 1596498428 2020/08/03 23:47:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ +# NetHack 5.0 unix $NHDT-Date: 1596498428 2020/08/03 23:47:08 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/sys/unix/mkmkfile.sh b/sys/unix/mkmkfile.sh index 12894305b..01cdb9b72 100755 --- a/sys/unix/mkmkfile.sh +++ b/sys/unix/mkmkfile.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.7 mkmkfile.sh $NHDT-Date: 1597332770 2020/08/13 15:32:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ +# NetHack 5.0 mkmkfile.sh $NHDT-Date: 1597332770 2020/08/13 15:32:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.15 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. diff --git a/sys/unix/nethack.sh b/sys/unix/nethack.sh index 9ce743494..6e49a1da0 100755 --- a/sys/unix/nethack.sh +++ b/sys/unix/nethack.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.7 nethack.sh $NHDT-Date: 1596498294 2020/08/03 23:44:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ +# NetHack 5.0 nethack.sh $NHDT-Date: 1596498294 2020/08/03 23:44:54 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.21 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/sys/unix/setup.sh b/sys/unix/setup.sh index 69595fd00..7f5b504e1 100755 --- a/sys/unix/setup.sh +++ b/sys/unix/setup.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.7 setup.sh $NHDT-Date: 1596498296 2020/08/03 23:44:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.17 $ +# NetHack 5.0 setup.sh $NHDT-Date: 1596498296 2020/08/03 23:44:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.17 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/sys/unix/sysconf b/sys/unix/sysconf index 34926903b..0e0cd3914 100644 --- a/sys/unix/sysconf +++ b/sys/unix/sysconf @@ -1,4 +1,4 @@ -# NetHack 3.7 sysconf $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.44 $ +# NetHack 5.0 sysconf $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.44 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. # @@ -130,7 +130,7 @@ MAXPLAYERS=10 # Only available if NetHack was compiled with DUMPLOG # Allows following placeholders: # %% literal '%' -# %v version (eg. "3.7.0-0") +# %v version (eg. "NetHack 5.0.0-0") # %u game UID # %t game start time, UNIX timestamp format # %T current time, UNIX timestamp format diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index c90385e5f..6cf99918e 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 unixmain.c $NHDT-Date: 1711213891 2024/03/23 17:11:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.127 $ */ +/* NetHack 5.0 unixmain.c $NHDT-Date: 1711213891 2024/03/23 17:11:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.127 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/unix/unixres.c b/sys/unix/unixres.c index 64006ddf2..e5a376fae 100644 --- a/sys/unix/unixres.c +++ b/sys/unix/unixres.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 unixres.c $NHDT-Date: 1596498298 2020/08/03 23:44:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 unixres.c $NHDT-Date: 1596498298 2020/08/03 23:44:58 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Slash'EM development team, 2001. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/unix/unixunix.c b/sys/unix/unixunix.c index 9bb5d42a8..d614f3278 100644 --- a/sys/unix/unixunix.c +++ b/sys/unix/unixunix.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 unixunix.c $NHDT-Date: 1711213894 2024/03/23 17:11:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.43 $ */ +/* NetHack 5.0 unixunix.c $NHDT-Date: 1711213894 2024/03/23 17:11:34 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.43 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ From d7a6b3085e378abf2be014b75a24c1635ecddbce Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 10:47:48 -0400 Subject: [PATCH 033/702] sys files --- sys/amiga/README.amiga | 6 +++--- sys/amiga/nethack.cnf | 2 +- sys/libnh/README.md | 8 ++++---- sys/libnh/sysconf | 4 ++-- sys/msdos/Install.dos | 6 +++--- sys/msdos/Makefile.GCC | 8 ++++---- sys/msdos/msdos.c | 2 +- sys/msdos/msdoshlp.txt | 2 +- sys/msdos/pckeys.c | 2 +- sys/msdos/pctiles.c | 2 +- sys/msdos/pctiles.h | 2 +- sys/msdos/pcvideo.h | 2 +- sys/msdos/portio.h | 2 +- sys/msdos/setup.bat | 2 +- sys/msdos/sysconf | 4 ++-- sys/msdos/tile2bin.c | 2 +- sys/msdos/vesa.h | 2 +- sys/msdos/video.c | 4 ++-- sys/msdos/vidtxt.c | 2 +- sys/msdos/vidvga.c | 2 +- sys/share/.gitattributes | 10 +++++----- sys/share/Makefile.lib | 2 +- sys/share/cppregex.cpp | 4 ++-- sys/share/ioctl.c | 2 +- sys/share/pcsys.c | 2 +- sys/share/pctty.c | 2 +- sys/share/pcunix.c | 2 +- sys/share/pmatchregex.c | 2 +- sys/share/posixregex.c | 2 +- sys/share/tclib.c | 2 +- sys/share/unixtty.c | 2 +- sys/share/uudecode.c | 2 +- sys/vms/Install.vms | 8 ++++---- sys/vms/Install370.vms | 10 +++++----- sys/vms/Makefile.dat | 2 +- sys/vms/Makefile.doc | 2 +- sys/vms/Makefile.src | 2 +- sys/vms/Makefile.top | 2 +- sys/vms/Makefile.utl | 2 +- sys/vms/Makefile_dat.vms | 2 +- sys/vms/Makefile_doc.vms | 2 +- sys/vms/Makefile_src.vms | 2 +- sys/vms/Makefile_top.vms | 4 ++-- sys/vms/Makefile_utl.vms | 4 ++-- sys/vms/oldcrtl.c | 2 +- sys/vms/sysconf | 4 ++-- sys/vms/vmsbuild.com | 14 +++++++------- sys/vms/vmsfiles.c | 2 +- sys/vms/vmsmail.c | 2 +- sys/vms/vmsmisc.c | 2 +- sys/vms/vmssetup.com | 4 ++-- sys/vms/vmstty.c | 2 +- sys/vms/vmsunix.c | 2 +- sys/windows/Install.windows | 2 +- sys/windows/Makefile.nmake | 20 ++++++++++---------- sys/windows/build-msys2.txt | 6 +++--- sys/windows/build-nmake.txt | 6 +++--- sys/windows/build-vs.txt | 4 ++-- sys/windows/console.rc | 8 ++++---- sys/windows/consoletty.c | 2 +- sys/windows/nethack.def | 2 +- sys/windows/nethackrc.template | 2 +- sys/windows/nhsetup.bat | 2 +- sys/windows/porthelp | 2 +- sys/windows/sysconf.template | 18 +++++++++--------- sys/windows/vs/FetchPrereq/fetchprereq.nmake | 4 ++-- sys/windows/vs/NetHackPackage.appxmanifest | 4 ++-- sys/windows/vs/Package.StoreAssociation.xml | 2 +- sys/windows/vs/fetchctags/fetchctags.nmake | 4 ++-- sys/windows/vs/package/package.nmake | 4 ++-- sys/windows/win10.c | 2 +- sys/windows/win10.h | 2 +- sys/windows/win32api.h | 2 +- sys/windows/windsys.c | 2 +- sys/windows/winos.h | 2 +- 75 files changed, 139 insertions(+), 139 deletions(-) diff --git a/sys/amiga/README.amiga b/sys/amiga/README.amiga index 6aa2a2a95..89362d8a9 100644 --- a/sys/amiga/README.amiga +++ b/sys/amiga/README.amiga @@ -1,4 +1,4 @@ - NetHack 3.7 for Amiga + NetHack 5.0 for Amiga ==================== Requirements @@ -71,7 +71,7 @@ Cross-compilation from Linux using bebbo's m68k-amigaos-gcc toolchain (https://franke.ms/git/bebbo/amiga-gcc): # Install toolchain to /opt/amiga - # Clone NetHack 3.7 source + # Clone NetHack 5.0 source cd NetHack sys/unix/setup.sh sys/unix/hints/linux.370 make fetch-lua @@ -103,5 +103,5 @@ Ken Lorber, and Gregg Wonderly are responsible for the 3.2 port. Janne Salmijärvi resurrected the Amiga port for 3.3 and Teemu Suikki joined before 3.4.0. -Updated for NetHack 3.7, cross compile fixes and 32 color tile support by Ingo +Updated for NetHack 5.0, cross compile fixes and 32 color tile support by Ingo Paschke in 2026. diff --git a/sys/amiga/nethack.cnf b/sys/amiga/nethack.cnf index dad37d4d5..84dd3d60b 100644 --- a/sys/amiga/nethack.cnf +++ b/sys/amiga/nethack.cnf @@ -1,4 +1,4 @@ -# NetHack 3.7 Amiga Configuration +# NetHack 5.0 Amiga Configuration # # For a full list of options, see the opthelp file or press '?' # then 'o' during gameplay. diff --git a/sys/libnh/README.md b/sys/libnh/README.md index b887b5730..6d4c3cb4d 100644 --- a/sys/libnh/README.md +++ b/sys/libnh/README.md @@ -39,10 +39,10 @@ WASM also has a npm module that can be published out of `sys/lib/npm-library`. A The API is two functions: * `nhmain(int argc, char *argv[])` - The main function for NetHack that configures the program and runs the `moveloop()` until the game is over. The arguments to this function are the [command line arguments](https://nethackwiki.com/wiki/Options) to NetHack. * `shim_graphics_set_callback(shim_callback_t cb)` - A single function that sets a callback to gather graphics events: write a string to screen, get user input, etc. Your job is to pass in a callback and handle all the requested rendering events to show NetHack on the screen. The callback is `void shim_callback_t(const char *name, void *ret_ptr, const char *fmt, ...)` - * `name` is the name of the [window function](https://github.com/NetHack/NetHack/blob/NetHack-3.7/doc/window.txt) that needs to be handled + * `name` is the name of the [window function](https://github.com/NetHack/NetHack/blob/NetHack-5.0/doc/window.txt) that needs to be handled * `ret_ptr` is a pointer to a memory space for the return value. The type expected to be returned in this pointer is described by the first character of the `fmt` string. * `fmt` is a string that describes the signature of the callback. The first character in the string is the return type and any additional characters describe the variable arguments: `i` for integer, `s` for string, `p` for pointer, `c` for character, `v` for void. For example, if format is "vis" the callback will have no return (void), the first argument will be an integer, and the second argument will be a string. If format is "iii" the callback must return an integer, and both the arguments passed in will be integers. - * [Variadic arguments](https://www.gnu.org/software/libc/manual/html_node/Variadic-Example.html): a variable number and type of arguments depending on the `window function` that is being called. The arguments associated with each `name` are described in the [NetHack window.txt](https://github.com/NetHack/NetHack/blob/NetHack-3.7/doc/window.txt). + * [Variadic arguments](https://www.gnu.org/software/libc/manual/html_node/Variadic-Example.html): a variable number and type of arguments depending on the `window function` that is being called. The arguments associated with each `name` are described in the [NetHack window.txt](https://github.com/NetHack/NetHack/blob/NetHack-5.0/doc/window.txt). Where is the header file for the API you ask? There isn't one. It's three functions, just drop the forward declarations at the top of your file (or create your own header). It's more work figuring out how to install and copy around header files than it's worth for such a small API. If you disagree, feel free to submit a PR to fix it. :) @@ -50,8 +50,8 @@ Where is the header file for the API you ask? There isn't one. It's three functi The WebAssembly API has a similar signature to `libnethack.a` with minor syntactic differences: * `main(int argc, char argv[])` - The main function for NetHack * `shim_graphics_set_callback(char *cbName)` - A `String` representing a name of a callback function. The callback function be registered as `globalThis[cbName] = function yourCallback(name, ... args) { /* your stuff */ }`. Note that [globalThis](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis) points to `window` in browsers and `global` in node.js. - * `name` is the name of the [window function](https://github.com/NetHack/NetHack/blob/NetHack-3.7/doc/window.txt) that needs to be handled - * `... args` is a variable number and type of arguments depending on the `window function` that is being called. The arguments associated with each `name` are described in the [NetHack window.txt](https://github.com/NetHack/NetHack/blob/NetHack-3.7/doc/window.txt) + * `name` is the name of the [window function](https://github.com/NetHack/NetHack/blob/NetHack-5.0/doc/window.txt) that needs to be handled + * `... args` is a variable number and type of arguments depending on the `window function` that is being called. The arguments associated with each `name` are described in the [NetHack window.txt](https://github.com/NetHack/NetHack/blob/NetHack-5.0/doc/window.txt) * The function must return the value expected for the specified `name` diff --git a/sys/libnh/sysconf b/sys/libnh/sysconf index 52148449d..af871c187 100644 --- a/sys/libnh/sysconf +++ b/sys/libnh/sysconf @@ -1,4 +1,4 @@ -# NetHack 3.7 sysconf $NHDT-Date: 1596498296 2020/08/03 23:44:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.39 $ +# NetHack 5.0 sysconf $NHDT-Date: 1596498296 2020/08/03 23:44:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.39 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. # @@ -102,7 +102,7 @@ HIDEUSAGE=1 # Only available if NetHack was compiled with DUMPLOG # Allows following placeholders: # %% literal '%' -# %v version (eg. "3.7.0-0") +# %v version (eg. "5.0.0-0") # %u game UID # %t game start time, UNIX timestamp format # %T current time, UNIX timestamp format diff --git a/sys/msdos/Install.dos b/sys/msdos/Install.dos index e60eb72b3..2b2be2096 100644 --- a/sys/msdos/Install.dos +++ b/sys/msdos/Install.dos @@ -3,12 +3,12 @@ NetHack may be freely redistributed. See license for details. ============================================================== Instructions for compiling and installing - NetHack 3.7 on a DOS system + NetHack 5.0 on a DOS system ====================================================== - (or, How to make PC NetHack 3.7) + (or, How to make PC NetHack 5.0) Last revision: $NHDT-Date: 1596508786 2021/06/04 08:45:00 $ -Credit for a runnable full PC NetHack 3.7 goes to the PC Development team +Credit for a runnable full PC NetHack 5.0 goes to the PC Development team of Paul Winner, Kevin Smolkowski, Michael Allison, Yitzhak Sapir, Bill Dyer, Timo Hakulinen, Yamamoto Keizo, Mike Threepoint, Mike Stephenson, Stephen White, Ken Washikita and Janet Walz. The present port is based diff --git a/sys/msdos/Makefile.GCC b/sys/msdos/Makefile.GCC index 782e1cd5c..d7220fc10 100644 --- a/sys/msdos/Makefile.GCC +++ b/sys/msdos/Makefile.GCC @@ -1,9 +1,9 @@ -# NetHack 3.7 Makefile.GCC $NHDT-Date: 1596498268 2020/08/03 23:44:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.53 $ +# NetHack 5.0 Makefile.GCC $NHDT-Date: 1596498268 2020/08/03 23:44:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.53 $ # Copyright (c) NetHack PC Development Team 1996-2024. -# PC NetHack 3.7 Makefile for djgpp V2 +# PC NetHack 5.0 Makefile for djgpp V2 # # Gnu gcc compiler for msdos (djgpp) -# Requires Gnu Make utility (V3.79.1 or greater) supplied with djgpp +# Requires Gnu Make utility (V5.09.1 or greater) supplied with djgpp # # For questions or comments: devteam@nethack.org # @@ -61,7 +61,7 @@ endif # This build assumes that the LUA sources are located # at the specified location. If they are actually elsewhere # you'll need to specify the correct spot below in order to -# successfully build NetHack-3.7. +# successfully build NetHack-5.0. # ADD_LUA=Y LUATOP=../lib/lua$(LUAVER) diff --git a/sys/msdos/msdos.c b/sys/msdos/msdos.c index e73880242..e2787b020 100644 --- a/sys/msdos/msdos.c +++ b/sys/msdos/msdos.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 msdos.c $NHDT-Date: 1596498269 2020/08/03 23:44:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 msdos.c $NHDT-Date: 1596498269 2020/08/03 23:44:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.15 $ */ /* Copyright (c) NetHack PC Development Team 1990 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/msdos/msdoshlp.txt b/sys/msdos/msdoshlp.txt index a56018236..b255f6f45 100644 --- a/sys/msdos/msdoshlp.txt +++ b/sys/msdos/msdoshlp.txt @@ -1,4 +1,4 @@ - MSDOS specific help file for NetHack 3.7 + MSDOS specific help file for NetHack 5.0 (Last Revision: December 4, 1999) Copyright (c) NetHack PC Development Team 1993-1999. diff --git a/sys/msdos/pckeys.c b/sys/msdos/pckeys.c index 068d9d116..51eb0cf0c 100644 --- a/sys/msdos/pckeys.c +++ b/sys/msdos/pckeys.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 pckeys.c $NHDT-Date: 1596498270 2020/08/03 23:44:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 pckeys.c $NHDT-Date: 1596498270 2020/08/03 23:44:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) NetHack PC Development Team 1996 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/msdos/pctiles.c b/sys/msdos/pctiles.c index b675b7d7d..9103c6d61 100644 --- a/sys/msdos/pctiles.c +++ b/sys/msdos/pctiles.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 pctiles.c $NHDT-Date: 1596498271 2020/08/03 23:44:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 pctiles.c $NHDT-Date: 1596498271 2020/08/03 23:44:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994 */ /* NetHack may be freely redistributed. See license for details. */ /* */ diff --git a/sys/msdos/pctiles.h b/sys/msdos/pctiles.h index 69c5ff875..44707c686 100644 --- a/sys/msdos/pctiles.h +++ b/sys/msdos/pctiles.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 pctiles.h $NHDT-Date: 1596498272 2020/08/03 23:44:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 pctiles.h $NHDT-Date: 1596498272 2020/08/03 23:44:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994 */ /* NetHack may be freely redistributed. See license for details. */ /* */ diff --git a/sys/msdos/pcvideo.h b/sys/msdos/pcvideo.h index 22a95041a..a9cce2bbb 100644 --- a/sys/msdos/pcvideo.h +++ b/sys/msdos/pcvideo.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 pcvideo.h $NHDT-Date: 1596498273 2020/08/03 23:44:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 pcvideo.h $NHDT-Date: 1596498273 2020/08/03 23:44:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994 */ /* NetHack may be freely redistributed. See license for details. */ /* */ diff --git a/sys/msdos/portio.h b/sys/msdos/portio.h index 0b31d8b00..0e6f53515 100644 --- a/sys/msdos/portio.h +++ b/sys/msdos/portio.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 portio.h $NHDT-Date: 1596498273 2020/08/03 23:44:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 portio.h $NHDT-Date: 1596498273 2020/08/03 23:44:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) NetHack PC Development Team 1995 */ /* NetHack may be freely redistributed. See license for details. */ /* */ diff --git a/sys/msdos/setup.bat b/sys/msdos/setup.bat index 988de68db..f2f983ba6 100755 --- a/sys/msdos/setup.bat +++ b/sys/msdos/setup.bat @@ -1,5 +1,5 @@ @echo off -REM NetHack 3.7 setup.bat $NHDT-Date: 1596498274 2020/08/03 23:44:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ +REM NetHack 5.0 setup.bat $NHDT-Date: 1596498274 2020/08/03 23:44:34 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.18 $ REM Copyright (c) NetHack PC Development Team 1990 - 2019 REM NetHack may be freely redistributed. See license for details. diff --git a/sys/msdos/sysconf b/sys/msdos/sysconf index b3ef5bdca..779e437bd 100644 --- a/sys/msdos/sysconf +++ b/sys/msdos/sysconf @@ -1,5 +1,5 @@ # -# NetHack 3.7 sysconf $NHDT-Date: 1524689357 2018/04/25 20:49:17 $ $NHDT-Branch: NetHack-3.7.0 $:$NHDT-Revision: 1.22 $ +# NetHack 5.0 sysconf $NHDT-Date: 1524689357 2018/04/25 20:49:17 $ $NHDT-Branch: NetHack-5.0.0 $:$NHDT-Revision: 1.22 $ # Copyright (c) 2015 by Michael Allison # NetHack may be freely redistributed. See license for details. # @@ -24,7 +24,7 @@ WIZARDS=* # Only available if NetHack was compiled with DUMPLOG # Allows following placeholders: # %% literal '%' -# %v version (eg. "3.7.0-0") +# %v version (eg. "5.0.0-0") # %u game UID # %t game start time, UNIX timestamp format # %T current time, UNIX timestamp format diff --git a/sys/msdos/tile2bin.c b/sys/msdos/tile2bin.c index 28e0be4c0..cc43bb3dc 100644 --- a/sys/msdos/tile2bin.c +++ b/sys/msdos/tile2bin.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 tile2bin.c $NHDT-Date: 1596498275 2020/08/03 23:44:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 tile2bin.c $NHDT-Date: 1596498275 2020/08/03 23:44:35 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994, 1995 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/msdos/vesa.h b/sys/msdos/vesa.h index 54d5dc12a..9549a2bd1 100644 --- a/sys/msdos/vesa.h +++ b/sys/msdos/vesa.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 vesa.h $NHDT-Date: 1596498276 2020/08/03 23:44:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 vesa.h $NHDT-Date: 1596498276 2020/08/03 23:44:36 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.0 $ */ /* VESA structures from the VESA BIOS Specification, retrieved 15 Jan 2016 * from http://flint.cs.yale.edu/cs422/readings/hardware/vbe3.pdf diff --git a/sys/msdos/video.c b/sys/msdos/video.c index 5d7f4fb30..7d2a91ef5 100644 --- a/sys/msdos/video.c +++ b/sys/msdos/video.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 video.c $NHDT-Date: 1596498277 2020/08/03 23:44:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.16 $ */ +/* NetHack 5.0 video.c $NHDT-Date: 1596498277 2020/08/03 23:44:37 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.16 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994, 2001 */ /* NetHack may be freely redistributed. See license for details. */ @@ -419,7 +419,7 @@ term_start_color(int color) if (monoflag) { g_attribute = attrib_text_normal; } else { - if (color == NO_COLOR) { /* 3.7 behave like term_end_color() */ + if (color == NO_COLOR) { /* 5.0 behave like term_end_color() */ g_attribute = iflags.grmode ? attrib_gr_normal : attrib_text_normal; curframecolor = NO_COLOR; } else if (color >= 0 && color < CLR_MAX) { diff --git a/sys/msdos/vidtxt.c b/sys/msdos/vidtxt.c index 37402cc5d..f60b1c715 100644 --- a/sys/msdos/vidtxt.c +++ b/sys/msdos/vidtxt.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 vidtxt.c $NHDT-Date: 1596498278 2020/08/03 23:44:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 vidtxt.c $NHDT-Date: 1596498278 2020/08/03 23:44:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) NetHack PC Development Team 1993 */ /* NetHack may be freely redistributed. See license for details. */ /* */ diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index fed1be22f..6b1a81239 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 vidvga.c $NHDT-Date: 1606765216 2020/11/30 19:40:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ */ +/* NetHack 5.0 vidvga.c $NHDT-Date: 1606765216 2020/11/30 19:40:16 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.26 $ */ /* Copyright (c) NetHack PC Development Team 1995 */ /* NetHack may be freely redistributed. See license for details. */ /* diff --git a/sys/share/.gitattributes b/sys/share/.gitattributes index 0ab91a6e9..2073bdcba 100644 --- a/sys/share/.gitattributes +++ b/sys/share/.gitattributes @@ -3,16 +3,16 @@ NetHack.cnf NHSUBST termcap NH_header=no Makefile.lib NH_header=no -Makefile.lib NH_filestag=(file%s_for_OS/2_version_-_untested_for_3.7) -#termcap.uu NH_filestag=(file%s_for_MSDOS_and_OS/2_versions_-_untested_for_3.7) +Makefile.lib NH_filestag=(file%s_for_OS/2_version_-_untested_for_5.0) +#termcap.uu NH_filestag=(file%s_for_MSDOS_and_OS/2_versions_-_untested_for_5.0) termcap.uu NH_filestag=>Makefile.lib -pcmain.c NH_filestag=(file_for_MSDOS,_OS/2,_Amiga,_and_Atari_versions_-_only_MSDOS_tested_for_3.7) +pcmain.c NH_filestag=(file_for_MSDOS,_OS/2,_Amiga,_and_Atari_versions_-_only_MSDOS_tested_for_5.0) -pcsys.c NH_filestag=(file%s_for_MSDOS,_OS/2_and_Atari_versions_-_only_MSDOS_tested_for_3.7) +pcsys.c NH_filestag=(file%s_for_MSDOS,_OS/2_and_Atari_versions_-_only_MSDOS_tested_for_5.0) pcunix.c NH_filestag=>pcsys.c -NetHack.cnf NH_filestag=(file_for_MSDOS,_OS/2,_and_Atari_versions_-_only_MSDOS_tested_for_3.7) +NetHack.cnf NH_filestag=(file_for_MSDOS,_OS/2,_and_Atari_versions_-_only_MSDOS_tested_for_5.0) pctty.c NH_filestag=>NetHack.cnf ioctl.c NH_filestag=(file%s_for_UNIX_and_Be_versions) diff --git a/sys/share/Makefile.lib b/sys/share/Makefile.lib index 8118a1af7..9f2318c3c 100644 --- a/sys/share/Makefile.lib +++ b/sys/share/Makefile.lib @@ -1,4 +1,4 @@ -# NetHack 3.7 Makefile.lib $NHDT-Date: 1596498281 2020/08/03 23:44:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ +# NetHack 5.0 Makefile.lib $NHDT-Date: 1596498281 2020/08/03 23:44:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.8 $ # Nethack makefile for Fred fish termlib -- Norman Meluch # CC = cl /c diff --git a/sys/share/cppregex.cpp b/sys/share/cppregex.cpp index 9835a1f5c..073eb8917 100644 --- a/sys/share/cppregex.cpp +++ b/sys/share/cppregex.cpp @@ -1,5 +1,5 @@ -/* NetHack 3.7 cppregex.cpp */ -/* $NHDT-Date: 1596498279 2020/08/03 23:44:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 cppregex.cpp */ +/* $NHDT-Date: 1596498279 2020/08/03 23:44:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) Sean Hunt 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/ioctl.c b/sys/share/ioctl.c index 4d92acd15..ec76ec740 100644 --- a/sys/share/ioctl.c +++ b/sys/share/ioctl.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 ioctl.c $NHDT-Date: 1596498280 2020/08/03 23:44:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 ioctl.c $NHDT-Date: 1596498280 2020/08/03 23:44:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.15 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/pcsys.c b/sys/share/pcsys.c index c48d79068..5ceaa4410 100644 --- a/sys/share/pcsys.c +++ b/sys/share/pcsys.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 pcsys.c $NHDT-Date: 1596498283 2020/08/03 23:44:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.42 $ */ +/* NetHack 5.0 pcsys.c $NHDT-Date: 1596498283 2020/08/03 23:44:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.42 $ */ /* Copyright (c) 2012 by Michael Allison */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/pctty.c b/sys/share/pctty.c index 7a8192ca7..f06dfe475 100644 --- a/sys/share/pctty.c +++ b/sys/share/pctty.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 pctty.c $NHDT-Date: 1596498284 2020/08/03 23:44:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 pctty.c $NHDT-Date: 1596498284 2020/08/03 23:44:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2005. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/pcunix.c b/sys/share/pcunix.c index 48c0da670..6ecd7dae9 100644 --- a/sys/share/pcunix.c +++ b/sys/share/pcunix.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 pcunix.c $NHDT-Date: 1596498285 2020/08/03 23:44:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.42 $ */ +/* NetHack 5.0 pcunix.c $NHDT-Date: 1596498285 2020/08/03 23:44:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.42 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/pmatchregex.c b/sys/share/pmatchregex.c index cf98672a8..a4bf0c119 100644 --- a/sys/share/pmatchregex.c +++ b/sys/share/pmatchregex.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 pmatchregex.c $NHDT-Date: 1737691300 2025/01/23 20:01:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 pmatchregex.c $NHDT-Date: 1737691300 2025/01/23 20:01:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) Sean Hunt 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/posixregex.c b/sys/share/posixregex.c index e5bc92e98..676e7dbe7 100644 --- a/sys/share/posixregex.c +++ b/sys/share/posixregex.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 posixregex.c $NHDT-Date: 1596498286 2020/08/03 23:44:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ */ +/* NetHack 5.0 posixregex.c $NHDT-Date: 1596498286 2020/08/03 23:44:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.7 $ */ /* Copyright (c) Sean Hunt 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/tclib.c b/sys/share/tclib.c index 80bfee0f3..51046a2b2 100644 --- a/sys/share/tclib.c +++ b/sys/share/tclib.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 tclib.c $NHDT-Date: 1596498287 2020/08/03 23:44:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 tclib.c $NHDT-Date: 1596498287 2020/08/03 23:44:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) Robert Patrick Rankin, 1995 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/unixtty.c b/sys/share/unixtty.c index 7fdf8e6d3..aa62a477d 100644 --- a/sys/share/unixtty.c +++ b/sys/share/unixtty.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 unixtty.c $NHDT-Date: 1596498288 2020/08/03 23:44:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.27 $ */ +/* NetHack 5.0 unixtty.c $NHDT-Date: 1596498288 2020/08/03 23:44:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.27 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/uudecode.c b/sys/share/uudecode.c index 9d3a4802b..a59856925 100644 --- a/sys/share/uudecode.c +++ b/sys/share/uudecode.c @@ -46,7 +46,7 @@ * Modified 09 Apr 2026 to change mode variable from (int) to (unsigned int) * to match prototype of sscanf %o. * - * $NHDT-Date: 1775744389 2026/04/09 14:19:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ + * $NHDT-Date: 1775744389 2026/04/09 14:19:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.21 $ */ #ifndef lint diff --git a/sys/vms/Install.vms b/sys/vms/Install.vms index 5b0b7e184..6f73e6739 100644 --- a/sys/vms/Install.vms +++ b/sys/vms/Install.vms @@ -1,11 +1,11 @@ - Instructions for Building and Installing NetHack 3.7.0 + Instructions for Building and Installing NetHack 5.0.0 on a VMS (aka OpenVMS) system ========================================= 0. Please read this entire file before trying to build or install NetHack, then read it again! -1. NetHack 3.7 was built and tested on OpenVMS on both the Integrity +1. NetHack 5.0 was built and tested on OpenVMS on both the Integrity and Alpha platform using the HP C V7.3 for OpenVMS compiler. While not tested, older versions of DEC C will most likely work as compatibility with older systems is a goal of the VMS porting team. Unfortunately, @@ -145,7 +145,7 @@ Notes: 0. Version 3.5.x was never publicly released. 1. Save files and bones files from 3.6.x and earlier versions will not - work with 3.7.0. The scoreboard file (RECORD) from 3.6.x or 3.4.x or + work with 5.0.0. The scoreboard file (RECORD) from 3.6.x or 3.4.x or 3.3.x will work. 2. Ancient C libs will not work; vsnprintf is required. @@ -510,6 +510,6 @@ minimally updated 9-NOV-2015... and again 5-MAY-2019... and yet again 26-JAN-2020... -# NetHack 3.7 Install.vms $NHDT-Date: 1575245132 2019/12/02 00:05:32 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.16 $ +# NetHack 5.0 Install.vms $NHDT-Date: 1575245132 2019/12/02 00:05:32 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.16 $ # Copyright (c) 2003 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. diff --git a/sys/vms/Install370.vms b/sys/vms/Install370.vms index edca9e9d0..b6c406e68 100644 --- a/sys/vms/Install370.vms +++ b/sys/vms/Install370.vms @@ -1,8 +1,8 @@ - Instructions for Building and Installing NetHack 3.7.0 + Instructions for Building and Installing NetHack 5.0.0 on a VSI openVMS 9.2 system ========================================= -This contains a description of how to build NetHack-3.7.0 on VSI OpenVMS 9.2. +This contains a description of how to build NetHack-5.0.0 on VSI OpenVMS 9.2. This process uses Gnu Make 4.1 (minimum) for VMS to carry out the build. Last tested with VSI C x86-64 V7.5-009 (GEM 50XBR) on OpenVMS x86_64 V9.2-2. @@ -26,7 +26,7 @@ Last tested with VSI C x86-64 V7.5-009 (GEM 50XBR) on OpenVMS x86_64 V9.2-2. [.win.tty] -- "window" routines for ordinary terminals (including terminal windows on workstations) -2. From the top of the NetHack 3.7 distribution, issue the following +2. From the top of the NetHack 5.0 distribution, issue the following pair of commands to distribute the GNU make Makefile.vms files to their working locations for building NetHack: $ set def [.sys.vms] @@ -76,7 +76,7 @@ Last tested with VSI C x86-64 V7.5-009 (GEM 50XBR) on OpenVMS x86_64 V9.2-2. Notes: 1. Save files and bones files from 3.6.x and earlier versions will not - work with 3.7.0. The scoreboard file (RECORD) from 3.6.x or 3.4.x or + work with 5.0.0. The scoreboard file (RECORD) from 3.6.x or 3.4.x or 3.3.x should work. 2. To specify user-preference options in your environment, define the @@ -360,5 +360,5 @@ Notes: make utility used. 8-March-2024 -# NetHack 3.7 Install370.vms $NHDT-Date: 1575245132 2019/12/02 00:05:32 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.16 $ +# NetHack 5.0 Install370.vms $NHDT-Date: 1575245132 2019/12/02 00:05:32 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.16 $ # NetHack may be freely redistributed. See license for details. diff --git a/sys/vms/Makefile.dat b/sys/vms/Makefile.dat index efe363297..e1787896b 100644 --- a/sys/vms/Makefile.dat +++ b/sys/vms/Makefile.dat @@ -1,5 +1,5 @@ # NetHack Makefile (VMS) - data files: special levels and other data. -# NetHack 3.7 Makefile.dat $NHDT-Date: 1596498300 2020/08/03 23:45:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ +# NetHack 5.0 Makefile.dat $NHDT-Date: 1596498300 2020/08/03 23:45:00 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ # Copyright (c) 2015 by Mike Stephenson # NetHack may be freely redistributed. See license for details. diff --git a/sys/vms/Makefile.doc b/sys/vms/Makefile.doc index d728620d4..cb54314de 100644 --- a/sys/vms/Makefile.doc +++ b/sys/vms/Makefile.doc @@ -1,5 +1,5 @@ # NetHack Makefile (VMS) - for the [Unix] documentation. -# NetHack 3.7 Makefile.doc $NHDT-Date: 1596498301 2020/08/03 23:45:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ +# NetHack 5.0 Makefile.doc $NHDT-Date: 1596498301 2020/08/03 23:45:01 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ # Copyright (c) 2011 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. diff --git a/sys/vms/Makefile.src b/sys/vms/Makefile.src index 31b87d521..4cdef1436 100644 --- a/sys/vms/Makefile.src +++ b/sys/vms/Makefile.src @@ -1,5 +1,5 @@ # NetHack Makefile (VMS) - for building nethack itself. -# NetHack 3.7 Makefile.src $NHDT-Date: 1683748060 2023/05/10 19:47:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.60 $ +# NetHack 5.0 Makefile.src $NHDT-Date: 1683748060 2023/05/10 19:47:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.60 $ # Copyright (c) 2011 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. diff --git a/sys/vms/Makefile.top b/sys/vms/Makefile.top index c12946959..d02dd4016 100644 --- a/sys/vms/Makefile.top +++ b/sys/vms/Makefile.top @@ -1,5 +1,5 @@ # NetHack Makefile (VMS) - top level for making & installing everything. -# NetHack 3.7 Makefile.top $NHDT-Date: 1596498303 2020/08/03 23:45:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ +# NetHack 5.0 Makefile.top $NHDT-Date: 1596498303 2020/08/03 23:45:03 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ # Copyright (c) 2011 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. diff --git a/sys/vms/Makefile.utl b/sys/vms/Makefile.utl index 22224c245..a9105ef11 100644 --- a/sys/vms/Makefile.utl +++ b/sys/vms/Makefile.utl @@ -1,5 +1,5 @@ # NetHack Makefile (VMS) - for utility programs. -# NetHack 3.7 Makefile.utl $NHDT-Date: 1609347482 2020/12/30 16:58:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.20 $ +# NetHack 5.0 Makefile.utl $NHDT-Date: 1609347482 2020/12/30 16:58:02 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.20 $ # Copyright (c) 2011 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. diff --git a/sys/vms/Makefile_dat.vms b/sys/vms/Makefile_dat.vms index 09979bb63..23c59d41f 100644 --- a/sys/vms/Makefile_dat.vms +++ b/sys/vms/Makefile_dat.vms @@ -1,4 +1,4 @@ -# NetHack Datafiles Makefile.dat $NHDT-Date: 1596486993 2020/08/03 20:36:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ +# NetHack Datafiles Makefile.dat $NHDT-Date: 1596486993 2020/08/03 20:36:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.32 $ # Copyright (c) 2018 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. diff --git a/sys/vms/Makefile_doc.vms b/sys/vms/Makefile_doc.vms index 64184d092..762df59d8 100644 --- a/sys/vms/Makefile_doc.vms +++ b/sys/vms/Makefile_doc.vms @@ -1,5 +1,5 @@ # NetHack Documentation Makefile. -# NetHack 3.7 Makefile.doc $NHDT-Date: 1596498290 2020/08/03 23:44:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ +# NetHack 5.0 Makefile.doc $NHDT-Date: 1596498290 2020/08/03 23:44:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.21 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/sys/vms/Makefile_src.vms b/sys/vms/Makefile_src.vms index 74f22ea55..160ddb95d 100644 --- a/sys/vms/Makefile_src.vms +++ b/sys/vms/Makefile_src.vms @@ -1,4 +1,4 @@ -# NetHack 3.7 Makefile.src $NHDT-Date: 1654287121 2022/06/03 20:12:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.145 $ +# NetHack 5.0 Makefile.src $NHDT-Date: 1654287121 2022/06/03 20:12:01 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.145 $ # Copyright (c) 2024 by Michael Allison # NetHack may be freely redistributed. See license for details. # diff --git a/sys/vms/Makefile_top.vms b/sys/vms/Makefile_top.vms index 47028c80d..274f2207e 100644 --- a/sys/vms/Makefile_top.vms +++ b/sys/vms/Makefile_top.vms @@ -1,5 +1,5 @@ # NetHack Top-level Makefile. -# NetHack 3.7 Makefile.vms $NHDT-Date: 1642630921 2022/01/19 22:22:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.72 $ +# NetHack 5.0 Makefile.vms $NHDT-Date: 1642630921 2022/01/19 22:22:01 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.72 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. @@ -21,7 +21,7 @@ NHSROOT=[] # MAKE = make -# NetHack 3.7 Makefile.vms $NHDT-Date: 1654287121 2022/06/03 20:12:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.145 $ +# NetHack 5.0 Makefile.vms $NHDT-Date: 1654287121 2022/06/03 20:12:01 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.145 $ # Copyright (c) 2023 by Michael Allison # NetHack may be freely redistributed. See license for details. # diff --git a/sys/vms/Makefile_utl.vms b/sys/vms/Makefile_utl.vms index c17283d13..6d62d51e4 100644 --- a/sys/vms/Makefile_utl.vms +++ b/sys/vms/Makefile_utl.vms @@ -1,12 +1,12 @@ # Makefile for NetHack's utility programs. -# NetHack 3.7 util Makefile.vms $NHDT-Date: 1602258295 2020/10/09 15:44:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.53 $ +# NetHack 5.0 util Makefile.vms $NHDT-Date: 1602258295 2020/10/09 15:44:55 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.53 $ # Copyright (c) 2018 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. # Root of source tree relative to here: NHSROOT=[-] -# NetHack 3.7 began introducing C99 code. +# NetHack 5.0 began introducing C99 code. # # If your compiler needs an appropriate switch to accept C99 code. # CSTD = -std=c99 diff --git a/sys/vms/oldcrtl.c b/sys/vms/oldcrtl.c index f60da1b63..1ffb6d210 100644 --- a/sys/vms/oldcrtl.c +++ b/sys/vms/oldcrtl.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 oldcrtl.c $NHDT-Date: 1596498304 2020/08/03 23:45:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 oldcrtl.c $NHDT-Date: 1596498304 2020/08/03 23:45:04 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.9 $ */ /* Pat Rankin May'90 */ /* VMS NetHack support, not needed for vms 4.6,4.7,5.x,or later */ diff --git a/sys/vms/sysconf b/sys/vms/sysconf index 8fb357e3c..8fe0fb3eb 100644 --- a/sys/vms/sysconf +++ b/sys/vms/sysconf @@ -1,4 +1,4 @@ -# NetHack 3.7 sysconf $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.7 $ +# NetHack 5.0 sysconf $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.7 $ # Copyright (c) 2015 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. # @@ -110,7 +110,7 @@ HIDEUSAGE=1 # Only available if NetHack was compiled with DUMPLOG # Allows following placeholders: # %% literal '%' -# %v version (eg. "3.7.0-0") +# %v version (eg. "5.0.0-0") # %u game UID # %t game start time, UNIX timestamp format # %T current time, UNIX timestamp format diff --git a/sys/vms/vmsbuild.com b/sys/vms/vmsbuild.com index 6146cd5f1..971573bd1 100755 --- a/sys/vms/vmsbuild.com +++ b/sys/vms/vmsbuild.com @@ -1,6 +1,6 @@ -$ ! vms/vmsbuild.com -- compile and link NetHack 3.7.* [pr] -$ version_number = "3.7.0" -$ ! $NHDT-Date: 1687541093 2023/06/23 17:24:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.39 $ +$ ! vms/vmsbuild.com -- compile and link NetHack 5.0.* [pr] +$ version_number = "5.0.0" +$ ! $NHDT-Date: 1687541093 2023/06/23 17:24:53 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.39 $ $ ! Copyright (c) 2018 by Robert Patrick Rankin $ ! NetHack may be freely redistributed. See license for details. $ ! @@ -10,7 +10,7 @@ $ ! $ @[-.sys.vms]vmsbuild [compiler-option] [link-option] [cc-switches] - $ ! [linker-switches] [interface] $ ! options: $ ! compiler-option : either "VSIC", "VAXC", "DECC", -$ ! "GNUC" or "" or "fetchlua" !default in 3.7 is VSIC +$ ! "GNUC" or "" or "fetchlua" !default in 5.0 is VSIC $ ! link-option : either "SHARE[able]" or "LIB[rary]" !default SHARE $ ! cc-switches : optional qualifiers for CC (such as "/noOpt/Debug") $ ! linker-switches : optional qualifiers for LINK (/Debug or /noTraceback) @@ -291,7 +291,7 @@ $ if f$search("[-.include]nhlua.h").nes."" then - $ milestone " (wiped existing [-.include]nhlua.h)" $ exit $! -$! 3.7 runtime LUA level parser/loader +$! 5.0 runtime LUA level parser/loader $! $buildlua: $ if f$search("[-.lib]lua.dir;").eqs."" then - @@ -406,7 +406,7 @@ $ gosub compile_list $ link makedefs.obj,[-.src]panic.obj,'nethacklib'/Lib,[-.src]ident.opt/Opt,[-.src]crtl/Opt $ milestone "makedefs" $! create some build-time files -$! 3.7 does not require these +$! 5.0 does not require these $! makedefs -p !pm.h $! makedefs -o !onames.h $! makedefs -v !date.h @@ -431,7 +431,7 @@ $ c_list = "hack,hacklib,iactions,insight,invent,light,lock,mail,makemon" - + ",music" $ gosub compile_list $! -$! Files added in 3.7 for Lua glue +$! Files added in 5.0 for Lua glue $! $ c_list = "nhlua,nhlobj,nhlsel" $ gosub compile_list diff --git a/sys/vms/vmsfiles.c b/sys/vms/vmsfiles.c index 82a12c934..cc05e1030 100644 --- a/sys/vms/vmsfiles.c +++ b/sys/vms/vmsfiles.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 vmsfiles.c $NHDT-Date: 1685522046 2023/05/31 08:34:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.19 $ */ +/* NetHack 5.0 vmsfiles.c $NHDT-Date: 1685522046 2023/05/31 08:34:06 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.19 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2007. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/vms/vmsmail.c b/sys/vms/vmsmail.c index afe279cb4..87685fd7e 100644 --- a/sys/vms/vmsmail.c +++ b/sys/vms/vmsmail.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 vmsmail.c $NHDT-Date: 1685522048 2023/05/31 08:34:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ */ +/* NetHack 5.0 vmsmail.c $NHDT-Date: 1685522048 2023/05/31 08:34:08 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.18 $ */ /* Copyright (c) Robert Patrick Rankin, 1991. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/vms/vmsmisc.c b/sys/vms/vmsmisc.c index d84c5c20c..83210662a 100644 --- a/sys/vms/vmsmisc.c +++ b/sys/vms/vmsmisc.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 vmsmisc.c $NHDT-Date: 1685522049 2023/05/31 08:34:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ */ +/* NetHack 5.0 vmsmisc.c $NHDT-Date: 1685522049 2023/05/31 08:34:09 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.18 $ */ /* Copyright (c) 2011 by Robert Patrick Rankin */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/vms/vmssetup.com b/sys/vms/vmssetup.com index b841bb882..3f3a3764b 100644 --- a/sys/vms/vmssetup.com +++ b/sys/vms/vmssetup.com @@ -1,6 +1,6 @@ $ ! vmssetup.com -- place GNU Makefiles in their target directories -$ version_number = "3.7.0" -$ ! $NHDT-Date: 1687541093 2024/03/08 17:24:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.39 $ +$ version_number = "5.0.0" +$ ! $NHDT-Date: 1687541093 2024/03/08 17:24:53 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.39 $ $ ! NetHack may be freely redistributed. See license for details. $ ! $ relsrc = "" diff --git a/sys/vms/vmstty.c b/sys/vms/vmstty.c index 9d1475391..8d9b5bf74 100644 --- a/sys/vms/vmstty.c +++ b/sys/vms/vmstty.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 vmstty.c $NHDT-Date: 1596498309 2020/08/03 23:45:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ +/* NetHack 5.0 vmstty.c $NHDT-Date: 1596498309 2020/08/03 23:45:09 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.21 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/vms/vmsunix.c b/sys/vms/vmsunix.c index 56455627d..c44819092 100644 --- a/sys/vms/vmsunix.c +++ b/sys/vms/vmsunix.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 vmsunix.c $NHDT-Date: 1685522050 2023/05/31 08:34:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.31 $ */ +/* NetHack 5.0 vmsunix.c $NHDT-Date: 1685522050 2023/05/31 08:34:10 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.31 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/windows/Install.windows b/sys/windows/Install.windows index 3b677e464..207ec5f5d 100644 --- a/sys/windows/Install.windows +++ b/sys/windows/Install.windows @@ -1,7 +1,7 @@ Copyright (c) NetHack Development Team 1990-2024 NetHack may be freely redistributed. See license for details. ============================================================== - Instructions for compiling NetHack 3.7 on a Windows system + Instructions for compiling NetHack 5.0 on a Windows system (only tested on Windows 10/11 or later) ============================================================== Last revision: $NHDT-Date: 1594155895 2020/07/07 21:04:55 $ diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index 1f9726a3b..a345513f1 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -1,10 +1,10 @@ -# NetHack 3.7 Makefile.nmake +# NetHack 5.0 Makefile.nmake # Copyright (c) NetHack Development Team 1993-2026 # #============================================================================== # Build Tools Environment # -# NetHack 3.7 Work-in-progress Makefile for +# NetHack 5.0 Work-in-progress Makefile for # MS Visual Studio Visual C++ compiler # # Visual Studio Compilers Tested: @@ -311,7 +311,7 @@ LUA_MAY_PROCEED=Y !MESSAGE or modify your Makefile to set the following: !MESSAGE INTERNET_AVAILABLE=Y !MESSAGE GIT_AVAILABLE=Y -!ERROR Stopping because NetHack 3.7 requires Lua for its build. +!ERROR Stopping because NetHack 5.0 requires Lua for its build. !ENDIF # LUA_MAY_PROCEED # Now, pdcursesmod @@ -385,7 +385,7 @@ ADD_CURSES = N !ENDIF # WANT_CURSES !IF "$(ADD_CURSES)" != "Y" -!MESSAGE NetHack 3.7 will be built without support for the curses window-port. +!MESSAGE NetHack 5.0 will be built without support for the curses window-port. !ENDIF #These will be in the environment variables with one of the Visual Studio @@ -548,8 +548,8 @@ GITPREFIX = -DNETHACK_GIT_PREFIX=\"$(GIT_PREFIX)\" # This build assumes that the LUA sources are located # at the specified location. If they are actually elsewhere # you'll need to specify the correct spot below in order to -# successfully build NetHack-3.7. You cannot build a functional -# version of NetHack-3.7 Work-in-progress without including Lua. +# successfully build NetHack-5.0. You cannot build a functional +# version of NetHack-5.0 Work-in-progress without including Lua. # !IFNDEF LUAVER @@ -778,7 +778,7 @@ RECOVOBJS = $(OUTL)recover.o TILEFILES = $(WSHR)monsters.txt $(WSHR)objects.txt $(WSHR)other.txt # -# These are not invoked during a normal game build in 3.7 +# These are not invoked during a normal game build in 5.0 # TEXT_IO = $(OUTL)tiletext.o $(OUTL)tiletxt.o $(OUTL)drawing$(HOST).o \ @@ -1886,9 +1886,9 @@ $(OTTY)sfbase.o: sfbase.c $(HACK_H) $(INCL)sfmacros.h $(Q)$(CC) $(CFLAGS) -Fo$@ $(@B).c # -# date.h is not used with NetHack 3.7 -# onames.h is not used with NetHack 3.7 -# pm.h is not used with NetHack 3.7 +# date.h is not used with NetHack 5.0 +# onames.h is not used with NetHack 5.0 +# pm.h is not used with NetHack 5.0 $(INCL)date.h $(OPTIONS_FILE) : $(U)makedefs.exe $(U)makedefs -v diff --git a/sys/windows/build-msys2.txt b/sys/windows/build-msys2.txt index 06938bfaa..ee4d4a11f 100644 --- a/sys/windows/build-msys2.txt +++ b/sys/windows/build-msys2.txt @@ -46,7 +46,7 @@ Required components that are not bundled in the NetHack repository, but are required to build NetHack yourself. Lua - NetHack 3.7 for Windows requires 3rd party Lua source that is not part + NetHack 5.0 for Windows requires 3rd party Lua source that is not part of the NetHack distribution or repository. A bash shell script for fetching prerequisite @@ -55,7 +55,7 @@ Lua sh sys/windows/fetch.sh lua Curses - If you want to include curses interface support in NetHack 3.7 for + If you want to include curses interface support in NetHack 5.0 for 3rd part pdcursesmod source code is required and is not part of the NetHack distribution or repository. @@ -82,7 +82,7 @@ architectures have evolved and you can now choose whether to build a 32-bit x86 version, or a 64-bit x64 version. The default Makefile is set up for a 32-bit x86 version, but that's only because it will run on the largest number of existing Windows environments. Change it if you -want. Be aware that NetHack's save files and bones files in the 3.7.0 +want. Be aware that NetHack's save files and bones files in the 5.0.0 release are not interchangeable between the 32-bit version and the 64-bit version (or between different platforms). diff --git a/sys/windows/build-nmake.txt b/sys/windows/build-nmake.txt index 35c339e7e..b564d20fb 100644 --- a/sys/windows/build-nmake.txt +++ b/sys/windows/build-nmake.txt @@ -7,7 +7,7 @@ Prerequisite Requirements: be installed on your machine. See: https://visualstudio.microsoft.com/vs/community/ o Lua - NetHack 3.7 for Windows requires 3rd party Lua source that is not part + NetHack 5.0 for Windows requires 3rd party Lua source that is not part of the NetHack distribution or repository. A windows cmd command procedure for fetching prerequisite sources @@ -15,7 +15,7 @@ Prerequisite Requirements: NetHack source tree to obtain lua: sys\windows\fetch.cmd lua o pdcursesmod (Only required if curses interface support is desired) - If you want to include curses interface support in NetHack 3.7 for + If you want to include curses interface support in NetHack 5.0 for 3rd part pdcursesmod source code is required and is not part of the NetHack distribution or repository. @@ -75,7 +75,7 @@ architectures have evolved and you can now choose whether to build a 32-bit x86 version, or a 64-bit x64 version. The default Makefile is set up for a 32-bit x86 version, but that's only because it will run on the most number of existing Windows environments. Change it if you -want. Be aware that NetHack's save files and bones files in the 3.7.0 +want. Be aware that NetHack's save files and bones files in the 5.0.0 release have not yet evolved enough to allow them to interchange between the 32-bit version and the 64-bit version (or between different platforms). That may change in future. diff --git a/sys/windows/build-vs.txt b/sys/windows/build-vs.txt index bd939a81b..0b3c7d12a 100644 --- a/sys/windows/build-vs.txt +++ b/sys/windows/build-vs.txt @@ -31,7 +31,7 @@ Prerequisite Requirements: See: https://visualstudio.microsoft.com/vs/community/ o Lua - NetHack 3.7 for Windows requires 3rd party Lua source that is not part + NetHack 5.0 for Windows requires 3rd party Lua source that is not part of the NetHack distribution or repository. A windows cmd command procedure for fetching prerequisite sources @@ -39,7 +39,7 @@ Prerequisite Requirements: NetHack source tree to obtain lua: sys\windows\fetch.cmd lua o pdcursesmod (Only required if curses interface support is desired) - If you want to include curses interface support in NetHack 3.7 for + If you want to include curses interface support in NetHack 5.0 for 3rd part pdcursesmod source code is required and is not part of the NetHack distribution or repository. diff --git a/sys/windows/console.rc b/sys/windows/console.rc index 598c0e2ff..3b87de6c6 100644 --- a/sys/windows/console.rc +++ b/sys/windows/console.rc @@ -1,4 +1,4 @@ -/* NetHack 3.7 console.rc $NHDT-Date: 1596498311 2020/08/03 23:45:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 console.rc $NHDT-Date: 1596498311 2020/08/03 23:45:11 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Yitzhak Sapir, 2002. */ /* NetHack may be freely redistributed. See license for details. */ @@ -29,13 +29,13 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "NetHack for Windows - TTY Interface\0" - VALUE "FileVersion", "3.7.0\0" + VALUE "FileVersion", "5.0.0\0" VALUE "InternalName", "NetHack\0" - VALUE "LegalCopyright", "Copyright (C) 1985 - 2023. By Stichting Mathematisch Centrum and M. Stephenson. See license for details.\0" + VALUE "LegalCopyright", "Copyright (C) 1985 - 2026. By Stichting Mathematisch Centrum and M. Stephenson. See license for details.\0" VALUE "OriginalFilename", "NetHack.exe\0" VALUE "PrivateBuild", "050107\0" VALUE "ProductName", "NetHack\0" - VALUE "ProductVersion", "3.7.0\0" + VALUE "ProductVersion", "5.0.0\0" END END BLOCK "VarFileInfo" diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index cf766ff4a..29b663a86 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 consoletty.c $NHDT-Date: 1596498316 2020/08/03 23:45:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.117 $ */ +/* NetHack 5.0 consoletty.c $NHDT-Date: 1596498316 2020/08/03 23:45:16 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.117 $ */ /* Copyright (c) NetHack PC Development Team 1993 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/windows/nethack.def b/sys/windows/nethack.def index 3bb31c60a..2695cecb9 100644 --- a/sys/windows/nethack.def +++ b/sys/windows/nethack.def @@ -1,5 +1,5 @@ NAME NETHACK -DESCRIPTION 'NetHack 3.7.0 for Windows' +DESCRIPTION 'NetHack 5.0.0 for Windows' EXETYPE WINDOWS STUB 'WINSTUB.EXE' CODE PRELOAD MOVEABLE DISCARDABLE diff --git a/sys/windows/nethackrc.template b/sys/windows/nethackrc.template index 6529b1505..0887fef41 100644 --- a/sys/windows/nethackrc.template +++ b/sys/windows/nethackrc.template @@ -1,4 +1,4 @@ -# NetHack 3.7 defaults.nh $NHDT-Date: 1524689357 2018/04/25 20:49:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.32 $ +# NetHack 5.0 defaults.nh $NHDT-Date: 1524689357 2018/04/25 20:49:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.32 $ # Copyright (c) 2006 by Michael Allison # NetHack may be freely redistributed. See license for details. diff --git a/sys/windows/nhsetup.bat b/sys/windows/nhsetup.bat index ed41d2361..684b81bb6 100755 --- a/sys/windows/nhsetup.bat +++ b/sys/windows/nhsetup.bat @@ -1,4 +1,4 @@ -@REM NetHack 3.7 nhsetup.bat $NHDT-Date: 1596498315 2020/08/03 23:45:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ */ +@REM NetHack 5.0 nhsetup.bat $NHDT-Date: 1596498315 2020/08/03 23:45:15 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.40 $ */ @REM Copyright (c) NetHack Development Team 1993-2024 @REM NetHack may be freely redistributed. See license for details. @REM Win32 setup batch file, see Install.windows for details diff --git a/sys/windows/porthelp b/sys/windows/porthelp index 7861b4062..cce6549a5 100644 --- a/sys/windows/porthelp +++ b/sys/windows/porthelp @@ -1,4 +1,4 @@ - Microsoft Windows specific help file for NetHack 3.7 + Microsoft Windows specific help file for NetHack 5.0 Copyright (c) NetHack PC Development Team 1993-2025. NetHack may be freely distributed. See license for details. (Last Revision: August 19, 2025) diff --git a/sys/windows/sysconf.template b/sys/windows/sysconf.template index 90095dc1b..3a4fea676 100644 --- a/sys/windows/sysconf.template +++ b/sys/windows/sysconf.template @@ -1,5 +1,5 @@ # -# NetHack 3.7 sysconf $NHDT-Date: 1524689357 2018/04/25 20:49:17 $ $NHDT-Branch: NetHack-3.7.0 $:$NHDT-Revision: 1.22 $ +# NetHack 5.0 sysconf $NHDT-Date: 1524689357 2018/04/25 20:49:17 $ $NHDT-Branch: NetHack-5.0.0 $:$NHDT-Revision: 1.22 $ # Copyright (c) 2015 by Michael Allison # NetHack may be freely redistributed. See license for details. # @@ -28,7 +28,7 @@ WIZARDS=* # Only available if NetHack was compiled with DUMPLOG # Allows following placeholders: # %% literal '%' -# %v version (eg. "3.7.0-0") +# %v version (eg. "5.0.0-0") # %u game UID # %t game start time, UNIX timestamp format # %T current time, UNIX timestamp format @@ -106,25 +106,25 @@ HIDEUSAGE=1 # # The location that a record of game aborts and self-diagnosed game problems # is kept (default=HACKDIR, writeable) -#TROUBLEDIR=%USERPROFILE%\NetHack\3.7 +#TROUBLEDIR=%USERPROFILE%\NetHack\5.0 # # The location that documentation and helps files are placed -#HACKDIR=%USERPROFILE%\NetHack\3.7 +#HACKDIR=%USERPROFILE%\NetHack\5.0 # # The location that level files in progress are stored (writeable) -#LEVELDIR=%USERPROFILE%\AppData\Local\NetHack\3.7 +#LEVELDIR=%USERPROFILE%\AppData\Local\NetHack\5.0 # # The location where saved games are kept (writeable) -#SAVEDIR=%USERPROFILE%\AppData\Local\NetHack\3.7 +#SAVEDIR=%USERPROFILE%\AppData\Local\NetHack\5.0 # # The location that bones files are kept (writeable) -#BONESDIR=c:\ProgramData\NetHack\3.7 +#BONESDIR=c:\ProgramData\NetHack\5.0 # # The location that score files are kept (writeable) -#SCOREDIR=c:\ProgramData\NetHack\3.7 +#SCOREDIR=c:\ProgramData\NetHack\5.0 # # The location that file synchronization locks are stored (writeable) -#LOCKDIR=c:\ProgramData\NetHack\3.7 +#LOCKDIR=c:\ProgramData\NetHack\5.0 # URL loaded for creating reports to the NetHack DevTeam #CRASHREPORTURL=https://nethack.org/links/cr-37BETA.html diff --git a/sys/windows/vs/FetchPrereq/fetchprereq.nmake b/sys/windows/vs/FetchPrereq/fetchprereq.nmake index 2d4f69913..2d89c381f 100644 --- a/sys/windows/vs/FetchPrereq/fetchprereq.nmake +++ b/sys/windows/vs/FetchPrereq/fetchprereq.nmake @@ -1,8 +1,8 @@ -# NetHack 3.7 fetchprereq.nmake +# NetHack 5.0 fetchprereq.nmake #============================================================================== # # The version of the game this Makefile was designed for -NETHACK_VERSION="3.7.0" +NETHACK_VERSION="5.0.0" # A brief version for use in macros NHV=$(NETHACK_VERSION:.=) diff --git a/sys/windows/vs/NetHackPackage.appxmanifest b/sys/windows/vs/NetHackPackage.appxmanifest index 54140a413..51aed7360 100644 --- a/sys/windows/vs/NetHackPackage.appxmanifest +++ b/sys/windows/vs/NetHackPackage.appxmanifest @@ -2,7 +2,7 @@ - NetHack 3.7 + NetHack 5.0 NetHack DevTeam Images\StoreLogo.png @@ -15,7 +15,7 @@ - + diff --git a/sys/windows/vs/Package.StoreAssociation.xml b/sys/windows/vs/Package.StoreAssociation.xml index 24422d2fd..a33a607d2 100644 --- a/sys/windows/vs/Package.StoreAssociation.xml +++ b/sys/windows/vs/Package.StoreAssociation.xml @@ -363,7 +363,7 @@ 30485NetHackDevTeam.NetHack3.6 - NetHack 3.7 + NetHack 5.0 diff --git a/sys/windows/vs/fetchctags/fetchctags.nmake b/sys/windows/vs/fetchctags/fetchctags.nmake index 70023ce1d..f11449433 100644 --- a/sys/windows/vs/fetchctags/fetchctags.nmake +++ b/sys/windows/vs/fetchctags/fetchctags.nmake @@ -1,8 +1,8 @@ -# NetHack 3.7 fetchctags.nmake +# NetHack 5.0 fetchctags.nmake #============================================================================== # # The version of the game this Makefile was designed for -NETHACK_VERSION="3.7.0" +NETHACK_VERSION="5.0.0" # A brief version for use in macros NHV=$(NETHACK_VERSION:.=) diff --git a/sys/windows/vs/package/package.nmake b/sys/windows/vs/package/package.nmake index 55b3e8e02..9842b20c1 100644 --- a/sys/windows/vs/package/package.nmake +++ b/sys/windows/vs/package/package.nmake @@ -1,10 +1,10 @@ -# NetHack 3.7 package.nmake +# NetHack 5.0 package.nmake #============================================================================== # # The version of the game this Makefile was designed for !IFNDEF NETHACK_VERSION -NETHACK_VERSION="3.7.0" +NETHACK_VERSION="5.0.0" !MESSAGE NETHACK_VERSION set to $(NETHACK_VERSION). !ELSE !MESSAGE NETHACK_VERSION set to $(NETHACK_VERSION) by caller. diff --git a/sys/windows/win10.c b/sys/windows/win10.c index d9af80b07..70b7859d8 100644 --- a/sys/windows/win10.c +++ b/sys/windows/win10.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 win10.c $NHDT-Date: 1596498318 2020/08/03 23:45:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 win10.c $NHDT-Date: 1596498318 2020/08/03 23:45:18 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /* Copyright (C) 2018 by Bart House */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/windows/win10.h b/sys/windows/win10.h index 504db9767..64ba6b27b 100644 --- a/sys/windows/win10.h +++ b/sys/windows/win10.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 win10.h $NHDT-Date: 1596498319 2020/08/03 23:45:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ */ +/* NetHack 5.0 win10.h $NHDT-Date: 1596498319 2020/08/03 23:45:19 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.8 $ */ /* Copyright (C) 2018 by Bart House */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/windows/win32api.h b/sys/windows/win32api.h index e1760e5e1..1aee5df18 100644 --- a/sys/windows/win32api.h +++ b/sys/windows/win32api.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 win32api.h $NHDT-Date: 1596498320 2020/08/03 23:45:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 win32api.h $NHDT-Date: 1596498320 2020/08/03 23:45:20 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.15 $ */ /* Copyright (c) NetHack PC Development Team 1996 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/windows/windsys.c b/sys/windows/windsys.c index 245f2681f..3dad0d330 100644 --- a/sys/windows/windsys.c +++ b/sys/windows/windsys.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 windsys.c $NHDT-Date: 1710949760 2024/03/20 15:49:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.95 $ */ +/* NetHack 5.0 windsys.c $NHDT-Date: 1710949760 2024/03/20 15:49:20 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.95 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/windows/winos.h b/sys/windows/winos.h index a28ab6378..9847dd28b 100644 --- a/sys/windows/winos.h +++ b/sys/windows/winos.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 winos.h $NHDT-Date: 1596498322 2020/08/03 23:45:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 winos.h $NHDT-Date: 1596498322 2020/08/03 23:45:22 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.0 $ */ /* Copyright (c) NetHack PC Development Team 2018 */ /* NetHack may be freely redistributed. See license for details. */ From 8d1e6b054cce8b4bc30d120b2f5de49b1f080039 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 10:57:31 -0400 Subject: [PATCH 034/702] Install.dos bit --- sys/msdos/Install.dos | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/msdos/Install.dos b/sys/msdos/Install.dos index 2b2be2096..9e2a16e5e 100644 --- a/sys/msdos/Install.dos +++ b/sys/msdos/Install.dos @@ -1,5 +1,5 @@ - Copyright (c) NetHack PC Development Team 1990-2023. + Copyright (c) NetHack PC Development Team 1990-2026. NetHack may be freely redistributed. See license for details. ============================================================== Instructions for compiling and installing From ab730b70daaf058957c6b7e9e417aa4efcb6e7dd Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 11:04:33 -0400 Subject: [PATCH 035/702] revert an external URL change --- sys/libnh/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/libnh/README.md b/sys/libnh/README.md index 6d4c3cb4d..b887b5730 100644 --- a/sys/libnh/README.md +++ b/sys/libnh/README.md @@ -39,10 +39,10 @@ WASM also has a npm module that can be published out of `sys/lib/npm-library`. A The API is two functions: * `nhmain(int argc, char *argv[])` - The main function for NetHack that configures the program and runs the `moveloop()` until the game is over. The arguments to this function are the [command line arguments](https://nethackwiki.com/wiki/Options) to NetHack. * `shim_graphics_set_callback(shim_callback_t cb)` - A single function that sets a callback to gather graphics events: write a string to screen, get user input, etc. Your job is to pass in a callback and handle all the requested rendering events to show NetHack on the screen. The callback is `void shim_callback_t(const char *name, void *ret_ptr, const char *fmt, ...)` - * `name` is the name of the [window function](https://github.com/NetHack/NetHack/blob/NetHack-5.0/doc/window.txt) that needs to be handled + * `name` is the name of the [window function](https://github.com/NetHack/NetHack/blob/NetHack-3.7/doc/window.txt) that needs to be handled * `ret_ptr` is a pointer to a memory space for the return value. The type expected to be returned in this pointer is described by the first character of the `fmt` string. * `fmt` is a string that describes the signature of the callback. The first character in the string is the return type and any additional characters describe the variable arguments: `i` for integer, `s` for string, `p` for pointer, `c` for character, `v` for void. For example, if format is "vis" the callback will have no return (void), the first argument will be an integer, and the second argument will be a string. If format is "iii" the callback must return an integer, and both the arguments passed in will be integers. - * [Variadic arguments](https://www.gnu.org/software/libc/manual/html_node/Variadic-Example.html): a variable number and type of arguments depending on the `window function` that is being called. The arguments associated with each `name` are described in the [NetHack window.txt](https://github.com/NetHack/NetHack/blob/NetHack-5.0/doc/window.txt). + * [Variadic arguments](https://www.gnu.org/software/libc/manual/html_node/Variadic-Example.html): a variable number and type of arguments depending on the `window function` that is being called. The arguments associated with each `name` are described in the [NetHack window.txt](https://github.com/NetHack/NetHack/blob/NetHack-3.7/doc/window.txt). Where is the header file for the API you ask? There isn't one. It's three functions, just drop the forward declarations at the top of your file (or create your own header). It's more work figuring out how to install and copy around header files than it's worth for such a small API. If you disagree, feel free to submit a PR to fix it. :) @@ -50,8 +50,8 @@ Where is the header file for the API you ask? There isn't one. It's three functi The WebAssembly API has a similar signature to `libnethack.a` with minor syntactic differences: * `main(int argc, char argv[])` - The main function for NetHack * `shim_graphics_set_callback(char *cbName)` - A `String` representing a name of a callback function. The callback function be registered as `globalThis[cbName] = function yourCallback(name, ... args) { /* your stuff */ }`. Note that [globalThis](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis) points to `window` in browsers and `global` in node.js. - * `name` is the name of the [window function](https://github.com/NetHack/NetHack/blob/NetHack-5.0/doc/window.txt) that needs to be handled - * `... args` is a variable number and type of arguments depending on the `window function` that is being called. The arguments associated with each `name` are described in the [NetHack window.txt](https://github.com/NetHack/NetHack/blob/NetHack-5.0/doc/window.txt) + * `name` is the name of the [window function](https://github.com/NetHack/NetHack/blob/NetHack-3.7/doc/window.txt) that needs to be handled + * `... args` is a variable number and type of arguments depending on the `window function` that is being called. The arguments associated with each `name` are described in the [NetHack window.txt](https://github.com/NetHack/NetHack/blob/NetHack-3.7/doc/window.txt) * The function must return the value expected for the specified `name` From 3cb7bfc0b32670ce802230b3e15eec7c064389d1 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 11:08:10 -0400 Subject: [PATCH 036/702] more sys --- sys/amiga/README.amiga | 2 +- sys/libnh/README.md | 4 ++-- sys/libnh/test/run.sh | 6 +++--- sys/msdos/Install.dos | 6 +++--- sys/msdos/fetch-cross-compiler.sh | 4 ++-- sys/unix/README-hints | 12 ++++++------ sys/windows/GNUmakefile | 2 +- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/sys/amiga/README.amiga b/sys/amiga/README.amiga index 89362d8a9..cc83a832d 100644 --- a/sys/amiga/README.amiga +++ b/sys/amiga/README.amiga @@ -73,7 +73,7 @@ Cross-compilation from Linux using bebbo's m68k-amigaos-gcc toolchain # Install toolchain to /opt/amiga # Clone NetHack 5.0 source cd NetHack - sys/unix/setup.sh sys/unix/hints/linux.370 + sys/unix/setup.sh sys/unix/hints/linux.500 make fetch-lua make CROSS_TO_AMIGA=1 fetch-regex make CROSS_TO_AMIGA=1 all diff --git a/sys/libnh/README.md b/sys/libnh/README.md index b887b5730..3a9c14d1d 100644 --- a/sys/libnh/README.md +++ b/sys/libnh/README.md @@ -12,14 +12,14 @@ Generally the build is the same as the unix build: [Edit Oct 4, 2020: Use the existing Makefile and hints, hints/include system for cross-compiles] 1. `cd sys/unix` -2. `./setup.sh hints/macOS.370` +2. `./setup.sh hints/macOS.500` 3. `cd ../..` 4. For `libnethack.a`: `make WANT_LIBNH=1 all` 5. For `nethack.js`: `make CROSS_TO_WASM=1 all` [Original text was:] 1. `cd sys/lib` -2. For `libnethack.a`: `./setup.sh hints/macOS.370`; for `nethack.js`: `./setup.sh hints/wasm` +2. For `libnethack.a`: `./setup.sh hints/macOS.500`; for `nethack.js`: `./setup.sh hints/wasm` 3. `cd ../..` 4. `make` diff --git a/sys/libnh/test/run.sh b/sys/libnh/test/run.sh index 96ead1482..f16571495 100755 --- a/sys/libnh/test/run.sh +++ b/sys/libnh/test/run.sh @@ -6,7 +6,7 @@ if [ x$1 == "xlib" ]; then make spotless fi cd sys/unix - ./setup.sh hints/macOS.370 + ./setup.sh hints/macOS.500 cd ../.. make WANT_LIBNH=1 fi @@ -25,7 +25,7 @@ if [ x$1 == "xwasm" ]; then make spotless fi cd sys/unix - ./setup.sh hints/macOS.370 + ./setup.sh hints/macOS.500 cd ../.. make CROSS_TO_WASM=1 fi @@ -38,7 +38,7 @@ if [ x$1 == "xbin" ]; then echo Doing bin... make spotless cd sys/unix - ./setup.sh hints/macOS.370 + ./setup.sh hints/macOS.500 cd ../.. make fi diff --git a/sys/msdos/Install.dos b/sys/msdos/Install.dos index 9e2a16e5e..a8091e607 100644 --- a/sys/msdos/Install.dos +++ b/sys/msdos/Install.dos @@ -61,7 +61,7 @@ II. There once was a time when people built NetHack right on their DOS machine. sys/msdos/fetch-cross-compiler.sh That script won't install anything, it just does file fetches and stores - them in subfolders of lib. The linux.370 and macOS.370 hints files are + them in subfolders of lib. The linux.500 and macOS.500 hints files are configured to find the cross-compiler there if you add CROSS_TO_MSDOS=1 on your make command line. @@ -72,12 +72,12 @@ II. There once was a time when people built NetHack right on their DOS machine. On your linux host: - cd sys/unix ; sh setup.sh hints/linux.370 ; cd ../.. + cd sys/unix ; sh setup.sh hints/linux.500 ; cd ../.. make fetch-lua On your macOS host: - cd sys/unix ; sh setup.sh hints/macOS.370 ; cd ../.. + cd sys/unix ; sh setup.sh hints/macOS.500 ; cd ../.. make fetch-lua The MSDOS cross-compile can then be carried out by specifying diff --git a/sys/msdos/fetch-cross-compiler.sh b/sys/msdos/fetch-cross-compiler.sh index 037d3aaf3..d9e7677ac 100755 --- a/sys/msdos/fetch-cross-compiler.sh +++ b/sys/msdos/fetch-cross-compiler.sh @@ -34,13 +34,13 @@ if [ "$(uname)" = "Darwin" ]; then #Mac DJGPP_FILE="djgpp-osx-$GCCVER.tar.bz2" if [ -z "HINTS" ]; then - export HINTS=macOS.370 + export HINTS=macOS.500 fi elif [ "$(expr substr $(uname -s) 1 5)" = "Linux" ]; then #Linux DJGPP_FILE="djgpp-linux64-$GCCVER.tar.bz2" if [ -z "$HINTS" ]; then - export HINTS=linux.370 + export HINTS=linux.500 fi elif [ "$(expr substr $(uname -s) 1 10)" = "MINGW32_NT" ]; then #mingw diff --git a/sys/unix/README-hints b/sys/unix/README-hints index 87e08e6d4..01979a8da 100644 --- a/sys/unix/README-hints +++ b/sys/unix/README-hints @@ -9,11 +9,11 @@ is included in the distributed Makefiles. There are two .370 series hints files provided with NetHack: - linux.370 for use on Linux - macOS.370 for use on macOS + linux.500 for use on Linux + macOS.500 for use on macOS Those will also pull in content from sys/unix/hints/include/*.370, -that is shared between the linux.370 and macOS.370 hints files. +that is shared between the linux.500 and macOS.500 hints files. [.370 make build options] @@ -57,9 +57,9 @@ make CROSS_TO_MSDOS=1 package Cross-compile for an MSDOS target package. make CROSS_TO_WASM=1 Cross-compile for a WASM target. make CROSS_TO_MIPS=1 Cross-compile for a mips target. -make WANT_BUNDLE=1 For macOS.370 only, place the build results into +make WANT_BUNDLE=1 For macOS.500 only, place the build results into a macOS bundle layout. -make WANT_MACSOUND=1 For macOS.370, include support for built-in macOS +make WANT_MACSOUND=1 For macOS.500, include support for built-in macOS sound libraries. make WANT_SPEECH=1 If one of the sound libraries was included, also include speech synthesis support (Recent macOS @@ -74,7 +74,7 @@ make WANT_UBSAN=1 Include support for the undefined behaviour make WANT_SHARE_INSTALL=1 Place the results of the install/update portion of the build into a shared area on a multiuser system. - + make WANT_SOURCE_INSTALL=1 Place the results of the install/update portion of the build into a subfolder of the source tree, rather than in a system-wide shared area. diff --git a/sys/windows/GNUmakefile b/sys/windows/GNUmakefile index 258a00120..e6bc43ec0 100644 --- a/sys/windows/GNUmakefile +++ b/sys/windows/GNUmakefile @@ -357,7 +357,7 @@ endif ifeq "$(GCC_EXTRA_WARNINGS)" "Y" # -# These match the warnings enabled on the linux.370 and macOS.370 hints builds +# These match the warnings enabled on the linux.500 and macOS.500 hints builds # CFLAGSXTRA = -Wall -Wextra -Wreturn-type -Wunused -Wswitch -Wshadow \ -Wwrite-strings -pedantic -Wmissing-declarations \ From 84e76bbbcb2087ca628f877d164fe6354ca1405f Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 11:13:03 -0400 Subject: [PATCH 037/702] README-hints bit --- sys/unix/README-hints | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/unix/README-hints b/sys/unix/README-hints index 01979a8da..a666bd9e8 100644 --- a/sys/unix/README-hints +++ b/sys/unix/README-hints @@ -8,7 +8,7 @@ is included in the distributed Makefiles. [.370 hints] -There are two .370 series hints files provided with NetHack: +There are two .500 series hints files provided with NetHack: linux.500 for use on Linux macOS.500 for use on macOS From 74e2062063c67b63404ba82e51f253360abe01b6 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 11:51:02 -0400 Subject: [PATCH 038/702] README 1st cut --- README | 146 +++++++------------------ doc/fixes3-6-7.txt | 6 +- doc/{fixes3-7-0.txt => fixes5-0-0.txt} | 0 doc/lua.adoc | 2 +- 4 files changed, 44 insertions(+), 110 deletions(-) rename doc/{fixes3-7-0.txt => fixes5-0-0.txt} (100%) diff --git a/README b/README index e6bf764f8..8dac1f905 100644 --- a/README +++ b/README @@ -1,67 +1,40 @@ - NetHack 3.7.0 work-in-progress -- General information + NetHack 5.0.0 work-in-progress -- General information -NetHack 3.7 is an enhancement to the dungeon exploration game NetHack, -which is a distant descendent of Rogue and Hack, and a direct descendent of -NetHack 3.6. +NetHack 5.0 is an enhancement to the dungeon exploration game NetHack, +which is a distant descendent of Rogue and Hack, and a direct descendent +of NetHack 3.6. -NetHack 3.7.0 work-in-progress is not a release of NetHack. As a .0 version, -and still very early in its development cycle, there has already been changes -made, and there will continue to be many more prior to an eventual release. -The file doc/fixes3-7-0.txt in the source distribution will be updated with -a list of fixes as they are committed. +NetHack 5.0.0 is a release of NetHack. As a .0 version, there may be some +bugs encountered. Constructive suggestions, GitHub pull requests, and bug +reports are all welcome and encouraged. -In short -- there are likely to be bugs. Don't treat NetHack-3.7 branch as -released code, and if stability is paramount, then the most recent -NetHack 3.6.7 release is safest for you. +The file doc/fixes5-0-0.txt in the source distribution contains a full list +of fixes and changes as they were committed. The text in there was written +for the development team's own use and is provided "as is", so please do +not ask us to further explain the entries in that file. Some entries might +be considered "spoilers", particularly in the "new features" section. -We're making the .0 work-in-progress available so that you can observe, test -out, and contribute to its development. Constructive suggestions, GitHub pull -requests, and bug reports are all welcome and encouraged. - -The file doc/fixes3-7-0.txt in the source distribution has a full list of -bug-fixes included so far, as well as brief mentions of some of the other code -changes. The text in there was written for the development team's own use and is -provided "as is", so please do not ask us to further explain the entries in -that file. Some entries might be considered "spoilers", particularly in the -"new features" section. - -Along with the game improvements and bug fixes, NetHack 3.7 strives to make +Along with the game improvements and bug fixes, NetHack 5.0 strives to make some general architectural improvements to the game or to its building -process. Among them: +process. Among them, 5.0 has: - * Remove barriers to building NetHack on one platform and operating system, + * removes barriers to building NetHack on one platform and operating system, for later execution on another (possibly quite different) platform and/or operating system. That capability is generally known as "cross-compiling." See the file "Cross-compiling" in the top-level folder for more information on that. - * Replace the build-time "yacc and lex"-based level compiler, the "yacc and - lex"-based dungeon compiler, and the quest text file processing done - by NetHack's "makedefs" utility, with Lua text alternatives that are - loaded and processed by the game during play. + * The build-time "yacc and lex"-based level compiler, the + "yacc and lex"-based dungeon compiler, and the quest text file processing + previously done by NetHack's "makedefs" utility, have been replaced with + Lua text alternatives that are loaded and processed by the game during play. - * Write game savefiles and bonesfiles in a more portable and consistent way - to open up the possibility of utilizing them between different platforms, - such as between your desktop computer and your hand-held device. - - * Add support to make the game restartable without exit (a.k.a. "play again" - support). Toward that end, many previously scattered and separate variables - have been gathered into central 'ga' through 'gz' structures in - decl.h/decl.c. That central ability to reinitialize the variables will - benefit the porting effort to some platforms that are under consideration - where "play again" is typical. - -Here are some other general notes on the changes in NetHack 3.7 that were not +Here are some other general notes on the changes in NetHack 5.0 that were not considered spoilers: - automatic annotation "gateway to Moloch's Sanctum" for vibrating square level once that square's location becomes known (found or magic mapped); goes away once sanctum temple is found (entered or high altar mapped) - - savefile: add support for a tool to deconstruct data structures, - that get stored in a savefile, down into their individual fields and - save those individual fields instead of the entire struct. The - intention is to provide a way to export and transport savefiles - between platforms, architectures and data models. - - - - - - - - - - - @@ -98,75 +71,36 @@ Please read items (1), (2) and (3) BEFORE doing anything with your new code. that the default configuration is SysV/Sun/Solaris2.x (simply because the code was housed on such a system). - The files sys/*/Install.* were written to guide you in configuring the - program for your operating system. The files win/*/Install.* are - available, where necessary, to help you in configuring the program - for particular windowing environments. Reading them, and the man pages, - should answer most of your questions. + The files sys/*/Install.*, or sys/*/NewInstall.* were written to guide + you in configuring the program for your operating system. The files + win/*/Install.* are available, where necessary, to help you in + configuring the program for particular windowing environments. + Reading them, and the man pages, should answer most of your questions. - At the time of the most recent official release, NetHack 3.6, it had - been tested to run/compile on: + At the time of the most recent official release, NetHack 5.0, it had + been tested to run and/or compile on: Intel Pentium or better running Linux, BSDI + [compiles, runs] Intel Pentium or better running Windows 10 or 11 + [compiles, runs] Intel-based, or Apple M1, M2, M3, M4, M5 Macs running - macOS 10.11 (El Capitan) to macOS 26 (Tahoe) + [compiles, runs] + macOS 10.11 (El Capitan) to macOS 26 (Tahoe) [compile, run] (follow the instructions in sys/unix/NewInstall.unx) Intel 80386 or greater running MS-DOS with DPMI + [cross-compiles on Linux, runs on MS-DOS, emulator/dosbox] built via djgpp compiler (native or Linux-hosted cross-compiler) + AmigaOS 3.0 or later + [cross-compiles on Linux or macOS, runs on Amiga or emulator] + Running requires Kickstart 39+ + 6 MB free RAM minimum (8 MB recommended) + Hard drive with ~5 MB free space + + There has also been some success runing/comiling on: OpenVMS (aka VMS) V8.4 on Alpha and on Integrity/Itanium/IA64 - - Previous versions of NetHack were tested and known to run on the - following systems, but it is unknown if they can still build and - execute NetHack 3.6 or NetHack 3.7: - - Apple Macintosh running MacOS 7.5 or higher, LinuxPPC, BeOS 4.0 - Atari ST/TT/Falcon running TOS (or MultiTOS) with GCC - AT&T 3B1 running System V (3.51) - AT&T 3B2/600 & 3B2/622 running System V R3.2.1 - AT&T 3B2/1000 Model 80 running System V R3.2.2 - AT&T 3B4000 running System V - AT&T 6386 running System V R3.2 - Commodore Amiga running AmigaDOS 3.0 or higher with SAS/C 6.x - (but see Makefile.ami about DICE and Manx) - Data General AViiON systems running DG/UX - DEC Alpha/VMS (aka OpenVMS AXP), running V1.x through V7.1 - DEC VAX/VMS, running V4.6 through V7.1 - DEC vaxen running BSD, Ultrix - Decstations running Ultrix 3.1, 4.x - Encore Multimax running UMAX 4.2 - Gould NP1 running UTX 3/2 - HP 9000s300 running HP-UX - HP 9000s700 running HP-UX 9.x, 10.x, 11.x - H/PC Pro devices running Windows CE 2.11 and higher. - IBM PC/RT and RS/6000 running AIX 3.x - IBM PS/2 and AT compatibles running OS/2 - 2.0 and up with GCC emx - IBM PS/2 and AT compatibles running OS/2 1.1 - 2.0 (and probably - Warp) with Microsoft 6.0, and OS/2 2.0 and up with IBM CSet++ 2.0. - Intel 80386 or greater (or clone) running 386BSD - Intel x86 running a version of Windows 7 or 8 or prior to XP. - Mips M2000 running RiscOS 4.1 - NeXT running Mach (using BSD configuration) - Palm Size PC 1.1 devices running Windows CE 2.11 - Pocket PC devices running Windows CE 3.0 and higher - Pyramid 9820x running OSx 4.4c - SGI Iris running IRIX - Stardent Vistra 800 running SysV R4.0 - Stride 460 running UniStride 2.1 - Sun-3s, -4s, and -386is running SunOS 3.x - Sun-3s and -386is running SunOS 4.x - "Sun SPARC"-based machine running SunOS 4.x, Solaris 2.x, or Solaris 7 - Valid Logic Systems SCALD-System - - Previous versions, using a cross-compiler hosted on another platform, - such as win32, could also build the following from source: - Pocket PC devices running Windows CE 3.0 and higher - H/PC Pro devices running Windows CE 2.11 and higher - Palm Size PC 1.1 devices running Windows CE 2.11 - - Unless otherwise mentioned, the compiler used was the OS-vendor's - C compiler. + OpenVMS (ask VMS) V9.2-3 on x86-64 - - - - - - - - - - - diff --git a/doc/fixes3-6-7.txt b/doc/fixes3-6-7.txt index e34d9f1b4..633950c95 100644 --- a/doc/fixes3-6-7.txt +++ b/doc/fixes3-6-7.txt @@ -7,7 +7,7 @@ produce 3.6.7 as well as any post-release fixes in binaries. General Fixes and Modified Features ----------------------------------- during engraving, spaces were counted instead of non-space (cherry-pick of - 4e0a1e04 from NetHack-3.7) + 4e0a1e04 from NetHack-5.0 WIP) avoid potential buffer overflow in append_str() resolve missing dependency in NetHack.sln code in include/tradstdc.h was trying to suppress warn_unused result by @@ -29,7 +29,7 @@ windows: the console.rc file had outdated information stating 3.6.3 when the official 3.6.6 binary was built. windows: switch from using keyhandling dll's to incorporating the three variations (default, ray, 340) in sys/winnt/nttty.c -curses: cherry-picked selectsaved code from 3.7 for menu of save files +curses: cherry-picked selectsaved code from 5.0 WIP for menu of save files NetHackW: fix delay rendering of cursor when using farlook @@ -63,7 +63,7 @@ makedefs can produce individual bogusmon, engrave and epitaph files drinkfountain() fate 24 to curse objects could end up cursing objects on the floor chain instead of the intended inventory object chain proceed with showpaths option even if the sysconf file is missing -avoid memory leak in mk_artifact(); cherry-pick of 3cca4f27 from 3.7 WIP +avoid memory leak in mk_artifact(); cherry-pick of 3cca4f27 from 5.0 WIP avoid using col in Guidebook build, since some distros no longer include it, particularly some that use musl libc back-port some nroff macro updates for Guidebook diff --git a/doc/fixes3-7-0.txt b/doc/fixes5-0-0.txt similarity index 100% rename from doc/fixes3-7-0.txt rename to doc/fixes5-0-0.txt diff --git a/doc/lua.adoc b/doc/lua.adoc index 9cfa1cd8e..456503569 100644 --- a/doc/lua.adoc +++ b/doc/lua.adoc @@ -100,7 +100,7 @@ Only available if NetHack was compiled with DUMPLOG. | %T | current time, timestamp | %d | game start, YYYYMMDDhhmmss | %D | current time, YYYYMMDDhhmmss -| %v | game version, eg. '3.7.0-0' +| %v | game version, eg. '5.0.0-0' | %u | UID | %n | player name | %N | first character of player name From ae1eb87b9da164d566ffd106c3514c4ddf7990c7 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sun, 26 Apr 2026 11:16:09 -0400 Subject: [PATCH 039/702] This is cron-daily v1-Apr-26-2026. 005manpages updated: recover.txt --- doc/recover.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/recover.txt b/doc/recover.txt index fcefe12db..e13d2995f 100644 --- a/doc/recover.txt +++ b/doc/recover.txt @@ -74,7 +74,7 @@ BUGS COPYRIGHT This file is Copyright (C) Kenneth Lorber, 2024 for version - NetHack-5.0:1.12. NetHack may be freely redistributed. See license + NetHack-3.7:1.12. NetHack may be freely redistributed. See license for details. From 3fb81a48a1042a96d79c7dc81a08720645f52855 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sun, 26 Apr 2026 11:16:09 -0400 Subject: [PATCH 040/702] This is cron-daily v1-Apr-26-2026. 005manpages updated: nethack.txt --- doc/nethack.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/nethack.txt b/doc/nethack.txt index fe59517f2..ca120c3e0 100644 --- a/doc/nethack.txt +++ b/doc/nethack.txt @@ -279,7 +279,7 @@ BUGS COPYRIGHT This file is Copyright (C) Robert Patrick Rankin, 2024 for version - NetHack-5.0:1.31. NetHack may be freely redistributed. See license + NetHack-3.7:1.31. NetHack may be freely redistributed. See license for details. Dungeons & Dragons is a Trademark of Wizards of the Coast, Inc. From 5b9df0041ceb9ba4d7cfbad79b1edf72f17247e1 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sun, 26 Apr 2026 11:16:09 -0400 Subject: [PATCH 041/702] This is cron-daily v1-Apr-26-2026. 005guidebook updated: doc/Guidebook.txt --- doc/Guidebook.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 3a2e0ff5f..bf2f29bbb 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -4305,7 +4305,7 @@ See pickup_types and also autopickup_exception for ways to refine the behavior. - Note: prior to version 3.7.0, the default for autopickup was on. + Note: prior to version 5.0.0, the default for autopickup was on. autoquiver This option controls what happens when you attempt the `f' (fire) @@ -6297,7 +6297,7 @@ Each SOUND entry is broken down into the following parts: MESG - message window mapping (the only one supported in - 3.7.0); + 5.0.0); msgtype - optional; message type to use, see "Configuring Mes- sage Types" pattern - the pattern to match; @@ -7026,7 +7026,7 @@ ing placeholders: %% - literal `%' - %v - version (eg. "3.7.0-0") + %v - version (eg. "5.0.0-0") %u - game UID %t - game start time, UNIX timestamp format %T - current time, UNIX timestamp format From 9e248ef8a28614b4d13ceb2540d288625be6fb83 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sun, 26 Apr 2026 11:16:07 -0400 Subject: [PATCH 042/702] This is cron-daily v1-Apr-26-2026. 000files updated: Files --- Files | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/Files b/Files index 37f8904b4..c968110bd 100644 --- a/Files +++ b/Files @@ -202,14 +202,6 @@ outdated/sys/wince/ceinc/sys: (sys/stat.h for Windows CE and PocketPC - untested for 3.6.2) stat.h -outdated/sys/windows: -(files that are no longer maintained for current game code) -travis-gcc.sh - -outdated/sys/windows/vs: -(files that are no longer maintained for current game code) -travisci.sh - outdated/win/Qt3: (files for the Qt 3 widget library - X11, Windows, Mac OS X, or Qtopia) Info.plist Install.Qt knethack.lnk @@ -359,10 +351,10 @@ random.c (Berkeley uudecode file, which may be used in build process of any version) uudecode.c -(file for MSDOS, OS/2, Amiga, and Atari versions - only MSDOS tested for 3.7) +(file for MSDOS, OS/2, Amiga, and Atari versions - only MSDOS tested for 5.0) pcmain.c -(file for MSDOS, OS/2, and Atari versions - only MSDOS tested for 3.7) +(file for MSDOS, OS/2, and Atari versions - only MSDOS tested for 5.0) NetHack.cnf pctty.c (file for MSDOS, OS/2, and VMS versions) @@ -371,10 +363,10 @@ termcap (file for VMS version) tclib.c -(files for MSDOS, OS/2 and Atari versions - only MSDOS tested for 3.7) +(files for MSDOS, OS/2 and Atari versions - only MSDOS tested for 5.0) pcsys.c pcunix.c -(files for OS/2 version - untested for 3.7) +(files for OS/2 version - untested for 5.0) Makefile.lib termcap.uu (files for UNIX and Be versions) @@ -416,16 +408,16 @@ NetHack.xcscheme makedefs.xcscheme recover.xcscheme sys/unix/hints: (files for configuring UNIX NetHack versions) -linux-minimal linux.370 macOS.370 +linux-minimal linux.500 macOS.500 macosx.sh solaris solaris-playground unix sys/unix/hints/include: (files for configuring UNIX NetHack versions) -compiler.370 cross-post.370 cross-pre1.370 cross-pre2.370 -gbdates-post.370 gbdates-pre.370 misc.370 multisnd-post.370 -multisnd1-pre.370 multisnd2-pre.370 multiw-1.370 multiw-2.370 -response.370 +compiler.500 cross-post.500 cross-pre1.500 cross-pre2.500 +gbdates-post.500 gbdates-pre.500 misc.500 multisnd-post.500 +multisnd1-pre.500 multisnd2-pre.500 multiw-1.500 multiw-2.500 +response.500 sys/vms: (files for VMS version) From 89a54b83702b75cf9f308260ad757ce39de7038e Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 11:58:47 -0400 Subject: [PATCH 043/702] update .gitattributes --- sys/share/.gitattributes | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/share/.gitattributes b/sys/share/.gitattributes index 2073bdcba..f240d70ab 100644 --- a/sys/share/.gitattributes +++ b/sys/share/.gitattributes @@ -7,12 +7,12 @@ Makefile.lib NH_filestag=(file%s_for_OS/2_version_-_untested_for_5.0) #termcap.uu NH_filestag=(file%s_for_MSDOS_and_OS/2_versions_-_untested_for_5.0) termcap.uu NH_filestag=>Makefile.lib -pcmain.c NH_filestag=(file_for_MSDOS,_OS/2,_Amiga,_and_Atari_versions_-_only_MSDOS_tested_for_5.0) +pcmain.c NH_filestag=(file_for_MSDOS,_Amiga_versions) -pcsys.c NH_filestag=(file%s_for_MSDOS,_OS/2_and_Atari_versions_-_only_MSDOS_tested_for_5.0) +pcsys.c NH_filestag=(file%s_for_MSDOS,_Amiga_versions) pcunix.c NH_filestag=>pcsys.c -NetHack.cnf NH_filestag=(file_for_MSDOS,_OS/2,_and_Atari_versions_-_only_MSDOS_tested_for_5.0) +NetHack.cnf NH_filestag=(file_for_MSDOS,_Amiga_versions) pctty.c NH_filestag=>NetHack.cnf ioctl.c NH_filestag=(file%s_for_UNIX_and_Be_versions) From 11ae226eeb3bfd4652b7db6e8fd46793a40b81cb Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 12:13:14 -0400 Subject: [PATCH 044/702] some dat updates --- dat/GENFILES | 2 +- dat/bogusmon.txt | 2 +- dat/data.base | 2 +- dat/engrave.txt | 2 +- dat/epitaph.txt | 2 +- dat/hellfill.lua | 2 +- dat/luahelper | 2 +- dat/minetn-1.lua | 2 +- dat/symbols | 2 +- dat/tribute | 34 +++++++++++++++++----------------- doc/fixes5-0-0.txt | 8 ++++---- sound/wav/README | 2 +- sound/wav/attributions.txt | 2 +- 13 files changed, 32 insertions(+), 32 deletions(-) diff --git a/dat/GENFILES b/dat/GENFILES index 2613ad90e..056dde16d 100755 --- a/dat/GENFILES +++ b/dat/GENFILES @@ -1,5 +1,5 @@ #!/usr/bin/perl -# NetHack 3.7 GENFILES $NHDT-Date: 1596498242 2020/08/03 23:44:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +# NetHack 5.0 GENFILES $NHDT-Date: 1596498242 2020/08/03 23:44:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ # Copyright (c) 2018 by Kenneth Lorber # NetHack may be freely redistributed. See license for details. diff --git a/dat/bogusmon.txt b/dat/bogusmon.txt index 8b5335296..584c51f70 100644 --- a/dat/bogusmon.txt +++ b/dat/bogusmon.txt @@ -1,4 +1,4 @@ -# NetHack 3.7 bogusmon.txt $NHDT-Date: 1596498237 2020/08/03 23:43:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ +# NetHack 5.0 bogusmon.txt $NHDT-Date: 1596498237 2020/08/03 23:43:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ # Copyright (c) 2016 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. # diff --git a/dat/data.base b/dat/data.base index d43307f33..b051cc62a 100644 --- a/dat/data.base +++ b/dat/data.base @@ -1,4 +1,4 @@ -# NetHack 3.7 data.base +# NetHack 5.0 data.base # $NHDT-Date: 1737609388 2025/01/22 21:16:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.141 $ # Copyright (c) 1994, 1995, 1996 by the NetHack Development Team # Copyright (c) 1994 by Boudewijn Wayers diff --git a/dat/engrave.txt b/dat/engrave.txt index ff473b610..1d199a3e7 100644 --- a/dat/engrave.txt +++ b/dat/engrave.txt @@ -1,4 +1,4 @@ -# NetHack 3.7 engrave.txt $NHDT-Date: 1596498240 2020/08/03 23:44:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ +# NetHack 5.0 engrave.txt $NHDT-Date: 1596498240 2020/08/03 23:44:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ # Copyright (c) 2015 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. # Random engravings on the floor diff --git a/dat/epitaph.txt b/dat/epitaph.txt index d559d1fb3..1c1a85f6a 100644 --- a/dat/epitaph.txt +++ b/dat/epitaph.txt @@ -1,4 +1,4 @@ -# NetHack 3.7 epitaph.txt $NHDT-Date: 1596498241 2020/08/03 23:44:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +# NetHack 5.0 epitaph.txt $NHDT-Date: 1596498241 2020/08/03 23:44:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ # Copyright (c) 2015 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. # Epitaphs for random headstones diff --git a/dat/hellfill.lua b/dat/hellfill.lua index 3a9b4ed9f..9808837fc 100644 --- a/dat/hellfill.lua +++ b/dat/hellfill.lua @@ -1,4 +1,4 @@ --- NetHack 3.7 hellfill.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ +-- NetHack 5.0 hellfill.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ -- Copyright (c) 2022 by Pasi Kallinen -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/luahelper b/dat/luahelper index 7f8a653fa..f06c9c367 100644 --- a/dat/luahelper +++ b/dat/luahelper @@ -1,4 +1,4 @@ -# NetHack 3.7 luahelper $NHDT-Date: $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 luahelper $NHDT-Date: $ $NHDT-Branch: NetHack-3.7 $ # # Makefile to assist developers in adding lines to various build # Makefiles, or project files, as lua files are added or removed. diff --git a/dat/minetn-1.lua b/dat/minetn-1.lua index ef10d70b7..87544b1c9 100644 --- a/dat/minetn-1.lua +++ b/dat/minetn-1.lua @@ -1,4 +1,4 @@ --- NetHack 3.7 mines minetn-1.lua $NHDT-Date: 1652196030 2022/05/10 15:20:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ +-- NetHack 5.0 mines minetn-1.lua $NHDT-Date: 1652196030 2022/05/10 15:20:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/symbols b/dat/symbols index 58bb8d3fa..cb46ec197 100644 --- a/dat/symbols +++ b/dat/symbols @@ -1,4 +1,4 @@ -# NetHack 3.7 symbols $NHDT-Date: 1725052751 2024/08/30 21:19:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.36 $ +# NetHack 5.0 symbols $NHDT-Date: 1725052751 2024/08/30 21:19:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.36 $ # Copyright (c) 2006 by Michael Allison # NetHack may be freely redistributed. See license for details. # diff --git a/dat/tribute b/dat/tribute index 5438d48be..f58dc89ac 100644 --- a/dat/tribute +++ b/dat/tribute @@ -1,4 +1,4 @@ -# NetHack 3.7 tribute $NHDT-Date: 1726809275 2024/09/20 05:14:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.118 $ +# NetHack 5.0 tribute $NHDT-Date: 1726809275 2024/09/20 05:14:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.118 $ # Copyright (c) 2017 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. # A tribute introduced in NetHack 3.6.0 to: @@ -1263,7 +1263,7 @@ They are not necessarily very good at it. [Sourcery, by Terry Pratchett] %e passage # -# additional passage added for 3.7 +# additional passage added for 5.0 # # p. 164 (passage begins mid-sentence) %passage 11 @@ -3201,7 +3201,7 @@ But, on the whole, there are worse places to be buried than inside a lion. [Small Gods, by Terry Pratchett] %e passage # -# 3 more passages added for 3.7 +# 3 more passages added for 5.0 # # p. 7 (Brother Nhumrod is in charge of a group of novices; he's thinking # about one of them, Brutha, the main character of the story) @@ -3463,7 +3463,7 @@ kingdom. [Lords and Ladies, by Terry Pratchett] %e passage # -# passage added for 3.7 +# passage added for 5.0 # # p. 60 (passage starts mid-paragraph; "paddlin'" is accurate but unclear; # "ooh-jar" is accurate for ouija after having been butchered by @@ -3962,7 +3962,7 @@ The Chair came down slowly, occasionally glancing fearfully up the stairs. [Soul Music, by Terry Pratchett] %e passage # -# 2 more passages added for 3.7 +# 2 more passages added for 5.0 # # p. 242 (passage starts and ends mid-paragraph; "the Old" rather than "the # Old " is accurate) @@ -4467,7 +4467,7 @@ Come on. I want to try a leg of the elephant that bit me." [Maskerade, by Terry Pratchett] %e passage # -# 4 new passages added for 3.7 +# 4 new passages added for 5.0 # # pp. 51-52 (Granny Weatherwax and Nanny Ogg are traveling to Ankh-Morpork # and Nanny feels that the weather is too chilly for flying; @@ -5044,7 +5044,7 @@ Death. OR THE FAME. OR BECAUSE THEY SHOULDN'T. [Hogfather, by Terry Pratchett] %e passage # -# 3 new passages added for 3.7 +# 3 new passages added for 5.0 # # pp. 2-3 (the door turns out to lead to a bathroom designed by Bergholt # Stuttly "Bloody Stupid" Johnson, an infamous architect and @@ -5373,7 +5373,7 @@ him and he's warm for the rest of his life.' See my point?" [Jingo, by Terry Pratchett] %e passage # -# 2 new passages added for 3.7 +# 2 new passages added for 5.0 # # p. 90 (second line beginning with "Sir." rather than "Sir," is accurate) %passage 13 @@ -5595,7 +5595,7 @@ of clothes, often with the same sort of insignia. [The Last Continent, by Terry Pratchett] %e passage # -# 4 new passages added for 3.7 +# 4 new passages added for 5.0 # # pp. 113-114 (passage ends mid-paragraph) %passage 11 @@ -5787,7 +5787,7 @@ saw what happened to the others! /You/ got your fingers burned!." [Carpe Jugulum, by Terry Pratchett] %e passage # -# 4 new passages added for 3.7 +# 4 new passages added for 5.0 # # p. 24 (ellipsis occurs at start of paragraph; Quite Reverend Oats has opened # /The Book of Om/ at random and is reading the passage found there) @@ -5987,7 +5987,7 @@ Been there, done that, bought the doublet... [The Fifth Elephant, by Terry Pratchett] %e passage # -# 3 new passages added for 3.7 +# 3 new passages added for 5.0 # # pp. 34-35 (a footnote about Cpl Nobbs lately dressing as a woman omitted) %passage 10 @@ -6173,7 +6173,7 @@ EYES... [The Truth, by Terry Pratchett] %e passage # -# 5 new passages added for 3.7 +# 5 new passages added for 5.0 # # p. 3 (two paragraphs in the middle skipped) %passage 9 @@ -6467,7 +6467,7 @@ there to make you think before you broke them. [Thief of Time, by Terry Pratchett] %e passage # -# 6 new passages added for 3.7 +# 6 new passages added for 5.0 # # p. 80 (passage ends mid-paragraph) %passage 9 @@ -6682,7 +6682,7 @@ betray 'em, quick as a wink. 'Cos that's villaining.' [The Last Hero, written by Terry Pratchett, illustrated by Paul Kidby] %e passage # -# 6 new passages added for 3.7 +# 6 new passages added for 5.0 # # p. 16 %passage 8 @@ -7013,7 +7013,7 @@ I'll promise to pretend that humans can think, too." [The Amazing Maurice and His Educated Rodents, by Terry Pratchett] %e passage # -# 4 new passages added for 3.7 +# 4 new passages added for 5.0 # # p. 19 (passage begins mid-paragraph) %passage 11 @@ -7687,7 +7687,7 @@ girls of seven are magnetically attracted to the color pink. [Monstrous Regiment, by Terry Pratchett] %e passage # -# 4 new passages added for 3.7 +# 4 new passages added for 5.0 # # p. 114 (the sergeant known as "Threeparts" is a bit daft, but Polly does # eventually walk with Death--not die, just walk and talk with him) @@ -7894,7 +7894,7 @@ is 'me'?" [A Hat Full of Sky, by Terry Pratchett] %e passage # -# 2 new passages added for 3.7 +# 2 new passages added for 5.0 # # p. 124 (first speaker is Tiffany) %passage 12 diff --git a/doc/fixes5-0-0.txt b/doc/fixes5-0-0.txt index aa27902a7..e269c7171 100644 --- a/doc/fixes5-0-0.txt +++ b/doc/fixes5-0-0.txt @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1649 $ $NHDT-Date: 1777000050 2026/04/23 19:07:30 $ +NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.1649 $ $NHDT-Date: 1777000050 2026/04/23 19:07:30 $ General Fixes and Modified Features ----------------------------------- @@ -1451,7 +1451,7 @@ some theft messages by nymphs force "she", others use default monster naming if a nymph stole worn armor and got killed (perhaps by pet) before hero's next turn, feedback would be "You finish taking off your suit." regardless of the type of armor being taken off -when setting an option interactively [via O or 3.7's mO], if the particular +when setting an option interactively [via O or 5.0's mO], if the particular option uses a prompt to get a line of input (for compounds: 'fruit', 'scores', most numeric ones), input was treated as a comma-separated list of option[:value] rather than just the new value of that option @@ -1605,7 +1605,7 @@ when starting a new game as a monk, newsym(0,0) was being called (adjabil -> incorporate a fix to prevent segfault due to rolling boulder trap -Fixes to 3.7.0-x General Problems Exposed Via git Repository +Fixes to 5.0.0-x General Problems Exposed Via git Repository ------------------------------------------------------------ incrementing EDITLEVEL to invalidate incompatible save files was not working as intended because VERSION_COMPATIBILITY was defined as 3.7.0-0 and up @@ -2236,7 +2236,7 @@ teleportation traps no longer teleport you on levels made temporarily no-teleport by the presence of a monster -Fixes to 3.7.0-x Platform and/or Interface Problems Exposed Via git Repository +Fixes to 5.0.0-x Platform and/or Interface Problems Exposed Via git Repository ------------------------------------------------------------------------------ curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/sound/wav/README b/sound/wav/README index 00a0321ae..e7917b36c 100644 --- a/sound/wav/README +++ b/sound/wav/README @@ -13,7 +13,7 @@ Those had been removed in commit 217671e00f626e53d314757b4687950466efb360 in May 2019, at the same time built-in speaker support was removed. Some of those original files have been converted into wav files starting -with NetHack 3.7. The pitch variation versions offer a chance for very +with NetHack 5.0. The pitch variation versions offer a chance for very simple tune playback on platforms that offer a basic play-sound function call, which many do. There is no need to manipulate the underlying sounds with those, although sound library interfaces may certainly produce diff --git a/sound/wav/attributions.txt b/sound/wav/attributions.txt index 1a90447e1..43ce7b051 100644 --- a/sound/wav/attributions.txt +++ b/sound/wav/attributions.txt @@ -1,4 +1,4 @@ -/* NetHack 3.7 attributions.txt $NHDT-Date: 1652831519 2022/05/17 23:51:59 $ +/* NetHack 5.0 attributions.txt $NHDT-Date: 1652831519 2022/05/17 23:51:59 $ Attributions and credits and modifications for sounds used are listed below. From d6f8241ac1d2a79e2cee69c6246b7dfbe6f1fa57 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 12:34:02 -0400 Subject: [PATCH 045/702] update dat src include... --- dat/data.base | 6 +++--- dat/dungeon.lua | 2 +- dat/history | 2 +- dat/tribute | 4 ++-- include/amiconf.h | 2 +- include/global.h | 2 +- include/monsters.h | 12 ++++++------ include/objects.h | 2 +- include/patchlevel.h | 4 ++-- include/tradstdc.h | 2 +- include/vmsconf.h | 2 +- include/winprocs.h | 6 +++--- include/wintype.h | 2 +- src/attrib.c | 2 +- src/dig.c | 2 +- src/display.c | 4 ++-- src/do.c | 6 +++--- src/do_name.c | 2 +- src/do_wear.c | 2 +- src/dokick.c | 4 ++-- src/dothrow.c | 2 +- src/eat.c | 12 ++++++------ src/hack.c | 4 ++-- src/mdlib.c | 2 +- src/mhitu.c | 2 +- src/mkobj.c | 6 +++--- src/monmove.c | 4 ++-- src/objnam.c | 4 ++-- src/options.c | 2 +- src/pager.c | 2 +- src/potion.c | 2 +- src/read.c | 4 ++-- src/rumors.c | 2 +- src/sfstruct.c | 2 +- src/shk.c | 4 ++-- src/sit.c | 2 +- src/sounds.c | 2 +- src/timeout.c | 2 +- src/trap.c | 6 +++--- src/uhitm.c | 4 ++-- src/windows.c | 2 +- src/wizard.c | 2 +- src/worm.c | 2 +- src/zap.c | 6 +++--- util/makedefs.c | 2 +- util/sfctool.c | 2 +- 46 files changed, 78 insertions(+), 78 deletions(-) diff --git a/dat/data.base b/dat/data.base index b051cc62a..ec1e5306e 100644 --- a/dat/data.base +++ b/dat/data.base @@ -1384,7 +1384,7 @@ dispater Wealth". It refers to the wealth of precious stone below the earth. [ Encyclopedia Mythica, ed. M.F. Lindemans ] -# 3.7; monster adapted from slash'em based on an AD&D Monster Manual entry; +# 5.0; monster adapted from slash'em based on an AD&D Monster Manual entry; # slash'em lacked a description so this entry has been created from scratch; # the puma comparison is how the AD&D monster is described (except that # that creature has six legs and two tentacles!) but the actual monster's @@ -2048,7 +2048,7 @@ gem or rock same as for jewels: it is always the false ones that look the most real, the most brilliant. [ Salvador Dali ] -# 3.7; monster derived from slash'em which lacked a description so this +# 5.0; monster derived from slash'em which lacked a description so this # entry has been created from scratch genetic engineer These very odd people have mastered the ability to insert gene @@ -2418,7 +2418,7 @@ helm of caution A helmet which confers the "warning" property, sensing the strength of threats posed by unseen hostile creatures. # note: this quotation had "high of steel" but we're going to cheat--it is -# now deliberately mistranslated as "high of crystal" to match nethack 3.7's +# now deliberately mistranslated as "high of crystal" to match nethack 5.0's # change to helm of brilliance and become more useful to players. # PR #1109 wanted to change it to be for all helms but being covered with # gems and gold is not appropriate for ordinary helmets (plus it states that diff --git a/dat/dungeon.lua b/dat/dungeon.lua index d90eb9214..7550d1317 100644 --- a/dat/dungeon.lua +++ b/dat/dungeon.lua @@ -185,7 +185,7 @@ dungeon = { }, { name = "minend", --- 3.7.0: minend changed to no-bones to simplify achievement tracking +-- 5.0.0: minend changed to no-bones to simplify achievement tracking -- bonetag = "E" base = -1, nlevels = 3 diff --git a/dat/history b/dat/history index 3d4b6e9bc..850ceab79 100644 --- a/dat/history +++ b/dat/history @@ -1,4 +1,4 @@ -NetHack History file for release 3.7 +NetHack History file for release 5.0 Behold, mortal, the origins of NetHack... diff --git a/dat/tribute b/dat/tribute index f58dc89ac..a2944d7d6 100644 --- a/dat/tribute +++ b/dat/tribute @@ -2464,7 +2464,7 @@ Dibbler removed his cigar. [Moving Pictures, by Terry Pratchett] %e passage # -# New for 3.7 - these are worthy but 16 passages are already more than enough. +# New for 5.0 - these are worthy but 16 passages are already more than enough. #-# #-# p. 304 #-%passage 17 @@ -4138,7 +4138,7 @@ followed by long periods of being dead." [Interesting Times, by Terry Pratchett] %e passage # -# 3 new passages for 3.7 +# 3 new passages for 5.0 # # p. 45 %passage 11 diff --git a/include/amiconf.h b/include/amiconf.h index 682ed3a2b..17b03c2eb 100644 --- a/include/amiconf.h +++ b/include/amiconf.h @@ -53,7 +53,7 @@ typedef long off_t; /* data librarian defs */ #define DLBFILE "nhdat" /* main library */ -/* nhsdat sound library not used in 3.7 */ +/* nhsdat sound library not used in 5.0 */ #undef DLBFILE2 #ifndef CROSS_TO_AMIGA diff --git a/include/global.h b/include/global.h index 88168858e..ef3497ea4 100644 --- a/include/global.h +++ b/include/global.h @@ -422,7 +422,7 @@ extern struct nomakedefs_s nomakedefs; #include "color.h" /* - * Version 3.7.x has aspirations of portable file formats. We + * Version 5.0.x has aspirations of portable file formats. We * make a distinction between MAIL functionality and MAIL_STRUCTURES * so that the underlying structures are consistent, whether MAIL is * defined or not. diff --git a/include/monsters.h b/include/monsters.h index 01bc6cc3a..202411128 100644 --- a/include/monsters.h +++ b/include/monsters.h @@ -972,7 +972,7 @@ 8, CLR_RED, SCORPION), /* * trappers, lurkers, &c - * Note: prior to 3.7, these were defined to do AD_DGST damage, + * Note: prior to 5.0, these were defined to do AD_DGST damage, * but they don't swallow their victims into their stomachs and * digest, they enfold and crush or suffocate. * The Monster Manual states that someone engulfed by a trapper @@ -2031,7 +2031,7 @@ | M1_OMNIVORE, M2_STRONG, 0, 13, HI_GOLD, GOLDEN_NAGA), - /* 3.7: guardian naga used to have three attacks: bite, spit, hug + /* 5.0: guardian naga used to have three attacks: bite, spit, hug but in order for the hug to succeed the two preceding attacks had to have hit, and it's not possible to both bite and spit, hence the hug never hit; change to spit, bite, touch, hug; if the bite @@ -2132,7 +2132,7 @@ M1_HUMANOID | M1_OMNIVORE | M1_POIS | M1_TPORT, M2_HOSTILE, M3_INFRAVISIBLE, 9, CLR_CYAN, QUANTUM_MECHANIC), - /* 3.7: from slash'em, to expand Q class; hit polymorphs target */ + /* 5.0: from slash'em, to expand Q class; hit polymorphs target */ MON(NAM("genetic engineer"), S_QUANTMECH, LVL(12, 12, 3, 10, 0), (G_GENO | 1), A(ATTK(AT_CLAW, AD_POLY, 1, 4), @@ -2695,7 +2695,7 @@ | M2_SHAPESHIFTER, M3_INFRAVISIBLE, 11, HI_DOMESTIC, DOPPELGANGER), - /* 3.7: shopkeepers used to have speed 18, but if/when they were + /* 5.0: shopkeepers used to have speed 18, but if/when they were hasted they always got 2 moves per turn and had a tendency to move away from blocking the door and then move right back; since they might start with a potion of speed and drink that as soon as the @@ -2925,7 +2925,7 @@ #define SEDUCTION_ATTACKS_NO \ A(ATTK(AT_CLAW, AD_PHYS, 1, 3), ATTK(AT_CLAW, AD_PHYS, 1, 3), \ ATTK(AT_BITE, AD_DRLI, 2, 6), NO_ATTK, NO_ATTK, NO_ATTK) - /* incubus and succubus; prior to 3.7, succubus and incubus were + /* incubus and succubus; prior to 5.0, succubus and incubus were distinct monsters; "amorous demon" is considered to be a temporary placeholder but may be here to stay... */ MON(NAMS("incubus", "succubus", "amorous demon"), S_DEMON, @@ -3195,7 +3195,7 @@ /* * sea monsters * - * 3.7: all the fish except kraken used to specify M1_SLITHY, presumably + * 5.0: all the fish except kraken used to specify M1_SLITHY, presumably * cloned from giant eel. Using "slither" to describe their movement * wasn't appropriate. Unfortunately, locomotion() isn't able to choose * "swim" as their movement description because it is only passed a diff --git a/include/objects.h b/include/objects.h index d9ae062c5..78d1c9d7a 100644 --- a/include/objects.h +++ b/include/objects.h @@ -224,7 +224,7 @@ WEAPON("stiletto", NoDes, /* 3.6: worm teeth and crysknives now stack; when a stack of teeth is enchanted at once, they fuse into one crysknife; when a stack of crysknives drops, the whole stack reverts to teeth */ -/* 3.7: change crysknife from MINERAL to BONE and worm tooth from 0 to BONE */ +/* 5.0: change crysknife from MINERAL to BONE and worm tooth from 0 to BONE */ WEAPON("worm tooth", NoDes, 1, 1, 0, 0, 20, 2, 2, 2, 0, 0, P_KNIFE, BONE, CLR_WHITE, WORM_TOOTH), diff --git a/include/patchlevel.h b/include/patchlevel.h index 68e54dbf5..ca88656ca 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -62,7 +62,7 @@ /*#define VERSION_COMPATIBILITY 0x03070000L*/ /****************************************************************************/ -/* Version 3.7.x */ +/* Version 5.0.x */ /* * NetHack 5.0.0, @@ -95,7 +95,7 @@ * the official 3.6.6 binary was built. * windows: switch from using keyhandling dll's to incorporating the three * variations (default, ray, 340) in sys/winnt/nttty.c - * curses: cherry-picked selectsaved code from 3.7 for menu of save files + * curses: cherry-picked selectsaved code from 5.0 for menu of save files * NetHackW: fix delayed rendering of cursor when using farlook */ diff --git a/include/tradstdc.h b/include/tradstdc.h index f4532aeba..a202c0c7b 100644 --- a/include/tradstdc.h +++ b/include/tradstdc.h @@ -157,7 +157,7 @@ typedef const char *vA; [nethack's core doesn't use VA_NEXT() so doesn't use VA_SHIFT() either, and this definition is just retained for completeness. lev_comp does use VA_NEXT(), but it passes all 'argX' arguments. - Note: as of 3.7.0, lev_comp doesn't exist anymore.] + Note: as of 5.0.0, lev_comp doesn't exist anymore.] */ #define VA_SHIFT() \ (arg1 = arg2, arg2 = arg3, arg3 = arg4, arg4 = arg5, arg5 = arg6, \ diff --git a/include/vmsconf.h b/include/vmsconf.h index 4fb77d24c..a4d1eb724 100644 --- a/include/vmsconf.h +++ b/include/vmsconf.h @@ -164,7 +164,7 @@ PANICTRACE_GDB=2 #at conclusion of panic, show a call traceback and then */ /* This used to be force-defined for VMS in topten.c, but with - * the global variable consolidation into g in 3.7, it has to be + * the global variable consolidation into g in 5.0, it has to be * defined here so that decl.h includes the field in g. */ #define UPDATE_RECORD_IN_PLACE diff --git a/include/winprocs.h b/include/winprocs.h index bbf97c91d..2797e7128 100644 --- a/include/winprocs.h +++ b/include/winprocs.h @@ -127,7 +127,7 @@ extern #define display_file (*windowprocs.win_display_file) #define start_menu (*windowprocs.win_start_menu) #define end_menu (*windowprocs.win_end_menu) -/* 3.7: There are real add_menu() and select_menu in the core now. +/* 5.0: There are real add_menu() and select_menu in the core now. * add_menu does some common activities, such as menu_colors. * select_menu does some before and after activities. * add_menu() and select_menu() are in windows.c @@ -151,7 +151,7 @@ extern #define nh_poskey (*windowprocs.win_nh_poskey) #define nhbell (*windowprocs.win_nhbell) #define nh_doprev_message (*windowprocs.win_doprev_message) -/* 3.7: There is a real getlin() in the core now, which does +/* 5.0: There is a real getlin() in the core now, which does * some before and after activities. * [alternative fix for menu search via ':'.] * getlin() is in windows.c @@ -297,7 +297,7 @@ struct wc_Opt { /* Macro for the currently active Window Port whose function pointers have been loaded */ #if 0 -/* 3.7 The string comparison version isn't used anymore */ +/* 5.0 The string comparison version isn't used anymore */ #define WINDOWPORT(wn) \ (windowprocs.name && !strncmpi((#wn), windowprocs.name, strlen((#wn)))) #endif diff --git a/include/wintype.h b/include/wintype.h index 3ec938d30..5d17e4147 100644 --- a/include/wintype.h +++ b/include/wintype.h @@ -167,7 +167,7 @@ typedef struct glyphinfo { #define MENU_ITEMFLAGS_SKIPINVERT 0x0000002U #define MENU_ITEMFLAGS_SKIPMENUCOLORS 0x0000004U -/* 3.7+ enhanced menu flags that not all window ports are likely to +/* 5.0+ enhanced menu flags that not all window ports are likely to * support initially. * * As behavior and appearance modification flags are added, the various diff --git a/src/attrib.c b/src/attrib.c index cd33557ad..27a0ad5d4 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -683,7 +683,7 @@ rnd_attr(void) { int i, x = rn2(100); - /* 3.7: the x -= ... calculation used to have an off by 1 error that + /* 5.0: the x -= ... calculation used to have an off by 1 error that resulted in the values being biased toward Str and away from Cha */ for (i = 0; i < A_MAX; ++i) if ((x -= gu.urole.attrdist[i]) < 0) diff --git a/src/dig.c b/src/dig.c index df27bb73d..0b69d6028 100644 --- a/src/dig.c +++ b/src/dig.c @@ -455,7 +455,7 @@ dig(void) } else if (digtyp == DIGTYP_BOULDER && (obj = sobj_at(BOULDER, dpx, dpy)) != 0) { fracture_rock(obj); - /*[3.7: this probably isn't necessary anymore]*/ + /*[5.0: this probably isn't necessary anymore]*/ if ((bobj = sobj_at(BOULDER, dpx, dpy)) != 0) { /* another boulder here, restack it to the top */ obj_extract_self(bobj); diff --git a/src/display.c b/src/display.c index 437d74154..2632b3fa8 100644 --- a/src/display.c +++ b/src/display.c @@ -2214,7 +2214,7 @@ flush_screen(int cursor_on_u) glyph_info bkglyphinfo = nul_glyphinfo; int bkglyph; - /* 3.7: don't update map, status, or perm_invent during save/restore */ + /* 5.0: don't update map, status, or perm_invent during save/restore */ if (_suppress_map_output()) return; @@ -3453,7 +3453,7 @@ t_warn(struct rm *lev) static const char warn_str[] = "wall_angle: %s: case %d: seenv = 0x%x"; const char *wname; - /* 3.7: non-T_wall cases added after shop repair (via breaching a wall, + /* 5.0: non-T_wall cases added after shop repair (via breaching a wall, using locking magic to put a door there, then unlocking the door; D_CLOSED carried over to the wall) triggered warning for "unknown" */ switch (lev->typ) { diff --git a/src/do.c b/src/do.c index ae39a0137..6d8747924 100644 --- a/src/do.c +++ b/src/do.c @@ -77,7 +77,7 @@ boulder_hits_pool( levl[rx][ry].typ = ROOM, levl[rx][ry].flags = 0; recalc_block_point(rx, ry); } - /* 3.7: normally DEADMONSTER() is used when traversing the fmon + /* 5.0: normally DEADMONSTER() is used when traversing the fmon list--dead monsters usually aren't still at specific map locations; however, if ice melts causing a giant to drown, that giant would still be on the map when it drops inventory; @@ -1533,7 +1533,7 @@ goto_level( * -2 5.21 4.17 0.0 * -3 2.08 0.0 0.0 * - * 3.7.0: the chance for the "mysterious force" to kick in goes down + * 5.0.0: the chance for the "mysterious force" to kick in goes down * as it kicks in, starting at 25% per climb attempt and dropping off * gradually but substantially. The drop off is greater when hero is * sent down farther so benefits lawfuls more than chaotics this time. @@ -2438,7 +2438,7 @@ set_wounded_legs(long side, int timex) set_itimeout(&HWounded_legs, (long) timex); /* the leg being wounded and its timeout might differ from one attack to the next, but we don't track the legs separately; - 3.7: both legs will ultimately heal together; this used to use + 5.0: both legs will ultimately heal together; this used to use direct assignment instead of bitwise-OR so getting wounded in one leg mysteriously healed the other */ EWounded_legs |= side; diff --git a/src/do_name.c b/src/do_name.c index 0fd1e98a0..81f8853be 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -433,7 +433,7 @@ objtyp_is_callable(int i) switch(objects[i].oc_class) { case AMULET_CLASS: - /* 3.7: calling these used to be allowed but that enabled the + /* 5.0: calling these used to be allowed but that enabled the player to tell whether two unID'd amulets of yendor were both fake or one was real by calling them distinct names and then checking discoveries to see whether first name was replaced diff --git a/src/do_wear.c b/src/do_wear.c index 6b24c426a..b92d7e31a 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -2501,7 +2501,7 @@ find_ac(void) uac -= u.ublessed; uac -= u.uspellprot; - /* put a cap on armor class [3.7: was +127,-128, now reduced to +/- 99 */ + /* put a cap on armor class [5.0: was +127,-128, now reduced to +/- 99 */ if (abs(uac) > AC_MAX) uac = sgn(uac) * AC_MAX; diff --git a/src/dokick.c b/src/dokick.c index 4e531a016..601810839 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -601,13 +601,13 @@ really_kick_object(coordxy x, coordxy y) || closed_door(x + u.dx, y + u.dy)) range = 1; - /* 3.7: this used to skip 'costly' handling if kickedobj->no_charge + /* 5.0: this used to skip 'costly' handling if kickedobj->no_charge was set but that optimization could result in no_charge staying set for objects kicked out of the shop */ shkp = find_objowner(gk.kickedobj, x, y); costly = (shkp && (costly_spot(x, y) || (costly_adjacent(shkp, x, y) && gk.kickedobj->unpaid))); - /* 3.7: give feedback about the item being kicked; some follow-on + /* 5.0: give feedback about the item being kicked; some follow-on messages refer to "it" */ Norep("You kick %s.", !isgold ? singular(gk.kickedobj, doname) : doname(gk.kickedobj)); diff --git a/src/dothrow.c b/src/dothrow.c index c63ad6412..8bc204915 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -2082,7 +2082,7 @@ thitmonst( /* throwing real gems to co-aligned unicorns boosts Luck, to cross-aligned unicorns changes Luck by random amount; throwing worthless glass doesn't affect Luck but doesn't anger them; - 3.7: treat rocks and gray stones as attacks rather than like glass + 5.0: treat rocks and gray stones as attacks rather than like glass and also treat gems or glass shot via sling as attacks */ if (obj->oclass == GEM_CLASS && is_unicorn(mon->data) && objects[obj->otyp].oc_material != MINERAL && !uslinging()) { diff --git a/src/eat.c b/src/eat.c index 179b44b0b..cde86e137 100644 --- a/src/eat.c +++ b/src/eat.c @@ -839,7 +839,7 @@ cprefx(int pm) /* life-saving needed to reach here */ exercise(A_WIS, FALSE); /* revive an actual corpse; can't do that if it was a tin; - 3.7: this used to assume that such tins were impossible but + 5.0: this used to assume that such tins were impossible but they can be wished for in wizard mode; they can't make it to normal play though because bones creation empties them */ if (svc.context.victual.piece /* Null for tins */ @@ -1891,7 +1891,7 @@ eatcorpse(struct obj *otmp) rotted -= 2L; } - /* 3.7: globs don't become tainted, they shrink away */ + /* 5.0: globs don't become tainted, they shrink away */ if (!glob && !stoneable && !slimeable && rotted > 5L) { boolean cannibal = maybe_cannibal(mnum, FALSE); @@ -2632,7 +2632,7 @@ edibility_prompts(struct obj *otmp) */ char buf[BUFSZ], foodsmell[BUFSZ], it_or_they[QBUFSZ]; - /* 3.7: decaying globs don't become tainted anymore; in 3.6, they did */ + /* 5.0: decaying globs don't become tainted anymore; in 3.6, they did */ boolean cadaver = (otmp->otyp == CORPSE), stoneorslime = FALSE; int material = objects[otmp->otyp].oc_material, mnum = otmp->corpsenm; long rotted = 0L; @@ -3179,7 +3179,7 @@ gethungry(void) u.uhunger--; /* ordinary food consumption */ /* - * 3.7: trigger is randomized instead of (moves % N). Makes + * 5.0: trigger is randomized instead of (moves % N). Makes * ring juggling (using the 'time' option to see the turn counter * in order to time swapping of a pair of rings of slow digestion, * wearing one on one hand, then putting on the other and taking @@ -3209,7 +3209,7 @@ gethungry(void) * Possessing the real Amulet imposes a separate hunger penalty * from wearing an amulet (so gets a double penalty when worn). * - * 3.7.0: Worn meat rings don't affect hunger. + * 5.0.0: Worn meat rings don't affect hunger. * Same with worn cheap plastic imitation of the Amulet. * +0 ring of protection might do something (enhanced "magical * cancellation") if hero doesn't have protection from some @@ -3222,7 +3222,7 @@ gethungry(void) */ switch (accessorytime) { /* note: use even cases among 0..19 only */ case 0: - /* 3.7: if not wearing a ring of slow digestion, obtaining + /* 5.0: if not wearing a ring of slow digestion, obtaining that property from worn armor (white dragon scales/mail) causes the armor to burn nutrition; since it's not actually a ring, we don't check for it on the ring diff --git a/src/hack.c b/src/hack.c index 3017eb2c7..78ca5579d 100644 --- a/src/hack.c +++ b/src/hack.c @@ -2298,7 +2298,7 @@ domove_fight_empty(coordxy x, coordxy y) } else if (solid) { /* glyph might indicate unseen terrain if hero is blind; unlike searching, this won't reveal what that terrain is; - 3.7: used to say "solid rock" for STONE, but that made it be + 5.0: used to say "solid rock" for STONE, but that made it be different from unmapped walls outside of rooms (and was wrong on arboreal levels) */ if (levl[x][y].seenv || IS_STWALL(levl[x][y].typ) @@ -2310,7 +2310,7 @@ domove_fight_empty(coordxy x, coordxy y) } /* note: 'solid' is misleadingly named and catches pools of water and lava as well as rock and walls; - 3.7: furniture too */ + 5.0: furniture too */ } else { Strcpy(buf, "thin air"); } diff --git a/src/mdlib.c b/src/mdlib.c index 873922fc1..8c8b0cd8d 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -93,7 +93,7 @@ staticfn void opt_out_words(char *, int *) NONNULLPTRS; staticfn void build_savebones_compat_string(void); static int idxopttext, done_runtime_opt_init_once = 0; -#define MAXOPT 60 /* 3.7: currently 40 lines get inserted into opttext[] */ +#define MAXOPT 60 /* 5.0: currently 40 lines get inserted into opttext[] */ static char *opttext[MAXOPT] = { 0 }; #define STOREOPTTEXT(line) \ ((void) ((idxopttext < MAXOPT) \ diff --git a/src/mhitu.c b/src/mhitu.c index 05e6f38aa..947e47fa4 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1312,7 +1312,7 @@ gulpmu(struct monst *mtmp, struct attack *mattk) place_monster(mtmp, u.ux, u.uy); set_ustuck(mtmp); newsym(mtmp->mx, mtmp->my); - /* 3.7: dismount for all engulfers, not just for purple worms */ + /* 5.0: dismount for all engulfers, not just for purple worms */ if (u.usteed) { char buf[BUFSZ]; diff --git a/src/mkobj.c b/src/mkobj.c index 650b1502f..93f047d14 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -957,7 +957,7 @@ mksobj_init(struct obj **obj, boolean artif) /* for emphasis; glob quantity is always 1 and weight varies when other globs coalesce with it or this one shrinks */ otmp->quan = 1L; - /* 3.7: globs in 3.6.x left owt as 0 and let weight() fix + /* 5.0: globs in 3.6.x left owt as 0 and let weight() fix that up during 'obj->owt = weight(obj)' below, but now we initialize glob->owt explicitly so weight() doesn't need to perform any fix up and returns glob->owt as-is */ @@ -1899,7 +1899,7 @@ weight(struct obj *obj) manage glob->owt and there is nothing for weight() to do except return the current value as-is */ if (obj->globby) { - /* 3.7: in 3.6.x this checked for owt==0 and then used + /* 5.0: in 3.6.x this checked for owt==0 and then used owt as-is when non-zero or objects[].oc_weight if zero; we don't do that anymore because it confused calculating the weight of a container when a glob inside shrank down @@ -1964,7 +1964,7 @@ weight(struct obj *obj) } else if (obj->oclass == FOOD_CLASS && obj->oeaten) { return eaten_stat((int) obj->quan * wt, obj); } else if (obj->oclass == COIN_CLASS) { - /* 3.7: always weigh at least 1 unit; used to yield 0 for 1..49 */ + /* 5.0: always weigh at least 1 unit; used to yield 0 for 1..49 */ wt = (int) ((obj->quan + 50L) / 100L); return max(wt, 1); } else if (obj->otyp == HEAVY_IRON_BALL && obj->owt != 0) { diff --git a/src/monmove.c b/src/monmove.c index 1c6242896..a21716e06 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1784,13 +1784,13 @@ m_move(struct monst *mtmp, int after) * attack it. */ if (intruder && intruder != mtmp - /* 3.7: this used to use 'dist2() < 2' which meant that intended + /* 5.0: this used to use 'dist2() < 2' which meant that intended attack was disallowed if they were adjacent diagonally */ && dist2(mtmp->mx, mtmp->my, tx, ty) <= 2) { gb.bhitpos.x = tx, gb.bhitpos.y = ty; gn.notonhead = (intruder->mx != tx || intruder->my != ty); covetousattack = mattackm(mtmp, intruder); - /* 3.7: this used to erroneously use '== 2' (M_ATTK_DEF_DIED) */ + /* 5.0: this used to erroneously use '== 2' (M_ATTK_DEF_DIED) */ if (covetousattack & M_ATTK_AGR_DIED) return MMOVE_DIED; mmoved = MMOVE_MOVED; diff --git a/src/objnam.c b/src/objnam.c index 032c6c0e6..f28367b5b 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -4106,9 +4106,9 @@ readobjnam_preparse(struct _readobjnam_data *d) break; d->gsize = 1; } else if (!strncmpi(d->bp, "medium ", l = 7)) { - /* 3.7: in 3.6, "medium" was only used during wishing and the + /* 5.0: in 3.6, "medium" was only used during wishing and the mid-size glob had no adjective when formatted, but as of - 3.7, "medium" has become an explicit part of the name for + 5.0, "medium" has become an explicit part of the name for combined globs of at least 5 individual ones (owt >= 100) and less than 15 (owt < 300) */ d->gsize = 2; diff --git a/src/options.c b/src/options.c index cdf29ed20..18edcfa96 100644 --- a/src/options.c +++ b/src/options.c @@ -3679,7 +3679,7 @@ optfn_scores( if ((op = string_for_opt(opts, FALSE)) == empty_optstr) return optn_err; - /* 3.7: earlier versions left old values for unspecified arguments + /* 5.0: earlier versions left old values for unspecified arguments if player's scores:foo option only specified some of the three; in particular, attempting to use 'scores:own' rather than 'scores:0 top/0 around/own' didn't work as intended */ diff --git a/src/pager.c b/src/pager.c index 4c40594de..9e399fff3 100644 --- a/src/pager.c +++ b/src/pager.c @@ -556,7 +556,7 @@ look_at_monster( /* describe a pool location's contents; might return a static buffer so caller should use it or copy it before calling waterbody_name() again - [3.7: moved here from mkmaze.c] */ + [5.0: moved here from mkmaze.c] */ const char * waterbody_name(coordxy x, coordxy y) { diff --git a/src/potion.c b/src/potion.c index f289c1d7b..fc2d629a3 100644 --- a/src/potion.c +++ b/src/potion.c @@ -582,7 +582,7 @@ dodrink(void) * was no longer dealing with an inventory item. Unwearing * the current potion is intended to keep it in inventory.] * - * 3.7: switch back to relying on useup() unless the object is + * 5.0: switch back to relying on useup() unless the object is * actually worn. Otherwise drinking a stack of unpaid potions * one by one in a shop makes each one a separate used-up item * for 'Ix' invent display and for itemized shop billing instead diff --git a/src/read.c b/src/read.c index 967824df2..614466e7f 100644 --- a/src/read.c +++ b/src/read.c @@ -1505,7 +1505,7 @@ seffect_remove_curse(struct obj **sobjp) if (scursed) { pline_The("scroll disintegrates."); } else { - /* 3.7: this used to use a straight + /* 5.0: this used to use a straight for (obj = invent; obj; obj = obj->nobj) {} traversal, but for the confused case, secondary weapon might become cursed and be dropped, moving it from the invent chain @@ -3212,7 +3212,7 @@ create_particular_parse( d->which = name_to_mon(bufp, &gender_name_var); /* * With the introduction of male and female monster names - * in 3.7, preserve that detail. + * in 5.0, preserve that detail. * * If d->fem is already set to MALE or FEMALE at this juncture, it means * one of those terms was explicitly specified. diff --git a/src/rumors.c b/src/rumors.c index 9d4ada852..e33dea512 100644 --- a/src/rumors.c +++ b/src/rumors.c @@ -303,7 +303,7 @@ rumor_check(void) DISABLE_WARNING_FORMAT_NONLITERAL -/* 3.7: augments rumors_check(); test 'engrave' or 'epitaph' or 'bogusmon' */ +/* 5.0: augments rumors_check(); test 'engrave' or 'epitaph' or 'bogusmon' */ staticfn void others_check( const char *ftype, /* header: "{Engravings|Epitaphs|Bogus monsters}:" */ diff --git a/src/sfstruct.c b/src/sfstruct.c index a58de75eb..268e2e3ac 100644 --- a/src/sfstruct.c +++ b/src/sfstruct.c @@ -308,7 +308,7 @@ static long floc = 0L; /* * historical structlevel savefile writing and reading routines follow. - * These were moved here from save.c and restore.c between 3.6.3 and 3.7.0. + * These were moved here from save.c and restore.c between 3.6.3 and 5.0.0,. */ staticfn int getidx(int, int); diff --git a/src/shk.c b/src/shk.c index 4180ec670..09b184fd9 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1525,7 +1525,7 @@ cheapest_item(int ibillct, Bill *ibill) long gmin = ibill[0].cost; /* - * 3.7: old version didn't determine cheapest item correctly if it + * 5.0: old version didn't determine cheapest item correctly if it * was either the partly used or partly intact portion of a partially * used stack. Rather than modify it to use bp_to_obj() in order to * obtain quanities for every entry on eshkp->bill_p[], switch to @@ -2107,7 +2107,7 @@ pay_billed_items( } while (via_menu); /* - * 3.7: this used to make two passes through eshkp->bill_p[], + * 5.0: this used to make two passes through eshkp->bill_p[], * the first for used up items and the second for unpaid ones. * Items which were partly used were processed on both passes. * diff --git a/src/sit.c b/src/sit.c index 5857dec28..fa88f35ec 100644 --- a/src/sit.c +++ b/src/sit.c @@ -214,7 +214,7 @@ throne_sit_effect(void) You_feel("somehow out of place..."); } - /* 3.7: when the random chance for removal is hit, ask for confirmation + /* 5.0: when the random chance for removal is hit, ask for confirmation if in wizard mode, and remove the throne even if hero was teleported away from it. [This used to remove a throne at hero's current location if there happened to be one, so for the teleport case that diff --git a/src/sounds.c b/src/sounds.c index d7652d62a..7089610d0 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1080,7 +1080,7 @@ domonnoise(struct monst *mtmp) } else switch (monsndx(ptr)) { case PM_HOBBIT: - /* 3.7: the 'complains' message used to be given if the + /* 5.0: the 'complains' message used to be given if the hobbit's current hit points were at 10 below max or less, but their max is normally less than 10 so it would almost never occur */ diff --git a/src/timeout.c b/src/timeout.c index 83d1aaf9a..75064b5d1 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -961,7 +961,7 @@ fall_asleep(int how_long, boolean wakeup_msg) if (wakeup_msg && gm.multi == how_long) { /* caller can follow with a direct call to Hear_again() if there's a need to override this when wakeup_msg is true */ - /* 3.7: how_long is negative so wasn't actually incrementing the + /* 5.0: how_long is negative so wasn't actually incrementing the deafness timeout when it used to be passed as-is */ incr_itimeout(&HDeaf, abs(how_long)); disp.botl = TRUE; diff --git a/src/trap.c b/src/trap.c index 7915cee7c..8b40d3faf 100644 --- a/src/trap.c +++ b/src/trap.c @@ -5311,7 +5311,7 @@ untrap_prob( chance = 1; /* else chance stays 3 */ } else if (!webmaker(u.umonst->data)) { - chance = 7; /* 3.7: used to be 30 */ + chance = 7; /* 5.0: used to be 30 */ } } if (Confusion || Hallucination) @@ -5996,7 +5996,7 @@ untrap( } /* end if */ if (boxcnt) { - /* 3.7: this used to allow searching for traps on multiple + /* 5.0: this used to allow searching for traps on multiple containers on the same move and needed to keep track of whether any had been found but not attempted to untrap; now at most one per move may be checked and we only @@ -6855,7 +6855,7 @@ lava_effects(void) /* Check whether we should burn away boots *first* so we know whether to * make the player sink into the lava. Assumption: water walking only * comes from boots. - * (3.7: that assumption is no longer true, but having boots be the first + * (5.0: that assumption is no longer true, but having boots be the first * thing to come into contact with lava makes sense.) */ if (uarmf && (uarmf->in_use diff --git a/src/uhitm.c b/src/uhitm.c index c5a18a000..8affa9699 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2202,7 +2202,7 @@ steal_it(struct monst *mdef, struct attack *mattk) if (ustealo) { /* we will be taking everything */ char heshe[20]; - /* 3.7: this uses hero's base gender rather than nymph femininity + /* 5.0: this uses hero's base gender rather than nymph femininity but was using hardcoded pronouns She/her for target monster; switch to dynamic pronoun */ if (gender(mdef) == (int) u.mfemale @@ -4228,7 +4228,7 @@ mhitm_ad_ston( pline("%s seems to grimace.", Monnam(magr)); } /* - * 3.7: New moon is no longer overridden by carrying a + * 5.0: New moon is no longer overridden by carrying a * lizard corpse. Having the moon's impact on terrestrial * activity be affected by carrying a dead critter felt * silly. diff --git a/src/windows.c b/src/windows.c index b6c61f2c9..d196ecd50 100644 --- a/src/windows.c +++ b/src/windows.c @@ -1186,7 +1186,7 @@ dump_fmtstr( else Strcpy(tmpbuf, "{current date+time}"); break; - case 'v': /* version, eg. "3.7.0-0" */ + case 'v': /* version, eg. "5.0.0,-0" */ Sprintf(tmpbuf, "%s", version_string(verbuf, sizeof verbuf)); break; case 'u': /* UID */ diff --git a/src/wizard.c b/src/wizard.c index 16dc405c9..b09e3a150 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -620,7 +620,7 @@ nasty(struct monst *summoner) for (i = rnd(tmp); i > 0 && count < MAXNASTIES; --i) { /* Of the 44 nasties[], 10 are lawful, 14 are chaotic, * and 20 are neutral. [These numbers are up date for - * 3.7.0; the ones in the next paragraph are not....] + * 5.0.0; the ones in the next paragraph are not....] * * Neutral caster, used for late-game harassment, * has 18/42 chance to stop the inner loop on each diff --git a/src/worm.c b/src/worm.c index 23e908942..c5a12fd12 100644 --- a/src/worm.c +++ b/src/worm.c @@ -224,7 +224,7 @@ worm_move(struct monst *worm) wgrowtime[wnum] = svm.moves + rnd(5); } else { int mmove = mcalcmove(worm, FALSE), - /* prior to 3.7.0, next-grow increment was 3..17 but since + /* prior to 5.0.0,, next-grow increment was 3..17 but since it got checked every 4th turn when the speed 3 worm got to move, it was effectively 0..5; also, its usage was 'wgrowtime += incr', so often 'wgrowtime' would be diff --git a/src/zap.c b/src/zap.c index e26c22fcf..c3d53a4fe 100644 --- a/src/zap.c +++ b/src/zap.c @@ -198,7 +198,7 @@ bhitm(struct monst *mtmp, struct obj *otmp) seemimic(mtmp); shieldeff(mtmp->mx, mtmp->my); pline("Boing!"); - /* 3.7: used to 'break' to avoid setting learn_it here */ + /* 5.0: used to 'break' to avoid setting learn_it here */ } else if (u.uswallow || rnd(20) < 10 + find_mac(mtmp)) { if (disguised_mimic) seemimic(mtmp); @@ -1865,7 +1865,7 @@ poly_obj(struct obj *obj, int id) while (otmp->otyp == SPE_POLYMORPH) otmp->otyp = rnd_class(svb.bases[SPBOOK_CLASS], SPE_BLANK_PAPER); /* reduce spellbook abuse; non-blank books degrade; - 3.7: novels don't use spestudied so shouldn't degrade to blank + 5.0: novels don't use spestudied so shouldn't degrade to blank (but don't force spestudied to zero for them since a non-zero value could get passed along to a future polymorph) */ if (otmp->otyp != SPE_BLANK_PAPER && otmp->otyp != SPE_NOVEL) { @@ -4547,7 +4547,7 @@ zhitu( } /* - * 3.7: when fatal, this used to yield "Killed by ." without any + * 5.0: when fatal, this used to yield "Killed by ." without any * information about who was responsible. Now 'buzzer' is used to try * to supply "zapped/cast/breathed by [imitating ]." * diff --git a/util/makedefs.c b/util/makedefs.c index a19a5ae5e..796bd9788 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1590,7 +1590,7 @@ do_oracles(void) /* Read one line from input, up to and including the next newline * character. Returns a pointer to the heap-allocated string, or a * null pointer if no characters were read. - * 3.7: redone to use nethack's alloc() rather than libc's malloc() + * 5.0: redone to use nethack's alloc() rather than libc's malloc() * and realloc(). */ static char * diff --git a/util/sfctool.c b/util/sfctool.c index 8d395cbbe..2c7dc63ef 100644 --- a/util/sfctool.c +++ b/util/sfctool.c @@ -195,7 +195,7 @@ main(int argc, char *argv[]) exit(EXIT_FAILURE); sz = strlen(folderbuf); (void) snprintf(eos(folderbuf), sizeof folderbuf - sz, - "\\AppData\\Local\\NetHack\\3.7\\"); + "\\AppData\\Local\\NetHack\\5.0\\"); // initoptions_init(); // This allows OPTIONS in syscf on Windows. set_default_prefix_locations(argv[0]); #endif From 0e10f8285613571adacba136ae383b00679279c9 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 12:42:38 -0400 Subject: [PATCH 046/702] update sys win --- sys/windows/console.rc | 4 ++-- win/Qt/Qt-issues.txt | 2 +- win/Qt/qt_inv.cpp | 2 +- win/Qt/qt_menu.cpp | 2 +- win/Qt/qt_svsel.cpp | 2 +- win/Qt/qt_win.cpp | 2 +- win/X11/winstat.c | 4 ++-- win/curses/Readme.txt | 2 +- win/curses/cursmain.c | 2 +- win/win32/NetHackW.rc | 10 +++++----- win/win32/nethack.rc | 10 +++++----- 11 files changed, 21 insertions(+), 21 deletions(-) diff --git a/sys/windows/console.rc b/sys/windows/console.rc index 3b87de6c6..81a21b2ca 100644 --- a/sys/windows/console.rc +++ b/sys/windows/console.rc @@ -12,8 +12,8 @@ // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,7,0,0 - PRODUCTVERSION 3,7,0,0 + FILEVERSION 5,0,0,0 + PRODUCTVERSION 5,0,0,0 FILEFLAGSMASK 0x1fL #ifdef _DEBUG FILEFLAGS 0x9L diff --git a/win/Qt/Qt-issues.txt b/win/Qt/Qt-issues.txt index 1bac3106c..1de8b9c8c 100644 --- a/win/Qt/Qt-issues.txt +++ b/win/Qt/Qt-issues.txt @@ -43,7 +43,7 @@ ESC and maybe also initiate quitting. Map column #0, which the core reserves for its own purposes and isn't intended to be displayed, is displayed (as blank terrain). -3.7 status conditions haven't been implemented. +5.0 status conditions haven't been implemented. 3.6 status conditions (Stone, Slime, Strngl, Deaf, Lev, Fly, Ride) have been implemented but need icon artwork (one 40x40 tile for each). diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index 01cf2039f..76bc06cff 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -172,7 +172,7 @@ void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*) // W wielded two-handed weapon // X wielded secondary weapon // - // 3.7: use a different layout (also different legend for it, above): + // 5.0: use a different layout (also different legend for it, above): // invert so grid is facing player, with right hand on screen left; // show gloves in only one slot; // move alternate weapon to former right hand glove slot; diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index 93a9064f6..f469597e2 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -1133,7 +1133,7 @@ void NetHackQtTextWindow::Display(bool block UNUSED) void NetHackQtTextWindow::PutStr(int attr UNUSED, const QString& text) { #if 1 - // 3.7: Always render text windows with fixed-width font. The majority + // 5.0: Always render text windows with fixed-width font. The majority // of text files we'll ever display including ('license' and 'history') // happen to have some lines with four spaces anyway and/or they have // been pre-formatted to fit within less than 80 columns. For data.base diff --git a/win/Qt/qt_svsel.cpp b/win/Qt/qt_svsel.cpp index 882fabce7..f08c0aa25 100644 --- a/win/Qt/qt_svsel.cpp +++ b/win/Qt/qt_svsel.cpp @@ -6,7 +6,7 @@ // // Popup's layout: //---- -// NetHack 3.7.x (literal text w/ dynamic version number) +// NetHack 5.0.x (literal text w/ dynamic version number) // /----------------------\ (text to prevent multi-line comment warning) // | | // | | diff --git a/win/Qt/qt_win.cpp b/win/Qt/qt_win.cpp index 1f356399c..db66579f6 100644 --- a/win/Qt/qt_win.cpp +++ b/win/Qt/qt_win.cpp @@ -2,7 +2,7 @@ // Qt4 conversion copyright (c) Ray Chason, 2012-2014. // NetHack may be freely redistributed. See license for details. -// Qt Windowing interface for NetHack 3.7 +// Qt Windowing interface for NetHack 5.0 // // Copyright (C) 1996-2001 by Warwick W. Allison (warwick@troll.no) // diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 761dd93e9..0e6f79f94 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -1714,7 +1714,7 @@ update_val(struct X_status_value *attr_rec, long new_value) * it's being set to blank (where that item should be reset now instead * of showing highlighted blank until the next expiration check). * - * 3.7: highlight non-labelled 'name' items (conditions plus hunger + * 5.0: highlight non-labelled 'name' items (conditions plus hunger * and encumbrance) when they come On. For all conditions going Off, * or changing to not-hungry or not-encumbered, there's nothing to * highlight because the field becomes blank. @@ -2348,7 +2348,7 @@ init_column( * indicates the end of the column. The two numbers after that are used * to store widths that are calculated at run-time. * - * 3.7: changed so that all 6 columns have 8 rows, but a few entries + * 5.0: changed so that all 6 columns have 8 rows, but a few entries * are left blank <>. Exp-points, Score, and Time are optional depending * on run-time settings; Xp-level is replaced by Hit-Dice (and Exp-points * suppressed) when the hero is polymorphed. Title and Dungeon-Level span diff --git a/win/curses/Readme.txt b/win/curses/Readme.txt index a9ae0be7b..1cec52e6e 100644 --- a/win/curses/Readme.txt +++ b/win/curses/Readme.txt @@ -29,7 +29,7 @@ sys/unix/Install.unx. By default, the Makefile is setup to compile against ncurses. Edit Makefile.src if you wish to compile against a different curses library, such as PDCurses for SDL. See sys/unix/NewInstall.unx for more information about building -NetHack 3.7 and above. +NetHack 5.0 and above. Windows build instructions: diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 5060c3e85..1fe79fcc6 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -924,7 +924,7 @@ print_glyph(window, x, y, glyphinfo, bkglyphinfo) int ttychar; the character mapping for the original tty interface. Most or all window ports wanted and used this for various things so it is - provided in 3.7+ + provided in 5.0+ short int symidx; offset into syms array unsigned glyphflags; more detail about the entity diff --git a/win/win32/NetHackW.rc b/win/win32/NetHackW.rc index 7f4317b2b..d4d197d2f 100644 --- a/win/win32/NetHackW.rc +++ b/win/win32/NetHackW.rc @@ -334,8 +334,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,7,0,0 - PRODUCTVERSION 3,7,0,0 + FILEVERSION 5,0,0,0 + PRODUCTVERSION 5,0,0,0 FILEFLAGSMASK 0x1fL #ifdef _DEBUG FILEFLAGS 0x9L @@ -351,13 +351,13 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "NetHack for Windows - Graphical Interface" - VALUE "FileVersion", "3.7.0" + VALUE "FileVersion", "5.0.0" VALUE "InternalName", "NetHackW" - VALUE "LegalCopyright", "Copyright (C) 1985 - 2021. By Stichting Mathematisch Centrum and M. Stephenson. See license for details." + VALUE "LegalCopyright", "Copyright (C) 1985 - 2026. By Stichting Mathematisch Centrum and M. Stephenson. See license for details." VALUE "OriginalFilename", "NetHackW.exe" VALUE "PrivateBuild", "140606" VALUE "ProductName", "NetHack" - VALUE "ProductVersion", "3.7.0" + VALUE "ProductVersion", "5.0.0" END END BLOCK "VarFileInfo" diff --git a/win/win32/nethack.rc b/win/win32/nethack.rc index 6f14e3328..4c167d047 100644 --- a/win/win32/nethack.rc +++ b/win/win32/nethack.rc @@ -60,8 +60,8 @@ IDI_ICON1 ICON "nethack.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,7,0,0 - PRODUCTVERSION 3,7,0,0 + FILEVERSION 5,0,0,0 + PRODUCTVERSION 5,0,0,0 FILEFLAGSMASK 0x1fL #ifdef _DEBUG FILEFLAGS 0x9L @@ -77,12 +77,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "NetHack for Windows - TTY Interface" - VALUE "FileVersion", "3.7.0" + VALUE "FileVersion", "5.0.0" VALUE "InternalName", "NetHack" - VALUE "LegalCopyright", "Copyright (C) 1985 - 2021. By Stichting Mathematisch Centrum and M. Stephenson. See license for details." + VALUE "LegalCopyright", "Copyright (C) 1985 - 2026. By Stichting Mathematisch Centrum and M. Stephenson. See license for details." VALUE "OriginalFilename", "NetHack.exe" VALUE "ProductName", "NetHack" - VALUE "ProductVersion", "3.7.0" + VALUE "ProductVersion", "5.0.0" END END BLOCK "VarFileInfo" From 45f4c697a793035233596c773e7655ac78f21c23 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 12:54:44 -0400 Subject: [PATCH 047/702] miscellaneous --- outdated/sys/amiga/.gitattributes | 2 +- outdated/sys/atari/.gitattributes | 2 +- outdated/sys/be/.gitattributes | 2 +- outdated/sys/os2/.gitattributes | 2 +- outdated/sys/wince/.gitattributes | 2 +- outdated/sys/wince/ceinc/.gitattributes | 2 +- outdated/win/gem/.gitattributes | 2 +- outdated/win/gnome/.gitattributes | 2 +- src/files.c | 2 +- sys/windows/nethackrc.template | 12 ++++++------ 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/outdated/sys/amiga/.gitattributes b/outdated/sys/amiga/.gitattributes index cc4b3cd52..483f30202 100644 --- a/outdated/sys/amiga/.gitattributes +++ b/outdated/sys/amiga/.gitattributes @@ -1,2 +1,2 @@ *.p NHSUBST -* NH_filestag=(file%s_for_Amiga_versions_-_untested_for_3.7) +* NH_filestag=(file%s_for_Amiga_versions_-_untested_for_5.0) diff --git a/outdated/sys/atari/.gitattributes b/outdated/sys/atari/.gitattributes index db7b27210..b51126e53 100644 --- a/outdated/sys/atari/.gitattributes +++ b/outdated/sys/atari/.gitattributes @@ -1 +1 @@ -* NH_filestag=(file%s_for_Atari_version_-_untested_for_3.7) +* NH_filestag=(file%s_for_Atari_version_-_untested_for_5.0) diff --git a/outdated/sys/be/.gitattributes b/outdated/sys/be/.gitattributes index 38ec7931e..f7d41ab76 100644 --- a/outdated/sys/be/.gitattributes +++ b/outdated/sys/be/.gitattributes @@ -1 +1 @@ -* NH_filestag=(file%s_for_BeOS_version_-_untested_for_3.7) +* NH_filestag=(file%s_for_BeOS_version_-_untested_for_5.0) diff --git a/outdated/sys/os2/.gitattributes b/outdated/sys/os2/.gitattributes index 4041868ff..7859972d3 100644 --- a/outdated/sys/os2/.gitattributes +++ b/outdated/sys/os2/.gitattributes @@ -1,2 +1,2 @@ Makefile.* NHSUBST -* NH_filestag=(file%s_for_OS/2_version_-_untested_for_3.7) +* NH_filestag=(file%s_for_OS/2_version_-_untested_for_5.0) diff --git a/outdated/sys/wince/.gitattributes b/outdated/sys/wince/.gitattributes index 0742a1d02..340366cbb 100644 --- a/outdated/sys/wince/.gitattributes +++ b/outdated/sys/wince/.gitattributes @@ -1,4 +1,4 @@ *.ce NHSUBST *.mak NHSUBST *.bat NHSUBST -* NH_filestag=(file%s_for_Windows_CE_and_PocketPC_-_untested_for_3.7) +* NH_filestag=(file%s_for_Windows_CE_and_PocketPC_-_untested_for_5.0) diff --git a/outdated/sys/wince/ceinc/.gitattributes b/outdated/sys/wince/ceinc/.gitattributes index 26a22a17d..5a72c68fc 100644 --- a/outdated/sys/wince/ceinc/.gitattributes +++ b/outdated/sys/wince/ceinc/.gitattributes @@ -1 +1 @@ -* NH_filestag=(header_file%s_for_Windows_CE_and_PocketPC_-_untested_for_3.7) +* NH_filestag=(header_file%s_for_Windows_CE_and_PocketPC_-_untested_for_5.0) diff --git a/outdated/win/gem/.gitattributes b/outdated/win/gem/.gitattributes index 303f8dfcc..b78f4ea3d 100644 --- a/outdated/win/gem/.gitattributes +++ b/outdated/win/gem/.gitattributes @@ -1 +1 @@ -* NH_filestag=(file%s_for_GEM_versions_-_untested_for_3.7) +* NH_filestag=(file%s_for_GEM_versions_-_untested_for_5.0) diff --git a/outdated/win/gnome/.gitattributes b/outdated/win/gnome/.gitattributes index b5ad839b8..15f036561 100644 --- a/outdated/win/gnome/.gitattributes +++ b/outdated/win/gnome/.gitattributes @@ -1 +1 @@ -* NH_filestag=(file%s_for_GNOME_versions_-_untested_for_3.7) +* NH_filestag=(file%s_for_GNOME_versions_-_untested_for_5.0) diff --git a/src/files.c b/src/files.c index 3b9a02505..15a587e90 100644 --- a/src/files.c +++ b/src/files.c @@ -2103,7 +2103,7 @@ make_converted_name(const char *filename) size_t sz = strlen(folderbuf); Snprintf(eos(folderbuf), sizeof folderbuf - sz, - "\\AppData\\Local\\NetHack\\3.7\\"); + "\\AppData\\Local\\NetHack\\5.0\\"); dir = (const char *) folderbuf; } #endif /* UNIX || WIN32 */ diff --git a/sys/windows/nethackrc.template b/sys/windows/nethackrc.template index 0887fef41..8e2ce9c68 100644 --- a/sys/windows/nethackrc.template +++ b/sys/windows/nethackrc.template @@ -146,22 +146,22 @@ OPTIONS=hilite_pet,!toptenwin # point at must exist. NetHack will not create them for you. # # The location that documentation and helps files are placed -#HACKDIR=c:\User\USERNAME\NetHack\3.6 +#HACKDIR=c:\User\USERNAME\NetHack\5.0 # # The location that level files in progress are stored (writeable) -#LEVELDIR=c:\User\USERNAME\AppData\Local\NetHack\3.6 +#LEVELDIR=c:\User\USERNAME\AppData\Local\NetHack\5.0 # # The location where saved games are kept (writeable) -#SAVEDIR=c:\User\USERNAME\AppData\Local\NetHack\3.6 +#SAVEDIR=c:\User\USERNAME\AppData\Local\NetHack\5.0 # # The location that bones files are kept (writeable) -#BONESDIR=c:\ProgramData\NetHack\3.6 +#BONESDIR=c:\ProgramData\NetHack\5.0 # # The location that score files are kept (writeable) -#SCOREDIR=c:\ProgramData\NetHack\3.6 +#SCOREDIR=c:\ProgramData\NetHack\5.0 # # The location that file synchronization locks are stored (writeable) -#LOCKDIR=c:\ProgramData\NetHack\3.6 +#LOCKDIR=c:\ProgramData\NetHack\5.0 # # Finnish keyboards might need these modifications uncommented. From e39a7c31adeb0718baa3b7b2dd3201a5935cf70f Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sun, 26 Apr 2026 12:16:07 -0400 Subject: [PATCH 048/702] This is cron-daily v1-Apr-26-2026. 000files updated: Files --- Files | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Files b/Files index c968110bd..6b011c970 100644 --- a/Files +++ b/Files @@ -76,7 +76,7 @@ fixes3-2-2.txt fixes3-2-3.txt fixes3-3-0.txt fixes3-3-1.txt fixes3-4-0.txt fixes3-4-1.txt fixes3-4-2.txt fixes3-4-3.txt fixes3-5-0.txt fixes3-6-0.txt fixes3-6-1.txt fixes3-6-2.txt fixes3-6-3.txt fixes3-6-4.txt fixes3-6-5.txt fixes3-6-6.txt -fixes3-6-7.txt fixes3-7-0.txt fixesX-X-X.txt lua.adoc +fixes3-6-7.txt fixes5-0-0.txt fixesX-X-X.txt lua.adoc makedefs.6 makedefs.txt mn.7 mn.txt mnh.7 mnh.txt nethack.6 nethack.txt options.txt recover.6 recover.txt sound.txt @@ -351,11 +351,8 @@ random.c (Berkeley uudecode file, which may be used in build process of any version) uudecode.c -(file for MSDOS, OS/2, Amiga, and Atari versions - only MSDOS tested for 5.0) -pcmain.c - -(file for MSDOS, OS/2, and Atari versions - only MSDOS tested for 5.0) -NetHack.cnf pctty.c +(file for MSDOS, Amiga versions) +NetHack.cnf pcmain.c pctty.c (file for MSDOS, OS/2, and VMS versions) termcap @@ -363,7 +360,7 @@ termcap (file for VMS version) tclib.c -(files for MSDOS, OS/2 and Atari versions - only MSDOS tested for 5.0) +(files for MSDOS, Amiga versions) pcsys.c pcunix.c (files for OS/2 version - untested for 5.0) From 97f8ad10b4b0a3144f650c39b891d33dc95f2be6 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 13:21:18 -0400 Subject: [PATCH 049/702] more updates --- DEVEL/code_features.txt | 4 ++-- DEVEL/hooksdir/NHsubst | 4 ++-- Porting | 2 +- include/display.h | 6 +++--- include/patchlevel.h | 10 +++++----- include/sym.h | 2 +- src/.gitattributes | 2 +- src/light.c | 2 +- src/mhitm.c | 2 +- src/objnam.c | 2 +- src/pickup.c | 2 +- src/rumors.c | 2 +- src/version.c | 2 +- submodules/CHKSUMS | 2 +- util/mdgrep.pl | 6 +++--- win/win32/NetHackW.rc | 2 +- 16 files changed, 26 insertions(+), 26 deletions(-) diff --git a/DEVEL/code_features.txt b/DEVEL/code_features.txt index 6c7100096..1377515a8 100644 --- a/DEVEL/code_features.txt +++ b/DEVEL/code_features.txt @@ -1,4 +1,4 @@ -# NetHack 3.7 code_features.txt $NHDT-Date: 1596498264 2020/08/03 23:44:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ +# NetHack 5.0 code_features.txt $NHDT-Date: 1596498264 2020/08/03 23:44:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ # Copyright (c) 2015 by Michael Allison # NetHack may be freely redistributed. See license for details. @@ -115,7 +115,7 @@ and available to all NetHack source files. decl.c variable definitions are generally laid out in much the same order as their corresponding declarations in decl.h. -A new header file cstd.h was added to coincide with 3.7's switch to +A new header file cstd.h was added to coincide with 5.0's switch to C99. It contains calls to some C99 standard header files. =================== NEXT FEATURE ========================== diff --git a/DEVEL/hooksdir/NHsubst b/DEVEL/hooksdir/NHsubst index 0c7aeb067..93ce45fc0 100755 --- a/DEVEL/hooksdir/NHsubst +++ b/DEVEL/hooksdir/NHsubst @@ -392,9 +392,9 @@ $TEST-Branch: theirs $ TEST 8: <<< d1 -/* NetHack 3.7 objnam.c $TEST-Date$ $TEST-Branch$:$TEST-Revision$ */ +/* NetHack 5.0 objnam.c $TEST-Date$ $TEST-Branch$:$TEST-Revision$ */ === -/* NetHack 3.7 objnam.c $TEST-Date: 1426977394 2015/03/21 22:36:34 $ $TEST-Branch: master $:$TEST-Revision: 1.108 $ */ +/* NetHack 5.0 objnam.c $TEST-Date: 1426977394 2015/03/21 22:36:34 $ $TEST-Branch: master $:$TEST-Revision: 1.108 $ */ >>> d3 =for nhgitset NHsubst NetHack merge driver diff --git a/Porting b/Porting index 45aa1bfc5..d4310d363 100644 --- a/Porting +++ b/Porting @@ -1,4 +1,4 @@ - NetHack Porting Guidelines v 3.7 2023-04-23 + NetHack Porting Guidelines v 5.0 2023-04-23 1.0 Introduction diff --git a/include/display.h b/include/display.h index da8009f26..c5e361484 100644 --- a/include/display.h +++ b/include/display.h @@ -27,12 +27,12 @@ * Returns true if the hero can sense the given monster. This includes * monsters that are hiding or mimicking other monsters. * - * [3.7] Note: the map doesn't display any monsters when hero is swallowed + * [5.0] Note: the map doesn't display any monsters when hero is swallowed * (or display non-adjacent, non-submerged ones when hero is underwater), * so treat those situations as blocking telepathy, detection, and warning * even though conceptually they shouldn't do so. * - * [3.7 also] The macros whose name begins with an underscore have been + * [5.0 also] The macros whose name begins with an underscore have been * converted to functions in order to have compilers generate smaller code. * The retained underscore versions are still used in display.c but should * only be used in other situations if the function calls actually produce @@ -138,7 +138,7 @@ * creature in an apparently empty spot. * Infravision is not relevant; we assume that invisible monsters are also * invisible to infravision. - * [3.7: the macro definition erroneously started with 'mtmp->minvis' for + * [5.0: the macro definition erroneously started with 'mtmp->minvis' for * over 20 years. The one place it's used called it as knowninvisible(mtmp) * so worked by coincidence when there was no argument expansion involved * on the first line.] diff --git a/include/patchlevel.h b/include/patchlevel.h index ca88656ca..eef05f6da 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -7,8 +7,8 @@ #define PATCHLEVEL_H /* NetHack 5.0.x */ -#define VERSION_MAJOR 3 -#define VERSION_MINOR 7 +#define VERSION_MAJOR 5 +#define VERSION_MINOR 0 /* * PATCHLEVEL is updated for each release. */ @@ -17,7 +17,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 141 +#define EDITLEVEL 0 /* * Development status possibilities. @@ -30,7 +30,7 @@ /* * Development status of this NetHack version. */ -#define NH_DEVEL_STATUS NH_STATUS_WIP +#define NH_DEVEL_STATUS NH_STATUS_RELEASED #ifndef DEBUG /* allow tool chains to define without causing warnings */ #define DEBUG @@ -75,7 +75,7 @@ /* Patch 7, February 16, 2023 * * during engraving, spaces were counted instead of non-space (cherry-pick of - * 4e0a1e04 from NetHack-3.7) + * 4e0a1e04 from NetHack WIP) * avoid potential buffer overflow in append_str() * resolve missing dependency in NetHack.sln * code in include/tradstdc.h was trying to suppress warn_unused result by diff --git a/include/sym.h b/include/sym.h index d965ec2ff..6939a4943 100644 --- a/include/sym.h +++ b/include/sym.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 sym.h $NHDT-Date: $ $NHDT-Branch: $ $NHDT-Revision: $ */ +/* NetHack 5.0 sym.h $NHDT-Date: $ $NHDT-Branch: $ $NHDT-Revision: $ */ /* Copyright (c) 2016 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/.gitattributes b/src/.gitattributes index a618fdc82..1a6ae3089 100644 --- a/src/.gitattributes +++ b/src/.gitattributes @@ -16,4 +16,4 @@ qt_xcmd.moc NH_filesgentag=>qt_kde0.moc qt_yndlg.moc NH_filesgentag=>qt_kde0.moc tile.c NH_filesgentag=(file%s_optionally_generated_by_tilemap_at_compile_time) -monstr.c NH_filesgentag=(file%s_generated_by_makedefs_-m_but_unused_in_3.7) +monstr.c NH_filesgentag=(file%s_generated_by_makedefs_-m_but_unused_in_5.0) diff --git a/src/light.c b/src/light.c index a4a3c1862..d5fbf09c0 100644 --- a/src/light.c +++ b/src/light.c @@ -522,7 +522,7 @@ relink_light_sources(boolean ghostly) /* * Caveat: - * There has been at least one instance during to-be-3.7 development + * There has been at least one instance during to-be-5.0 development * where the light_base linked list ended up with a circular link. * If that happens, then once all the traversed elements have their * LSF_NEEDS_FIXUP flag cleared, the traversal attempt will run wild. diff --git a/src/mhitm.c b/src/mhitm.c index 1508937e9..41fd276de 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -919,7 +919,7 @@ gulpmm( * -> relmon() used to call remove_monster() for the dead * monster even when it wasn't the one on the map, so we * needed to put magr back after mdef was killed and removed - * from their shared spot. But now [3.7] relmon() calls + * from their shared spot. But now [5.0] relmon() calls * mon_leaving_level() and that checks whether the monster at * dying monster's coordinates is that dying monster and only * removes it when they match. So magr is still at mdef's diff --git a/src/objnam.c b/src/objnam.c index f28367b5b..8ec461019 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -780,7 +780,7 @@ xname_flags( doname() so we've added an external flag to request it */ Concat(buf, 0, "partly eaten "); } - if (obj->globby) { /* 3.7 added "medium" to replace no-prefix */ + if (obj->globby) { /* 5.0 added "medium" to replace no-prefix */ ConcatF2(buf, 0, "%s %s", (obj->owt <= 100) ? "small" : (obj->owt <= 300) ? "medium" : (obj->owt <= 500) ? "large" diff --git a/src/pickup.c b/src/pickup.c index cc2c9baec..b20b473ff 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -544,7 +544,7 @@ allow_category(struct obj *obj) * 1) object class (armor, potion, &c); * 2) unpaid shop item; * 3) bless/curse state (blessed, uncursed, cursed, BUC-unknown). - * Version 3.7 added a fourth: + * Version 5.0 added a fourth: * 4) 'novelty' ('P' for just picked up items). * When only one type is present, the situation is simple: * to be accepted, obj's status must match one of the entries. diff --git a/src/rumors.c b/src/rumors.c index e33dea512..22d3e3077 100644 --- a/src/rumors.c +++ b/src/rumors.c @@ -7,7 +7,7 @@ #include "dlb.h" /* [Note: this comment is fairly old, but still accurate for 3.1; - * it's no longer accurate for 3.7 but may still be of interest.] + * it's no longer accurate for 5.0 but may still be of interest.] * Rumors have been entirely rewritten to speed up the access. This is * essential when working from floppies. Using fseek() the way that's done * here means rumors following longer rumors are output more often than those diff --git a/src/version.c b/src/version.c index d3b6ecfc8..1958ae5ed 100644 --- a/src/version.c +++ b/src/version.c @@ -118,7 +118,7 @@ status_version(char *buf, size_t bufsz, boolean indent) #if 0 /* note: it's possible for branch name to be a prefix of game name but that's unlikely enough that we won't bother with it; having - branch "nethack-3.7" be a superset of game "nethack" seems like + branch "nethack-5.0" be a superset of game "nethack" seems like including both is redundant, but having branch "net" be a subset of game "nethack" doesn't feel that way; optimizing "net" out seems like it would be a mistake */ diff --git a/submodules/CHKSUMS b/submodules/CHKSUMS index c40043d77..94f84cb0d 100644 --- a/submodules/CHKSUMS +++ b/submodules/CHKSUMS @@ -1,5 +1,5 @@ # checksums for fetched submodules -# NetHack 3.7 CHKSUMS $NHDT-Date: 1693155877 2023/08/27 17:04:37 $ $NHDT-Branch: keni-luacksum $ +# NetHack 5.0 CHKSUMS $NHDT-Date: 1693155877 2023/08/27 17:04:37 $ $NHDT-Branch: keni-luacksum $ # check: # shasum -a 256 -c -s THISFILE < FILETOCHECK # generate: diff --git a/util/mdgrep.pl b/util/mdgrep.pl index 785a2c185..24dd3d0a8 100644 --- a/util/mdgrep.pl +++ b/util/mdgrep.pl @@ -1,5 +1,5 @@ #!perl -# NetHack 3.7 mdgrep.pl $NHDT-Date: 1710949914 2024/03/20 15:51:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ +# NetHack 5.0 mdgrep.pl $NHDT-Date: 1710949914 2024/03/20 15:51:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. @@ -61,7 +61,7 @@ $outfile = "mdgrep.h"; sub start_file { ($rev) = ('$NHDT-Revision: 1.26 $') =~ m/: (.*) .$/; my $date = '$NHDT-Date: 1710949915 2024/03/20 15:51:55 $'; - my $branch = '$NHDT-Branch: NetHack-3.7 $'; + my $branch = '$NHDT-Branch: NetHack-5.0 $'; my $revision = '$NHDT-Revision: 1.26 $'; open(OUT, ">$outfile") || die "open $outfile: $!"; # NB: Date and Revision below will be modified when mdgrep.h is written to @@ -69,7 +69,7 @@ sub start_file { # before generating mdgrep.h and committing that file). print OUT < // would execute it or typing another 'l' or 'L' would unhighlight the // currently highlit one and highlight the other. All other accelerators From 0bacd6fedf2578501ec2012da7bd591e2bde073a Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sun, 26 Apr 2026 13:16:08 -0400 Subject: [PATCH 050/702] This is cron-daily v1-Apr-26-2026. 000files updated: Files --- Files | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Files b/Files index 6b011c970..b1fe63024 100644 --- a/Files +++ b/Files @@ -132,17 +132,17 @@ mac-carbon.h mac-qt.h mac-term.h macconf.h macpopup.h mactty.h macwin.h mttypriv.h outdated/sys/amiga: -(files for Amiga versions - untested for 3.7) +(files for Amiga versions - untested for 5.0) Build.ami Install.ami Makefile.agc Makefile.ami NetHack.cnf ifchange mkdmake txt2iff.c xpm2iff.c outdated/sys/atari: -(files for Atari version - untested for 3.7) +(files for Atari version - untested for 5.0) Install.tos atarifnt.uue nethack.mnu setup.g tos.c unx2atar.sed outdated/sys/be: -(files for BeOS version - untested for 3.7) +(files for BeOS version - untested for 5.0) README bemain.c outdated/sys/mac: @@ -159,7 +159,7 @@ Makefile.BC Makefile.MSC SCHEMA35.MSC moveinit.pat ovlinit.c schema1.BC schema2.BC schema3.MSC outdated/sys/os2: -(files for OS/2 version - untested for 3.7) +(files for OS/2 version - untested for 5.0) Install.os2 Makefile.os2 nhpmico.uu os2.c outdated/sys/unix: @@ -182,7 +182,7 @@ outdated/sys/vms: lev_lex.h outdated/sys/wince: -(files for Windows CE and PocketPC - untested for 3.7) +(files for Windows CE and PocketPC - untested for 5.0) Install.ce bootstrp.mak celib.c cesetup.bat cesound.c defaults.nh keypad.uu menubar.uu mhaskyn.c mhaskyn.h mhcmd.c mhcmd.h mhcolor.c mhcolor.h mhdlg.c @@ -195,7 +195,7 @@ resource.h winMS.h winhack.c winhack.rc winhcksp.rc winmain.c outdated/sys/wince/ceinc: -(header files for Windows CE and PocketPC - untested for 3.7) +(header files for Windows CE and PocketPC - untested for 5.0) assert.h errno.h fcntl.h outdated/sys/wince/ceinc/sys: @@ -212,12 +212,12 @@ qt3tableview.cpp qt3tableview.h tileedit.cpp tileedit.h outdated/win/gem: -(files for GEM versions - untested for 3.7) +(files for GEM versions - untested for 5.0) Install.gem bitmfile.c gem_rsc.uu gem_rso.uu gr_rect.c gr_rect.h load_img.c tile2img.c title.uu wingem.c wingem1.c xpm2img.c outdated/win/gnome: -(files for GNOME versions - untested for 3.7) +(files for GNOME versions - untested for 5.0) README gn_xpms.h gnaskstr.c gnaskstr.h gnbind.c gnbind.h gnglyph.c gnglyph.h gnmain.c gnmain.h gnmap.c gnmap.h gnmenu.c gnmenu.h gnmesg.c gnmesg.h gnomeprv.h gnopts.c From a396ad1033032793b2dbd54bd0d551c319d35823 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 13:29:30 -0400 Subject: [PATCH 051/702] force new txt files in doc --- doc/makedefs.6 | 4 ++-- doc/nethack.6 | 4 ++-- doc/recover.6 | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/makedefs.6 b/doc/makedefs.6 index 5e24242fa..f33dc42e1 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -1,5 +1,5 @@ .\"DO NOT REMOVE NH_DATESUB .TH MAKEDEFS 6 "Date(%-d %B %Y)" Project(uc) -.TH MAKEDEFS 6 "25 December 2024" NETHACK +.TH MAKEDEFS 6 "26 April 2026" NETHACK .\"DO NOT REMOVE NH_DATESUB .ds Nd Date(%Y) .ds Nd 2024 .de NB @@ -8,7 +8,7 @@ .de NR .ds Nr \\$2 .. -.NB $NHDT-Branch: NetHack-3.7 $ +.NB $NHDT-Branch: NetHack-5 $ .NR $NHDT-Revision: 1.22 $ .\" groff and AT&T-descended troffs use different hyphenation patterns. .\" Don't hyphenate the last word on a page or column, or diff --git a/doc/nethack.6 b/doc/nethack.6 index 3605423ca..85b99c389 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -1,5 +1,5 @@ .\"DO NOT REMOVE NH_DATESUB .TH NETHACK 6 "Date(%-d %B %Y)" Project(uc) -.TH NETHACK 6 "25 December 2024" NETHACK +.TH NETHACK 6 "26 April 2026" NETHACK .\"DO NOT REMOVE NH_DATESUB .ds Nd Date(%Y) .ds Nd 2024 .de NB @@ -8,7 +8,7 @@ .de NR .ds Nr \\$2 .. -.NB $NHDT-Branch: NetHack-3.7 $ +.NB $NHDT-Branch: NetHack-5 $ .NR $NHDT-Revision: 1.31 $ .\" groff and AT&T-descended troffs use different hyphenation patterns. .\" Don't hyphenate the last word on a page or column, or diff --git a/doc/recover.6 b/doc/recover.6 index 3829760e9..90d56c8c9 100644 --- a/doc/recover.6 +++ b/doc/recover.6 @@ -1,5 +1,5 @@ .\"DO NOT REMOVE NH_DATESUB .TH RECOVER 6 "Date(%-d %B %Y)" Project(uc) -.TH RECOVER 6 "25 December 2024" NETHACK +.TH RECOVER 6 "26 April 2026" NETHACK .\"DO NOT REMOVE NH_DATESUB .ds Nd Date(%Y) .ds Nd 2024 .de NB @@ -8,7 +8,7 @@ .de NR .ds Nr \\$2 .. -.NB $NHDT-Branch: NetHack-3.7 $ +.NB $NHDT-Branch: NetHack-5 $ .NR $NHDT-Revision: 1.12 $ .\" groff and AT&T-descended troffs use different hyphenation patterns. .\" Don't hyphenate the last word on a page or column, or From 27fa906ebfb60d15948953a4e5367aa11aed455f Mon Sep 17 00:00:00 2001 From: nhkeni Date: Sun, 26 Apr 2026 18:01:10 -0400 Subject: [PATCH 052/702] update CRASHREPORTURL examples --- src/report.c | 4 ++-- sys/unix/sysconf | 4 ++-- sys/windows/sysconf.template | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/report.c b/src/report.c index 2ec645b44..e5f701287 100644 --- a/src/report.c +++ b/src/report.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 report.c $NHDT-Date: 1741406837 2025/03/07 20:07:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.16 $ */ +/* NetHack 5.0 report.c $NHDT-Date: 1777240823 2026/04/26 22:00:23 $ $NHDT-Branch: to500 $:$NHDT-Revision: 1.19 $ */ /* Copyright (c) Kenneth Lorber, Kensington, Maryland, 2024 */ /* NetHack may be freely redistributed. See license for details. */ @@ -295,7 +295,7 @@ submit_web_report(int cos, const char *msg, const char *why) char temp2[200]; int countpp = 0; /* pre and post traceback lines */ // URL loaded for creating reports to the NetHack DevTeam -// CRASHREPORTURL=https://nethack.org/links/cr-37BETA.html +// CRASHREPORTURL=https://nethack.org/links/cr-5.0.0.html if (!sysopt.crashreporturl) return FALSE; SWR_ADD(sysopt.crashreporturl); diff --git a/sys/unix/sysconf b/sys/unix/sysconf index 0e0cd3914..e960bd522 100644 --- a/sys/unix/sysconf +++ b/sys/unix/sysconf @@ -1,4 +1,4 @@ -# NetHack 5.0 sysconf $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.44 $ +# NetHack 5.0 sysconf $NHDT-Date: 1777240863 2026/04/26 22:01:03 $ $NHDT-Branch: to500 $:$NHDT-Revision: 1.47 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. # @@ -164,7 +164,7 @@ PANICTRACE_GDB=1 PANICTRACE_LIBC=2 # URL loaded for creating reports to the NetHack DevTeam -#CRASHREPORTURL=https://nethack.org/links/cr-37BETA.html +#CRASHREPORTURL=https://nethack.org/links/cr-5.0.0.html # 'portable_device_paths' is only supported for Windows. Starting with # 3.6.3, nethack on Windows treats the folder containing nethack.exe and diff --git a/sys/windows/sysconf.template b/sys/windows/sysconf.template index 3a4fea676..4b00865c3 100644 --- a/sys/windows/sysconf.template +++ b/sys/windows/sysconf.template @@ -127,4 +127,4 @@ HIDEUSAGE=1 #LOCKDIR=c:\ProgramData\NetHack\5.0 # URL loaded for creating reports to the NetHack DevTeam -#CRASHREPORTURL=https://nethack.org/links/cr-37BETA.html +#CRASHREPORTURL=https://nethack.org/links/cr-5.0.0.html From 8f7f9a8c46d73bc0344add9f95532903876aa323 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sun, 26 Apr 2026 14:16:09 -0400 Subject: [PATCH 053/702] This is cron-daily v1-Apr-26-2026. 005manpages updated: recover.txt --- doc/recover.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/recover.txt b/doc/recover.txt index e13d2995f..bfbc9f36a 100644 --- a/doc/recover.txt +++ b/doc/recover.txt @@ -74,9 +74,9 @@ BUGS COPYRIGHT This file is Copyright (C) Kenneth Lorber, 2024 for version - NetHack-3.7:1.12. NetHack may be freely redistributed. See license - for details. + NetHack-5:1.12. NetHack may be freely redistributed. See license for + details. -NETHACK 25 December 2024 RECOVER(6) +NETHACK 26 April 2026 RECOVER(6) From 226c773ca7c3a3df240a9935b379b6dcc75a5e94 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sun, 26 Apr 2026 14:16:09 -0400 Subject: [PATCH 054/702] This is cron-daily v1-Apr-26-2026. 005manpages updated: nethack.txt --- doc/nethack.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/nethack.txt b/doc/nethack.txt index ca120c3e0..cc9e5dffc 100644 --- a/doc/nethack.txt +++ b/doc/nethack.txt @@ -279,11 +279,11 @@ BUGS COPYRIGHT This file is Copyright (C) Robert Patrick Rankin, 2024 for version - NetHack-3.7:1.31. NetHack may be freely redistributed. See license - for details. + NetHack-5:1.31. NetHack may be freely redistributed. See license for + details. Dungeons & Dragons is a Trademark of Wizards of the Coast, Inc. -NETHACK 25 December 2024 NETHACK(6) +NETHACK 26 April 2026 NETHACK(6) From fae32c29d123257a96818f7dca7adba91cab05d2 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sun, 26 Apr 2026 14:16:09 -0400 Subject: [PATCH 055/702] This is cron-daily v1-Apr-26-2026. 005manpages updated: makedefs.txt --- doc/makedefs.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/makedefs.txt b/doc/makedefs.txt index 38a27f308..210ec0ca4 100644 --- a/doc/makedefs.txt +++ b/doc/makedefs.txt @@ -144,9 +144,9 @@ AUTHOR COPYRIGHT This file is Copyright (C) Kenneth Lorber, 2024 for version - NetHack-3.7:1.22. NetHack may be freely redistributed. See license - for details. + NetHack-5:1.22. NetHack may be freely redistributed. See license for + details. -NETHACK 25 December 2024 MAKEDEFS(6) +NETHACK 26 April 2026 MAKEDEFS(6) From bfc3eca4f4433c7ffad4a00ac18920f21d34634f Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sun, 26 Apr 2026 14:16:07 -0400 Subject: [PATCH 056/702] This is cron-daily v1-Apr-26-2026. 000files updated: Files --- Files | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Files b/Files index b1fe63024..f27c19b60 100644 --- a/Files +++ b/Files @@ -1,4 +1,4 @@ -This is a listing of all files in a full NetHack 3.7 distribution, organized +This is a listing of all files in a full NetHack 5.0 distribution, organized in their standard manner on a UNIX system. It indicates which files are necessary for which versions, so that you can tell which files may be deleted from or not transferred to your system if you wish. @@ -691,7 +691,7 @@ GNUmakefile Makefile qt_kde0.moc qt_main.moc qt_map.moc qt_menu.moc qt_msg.moc qt_plsel.moc qt_set.moc qt_stat.moc qt_xcmd.moc qt_yndlg.moc -(file generated by makedefs -m but unused in 3.7) +(file generated by makedefs -m but unused in 5.0) monstr.c (file optionally generated by tilemap at compile time) From 05b02c7b9b3db414b58210a07db34f68d9a01aa7 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 22:31:52 -0400 Subject: [PATCH 057/702] use newer Windows file routines on bones Also correct a double-open bug that resulted from earlier code removal. --- src/files.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/files.c b/src/files.c index 74f600ef2..a55616382 100644 --- a/src/files.c +++ b/src/files.c @@ -510,7 +510,7 @@ free_nhfile(NHFILE *nhfp) { if (nhfp) { init_nhfile(nhfp); - free(nhfp); + free((genericptr_t) nhfp); } } @@ -833,6 +833,9 @@ create_bonesfile(d_level *lev, char **bonesid, char errbuf[]) const char *file; NHFILE *nhfp = (NHFILE *) 0; int failed = 0; +#if defined(WIN32) + errno_t err; +#endif if (errbuf) *errbuf = '\0'; @@ -851,7 +854,7 @@ create_bonesfile(d_level *lev, char **bonesid, char errbuf[]) nhfp->style.binary = TRUE; nhfp->fnidx = historical; nhfp->fd = -1; - nhfp->fpdef = fopen(file, nhfp->style.binary ? WRBMODE : WRTMODE); + nhfp->fpdef = (FILE *) 0; if (nhfp->fpdef) { #ifdef SAVEFILE_DEBUGGING nhfp->fpdebug = fopen("create_bonesfile-debug.log", "a"); @@ -860,12 +863,16 @@ create_bonesfile(d_level *lev, char **bonesid, char errbuf[]) failed = errno; } if (nhfp->structlevel) { -#if defined(MICRO) || defined(WIN32) +#if defined(MICRO) /* Use O_TRUNC to force the file to be shortened if it already * exists and is currently longer. */ nhfp->fd = open(file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, FCMASK); +#elif defined(WIN32) + err = _sopen_s(&nhfp->fd, file, + O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, + _SH_DENYRW, _S_IREAD | _S_IWRITE); #else /* ?MICRO || WIN32 */ /* implies UNIX or MAC (MAC is for OS9 or earlier) */ #ifdef MAC @@ -931,6 +938,9 @@ open_bonesfile(d_level *lev, char **bonesid) { const char *fq_bones; NHFILE *nhfp = (NHFILE *) 0; +#if defined(WIN32) + errno_t err UNUSED; +#endif *bonesid = set_bonesfile_name(gb.bones, lev); fq_bones = fqname(gb.bones, BONESPREFIX, 0); @@ -938,6 +948,10 @@ open_bonesfile(d_level *lev, char **bonesid) nhfp = new_nhfile(); if (nhfp) { +#if defined(WIN32) && defined(DEBUG) + if (nhfp->fd >= 0) + impossible("bones file NHFILE * has odd fd (%d)", nhfp->fd); +#endif nhfp->structlevel = TRUE; nhfp->fieldlevel = FALSE; nhfp->ftype = NHF_BONESFILE; @@ -947,15 +961,18 @@ open_bonesfile(d_level *lev, char **bonesid) nhfp->style.binary = (sysopt.bonesformat[0] != exportascii); nhfp->fnidx = sysopt.bonesformat[0]; nhfp->fd = -1; - nhfp->fpdef = fopen(fq_bones, nhfp->style.binary ? RDBMODE : RDTMODE); + nhfp->fpdef = (FILE *) 0; if (nhfp->fpdef) { #ifdef SAVEFILE_DEBUGGING nhfp->fpdebug = fopen("open_bonesfile-debug.log", "a"); #endif } if (nhfp->structlevel) { -#ifdef MAC +#if defined(MAC) nhfp->fd = macopen(fq_bones, O_RDONLY | O_BINARY, BONE_TYPE); +#elif defined(WIN32) + err = _sopen_s(&nhfp->fd, fq_bones, _O_RDONLY | _O_BINARY, + _SH_DENYRW, _S_IREAD | _S_IWRITE); #else nhfp->fd = open(fq_bones, O_RDONLY | O_BINARY, 0); #endif From 291972d0389cc24265975523b04072c3d81845c8 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 26 Apr 2026 22:58:26 -0400 Subject: [PATCH 058/702] wizmode wizshowuuid to view the game's NHUUID --- include/extern.h | 1 + src/cmd.c | 2 ++ src/wizcmds.c | 7 +++++++ 3 files changed, 10 insertions(+) diff --git a/include/extern.h b/include/extern.h index d17497325..0550b63b8 100644 --- a/include/extern.h +++ b/include/extern.h @@ -3889,6 +3889,7 @@ extern void wizcustom_callback(winid win, int glyphnum, char *id); extern int wiz_display_macros(void); extern int wiz_mon_diff(void); extern int wiz_objprobs(void); +extern int wiz_show_nhuuid(void); #endif extern void sanity_check(void); diff --git a/src/cmd.c b/src/cmd.c index 93edbe4b9..c1ef88b1d 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1989,6 +1989,8 @@ struct ext_func_tab extcmdlist[] = { wiz_rumor_check, IFBURIED | AUTOCOMPLETE | WIZMODECMD, NULL }, { '\0', "wizseenv", "show map locations' seen vectors", wiz_show_seenv, IFBURIED | AUTOCOMPLETE | WIZMODECMD, NULL }, + { '\0', "wizshownhuuid", "show NHUUID for this game", + wiz_show_nhuuid, AUTOCOMPLETE | WIZMODECMD, NULL }, { '\0', "wizsmell", "smell monster", wiz_smell, IFBURIED | AUTOCOMPLETE | WIZMODECMD, NULL }, { '\0', "wiztelekinesis", "telekinesis", diff --git a/src/wizcmds.c b/src/wizcmds.c index 0bee2da86..c4c89f750 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -1777,6 +1777,13 @@ wiz_display_macros(void) return ECMD_OK; } +/* the #wizshownhuuid command */ +int +wiz_show_nhuuid(void) +{ + pline("The NHUUID for this game is { %s }.", svn.nhuuid); +} + /* the #wizmondiff command */ int wiz_mon_diff(void) From e0e87b0aa429519db2b617a9567f4df3a6994841 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 26 Apr 2026 20:47:22 -0700 Subject: [PATCH 059/702] update X11/nh32icon and nh56icon Updated and previewed with the X11 bitmap program but not with nethack itself. --- win/X11/nh32icon | 8 ++++---- win/X11/nh56icon | 23 ++++++++++++----------- win/X11/nh72icon | 2 +- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/win/X11/nh32icon b/win/X11/nh32icon index cdacc920b..0174d49c8 100644 --- a/win/X11/nh32icon +++ b/win/X11/nh32icon @@ -1,5 +1,5 @@ -/* NetHack 3.7 nh32icon $NHDT-Date: 1597001766 2020/08/09 19:36:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ -/* Copyright (C) 1993,1995,2015 by Robert Patrick Rankin */ +/* NetHack 3.7 nh32icon $NHDT-Date: 1777289114 2026/04/27 03:25:14 $ $NHDT-Branch: to500 $:$NHDT-Revision: 1.13 $ */ +/* Copyright (C) 1993,1995,2015,2026 by Robert Patrick Rankin */ /* NetHack may be freely redistributed. See license for details. */ /* 32x32 X11 icon for NetHack. */ @@ -10,8 +10,8 @@ static unsigned char nh32icon_bits[] = { 0xff, 0x7f, 0xfe, 0xff, 0x01, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x40, 0x82, 0x21, 0x25, 0xc0, 0x83, 0x61, 0x25, 0x80, 0x81, 0xe1, 0x3d, 0x80, 0x81, 0xa1, 0x25, 0x80, 0x81, 0x21, 0x25, 0x80, 0x81, 0x01, 0x00, 0xe0, 0x87, - 0x71, 0x78, 0x90, 0x89, 0x81, 0x40, 0x80, 0x81, 0x61, 0x20, 0x80, 0x81, - 0x81, 0x10, 0x80, 0x81, 0x71, 0x12, 0x84, 0x81, 0x03, 0x00, 0x8a, 0xc1, + 0x71, 0x30, 0x90, 0x89, 0x11, 0x48, 0x80, 0x81, 0x61, 0x48, 0x80, 0x81, + 0x81, 0x48, 0x80, 0x81, 0x71, 0x32, 0x84, 0x81, 0x03, 0x00, 0x8a, 0xc1, 0x02, 0x00, 0x84, 0x41, 0x32, 0x67, 0x80, 0x41, 0xf3, 0x7f, 0x80, 0xc1, 0xf1, 0x7f, 0x84, 0x81, 0x71, 0x77, 0x8a, 0x81, 0xb1, 0x68, 0x84, 0x81, 0x71, 0x77, 0x80, 0x81, 0x71, 0x77, 0x80, 0x81, 0xb1, 0x68, 0x84, 0x81, diff --git a/win/X11/nh56icon b/win/X11/nh56icon index 5de4aa8bf..f5c372b2e 100644 --- a/win/X11/nh56icon +++ b/win/X11/nh56icon @@ -1,5 +1,6 @@ -/* NetHack 3.7 nh56icon $NHDT-Date: 1597001767 2020/08/09 19:36:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ -/* Copyright (c) 1993,1995,2015 by M. Stephenson */ +/* NetHack 5.0 nh56icon $NHDT-Date: 1777289257 2026/04/27 03:27:37 $ $N +HDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ */ +/* Copyright (c) 1993,1995,2015,2026 by M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ /* 56x56 X11 icon for NetHack. */ @@ -15,28 +16,28 @@ static unsigned char nh56icon_bits[] = { 0x3e, 0x00, 0xc0, 0x03, 0x00, 0xf8, 0x55, 0x3f, 0x00, 0xc0, 0x23, 0x22, 0xfc, 0xc7, 0x7f, 0x88, 0xc8, 0x43, 0x10, 0xfc, 0xd7, 0x7f, 0x10, 0xc4, 0x03, 0x07, 0xfe, 0xc7, 0xff, 0xc0, 0xc1, 0x83, 0x0d, 0xfe, 0xd7, 0xff, - 0x60, 0xc3, 0xa3, 0x28, 0xfe, 0xc7, 0xff, 0x28, 0xca, 0x83, 0x0d, 0xfe, + 0x60, 0xc3, 0xa3, 0x28, 0xfe, 0xc7, 0xff, 0x28, 0xca, 0x82, 0x0d, 0xfe, 0xd7, 0xff, 0x60, 0xc3, 0x03, 0x07, 0xfe, 0xc7, 0xff, 0xc0, 0xc1, 0x43, 0x10, 0xfc, 0xd7, 0x7f, 0x10, 0xc4, 0x23, 0x22, 0xfc, 0xc7, 0x7f, 0x88, 0xc8, 0x03, 0x00, 0xf8, 0x55, 0x3f, 0x00, 0xc0, 0x03, 0x00, 0xf8, 0x44, 0x3e, 0x00, 0xc0, 0x03, 0x00, 0x78, 0x54, 0x3c, 0x00, 0xc0, 0x03, 0x00, - 0x30, 0x6c, 0x18, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x6c, 0x00, 0x00, 0xc0, + 0x30, 0x6c, 0x18, 0x00, 0xc0, 0x03, 0x04, 0x00, 0x6c, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, - 0xc0, 0x43, 0x10, 0x21, 0x38, 0x70, 0xe0, 0xc3, 0xc3, 0x10, 0x21, 0x38, - 0x88, 0x00, 0xc2, 0xc3, 0x10, 0x21, 0x38, 0x80, 0x00, 0xc2, 0x43, 0x11, - 0x21, 0x38, 0x80, 0x00, 0xc1, 0x43, 0x12, 0x3f, 0x38, 0x70, 0x00, 0xc1, - 0x43, 0x12, 0x21, 0x38, 0x80, 0x80, 0xc0, 0x43, 0x14, 0x21, 0x38, 0x80, - 0x80, 0xc0, 0x43, 0x18, 0x21, 0x38, 0x80, 0x40, 0xc0, 0x43, 0x18, 0x21, - 0x38, 0x88, 0x4c, 0xc0, 0x43, 0x10, 0x21, 0x38, 0x70, 0x4c, 0xc0, 0x03, + 0xc0, 0x43, 0x10, 0x21, 0x38, 0xf8, 0xc0, 0xc1, 0xc3, 0x10, 0x21, 0x38, + 0x08, 0x20, 0xc2, 0xc3, 0x10, 0x21, 0x38, 0x08, 0x20, 0xc2, 0x43, 0x11, + 0x21, 0x38, 0x08, 0x20, 0xc2, 0x43, 0x12, 0x3f, 0x38, 0x70, 0x20, 0xc2, + 0x43, 0x12, 0x21, 0x38, 0x80, 0x20, 0xc2, 0x43, 0x14, 0x21, 0x38, 0x80, + 0x20, 0xc2, 0x43, 0x18, 0x21, 0x38, 0x80, 0x20, 0xc2, 0x43, 0x18, 0x21, + 0x38, 0x88, 0x2c, 0xc2, 0x43, 0x10, 0x21, 0x38, 0x70, 0xcc, 0xc1, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0xfb, 0xff, 0xff, 0x39, 0xff, 0xff, 0xdf, 0x0b, 0x00, 0x80, 0x7c, 0x02, 0x00, 0xd0, 0x0b, 0x00, 0x80, 0xee, 0x02, 0x00, 0xd0, 0xfb, 0xff, 0xff, 0xd6, 0xfe, 0xff, 0xdf, 0x0b, 0x00, 0x80, 0xaa, 0x02, 0x00, 0xd0, 0x0b, 0x00, 0x80, 0x54, 0x02, 0x00, 0xd0, 0xfb, 0xff, 0xff, 0x39, 0xff, - 0xff, 0xdf, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, + 0xff, 0xdf, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; diff --git a/win/X11/nh72icon b/win/X11/nh72icon index 60043a5f2..3f1e28da7 100644 --- a/win/X11/nh72icon +++ b/win/X11/nh72icon @@ -1,4 +1,4 @@ -/* NetHack 3.7 nh72icon $NHDT-Date: 1596498370 2020/08/03 23:46:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 nh72icon $NHDT-Date: 1596498370 2020/08/03 23:46:10 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) 1993 by M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ From 9098c2142111e89876da1d89a59c8be572c57110 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 27 Apr 2026 10:22:07 +0300 Subject: [PATCH 060/702] wizshowuuid return value --- src/wizcmds.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wizcmds.c b/src/wizcmds.c index c4c89f750..2c8554a8a 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -1782,6 +1782,7 @@ int wiz_show_nhuuid(void) { pline("The NHUUID for this game is { %s }.", svn.nhuuid); + return ECMD_OK; } /* the #wizmondiff command */ From b7f66f972305b0ad9d0c5804057ce2b8e9847526 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 27 Apr 2026 14:50:01 -0400 Subject: [PATCH 061/702] fix an issue with internal recover (Windows) --- src/files.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/files.c b/src/files.c index a55616382..ad9c62ef6 100644 --- a/src/files.c +++ b/src/files.c @@ -660,8 +660,9 @@ create_levelfile(int lev, char errbuf[]) Sprintf(errbuf, "Cannot create file \"%s\" for level %d (errno %d).", gl.lock, lev, errno); -#if defined(MSDOS) - setmode(nhfp->fd, O_BINARY); +#if defined(MSDOS) || defined(WIN32) + if (nhfp->fd >= 0) + (void) setmode(nhfp->fd, O_BINARY); #endif } nhfp = viable_nhfile(nhfp); @@ -705,8 +706,9 @@ open_levelfile(int lev, char errbuf[]) Sprintf(errbuf, "Cannot open file \"%s\" for level %d (errno %d).", gl.lock, lev, errno); -#if defined(MSDOS) - setmode(nhfp->fd, O_BINARY); +#if defined(MSDOS) || defined(WIN32) + if (nhfp->fd >= 0) + (void) setmode(nhfp->fd, O_BINARY); #endif } nhfp = viable_nhfile(nhfp); @@ -883,8 +885,9 @@ create_bonesfile(d_level *lev, char **bonesid, char errbuf[]) #endif /* ?MICRO || WIN32 */ if (nhfp->fd < 0) failed = errno; -#if defined(MSDOS) - setmode(nhfp->fd, O_BINARY); +#if defined(MSDOS) || defined(WIN32) + if (nhfp->fd >= 0) + (void) setmode(nhfp->fd, O_BINARY); #endif } if (failed && errbuf) /* failure explanation */ @@ -976,8 +979,9 @@ open_bonesfile(d_level *lev, char **bonesid) #else nhfp->fd = open(fq_bones, O_RDONLY | O_BINARY, 0); #endif -#if defined(MSDOS) - setmode(nhfp->fd, O_BINARY); +#if defined(MSDOS) || defined(WIN32) + if (nhfp->fd >= 0) + (void) setmode(nhfp->fd, O_BINARY); #endif } } @@ -1188,8 +1192,8 @@ create_savefile(void) #endif #endif /* MICRO || WIN32 */ #if defined(MSDOS) || defined(WIN32) - if (nhfp->fd >= 0) - (void) setmode(nhfp->fd, O_BINARY); + if (nhfp->fd >= 0) + (void) setmode(nhfp->fd, O_BINARY); #endif } } @@ -2989,6 +2993,9 @@ recover_savefile(void) if (savewrite_failure) goto cleanup; + if (snhfp->structlevel) + bufoff(snhfp->fd); + /* TODO: this is not a single byte, so a big-endian byte swap * might be necessary here, if anyone is concerned about big-endian */ Sfo_int(snhfp, &pltmpsiz, "plname-size"); @@ -3041,6 +3048,8 @@ recover_savefile(void) } } } + if (snhfp->structlevel) + bufon(snhfp->fd); close_nhfile(snhfp); /* * We have a successful savefile! From a090ba90a10ac81ba7bbab5226fea7a130aa37fb Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 27 Apr 2026 19:22:04 -0400 Subject: [PATCH 062/702] add option idlecheckpoint New experimental option This requires platform support to be useful. Currently an implementation for Windows TTY console is included. A Unix TTY implementation should be achievable I would think, but I haven't pursued that, at least not yet (contributions welcome). I'm not sure whether Qt or X11 interfaces offer a similar timeout capability.. How it works: When idlecheckpoint in on, if the wait for a new input is idle for 10 seconds (length of time to waite is controlled by IDLECHECKPOINT_WAIT_TIME #define in hack.h), save_currentstate() is called to bring everything up-to-date should a hangup or crash occur. The input wait then continues/resumes. The save_currentstate() call is only executed once per input request. --- include/config.h | 10 +++++ include/flag.h | 2 + include/hack.h | 7 ++++ include/optlist.h | 3 ++ include/windconf.h | 4 ++ src/options.c | 8 ++++ sys/windows/consoletty.c | 89 +++++++++++++++++++++++++--------------- sys/windows/windmain.c | 2 +- 8 files changed, 92 insertions(+), 33 deletions(-) diff --git a/include/config.h b/include/config.h index 5016c6702..b54d073de 100644 --- a/include/config.h +++ b/include/config.h @@ -681,6 +681,16 @@ typedef unsigned char uchar; #endif #endif +/* experimential; if the platform/window-port supports it; when the game has + * started to wait for player input, and the wait lasts longer than + * IDLECHECKPOINT_WAIT_TIME seconds (defined in hack.h or *conf.h), the game + * will perform an update to the checkpoint file. + * Currently has support in: + * WIN32CON + */ + +/* #define IDLECHECKPOINT */ + /* End of Section 4 */ #ifdef TTY_TILES_ESCCODES diff --git a/include/flag.h b/include/flag.h index f48b4693c..e125694b3 100644 --- a/include/flag.h +++ b/include/flag.h @@ -246,6 +246,8 @@ struct instance_flags { * to input becoming taken over); * True => enable fuzzer when entering moveloop */ boolean herecmd_menu; /* use menu when mouseclick on yourself */ + boolean idlecheckpoint; /* platform should perform a checkpoint update + * if waiting for input longer than 10 seconds */ boolean invis_goldsym; /* gold symbol is ' '? */ boolean in_lua; /* executing a lua script */ boolean lua_testing; /* doing lua tests */ diff --git a/include/hack.h b/include/hack.h index 1a8e07f14..19f543ac0 100644 --- a/include/hack.h +++ b/include/hack.h @@ -588,6 +588,13 @@ enum inventory_counts { /* 2023/11/30 invlet_max is not yet used anywhere */ }; +#ifndef IDLECHECKPOINT_WAIT_TIME +#define IDLECHECKPOINT_WAIT_TIME 10 /* seconds to wait before executing a checkpoint; + * always #define'd but only has meaning if + * IDLECHECKPOINT is defined. + */ +#endif + struct kinfo { struct kinfo *next; /* chain of delayed killers */ int id; /* uprop keys to ID a delayed killer */ diff --git a/include/optlist.h b/include/optlist.h index 4d3474a4b..e91fb0238 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -387,6 +387,9 @@ static int optfn_##a(int, int, boolean, char *, char *); Yes, Yes, No, No, NoAlias, "load IBMGraphics display symbols into symset") #endif + NHOPTB(idlecheckpoint, Advanced, 0, opt_in, set_in_game, + Off, Yes, No, No, NoAlias, &iflags.idlecheckpoint, Term_Off, + "update checkpoint file if input is idle for 10 seconds") #ifndef MAC NHOPTB(ignintr, Advanced, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &flags.ignintr, Term_False, diff --git a/include/windconf.h b/include/windconf.h index 81ad8baeb..5644451da 100644 --- a/include/windconf.h +++ b/include/windconf.h @@ -35,6 +35,10 @@ #define EARLY_CONFIGFILE_PASS #define TTY_PERM_INVENT +#ifdef WIN32CON +#define IDLECHECKPOINT +#endif + /* * ----------------------------------------------------------------- * The remaining code shouldn't need modification. diff --git a/src/options.c b/src/options.c index 786c5757e..4897e7e7f 100644 --- a/src/options.c +++ b/src/options.c @@ -5310,6 +5310,14 @@ optfn_boolean( #endif go.opt_need_redraw = TRUE; break; +#ifndef IDLECHECKPOINT + case opt_idlecheckpoint: + pline("There is no underlying support for 'idlecheckpoint'" + " compiled in."); + iflags.idlecheckpoint = FALSE; + give_opt_msg = FALSE; + break; +#endif default: break; } diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index 9ffdc5880..926b4033f 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -3097,7 +3097,8 @@ default_checkinput( DWORD dwWait; #endif int ch = 0; - boolean valid = 0, done = 0; + boolean valid = 0, done = 0, done_a_checkpoint = FALSE; + DWORD how_many_milliseconds = 0; #ifdef QWERTZ_SUPPORT if (numberpad & 0x10) { @@ -3107,54 +3108,78 @@ default_checkinput( qwertz = FALSE; } #endif + done_a_checkpoint = FALSE; + how_many_milliseconds = (iflags.idlecheckpoint) + ? (IDLECHECKPOINT_WAIT_TIME * 1000) + : INFINITE; while (!done) { -#if defined(SAFERHANGUP) dwWait = WaitForSingleObjectEx(hConIn, // event object to wait for - INFINITE, // waits indefinitely + how_many_milliseconds, TRUE); // alertable wait enabled +#if defined(SAFERHANGUP) if (dwWait == WAIT_FAILED) return '\033'; #endif - ReadConsoleInput(hConIn, ir, 1, count); - if (mode == 0) { - if ((ir->EventType == KEY_EVENT) && ir->Event.KeyEvent.bKeyDown) { - ch = default_processkeystroke(hConIn, ir, &valid, numberpad, 0); - done = valid; - } - } else { - if (*count > 0) { - if (ir->EventType == KEY_EVENT +#ifdef INSURANCE + if (iflags.idlecheckpoint + && dwWait == WAIT_TIMEOUT && !done_a_checkpoint) { + /* no input for 30 seconds, so let's take + * advantage and do a game checkpoint, + * then resume the wait. + */ + save_currentstate(); + done_a_checkpoint = TRUE; + } else +#endif /* INSURANCE */ + { + ReadConsoleInput(hConIn, ir, 1, count); + if (mode == 0) { + if ((ir->EventType == KEY_EVENT) && ir->Event.KeyEvent.bKeyDown) { + ch = default_processkeystroke(hConIn, ir, &valid, + numberpad, 0); + done = valid; + } + } else { + if (*count > 0) { + if (ir->EventType == KEY_EVENT + && ir->Event.KeyEvent.bKeyDown) { #ifdef QWERTZ_SUPPORT - if (qwertz) - numberpad |= 0x10; + if (qwertz) + numberpad |= 0x10; #endif - ch = default_processkeystroke(hConIn, ir, &valid, numberpad, 0); + ch = default_processkeystroke(hConIn, ir, &valid, + numberpad, 0); #ifdef QWERTZ_SUPPORT - numberpad &= ~0x10; + numberpad &= ~0x10; #endif - if (valid) - return ch; - } else if (ir->EventType == MOUSE_EVENT) { - if ((ir->Event.MouseEvent.dwEventFlags == 0) - && (ir->Event.MouseEvent.dwButtonState & MOUSEMASK)) { - cc->x = ir->Event.MouseEvent.dwMousePosition.X + 1; - cc->y = ir->Event.MouseEvent.dwMousePosition.Y - 1; + if (valid) + return ch; + } else if (ir->EventType == MOUSE_EVENT) { + if ((ir->Event.MouseEvent.dwEventFlags == 0) + && (ir->Event.MouseEvent.dwButtonState + & MOUSEMASK)) { + cc->x = + ir->Event.MouseEvent.dwMousePosition.X + 1; + cc->y = + ir->Event.MouseEvent.dwMousePosition.Y - 1; - if (ir->Event.MouseEvent.dwButtonState & LEFTBUTTON) - *mod = CLICK_1; - else if (ir->Event.MouseEvent.dwButtonState - & RIGHTBUTTON) - *mod = CLICK_2; + if (ir->Event.MouseEvent.dwButtonState + & LEFTBUTTON) + *mod = CLICK_1; + else if (ir->Event.MouseEvent.dwButtonState + & RIGHTBUTTON) + *mod = CLICK_2; #if 0 /* middle button */ else if (ir->Event.MouseEvent.dwButtonState & MIDBUTTON) *mod = CLICK_3; #endif - return 0; + return 0; + } } - } - } else - done = 1; + } else + done = 1; + } } } return mode ? 0 : ch; diff --git a/sys/windows/windmain.c b/sys/windows/windmain.c index 99567f9d2..20f5ebdb6 100644 --- a/sys/windows/windmain.c +++ b/sys/windows/windmain.c @@ -300,7 +300,7 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ if WINDOWPORT(tty) { int i; - for (i = 0; i < 20; ++i) { + for (i = 0; i < 5; ++i) { nh_delay_output(); } From f6761c7d22c9a0c16ad7cb094ccce82eb8dff8db Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 28 Apr 2026 01:54:33 -0400 Subject: [PATCH 063/702] fix an impossible() on pick-up from stomach --- doc/fixes3-7-0.txt | 5 ++++- src/pickup.c | 20 ++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index aa27902a7..d9a068c73 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -2233,7 +2233,10 @@ when reading an engraving, suppress the addition of a trailing period if the cursed magic whistle could teleport hero on no-teleport levels give a brief explanation when receiving a wish for acquiring the Amulet teleportation traps no longer teleport you on levels made temporarily - no-teleport by the presence of a monster + no-teleport by the presence of a monster +an attempt to pick up an object from a monster's stomach would trigger + an impossible() in newsym() due to object having no ox,oy coordinates + set; set the coordinates to the monster's at the start of pick_obj() Fixes to 3.7.0-x Platform and/or Interface Problems Exposed Via git Repository diff --git a/src/pickup.c b/src/pickup.c index 5f6e55de8..4b5a1c573 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1897,8 +1897,24 @@ struct obj * pick_obj(struct obj *otmp) { struct obj *result; - int ox = otmp->ox, oy = otmp->oy; - boolean robshop = (!u.uswallow && otmp != uball && costly_spot(ox, oy)); + int ox, oy; + boolean robshop = FALSE; + + if (otmp->ox == 0 && otmp->oy == 0) { + if (u.uswallow && u.ustuck && otmp->where == OBJ_MINVENT + && otmp->ocarry == u.ustuck) { + otmp->ox = u.ustuck->mx; + otmp->oy = u.ustuck->my; + } else { + /* this will be a problem for newsym below */ + impossible("otmp has no location coordinates <%d, %d> where=%d.", + otmp->ox, otmp->oy, otmp->where); + } + } + + ox = otmp->ox; + oy = otmp->oy; + robshop = (!u.uswallow && otmp != uball && costly_spot(ox, oy)); obj_extract_self(otmp); newsym(ox, oy); From 845a9a7b9cc8c9d13b797333eb697820d3058c51 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 28 Apr 2026 12:09:55 -0400 Subject: [PATCH 064/702] a first try at a Qt idlecheckpoint implementation --- include/config.h | 1 + win/Qt/qt_bind.cpp | 70 +++++++++++++++++++++++++++++++++++++++++++++- win/Qt/qt_bind.h | 3 ++ 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/include/config.h b/include/config.h index b54d073de..6eacad389 100644 --- a/include/config.h +++ b/include/config.h @@ -687,6 +687,7 @@ typedef unsigned char uchar; * will perform an update to the checkpoint file. * Currently has support in: * WIN32CON + * Qt */ /* #define IDLECHECKPOINT */ diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index fd55061e2..10e2c3d8f 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -70,6 +70,14 @@ static struct key_macro_rec { { 0, 0U, (const char *) 0, (const char *) 0 } }; +#ifdef IDLECHECKPOINT +#ifndef IDLECHECKPOINT_WAIT_TIME +#define IDLECHECKPOINT_WAIT_TIME 10 +#endif +static void qt_timer_fire(void); +QTimer *qt_input_timer; +#endif + static QPen *pen = (QPen *) 0; NetHackQtBind::NetHackQtBind(int& argc, char** argv) : @@ -309,6 +317,11 @@ public: void NetHackQtBind::qt_exit_nhwindows(const char *) { +#ifdef IDLECHECKPOINT + if (qt_input_timer) { + NetHackQtBind::free_qt_input_timer(); + } +#endif #if defined(QWS) // Avoids bug in SHARP SL5500 ((TApp*)qApp)->lwc(); @@ -653,11 +666,58 @@ QCoreApplication::exec: The event loop is already running return keybuffer.GetAscii(); } +#ifdef IDLECHECKPOINT +void +NetHackQtBind::free_qt_input_timer(void) +{ + if (qt_input_timer) { + if (qt_input_timer->isActive()) + qt_input_timer->stop(); + if (qt_input_timer) + delete qt_input_timer; + qt_input_timer = 0; + } +} + +static void +qt_timer_fire(void) +{ +#if defined(INSURANCE) + if (iflags.idlecheckpoint) { + /* no input for 30 seconds, so let's take + * advantage and do a game checkpoint, + * then resume the wait. + */ + save_currentstate(); + } + if (qt_input_timer->isActive()) + qt_input_timer->stop(); +#endif /* INSURANCE */ +} + +//void +//cancel_qt_input_timer(void) +//{ +// +//} +#endif /* IDLECHECKPOINT */ + int NetHackQtBind::qt_nh_poskey(coordxy *x, coordxy *y, int *mod) { if (main) main->fadeHighlighting(true); +#ifdef IDLECHECKPOINT + if (iflags.idlecheckpoint) { + if (!qt_input_timer) { + qt_input_timer = new QTimer(); + qt_input_timer->setSingleShot(true); + connect(qt_input_timer, &QTimer::timeout, &qt_timer_fire); + } + if (!qt_input_timer->isActive()) + qt_input_timer->start(IDLECHECKPOINT_WAIT_TIME * 1000); + } +#endif // Process events until a key or map-click arrives. // while (keybuffer.Empty() && clickbuffer.Empty()) { @@ -672,12 +732,20 @@ int NetHackQtBind::qt_nh_poskey(coordxy *x, coordxy *y, int *mod) main->fadeHighlighting(false); if (!keybuffer.Empty()) { - return keybuffer.GetAscii(); +#ifdef IDLECHECKPOINT + if (qt_input_timer->isActive()) + qt_input_timer->stop(); +#endif + return keybuffer.GetAscii(); } else { *x=clickbuffer.NextX(); *y=clickbuffer.NextY(); *mod=clickbuffer.NextMod(); clickbuffer.Get(); +#ifdef IDLECHECKPOINT + if (qt_input_timer->isActive()) + qt_input_timer->stop(); +#endif return 0; } } diff --git a/win/Qt/qt_bind.h b/win/Qt/qt_bind.h index d0c71759c..45336c29f 100644 --- a/win/Qt/qt_bind.h +++ b/win/Qt/qt_bind.h @@ -106,6 +106,9 @@ public: static void qtsound_ambience(int32_t, int32_t, int32_t); static void qtsound_verbal(char *text, int32_t gender, int32_t tone, int32_t vol, int32_t moreinfo); #endif +#ifdef IDLECHECKPOINT + static void free_qt_input_timer(void); +#endif private: virtual bool notify(QObject *receiver, QEvent *event); From b2c52b6de245a8f9b5bebc2b5a7b5b96d088cd54 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 28 Apr 2026 12:14:01 -0400 Subject: [PATCH 065/702] follow-up bit for Qt idlecheckpoint --- win/Qt/qt_bind.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 10e2c3d8f..b82c899cc 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -682,17 +682,17 @@ NetHackQtBind::free_qt_input_timer(void) static void qt_timer_fire(void) { -#if defined(INSURANCE) if (iflags.idlecheckpoint) { /* no input for 30 seconds, so let's take * advantage and do a game checkpoint, * then resume the wait. */ +#if defined(INSURANCE) save_currentstate(); +#endif /* INSURANCE */ } if (qt_input_timer->isActive()) qt_input_timer->stop(); -#endif /* INSURANCE */ } //void From 26e67755913e2eddc34abb51536f99be6977d52a Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 28 Apr 2026 12:22:51 -0400 Subject: [PATCH 066/702] more 3.7 to 5.0 in win files --- win/X11/nh32icon | 8 ++++---- win/X11/nh56icon | 23 +++++++++++------------ win/X11/nh72icon | 2 +- win/macosx/NetHackGuidebook.applescript | 2 +- win/macosx/NetHackRecover.applescript | 2 +- win/macosx/recover.pl | 2 +- win/share/tile.doc | 2 +- 7 files changed, 20 insertions(+), 21 deletions(-) diff --git a/win/X11/nh32icon b/win/X11/nh32icon index 0174d49c8..553ea2d92 100644 --- a/win/X11/nh32icon +++ b/win/X11/nh32icon @@ -1,5 +1,5 @@ -/* NetHack 3.7 nh32icon $NHDT-Date: 1777289114 2026/04/27 03:25:14 $ $NHDT-Branch: to500 $:$NHDT-Revision: 1.13 $ */ -/* Copyright (C) 1993,1995,2015,2026 by Robert Patrick Rankin */ +/* NetHack 5.0 nh32icon $NHDT-Date: 1597001766 2020/08/09 19:36:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* Copyright (C) 1993,1995,2015 by Robert Patrick Rankin */ /* NetHack may be freely redistributed. See license for details. */ /* 32x32 X11 icon for NetHack. */ @@ -10,8 +10,8 @@ static unsigned char nh32icon_bits[] = { 0xff, 0x7f, 0xfe, 0xff, 0x01, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x40, 0x82, 0x21, 0x25, 0xc0, 0x83, 0x61, 0x25, 0x80, 0x81, 0xe1, 0x3d, 0x80, 0x81, 0xa1, 0x25, 0x80, 0x81, 0x21, 0x25, 0x80, 0x81, 0x01, 0x00, 0xe0, 0x87, - 0x71, 0x30, 0x90, 0x89, 0x11, 0x48, 0x80, 0x81, 0x61, 0x48, 0x80, 0x81, - 0x81, 0x48, 0x80, 0x81, 0x71, 0x32, 0x84, 0x81, 0x03, 0x00, 0x8a, 0xc1, + 0x71, 0x78, 0x90, 0x89, 0x81, 0x40, 0x80, 0x81, 0x61, 0x20, 0x80, 0x81, + 0x81, 0x10, 0x80, 0x81, 0x71, 0x12, 0x84, 0x81, 0x03, 0x00, 0x8a, 0xc1, 0x02, 0x00, 0x84, 0x41, 0x32, 0x67, 0x80, 0x41, 0xf3, 0x7f, 0x80, 0xc1, 0xf1, 0x7f, 0x84, 0x81, 0x71, 0x77, 0x8a, 0x81, 0xb1, 0x68, 0x84, 0x81, 0x71, 0x77, 0x80, 0x81, 0x71, 0x77, 0x80, 0x81, 0xb1, 0x68, 0x84, 0x81, diff --git a/win/X11/nh56icon b/win/X11/nh56icon index f5c372b2e..6d6156672 100644 --- a/win/X11/nh56icon +++ b/win/X11/nh56icon @@ -1,6 +1,5 @@ -/* NetHack 5.0 nh56icon $NHDT-Date: 1777289257 2026/04/27 03:27:37 $ $N -HDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ */ -/* Copyright (c) 1993,1995,2015,2026 by M. Stephenson */ +/* NetHack 5.0 nh56icon $NHDT-Date: 1597001767 2020/08/09 19:36:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* Copyright (c) 1993,1995,2015 by M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ /* 56x56 X11 icon for NetHack. */ @@ -16,28 +15,28 @@ static unsigned char nh56icon_bits[] = { 0x3e, 0x00, 0xc0, 0x03, 0x00, 0xf8, 0x55, 0x3f, 0x00, 0xc0, 0x23, 0x22, 0xfc, 0xc7, 0x7f, 0x88, 0xc8, 0x43, 0x10, 0xfc, 0xd7, 0x7f, 0x10, 0xc4, 0x03, 0x07, 0xfe, 0xc7, 0xff, 0xc0, 0xc1, 0x83, 0x0d, 0xfe, 0xd7, 0xff, - 0x60, 0xc3, 0xa3, 0x28, 0xfe, 0xc7, 0xff, 0x28, 0xca, 0x82, 0x0d, 0xfe, + 0x60, 0xc3, 0xa3, 0x28, 0xfe, 0xc7, 0xff, 0x28, 0xca, 0x83, 0x0d, 0xfe, 0xd7, 0xff, 0x60, 0xc3, 0x03, 0x07, 0xfe, 0xc7, 0xff, 0xc0, 0xc1, 0x43, 0x10, 0xfc, 0xd7, 0x7f, 0x10, 0xc4, 0x23, 0x22, 0xfc, 0xc7, 0x7f, 0x88, 0xc8, 0x03, 0x00, 0xf8, 0x55, 0x3f, 0x00, 0xc0, 0x03, 0x00, 0xf8, 0x44, 0x3e, 0x00, 0xc0, 0x03, 0x00, 0x78, 0x54, 0x3c, 0x00, 0xc0, 0x03, 0x00, - 0x30, 0x6c, 0x18, 0x00, 0xc0, 0x03, 0x04, 0x00, 0x6c, 0x00, 0x00, 0xc0, + 0x30, 0x6c, 0x18, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x6c, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, - 0xc0, 0x43, 0x10, 0x21, 0x38, 0xf8, 0xc0, 0xc1, 0xc3, 0x10, 0x21, 0x38, - 0x08, 0x20, 0xc2, 0xc3, 0x10, 0x21, 0x38, 0x08, 0x20, 0xc2, 0x43, 0x11, - 0x21, 0x38, 0x08, 0x20, 0xc2, 0x43, 0x12, 0x3f, 0x38, 0x70, 0x20, 0xc2, - 0x43, 0x12, 0x21, 0x38, 0x80, 0x20, 0xc2, 0x43, 0x14, 0x21, 0x38, 0x80, - 0x20, 0xc2, 0x43, 0x18, 0x21, 0x38, 0x80, 0x20, 0xc2, 0x43, 0x18, 0x21, - 0x38, 0x88, 0x2c, 0xc2, 0x43, 0x10, 0x21, 0x38, 0x70, 0xcc, 0xc1, 0x03, + 0xc0, 0x43, 0x10, 0x21, 0x38, 0x70, 0xe0, 0xc3, 0xc3, 0x10, 0x21, 0x38, + 0x88, 0x00, 0xc2, 0xc3, 0x10, 0x21, 0x38, 0x80, 0x00, 0xc2, 0x43, 0x11, + 0x21, 0x38, 0x80, 0x00, 0xc1, 0x43, 0x12, 0x3f, 0x38, 0x70, 0x00, 0xc1, + 0x43, 0x12, 0x21, 0x38, 0x80, 0x80, 0xc0, 0x43, 0x14, 0x21, 0x38, 0x80, + 0x80, 0xc0, 0x43, 0x18, 0x21, 0x38, 0x80, 0x40, 0xc0, 0x43, 0x18, 0x21, + 0x38, 0x88, 0x4c, 0xc0, 0x43, 0x10, 0x21, 0x38, 0x70, 0x4c, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0xfb, 0xff, 0xff, 0x39, 0xff, 0xff, 0xdf, 0x0b, 0x00, 0x80, 0x7c, 0x02, 0x00, 0xd0, 0x0b, 0x00, 0x80, 0xee, 0x02, 0x00, 0xd0, 0xfb, 0xff, 0xff, 0xd6, 0xfe, 0xff, 0xdf, 0x0b, 0x00, 0x80, 0xaa, 0x02, 0x00, 0xd0, 0x0b, 0x00, 0x80, 0x54, 0x02, 0x00, 0xd0, 0xfb, 0xff, 0xff, 0x39, 0xff, - 0xff, 0xdf, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, + 0xff, 0xdf, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; diff --git a/win/X11/nh72icon b/win/X11/nh72icon index 3f1e28da7..55ac15767 100644 --- a/win/X11/nh72icon +++ b/win/X11/nh72icon @@ -1,4 +1,4 @@ -/* NetHack 5.0 nh72icon $NHDT-Date: 1596498370 2020/08/03 23:46:10 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 nh72icon $NHDT-Date: 1596498370 2020/08/03 23:46:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) 1993 by M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/macosx/NetHackGuidebook.applescript b/win/macosx/NetHackGuidebook.applescript index 71f59f031..81281a397 100644 --- a/win/macosx/NetHackGuidebook.applescript +++ b/win/macosx/NetHackGuidebook.applescript @@ -1,5 +1,5 @@ #!/usr/bin/osascript -# NetHack 3.7 NetHackGuidebook.applescript $NHDT-Date: 1596498328 2020/08/03 23:45:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ +# NetHack 5.0 NetHackGuidebook.applescript $NHDT-Date: 1596498328 2020/08/03 23:45:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2011 # NetHack may be freely redistributed. See license for details. diff --git a/win/macosx/NetHackRecover.applescript b/win/macosx/NetHackRecover.applescript index 097894e76..c6e81ae0a 100644 --- a/win/macosx/NetHackRecover.applescript +++ b/win/macosx/NetHackRecover.applescript @@ -1,5 +1,5 @@ #!/usr/bin/osascript -# NetHack 3.7 NetHackRecover.applescript $NHDT-Date: 1596498329 2020/08/03 23:45:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ +# NetHack 5.0 NetHackRecover.applescript $NHDT-Date: 1596498329 2020/08/03 23:45:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2009 # NetHack may be freely redistributed. See license for details. diff --git a/win/macosx/recover.pl b/win/macosx/recover.pl index ba9df67c0..7fb9411aa 100755 --- a/win/macosx/recover.pl +++ b/win/macosx/recover.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl -# NetHack 3.7 recover.pl $NHDT-Date: 1596498329 2020/08/03 23:45:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ +# NetHack 5.0 recover.pl $NHDT-Date: 1596498329 2020/08/03 23:45:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2009 # NetHack may be freely redistributed. See license for details. diff --git a/win/share/tile.doc b/win/share/tile.doc index fabc6f295..d701d33df 100644 --- a/win/share/tile.doc +++ b/win/share/tile.doc @@ -1,4 +1,4 @@ -NetHack 3.7 tile.doc $NHDT-Date: 1596498338 2020/08/03 23:45:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ +NetHack 5.0 tile.doc $NHDT-Date: 1596498338 2020/08/03 23:45:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ Window ports can optionally make use of the tiles (pictures for NetHack symbols) found in this directory. They are distributed in a text format From a340d43d3a33aad5dc98a124f6579b15de3a3ca3 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 28 Apr 2026 19:29:44 +0300 Subject: [PATCH 067/702] Guidebook.tex: Add missing price_quotes option --- doc/Guidebook.tex | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 54807f77d..f13efd61d 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -5069,6 +5069,16 @@ name (on single-user systems) or it might be disabled entirely. Requesting it when not allowed or not possible results in explore mode instead. Default is normal play. %.lp +\item[price\textunderscore quotes] +Whenever the game mentions the name of an object you haven't identified yet, +it also mentions the range of buy and sell prices you have seen for that +item (to help narrow down what it could be). +The price shown is the unit price for one item (even when you are looking at +a stack of multiple items). +Many players may want to turn this on while identifying objects, and then +turn it back off again for general play. +Default is off. +%.lp \item[pushweapon] Using the `\texttt{w}' (wield) command when already wielding something pushes the old item into your alternate weapon slot (default off). From 75b3c83a1d7345042a7f016eaa4e1a6eefe372b1 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 28 Apr 2026 19:34:17 +0300 Subject: [PATCH 068/702] Guidebook.tex: Archeologists and scrolls --- doc/Guidebook.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index f13efd61d..4814f264a 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -97,7 +97,8 @@ will vary with your background and training: \item[Archeologists] understand dungeons pretty well; this enables them to move quickly and sneak up on the local nasties. They start equipped -with the tools for a proper scientific expedition. +with the tools for a proper scientific expedition, and are able to read +ancient languages. %.pg % \item[Barbarians] From ed885d3ff6aa05a0d02f36a79666900109ebac2f Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 28 Apr 2026 19:38:00 +0300 Subject: [PATCH 069/702] Guidebook.tex: reroll Add missing reroll-option Remove one mangled line. --- doc/Guidebook.tex | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 4814f264a..98cde9e46 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -5107,9 +5107,20 @@ for a description of how to use negation to exclude choices. \\ If \texttt{race} is not specified, there is no default value; player will be prompted unless role forces a choice for race. -unless role forces a choice for race. Cannot be set with the `\texttt{O}' command. Persistent. %.lp +\item[reroll] +Allows rerolling your character's starting inventory and attributes (default +false). Persistent. +%.lp "" +\\ +Note that rerolling your character is not a recommended way to play if aiming +merely to win (a lucky start has a much smaller influence on whether or not +you win the game than your actions later in the game). This option exists +partly as an acknowledgement that some players will insist on doing so anyway, +and partly because rerolling may be necessary for certain types of challenge +games. +%.lp \item[rest\textunderscore on\textunderscore space] Make the space bar a synonym for the `\texttt{.}' (\#wait) command (default off). Persistent. From bb53b29481035a993a03732b4abf73845cd8f809 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 28 Apr 2026 12:35:39 -0700 Subject: [PATCH 070/702] simplify picking item up while swallowed --- src/pickup.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/pickup.c b/src/pickup.c index 4b5a1c573..5cc2fbcef 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1897,27 +1897,17 @@ struct obj * pick_obj(struct obj *otmp) { struct obj *result; - int ox, oy; - boolean robshop = FALSE; + coordxy ox, oy; + boolean robshop, fromfloor = otmp->where == OBJ_FLOOR; - if (otmp->ox == 0 && otmp->oy == 0) { - if (u.uswallow && u.ustuck && otmp->where == OBJ_MINVENT - && otmp->ocarry == u.ustuck) { - otmp->ox = u.ustuck->mx; - otmp->oy = u.ustuck->my; - } else { - /* this will be a problem for newsym below */ - impossible("otmp has no location coordinates <%d, %d> where=%d.", - otmp->ox, otmp->oy, otmp->where); - } - } + /* otmp is either on the floor or in an engulfer's inventory; for the + latter, its probably won't be set */ + (void) get_obj_location(otmp, &ox, &oy, 0); - ox = otmp->ox; - oy = otmp->oy; robshop = (!u.uswallow && otmp != uball && costly_spot(ox, oy)); - obj_extract_self(otmp); - newsym(ox, oy); + if (fromfloor) + newsym(ox, oy); /* for shop items, addinv() needs to be after addtobill() (so that object merger can take otmp->unpaid into account) but before From ee55f125a007803395a7ed0ce2871acc9460e48b Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 28 Apr 2026 16:03:04 -0400 Subject: [PATCH 071/702] follow-up bit for consoletty.c Limit the #ifdef INSURANCE range to only the function call that requires it. --- sys/windows/consoletty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index 926b4033f..781f85709 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -3120,17 +3120,17 @@ default_checkinput( if (dwWait == WAIT_FAILED) return '\033'; #endif -#ifdef INSURANCE if (iflags.idlecheckpoint && dwWait == WAIT_TIMEOUT && !done_a_checkpoint) { /* no input for 30 seconds, so let's take * advantage and do a game checkpoint, * then resume the wait. */ +#ifdef INSURANCE save_currentstate(); +#endif /* INSURANCE */ done_a_checkpoint = TRUE; } else -#endif /* INSURANCE */ { ReadConsoleInput(hConIn, ir, 1, count); if (mode == 0) { From 25c8528a7977f3ef497f8997c019017dfb4d0b9e Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 28 Apr 2026 16:46:01 -0400 Subject: [PATCH 072/702] 3.7 -> 5.0 in DEVEL Porting --- DEVEL/hooksdir/nhsub | 2 +- Porting | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEVEL/hooksdir/nhsub b/DEVEL/hooksdir/nhsub index b5b90704b..aeff30b27 100644 --- a/DEVEL/hooksdir/nhsub +++ b/DEVEL/hooksdir/nhsub @@ -1,5 +1,5 @@ #!/usr/bin/perl -# $NHDT-Date: 1524689646 2018/04/25 20:54:06 $ Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ +# $NHDT-Date: 1524689646 2018/04/25 20:54:06 $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/Porting b/Porting index d4310d363..277304df7 100644 --- a/Porting +++ b/Porting @@ -229,7 +229,7 @@ libraries. 5.0 Design Updates -The following design updates were introduced in NetHack 3.7. +The following design updates were introduced in NetHack 5.0. 5.1 Quest text files From 4b85aff7077dca8a6dd6412ee0e4847d777c646b Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 28 Apr 2026 16:59:54 -0400 Subject: [PATCH 073/702] updated doc/fixes3-6-7.txt --- doc/fixes3-6-7.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/fixes3-6-7.txt b/doc/fixes3-6-7.txt index 633950c95..6ac447eb6 100644 --- a/doc/fixes3-6-7.txt +++ b/doc/fixes3-6-7.txt @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.21 $ $NHDT-Date: 1683746783 2023/05/10 19:26:23 $ +$NHDT-Branch: to500 $:$NHDT-Revision: 1.2 $ $NHDT-Date: 1777409988 2026/04/28 20:59:48 $ fixes36.7 contains a summary of changes made to 3.6.6 in order to produce 3.6.7 as well as any post-release fixes in binaries. @@ -7,7 +7,7 @@ produce 3.6.7 as well as any post-release fixes in binaries. General Fixes and Modified Features ----------------------------------- during engraving, spaces were counted instead of non-space (cherry-pick of - 4e0a1e04 from NetHack-5.0 WIP) + 4e0a1e04 from NetHack WIP) avoid potential buffer overflow in append_str() resolve missing dependency in NetHack.sln code in include/tradstdc.h was trying to suppress warn_unused result by @@ -29,7 +29,7 @@ windows: the console.rc file had outdated information stating 3.6.3 when the official 3.6.6 binary was built. windows: switch from using keyhandling dll's to incorporating the three variations (default, ray, 340) in sys/winnt/nttty.c -curses: cherry-picked selectsaved code from 5.0 WIP for menu of save files +curses: cherry-picked selectsaved code from NetHack WIP for menu of save files NetHackW: fix delay rendering of cursor when using farlook @@ -63,9 +63,11 @@ makedefs can produce individual bogusmon, engrave and epitaph files drinkfountain() fate 24 to curse objects could end up cursing objects on the floor chain instead of the intended inventory object chain proceed with showpaths option even if the sysconf file is missing -avoid memory leak in mk_artifact(); cherry-pick of 3cca4f27 from 5.0 WIP +avoid memory leak in mk_artifact(); cherry-pick of 3cca4f27 from NetHack WIP avoid using col in Guidebook build, since some distros no longer include it, particularly some that use musl libc back-port some nroff macro updates for Guidebook prevent a crash when using 'O' to interactively set a text match highlight for hunger +avoid a reported obuf reuse in use_misc() when using a bullwhip + From dafa24b742dca0d62cf6225b74025f0f90102df3 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 28 Apr 2026 17:31:21 -0400 Subject: [PATCH 074/702] stray tabs --- src/coloratt.c | 2 +- src/options.c | 10 ++-- win/Qt/qt_bind.cpp | 138 ++++++++++++++++++++++----------------------- win/Qt/qt_bind.h | 98 ++++++++++++++++---------------- 4 files changed, 124 insertions(+), 124 deletions(-) diff --git a/src/coloratt.c b/src/coloratt.c index a929417fb..84c2cfcda 100644 --- a/src/coloratt.c +++ b/src/coloratt.c @@ -76,7 +76,7 @@ const struct nethack_color colortable[] = { { NOC, 8, 0, "nocolor", 0x00, 0x00, 0x00 }, /* NO_COLOR */ { NHC, 9, 0, "orange", 0xFF, 0xA5, 0x00 }, /* CLR_ORANGE */ { NHC, 10, 0, "bright-green", - 0x00, 0x80, 0x00 }, /* CLR_BRIGHT_GREEN */ + 0x00, 0x80, 0x00 }, /* CLR_BRIGHT_GREEN */ { NHC, 11, 0, "yellow", 0xFF, 0xFF, 0x00 }, /* CLR_YELLOW */ { NHC, 12, 0, "bright-blue", 0xAD, 0xD8, 0xE6 }, /* CLR_BRIGHT_BLUE */ { NHC, 13, 0, "bright-magenta", diff --git a/src/options.c b/src/options.c index 4897e7e7f..4a292e03c 100644 --- a/src/options.c +++ b/src/options.c @@ -5311,11 +5311,11 @@ optfn_boolean( go.opt_need_redraw = TRUE; break; #ifndef IDLECHECKPOINT - case opt_idlecheckpoint: - pline("There is no underlying support for 'idlecheckpoint'" - " compiled in."); - iflags.idlecheckpoint = FALSE; - give_opt_msg = FALSE; + case opt_idlecheckpoint: + pline("There is no underlying support for 'idlecheckpoint'" + " compiled in."); + iflags.idlecheckpoint = FALSE; + give_opt_msg = FALSE; break; #endif default: diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index b82c899cc..feb716a2d 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -238,7 +238,7 @@ static bool have_asked = false; void NetHackQtBind::qt_player_selection() { if ( !have_asked ) - qt_askname(); + qt_askname(); } void NetHackQtBind::qt_askname() @@ -345,38 +345,38 @@ winid NetHackQtBind::qt_create_nhwindow(int type) { winid id; for (id = 0; id < (winid) id_to_window.size(); id++) { - if ( !id_to_window[(int)id] ) - break; + if ( !id_to_window[(int)id] ) + break; } if ( id == (winid) id_to_window.size() ) - id_to_window.resize(id+1); + id_to_window.resize(id+1); NetHackQtWindow* window=0; switch (type) { case NHW_MAP: { - NetHackQtMapWindow2* w=new NetHackQtMapWindow2(clickbuffer); - main->AddMapWindow(w); - window=w; + NetHackQtMapWindow2* w=new NetHackQtMapWindow2(clickbuffer); + main->AddMapWindow(w); + window=w; break; } case NHW_MESSAGE: { - NetHackQtMessageWindow* w=new NetHackQtMessageWindow; - main->AddMessageWindow(w); - window=w; + NetHackQtMessageWindow* w=new NetHackQtMessageWindow; + main->AddMessageWindow(w); + window=w; break; } case NHW_STATUS: { - NetHackQtStatusWindow* w=new NetHackQtStatusWindow; - main->AddStatusWindow(w); - window=w; + NetHackQtStatusWindow* w=new NetHackQtStatusWindow; + main->AddStatusWindow(w); + window=w; break; } case NHW_MENU: - window=new NetHackQtMenuOrTextWindow(mainWidget()); + window=new NetHackQtMenuOrTextWindow(mainWidget()); break; case NHW_TEXT: - window=new NetHackQtTextWindow(mainWidget()); + window=new NetHackQtTextWindow(mainWidget()); break; } @@ -387,11 +387,11 @@ winid NetHackQtBind::qt_create_nhwindow(int type) #if QT_VERSION >= 300 && !main->isHidden() #else - && main->isVisible() + && main->isVisible() #endif - ) { - delete splash; - splash = 0; + ) { + delete splash; + splash = 0; } id_to_window[(int)id] = window; @@ -453,30 +453,30 @@ void NetHackQtBind::qt_display_file(const char *filename, boolean must_exist) bool complain = false; { - dlb *f; - char buf[BUFSZ]; - char *cr; + dlb *f; + char buf[BUFSZ]; + char *cr; - window->Clear(); - f = dlb_fopen(filename, "r"); - if (!f) { - complain = must_exist; - } else { - while (dlb_fgets(buf, BUFSZ, f)) { - if ((cr = strchr(buf, '\n')) != 0) *cr = 0; + window->Clear(); + f = dlb_fopen(filename, "r"); + if (!f) { + complain = must_exist; + } else { + while (dlb_fgets(buf, BUFSZ, f)) { + if ((cr = strchr(buf, '\n')) != 0) *cr = 0; #ifdef MSDOS - if ((cr = strchr(buf, '\r')) != 0) *cr = 0; + if ((cr = strchr(buf, '\r')) != 0) *cr = 0; #endif - window->PutStr(ATR_NONE, tabexpand(buf)); - } - window->Display(false); - (void) dlb_fclose(f); - } + window->PutStr(ATR_NONE, tabexpand(buf)); + } + window->Display(false); + (void) dlb_fclose(f); + } } if (complain) { - QString message = nh_qsprintf("File not found: %s\n",filename); - QMessageBox::warning(NULL, "File Error", message, QMessageBox::Ignore); + QString message = nh_qsprintf("File not found: %s\n",filename); + QMessageBox::warning(NULL, "File Error", message, QMessageBox::Ignore); } } @@ -511,7 +511,7 @@ int NetHackQtBind::qt_select_menu(winid wid, int how, MENU_ITEM_P **menu_list) void NetHackQtBind::qt_update_inventory(int arg UNUSED) { if (main) - main->updateInventory(); // update the paper doll inventory subset + main->updateInventory(); // update the paper doll inventory subset /* doesn't work yet if (program_state.something_worth_saving && iflags.perm_invent) @@ -636,7 +636,7 @@ const QPen NetHackQtBind::nhcolor_to_pen(uint32_t c) int NetHackQtBind::qt_nhgetch() { if (main) - main->fadeHighlighting(true); + main->fadeHighlighting(true); // Process events until a key arrives. // @@ -705,17 +705,17 @@ qt_timer_fire(void) int NetHackQtBind::qt_nh_poskey(coordxy *x, coordxy *y, int *mod) { if (main) - main->fadeHighlighting(true); + main->fadeHighlighting(true); #ifdef IDLECHECKPOINT if (iflags.idlecheckpoint) { if (!qt_input_timer) { qt_input_timer = new QTimer(); - qt_input_timer->setSingleShot(true); - connect(qt_input_timer, &QTimer::timeout, &qt_timer_fire); + qt_input_timer->setSingleShot(true); + connect(qt_input_timer, &QTimer::timeout, &qt_timer_fire); } if (!qt_input_timer->isActive()) - qt_input_timer->start(IDLECHECKPOINT_WAIT_TIME * 1000); + qt_input_timer->start(IDLECHECKPOINT_WAIT_TIME * 1000); } #endif // Process events until a key or map-click arrives. @@ -738,15 +738,15 @@ int NetHackQtBind::qt_nh_poskey(coordxy *x, coordxy *y, int *mod) #endif return keybuffer.GetAscii(); } else { - *x=clickbuffer.NextX(); - *y=clickbuffer.NextY(); - *mod=clickbuffer.NextMod(); - clickbuffer.Get(); + *x=clickbuffer.NextX(); + *y=clickbuffer.NextY(); + *mod=clickbuffer.NextMod(); + clickbuffer.Get(); #ifdef IDLECHECKPOINT if (qt_input_timer->isActive()) qt_input_timer->stop(); #endif - return 0; + return 0; } } @@ -792,10 +792,10 @@ char NetHackQtBind::qt_more() int complain = 0; do { ch = NetHackQtBind::qt_nhgetch(); - if (::program_state.savefile_completed) { - retry = false; - break; - } + if (::program_state.savefile_completed) { + retry = false; + break; + } switch (ch) { case '\0': // hypothetical ch = '\033'; @@ -876,26 +876,26 @@ char NetHackQtBind::qt_yn_function(const char *question_, !::iflags.wc_popup_dialog #endif && WIN_MESSAGE != WIN_ERR) { - // Similar to X11 windowport `slow' feature. + // Similar to X11 windowport `slow' feature. char cbuf[20]; cbuf[0] = '\0'; // add the prompt to the message window - NetHackQtBind::qt_putstr(WIN_MESSAGE, ATR_BOLD, message); + NetHackQtBind::qt_putstr(WIN_MESSAGE, ATR_BOLD, message); - while (result < 0) { + while (result < 0) { cbuf[0] = '\0'; - char ch=NetHackQtBind::qt_nhgetch(); - if (ch=='\033') { - result=yn_esc_map; + char ch=NetHackQtBind::qt_nhgetch(); + if (ch=='\033') { + result=yn_esc_map; Strcpy(cbuf, "ESC"); - } else if (choices && !strchr(choices,ch)) { - if (def && (ch==' ' || ch=='\r' || ch=='\n')) { - result=def; + } else if (choices && !strchr(choices,ch)) { + if (def && (ch==' ' || ch=='\r' || ch=='\n')) { + result=def; Strcpy(cbuf, visctrl(def)); - } else { - NetHackQtBind::qt_nhbell(); + } else { + NetHackQtBind::qt_nhbell(); // typing anything caused the most recent message line // (which happens to our prompt) from having highlighting // be removed; put that back @@ -903,13 +903,13 @@ char NetHackQtBind::qt_yn_function(const char *question_, *mesgwin = main ? main->GetMessageWindow() : NULL; if (mesgwin) mesgwin->RehighlightPrompt(); - // and try again... - } - } else { - result=ch; + // and try again... + } + } else { + result=ch; Strcpy(cbuf, visctrl(ch)); - } - } + } + } // update the prompt message line to include the response if (cbuf[0]) { diff --git a/win/Qt/qt_bind.h b/win/Qt/qt_bind.h index 45336c29f..17dad758c 100644 --- a/win/Qt/qt_bind.h +++ b/win/Qt/qt_bind.h @@ -23,78 +23,78 @@ class NetHackQtClickBuffer; class NetHackQtBind : NetHackQtBindBase { private: - // Single-instance preservation... - NetHackQtBind(int& argc, char** argv); + // Single-instance preservation... + NetHackQtBind(int& argc, char** argv); - static NetHackQtBind* instance; + static NetHackQtBind* instance; - static NetHackQtKeyBuffer keybuffer; - static NetHackQtClickBuffer clickbuffer; + static NetHackQtKeyBuffer keybuffer; + static NetHackQtClickBuffer clickbuffer; - static QFrame* splash; - static NetHackQtMainWindow* main; + static QFrame* splash; + static NetHackQtMainWindow* main; public: static void qt_Splash(); /* window interface */ - static void qt_init_nhwindows(int* argc, char** argv); - static void qt_player_selection(); - static void qt_askname(); - static void qt_get_nh_event(); - static void qt_exit_nhwindows(const char *); - static void qt_suspend_nhwindows(const char *); - static void qt_resume_nhwindows(); - static winid qt_create_nhwindow(int type); - static void qt_clear_nhwindow(winid wid); - static void qt_display_nhwindow(winid wid, boolean block); - static void qt_destroy_nhwindow(winid wid); - static void qt_curs(winid wid, int x, int y); - static void qt_putstr(winid wid, int attr, const char *text); - static void qt_putstr(winid wid, int attr, const std::string& text); - static void qt_putstr(winid wid, int attr, const QString& text); - static void qt_display_file(const char *filename, boolean must_exist); - static void qt_start_menu(winid wid, unsigned long mbehavior); - static void qt_add_menu(winid wid, const glyph_info *glyphinfo, - const ANY_P * identifier, char ch, char gch, int attr, int clr, - const char *str, unsigned int itemflags); + static void qt_init_nhwindows(int* argc, char** argv); + static void qt_player_selection(); + static void qt_askname(); + static void qt_get_nh_event(); + static void qt_exit_nhwindows(const char *); + static void qt_suspend_nhwindows(const char *); + static void qt_resume_nhwindows(); + static winid qt_create_nhwindow(int type); + static void qt_clear_nhwindow(winid wid); + static void qt_display_nhwindow(winid wid, boolean block); + static void qt_destroy_nhwindow(winid wid); + static void qt_curs(winid wid, int x, int y); + static void qt_putstr(winid wid, int attr, const char *text); + static void qt_putstr(winid wid, int attr, const std::string& text); + static void qt_putstr(winid wid, int attr, const QString& text); + static void qt_display_file(const char *filename, boolean must_exist); + static void qt_start_menu(winid wid, unsigned long mbehavior); + static void qt_add_menu(winid wid, const glyph_info *glyphinfo, + const ANY_P * identifier, char ch, char gch, int attr, int clr, + const char *str, unsigned int itemflags); static void qt_end_menu(winid wid, const char *prompt); - static int qt_select_menu(winid wid, int how, MENU_ITEM_P **menu_list); - static void qt_mark_synch(); - static void qt_wait_synch(); + static int qt_select_menu(winid wid, int how, MENU_ITEM_P **menu_list); + static void qt_mark_synch(); + static void qt_wait_synch(); - static void qt_cliparound(int x, int y); - static void qt_cliparound_window(winid wid, int x, int y); + static void qt_cliparound(int x, int y); + static void qt_cliparound_window(winid wid, int x, int y); static void qt_print_glyph(winid wid, coordxy x, coordxy y, const glyph_info *glyphingo, - const glyph_info *bkglyphinfo); - static void qt_raw_print(const char *str); - static void qt_raw_print_bold(const char *str); - static const QPen nhcolor_to_pen(uint32_t c); + const glyph_info *bkglyphinfo); + static void qt_raw_print(const char *str); + static void qt_raw_print_bold(const char *str); + static const QPen nhcolor_to_pen(uint32_t c); static void qt_change_color(int color, long rgb, int reverse UNUSED); static char *qt_get_color_string(void); - static int qt_nhgetch(); - static int qt_nh_poskey(coordxy *x, coordxy *y, int *mod); - static void qt_nhbell(); - static int qt_doprev_message(); + static int qt_nhgetch(); + static int qt_nh_poskey(coordxy *x, coordxy *y, int *mod); + static void qt_nhbell(); + static int qt_doprev_message(); static char qt_more(); static char qt_yn_function(const char *question, const char *choices, char def); - static void qt_getlin(const char *prompt, char *line); - static int qt_get_ext_cmd(); - static void qt_number_pad(int); - static void qt_delay_output(); + static void qt_getlin(const char *prompt, char *line); + static int qt_get_ext_cmd(); + static void qt_number_pad(int); + static void qt_delay_output(); static void qt_preference_update(const char *optname); static char *qt_getmsghistory(boolean init); static void qt_putmsghistory(const char *msg, boolean is_restoring); - static void qt_outrip(winid wid, int how, time_t when); - static int qt_kbhit(); - static void qt_update_inventory(int); + static void qt_outrip(winid wid, int how, time_t when); + static int qt_kbhit(); + static void qt_update_inventory(int); static win_request_info *qt_ctrl_nhwindow(winid, int, win_request_info *); - static QWidget *mainWidget() { return main; } + static QWidget *mainWidget() { return main; } #if defined(SND_LIB_QTSOUND) && !defined(QT_NO_SOUND) /* sound interface */ static void qtsound_init_nhsound(void); @@ -111,7 +111,7 @@ public: #endif private: - virtual bool notify(QObject *receiver, QEvent *event); + virtual bool notify(QObject *receiver, QEvent *event); static QStringList *msgs_strings; static boolean msgs_saved; From 62cfbdc4a09199988bb4aaf4f19715e21115c23a Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Wed, 29 Apr 2026 04:16:56 +0100 Subject: [PATCH 075/702] Fix the new rolling boulder traps for when monsters step on them The traps don't disappear when stepped on any more; that should be true even when monsters step on them. (This bug was reported privately to me via IRC, rather than via the devteam's email address, so there isn't a ticket number to close.) --- src/trap.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/trap.c b/src/trap.c index a97706fe8..0358e3520 100644 --- a/src/trap.c +++ b/src/trap.c @@ -2698,9 +2698,6 @@ trapeffect_rolling_boulder_trap( trap->tseen = TRUE; if (DEADMONSTER(mtmp)) trapkilled = TRUE; - } else { - deltrap(trap); - newsym(mtmp->mx, mtmp->my); } return trapkilled ? Trap_Killed_Mon : mtmp->mtrapped ? Trap_Caught_Mon : Trap_Effect_Finished; From a3fdf22153e73206b447e98bdc3784a777039635 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 29 Apr 2026 15:43:55 +0300 Subject: [PATCH 076/702] Fix monster postmove moving off-map monster --- src/monmove.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/monmove.c b/src/monmove.c index fe3040da3..773fa3011 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1511,6 +1511,8 @@ postmov( if (mtmp->mx) newsym(mtmp->mx, mtmp->my); return MMOVE_DIED; /* it died */ + } else if (mon_offmap(mtmp)) { + return MMOVE_DONE; } ptr = mtmp->data; /* in case mintrap() caused polymorph */ From 0be07d2816a5be9918525b85853c59b91a308bd2 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 29 Apr 2026 15:45:12 +0300 Subject: [PATCH 077/702] Fix migrating object trying to newsym invalid location --- src/teleport.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/teleport.c b/src/teleport.c index 48fa7da78..3384fa204 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -2139,9 +2139,10 @@ rloco(struct obj *obj) svd.dndest.nhx, svd.dndest.nhy))); if (flooreffects(obj, tx, ty, "fall")) { - /* update old location since flooreffects() couldn't; + /* update old location (if any) since flooreffects() couldn't; unblock_point() for boulder handled by obj_extract_self() */ - newsym(otx, oty); + if (!(otx == 0 && oty == 0)) + newsym(otx, oty); return FALSE; } else if (otx == 0 && oty == 0) { ; /* fell through a trap door; no update of old loc needed */ From 8a41076657c60ef6b8d778fb1bf5bfe4238a4317 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 29 Apr 2026 19:14:47 +0300 Subject: [PATCH 078/702] Some hallu monster, liquid, trap changes --- dat/bogusmon.txt | 20 +++++++++++++++++--- src/do_name.c | 2 +- src/trap.c | 3 +++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/dat/bogusmon.txt b/dat/bogusmon.txt index 8b5335296..c3b6a7019 100644 --- a/dat/bogusmon.txt +++ b/dat/bogusmon.txt @@ -97,6 +97,22 @@ voussoir barking spider frog cloud toothsayer +third eye +owlpug +pugasus +acorn +red dot +robot chicken +doozer +poison cackler +lhurgoyf +phelddagrif +tiktaalik +weremoustache +rapier tapir +choplet +pommelbug +quest sprout # Quendor (Zork, &c.) grue @@ -301,6 +317,7 @@ wiki peer COBOL wire shark +stray tab # bugs bohrbug @@ -384,9 +401,6 @@ little green man # Portal weighted Companion Cube -# /b/ -/b/tard - # South Park manbearpig diff --git a/src/do_name.c b/src/do_name.c index b69b56e4d..8ef9f7294 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1484,7 +1484,7 @@ static NEARDATA const char *const hliquids[] = { "caramel sauce", "ink", "aqueous humour", "milk substitute", "fruit juice", "glowing lava", "gastric acid", "mineral water", "cough syrup", "quicksilver", "sweet vitriol", "grey goo", "pink slime", - "cosmic latte", + "cosmic latte", "bone oil", "custard", "lard", "vinegar", "creosote", /* "new coke (tm)", --better not */ }; diff --git a/src/trap.c b/src/trap.c index 0358e3520..62f47bb96 100644 --- a/src/trap.c +++ b/src/trap.c @@ -7123,6 +7123,9 @@ trapname( "sweet-smelling gas vent", "phone booth", "exploding runes", "never-ending elevator", "slime pit", "warp zone", "illusory floor", "pile of poo", "honey trap", "tourist trap", + "banana peel", "garden rake", "whoopie cushion", "box and stick trap", + "fly trap", "legal trap", "pit of snakes", "pollywog trap", + "slippery slope", "thirst trap", "tourist trap", "suntrap", }; static char roletrap[33]; /* [17 + 5 + 1] should suffice */ From 1b28d5e261d5cf0807bd6a5196fa824046f109b7 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 29 Apr 2026 12:35:33 -0400 Subject: [PATCH 079/702] update tested versions of Visual Studio 2026-04-29 --- sys/windows/Makefile.nmake | 6 +++--- sys/windows/vs/NetHack/NetHack.vcxproj | 5 ++++- sys/windows/vs/NetHackW/NetHackW.vcxproj | 5 ++++- sys/windows/vs/PDCurses/PDCurses.vcxproj | 3 +++ sys/windows/vs/PDCursesGui/pdcursesgui.vcxproj | 3 +++ sys/windows/vs/dlb/dlb.vcxproj | 3 +++ sys/windows/vs/hacklib/hacklib.vcxproj | 6 +++--- sys/windows/vs/lualib/lualib.vcxproj | 14 +++++++------- sys/windows/vs/makedefs/makedefs.vcxproj | 3 +++ sys/windows/vs/nhlua_h/nhlua_h.vcxproj | 8 ++++++-- sys/windows/vs/recover/recover.vcxproj | 3 +++ sys/windows/vs/sfctool/sfctool.vcxproj | 12 ++++++------ sys/windows/vs/sftags/sftags.vcxproj | 12 ++++++------ sys/windows/vs/tile2bmp/tile2bmp.vcxproj | 3 +++ sys/windows/vs/tilemap/tilemap.vcxproj | 3 +++ sys/windows/vs/tiles/tiles.vcxproj | 8 ++++---- sys/windows/vs/uudecode/uudecode.vcxproj | 3 +++ 17 files changed, 67 insertions(+), 33 deletions(-) diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index f4be7a51c..260bb9939 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -8,8 +8,8 @@ # MS Visual Studio Visual C++ compiler # # Visual Studio Compilers Tested: -# - Microsoft Visual Studio Community 2022 v 17.14.30 -# - Microsoft Visual Studio Community 2026 v 18.5.0 +# - Microsoft Visual Studio Community 2022 v 17.14.31 +# - Microsoft Visual Studio Community 2026 v 18.5.2 # #============================================================================== # This is used for building two distinct executables of NetHack: @@ -1188,7 +1188,7 @@ rc=Rc.exe # # Recently tested versions: TESTEDVS2022 = 14.44.35225.0 -TESTEDVS2026 = 14.50.35729.0 +TESTEDVS2026 = 14.50.35730.0 VS20261ST = 1450000000 VS2026CUR = $(TESTEDVS2026:.=) diff --git a/sys/windows/vs/NetHack/NetHack.vcxproj b/sys/windows/vs/NetHack/NetHack.vcxproj index fc2604af1..1d29c4f80 100644 --- a/sys/windows/vs/NetHack/NetHack.vcxproj +++ b/sys/windows/vs/NetHack/NetHack.vcxproj @@ -3,6 +3,9 @@ + + + @@ -329,4 +332,4 @@ - + \ No newline at end of file diff --git a/sys/windows/vs/NetHackW/NetHackW.vcxproj b/sys/windows/vs/NetHackW/NetHackW.vcxproj index 6b7ecc097..df2507e81 100644 --- a/sys/windows/vs/NetHackW/NetHackW.vcxproj +++ b/sys/windows/vs/NetHackW/NetHackW.vcxproj @@ -33,6 +33,9 @@ 10.0 + + + @@ -406,4 +409,4 @@ - + \ No newline at end of file diff --git a/sys/windows/vs/PDCurses/PDCurses.vcxproj b/sys/windows/vs/PDCurses/PDCurses.vcxproj index 10f9712ec..e849ca497 100644 --- a/sys/windows/vs/PDCurses/PDCurses.vcxproj +++ b/sys/windows/vs/PDCurses/PDCurses.vcxproj @@ -35,6 +35,9 @@ 10.0 + + + diff --git a/sys/windows/vs/PDCursesGui/pdcursesgui.vcxproj b/sys/windows/vs/PDCursesGui/pdcursesgui.vcxproj index e709ade6d..fef23ab69 100644 --- a/sys/windows/vs/PDCursesGui/pdcursesgui.vcxproj +++ b/sys/windows/vs/PDCursesGui/pdcursesgui.vcxproj @@ -35,6 +35,9 @@ 10.0 + + + diff --git a/sys/windows/vs/dlb/dlb.vcxproj b/sys/windows/vs/dlb/dlb.vcxproj index 44a1dad6a..a0a29af68 100644 --- a/sys/windows/vs/dlb/dlb.vcxproj +++ b/sys/windows/vs/dlb/dlb.vcxproj @@ -33,6 +33,9 @@ 10.0 + + + diff --git a/sys/windows/vs/hacklib/hacklib.vcxproj b/sys/windows/vs/hacklib/hacklib.vcxproj index 3c7241496..c6921c542 100644 --- a/sys/windows/vs/hacklib/hacklib.vcxproj +++ b/sys/windows/vs/hacklib/hacklib.vcxproj @@ -75,7 +75,7 @@ StaticLibrary true Unicode - v145 + $(DefaultPlatformToolset) StaticLibrary @@ -87,7 +87,7 @@ false true Unicode - v145 + $(DefaultPlatformToolset) StaticLibrary @@ -230,4 +230,4 @@ - \ No newline at end of file + diff --git a/sys/windows/vs/lualib/lualib.vcxproj b/sys/windows/vs/lualib/lualib.vcxproj index 0849b2893..9b8bb3667 100644 --- a/sys/windows/vs/lualib/lualib.vcxproj +++ b/sys/windows/vs/lualib/lualib.vcxproj @@ -90,22 +90,22 @@ Unicode - v143 + $(DefaultPlatformToolset) - v143 + $(DefaultPlatformToolset) - v145 + $(DefaultPlatformToolset) - v143 + $(DefaultPlatformToolset) - v143 + $(DefaultPlatformToolset) - v145 + $(DefaultPlatformToolset) @@ -239,4 +239,4 @@ - \ No newline at end of file + diff --git a/sys/windows/vs/makedefs/makedefs.vcxproj b/sys/windows/vs/makedefs/makedefs.vcxproj index b832056f9..cced77ffd 100644 --- a/sys/windows/vs/makedefs/makedefs.vcxproj +++ b/sys/windows/vs/makedefs/makedefs.vcxproj @@ -33,6 +33,9 @@ 10.0 + + + diff --git a/sys/windows/vs/nhlua_h/nhlua_h.vcxproj b/sys/windows/vs/nhlua_h/nhlua_h.vcxproj index 842f541d8..2f8f14f28 100644 --- a/sys/windows/vs/nhlua_h/nhlua_h.vcxproj +++ b/sys/windows/vs/nhlua_h/nhlua_h.vcxproj @@ -33,6 +33,9 @@ 10.0 + + + @@ -50,10 +53,11 @@ - + + - + \ No newline at end of file diff --git a/sys/windows/vs/recover/recover.vcxproj b/sys/windows/vs/recover/recover.vcxproj index 1fe6f0a16..a15b4c17b 100644 --- a/sys/windows/vs/recover/recover.vcxproj +++ b/sys/windows/vs/recover/recover.vcxproj @@ -33,6 +33,9 @@ 10.0 + + + diff --git a/sys/windows/vs/sfctool/sfctool.vcxproj b/sys/windows/vs/sfctool/sfctool.vcxproj index ad1971969..c6485a0e6 100644 --- a/sys/windows/vs/sfctool/sfctool.vcxproj +++ b/sys/windows/vs/sfctool/sfctool.vcxproj @@ -87,39 +87,39 @@ Application true - v143 + $(DefaultPlatformToolset) Unicode Application false - v143 + $(DefaultPlatformToolset) true Unicode Application true - v143 + $(DefaultPlatformToolset) Unicode Application true - v143 + $(DefaultPlatformToolset) Unicode Application false - v143 + $(DefaultPlatformToolset) true Unicode Application false - v143 + $(DefaultPlatformToolset) true Unicode diff --git a/sys/windows/vs/sftags/sftags.vcxproj b/sys/windows/vs/sftags/sftags.vcxproj index 52c63d47a..fb1aa0c66 100644 --- a/sys/windows/vs/sftags/sftags.vcxproj +++ b/sys/windows/vs/sftags/sftags.vcxproj @@ -47,39 +47,39 @@ Application true - v143 + $(DefaultPlatformToolset) Unicode Application false - v143 + $(DefaultPlatformToolset) true Unicode Application true - v143 + $(DefaultPlatformToolset) Unicode Application true - v143 + $(DefaultPlatformToolset) Unicode Application false - v143 + $(DefaultPlatformToolset) true Unicode Application false - v143 + $(DefaultPlatformToolset) true Unicode diff --git a/sys/windows/vs/tile2bmp/tile2bmp.vcxproj b/sys/windows/vs/tile2bmp/tile2bmp.vcxproj index 6ed724f2b..0c94bf9f7 100644 --- a/sys/windows/vs/tile2bmp/tile2bmp.vcxproj +++ b/sys/windows/vs/tile2bmp/tile2bmp.vcxproj @@ -33,6 +33,9 @@ 10.0 + + + diff --git a/sys/windows/vs/tilemap/tilemap.vcxproj b/sys/windows/vs/tilemap/tilemap.vcxproj index 70ce0296b..a21a17a72 100644 --- a/sys/windows/vs/tilemap/tilemap.vcxproj +++ b/sys/windows/vs/tilemap/tilemap.vcxproj @@ -33,6 +33,9 @@ 10.0 + + + diff --git a/sys/windows/vs/tiles/tiles.vcxproj b/sys/windows/vs/tiles/tiles.vcxproj index e6b52ad78..4481d9b81 100644 --- a/sys/windows/vs/tiles/tiles.vcxproj +++ b/sys/windows/vs/tiles/tiles.vcxproj @@ -26,22 +26,22 @@ Makefile false - v120 + $(DefaultPlatformToolset) Makefile false - v120 + $(DefaultPlatformToolset) Makefile false - v120 + $(DefaultPlatformToolset) Makefile false - v120 + $(DefaultPlatformToolset) diff --git a/sys/windows/vs/uudecode/uudecode.vcxproj b/sys/windows/vs/uudecode/uudecode.vcxproj index 296d97ab8..e1eba7dc8 100644 --- a/sys/windows/vs/uudecode/uudecode.vcxproj +++ b/sys/windows/vs/uudecode/uudecode.vcxproj @@ -33,6 +33,9 @@ 10.0 + + + From 2dfc2e7e877eccc0111d038ed5fef8dad4ea88f0 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 29 Apr 2026 21:03:15 +0300 Subject: [PATCH 080/702] Remove double hallu trap --- src/trap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trap.c b/src/trap.c index 62f47bb96..5ff6c0747 100644 --- a/src/trap.c +++ b/src/trap.c @@ -7125,7 +7125,7 @@ trapname( "pile of poo", "honey trap", "tourist trap", "banana peel", "garden rake", "whoopie cushion", "box and stick trap", "fly trap", "legal trap", "pit of snakes", "pollywog trap", - "slippery slope", "thirst trap", "tourist trap", "suntrap", + "slippery slope", "thirst trap", "suntrap", }; static char roletrap[33]; /* [17 + 5 + 1] should suffice */ From 6d8d1b20447548a5cc5620d8ceee6e8a3cb2e8bb Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 29 Apr 2026 14:40:33 -0400 Subject: [PATCH 081/702] documentation updates Dungeoneers list updates Ingo Paschke provided Amiga updates to get the port working for the release to follow 3.6.7. He used the gcc-15.2 branch of bebbo's Amiga toolchain on Linux. G. Branden Robinson contributed several updates and suggestions to help ensure that the *roff documentation production remains viable. --- dat/history | 84 +++++++++++++++++++++++------------------------ doc/Guidebook.mn | 84 +++++++++++++++++++++++------------------------ doc/Guidebook.tex | 84 +++++++++++++++++++++++------------------------ 3 files changed, 126 insertions(+), 126 deletions(-) diff --git a/dat/history b/dat/history index 3d4b6e9bc..568fd8e9d 100644 --- a/dat/history +++ b/dat/history @@ -292,45 +292,45 @@ particularly intriguing modification to help out with the game. The NetHack Development Team sometimes makes note of the names of the worst of these miscreants in this, the list of Dungeoneers: - Adam Aronow J. Ali Harlow Mikko Juola - Alex Kompel Janet Walz Nathan Eady - Alex Smith Janne Salmijarvi Norm Meluch - Andreas Dorn Jean-Christophe Collet Olaf Seibert - Andy Church Jeff Bailey Pasi Kallinen - Andy Swanson Jochen Erwied Pat Rankin - Andy Thomson John Kallen Patric Mueller - Ari Huttunen John Rupley Paul Winner - Bart House John S. Bien Pierre Martineau - Benson I. Margulies Johnny Lee Ralf Brown - Bill Dyer Jon W{tte Ray Chason - Boudewijn Waijers Jonathan Handler Richard Addison - Bruce Cox Joshua Delahunty Richard Beigel - Bruce Holloway Karl Garrison Richard P. Hughey - Bruce Mewborne Keizo Yamamoto Rob Menke - Carl Schelin Keith Simpson Robin Bandy - Chris Russo Ken Arnold Robin Johnson - David Cohrs Ken Arromdee Roderick Schertler - David Damerell Ken Lorber Roland McGrath - David Gentzel Ken Washikita Ron Van Iwaarden - David Hairston Kevin Darcy Ronnen Miller - Dean Luick Kevin Hugo Ross Brown - Del Lamb Kevin Sitze Sascha Wostmann - Derek S. Ray Kevin Smolkowski Scott Bigham - Deron Meranda Kevin Sweet Scott R. Turner - Dion Nicolaas Lars Huttar Sean Hunt - Dylan O'Donnell Leon Arnott Stephen Spackman - Eric Backus M. Drew Streib Stefan Thielscher - Eric Hendrickson Malcolm Ryan Stephen White - Eric R. Smith Mark Gooderum Steve Creps - Eric S. Raymond Mark Modrall Steve Linhart - Erik Andersen Marvin Bressler Steve VanDevender - Fredrik Ljungdahl Matthew Day Teemu Suikki - Frederick Roeber Merlyn LeRoy Tim Lennan - Gil Neiger Michael Allison Timo Hakulinen - Greg Laskin Michael Feir Tom Almy - Greg Olson Michael Hamel Tom West - Gregg Wonderly Michael Sokolov Warren Cheung - Hao-yang Wang Mike Engber Warwick Allison - Helge Hafting Mike Gallop Yitzhak Sapir - Irina Rempt-Drijfhout Mike Passaretti - Izchak Miller Mike Stephenson + Adam Aronow Irina Rempt-Drijfhout Mike Passaretti + Alex Kompel Izchak Miller Mike Stephenson + Alex Smith J. Ali Harlow Mikko Juola + Andreas Dorn Janet Walz Nathan Eady + Andy Church Janne Salmijarvi Norm Meluch + Andy Swanson Jean-Christophe Collet Olaf Seibert + Andy Thomson Jeff Bailey Pasi Kallinen + Ari Huttunen Jochen Erwied Pat Rankin + Bart House John Kallen Patric Mueller + Benson I. Margulies John Rupley Paul Winner + Bill Dyer John S. Bien Pierre Martineau + Boudewijn Waijers Johnny Lee Ralf Brown + Bruce Cox Jon W{tte Ray Chason + Bruce Holloway Jonathan Handler Richard Addison + Bruce Mewborne Joshua Delahunty Richard Beigel + Carl Schelin Karl Garrison Richard P. Hughey + Chris Russo Keizo Yamamoto Rob Menke + David Cohrs Keith Simpson Robin Bandy + David Damerell Ken Arnold Robin Johnson + David Gentzel Ken Arromdee Roderick Schertler + David Hairston Ken Lorber Roland McGrath + Dean Luick Ken Washikita Ron Van Iwaarden + Del Lamb Kevin Darcy Ronnen Miller + Derek S. Ray Kevin Hugo Ross Brown + Deron Meranda Kevin Sitze Sascha Wostmann + Dion Nicolaas Kevin Smolkowski Scott Bigham + Dylan O'Donnell Kevin Sweet Scott R. Turner + Eric Backus Lars Huttar Sean Hunt + Eric Hendrickson Leon Arnott Stephen Spackman + Eric R. Smith M. Drew Streib Stefan Thielscher + Eric S. Raymond Malcolm Ryan Stephen White + Erik Andersen Mark Gooderum Steve Creps + Fredrik Ljungdahl Mark Modrall Steve Linhart + Frederick Roeber Marvin Bressler Steve VanDevender + G. Branden Robinson Matthew Day Teemu Suikki + Gil Neiger Merlyn LeRoy Tim Lennan + Greg Laskin Michael Allison Timo Hakulinen + Greg Olson Michael Feir Tom Almy + Gregg Wonderly Michael Hamel Tom West + Hao-yang Wang Michael Sokolov Warren Cheung + Helge Hafting Mike Engber Warwick Allison + Ingo Paschke Mike Gallop Yitzhak Sapir diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index cb9b023c2..d74ce54be 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -6811,48 +6811,48 @@ miscreants in this, the list of Dungeoneers: center; c2 c2 c. .\"TABLE_START -Adam Aronow J. Ali Harlow Mikko Juola -Alex Kompel Janet Walz Nathan Eady -Alex Smith Janne Salmijarvi Norm Meluch -Andreas Dorn Jean-Christophe Collet Olaf Seibert -Andy Church Jeff Bailey Pasi Kallinen -Andy Swanson Jochen Erwied Pat Rankin -Andy Thomson John Kallen Patric Mueller -Ari Huttunen John Rupley Paul Winner -Bart House John S. Bien Pierre Martineau -Benson I. Margulies Johnny Lee Ralf Brown -Bill Dyer Jon W{tte Ray Chason -Boudewijn Waijers Jonathan Handler Richard Addison -Bruce Cox Joshua Delahunty Richard Beigel -Bruce Holloway Karl Garrison Richard P. Hughey -Bruce Mewborne Keizo Yamamoto Rob Menke -Carl Schelin Keith Simpson Robin Bandy -Chris Russo Ken Arnold Robin Johnson -David Cohrs Ken Arromdee Roderick Schertler -David Damerell Ken Lorber Roland McGrath -David Gentzel Ken Washikita Ron Van Iwaarden -David Hairston Kevin Darcy Ronnen Miller -Dean Luick Kevin Hugo Ross Brown -Del Lamb Kevin Sitze Sascha Wostmann -Derek S. Ray Kevin Smolkowski Scott Bigham -Deron Meranda Kevin Sweet Scott R. Turner -Dion Nicolaas Lars Huttar Sean Hunt -Dylan O'Donnell Leon Arnott Stephen Spackman -Eric Backus M. Drew Streib Stefan Thielscher -Eric Hendrickson Malcolm Ryan Stephen White -Eric R. Smith Mark Gooderum Steve Creps -Eric S. Raymond Mark Modrall Steve Linhart -Erik Andersen Marvin Bressler Steve VanDevender -Fredrik Ljungdahl Matthew Day Teemu Suikki -Frederick Roeber Merlyn LeRoy Tim Lennan -Gil Neiger Michael Allison Timo Hakulinen -Greg Laskin Michael Feir Tom Almy -Greg Olson Michael Hamel Tom West -Gregg Wonderly Michael Sokolov Warren Cheung -Hao-yang Wang Mike Engber Warwick Allison -Helge Hafting Mike Gallop Yitzhak Sapir -Irina Rempt-Drijfhout Mike Passaretti -Izchak Miller Mike Stephenson +Adam Aronow Irina Rempt-Drijfhout Mike Passaretti +Alex Kompel Izchak Miller Mike Stephenson +Alex Smith J. Ali Harlow Mikko Juola +Andreas Dorn Janet Walz Nathan Eady +Andy Church Janne Salmijarvi Norm Meluch +Andy Swanson Jean-Christophe Collet Olaf Seibert +Andy Thomson Jeff Bailey Pasi Kallinen +Ari Huttunen Jochen Erwied Pat Rankin +Bart House John Kallen Patric Mueller +Benson I. Margulies John Rupley Paul Winner +Bill Dyer John S. Bien Pierre Martineau +Boudewijn Waijers Johnny Lee Ralf Brown +Bruce Cox Jon W{tte Ray Chason +Bruce Holloway Jonathan Handler Richard Addison +Bruce Mewborne Joshua Delahunty Richard Beigel +Carl Schelin Karl Garrison Richard P. Hughey +Chris Russo Keizo Yamamoto Rob Menke +David Cohrs Keith Simpson Robin Bandy +David Damerell Ken Arnold Robin Johnson +David Gentzel Ken Arromdee Roderick Schertler +David Hairston Ken Lorber Roland McGrath +Dean Luick Ken Washikita Ron Van Iwaarden +Del Lamb Kevin Darcy Ronnen Miller +Derek S. Ray Kevin Hugo Ross Brown +Deron Meranda Kevin Sitze Sascha Wostmann +Dion Nicolaas Kevin Smolkowski Scott Bigham +Dylan O'Donnell Kevin Sweet Scott R. Turner +Eric Backus Lars Huttar Sean Hunt +Eric Hendrickson Leon Arnott Stephen Spackman +Eric R. Smith M. Drew Streib Stefan Thielscher +Eric S. Raymond Malcolm Ryan Stephen White +Erik Andersen Mark Gooderum Steve Creps +Fredrik Ljungdahl Mark Modrall Steve Linhart +Frederick Roeber Marvin Bressler Steve VanDevender +G. Branden Robinson Matthew Day Teemu Suikki +Gil Neiger Merlyn LeRoy Tim Lennan +Greg Laskin Michael Allison Timo Hakulinen +Greg Olson Michael Feir Tom Almy +Gregg Wonderly Michael Hamel Tom West +Hao-yang Wang Michael Sokolov Warren Cheung +Helge Hafting Mike Engber Warwick Allison +Ingo Paschke Mike Gallop Yitzhak Sapir .\"TABLE_END Do not delete this line. .TE .BR 1 diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 98cde9e46..ab63f14bd 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -7555,48 +7555,48 @@ of these miscreants in this, the list of Dungeoneers: \begin{center} \begin{tabular}{llll} %TABLE_START -Adam Aronow & J. Ali Harlow & Mikko Juola\\ -Alex Kompel & Janet Walz & Nathan Eady\\ -Alex Smith & Janne Salmij\"{a}rvi & Norm Meluch\\ -Andreas Dorn & Jean-Christophe Collet & Olaf Seibert\\ -Andy Church & Jeff Bailey & Pasi Kallinen\\ -Andy Swanson & Jochen Erwied & Pat Rankin\\ -Andy Thomson & John Kallen & Patric Mueller\\ -Ari Huttunen & John Rupley & Paul Winner\\ -Bart House & John S. Bien & Pierre Martineau\\ -Benson I. Margulies & Johnny Lee & Ralf Brown\\ -Bill Dyer & Jon W\textbraceleft tte & Ray Chason\\ -Boudewijn Waijers & Jonathan Handler & Richard Addison\\ -Bruce Cox & Joshua Delahunty & Richard Beigel\\ -Bruce Holloway & Karl Garrison & Richard P. Hughey\\ -Bruce Mewborne & Keizo Yamamoto & Rob Menke\\ -Carl Schelin & Keith Simpson & Robin Bandy\\ -Chris Russo & Ken Arnold & Robin Johnson\\ -David Cohrs & Ken Arromdee & Roderick Schertler\\ -David Damerell & Ken Lorber & Roland McGrath\\ -David Gentzel & Ken Washikita & Ron Van Iwaarden\\ -David Hairston & Kevin Darcy & Ronnen Miller\\ -Dean Luick & Kevin Hugo & Ross Brown\\ -Del Lamb & Kevin Sitze & Sascha Wostmann\\ -Derek S. Ray & Kevin Smolkowski & Scott Bigham\\ -Deron Meranda & Kevin Sweet & Scott R. Turner\\ -Dion Nicolaas & Lars Huttar & Sean Hunt\\ -Dylan O'Donnell & Leon Arnott & Stephen Spackman\\ -Eric Backus & M. Drew Streib & Stefan Thielscher\\ -Eric Hendrickson & Malcolm Ryan & Stephen White\\ -Eric R. Smith & Mark Gooderum & Steve Creps\\ -Eric S. Raymond & Mark Modrall & Steve Linhart\\ -Erik Andersen & Marvin Bressler & Steve VanDevender\\ -Fredrik Ljungdahl & Matthew Day & Teemu Suikki\\ -Frederick Roeber & Merlyn LeRoy & Tim Lennan\\ -Gil Neiger & Michael Allison & Timo Hakulinen\\ -Greg Laskin & Michael Feir & Tom Almy\\ -Greg Olson & Michael Hamel & Tom West\\ -Gregg Wonderly & Michael Sokolov & Warren Cheung\\ -Hao-yang Wang & Mike Engber & Warwick Allison\\ -Helge Hafting & Mike Gallop & Yitzhak Sapir\\ -Irina Rempt-Drijfhout & Mike Passaretti\\ -Izchak Miller & Mike Stephenson +Adam Aronow & Irina Rempt-Drijfhout & Mike Passaretti\\ +Alex Kompel & Izchak Miller & Mike Stephenson\\ +Alex Smith & J. Ali Harlow & Mikko Juola\\ +Andreas Dorn & Janet Walz & Nathan Eady\\ +Andy Church & Janne Salmij\"{a}rvi & Norm Meluch\\ +Andy Swanson & Jean-Christophe Collet & Olaf Seibert\\ +Andy Thomson & Jeff Bailey & Pasi Kallinen\\ +Ari Huttunen & Jochen Erwied & Pat Rankin\\ +Bart House & John Kallen & Patric Mueller\\ +Benson I. Margulies & John Rupley & Paul Winner\\ +Bill Dyer & John S. Bien & Pierre Martineau\\ +Boudewijn Waijers & Johnny Lee & Ralf Brown\\ +Bruce Cox & Jon W\{tte & Ray Chason\\ +Bruce Holloway & Jonathan Handler & Richard Addison\\ +Bruce Mewborne & Joshua Delahunty & Richard Beigel\\ +Carl Schelin & Karl Garrison & Richard P. Hughey\\ +Chris Russo & Keizo Yamamoto & Rob Menke\\ +David Cohrs & Keith Simpson & Robin Bandy\\ +David Damerell & Ken Arnold & Robin Johnson\\ +David Gentzel & Ken Arromdee & Roderick Schertler\\ +David Hairston & Ken Lorber & Roland McGrath\\ +Dean Luick & Ken Washikita & Ron Van Iwaarden\\ +Del Lamb & Kevin Darcy & Ronnen Miller\\ +Derek S. Ray & Kevin Hugo & Ross Brown\\ +Deron Meranda & Kevin Sitze & Sascha Wostmann\\ +Dion Nicolaas & Kevin Smolkowski & Scott Bigham\\ +Dylan O'Donnell & Kevin Sweet & Scott R. Turner\\ +Eric Backus & Lars Huttar & Sean Hunt\\ +Eric Hendrickson & Leon Arnott & Stephen Spackman\\ +Eric R. Smith & M. Drew Streib & Stefan Thielscher\\ +Eric S. Raymond & Malcolm Ryan & Stephen White\\ +Erik Andersen & Mark Gooderum & Steve Creps\\ +Fredrik Ljungdahl & Mark Modrall & Steve Linhart\\ +Frederick Roeber & Marvin Bressler & Steve VanDevender\\ +G. Branden Robinson & Matthew Day & Teemu Suikki\\ +Gil Neiger & Merlyn LeRoy & Tim Lennan\\ +Greg Laskin & Michael Allison & Timo Hakulinen\\ +Greg Olson & Michael Feir & Tom Almy\\ +Gregg Wonderly & Michael Hamel & Tom West\\ +Hao-yang Wang & Michael Sokolov & Warren Cheung\\ +Helge Hafting & Mike Engber & Warwick Allison\\ +Ingo Paschke & Mike Gallop & Yitzhak Sapir %TABLE_END Do not delete this line. \end{tabular} \end{center} From cc00eca91577e31ba106cdad913f7ba9b8893964 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 29 Apr 2026 14:58:03 -0400 Subject: [PATCH 082/702] documentation updates Dungeoneers list updates Michael Meyer (aka entrez on GitHub) provided a large number of fixes, updates and suggestions for the next upcoming release. --- dat/history | 85 ++++++++++++++++++++++++----------------------- doc/Guidebook.mn | 85 ++++++++++++++++++++++++----------------------- doc/Guidebook.tex | 85 ++++++++++++++++++++++++----------------------- 3 files changed, 129 insertions(+), 126 deletions(-) diff --git a/dat/history b/dat/history index 568fd8e9d..10bfa67a9 100644 --- a/dat/history +++ b/dat/history @@ -292,45 +292,46 @@ particularly intriguing modification to help out with the game. The NetHack Development Team sometimes makes note of the names of the worst of these miscreants in this, the list of Dungeoneers: - Adam Aronow Irina Rempt-Drijfhout Mike Passaretti - Alex Kompel Izchak Miller Mike Stephenson - Alex Smith J. Ali Harlow Mikko Juola - Andreas Dorn Janet Walz Nathan Eady - Andy Church Janne Salmijarvi Norm Meluch - Andy Swanson Jean-Christophe Collet Olaf Seibert - Andy Thomson Jeff Bailey Pasi Kallinen - Ari Huttunen Jochen Erwied Pat Rankin - Bart House John Kallen Patric Mueller - Benson I. Margulies John Rupley Paul Winner - Bill Dyer John S. Bien Pierre Martineau - Boudewijn Waijers Johnny Lee Ralf Brown - Bruce Cox Jon W{tte Ray Chason - Bruce Holloway Jonathan Handler Richard Addison - Bruce Mewborne Joshua Delahunty Richard Beigel - Carl Schelin Karl Garrison Richard P. Hughey - Chris Russo Keizo Yamamoto Rob Menke - David Cohrs Keith Simpson Robin Bandy - David Damerell Ken Arnold Robin Johnson - David Gentzel Ken Arromdee Roderick Schertler - David Hairston Ken Lorber Roland McGrath - Dean Luick Ken Washikita Ron Van Iwaarden - Del Lamb Kevin Darcy Ronnen Miller - Derek S. Ray Kevin Hugo Ross Brown - Deron Meranda Kevin Sitze Sascha Wostmann - Dion Nicolaas Kevin Smolkowski Scott Bigham - Dylan O'Donnell Kevin Sweet Scott R. Turner - Eric Backus Lars Huttar Sean Hunt - Eric Hendrickson Leon Arnott Stephen Spackman - Eric R. Smith M. Drew Streib Stefan Thielscher - Eric S. Raymond Malcolm Ryan Stephen White - Erik Andersen Mark Gooderum Steve Creps - Fredrik Ljungdahl Mark Modrall Steve Linhart - Frederick Roeber Marvin Bressler Steve VanDevender - G. Branden Robinson Matthew Day Teemu Suikki - Gil Neiger Merlyn LeRoy Tim Lennan - Greg Laskin Michael Allison Timo Hakulinen - Greg Olson Michael Feir Tom Almy - Gregg Wonderly Michael Hamel Tom West - Hao-yang Wang Michael Sokolov Warren Cheung - Helge Hafting Mike Engber Warwick Allison - Ingo Paschke Mike Gallop Yitzhak Sapir + Adam Aronow Izchak Miller Mike Stephenson + Alex Kompel J. Ali Harlow Mikko Juola + Alex Smith Janet Walz Nathan Eady + Andreas Dorn Janne Salmijarvi Norm Meluch + Andy Church Jean-Christophe Collet Olaf Seibert + Andy Swanson Jeff Bailey Pasi Kallinen + Andy Thomson Jochen Erwied Pat Rankin + Ari Huttunen John Kallen Patric Mueller + Bart House John Rupley Paul Winner + Benson I. Margulies John S. Bien Pierre Martineau + Bill Dyer Johnny Lee Ralf Brown + Boudewijn Waijers Jon W{tte Ray Chason + Bruce Cox Jonathan Handler Richard Addison + Bruce Holloway Joshua Delahunty Richard Beigel + Bruce Mewborne Karl Garrison Richard P. Hughey + Carl Schelin Keizo Yamamoto Rob Menke + Chris Russo Keith Simpson Robin Bandy + David Cohrs Ken Arnold Robin Johnson + David Damerell Ken Arromdee Roderick Schertler + David Gentzel Ken Lorber Roland McGrath + David Hairston Ken Washikita Ron Van Iwaarden + Dean Luick Kevin Darcy Ronnen Miller + Del Lamb Kevin Hugo Ross Brown + Derek S. Ray Kevin Sitze Sascha Wostmann + Deron Meranda Kevin Smolkowski Scott Bigham + Dion Nicolaas Kevin Sweet Scott R. Turner + Dylan O'Donnell Lars Huttar Sean Hunt + Eric Backus Leon Arnott Stephen Spackman + Eric Hendrickson M. Drew Streib Stefan Thielscher + Eric R. Smith Malcolm Ryan Stephen White + Eric S. Raymond Mark Gooderum Steve Creps + Erik Andersen Mark Modrall Steve Linhart + Fredrik Ljungdahl Marvin Bressler Steve VanDevender + Frederick Roeber Matthew Day Teemu Suikki + G. Branden Robinson Merlyn LeRoy Tim Lennan + Gil Neiger Michael Allison Timo Hakulinen + Greg Laskin Michael Feir Tom Almy + Greg Olson Michael Hamel Tom West + Gregg Wonderly Michael Meyer Warren Cheung + Hao-yang Wang Michael Sokolov Warwick Allison + Helge Hafting Mike Engber Yitzhak Sapir + Ingo Paschke Mike Gallop + Irina Rempt-Drijfhout Mike Passaretti diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index d74ce54be..44801028e 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -6811,48 +6811,49 @@ miscreants in this, the list of Dungeoneers: center; c2 c2 c. .\"TABLE_START -Adam Aronow Irina Rempt-Drijfhout Mike Passaretti -Alex Kompel Izchak Miller Mike Stephenson -Alex Smith J. Ali Harlow Mikko Juola -Andreas Dorn Janet Walz Nathan Eady -Andy Church Janne Salmijarvi Norm Meluch -Andy Swanson Jean-Christophe Collet Olaf Seibert -Andy Thomson Jeff Bailey Pasi Kallinen -Ari Huttunen Jochen Erwied Pat Rankin -Bart House John Kallen Patric Mueller -Benson I. Margulies John Rupley Paul Winner -Bill Dyer John S. Bien Pierre Martineau -Boudewijn Waijers Johnny Lee Ralf Brown -Bruce Cox Jon W{tte Ray Chason -Bruce Holloway Jonathan Handler Richard Addison -Bruce Mewborne Joshua Delahunty Richard Beigel -Carl Schelin Karl Garrison Richard P. Hughey -Chris Russo Keizo Yamamoto Rob Menke -David Cohrs Keith Simpson Robin Bandy -David Damerell Ken Arnold Robin Johnson -David Gentzel Ken Arromdee Roderick Schertler -David Hairston Ken Lorber Roland McGrath -Dean Luick Ken Washikita Ron Van Iwaarden -Del Lamb Kevin Darcy Ronnen Miller -Derek S. Ray Kevin Hugo Ross Brown -Deron Meranda Kevin Sitze Sascha Wostmann -Dion Nicolaas Kevin Smolkowski Scott Bigham -Dylan O'Donnell Kevin Sweet Scott R. Turner -Eric Backus Lars Huttar Sean Hunt -Eric Hendrickson Leon Arnott Stephen Spackman -Eric R. Smith M. Drew Streib Stefan Thielscher -Eric S. Raymond Malcolm Ryan Stephen White -Erik Andersen Mark Gooderum Steve Creps -Fredrik Ljungdahl Mark Modrall Steve Linhart -Frederick Roeber Marvin Bressler Steve VanDevender -G. Branden Robinson Matthew Day Teemu Suikki -Gil Neiger Merlyn LeRoy Tim Lennan -Greg Laskin Michael Allison Timo Hakulinen -Greg Olson Michael Feir Tom Almy -Gregg Wonderly Michael Hamel Tom West -Hao-yang Wang Michael Sokolov Warren Cheung -Helge Hafting Mike Engber Warwick Allison -Ingo Paschke Mike Gallop Yitzhak Sapir +Adam Aronow Izchak Miller Mike Stephenson +Alex Kompel J. Ali Harlow Mikko Juola +Alex Smith Janet Walz Nathan Eady +Andreas Dorn Janne Salmijarvi Norm Meluch +Andy Church Jean-Christophe Collet Olaf Seibert +Andy Swanson Jeff Bailey Pasi Kallinen +Andy Thomson Jochen Erwied Pat Rankin +Ari Huttunen John Kallen Patric Mueller +Bart House John Rupley Paul Winner +Benson I. Margulies John S. Bien Pierre Martineau +Bill Dyer Johnny Lee Ralf Brown +Boudewijn Waijers Jon W{tte Ray Chason +Bruce Cox Jonathan Handler Richard Addison +Bruce Holloway Joshua Delahunty Richard Beigel +Bruce Mewborne Karl Garrison Richard P. Hughey +Carl Schelin Keizo Yamamoto Rob Menke +Chris Russo Keith Simpson Robin Bandy +David Cohrs Ken Arnold Robin Johnson +David Damerell Ken Arromdee Roderick Schertler +David Gentzel Ken Lorber Roland McGrath +David Hairston Ken Washikita Ron Van Iwaarden +Dean Luick Kevin Darcy Ronnen Miller +Del Lamb Kevin Hugo Ross Brown +Derek S. Ray Kevin Sitze Sascha Wostmann +Deron Meranda Kevin Smolkowski Scott Bigham +Dion Nicolaas Kevin Sweet Scott R. Turner +Dylan O'Donnell Lars Huttar Sean Hunt +Eric Backus Leon Arnott Stephen Spackman +Eric Hendrickson M. Drew Streib Stefan Thielscher +Eric R. Smith Malcolm Ryan Stephen White +Eric S. Raymond Mark Gooderum Steve Creps +Erik Andersen Mark Modrall Steve Linhart +Fredrik Ljungdahl Marvin Bressler Steve VanDevender +Frederick Roeber Matthew Day Teemu Suikki +G. Branden Robinson Merlyn LeRoy Tim Lennan +Gil Neiger Michael Allison Timo Hakulinen +Greg Laskin Michael Feir Tom Almy +Greg Olson Michael Hamel Tom West +Gregg Wonderly Michael Meyer Warren Cheung +Hao-yang Wang Michael Sokolov Warwick Allison +Helge Hafting Mike Engber Yitzhak Sapir +Ingo Paschke Mike Gallop +Irina Rempt-Drijfhout Mike Passaretti .\"TABLE_END Do not delete this line. .TE .BR 1 diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index ab63f14bd..b48d5c53e 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -7555,48 +7555,49 @@ of these miscreants in this, the list of Dungeoneers: \begin{center} \begin{tabular}{llll} %TABLE_START -Adam Aronow & Irina Rempt-Drijfhout & Mike Passaretti\\ -Alex Kompel & Izchak Miller & Mike Stephenson\\ -Alex Smith & J. Ali Harlow & Mikko Juola\\ -Andreas Dorn & Janet Walz & Nathan Eady\\ -Andy Church & Janne Salmij\"{a}rvi & Norm Meluch\\ -Andy Swanson & Jean-Christophe Collet & Olaf Seibert\\ -Andy Thomson & Jeff Bailey & Pasi Kallinen\\ -Ari Huttunen & Jochen Erwied & Pat Rankin\\ -Bart House & John Kallen & Patric Mueller\\ -Benson I. Margulies & John Rupley & Paul Winner\\ -Bill Dyer & John S. Bien & Pierre Martineau\\ -Boudewijn Waijers & Johnny Lee & Ralf Brown\\ -Bruce Cox & Jon W\{tte & Ray Chason\\ -Bruce Holloway & Jonathan Handler & Richard Addison\\ -Bruce Mewborne & Joshua Delahunty & Richard Beigel\\ -Carl Schelin & Karl Garrison & Richard P. Hughey\\ -Chris Russo & Keizo Yamamoto & Rob Menke\\ -David Cohrs & Keith Simpson & Robin Bandy\\ -David Damerell & Ken Arnold & Robin Johnson\\ -David Gentzel & Ken Arromdee & Roderick Schertler\\ -David Hairston & Ken Lorber & Roland McGrath\\ -Dean Luick & Ken Washikita & Ron Van Iwaarden\\ -Del Lamb & Kevin Darcy & Ronnen Miller\\ -Derek S. Ray & Kevin Hugo & Ross Brown\\ -Deron Meranda & Kevin Sitze & Sascha Wostmann\\ -Dion Nicolaas & Kevin Smolkowski & Scott Bigham\\ -Dylan O'Donnell & Kevin Sweet & Scott R. Turner\\ -Eric Backus & Lars Huttar & Sean Hunt\\ -Eric Hendrickson & Leon Arnott & Stephen Spackman\\ -Eric R. Smith & M. Drew Streib & Stefan Thielscher\\ -Eric S. Raymond & Malcolm Ryan & Stephen White\\ -Erik Andersen & Mark Gooderum & Steve Creps\\ -Fredrik Ljungdahl & Mark Modrall & Steve Linhart\\ -Frederick Roeber & Marvin Bressler & Steve VanDevender\\ -G. Branden Robinson & Matthew Day & Teemu Suikki\\ -Gil Neiger & Merlyn LeRoy & Tim Lennan\\ -Greg Laskin & Michael Allison & Timo Hakulinen\\ -Greg Olson & Michael Feir & Tom Almy\\ -Gregg Wonderly & Michael Hamel & Tom West\\ -Hao-yang Wang & Michael Sokolov & Warren Cheung\\ -Helge Hafting & Mike Engber & Warwick Allison\\ -Ingo Paschke & Mike Gallop & Yitzhak Sapir +Adam Aronow & Izchak Miller & Mike Stephenson\\ +Alex Kompel & J. Ali Harlow & Mikko Juola\\ +Alex Smith & Janet Walz & Nathan Eady\\ +Andreas Dorn & Janne Salmij\"{a}rvi & Norm Meluch\\ +Andy Church & Jean-Christophe Collet & Olaf Seibert\\ +Andy Swanson & Jeff Bailey & Pasi Kallinen\\ +Andy Thomson & Jochen Erwied & Pat Rankin\\ +Ari Huttunen & John Kallen & Patric Mueller\\ +Bart House & John Rupley & Paul Winner\\ +Benson I. Margulies & John S. Bien & Pierre Martineau\\ +Bill Dyer & Johnny Lee & Ralf Brown\\ +Boudewijn Waijers & Jon W\{tte & Ray Chason\\ +Bruce Cox & Jonathan Handler & Richard Addison\\ +Bruce Holloway & Joshua Delahunty & Richard Beigel\\ +Bruce Mewborne & Karl Garrison & Richard P. Hughey\\ +Carl Schelin & Keizo Yamamoto & Rob Menke\\ +Chris Russo & Keith Simpson & Robin Bandy\\ +David Cohrs & Ken Arnold & Robin Johnson\\ +David Damerell & Ken Arromdee & Roderick Schertler\\ +David Gentzel & Ken Lorber & Roland McGrath\\ +David Hairston & Ken Washikita & Ron Van Iwaarden\\ +Dean Luick & Kevin Darcy & Ronnen Miller\\ +Del Lamb & Kevin Hugo & Ross Brown\\ +Derek S. Ray & Kevin Sitze & Sascha Wostmann\\ +Deron Meranda & Kevin Smolkowski & Scott Bigham\\ +Dion Nicolaas & Kevin Sweet & Scott R. Turner\\ +Dylan O'Donnell & Lars Huttar & Sean Hunt\\ +Eric Backus & Leon Arnott & Stephen Spackman\\ +Eric Hendrickson & M. Drew Streib & Stefan Thielscher\\ +Eric R. Smith & Malcolm Ryan & Stephen White\\ +Eric S. Raymond & Mark Gooderum & Steve Creps\\ +Erik Andersen & Mark Modrall & Steve Linhart\\ +Fredrik Ljungdahl & Marvin Bressler & Steve VanDevender\\ +Frederick Roeber & Matthew Day & Teemu Suikki\\ +G. Branden Robinson & Merlyn LeRoy & Tim Lennan\\ +Gil Neiger & Michael Allison & Timo Hakulinen\\ +Greg Laskin & Michael Feir & Tom Almy\\ +Greg Olson & Michael Hamel & Tom West\\ +Gregg Wonderly & Michael Meyer & Warren Cheung\\ +Hao-yang Wang & Michael Sokolov & Warwick Allison\\ +Helge Hafting & Mike Engber & Yitzhak Sapir\\ +Ingo Paschke & Mike Gallop\\ +Irina Rempt-Drijfhout & Mike Passaretti %TABLE_END Do not delete this line. \end{tabular} \end{center} From a646c3d55e38245df4ea795e054815a4bec2dfc8 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Wed, 29 Apr 2026 15:16:15 -0400 Subject: [PATCH 083/702] This is cron-daily v1-Apr-26-2026. 005guidebook updated: doc/Guidebook.txt --- doc/Guidebook.txt | 78 +++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 885dafdd5..3827a7dda 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -7636,17 +7636,17 @@ - Adam Aronow J. Ali Harlow Mikko Juola - Alex Kompel Janet Walz Nathan Eady - Alex Smith Janne Salmijarvi Norm Meluch - Andreas Dorn Jean-Christophe Collet Olaf Seibert - Andy Church Jeff Bailey Pasi Kallinen - Andy Swanson Jochen Erwied Pat Rankin - Andy Thomson John Kallen Patric Mueller - Ari Huttunen John Rupley Paul Winner - Bart House John S. Bien Pierre Martineau - Benson I. Margulies Johnny Lee Ralf Brown - Bill Dyer Jon W{tte Ray Chason + Adam Aronow Izchak Miller Mike Stephenson + Alex Kompel J. Ali Harlow Mikko Juola + Alex Smith Janet Walz Nathan Eady + Andreas Dorn Janne Salmijarvi Norm Meluch + Andy Church Jean-Christophe Collet Olaf Seibert + Andy Swanson Jeff Bailey Pasi Kallinen + Andy Thomson Jochen Erwied Pat Rankin + Ari Huttunen John Kallen Patric Mueller + Bart House John Rupley Paul Winner + Benson I. Margulies John S. Bien Pierre Martineau + Bill Dyer Johnny Lee Ralf Brown @@ -7660,38 +7660,38 @@ - Boudewijn Waijers Jonathan Handler Richard Addison - Bruce Cox Joshua Delahunty Richard Beigel - Bruce Holloway Karl Garrison Richard P. Hughey - Bruce Mewborne Keizo Yamamoto Rob Menke - Carl Schelin Keith Simpson Robin Bandy - Chris Russo Ken Arnold Robin Johnson - David Cohrs Ken Arromdee Roderick Schertler - David Damerell Ken Lorber Roland McGrath - David Gentzel Ken Washikita Ron Van Iwaarden - David Hairston Kevin Darcy Ronnen Miller - Dean Luick Kevin Hugo Ross Brown - Del Lamb Kevin Sitze Sascha Wostmann - Derek S. Ray Kevin Smolkowski Scott Bigham - Deron Meranda Kevin Sweet Scott R. Turner - Dion Nicolaas Lars Huttar Sean Hunt - Dylan O'Donnell Leon Arnott Stephen Spackman - Eric Backus M. Drew Streib Stefan Thielscher - Eric Hendrickson Malcolm Ryan Stephen White - Eric R. Smith Mark Gooderum Steve Creps - Eric S. Raymond Mark Modrall Steve Linhart - Erik Andersen Marvin Bressler Steve VanDevender - Fredrik Ljungdahl Matthew Day Teemu Suikki - Frederick Roeber Merlyn LeRoy Tim Lennan + Boudewijn Waijers Jon W{tte Ray Chason + Bruce Cox Jonathan Handler Richard Addison + Bruce Holloway Joshua Delahunty Richard Beigel + Bruce Mewborne Karl Garrison Richard P. Hughey + Carl Schelin Keizo Yamamoto Rob Menke + Chris Russo Keith Simpson Robin Bandy + David Cohrs Ken Arnold Robin Johnson + David Damerell Ken Arromdee Roderick Schertler + David Gentzel Ken Lorber Roland McGrath + David Hairston Ken Washikita Ron Van Iwaarden + Dean Luick Kevin Darcy Ronnen Miller + Del Lamb Kevin Hugo Ross Brown + Derek S. Ray Kevin Sitze Sascha Wostmann + Deron Meranda Kevin Smolkowski Scott Bigham + Dion Nicolaas Kevin Sweet Scott R. Turner + Dylan O'Donnell Lars Huttar Sean Hunt + Eric Backus Leon Arnott Stephen Spackman + Eric Hendrickson M. Drew Streib Stefan Thielscher + Eric R. Smith Malcolm Ryan Stephen White + Eric S. Raymond Mark Gooderum Steve Creps + Erik Andersen Mark Modrall Steve Linhart + Fredrik Ljungdahl Marvin Bressler Steve VanDevender + Frederick Roeber Matthew Day Teemu Suikki + G. Branden Robinson Merlyn LeRoy Tim Lennan Gil Neiger Michael Allison Timo Hakulinen Greg Laskin Michael Feir Tom Almy Greg Olson Michael Hamel Tom West - Gregg Wonderly Michael Sokolov Warren Cheung - Hao-yang Wang Mike Engber Warwick Allison - Helge Hafting Mike Gallop Yitzhak Sapir + Gregg Wonderly Michael Meyer Warren Cheung + Hao-yang Wang Michael Sokolov Warwick Allison + Helge Hafting Mike Engber Yitzhak Sapir + Ingo Paschke Mike Gallop Irina Rempt-Drijfhout Mike Passaretti - Izchak Miller Mike Stephenson - From f98428001c2b31a6f7bdbde41c8a6ac665b58860 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Thu, 30 Apr 2026 01:17:01 +0100 Subject: [PATCH 084/702] Fix a bug in price quote display They weren't displaying in, e.g., the menu to pick up multiple objects at once, which is a particularly important place to display them. --- src/objnam.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/objnam.c b/src/objnam.c index 1246029fd..cd50e0bb5 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1673,9 +1673,11 @@ doname_base( nochrg ? "contents" : "for sale", pricebuf); } else if (nochrg > 0) { Concat(bp, 0, " (no charge)"); + } else { + append_price_quote(bp, &bp_eos, obj->otyp); } - if (price) + if (price > 0L) record_price_quote(obj->otyp, price / obj->quan, TRUE); } else if (iflags.pricequotes && !objects[obj->otyp].oc_name_known) { append_price_quote(bp, &bp_eos, obj->otyp); From 702fbfa06ed5bbdb1bc6d72c2226d84764fa6b49 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 29 Apr 2026 21:48:52 -0400 Subject: [PATCH 085/702] make the inclusion of NHUUID support the default in hints files On macOS, the required underlying pieces are in there. On Linux, we try to test for the presence of libuuid and the uuid.h header files. If the tests are both successful, we proceed to include NHUUID support. On either macOS or Linux, NO_NHUUID=1 on the Make command line will forcibly prevent the inclusion of the support for NHUUID. --- sys/unix/hints/include/multiw-2.370 | 4 --- sys/unix/hints/linux.370 | 41 ++++++++++++++++++++++++++--- sys/unix/hints/macOS.370 | 9 ++++++- 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/sys/unix/hints/include/multiw-2.370 b/sys/unix/hints/include/multiw-2.370 index ca732f6c8..e1cf1633d 100644 --- a/sys/unix/hints/include/multiw-2.370 +++ b/sys/unix/hints/include/multiw-2.370 @@ -168,10 +168,6 @@ CPLUSPLUS_NEED_DEPSUPPRESS = 1 endif # WANT_WIN_QT6 endif # WANT_WIN_QT -ifdef WANT_NHUUID -USE_UUIDLIB=1 -endif - ifeq "$(GIT)" "1" ifndef GITSUBMODULES GITSUBMODULES=1 diff --git a/sys/unix/hints/linux.370 b/sys/unix/hints/linux.370 index ea239260e..a8c4bc212 100755 --- a/sys/unix/hints/linux.370 +++ b/sys/unix/hints/linux.370 @@ -227,11 +227,46 @@ ifdef MAKEFILE_SRC ifdef CURSESLIB WINLIB += $(CURSESLIB) endif #CURSESLIB -ifdef WANT_NHUUID + +ifneq "$(NO_NHUUID)" "1" +UUID_LIB_CHECK := $(shell echo `/sbin/ldconfig -p | grep libuuid`) +#$(info UUID_LIB_CHECK=$(UUID_LIB_CHECK)) +ifneq "$(UUID_LIB_CHECK)" "" +UUID_LIB=1 +else +UUID_LIB=0 +endif +#$(info UUID_LIB=$(UUID_LIB)) +# +# check for uuid development headers +UUID_HEADERS_CHECK := $(wildcard /usr/include/uuid/uuid.h) +#$(info UUID_HEADERS_CHECK=$(UUID_HEADERS_CHECK)) +ifneq "$(UUID_HEADERS_CHECK)" "" +UUID_HEADERS = 1 +else +UUID_HEADERS = 0 +endif +#$(info UUID_HEADERS=$(UUID_HEADERS)) + +ifeq "$(UUID_LIB)" "1" +ifeq "$(UUID_HEADERS)" "1" +ifndef WANT_NHUUID +WANT_NHUUID=1 +endif +endif +endif +else # NO_NHUUID +WANT_NHUUID=0 +endif # NO_NHUUID + +ifeq "$(WANT_NHUUID)" "1" +#$(info NHUUID support will be included) CFLAGS+= -DNHUUID LIBS+=-luuid -endif #NHUUID -endif #MAKEFILE_SRC +else # WANT_NHUUID +$(info Attention - No NHUUID support will be included) +endif # WANT_NHUUID +endif # MAKEFILE_SRC ifdef WANT_WIN_X11 USE_XPM=1 diff --git a/sys/unix/hints/macOS.370 b/sys/unix/hints/macOS.370 index 006c54a45..c48926805 100755 --- a/sys/unix/hints/macOS.370 +++ b/sys/unix/hints/macOS.370 @@ -216,11 +216,18 @@ LFLAGS += -framework AVFoundation endif ifdef MAKEFILE_SRC +ifndef NO_NHUUID +# macOS doesn't need any extra prerequisite libraries +# so do this unconditionally, unless NO_NHUUID=1 is +# passed on the Make command line. +WANT_NHUUID=1 +endif #NO_NHUUID + ifdef WANT_NHUUID CFLAGS += -DNHUUID UUIDOBJ = macuuid.o endif -endif +endif #MAKEFILE_SRC # #-INCLUDE multisnd1-pre.370 From 84a6eb5e224d3cece2a888cc85501b682b17b1d5 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 29 Apr 2026 23:43:01 -0400 Subject: [PATCH 086/702] avoid impossible() with inbound migrating mon --- include/monst.h | 1 + src/display.c | 2 ++ src/dog.c | 4 ++++ 3 files changed, 7 insertions(+) diff --git a/include/monst.h b/include/monst.h index 6b3262706..1d16a05db 100644 --- a/include/monst.h +++ b/include/monst.h @@ -64,6 +64,7 @@ enum m_ap_types { #define MON_ENDGAME_FREE 0x20 #define MON_ENDGAME_MIGR 0x40 #define MON_OBLITERATE 0x80 +#define MON_STILL_ARRIVING 0x100 #define M_AP_TYPMASK 0x7 #define M_AP_F_DKNOWN 0x8 diff --git a/src/display.c b/src/display.c index d3241ce9f..cb8f0f6be 100644 --- a/src/display.c +++ b/src/display.c @@ -1505,6 +1505,8 @@ see_monsters(void) for (mon = fmon; mon; mon = mon->nmon) { if (DEADMONSTER(mon)) continue; + if ((mon->mstate & MON_STILL_ARRIVING) != 0) + continue; newsym(mon->mx, mon->my); if (mon->wormno) see_wsegs(mon); diff --git a/src/dog.c b/src/dog.c index f9676050c..675ca4676 100644 --- a/src/dog.c +++ b/src/dog.c @@ -427,6 +427,7 @@ mon_arrive(struct monst *mtmp, int when) stairway *stway; d_level fromdlev; + mtmp->mstate |= MON_STILL_ARRIVING; mtmp->nmon = fmon; fmon = mtmp; if (mtmp->isshk) @@ -475,6 +476,7 @@ mon_arrive(struct monst *mtmp, int when) rloc_to(mtmp, u.ux, u.uy); else mnexto(mtmp, RLOC_NOMSG); + mtmp->mstate &= ~MON_STILL_ARRIVING; return; } else if (when == Wiz_arrive) { /* resurrect() is bringing existing wizard to harass the hero */ @@ -604,6 +606,8 @@ mon_arrive(struct monst *mtmp, int when) mtmp->mx = 0; /*(already is 0)*/ mtmp->my = xyflags; + mtmp->mstate &= ~MON_STILL_ARRIVING; + if (xlocale) failed_to_place = !mnearto(mtmp, xlocale, ylocale, FALSE, RLOC_NOMSG); else From 5035b3695604f167101f1b097dad9986beb19a32 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 29 Apr 2026 23:48:19 -0400 Subject: [PATCH 087/702] possible macOS build fix I need someone with arm64 Mac to confirm. --- sys/unix/hints/macOS.370 | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/unix/hints/macOS.370 b/sys/unix/hints/macOS.370 index c48926805..ba54d72ab 100755 --- a/sys/unix/hints/macOS.370 +++ b/sys/unix/hints/macOS.370 @@ -226,6 +226,7 @@ endif #NO_NHUUID ifdef WANT_NHUUID CFLAGS += -DNHUUID UUIDOBJ = macuuid.o +LFLAGS += -framework foundation endif endif #MAKEFILE_SRC From 6c36009ce428b116650b6d08a9b94de79684dd5b Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 29 Apr 2026 23:55:48 -0400 Subject: [PATCH 088/702] case bit --- sys/unix/hints/macOS.370 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/unix/hints/macOS.370 b/sys/unix/hints/macOS.370 index ba54d72ab..5b78f6245 100755 --- a/sys/unix/hints/macOS.370 +++ b/sys/unix/hints/macOS.370 @@ -226,7 +226,7 @@ endif #NO_NHUUID ifdef WANT_NHUUID CFLAGS += -DNHUUID UUIDOBJ = macuuid.o -LFLAGS += -framework foundation +LFLAGS += -framework Foundation endif endif #MAKEFILE_SRC From 52c74222c2f036348b9038ce42d3642e997bff4e Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 30 Apr 2026 07:07:44 +0300 Subject: [PATCH 089/702] Update perm_inventory when returning to human form Embedded dragon scales weren't updated to worn --- src/polyself.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/polyself.c b/src/polyself.c index 2461a1b79..db3824bb4 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1408,6 +1408,7 @@ rehumanize(void) disp.botl = TRUE; gv.vision_full_recalc = 1; encumber_msg(); + update_inventory(); if (was_flying && !Flying && u.usteed) You("and %s return gently to the %s.", mon_nam(u.usteed), surface(u.ux, u.uy)); From c99da87c7006cac968e0243775afebda8cfc11fa Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 29 Apr 2026 21:17:31 -0700 Subject: [PATCH 090/702] issue #1506 - Str 18/50 Requested by Tomsod: change the break point for +2 damage bonus from strength to be 18/50 instead of 18/51 so that gnome and orc heros can achieve that 'naturally' by maxxing out Str. Closes #1506 --- src/weapon.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/weapon.c b/src/weapon.c index b400ac91c..708e2bc3a 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -954,14 +954,19 @@ abon(void) if (Upolyd) return (adj_lev(&mons[u.umonnum]) - 3); + + /* this used to be '<= 18/50' for bonus of 1 but got changed to '< 18/50' + so that '18/50' gives a bonus of 2; gnome and orc player characters + have max Str of 18/50 and giving an extra bonus at that break point + provides an incentive for them to max out that characteristic */ if (str < 6) sbon = -2; else if (str < 8) sbon = -1; else if (str < 17) sbon = 0; - else if (str <= STR18(50)) - sbon = 1; /* up to 18/50 */ + else if (str < STR18(50)) + sbon = 1; /* up to 18/49 */ else if (str < STR18(100)) sbon = 2; else From 2b985be3b9e9dc65a46bad0fd925e72d29d62f35 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 30 Apr 2026 01:13:40 -0400 Subject: [PATCH 091/702] macOS fixes --- sys/unix/NetHack.xcodeproj/project.pbxproj | 10 ++++++++ sys/unix/macuuid.m | 27 +++++++++++++++++----- sys/unix/unixmain.c | 20 ++++++---------- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/sys/unix/NetHack.xcodeproj/project.pbxproj b/sys/unix/NetHack.xcodeproj/project.pbxproj index e379e51f8..81a1eb1b9 100644 --- a/sys/unix/NetHack.xcodeproj/project.pbxproj +++ b/sys/unix/NetHack.xcodeproj/project.pbxproj @@ -209,6 +209,7 @@ F5857AA22DED026700A8CB4F /* version.c in Sources */ = {isa = PBXBuildFile; fileRef = 31B8A32721A238010055BD01 /* version.c */; }; F5857AA42DED032D00A8CB4F /* cfgfiles.c in Sources */ = {isa = PBXBuildFile; fileRef = F5857AA32DED032C00A8CB4F /* cfgfiles.c */; }; F5857AA62DED03BB00A8CB4F /* sfbase.c in Sources */ = {isa = PBXBuildFile; fileRef = F5857AA52DED03BB00A8CB4F /* sfbase.c */; }; + F5E1A4CF2FA2F74C0014D115 /* macuuid.m in Sources */ = {isa = PBXBuildFile; fileRef = F5E1A4CE2FA2F74C0014D115 /* macuuid.m */; }; F5E66A222F7D4B30000E30B7 /* earlyarg.c in Sources */ = {isa = PBXBuildFile; fileRef = F5E66A212F7D4B30000E30B7 /* earlyarg.c */; }; /* End PBXBuildFile section */ @@ -635,6 +636,7 @@ F54C1AE42E43D22A006CAA8E /* sfprocs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = sfprocs.h; path = ../../include/include/sfprocs.h; sourceTree = ""; }; F5857AA32DED032C00A8CB4F /* cfgfiles.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cfgfiles.c; path = ../../src/cfgfiles.c; sourceTree = ""; }; F5857AA52DED03BB00A8CB4F /* sfbase.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = sfbase.c; path = ../../src/sfbase.c; sourceTree = ""; }; + F5E1A4CE2FA2F74C0014D115 /* macuuid.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = macuuid.m; sourceTree = ""; }; F5E66A212F7D4B30000E30B7 /* earlyarg.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = earlyarg.c; path = ../../src/earlyarg.c; sourceTree = ""; }; /* End PBXFileReference section */ @@ -695,6 +697,7 @@ 3189576821A1FCC100FB2ABE = { isa = PBXGroup; children = ( + F5E1A4CE2FA2F74C0014D115 /* macuuid.m */, F5E66A212F7D4B30000E30B7 /* earlyarg.c */, F50818302F6F564300D2AAFA /* iactions.c */, F515A73B2DED0B47006E1F63 /* hacklib.c */, @@ -1883,6 +1886,7 @@ 31B8A38621A238060055BD01 /* mondata.c in Sources */, 31B8A41921A244940055BD01 /* objects.c in Sources */, 31B8A3AA21A238060055BD01 /* wizard.c in Sources */, + F5E1A4CF2FA2F74C0014D115 /* macuuid.m in Sources */, 31B8A3D021A238060055BD01 /* explode.c in Sources */, 31B8A3DE21A238060055BD01 /* sys.c in Sources */, 31B8A38021A238060055BD01 /* sit.c in Sources */, @@ -2190,6 +2194,7 @@ "DEBUG=1", "$(inherited)", ); + "GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = "NHUUID=1"; GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_PEDANTIC = YES; @@ -2318,6 +2323,10 @@ DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 5J8MP36Y73; GCC_C_LANGUAGE_STANDARD = c99; + "GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = ( + "DEBUG=1", + "$(inherited)", + ); INSTALL_PATH = "$(NH_INSTALL_DIR)"; MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; OTHER_CFLAGS = ( @@ -2351,6 +2360,7 @@ DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 5J8MP36Y73; GCC_C_LANGUAGE_STANDARD = c99; + "GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = "NHUUID=1"; INSTALL_PATH = "$(NH_INSTALL_DIR)"; MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; OTHER_CFLAGS = ( diff --git a/sys/unix/macuuid.m b/sys/unix/macuuid.m index 67a4f2486..fb5dc6699 100644 --- a/sys/unix/macuuid.m +++ b/sys/unix/macuuid.m @@ -5,7 +5,7 @@ #include "hack.h" void free_macos_uuid(void); -const char *get_macos_uuid(void); +void get_macos_uuid(char *); #ifdef DEBUG #undef DEBUG @@ -25,19 +25,34 @@ free_macos_uuid(void) } } -const char * -get_macos_uuid(void) +void +get_macos_uuid(char *target) { NSString *uuidString = [[NSUUID UUID] UUIDString]; - const char *str_uuid; - + const char *str_uuid, *src; + char *dst; + int i; + if (macos_uuid) free_macos_uuid(); /* str_uuid = [uuidString cStringUsingEncoding:NSUTF8StringEncoding]; */ str_uuid = [uuidString cStringUsingEncoding:NSASCIIStringEncoding]; macos_uuid = dupstr(str_uuid); - return macos_uuid; + + if (macos_uuid) { + src = macos_uuid; + dst = target; + for (i = 0; i < 36; ++i) { + *dst = *src; + ++src; + ++dst; + } + dst[36] = '\0'; + } + free_macos_uuid(); + macos_uuid = 0; + return; } diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index a197056cc..73318c506 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -842,19 +842,16 @@ sys_random_seed(void) } #if defined(MACOS) && defined(NHUUID) -extern char *get_macos_uuid(char **); /* sys/unix/macuuid.m */ +extern void get_macos_uuid(char *); /* sys/unix/macuuid.m */ extern void free_macos_uuid(void); /* sys/unix/macuuid.m */ #endif void get_nhuuid(void) { -#if !defined(MACOS) #if defined(NHUUID) char struuid[37] = { 0 }; -#endif -#endif - char *struuidptr = NULL; + char *struuidptr = &struuid[0]; #if defined(LINUX) && defined(NHUUID) uuid_t binuuid; #endif @@ -862,20 +859,17 @@ get_nhuuid(void) if (svn.nhuuid[0]) return; -#if defined(MACOS) && defined(NHUUID) - get_macos_uuid(&struuidptr); -#elif defined(LINUX) && defined(NHUUID) +#if defined(MACOS) + get_macos_uuid(&struuid[0]); +#elif defined(LINUX) uuid_generate_random(binuuid); uuid_unparse(binuuid, struuid); - struuidptr = &struuid[0]; #endif /* MACOS || LINUX */ - if (struuidptr) + if (*struuidptr) Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", struuidptr); -#if defined(MACOS) && defined(NHUUID) - free_macos_uuid(); -#endif +#endif /* NHUUID */ } void From 22ab0456d0dedfbb22bbd447863c03e4a25af302 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 30 Apr 2026 01:28:07 -0400 Subject: [PATCH 092/702] follow-up: don't clear the bit until end of function --- src/dog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dog.c b/src/dog.c index 675ca4676..742af8dc8 100644 --- a/src/dog.c +++ b/src/dog.c @@ -606,7 +606,6 @@ mon_arrive(struct monst *mtmp, int when) mtmp->mx = 0; /*(already is 0)*/ mtmp->my = xyflags; - mtmp->mstate &= ~MON_STILL_ARRIVING; if (xlocale) failed_to_place = !mnearto(mtmp, xlocale, ylocale, FALSE, RLOC_NOMSG); @@ -620,6 +619,7 @@ mon_arrive(struct monst *mtmp, int when) else /* when==Wiz_arrive => not being called by losedogs() */ m_into_limbo(mtmp); } + mtmp->mstate &= ~MON_STILL_ARRIVING; } /* heal monster for time spent elsewhere */ From 82854b79364f60dca68ba57e01f726224ae1cdc1 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 30 Apr 2026 01:39:18 -0400 Subject: [PATCH 093/702] documentation updates more Dungeoneers list updates for valued contributors --- dat/history | 86 +++++++++++++++++++++++------------------------ doc/Guidebook.mn | 86 +++++++++++++++++++++++------------------------ doc/Guidebook.tex | 86 +++++++++++++++++++++++------------------------ 3 files changed, 129 insertions(+), 129 deletions(-) diff --git a/dat/history b/dat/history index 10bfa67a9..5b495b2ca 100644 --- a/dat/history +++ b/dat/history @@ -292,46 +292,46 @@ particularly intriguing modification to help out with the game. The NetHack Development Team sometimes makes note of the names of the worst of these miscreants in this, the list of Dungeoneers: - Adam Aronow Izchak Miller Mike Stephenson - Alex Kompel J. Ali Harlow Mikko Juola - Alex Smith Janet Walz Nathan Eady - Andreas Dorn Janne Salmijarvi Norm Meluch - Andy Church Jean-Christophe Collet Olaf Seibert - Andy Swanson Jeff Bailey Pasi Kallinen - Andy Thomson Jochen Erwied Pat Rankin - Ari Huttunen John Kallen Patric Mueller - Bart House John Rupley Paul Winner - Benson I. Margulies John S. Bien Pierre Martineau - Bill Dyer Johnny Lee Ralf Brown - Boudewijn Waijers Jon W{tte Ray Chason - Bruce Cox Jonathan Handler Richard Addison - Bruce Holloway Joshua Delahunty Richard Beigel - Bruce Mewborne Karl Garrison Richard P. Hughey - Carl Schelin Keizo Yamamoto Rob Menke - Chris Russo Keith Simpson Robin Bandy - David Cohrs Ken Arnold Robin Johnson - David Damerell Ken Arromdee Roderick Schertler - David Gentzel Ken Lorber Roland McGrath - David Hairston Ken Washikita Ron Van Iwaarden - Dean Luick Kevin Darcy Ronnen Miller - Del Lamb Kevin Hugo Ross Brown - Derek S. Ray Kevin Sitze Sascha Wostmann - Deron Meranda Kevin Smolkowski Scott Bigham - Dion Nicolaas Kevin Sweet Scott R. Turner - Dylan O'Donnell Lars Huttar Sean Hunt - Eric Backus Leon Arnott Stephen Spackman - Eric Hendrickson M. Drew Streib Stefan Thielscher - Eric R. Smith Malcolm Ryan Stephen White - Eric S. Raymond Mark Gooderum Steve Creps - Erik Andersen Mark Modrall Steve Linhart - Fredrik Ljungdahl Marvin Bressler Steve VanDevender - Frederick Roeber Matthew Day Teemu Suikki - G. Branden Robinson Merlyn LeRoy Tim Lennan - Gil Neiger Michael Allison Timo Hakulinen - Greg Laskin Michael Feir Tom Almy - Greg Olson Michael Hamel Tom West - Gregg Wonderly Michael Meyer Warren Cheung - Hao-yang Wang Michael Sokolov Warwick Allison - Helge Hafting Mike Engber Yitzhak Sapir - Ingo Paschke Mike Gallop - Irina Rempt-Drijfhout Mike Passaretti + Adam Aronow Irina Rempt-Drijfhout Mike Gallop + Alex Kompel Izchak Miller Mike Passaretti + Alex Smith J. Ali Harlow Mike Stephenson + Andreas Dorn Janet Walz Mikko Juola + Andy Church Janne Salmijarvi Nathan Eady + Andy Swanson Jean-Christophe Collet Norm Meluch + Andy Thomson Jeff Bailey Olaf Seibert + Ari Huttunen Jochen Erwied Pasi Kallinen + Bart House John Kallen Pat Rankin + Benson I. Margulies John Rupley Patric Mueller + Bill Dyer John S. Bien Paul Winner + Boudewijn Waijers Johnny Lee Pierre Martineau + Bruce Cox Jon W{tte Ralf Brown + Bruce Holloway Jonathan Handler Ray Chason + Bruce Mewborne Joshua Delahunty Richard Addison + Cameron Root Karl Garrison Richard Beigel + Carl Schelin Keizo Yamamoto Richard P. Hughey + Chris Russo Keith Simpson Rob Menke + David Cohrs Ken Arnold Robin Bandy + David Damerell Ken Arromdee Robin Johnson + David Gentzel Ken Lorber Roderick Schertler + David Hairston Ken Washikita Roland McGrath + Dean Luick Kestrel Gregorich-Trevor Ron Van Iwaarden + Del Lamb Kevin Darcy Ronnen Miller + Derek S. Ray Kevin Hugo Ross Brown + Deron Meranda Kevin Sitze Sascha Wostmann + Dion Nicolaas Kevin Smolkowski Scott Bigham + Dylan O'Donnell Kevin Sweet Scott R. Turner + Eric Backus Lars Huttar Sean Hunt + Eric Hendrickson Leon Arnott Stephen Spackman + Eric R. Smith M. Drew Streib Stefan Thielscher + Eric S. Raymond Malcolm Ryan Stephen White + Erik Andersen Mark Gooderum Steve Creps + Fredrik Ljungdahl Mark Modrall Steve Linhart + Frederick Roeber Marvin Bressler Steve VanDevender + G. Branden Robinson Matthew Day Teemu Suikki + Gil Neiger Merlyn LeRoy Tim Lennan + Greg Laskin Michael Allison Timo Hakulinen + Greg Olson Michael Feir Tom Almy + Gregg Wonderly Michael Hamel Tom West + Hao-yang Wang Michael Meyer Warren Cheung + Helge Hafting Michael Sokolov Warwick Allison + Ingo Paschke Mike Engber Yitzhak Sapir diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 44801028e..4d1499510 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -6811,49 +6811,49 @@ miscreants in this, the list of Dungeoneers: center; c2 c2 c. .\"TABLE_START -Adam Aronow Izchak Miller Mike Stephenson -Alex Kompel J. Ali Harlow Mikko Juola -Alex Smith Janet Walz Nathan Eady -Andreas Dorn Janne Salmijarvi Norm Meluch -Andy Church Jean-Christophe Collet Olaf Seibert -Andy Swanson Jeff Bailey Pasi Kallinen -Andy Thomson Jochen Erwied Pat Rankin -Ari Huttunen John Kallen Patric Mueller -Bart House John Rupley Paul Winner -Benson I. Margulies John S. Bien Pierre Martineau -Bill Dyer Johnny Lee Ralf Brown -Boudewijn Waijers Jon W{tte Ray Chason -Bruce Cox Jonathan Handler Richard Addison -Bruce Holloway Joshua Delahunty Richard Beigel -Bruce Mewborne Karl Garrison Richard P. Hughey -Carl Schelin Keizo Yamamoto Rob Menke -Chris Russo Keith Simpson Robin Bandy -David Cohrs Ken Arnold Robin Johnson -David Damerell Ken Arromdee Roderick Schertler -David Gentzel Ken Lorber Roland McGrath -David Hairston Ken Washikita Ron Van Iwaarden -Dean Luick Kevin Darcy Ronnen Miller -Del Lamb Kevin Hugo Ross Brown -Derek S. Ray Kevin Sitze Sascha Wostmann -Deron Meranda Kevin Smolkowski Scott Bigham -Dion Nicolaas Kevin Sweet Scott R. Turner -Dylan O'Donnell Lars Huttar Sean Hunt -Eric Backus Leon Arnott Stephen Spackman -Eric Hendrickson M. Drew Streib Stefan Thielscher -Eric R. Smith Malcolm Ryan Stephen White -Eric S. Raymond Mark Gooderum Steve Creps -Erik Andersen Mark Modrall Steve Linhart -Fredrik Ljungdahl Marvin Bressler Steve VanDevender -Frederick Roeber Matthew Day Teemu Suikki -G. Branden Robinson Merlyn LeRoy Tim Lennan -Gil Neiger Michael Allison Timo Hakulinen -Greg Laskin Michael Feir Tom Almy -Greg Olson Michael Hamel Tom West -Gregg Wonderly Michael Meyer Warren Cheung -Hao-yang Wang Michael Sokolov Warwick Allison -Helge Hafting Mike Engber Yitzhak Sapir -Ingo Paschke Mike Gallop -Irina Rempt-Drijfhout Mike Passaretti +Adam Aronow Irina Rempt-Drijfhout Mike Gallop +Alex Kompel Izchak Miller Mike Passaretti +Alex Smith J. Ali Harlow Mike Stephenson +Andreas Dorn Janet Walz Mikko Juola +Andy Church Janne Salmijarvi Nathan Eady +Andy Swanson Jean-Christophe Collet Norm Meluch +Andy Thomson Jeff Bailey Olaf Seibert +Ari Huttunen Jochen Erwied Pasi Kallinen +Bart House John Kallen Pat Rankin +Benson I. Margulies John Rupley Patric Mueller +Bill Dyer John S. Bien Paul Winner +Boudewijn Waijers Johnny Lee Pierre Martineau +Bruce Cox Jon W{tte Ralf Brown +Bruce Holloway Jonathan Handler Ray Chason +Bruce Mewborne Joshua Delahunty Richard Addison +Cameron Root Karl Garrison Richard Beigel +Carl Schelin Keizo Yamamoto Richard P. Hughey +Chris Russo Keith Simpson Rob Menke +David Cohrs Ken Arnold Robin Bandy +David Damerell Ken Arromdee Robin Johnson +David Gentzel Ken Lorber Roderick Schertler +David Hairston Ken Washikita Roland McGrath +Dean Luick Kestrel Gregorich-Trevor Ron Van Iwaarden +Del Lamb Kevin Darcy Ronnen Miller +Derek S. Ray Kevin Hugo Ross Brown +Deron Meranda Kevin Sitze Sascha Wostmann +Dion Nicolaas Kevin Smolkowski Scott Bigham +Dylan O'Donnell Kevin Sweet Scott R. Turner +Eric Backus Lars Huttar Sean Hunt +Eric Hendrickson Leon Arnott Stephen Spackman +Eric R. Smith M. Drew Streib Stefan Thielscher +Eric S. Raymond Malcolm Ryan Stephen White +Erik Andersen Mark Gooderum Steve Creps +Fredrik Ljungdahl Mark Modrall Steve Linhart +Frederick Roeber Marvin Bressler Steve VanDevender +G. Branden Robinson Matthew Day Teemu Suikki +Gil Neiger Merlyn LeRoy Tim Lennan +Greg Laskin Michael Allison Timo Hakulinen +Greg Olson Michael Feir Tom Almy +Gregg Wonderly Michael Hamel Tom West +Hao-yang Wang Michael Meyer Warren Cheung +Helge Hafting Michael Sokolov Warwick Allison +Ingo Paschke Mike Engber Yitzhak Sapir .\"TABLE_END Do not delete this line. .TE .BR 1 diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index b48d5c53e..3539b0242 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -7555,49 +7555,49 @@ of these miscreants in this, the list of Dungeoneers: \begin{center} \begin{tabular}{llll} %TABLE_START -Adam Aronow & Izchak Miller & Mike Stephenson\\ -Alex Kompel & J. Ali Harlow & Mikko Juola\\ -Alex Smith & Janet Walz & Nathan Eady\\ -Andreas Dorn & Janne Salmij\"{a}rvi & Norm Meluch\\ -Andy Church & Jean-Christophe Collet & Olaf Seibert\\ -Andy Swanson & Jeff Bailey & Pasi Kallinen\\ -Andy Thomson & Jochen Erwied & Pat Rankin\\ -Ari Huttunen & John Kallen & Patric Mueller\\ -Bart House & John Rupley & Paul Winner\\ -Benson I. Margulies & John S. Bien & Pierre Martineau\\ -Bill Dyer & Johnny Lee & Ralf Brown\\ -Boudewijn Waijers & Jon W\{tte & Ray Chason\\ -Bruce Cox & Jonathan Handler & Richard Addison\\ -Bruce Holloway & Joshua Delahunty & Richard Beigel\\ -Bruce Mewborne & Karl Garrison & Richard P. Hughey\\ -Carl Schelin & Keizo Yamamoto & Rob Menke\\ -Chris Russo & Keith Simpson & Robin Bandy\\ -David Cohrs & Ken Arnold & Robin Johnson\\ -David Damerell & Ken Arromdee & Roderick Schertler\\ -David Gentzel & Ken Lorber & Roland McGrath\\ -David Hairston & Ken Washikita & Ron Van Iwaarden\\ -Dean Luick & Kevin Darcy & Ronnen Miller\\ -Del Lamb & Kevin Hugo & Ross Brown\\ -Derek S. Ray & Kevin Sitze & Sascha Wostmann\\ -Deron Meranda & Kevin Smolkowski & Scott Bigham\\ -Dion Nicolaas & Kevin Sweet & Scott R. Turner\\ -Dylan O'Donnell & Lars Huttar & Sean Hunt\\ -Eric Backus & Leon Arnott & Stephen Spackman\\ -Eric Hendrickson & M. Drew Streib & Stefan Thielscher\\ -Eric R. Smith & Malcolm Ryan & Stephen White\\ -Eric S. Raymond & Mark Gooderum & Steve Creps\\ -Erik Andersen & Mark Modrall & Steve Linhart\\ -Fredrik Ljungdahl & Marvin Bressler & Steve VanDevender\\ -Frederick Roeber & Matthew Day & Teemu Suikki\\ -G. Branden Robinson & Merlyn LeRoy & Tim Lennan\\ -Gil Neiger & Michael Allison & Timo Hakulinen\\ -Greg Laskin & Michael Feir & Tom Almy\\ -Greg Olson & Michael Hamel & Tom West\\ -Gregg Wonderly & Michael Meyer & Warren Cheung\\ -Hao-yang Wang & Michael Sokolov & Warwick Allison\\ -Helge Hafting & Mike Engber & Yitzhak Sapir\\ -Ingo Paschke & Mike Gallop\\ -Irina Rempt-Drijfhout & Mike Passaretti +Adam Aronow & Irina Rempt-Drijfhout & Mike Gallop\\ +Alex Kompel & Izchak Miller & Mike Passaretti\\ +Alex Smith & J. Ali Harlow & Mike Stephenson\\ +Andreas Dorn & Janet Walz & Mikko Juola\\ +Andy Church & Janne Salmij\"{a}rvi & Nathan Eady\\ +Andy Swanson & Jean-Christophe Collet & Norm Meluch\\ +Andy Thomson & Jeff Bailey & Olaf Seibert\\ +Ari Huttunen & Jochen Erwied & Pasi Kallinen\\ +Bart House & John Kallen & Pat Rankin\\ +Benson I. Margulies & John Rupley & Patric Mueller\\ +Bill Dyer & John S. Bien & Paul Winner\\ +Boudewijn Waijers & Johnny Lee & Pierre Martineau\\ +Bruce Cox & Jon W\{tte & Ralf Brown\\ +Bruce Holloway & Jonathan Handler & Ray Chason\\ +Bruce Mewborne & Joshua Delahunty & Richard Addison\\ +Cameron Root & Karl Garrison & Richard Beigel\\ +Carl Schelin & Keizo Yamamoto & Richard P. Hughey\\ +Chris Russo & Keith Simpson & Rob Menke\\ +David Cohrs & Ken Arnold & Robin Bandy\\ +David Damerell & Ken Arromdee & Robin Johnson\\ +David Gentzel & Ken Lorber & Roderick Schertler\\ +David Hairston & Ken Washikita & Roland McGrath\\ +Dean Luick & Kestrel Gregorich-Trevor & Ron Van Iwaarden\\ +Del Lamb & Kevin Darcy & Ronnen Miller\\ +Derek S. Ray & Kevin Hugo & Ross Brown\\ +Deron Meranda & Kevin Sitze & Sascha Wostmann\\ +Dion Nicolaas & Kevin Smolkowski & Scott Bigham\\ +Dylan O'Donnell & Kevin Sweet & Scott R. Turner\\ +Eric Backus & Lars Huttar & Sean Hunt\\ +Eric Hendrickson & Leon Arnott & Stephen Spackman\\ +Eric R. Smith & M. Drew Streib & Stefan Thielscher\\ +Eric S. Raymond & Malcolm Ryan & Stephen White\\ +Erik Andersen & Mark Gooderum & Steve Creps\\ +Fredrik Ljungdahl & Mark Modrall & Steve Linhart\\ +Frederick Roeber & Marvin Bressler & Steve VanDevender\\ +G. Branden Robinson & Matthew Day & Teemu Suikki\\ +Gil Neiger & Merlyn LeRoy & Tim Lennan\\ +Greg Laskin & Michael Allison & Timo Hakulinen\\ +Greg Olson & Michael Feir & Tom Almy\\ +Gregg Wonderly & Michael Hamel & Tom West\\ +Hao-yang Wang & Michael Meyer & Warren Cheung\\ +Helge Hafting & Michael Sokolov & Warwick Allison\\ +Ingo Paschke & Mike Engber & Yitzhak Sapir %TABLE_END Do not delete this line. \end{tabular} \end{center} From 7fdaf923679d670492f4c07435e792f1d56c1a4e Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Thu, 30 Apr 2026 09:15:22 +0100 Subject: [PATCH 094/702] Reduce generation probabilities of the wand of digging In earlier versions of NetHack, wands of digging generated fairly often, allowing players to do a large amount of digging through the maze walls in Gehennom and giving them a chance of an early escape item. In the current version, the need for both of these things has been reduced: supply chests give a supply of early escape items (including wands of digging), and Gehennom is no longer mostly made of mazes with diggable walls. As such, there is no longer a reason to generate wands of digging in such large numbers, even though it was correct in the past. This commit modifies some of the generation probabilities for wands of digging in order to make them less abundant, in order to work better with the code changes since the previous version. --- doc/fixes3-7-0.txt | 1 + include/objects.h | 8 ++++---- src/makemon.c | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index d9a068c73..65da5b0cf 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1603,6 +1603,7 @@ when starting a new game as a monk, newsym(0,0) was being called (adjabil -> became level 1; seen 'monster' was the hero who hadn't been placed on the map yet) incorporate a fix to prevent segfault due to rolling boulder trap +wands of digging generate less often lategame Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/include/objects.h b/include/objects.h index 41076db28..b9c35f273 100644 --- a/include/objects.h +++ b/include/objects.h @@ -1453,7 +1453,7 @@ WAND("secret door detection", WAN_SECRET_DOOR_DETECTION), WAND("enlightenment", "crystal", 15, 150, 1, NODIR, GLASS, HI_GLASS, WAN_ENLIGHTENMENT), -WAND("create monster", "maple", 45, 200, 1, NODIR, WOOD, HI_WOOD, +WAND("create monster", "maple", 50, 200, 1, NODIR, WOOD, HI_WOOD, WAN_CREATE_MONSTER), WAND("wishing", "pine", 5, 500, 1, NODIR, WOOD, HI_WOOD, WAN_WISHING), @@ -1477,13 +1477,13 @@ WAND("cancellation", "platinum", 45, 200, 1, IMMEDIATE, PLATINUM, CLR_WHITE, WAN_CANCELLATION), WAND("teleportation", "iridium", 45, 200, 1, IMMEDIATE, METAL, CLR_BRIGHT_CYAN, WAN_TELEPORTATION), -WAND("opening", "zinc", 25, 150, 1, IMMEDIATE, METAL, HI_METAL, +WAND("opening", "zinc", 30, 150, 1, IMMEDIATE, METAL, HI_METAL, WAN_OPENING), -WAND("locking", "aluminum", 25, 150, 1, IMMEDIATE, METAL, HI_METAL, +WAND("locking", "aluminum", 30, 150, 1, IMMEDIATE, METAL, HI_METAL, WAN_LOCKING), WAND("probing", "uranium", 30, 150, 1, IMMEDIATE, METAL, HI_METAL, WAN_PROBING), -WAND("digging", "iron", 55, 150, 1, RAY, IRON, HI_METAL, +WAND("digging", "iron", 40, 150, 1, RAY, IRON, HI_METAL, WAN_DIGGING), /* magic missile ... lightning must be in this order; see buzz() */ WAND("magic missile", "steel", 50, 150, 1, RAY, IRON, HI_METAL, diff --git a/src/makemon.c b/src/makemon.c index 6f158ee01..5cbb98cb3 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -738,7 +738,7 @@ m_initinv(struct monst *mtmp) break; case S_GIANT: if (ptr == &mons[PM_MINOTAUR]) { - if (!rn2(3) || (gi.in_mklev && Is_earthlevel(&u.uz))) + if (!rn2(8) || (gi.in_mklev && Is_earthlevel(&u.uz))) (void) mongets(mtmp, WAN_DIGGING); } else if (is_giant(ptr)) { for (cnt = rn2((int) (mtmp->m_lev / 2)); cnt; cnt--) { From c5b258c2cf9237500f418ef867e27330429dcd2b Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 30 Apr 2026 09:08:29 -0400 Subject: [PATCH 095/702] more empty bonesfile --- include/hack.h | 1 + src/bones.c | 12 ++++++------ src/sfstruct.c | 3 ++- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/hack.h b/include/hack.h index 19f543ac0..b59a712b1 100644 --- a/include/hack.h +++ b/include/hack.h @@ -798,6 +798,7 @@ struct sinfo { int config_error_ready; /* config_error_add is ready, available */ int beyond_savefile_load; /* set when past savefile loading */ int savefile_completed; /* savefile has completed writing */ + int reading_bonesfile; /* in the midst of trying to read bones file */ #ifdef PANICLOG int in_paniclog; /* writing a panicloc entry */ #endif diff --git a/src/bones.c b/src/bones.c index 3e484279f..85431390f 100644 --- a/src/bones.c +++ b/src/bones.c @@ -659,19 +659,19 @@ getbones(void) return 0; } - restoreinfo.mread_flags = 1; /* return despite error for a bones file */ + program_state.reading_bonesfile = 1; if (validate(nhfp, gb.bones, FALSE) != SF_UPTODATE) { if (!wizard) pline("Discarding unusable bones; no need to panic..."); ok = FALSE; - restoreinfo.mread_flags = 0; + program_state.reading_bonesfile = 0; } else { ok = TRUE; if (wizard) { if (y_n("Get bones?") == 'n') { close_nhfile(nhfp); compress_bonesfile(); - restoreinfo.mread_flags = 0; + program_state.reading_bonesfile = 0; return 0; } } @@ -687,7 +687,7 @@ getbones(void) close_nhfile(nhfp); compress_bonesfile(); /* ToDo: maybe unlink these problematic bones? */ - restoreinfo.mread_flags = 0; + program_state.reading_bonesfile = 0; return 0; } if (strcmp(bonesid, oldbonesid) != 0) { @@ -699,7 +699,7 @@ getbones(void) pline1(errbuf); ok = FALSE; /* won't die of trickery */ } - restoreinfo.mread_flags = 0; + program_state.reading_bonesfile = 0; trickery(errbuf); } else { struct monst *mtmp; @@ -731,8 +731,8 @@ getbones(void) fix_shop_damage(); } } - restoreinfo.mread_flags = 0; close_nhfile(nhfp); + program_state.reading_bonesfile = 0; sanitize_engravings(); u.uroleplay.numbones++; diff --git a/src/sfstruct.c b/src/sfstruct.c index 8a15a0c17..5e793079b 100644 --- a/src/sfstruct.c +++ b/src/sfstruct.c @@ -572,7 +572,8 @@ mread(int fd, genericptr_t buf, unsigned len) /* Not perfect, but we don't have ssize_t available. */ rlen = (readLenType) read(fd, buf, (readLenType) len); if ((readLenType) rlen != (readLenType) len) { - if (restoreinfo.mread_flags == 1) { /* means "return anyway" */ + if ((restoreinfo.mread_flags == 1) /* means "return anyway" */ + || (program_state.reading_bonesfile == 1)) { restoreinfo.mread_flags = -1; return; } else { From 319dd3887338b00c61c516eac58fe317894ee12a Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 30 Apr 2026 09:27:50 -0400 Subject: [PATCH 096/702] simplify get_macos_uuid() also remove a magic number 37 by replacing it with NHUUIDSZ --- include/decl.h | 2 +- include/hack.h | 4 ++++ sys/unix/macuuid.m | 33 +++++---------------------------- sys/unix/unixmain.c | 8 +++----- 4 files changed, 13 insertions(+), 34 deletions(-) diff --git a/include/decl.h b/include/decl.h index 1ea39d6f9..8ca46678a 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1175,7 +1175,7 @@ struct instance_globals_saved_n { /* dungeon.c */ int n_dgns; /* number of dungeons (also used in mklev.c and do.c) */ /* files.c */ - char nhuuid[37]; + char nhuuid[NHUUIDSZ]; /* mkroom.c */ int nroom; /* region.c */ diff --git a/include/hack.h b/include/hack.h index b59a712b1..425094f5b 100644 --- a/include/hack.h +++ b/include/hack.h @@ -709,6 +709,10 @@ enum nhcb_calls { NUM_NHCB }; +#ifdef NHUUID +#define NHUUIDSZ 37 +#endif + struct plinemsg_type { xint16 msgtype; /* one of MSGTYP_foo */ struct nhregex *regex; diff --git a/sys/unix/macuuid.m b/sys/unix/macuuid.m index fb5dc6699..26b86e3b6 100644 --- a/sys/unix/macuuid.m +++ b/sys/unix/macuuid.m @@ -4,7 +4,6 @@ #include "hack.h" -void free_macos_uuid(void); void get_macos_uuid(char *); #ifdef DEBUG @@ -14,44 +13,22 @@ void get_macos_uuid(char *); /* #import */ #import -static const char *macos_uuid = 0; - -void -free_macos_uuid(void) -{ - if (macos_uuid) { - free((genericptr_t) macos_uuid); - macos_uuid = 0; - } -} - void get_macos_uuid(char *target) { NSString *uuidString = [[NSUUID UUID] UUIDString]; - const char *str_uuid, *src; - char *dst; + const char *str_uuid; int i; - if (macos_uuid) - free_macos_uuid(); - /* str_uuid = [uuidString cStringUsingEncoding:NSUTF8StringEncoding]; */ str_uuid = [uuidString cStringUsingEncoding:NSASCIIStringEncoding]; - macos_uuid = dupstr(str_uuid); - if (macos_uuid) { - src = macos_uuid; - dst = target; - for (i = 0; i < 36; ++i) { - *dst = *src; - ++src; - ++dst; + if (str_uuid && target) { + for (i = 0; i < (NHUUIDSZ -1 ); ++i) { + target[i] = str_uuid[i]; } - dst[36] = '\0'; + target[(NHUUIDSZ - 1)] = '\0'; } - free_macos_uuid(); - macos_uuid = 0; return; } diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 73318c506..265e73619 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -843,15 +843,13 @@ sys_random_seed(void) #if defined(MACOS) && defined(NHUUID) extern void get_macos_uuid(char *); /* sys/unix/macuuid.m */ -extern void free_macos_uuid(void); /* sys/unix/macuuid.m */ #endif void get_nhuuid(void) { #if defined(NHUUID) - char struuid[37] = { 0 }; - char *struuidptr = &struuid[0]; + char struuid[NHUUIDSZ] = { 0 }; #if defined(LINUX) && defined(NHUUID) uuid_t binuuid; #endif @@ -866,8 +864,8 @@ get_nhuuid(void) uuid_unparse(binuuid, struuid); #endif /* MACOS || LINUX */ - if (*struuidptr) - Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", struuidptr); + if (struuid[0]) + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", struuid); #endif /* NHUUID */ } From c5e48213d24ab335a171528fce583d7a6b8e6a41 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 30 Apr 2026 09:37:40 -0400 Subject: [PATCH 097/702] Qt and c++ use a different set of CFLAGS --- include/hack.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/hack.h b/include/hack.h index 425094f5b..6cde43efe 100644 --- a/include/hack.h +++ b/include/hack.h @@ -709,9 +709,7 @@ enum nhcb_calls { NUM_NHCB }; -#ifdef NHUUID #define NHUUIDSZ 37 -#endif struct plinemsg_type { xint16 msgtype; /* one of MSGTYP_foo */ From 7d4885e2fd76b7a0526df1d867f71f9cd716d972 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 30 Apr 2026 20:06:20 -0400 Subject: [PATCH 098/702] updated Guidebook.mn history text --- doc/Guidebook.mn | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 3ac3b7481..9023fb885 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -6777,6 +6777,72 @@ some bug fixes. NetHack 3.6.7 was released on February 16, 2023 containing a security fix and some bug fixes. .pg +Development work for the major release to follow NetHack 3.6 begain in 2015 +around the same time as NetHack 3.6.0 was being released. That development +work continued in parallel to each of the NetHack 3.6 releases from 2015 +through 2023, and continued until the end of April 2026. For the first time, +that development was shared publicly on GitHub and SourceForge as it occurred. +It was done under the label NetHack-3.7 work-in-progress (WIP), although the +version number for the next release had not yet been solidified. +.pg +Exposure of the development to the public brought many good things, and some +challenges. People were able to observe and critize changes and new features +almost immediately, and they often did. The GitHub pull request system made +it straightforward for people to contribute directly to development. +Contributions resolved many, many bugs in the game and we thank all the +contributors. +.pg +In early 2026, with the game development getting stable enough to consider +initiating an official release, the devteam reviewed the nature and number of +changes in the game. It was clear that there was sufficient depth and +breadth to warrant a major release and version 5.0 was decided on. +That's a new major release over 3.x, without opening up any ambiguity +or confusion with existing variants that there might have been had it +been released version 4.0. +.pg +NetHack 5.0.0 was released on ???? ??, 2026. +.pg +The source code for NetHack 5.0.0 was modified and modernized to be +compliant with standard C99. +.pg +NetHack 5.0 was the first version to replace the lex and yacc level +and dungeon compilers of past versions, with a new Lua interpreter-based +approach to provide those elements. Lua is also used for the quest texts +in NetHack 5.0.0. The entire development team acknowledges the work +done by \fBPasi Kallinen\fP to make that happen. +.pg +At the time of the NetHack 5.0 release, the core development team, +active and alumni, included \fBWarwick Allison\fP, \fBMichael Allison\fP, +\fBKen Arromdee\fP, \fBDavid Cohrs\fP, \fBJessie Collet\fP, \fBBart House\fP, +\fBKevin Hugo\fP, \fBPasi Kallinen\fP, \fBKen Lorber\fP, \fBDean Luick\fP, +\fBPat Rankin\fP, \fBDerek S. Ray\fP, \bBAlex Smith\fP, \fBPatric Mueller\fP, +\fBMike Stephenson\fP, \fBJanet Walz\fP, \fBPaul Winner\fP. +.pg +\fBKen Lorber\fP, \fBPat Rankin\fP, \fBPatrick Mueller\fP and +\fBMichael Allison\fP helped ensure that NetHack 5.0 would run +on macOS. +.pg +\fBIngo Paschke\fP somehow managed to revive a NetHack 5.0 port for the Amiga, +using a cross-compiler on a modern platform to do so. His work was shared so +other's can straightforwardly produce NetHack 5.0 for the Amiga thanks to his +efforts. +.pg +\fBRay Chason\fP contributed the majority of maintenance work for the +NetHack 5.0 MS-DOS port, including porting the curses interface to it. +\fBMichael Allison\fP ensured that NetHack 5.0 core changes continued to +work with the msdos port and keep it alive. Cross-compiling the MS-DOS +port has helped make that possible and mostly painless. +.pg +People that contributed to the Windows port of NetHack 5.0 since the +development of NetHack 5.0 begain over eleven years ago, included +\fBMichael Allison\fP, \fBDavid Cohrs\fP, \fBBart House\fP, +\fBPasi Kallinen\fP, \fBAlex Kompel\fP, \fBDion Nicolaas\fP, +\fBDerek S. Ray\fP and \fBYitzhak Sapir\fP. +.pg +With sadness, the devteam would like to acknowledge and remember the past +contributions from the late \fBRon Van Iwaarden\fP, who was the sole maintainer +of NetHack for OS/2 for several past NetHack releases. Ron will be missed. +.pg The official NetHack web site is maintained by \fBKen Lorber\fP at .UR https://www.nethack.org/ . From 49fac6b422ad7ba83394087158a70702914b6a1b Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 30 Apr 2026 20:12:08 -0400 Subject: [PATCH 099/702] a couple of typos --- doc/Guidebook.mn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 9023fb885..2aca7edda 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -6777,7 +6777,7 @@ some bug fixes. NetHack 3.6.7 was released on February 16, 2023 containing a security fix and some bug fixes. .pg -Development work for the major release to follow NetHack 3.6 begain in 2015 +Development work for the major release to follow NetHack 3.6 began in 2015 around the same time as NetHack 3.6.0 was being released. That development work continued in parallel to each of the NetHack 3.6 releases from 2015 through 2023, and continued until the end of April 2026. For the first time, @@ -6786,7 +6786,7 @@ It was done under the label NetHack-3.7 work-in-progress (WIP), although the version number for the next release had not yet been solidified. .pg Exposure of the development to the public brought many good things, and some -challenges. People were able to observe and critize changes and new features +challenges. People were able to observe and criticize changes and new features almost immediately, and they often did. The GitHub pull request system made it straightforward for people to contribute directly to development. Contributions resolved many, many bugs in the game and we thank all the From e607982c6a721467ad66123b0f1a1c0f7c1f2716 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 30 Apr 2026 20:38:14 -0400 Subject: [PATCH 100/702] whitespace --- doc/Guidebook.mn | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 2aca7edda..fb4c82eb9 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -6132,7 +6132,7 @@ If your platform or terminal supports the display of UTF-8 character sequences, you can customize your game display by assigning Unicode codepoint values and \fIred-green-blue\fP colors to glyph representations. The customizations can be specified for use with a symset that -has a UTF8 handler within the symbols file such as the enhanced1 set, or +has a UTF8 handler within the symbols file such as the enhanced1 set, or individually within your nethack.rc file. .pg The format for defining a glyph representation is: @@ -6153,7 +6153,7 @@ U+224B and the color represented by R-G-B value 0-0-160: OPTIONS=glyph:G_pool/U+224B/0-0-160 .ft .ED -The list of acceptable glyphid's can be produced by +The list of acceptable glyphid's can be produced by \fBnethack \-\-dumpglyphids\fP. Individual NetHack glyphs can be specified using the G_ prefix, or you can use an S_ symbol for a glyphid and store the custom @@ -6794,15 +6794,15 @@ contributors. .pg In early 2026, with the game development getting stable enough to consider initiating an official release, the devteam reviewed the nature and number of -changes in the game. It was clear that there was sufficient depth and +changes in the game. It was clear that there was sufficient depth and breadth to warrant a major release and version 5.0 was decided on. That's a new major release over 3.x, without opening up any ambiguity or confusion with existing variants that there might have been had it been released version 4.0. .pg -NetHack 5.0.0 was released on ???? ??, 2026. +NetHack 5.0.0 was released on , 2026. .pg -The source code for NetHack 5.0.0 was modified and modernized to be +The source code for NetHack 5.0.0 was modified and modernized to be compliant with standard C99. .pg NetHack 5.0 was the first version to replace the lex and yacc level @@ -6816,8 +6816,8 @@ active and alumni, included \fBWarwick Allison\fP, \fBMichael Allison\fP, \fBKen Arromdee\fP, \fBDavid Cohrs\fP, \fBJessie Collet\fP, \fBBart House\fP, \fBKevin Hugo\fP, \fBPasi Kallinen\fP, \fBKen Lorber\fP, \fBDean Luick\fP, \fBPat Rankin\fP, \fBDerek S. Ray\fP, \bBAlex Smith\fP, \fBPatric Mueller\fP, -\fBMike Stephenson\fP, \fBJanet Walz\fP, \fBPaul Winner\fP. -.pg +\fBMike Stephenson\fP, \fBJanet Walz\fP, \fBPaul Winner\fP. +.pg \fBKen Lorber\fP, \fBPat Rankin\fP, \fBPatrick Mueller\fP and \fBMichael Allison\fP helped ensure that NetHack 5.0 would run on macOS. From 82dc90c713128fa26beb360c3327869a9e4eaf94 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 30 Apr 2026 22:59:07 -0700 Subject: [PATCH 101/702] newsym() impossible() band-aid Prevent the main vision_recalc loop from triggering an impossible for bad coordinates from newsym(). This hack may mean that the underlying problem will remain unsolved but at least newsym won't cause the fuzzer to panic or frighten players with impossible warnings. --- src/vision.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/vision.c b/src/vision.c index 90bd965a9..ce293ade4 100644 --- a/src/vision.c +++ b/src/vision.c @@ -822,7 +822,18 @@ vision_recalc(int control) if ((old_row[col] & IN_SIGHT) || ((next_row[col] & COULD_SEE) ^ (old_row[col] & COULD_SEE))) + { + /* + * TEMPORARY? Sometimes we get here with col==0 and + * newsym()'s impossible() for !isok() is being + * triggered, so avoid calling it for <0,y>; other bad + * coordinates will produce a panic() as they should. + */ + if (col != 0) + /* + */ newsym(col, row); + } } } /* end for col . . */ From 88309ebfd19185309bd634346a40f7ede0bb88f6 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 1 May 2026 07:46:38 -0400 Subject: [PATCH 102/702] wording bit --- doc/Guidebook.mn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index fb4c82eb9..13a59e1da 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -6812,7 +6812,7 @@ in NetHack 5.0.0. The entire development team acknowledges the work done by \fBPasi Kallinen\fP to make that happen. .pg At the time of the NetHack 5.0 release, the core development team, -active and alumni, included \fBWarwick Allison\fP, \fBMichael Allison\fP, +active and erstwhile, included \fBWarwick Allison\fP, \fBMichael Allison\fP, \fBKen Arromdee\fP, \fBDavid Cohrs\fP, \fBJessie Collet\fP, \fBBart House\fP, \fBKevin Hugo\fP, \fBPasi Kallinen\fP, \fBKen Lorber\fP, \fBDean Luick\fP, \fBPat Rankin\fP, \fBDerek S. Ray\fP, \bBAlex Smith\fP, \fBPatric Mueller\fP, From 7f824c8d5c3926e3d075c6f918af44fe0b3bc30d Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 1 May 2026 07:58:02 -0400 Subject: [PATCH 103/702] Guidebook type --- doc/Guidebook.mn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 13a59e1da..72a3fad13 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -6815,7 +6815,7 @@ At the time of the NetHack 5.0 release, the core development team, active and erstwhile, included \fBWarwick Allison\fP, \fBMichael Allison\fP, \fBKen Arromdee\fP, \fBDavid Cohrs\fP, \fBJessie Collet\fP, \fBBart House\fP, \fBKevin Hugo\fP, \fBPasi Kallinen\fP, \fBKen Lorber\fP, \fBDean Luick\fP, -\fBPat Rankin\fP, \fBDerek S. Ray\fP, \bBAlex Smith\fP, \fBPatric Mueller\fP, +\fBPat Rankin\fP, \fBDerek S. Ray\fP, \fBAlex Smith\fP, \fBPatric Mueller\fP, \fBMike Stephenson\fP, \fBJanet Walz\fP, \fBPaul Winner\fP. .pg \fBKen Lorber\fP, \fBPat Rankin\fP, \fBPatrick Mueller\fP and From cfcc3bad8565ef4e383ad393e0d1ec2443a0dcd6 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 1 May 2026 08:37:33 -0400 Subject: [PATCH 104/702] wording/grammar bit in Cross-compiling --- Cross-compiling | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cross-compiling b/Cross-compiling index 285e824b5..dc2085652 100644 --- a/Cross-compiling +++ b/Cross-compiling @@ -642,7 +642,7 @@ Cross-compiler url: https://emscripten.org/docs/getting_started/downloads.html sudo apt-get install python3 cmake default-jre - For macOS, you will need to install Xcode, git, cmake, Python 3.5 or new + For macOS, you will need to install Xcode, git, cmake, Python 3.5 or newer (at time of this writing). After installing the prerequisite packages above, obtain the cross-compiler From a165d9ee429f9230ed9275936500f8915e413cf7 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 1 May 2026 09:11:29 -0400 Subject: [PATCH 105/702] preprocessor macro: MAC -> MACOS9 --- include/config.h | 12 ++++++------ include/config1.h | 8 ++++---- include/dlb.h | 2 +- include/extern.h | 2 +- include/flag.h | 2 +- include/global.h | 2 +- include/optlist.h | 6 +++--- include/tcap.h | 2 +- include/winprocs.h | 6 +++--- include/wintty.h | 6 +++--- outdated/include/mac-carbon.h | 1 + outdated/include/mac-qt.h | 1 + outdated/include/mac-term.h | 1 + outdated/include/macconf.h | 6 +++--- outdated/include/system.h | 12 ++++++------ outdated/win/gem/wingem.c | 4 ++-- src/allmain.c | 2 +- src/cfgfiles.c | 8 ++++---- src/eat.c | 2 +- src/end.c | 2 +- src/files.c | 30 +++++++++++++++--------------- src/getpos.c | 4 ++-- src/mdlib.c | 4 ++-- src/options.c | 12 ++++++------ src/shknam.c | 2 +- src/windows.c | 12 ++++++------ util/dlb_main.c | 2 +- util/makedefs.c | 18 +++++++++--------- win/curses/cursmain.c | 2 +- win/share/tilemap.c | 2 +- win/tty/getline.c | 2 +- win/tty/wintty.c | 4 ++-- 32 files changed, 92 insertions(+), 89 deletions(-) diff --git a/include/config.h b/include/config.h index 6eacad389..f5a44b289 100644 --- a/include/config.h +++ b/include/config.h @@ -36,7 +36,7 @@ /* Hint: if you're not developing code, don't define ULTRIX_PROTO. */ -#include "config1.h" /* should auto-detect MSDOS, MAC, AMIGA, and WIN32 */ +#include "config1.h" /* should auto-detect MSDOS, MACOS9, AMIGA, and WIN32 */ /* * Consolidated version, patchlevel, development status. @@ -67,8 +67,8 @@ * tty, X11, mac, amii, BeOS, Qt, Gem, Gnome, shim */ -/* MAC also means MAC windows */ -#ifdef MAC +/* MACOS9 also means MAC windows */ +#ifdef MACOS9 #ifndef AUX #define DEFAULT_WINDOW_SYS "mac" #endif @@ -339,7 +339,7 @@ #define ENTRYMAX 100 /* must be >= 10 */ #endif #ifndef PERS_IS_UID -#if !defined(MICRO) && !defined(MAC) && !defined(WIN32) +#if !defined(MICRO) && !defined(MACOS9) && !defined(WIN32) #define PERS_IS_UID 1 /* delete for PERSMAX per name; now per uid */ #else #define PERS_IS_UID 0 @@ -434,7 +434,7 @@ */ #define INSURANCE /* allow crashed game recovery */ -#if !defined(MAC) && !defined(SHIM_GRAPHICS) +#if !defined(MACOS9) && !defined(SHIM_GRAPHICS) #define CHDIR /* delete if no chdir() available */ #endif @@ -533,7 +533,7 @@ typedef unsigned char uchar; #define MACRO_CPATH /* use clear_path macros instead of functions */ #endif -#if !defined(MAC) +#if !defined(MACOS9) #if !defined(NOCLIPPING) #define CLIPPING /* allow smaller screens -- ERS */ #endif diff --git a/include/config1.h b/include/config1.h index 402e0e73c..8048be9d6 100644 --- a/include/config1.h +++ b/include/config1.h @@ -45,23 +45,23 @@ #endif #ifdef macintosh /* Auto-defined symbol for MPW compilers (sc and mrc) */ -#define MAC +#define MACOS9 #endif #ifdef THINK_C /* Think C auto-defined symbol */ -#define MAC +#define MACOS9 #define NEED_VARARGS #endif #ifdef __MWERKS__ /* defined by Metrowerks' Codewarrior compiler */ #ifndef __BEOS__ /* BeOS */ -#define MAC +#define MACOS9 #endif #define NEED_VARARGS #define USE_STDARG #endif -#if defined(MAC) || defined(__BEOS__) +#if defined(MACOS9) || defined(__BEOS__) #define DLB #undef UNIX #endif diff --git a/include/dlb.h b/include/dlb.h index 2fff03046..654b8c344 100644 --- a/include/dlb.h +++ b/include/dlb.h @@ -9,7 +9,7 @@ #ifdef DLB /* implementations */ -#if defined(MAC) && !defined(MAC_CROSS) +#if defined(MACOS9) && !defined(MACOS9_CROSS) #define DLBRSRC /* use Mac resources */ #else #define DLBLIB /* use a set of external files */ diff --git a/include/extern.h b/include/extern.h index 0550b63b8..4843b3731 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1451,7 +1451,7 @@ extern boolean stumble_on_door_mimic(coordxy, coordxy); extern int doopen_indir(coordxy, coordxy); extern int doclose(void); -#ifdef MAC +#ifdef MACOS9 /* outdated functions removed */ /* ### macfile.c ### */ /* ### macmain.c ### */ diff --git a/include/flag.h b/include/flag.h index e125694b3..cd78d899e 100644 --- a/include/flag.h +++ b/include/flag.h @@ -501,7 +501,7 @@ struct instance_flags { #ifdef MAC_GRAPHICS_ENV #define large_font obsolete #endif -#ifdef MAC +#ifdef MACOS9 #define popup_dialog wc_popup_dialog #endif #define preload_tiles wc_preload_tiles diff --git a/include/global.h b/include/global.h index 47e783742..b4eb54dbc 100644 --- a/include/global.h +++ b/include/global.h @@ -185,7 +185,7 @@ typedef uchar nhsym; #ifdef AMIGA #define PORT_ID "Amiga" #endif -#ifdef MAC +#ifdef MACOS9 #define PORT_ID "Mac" #endif #ifdef __APPLE__ diff --git a/include/optlist.h b/include/optlist.h index e91fb0238..c8d7e4b47 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -357,7 +357,7 @@ static int optfn_##a(int, int, boolean, char *, char *); NHOPTB(herecmd_menu, Advanced, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &iflags.herecmd_menu, Term_False, "show commands available in this location") -#if defined(MAC) +#if defined(MACOS9) NHOPTC(hicolor, Advanced, 15, opt_in, set_in_config, No, Yes, No, No, NoAlias, "same as palette, only order is reversed") @@ -390,7 +390,7 @@ static int optfn_##a(int, int, boolean, char *, char *); NHOPTB(idlecheckpoint, Advanced, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &iflags.idlecheckpoint, Term_Off, "update checkpoint file if input is idle for 10 seconds") -#ifndef MAC +#ifndef MACOS9 NHOPTB(ignintr, Advanced, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &flags.ignintr, Term_False, "ignore interrupt signals") @@ -542,7 +542,7 @@ static int optfn_##a(int, int, boolean, char *, char *); No, Yes, No, No, NoAlias, "the inventory order of the items in your pack") #ifdef CHANGE_COLOR -#ifndef MAC /* not old Mac OS9 */ +#ifndef MACOS9 /* not old Mac OS9 */ NHOPTC(palette, Advanced, 15, opt_in, set_gameview, No, Yes, Yes, No, "hicolor", "palette (adjust an RGB color in palette (color/R-G-B)") diff --git a/include/tcap.h b/include/tcap.h index 896c00e6f..2142a0879 100644 --- a/include/tcap.h +++ b/include/tcap.h @@ -13,7 +13,7 @@ #endif /* might display need graphics code? */ -#if !defined(AMIGA) && !defined(TOS) && !defined(MAC) +#if !defined(AMIGA) && !defined(TOS) && !defined(MACOS9) #if defined(TERMLIB) || defined(OS2) || defined(MSDOS) #define ASCIIGRAPH #endif diff --git a/include/winprocs.h b/include/winprocs.h index a60a00c77..a3a03feb4 100644 --- a/include/winprocs.h +++ b/include/winprocs.h @@ -76,7 +76,7 @@ struct window_procs { void (*win_delay_output)(void); #ifdef CHANGE_COLOR void (*win_change_color)(int, long, int); -#ifdef MAC +#ifdef MACOS9 void (*win_change_background)(int); short (*win_set_font_name)(winid, char *); #endif @@ -162,7 +162,7 @@ extern #define nh_delay_output (*windowprocs.win_delay_output) #ifdef CHANGE_COLOR #define change_color (*windowprocs.win_change_color) -#ifdef MAC +#ifdef MACOS9 #define change_background (*windowprocs.win_change_background) #define set_font_name (*windowprocs.win_set_font_name) #endif @@ -394,7 +394,7 @@ struct chain_procs { void (*win_delay_output)(CARGS); #ifdef CHANGE_COLOR void (*win_change_color)(CARGS, int, long, int); -#ifdef MAC +#ifdef MACOS9 void (*win_change_background)(CARGS, int); short (*win_set_font_name)(CARGS, winid, char *); #endif diff --git a/include/wintty.h b/include/wintty.h index c0c5d842e..12cde1d0d 100644 --- a/include/wintty.h +++ b/include/wintty.h @@ -280,7 +280,7 @@ extern void tty_number_pad(int); extern void tty_delay_output(void); #ifdef CHANGE_COLOR extern void tty_change_color(int color, long rgb, int reverse); -#ifdef MAC +#ifdef MACOS9 extern void tty_change_background(int white_or_black); extern short set_tty_font_name(winid, char *); #endif @@ -331,7 +331,7 @@ extern char *tgetstr(const char *, char **); extern char *tgoto(const char *, int, int); #endif /* NO_TERMCAP_HEADERS */ #else /* ?NO_TERMS */ -#ifdef MAC +#ifdef MACOS9 #ifdef putchar #undef putchar #undef putc @@ -342,7 +342,7 @@ extern char *tgoto(const char *, int, int); extern int term_putc(int c); extern int term_flush(void *desc); extern int term_puts(const char *str); -#endif /* MAC */ +#endif /* MACOS9 */ #if defined(MSDOS) || defined(WIN32) #if defined(SCREEN_BIOS) || defined(SCREEN_DJGPPFAST) || defined(WIN32) #undef putchar diff --git a/outdated/include/mac-carbon.h b/outdated/include/mac-carbon.h index b773c732f..570368710 100644 --- a/outdated/include/mac-carbon.h +++ b/outdated/include/mac-carbon.h @@ -21,6 +21,7 @@ * set "Prefix File" to include/mac-carbon.h */ +#define MACOS9 #define MAC #undef UNIX diff --git a/outdated/include/mac-qt.h b/outdated/include/mac-qt.h index 429106c92..48e5bef7a 100644 --- a/outdated/include/mac-qt.h +++ b/outdated/include/mac-qt.h @@ -22,6 +22,7 @@ */ #undef MAC +#undef MACOS9 #define UNIX #define BSD diff --git a/outdated/include/mac-term.h b/outdated/include/mac-term.h index 8bef72d0b..c827f59cf 100644 --- a/outdated/include/mac-term.h +++ b/outdated/include/mac-term.h @@ -23,6 +23,7 @@ /* Stuff needed for the core of NetHack */ #undef MAC +#undef MACOS9 #define UNIX #define BSD #define __FreeBSD__ /* Darwin is based on FreeBSD */ diff --git a/outdated/include/macconf.h b/outdated/include/macconf.h index fdde526c3..76b7548d8 100644 --- a/outdated/include/macconf.h +++ b/outdated/include/macconf.h @@ -3,7 +3,7 @@ /*-Copyright (c) Kevin Hugo, 2004. */ /* NetHack may be freely redistributed. See license for details. */ -#ifdef MAC +#ifdef MACOS9 #ifndef MACCONF_H #define MACCONF_H @@ -16,7 +16,7 @@ * __MWERKS__ Metrowerks' Codewarrior compiler * * We use these early in config.h to define some needed symbols, - * including MAC. + * including MACOS9. # # The Metrowerks compiler defines __STDC__ (which sets NHSTC) and uses # WIDENED_PROTOTYPES (defined if UNWIDENED_PROTOTYPES is undefined and @@ -123,4 +123,4 @@ extern void error(const char *, ...); #define MAC_GRAPHICS_ENV #endif /* ! MACCONF_H */ -#endif /* MAC */ +#endif /* MACOS9 */ diff --git a/outdated/include/system.h b/outdated/include/system.h index 2616b07f6..df5b81d5e 100644 --- a/outdated/include/system.h +++ b/outdated/include/system.h @@ -21,7 +21,7 @@ /* some old may not define off_t and size_t; if your system is * one of these, define them by hand below */ -#if (defined(VMS) && !defined(__GNUC__)) || defined(MAC) +#if (defined(VMS) && !defined(__GNUC__)) || defined(MACOS9) #include #else #ifndef AMIGA @@ -41,7 +41,7 @@ typedef unsigned int size_t; #endif #endif /* MICRO && !TOS */ -#if defined(__TURBOC__) || defined(MAC) +#if defined(__TURBOC__) || defined(MACOS9) #include /* time_t is not in */ #endif #if defined(ULTRIX) && !(defined(ULTRIX_PROTO) || defined(NHSTDC)) @@ -200,7 +200,7 @@ extern int unlink(const char *); #endif /* AZTEC_50 && __GNUC__ */ -#ifdef MAC +#ifdef MACOS9 #ifndef __CONDITIONALMACROS__ /* universal headers */ extern int close(int); /* unistd.h */ extern int read(int, char *, int); /* unistd.h */ @@ -313,7 +313,7 @@ extern long fork(void); /* The POSIX string.h is required to define all the mem* and str* functions */ #include #else -#if defined(SYSV) || defined(VMS) || defined(MAC) || defined(SUNOS4) +#if defined(SYSV) || defined(VMS) || defined(MACOS9) || defined(SUNOS4) #if defined(NHSTDC) || (defined(VMS) && !defined(ANCIENT_VAXC)) #if !defined(_AIX32) && !(defined(SUNOS4) && defined(__STDC__)) /* Solaris unbundled cc (acc) */ @@ -423,7 +423,7 @@ extern char *strncat(char *, const char *, size_t); extern char *strpbrk(const char *, const char *); #ifdef NOT_C99 -#if defined(SYSV) || defined(MICRO) || defined(MAC) || defined(VMS) \ +#if defined(SYSV) || defined(MICRO) || defined(MACOS9) || defined(VMS) \ || defined(HPUX) extern char *strchr(const char *, int); extern char *strrchr(const char *, int); @@ -435,7 +435,7 @@ extern char *rindex(const char *, int); extern int strcmp(const char *, const char *); extern int strncmp(const char *, const char *, size_t); -#if defined(MICRO) || defined(MAC) || defined(VMS) +#if defined(MICRO) || defined(MACOS9) || defined(VMS) extern size_t strlen(const char *); #else #ifdef HPUX diff --git a/outdated/win/gem/wingem.c b/outdated/win/gem/wingem.c index 078a2d2a7..b41991f93 100644 --- a/outdated/win/gem/wingem.c +++ b/outdated/win/gem/wingem.c @@ -63,7 +63,7 @@ struct window_procs Gem_procs = { Gem_getlin, Gem_get_ext_cmd, Gem_number_pad, Gem_delay_output, #ifdef CHANGE_COLOR /* the Mac uses a palette device */ Gem_change_color, -#ifdef MAC +#ifdef MACOS9 Gem_change_background, Gem_set_font_name, #endif Gem_get_color_string, @@ -76,7 +76,7 @@ struct window_procs Gem_procs = { genl_can_suspend_no, }; -#ifdef MAC +#ifdef MACOS9 void * Gem_change_background(dummy) int dummy; diff --git a/src/allmain.c b/src/allmain.c index 530840a1a..86f5b1db4 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -742,7 +742,7 @@ init_sound_disp_gamewindows(void) ever having been used, use it here to pacify the Qt interface */ start_menu(WIN_INVEN, menu_behavior), end_menu(WIN_INVEN, (char *) 0); -#ifdef MAC +#ifdef MACOS9 /* This _is_ the right place for this - maybe we will * have to split init_sound_disp_gamewindows into * create_gamewindows and show_gamewindows to get rid of this ifdef... diff --git a/src/cfgfiles.c b/src/cfgfiles.c index 2ba0c2fde..bdd6a4f37 100644 --- a/src/cfgfiles.c +++ b/src/cfgfiles.c @@ -9,7 +9,7 @@ #include "dlb.h" #include -#if (!defined(MAC) && !defined(O_WRONLY) && !defined(AZTEC_C)) \ +#if (!defined(MACOS9) && !defined(O_WRONLY) && !defined(AZTEC_C)) \ || defined(USE_FCNTL) #include #endif @@ -127,7 +127,7 @@ static const char *default_configfile = #ifdef UNIX ".nethackrc"; #else -#if defined(MAC) || defined(__BEOS__) +#if defined(MACOS9) || defined(__BEOS__) "NetHack Defaults"; #else #if defined(MSDOS) || defined(WIN32) @@ -276,7 +276,7 @@ fopen_config_file(const char *filename, int src) } /* fall through to standard names */ -#if defined(MICRO) || defined(MAC) || defined(__BEOS__) || defined(WIN32) +#if defined(MICRO) || defined(MACOS9) || defined(__BEOS__) || defined(WIN32) set_configfile_name(fqname(default_configfile, CONFIGPREFIX, 0)); if ((fp = fopen(configfile, "r")) != (FILE *) 0) { return fp; @@ -367,7 +367,7 @@ fopen_config_file(const char *filename, int src) wait_synch(); } #endif /* !VMS => Unix */ -#endif /* !(MICRO || MAC || __BEOS__ || WIN32) */ +#endif /* !(MICRO || MACOS9 || __BEOS__ || WIN32) */ return (FILE *) 0; } diff --git a/src/eat.c b/src/eat.c index 1b58c316f..9a93b212f 100644 --- a/src/eat.c +++ b/src/eat.c @@ -2176,7 +2176,7 @@ fprefx(struct obj *otmp) } else if (otmp->otyp == APPLE && otmp->cursed && !Sleep_resistance) { ; /* skip core joke; feedback deferred til fpostfx() */ -#if defined(MAC) || defined(MACOS) +#if defined(MACOS9) || defined(MACOS) /* KMH -- Why should Unix have all the fun? We check MACOS before UNIX to get the Apple-specific apple message; the '#if UNIX' code will still kick in for pear. */ diff --git a/src/end.c b/src/end.c index ff67412eb..c567fd716 100644 --- a/src/end.c +++ b/src/end.c @@ -1676,7 +1676,7 @@ nh_terminate(int status) program_state.in_moveloop = 0; /* won't be returning to normal play */ l_nhcore_call(NHCORE_GAME_EXIT); -#ifdef MAC +#ifdef MACOS9 getreturn("to exit"); #endif /* don't bother to try to release memory if we're in panic mode, to diff --git a/src/files.c b/src/files.c index ad9c62ef6..b0744126e 100644 --- a/src/files.c +++ b/src/files.c @@ -38,7 +38,7 @@ #include "wintty.h" /* more() */ #endif -#if (!defined(MAC) && !defined(O_WRONLY) && !defined(AZTEC_C)) \ +#if (!defined(MACOS9) && !defined(O_WRONLY) && !defined(AZTEC_C)) \ || defined(USE_FCNTL) #include #endif @@ -137,7 +137,7 @@ extern boolean get_user_home_folder(char *, size_t); #endif #endif -#ifdef MAC +#ifdef MACOS9 #undef unlink #define unlink macunlink #endif @@ -647,7 +647,7 @@ create_levelfile(int lev, char errbuf[]) nhfp->fd = open(fq_lock, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, FCMASK); #else -#ifdef MAC +#ifdef MACOS9 nhfp->fd = maccreat(fq_lock, LEVL_TYPE); #else nhfp->fd = creat(fq_lock, FCMASK); @@ -693,7 +693,7 @@ open_levelfile(int lev, char errbuf[]) nhfp->fpdef = (FILE *) 0; } if (nhfp && nhfp->structlevel) { -#ifdef MAC +#ifdef MACOS9 nhfp->fd = macopen(fq_lock, O_RDONLY | O_BINARY, LEVL_TYPE); #else nhfp->fd = open(fq_lock, O_RDONLY | O_BINARY, 0); @@ -876,12 +876,12 @@ create_bonesfile(d_level *lev, char **bonesid, char errbuf[]) O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, _SH_DENYRW, _S_IREAD | _S_IWRITE); #else /* ?MICRO || WIN32 */ -/* implies UNIX or MAC (MAC is for OS9 or earlier) */ -#ifdef MAC +/* implies UNIX or MACOS9 (MACOS9 is for OS9 or earlier) */ +#ifdef MACOS9 nhfp->fd = maccreat(file, BONE_TYPE); #else nhfp->fd = creat(file, FCMASK); -#endif /* ?MAC */ +#endif /* ?MACOS9 */ #endif /* ?MICRO || WIN32 */ if (nhfp->fd < 0) failed = errno; @@ -971,7 +971,7 @@ open_bonesfile(d_level *lev, char **bonesid) #endif } if (nhfp->structlevel) { -#if defined(MAC) +#if defined(MACOS9) nhfp->fd = macopen(fq_bones, O_RDONLY | O_BINARY, BONE_TYPE); #elif defined(WIN32) err = _sopen_s(&nhfp->fd, fq_bones, _O_RDONLY | _O_BINARY, @@ -1145,7 +1145,7 @@ set_error_savefile(void) } Strcat(gs.SAVEF, ".e;1"); #else -#ifdef MAC +#ifdef MACOS9 Strcat(gs.SAVEF, "-e"); #else Strcat(gs.SAVEF, ".e"); @@ -1184,8 +1184,8 @@ create_savefile(void) nhfp->fd = open(fq_save, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK); #else /* !MICRO && !WIN32 */ -/* UNIX || MAC implied (MAC is OS9 or earlier only) */ -#ifdef MAC +/* UNIX || MACOS9 implied (MACOS9 is OS9 or earlier only) */ +#ifdef MACOS9 nhfp->fd = maccreat(fq_save, SAVE_TYPE); #else nhfp->fd = creat(fq_save, FCMASK); @@ -1240,7 +1240,7 @@ open_savefile(void) nhfp->fplog = fopen("open-savefile.log", "w"); #endif } -#ifdef MAC +#ifdef MACOS9 nhfp->fd = macopen(fq_save, O_RDONLY | O_BINARY, SAVE_TYPE); #else nhfp->fd = open(fq_save, O_RDONLY | O_BINARY, 0); @@ -2500,7 +2500,7 @@ fopen_wizkit_file(void) #endif } -#if defined(MICRO) || defined(MAC) || defined(__BEOS__) || defined(WIN32) +#if defined(MICRO) || defined(MACOS9) || defined(__BEOS__) || defined(WIN32) if ((fp = fopen(fqname(gw.wizkit, CONFIGPREFIX, 0), "r")) != (FILE *) 0) return fp; #else @@ -2779,13 +2779,13 @@ check_recordfile(const char *dir UNUSED_if_not_OS2_CODEVIEW) } #else /* MICRO || WIN32*/ -#ifdef MAC +#ifdef MACOS9 /* Create the "record" file, if necessary */ fq_record = fqname(RECORD, SCOREPREFIX, 0); fd = macopen(fq_record, O_RDWR | O_CREAT, TEXT_TYPE); if (fd != -1) macclose(fd); -#endif /* MAC */ +#endif /* MACOS9 */ #endif /* MICRO || WIN32*/ } diff --git a/src/getpos.c b/src/getpos.c index ed53d334b..653dc3cb2 100644 --- a/src/getpos.c +++ b/src/getpos.c @@ -852,7 +852,7 @@ getpos(coord *ccp, boolean force, const char *goal) #endif curs(WIN_MAP, cx, cy); flush_screen(0); -#ifdef MAC +#ifdef MACOS9 lock_mouse_cursor(TRUE); #endif lock_mouse_buttons(TRUE); @@ -1149,7 +1149,7 @@ getpos(coord *ccp, boolean force, const char *goal) flush_screen(0); } exitgetpos: -#ifdef MAC +#ifdef MACOS9 lock_mouse_cursor(FALSE); #endif lock_mouse_buttons(FALSE); diff --git a/src/mdlib.c b/src/mdlib.c index fb4155dab..ca7dad4f3 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -147,7 +147,7 @@ static struct win_information window_opts[] = { #ifdef GNOME_GRAPHICS /* unmaintained/defunct */ { "Gnome", "Gnome", TRUE }, #endif -#ifdef MAC /* defunct OS 9 interface */ +#ifdef MACOS9 /* defunct OS 9 interface */ { "mac", "Mac", TRUE }, #endif #ifdef AMIGA_INTUITION /* unmaintained/defunct */ @@ -533,7 +533,7 @@ static const char *const build_opts[] = { "screen clipping", #endif #ifdef NO_TERMS -#ifdef MAC +#ifdef MACOS9 "screen control via mactty", #endif #ifdef SCREEN_BIOS diff --git a/src/options.c b/src/options.c index 4a292e03c..0b4ecaa38 100644 --- a/src/options.c +++ b/src/options.c @@ -2730,7 +2730,7 @@ optfn_palette( } #if 0 -/* old MAC OS9 code */ +/* old MACOS9 OS9 code */ staticfn int optfn_palette( int optidx UNUSED, int req, boolean negated UNUSED, @@ -5107,7 +5107,7 @@ pfxfn_font(int optidx, int req, boolean negated, char *opts, char *op) if (opttype > 0 && (op = string_for_opt(opts, FALSE)) != empty_optstr) { wc_set_font_name(opttype, op); -#ifdef MAC +#ifdef MACOS9 set_font_name(opttype, op); #endif return optn_ok; @@ -6791,12 +6791,12 @@ complain_about_duplicate(int optidx) { char buf[BUFSZ]; -#ifdef MAC +#ifdef MACOS9 /* the Mac has trouble dealing with the output of messages while * processing the config file. That should get fixed one day. * For now just return. */ -#else /* !MAC */ +#else /* !MACOS9 */ buf[0] = '\0'; if (using_alias) Sprintf(buf, " (via alias: %s)", allopt[optidx].alias); @@ -6804,7 +6804,7 @@ complain_about_duplicate(int optidx) (allopt[optidx].opttyp == CompOpt) ? "compound" : "boolean", allopt[optidx].name, buf); -#endif /* ?MAC */ +#endif /* ?MACOS9 */ return; } @@ -9431,7 +9431,7 @@ static const char *opt_intro[] = { " NetHack Options Help:", "", #define CONFIG_SLOT 3 /* fill in next value at run-time */ (char *) 0, -#if !defined(MICRO) && !defined(MAC) +#if !defined(MICRO) && !defined(MACOS9) "or use `NETHACKOPTIONS=\"\"' in your environment", #endif "( is a list of options separated by commas)", diff --git a/src/shknam.c b/src/shknam.c index 657487ed8..f1ae9ea67 100644 --- a/src/shknam.c +++ b/src/shknam.c @@ -128,7 +128,7 @@ static const char *const shktools[] = { #ifdef WIN32 "Lexa", "Niod", #endif -#ifdef MAC +#ifdef MACOS9 "Nhoj-lee", "Evad\'kh", "Ettaw-noj", "Tsew-mot", "Ydna-s", "Yao-hang", "Tonbar", "Kivenhoug", "Llardom", #endif diff --git a/src/windows.c b/src/windows.c index a36b0eaa4..49e88ab60 100644 --- a/src/windows.c +++ b/src/windows.c @@ -22,7 +22,7 @@ extern struct window_procs Qt_procs; #ifdef GEM_GRAPHICS /*#include "wingem.h"*/ #endif -#ifdef MAC +#ifdef MACOS9 extern struct window_procs mac_procs; #endif #ifdef BEOS_GRAPHICS @@ -111,7 +111,7 @@ static struct win_choices { #ifdef GEM_GRAPHICS { &Gem_procs, win_Gem_init CHAINR(0) }, #endif -#ifdef MAC +#ifdef MACOS9 { &mac_procs, 0 CHAINR(0) }, #endif #ifdef BEOS_GRAPHICS @@ -543,7 +543,7 @@ staticfn void hup_cliparound(int, int); #endif #ifdef CHANGE_COLOR staticfn void hup_change_color(int, long, int); -#ifdef MAC +#ifdef MACOS9 staticfn short hup_set_font_name(winid, char *); #endif staticfn char *hup_get_color_string(void); @@ -592,7 +592,7 @@ static struct window_procs hup_procs = { hup_void_ndecl, /* nh_delay_output */ #ifdef CHANGE_COLOR hup_change_color, -#ifdef MAC +#ifdef MACOS9 hup_void_fdecl_int, /* change_background */ hup_set_font_name, #endif @@ -795,14 +795,14 @@ hup_change_color(int color UNUSED, long rgb UNUSED, int reverse UNUSED) return; } -#ifdef MAC +#ifdef MACOS9 /*ARGSUSED*/ staticfn short hup_set_font_name(winid window UNUSED, char *fontname UNUSED) { return 0; } -#endif /* MAC */ +#endif /* MACOS9 */ staticfn char * hup_get_color_string(void) diff --git a/util/dlb_main.c b/util/dlb_main.c index 1926b871d..ae92fbacb 100644 --- a/util/dlb_main.c +++ b/util/dlb_main.c @@ -9,7 +9,7 @@ #include "dlb.h" #include "hacklib.h" -#if !defined(O_WRONLY) && !defined(MAC) && !defined(AZTEC_C) +#if !defined(O_WRONLY) && !defined(MACOS9) && !defined(AZTEC_C) #include #endif #if defined(__DJGPP__) diff --git a/util/makedefs.c b/util/makedefs.c index 53c90c151..8037b14cc 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -23,15 +23,15 @@ #include "dlb.h" #include "hacklib.h" -#ifdef MAC +#ifdef MACOS9 #if defined(__SC__) || defined(__MRC__) /* MPW compilers */ #define MPWTOOL #include #include -#else /* MAC without MPWTOOL */ +#else /* MACOS9 without MPWTOOL */ #define MACsansMPWTOOL #endif -#endif /* MAC */ +#endif /* MACOS9 */ #ifndef MPWTOOL #define SpinCursor(x) @@ -78,7 +78,7 @@ #define DGN_TEMPLATE "NH:dat/%s" /* where dungeon.pdf file goes */ #endif /* OLD_MAKEDEFS_OPTIONS */ #else /* not AMIGA */ -#if defined(MAC) && !defined(__MACH__) +#if defined(MACOS9) && !defined(__MACH__) /* MacOS 9 or earlier */ #define SOURCE_TEMPLATE ":src:%s" #if __SC__ || __MRC__ @@ -91,7 +91,7 @@ #define INCLUDE_TEMPLATE ":include:%s" #define DGN_TEMPLATE ":dat:%s" /* where dungeon.pdf file goes */ #endif /* OLD_MAKEDEFS_OPTIONS */ -#else /* neither AMIGA nor MAC */ +#else /* neither AMIGA nor MACOS9 */ #ifdef OS2 #define SOURCE_TEMPLATE "..\\src\\%s" #define DATA_TEMPLATE "..\\dat\\%s" @@ -100,7 +100,7 @@ #define INCLUDE_TEMPLATE "..\\include\\%s" #define DGN_TEMPLATE "..\\dat\\%s" /* where dungeon.pdf file goes */ #endif /* OLD_MAKEDEFS_OPTIONS */ -#else /* not AMIGA, MAC, or OS2 */ +#else /* not AMIGA, MACOS9, or OS2 */ #define SOURCE_TEMPLATE "../src/%s" #define DATA_TEMPLATE "../dat/%s" #define DATA_IN_TEMPLATE "../dat/%s" @@ -109,7 +109,7 @@ #define DGN_TEMPLATE "../dat/%s" /* where dungeon.pdf file goes */ #endif /* OLD_MAKEDEFS_OPTIONS */ #endif /* else !OS2 */ -#endif /* else !MAC */ +#endif /* else !MACOS9 */ #endif /* else !AMIGA */ static const char @@ -257,7 +257,7 @@ main(void) return 0; } -#else /* ! MAC */ +#else /* ! MACOS9 */ DISABLE_WARNING_UNREACHABLE_CODE @@ -1551,7 +1551,7 @@ do_oracles(void) break; if (!(ok = (fscanf(ofp, "%5lx", &offset) == 1))) break; -#ifdef MAC +#ifdef MACOS9 #ifdef __MWERKS__ /* MetroWerks CodeWarrior Pro 1's (AKA CW12) version of MSL diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 4d1923eda..a8019be94 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -122,7 +122,7 @@ struct window_procs curses_procs = { curses_delay_output, #ifdef CHANGE_COLOR curses_change_color, -#ifdef MAC /* old OS 9, not OSX */ +#ifdef MACOS9 /* old OS 9, not OSX */ (void (*)(int)) 0, (short (*)(winid, char *)) 0, #endif diff --git a/win/share/tilemap.c b/win/share/tilemap.c index 41583dfa0..a9bd73ad4 100644 --- a/win/share/tilemap.c +++ b/win/share/tilemap.c @@ -541,7 +541,7 @@ tilename(int set, const int file_entry, int gend UNUSED) #define SOURCE_TEMPLATE "NH:src/%s" #define INCLUDE_TEMPLATE "NH:include/t.%s" #else -#ifdef MAC +#ifdef MACOS9 #define SOURCE_TEMPLATE ":src:%s" #define INCLUDE_TEMPLATE ":include:%s" #else diff --git a/win/tty/getline.c b/win/tty/getline.c index acb3f7f14..03744f322 100644 --- a/win/tty/getline.c +++ b/win/tty/getline.c @@ -7,7 +7,7 @@ #ifdef TTY_GRAPHICS -#if !defined(MAC) +#if !defined(MACOS9) #define NEWAUTOCOMP #endif diff --git a/win/tty/wintty.c b/win/tty/wintty.c index b2c6a5c42..21e0ed8b1 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -20,7 +20,7 @@ /* leave this undefined; it produces bad screen output with rxvt-unicode */ /*#define DECgraphicsOptimization*/ -#ifdef MAC +#ifdef MACOS9 #define MICRO /* The Mac is a MICRO only for this file, not in general! */ #ifdef THINK_C extern void msmsg(const char *, ...); @@ -143,7 +143,7 @@ struct window_procs tty_procs = { tty_getlin, tty_get_ext_cmd, tty_number_pad, tty_delay_output, #ifdef CHANGE_COLOR /* the Mac uses a palette device */ tty_change_color, -#ifdef MAC +#ifdef MACOS9 tty_change_background, set_tty_font_name, #endif tty_get_color_string, From 540e2a999e18155e0adf36daba4dc9bc1ab2b79c Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 1 May 2026 18:31:57 +0300 Subject: [PATCH 106/702] Couple language nits --- doc/Guidebook.mn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 72a3fad13..a3994124c 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -6798,7 +6798,7 @@ changes in the game. It was clear that there was sufficient depth and breadth to warrant a major release and version 5.0 was decided on. That's a new major release over 3.x, without opening up any ambiguity or confusion with existing variants that there might have been had it -been released version 4.0. +been released as version 4.0. .pg NetHack 5.0.0 was released on , 2026. .pg @@ -6824,7 +6824,7 @@ on macOS. .pg \fBIngo Paschke\fP somehow managed to revive a NetHack 5.0 port for the Amiga, using a cross-compiler on a modern platform to do so. His work was shared so -other's can straightforwardly produce NetHack 5.0 for the Amiga thanks to his +others can straightforwardly produce NetHack 5.0 for the Amiga thanks to his efforts. .pg \fBRay Chason\fP contributed the majority of maintenance work for the From 6c9e7b60e246231cdbedc590ed242299e96cf2a5 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 1 May 2026 12:38:03 -0400 Subject: [PATCH 107/702] Guidebook update --- doc/Guidebook.mn | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index a3994124c..18461b585 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -6803,7 +6803,8 @@ been released as version 4.0. NetHack 5.0.0 was released on , 2026. .pg The source code for NetHack 5.0.0 was modified and modernized to be -compliant with standard C99. +compliant with standard C99. The 5.0.0 release contains over 3100 fixes, +changes, and updated features. .pg NetHack 5.0 was the first version to replace the lex and yacc level and dungeon compilers of past versions, with a new Lua interpreter-based From bce8624a077b8d21484a487863c9dccf15671e3b Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 1 May 2026 12:41:31 -0400 Subject: [PATCH 108/702] verb tense bit --- doc/Guidebook.mn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 18461b585..ba99287ff 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -6803,7 +6803,7 @@ been released as version 4.0. NetHack 5.0.0 was released on , 2026. .pg The source code for NetHack 5.0.0 was modified and modernized to be -compliant with standard C99. The 5.0.0 release contains over 3100 fixes, +compliant with standard C99. The 5.0.0 release contained over 3100 fixes, changes, and updated features. .pg NetHack 5.0 was the first version to replace the lex and yacc level From 218bb7bffef54223b3a13b05aba550a86116fb33 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 1 May 2026 09:56:08 -0700 Subject: [PATCH 109/702] documentation update: v vs V Version and history commands. Plus a quarter-assed description of the versinfo option. ('mO' can update and possibly provide enough into to make sense of it.) \#history was already revised but the new description was inaccurate. Guidebook.tex is untested. --- doc/Guidebook.mn | 25 +++++++++++++++++++++---- doc/Guidebook.tex | 26 ++++++++++++++++++++++---- src/cmd.c | 4 ++-- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 4d1499510..3ed19cb1b 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -60,7 +60,7 @@ .ds f0 \*(vr .ds f1 \" empty .\"DO NOT REMOVE NH_DATESUB .ds f2 Date(%B %-d, %Y) -.ds f2 April 16, 2026 +.ds f2 May 1, 2026 . .\" A note on some special characters: .\" \(lq = left double quote @@ -1034,9 +1034,16 @@ choices but will accept an item of armor and attempt to take it off.) .lp \(haT Teleport, if you have the ability. .lp v -Display version number. +Display a list of significant events in the current game, also shown by +\f(CR#chronicle\fP. +.lp "" +\(oq\f(CRv\fP\(cq used to display the game's version number. +Use \(oq\f(CRV\fP\(cq for that now. .lp V -Display the game history. +Display version number. +.lp "" +\(oq\f(CRV\fP\(cq used to display a summary of the game's history. +Still available via \f(CR#history\fP. .lp w Wield weapon. .sd @@ -1385,7 +1392,7 @@ If mouse support is enabled and the option is On, clicking on the hero (or steed when mounted) will execute this command. .lp "#history " -Show long version and game history. +Show a summary of the game's development. .lp #inventory Show your inventory. Default key is \(oqi\(cq. @@ -4803,6 +4810,12 @@ option is recommended so that there will be more room available for status information, unless you're using NetHack's \fIQt\fP interface or your terminal emulator window displays fewer than 25 lines. Persistent. +.lp "" +The +.op versinfo +option provides limited control over what information +.op showvers +displays. .lp "silent " Suppress terminal beeps (default on). Persistent. @@ -4943,6 +4956,10 @@ Play a tutorial level at the start of the game. Setting this option on or off in the config file will skip the query. .lp "verbose " Provide more commentary during the game (default on). Persistent. +.lp versinfo +Controls what the +.op showvers +option displays on the status lines. .lp weaponstatus Display an extra status condition which describes currently wielded weapon (default off, not supported by all interfaces). diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 3539b0242..2c9ee2677 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -25,7 +25,7 @@ \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.7.0 by Mike Stephenson and others)} %DO NOT REMOVE NH_DATESUB \date{Date(%B %-d, %Y)} -\date{April 16, 2026} +\date{May 1, 2026} \maketitle @@ -1067,10 +1067,20 @@ choices but will accept an item of armor and attempt to take it off.) Teleport, if you have the ability. %.lp \item[v] -Display version number. +Display a list of significant events in the current game, also shown by +\texttt{\#chronicle}. +\\ +%.lp "" +`\texttt{v}' used to display the game's version number. +Use `\texttt{V}' for that now. + %.lp \item[V] -Display the game history. +Display version number. +\\ +%.lp "" +`\texttt{V' used to display a summary of the game's history. +Still available via \texttt{\#history}. %.lp \item[w] Wield weapon.\\ @@ -1430,7 +1440,7 @@ option is On, clicking on the hero (or steed when mounted) will execute this command. %.lp \item[\#history] -Show long version and game history. +Show a summary of the game's development. %.lp \item[\#inventory] Show your inventory. Default key is `\texttt{i}'. @@ -5234,6 +5244,11 @@ option is recommended so that there will be more room available for status information, unless you're using NetHack's \textit{Qt} interface or your terminal emulator window displays fewer than 25 lines. Persistent. +\\ +%.lp "" +The \textit{versinfo} +option provides limited control over what information +\textit{showvers} displays. %.lp \item[silent] Suppress terminal beeps (default on). Persistent. @@ -5398,6 +5413,9 @@ Setting this option on or off in the config file will skip the query. \item[verbose] Provide more commentary during the game (default on). Persistent. %.lp +\item[versinfo] +Controls what the \textit{showvers} option displays on the status lines. +%.lp \item[weaponstatus] Display an extra status condition which describes currently wielded weapon (default off, not supported by all interfaces). diff --git a/src/cmd.c b/src/cmd.c index c1ef88b1d..705e2dbc4 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1735,8 +1735,8 @@ struct ext_func_tab extcmdlist[] = { dohelp, IFBURIED | GENERALCMD, NULL }, { '\0', "herecmdmenu", "show menu of commands you can do here", doherecmdmenu, IFBURIED | AUTOCOMPLETE | GENERALCMD, NULL }, - { '\0', "history", "show long version and game history", - dohistory, IFBURIED | GENERALCMD, NULL }, + { '\0', "history", "show a summary of the game's development", + dohistory, IFBURIED | AUTOCOMPLETE | GENERALCMD, NULL }, { 'i', "inventory", "show your inventory", ddoinv, IFBURIED | GENERALCMD, NULL }, { 'I', "inventtype", "show inventory of one specific item class", From 7739b382ace29404a55dcc2380b4ebaee2c9a093 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 1 May 2026 13:09:49 -0400 Subject: [PATCH 110/702] Guidebook.tex fix --- doc/Guidebook.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 71a4d30ce..25f408519 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -1079,7 +1079,7 @@ Use `\texttt{V}' for that now. Display version number. \\ %.lp "" -`\texttt{V' used to display a summary of the game's history. +`\texttt{V}' used to display a summary of the game's history. Still available via \texttt{\#history}. %.lp \item[w] From d3f2ed4e4746bc5feec598aa876ca3fcd91c4362 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 1 May 2026 13:09:49 -0400 Subject: [PATCH 111/702] Guidebook.tex fix --- doc/Guidebook.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 2c9ee2677..454bbee4b 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -1079,7 +1079,7 @@ Use `\texttt{V}' for that now. Display version number. \\ %.lp "" -`\texttt{V' used to display a summary of the game's history. +`\texttt{V}' used to display a summary of the game's history. Still available via \texttt{\#history}. %.lp \item[w] From e35af92d13ba1d45ff6937583097f9444bb4db71 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Fri, 1 May 2026 21:41:40 +0100 Subject: [PATCH 112/702] Fix the fix to the pricequotes option It was displaying price quotes even with the option off, when removing items from a container. --- src/objnam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objnam.c b/src/objnam.c index cd50e0bb5..983741cf8 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1673,7 +1673,7 @@ doname_base( nochrg ? "contents" : "for sale", pricebuf); } else if (nochrg > 0) { Concat(bp, 0, " (no charge)"); - } else { + } else if (iflags.pricequotes && !objects[obj->otyp].oc_name_known) { append_price_quote(bp, &bp_eos, obj->otyp); } From 4e20ebc7aae77c86fb178b213321d214ee43eea6 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Sat, 2 May 2026 01:14:25 +0100 Subject: [PATCH 113/702] Reserve save file space for new conducts and options This will make it possible to change conducts and options in the future without breaking the save format. --- include/flag.h | 9 +++++++++ include/you.h | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/include/flag.h b/include/flag.h index 8494d40d2..541343d41 100644 --- a/include/flag.h +++ b/include/flag.h @@ -156,6 +156,15 @@ struct flag { boolean showrace; /* show hero glyph by race rather than by role */ boolean travelcmd; /* allow travel command */ int runmode; /* update screen display during run moves */ + + int reserved1; + int reserved2; + int reserved3; + int reserved4; + int reserved5; + int reserved6; + int reserved7; + int reserved8; }; /* diff --git a/include/you.h b/include/you.h index 0c9368b76..16af33c11 100644 --- a/include/you.h +++ b/include/you.h @@ -160,6 +160,10 @@ struct u_conduct { /* number of times... */ long sokocheat; /* violated special 'rules' in Sokoban */ long pets; /* obtained a pet */ /* genocides already listed at end of game */ + long reserved1; + long reserved2; + long reserved3; + long reserved4; }; struct u_roleplay { @@ -168,6 +172,9 @@ struct u_roleplay { boolean deaf; /* permanently deaf */ boolean pauper; /* no starting inventory */ boolean reroll; /* starting inventory/attr rerolling enabled */ + boolean reserved1; + boolean reserved2; + boolean reserved3; long numbones; /* # of bones files loaded */ long numrerolls; /* # of rerolls used */ }; From bd74660e065a7edbb2e7184489a1370faec1bb07 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 1 May 2026 21:50:38 -0400 Subject: [PATCH 114/702] some documentation updates including date stamp --- dat/history | 64 +++++++++++++++++++++ doc/Guidebook.mn | 4 +- doc/Guidebook.tex | 131 ++++++++++++++++++++++++++++++++++++------- include/patchlevel.h | 9 ++- 4 files changed, 185 insertions(+), 23 deletions(-) diff --git a/dat/history b/dat/history index 0d591d81c..242781643 100644 --- a/dat/history +++ b/dat/history @@ -274,6 +274,70 @@ some bug fixes. NetHack 3.6.7 was released on February 16, 2023 containing a security fix and some bug fixes. +Development work for the major release to follow NetHack 3.6 began in 2015 +around the same time as NetHack 3.6.0 was being released. That development +work continued in parallel to each of the NetHack 3.6 releases from 2015 +through 2023, and continued until the end of April 2026. For the first time, +that development was shared publicly on GitHub and SourceForge as it occurred. +It was done under the label NetHack-3.7 work-in-progress (WIP), although the +version number for the next release had not yet been solidified. + +Exposure of the development to the public brought many good things, and some +challenges. People were able to observe and criticize changes and new features +almost immediately, and they often did. The GitHub pull request system made +it straightforward for people to contribute directly to development. +Contributions resolved many, many bugs in the game and we thank all the +contributors. + +In early 2026, with the game development getting stable enough to consider +initiating an official release, the devteam reviewed the nature and number of +changes in the game. It was clear that there was sufficient depth and +breadth to warrant a major release and version 5.0 was decided on. +That's a new major release over 3.x, without opening up any ambiguity +or confusion with existing variants that there might have been had it +been released as version 4.0. + +NetHack 5.0.0 was released on May 2, 2026. + +The source code for NetHack 5.0.0 was modified and modernized to be +compliant with standard C99. The 5.0.0 release contained over 3100 fixes, +changes, and updated features. + +NetHack 5.0 was the first version to replace the lex and yacc level +and dungeon compilers of past versions, with a new Lua interpreter-based +approach to provide those elements. Lua is also used for the quest texts +in NetHack 5.0.0. The entire development team acknowledges the work +done by Pasi Kallinen to make that happen. + +At the time of the NetHack 5.0 release, the core development team, +active and erstwhile, included Warwick Allison, Michael Allison, +Ken Arromdee, David Cohrs, Jessie Collet, Bart House, Kevin Hugo, +Pasi Kallinen, Ken Lorber, Dean Luick, Pat Rankin, Derek S. Ray, +Alex Smith, Patric Mueller, Mike Stephenson, Janet Walz, Paul Winner. + +Ken Lorber, Pat Rankin, Patrick Mueller and Michael Allison helped ensure +that NetHack 5.0 would run on macOS. + +Ingo Paschke somehow managed to revive a NetHack 5.0 port for the Amiga, +using a cross-compiler on a modern platform to do so. His work was shared +so others can straightforwardly produce NetHack 5.0 for the Amiga thanks +to his efforts. + +Ray Chason contributed the majority of maintenance work for the NetHack 5.0 +MS-DOS port, including porting the curses interface to it. +Michael Allison ensured that NetHack 5.0 core changes continued to work +with the msdos port and keep it alive. Cross-compiling the MS-DOS port +has helped make that possible and mostly painless. + +People that contributed to the Windows port of NetHack 5.0 since the +development of NetHack 5.0 begain over eleven years ago, included +Michael Allison, David Cohrs, Bart House, Pasi Kallinen, Alex Kompel, +Dion Nicolaas, Derek S. Ray and Yitzhak Sapir. + +With sadness, the devteam would like to acknowledge and remember the past +contributions from the late Ron Van Iwaarden, who was the sole maintainer +of NetHack for OS/2 for several past NetHack releases. Ron will be missed. + The official NetHack web site is maintained by Ken Lorber at https://www.nethack.org/. diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 53de0ba05..b32144a6d 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -60,7 +60,7 @@ .ds f0 \*(vr .ds f1 \" empty .\"DO NOT REMOVE NH_DATESUB .ds f2 Date(%B %-d, %Y) -.ds f2 May 1, 2026 +.ds f2 May 2, 2026 . .\" A note on some special characters: .\" \(lq = left double quote @@ -6817,7 +6817,7 @@ That's a new major release over 3.x, without opening up any ambiguity or confusion with existing variants that there might have been had it been released as version 4.0. .pg -NetHack 5.0.0 was released on , 2026. +NetHack 5.0.0 was released on May 2, 2026. .pg The source code for NetHack 5.0.0 was modified and modernized to be compliant with standard C99. The 5.0.0 release contained over 3100 fixes, diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 25f408519..20bd1fcaa 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -25,7 +25,7 @@ \author{Original version - Eric S. Raymond\\ (Edited and expanded for 5.0.0 by Mike Stephenson and others)} %DO NOT REMOVE NH_DATESUB \date{Date(%B %-d, %Y)} -\date{May 1, 2026} +\date{May 2, 2026} \maketitle @@ -5792,7 +5792,7 @@ computer unless you manually click submit on a form. %.ei \end{description} These options are used only to save you some typing on the crash -report and \#bugreport forms. +report and \#bugreport forms. %.si \begin{description} %.lp @@ -6769,7 +6769,7 @@ U+224B and the color represented by R-G-B value 0-0-160:\\ OPTIONS=glyph:G_pool/U+224B/0-0-160 \end{verbatim} -The list of acceptable glyphid's can be produced by +The list of acceptable glyphid's can be produced by \begin{verbatim} nethack --glyphids \end{verbatim} @@ -6911,7 +6911,7 @@ The syntax is the same as WIZARDS. %.lp \item[MSGHANDLER] A path and filename of executable. Whenever a message-window -message is shown, NetHack runs this program. The program will get +message is shown, \textit{NetHack} runs this program. The program will get the message as the only parameter. %.lp \item[MAXPLAYERS] @@ -6965,12 +6965,12 @@ random statue names (default is 10). %.lp \item[ACCESSIBILITY] 0 or 1 to disable or enable, respectively, the ability for players -to set S\textunderscore pet\textunderscore override and S\textunderscore hero\textunderscore override +to set S\textunderscore pet\textunderscore override and S\textunderscore hero\textunderscore override symbols in their configuration file. %.lp \item[PORTABLE\textunderscore DEVICE\textunderscore PATHS] 0 or 1 Windows OS only, the game will look for all of its external -files, and write to all of its output files in one place +files, and write to all of its output files in one place rather than at the standard locations. %.lp \item[DUMPLOGFILE] @@ -7170,8 +7170,8 @@ subsequent revisions of 3.0. \medskip \noindent \textit{Olaf Seibert} ported \textit{NetHack} 2.3 and 3.0 to the Amiga. {\it Norm Meluch}, \textit{Stephen Spackman} and \textit{Pierre Martineau} designed -overlay code for \textit{PC NetHack} 3.0. \textit{Johnny Lee} ported {\it -NetHack} 3.0 to the Macintosh. Along with various other Dungeoneers, they +overlay code for \textit{PC NetHack} 3.0. \textit{Johnny Lee} ported +\textit{NetHack} 3.0 to the Macintosh. Along with various other Dungeoneers, they continued to enhance the PC, Macintosh, and Amiga ports through the later revisions of 3.0. @@ -7437,7 +7437,7 @@ official release version. %.pg \medskip -In January 2015, preparation began for the release of NetHack 3.6. +In January 2015, preparation began for the release of \textit{NetHack} 3.6. %.pg \medskip @@ -7449,7 +7449,7 @@ At the beginning of development for what would eventually get released as \textit{Mike Stephenson}, \textit{Janet Walz}, and \textit{Paul Winner}. In early 2015, ahead of the release of 3.6.0, new members \textit{Sean Hunt}, \textit{Pasi Kallinen}, and \textit{Derek S. Ray} -joined the \textit{NetHack} development team. +joined the \textit{NetHack Development Team}. %.pg \medskip @@ -7484,7 +7484,7 @@ maintained the port of \textit{NetHack} 3.6 for Microsoft Windows. %.pg \medskip -\textit{Pat Rankin} attempted to keep the VMS port running for NetHack 3.6, +\textit{Pat Rankin} attempted to keep the VMS port running for \textit{NetHack} 3.6, hindered by limited access. \textit{Kevin Smolkowski} has updated and tested it for the most recent version of OpenVMS (V8.4 as of this writing) on Alpha and Integrity (aka Itanium aka IA64) but not VAX. @@ -7497,7 +7497,7 @@ necessary updates to the community at large. %.pg \medskip In late April 2018, several hundred bug fixes for 3.6.0 and some new features -were assembled and released as NetHack 3.6.1. +were assembled and released as \textit{NetHack} 3.6.1. The \textit{NetHack Development Team} at the time of release of 3.6.1 consisted of \textit{Warwick Allison}, \textit{Michael Allison}, \textit{Ken Arromdee}, @@ -7519,29 +7519,122 @@ for decades, joined the \textit{NetHack Development Team} in late May 2019. %.pg \medskip -NetHack 3.6.3 was released on December 5, 2019 containing over 190 bug -fixes to NetHack 3.6.2. +\textit{NetHack} 3.6.3 was released on December 5, 2019 containing over 190 bug +fixes to \textit{NetHack} 3.6.2. %.pg \medskip -NetHack 3.6.4 was released on December 18, 2019 containing a security fix and +\textit{NetHack} 3.6.4 was released on December 18, 2019 containing a security fix and a few bug fixes. %.pg \medskip -NetHack 3.6.5 was released on January 27, 2020 containing some security fixes +\textit{NetHack} 3.6.5 was released on January 27, 2020 containing some security fixes and a small number of bug fixes. %.pg \medskip -NetHack 3.6.6 was released on March 8, 2020 containing a security fix and +\textit{NetHack} 3.6.6 was released on March 8, 2020 containing a security fix and some bug fixes. %.pg \medskip -NetHack 3.6.7 was released on February 16, 2023 containing a security fix and +\textit{NetHack} 3.6.7 was released on February 16, 2023 containing a security fix and some bug fixes. +%.pg +\medskip +Development work for the major release to follow \textit{NetHack} 3.6 began in 2015 +around the same time as \textit{NetHack} 3.6.0 was being released. That development +work continued in parallel to each of the \textit{NetHack} 3.6 releases from 2015 +through 2023, and continued until the end of April 2026. For the first time, +that development was shared publicly on GitHub and SourceForge as it occurred. +It was done under the label NetHack-3.7 work-in-progress (WIP), although the +version number for the next release had not yet been solidified. + +%.pg +\medskip +Exposure of the development to the public brought many good things, and some +challenges. People were able to observe and criticize changes and new features +almost immediately, and they often did. The GitHub pull request system made +it straightforward for people to contribute directly to development. +Contributions resolved many, many bugs in the game and we thank all the +contributors. + +%.pg +\medskip +In early 2026, with the game development getting stable enough to consider +initiating an official release, the devteam reviewed the nature and number of +changes in the game. It was clear that there was sufficient depth and +breadth to warrant a major release and version 5.0 was decided on. +That's a new major release over 3.x, without opening up any ambiguity +or confusion with existing variants that there might have been had it +been released as version 4.0. + +%.pg +\medskip +\textit{NetHack} 5.0.0 was released on May 2, 2026. + +%.pg +\medskip +The source code for \textit{NetHack} 5.0.0 was modified and modernized to be +compliant with standard C99. The 5.0.0 release contained over 3100 fixes, +changes, and updated features. + +%.pg +\medskip +\textit{NetHack} 5.0 was the first version to replace the lex and yacc level +and dungeon compilers of past versions, with a new Lua interpreter-based +approach to provide those elements. Lua is also used for the quest texts +in \textit{NetHack} 5.0.0. The entire development team acknowledges the work +done by \textit{Pasi Kallinen} to make that happen. +\textit{Ray Chason} + +%.pg +\medskip +At the time of the \textit{NetHack} 5.0 release, the core +\textit{NetHack Development Team}, +active and erstwhile, included \textit{Warwick Allison}, \textit{Michael Allison}, +\textit{Ken Arromdee}, \textit{David Cohrs}, \textit{Jessie Collet}, \textit{Bart House}, +\textit{Kevin Hugo}, \textit{Pasi Kallinen}, \textit{Ken Lorber}, \textit{Dean Luick}, +\textit{Pat Rankin}, \textit{Derek S. Ray}, \textit{Alex Smith}, \textit{Patric Mueller}, +\textit{Mike Stephenson}, \textit{Janet Walz}, \textit{Paul Winner}. + +%.pg +\medskip +\textit{Ken Lorber}, \textit{Pat Rankin}, \textit{Patrick Mueller} and +\textit{Michael Allison} helped ensure that \textit{NetHack} 5.0 would run +on macOS. + +%.pg +\medskip +\textit{Ingo Paschke} somehow managed to revive a \textit{NetHack} 5.0 port for the Amiga, +using a cross-compiler on a modern platform to do so. His work was shared so +others can straightforwardly produce \textit{NetHack} 5.0 for the Amiga thanks to his +efforts. + +%.pg +\medskip +\textit{Ray Chason} contributed the majority of maintenance work for the +\textit{NetHack} 5.0 MS-DOS port, including porting the curses interface to it. +\textit{Michael Allison} ensured that \textit{NetHack} 5.0 core changes continued to +work with the msdos port and keep it alive. Cross-compiling the MS-DOS +port has helped make that possible and mostly painless. + +%.pg +\medskip +People that contributed to the Windows port of \textit{NetHack} 5.0 since the +development of \textit{NetHack} 5.0 begain over eleven years ago, included +\textit{Michael Allison}, \textit{David Cohrs}, \textit{Bart House}, +\textit{Pasi Kallinen}, \textit{Alex Kompel}, \textit{Dion Nicolaas}, +\textit{Derek S. Ray} and \textit{Yitzhak Sapir}. + +%.pg +\medskip +With sadness, the devteam would like to acknowledge and remember the past +contributions from the late \textit{Ron Van Iwaarden}, who was the sole maintainer +of \textit{NetHack} for OS/2 for several past \textit{NetHack} releases. Ron will be missed. + %.pg \medskip \noindent The official \textit{NetHack} web site is maintained by \textit{Ken Lorber} at @@ -7553,7 +7646,7 @@ some bug fixes. \subsection*{Special Thanks} \noindent On behalf of the \textit{NetHack} community, thank you very much once again to \textit{M. Drew Streib} and \textit{Pasi Kallinen} for providing a -public NetHack server at nethack.alt.org. Thanks to \textit{Keith Simpson} +public \textit{NetHack} server at nethack.alt.org. Thanks to \textit{Keith Simpson} and \textit{Andy Thomson} for hardfought.org. Thanks to all those unnamed dungeoneers who invest their time and effort into annual \textit{NetHack} tournaments such as \textit{Junethack}, diff --git a/include/patchlevel.h b/include/patchlevel.h index eef05f6da..f2c1a667d 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -59,13 +59,18 @@ * to individual level files matter; changes to general game state don't) * but the extra complexity to support that is not worth the effort.] */ -/*#define VERSION_COMPATIBILITY 0x03070000L*/ +/*#define VERSION_COMPATIBILITY 0x05000000L*/ /****************************************************************************/ /* Version 5.0.x */ /* - * NetHack 5.0.0, + * NetHack 5.0.0, May 2, 2026 + * + * Sources changed to C99. + * level compiler, dungeon compiler, and quest text all replaced with + * Lua alternatives. + * Refer to doc/fixes5-0-0.txt for a complete list of fixes and changes. * */ From fcc8d4d3c3aeb2984016efe333cf81479ae72e9a Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 1 May 2026 22:36:37 -0400 Subject: [PATCH 115/702] mhm initialization --- src/uhitm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/uhitm.c b/src/uhitm.c index eb04e0d1a..15222a3bd 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -4837,7 +4837,8 @@ damageum( struct attack *mattk, /* hero's attack */ int specialdmg) /* blessed and/or silver bonus against various things */ { - struct mhitm_data mhm; + /* { damage, hitflags, done, permdmg, specialdmg, dieroll } */ + struct mhitm_data mhm = { 0, 0, FALSE, FALSE, 0, 0 }; mhm.damage = d((int) mattk->damn, (int) mattk->damd); mhm.hitflags = M_ATTK_MISS; From fd2e44e24fd68961cd20f6b63593235cacb30f92 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 1 May 2026 23:27:24 -0400 Subject: [PATCH 116/702] Revert "mhm initialization" This reverts commit fcc8d4d3c3aeb2984016efe333cf81479ae72e9a. --- src/uhitm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/uhitm.c b/src/uhitm.c index 15222a3bd..eb04e0d1a 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -4837,8 +4837,7 @@ damageum( struct attack *mattk, /* hero's attack */ int specialdmg) /* blessed and/or silver bonus against various things */ { - /* { damage, hitflags, done, permdmg, specialdmg, dieroll } */ - struct mhitm_data mhm = { 0, 0, FALSE, FALSE, 0, 0 }; + struct mhitm_data mhm; mhm.damage = d((int) mattk->damn, (int) mattk->damd); mhm.hitflags = M_ATTK_MISS; From b8c1a5dae94902d8347c01ab9a45a2405c8082e1 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 2 May 2026 00:11:06 -0400 Subject: [PATCH 117/702] Revert "change gy.youmonst" This reverts commit 5b66ba4c993882303d3b38c8006d9227e184b86b. --- include/decl.h | 1 + include/display.h | 6 +- include/hack.h | 4 +- include/monst.h | 4 +- include/patchlevel.h | 2 +- include/you.h | 3 +- include/youprop.h | 8 +- src/allmain.c | 10 +- src/apply.c | 36 ++--- src/artifact.c | 40 +++--- src/attrib.c | 4 +- src/botl.c | 6 +- src/cmd.c | 8 +- src/dbridge.c | 6 +- src/decl.c | 1 + src/detect.c | 6 +- src/dig.c | 26 ++-- src/do.c | 10 +- src/do_name.c | 6 +- src/do_wear.c | 56 ++++---- src/dog.c | 6 +- src/dogmove.c | 10 +- src/dokick.c | 22 ++-- src/dothrow.c | 58 ++++---- src/eat.c | 112 ++++++++-------- src/end.c | 2 +- src/engrave.c | 12 +- src/exper.c | 6 +- src/explode.c | 20 +-- src/fountain.c | 2 +- src/hack.c | 124 +++++++++--------- src/iactions.c | 4 +- src/insight.c | 44 +++---- src/invent.c | 16 +-- src/light.c | 10 +- src/lock.c | 28 ++-- src/mcastu.c | 12 +- src/mhitm.c | 32 ++--- src/mhitu.c | 128 +++++++++--------- src/minion.c | 2 +- src/mon.c | 22 ++-- src/mondata.c | 34 ++--- src/monmove.c | 22 ++-- src/mthrowu.c | 40 +++--- src/muse.c | 14 +- src/music.c | 14 +- src/pager.c | 8 +- src/pickup.c | 30 ++--- src/pline.c | 2 +- src/polyself.c | 170 ++++++++++++------------ src/potion.c | 48 +++---- src/pray.c | 30 ++--- src/read.c | 34 ++--- src/region.c | 10 +- src/restore.c | 74 ++++------- src/save.c | 36 ++--- src/shk.c | 10 +- src/sit.c | 34 ++--- src/sounds.c | 18 +-- src/spell.c | 6 +- src/steal.c | 4 +- src/steed.c | 18 +-- src/teleport.c | 24 ++-- src/timeout.c | 28 ++-- src/trap.c | 188 +++++++++++++------------- src/u_init.c | 3 - src/uhitm.c | 306 +++++++++++++++++++++---------------------- src/vault.c | 8 +- src/weapon.c | 2 +- src/were.c | 4 +- src/wield.c | 10 +- src/wizcmds.c | 4 +- src/worn.c | 4 +- src/write.c | 2 +- src/zap.c | 86 ++++++------ 75 files changed, 1103 insertions(+), 1137 deletions(-) diff --git a/include/decl.h b/include/decl.h index 8ca46678a..9f9478052 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1082,6 +1082,7 @@ struct instance_globals_y { /* decl.c */ int y_maze_max; + struct monst youmonst; /* pline.c */ /* work buffer for You(), &c and verbalize() */ diff --git a/include/display.h b/include/display.h index beac064c0..fc52eac41 100644 --- a/include/display.h +++ b/include/display.h @@ -253,11 +253,11 @@ ((int) U_AP_TYPE == M_AP_NOTHING) \ ? hero_glyph \ : ((int) U_AP_TYPE == M_AP_FURNITURE) \ - ? cmap_to_glyph((int) u.umonst->mappearance) \ + ? cmap_to_glyph((int) gy.youmonst.mappearance) \ : ((int) U_AP_TYPE == M_AP_OBJECT) \ - ? objnum_to_glyph((int) u.umonst->mappearance) \ + ? objnum_to_glyph((int) gy.youmonst.mappearance) \ /* else U_AP_TYPE == M_AP_MONSTER */ \ - : monnum_to_glyph((int) u.umonst->mappearance, Ugender))) + : monnum_to_glyph((int) gy.youmonst.mappearance, Ugender))) /* * NetHack glyphs diff --git a/include/hack.h b/include/hack.h index 6cde43efe..f2197f13a 100644 --- a/include/hack.h +++ b/include/hack.h @@ -464,7 +464,7 @@ enum encumbrance_types { }; struct entity { - struct monst *emon; /* u.umonst for the player */ + struct monst *emon; /* youmonst for the player */ struct permonst *edata; /* must be non-zero for record to be valid */ int ex, ey; }; @@ -1294,7 +1294,7 @@ typedef uint32_t mmflags_nht; /* makemon MM_ flags */ #define FM_FMON 0x01 /* search the fmon chain */ #define FM_MIGRATE 0x02 /* search the migrating monster chain */ #define FM_MYDOGS 0x04 /* search gm.mydogs */ -#define FM_YOU 0x08 /* check for u.umonst */ +#define FM_YOU 0x08 /* check for gy.youmonst */ #define FM_EVERYWHERE (FM_YOU | FM_FMON | FM_MIGRATE | FM_MYDOGS) /* Flags to control pick_[race,role,gend,align] routines in role.c */ diff --git a/include/monst.h b/include/monst.h index 1d16a05db..af5147579 100644 --- a/include/monst.h +++ b/include/monst.h @@ -68,8 +68,8 @@ enum m_ap_types { #define M_AP_TYPMASK 0x7 #define M_AP_F_DKNOWN 0x8 -#define U_AP_TYPE (u.umonst->m_ap_type & M_AP_TYPMASK) -#define U_AP_FLAG (u.umonst->m_ap_type & ~M_AP_TYPMASK) +#define U_AP_TYPE (gy.youmonst.m_ap_type & M_AP_TYPMASK) +#define U_AP_FLAG (gy.youmonst.m_ap_type & ~M_AP_TYPMASK) #define M_AP_TYPE(m) ((m)->m_ap_type & M_AP_TYPMASK) #define M_AP_FLAG(m) ((m)->m_ap_type & ~M_AP_TYPMASK) diff --git a/include/patchlevel.h b/include/patchlevel.h index d9f25fea4..fd3dafc09 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -17,7 +17,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 141 +#define EDITLEVEL 142 /* * Development status possibilities. diff --git a/include/you.h b/include/you.h index 1f4b9c592..a073e5c57 100644 --- a/include/you.h +++ b/include/you.h @@ -496,9 +496,8 @@ struct you { struct skills weapon_skills[P_NUM_SKILLS]; boolean twoweap; /* KMH -- Using two-weapon combat */ short mcham; /* vampire mndx if shapeshifted to bat/cloud */ - short umovement; /* instead of u.umonst->movement */ + short umovement; /* instead of youmonst.movement */ schar uachieved[N_ACH]; /* list of achievements in the order attained */ - struct monst *umonst; }; /* end of `struct you' */ diff --git a/include/youprop.h b/include/youprop.h index 98862dead..f2c166606 100644 --- a/include/youprop.h +++ b/include/youprop.h @@ -67,7 +67,7 @@ #define HSick_resistance u.uprops[SICK_RES].intrinsic #define ESick_resistance u.uprops[SICK_RES].extrinsic #define Sick_resistance (HSick_resistance || ESick_resistance \ - || defended(u.umonst, AD_DISE)) + || defended(&gy.youmonst, AD_DISE)) /* Intrinsics only */ #define Invulnerable u.uprops[INVULNERABLE].intrinsic /* [Tom] */ @@ -270,11 +270,11 @@ #define HMagical_breathing u.uprops[MAGICAL_BREATHING].intrinsic #define EMagical_breathing u.uprops[MAGICAL_BREATHING].extrinsic #define Amphibious \ - (HMagical_breathing || EMagical_breathing || amphibious(u.umonst->data)) + (HMagical_breathing || EMagical_breathing || amphibious(gy.youmonst.data)) /* Get wet, may go under surface */ #define Breathless \ - (HMagical_breathing || EMagical_breathing || breathless(u.umonst->data)) + (HMagical_breathing || EMagical_breathing || breathless(gy.youmonst.data)) #define Underwater (u.uinwater) /* Note that Underwater and u.uinwater are both used in code. @@ -398,7 +398,7 @@ redundant but allows the function calls to be skipped most of the time */ #define Unaware (gm.multi < 0 && (unconscious() || is_fainted())) -#define Hate_silver (u.ulycn >= LOW_PM || hates_silver(u.umonst->data)) +#define Hate_silver (u.ulycn >= LOW_PM || hates_silver(gy.youmonst.data)) /* _The_Hitchhikers_Guide_to_the_Galaxy_ on uses for 'towel': "wrap it round your head to ward off noxious fumes" [we require it to be damp or wet] */ diff --git a/src/allmain.c b/src/allmain.c index 86f5b1db4..48dc040ef 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -120,7 +120,7 @@ u_calc_moveamt(int wtcap) /* your speed doesn't augment steed's speed */ moveamt = mcalcmove(u.usteed, TRUE); } else { - moveamt = u.umonst->data->mmove; + moveamt = gy.youmonst.data->mmove; if (Very_fast) { /* speed boots, potion, or spell */ /* gain a free action on 2/3 of turns */ @@ -292,7 +292,7 @@ moveloop_core(void) mvl_wtcap = UNENCUMBERED; } else if (!Upolyd ? (u.uhp < u.uhpmax) : (u.mh < u.mhmax - || u.umonst->data->mlet == S_EEL)) { + || gy.youmonst.data->mlet == S_EEL)) { /* maybe heal */ regen_hp(mvl_wtcap); } @@ -483,7 +483,7 @@ moveloop_core(void) curs_on_u(); } - m_everyturn_effect(u.umonst); + m_everyturn_effect(&gy.youmonst); svc.context.move = 1; @@ -636,7 +636,7 @@ regen_hp(int wtcap) if (Upolyd) { if (u.mh < 1) { /* shouldn't happen... */ rehumanize(); - } else if (u.umonst->data->mlet == S_EEL + } else if (gy.youmonst.data->mlet == S_EEL && !is_pool(u.ux, u.uy) && !Is_waterlevel(&u.uz) && !Breathless) { /* eel out of water loses hp, similar to monster eels; @@ -775,7 +775,7 @@ newgame(void) /* make sure welcome messages are given before noticing monsters */ notice_mon_off(); disp.botlx = TRUE; - svc.context.ident = 2; /* id 1 is reserved for u.umonst->m_id */ + svc.context.ident = 2; /* id 1 is reserved for gy.youmonst */ svc.context.warnlevel = 1; svc.context.next_attrib_check = 600L; /* arbitrary first setting */ svc.context.tribute.enabled = TRUE; /* turn on 3.6 tributes */ diff --git a/src/apply.c b/src/apply.c index 7f0d4320e..40aefc3d9 100644 --- a/src/apply.c +++ b/src/apply.c @@ -324,7 +324,7 @@ use_stethoscope(struct obj *obj) boolean interference = (u.uswallow && is_whirly(u.ustuck->data) && !rn2(Role_if(PM_HEALER) ? 10 : 3)); - if (nohands(u.umonst->data)) { + if (nohands(gy.youmonst.data)) { You("have no hands!"); /* not `body_part(HAND)' */ return ECMD_OK; } else if (Deaf) { @@ -475,7 +475,7 @@ static const char whistle_str[] = "produce a %s whistling sound.", staticfn void use_whistle(struct obj *obj) { - if (!can_blow(u.umonst)) { + if (!can_blow(&gy.youmonst)) { You("are incapable of using the whistle."); } else if (Underwater) { You("blow bubbles through %s.", yname(obj)); @@ -494,13 +494,13 @@ use_whistle(struct obj *obj) staticfn void use_magic_whistle(struct obj *obj) { - if (!can_blow(u.umonst)) { + if (!can_blow(&gy.youmonst)) { You("are incapable of using the whistle."); } else if (obj->cursed && !rn2(2)) { You("produce a %shigh-%s.", Underwater ? "very " : "", Deaf ? "frequency vibration" : "pitched humming noise"); wake_nearby(TRUE); - if (!rn2(2) && !noteleport_level(u.umonst)) + if (!rn2(2) && !noteleport_level(&gy.youmonst)) tele_to_rnd_pet(); } else { /* it's magic! it works underwater too (at a higher pitch) */ @@ -1054,8 +1054,8 @@ use_mirror(struct obj *obj) } gn.nomovemsg = 0; /* default, "you can move again" */ } - } else if (is_vampire(u.umonst->data) - || is_vampshifter(u.umonst)) { + } else if (is_vampire(gy.youmonst.data) + || is_vampshifter(&gy.youmonst)) { You("don't have a reflection."); } else if (u.umonnum == PM_UMBER_HULK) { pline("Huh? That doesn't look like you!"); @@ -1786,7 +1786,7 @@ dorub(void) { struct obj *obj; - if (nohands(u.umonst->data)) { + if (nohands(gy.youmonst.data)) { You("aren't able to rub anything without hands."); return ECMD_OK; } @@ -1884,7 +1884,7 @@ check_jump(genericptr arg, coordxy x, coordxy y) /* let giants jump over boulders (what about Flying? and is there really enough head room for giants to jump at all, let alone over something tall?) */ - if (sobj_at(BOULDER, x, y) && !throws_rocks(u.umonst->data)) + if (sobj_at(BOULDER, x, y) && !throws_rocks(gy.youmonst.data)) return FALSE; return TRUE; } @@ -1993,7 +1993,7 @@ jump(int magic) /* 0=Physical, otherwise skill level */ if (!magic && !Jumping && known_spell(SPE_JUMPING) >= spe_Fresh) return spelleffects(SPE_JUMPING, FALSE, FALSE); - if (!magic && (nolimbs(u.umonst->data) || slithy(u.umonst->data))) { + if (!magic && (nolimbs(gy.youmonst.data) || slithy(gy.youmonst.data))) { /* normally (nolimbs || slithy) implies !Jumping, but that isn't necessarily the case for knights */ You_cant("jump; you have no legs!"); @@ -2197,7 +2197,7 @@ use_tinning_kit(struct obj *obj) char kbuf[BUFSZ]; const char *corpse_name = an(cxname(corpse)); - if (poly_when_stoned(u.umonst->data)) { + if (poly_when_stoned(gy.youmonst.data)) { You("tin %s without wearing gloves.", corpse_name); kbuf[0] = '\0'; } else { @@ -2634,7 +2634,7 @@ use_grease(struct obj *obj) if (otmp != &hands_obj) { You("cover %s with a thick layer of grease.", yname(otmp)); otmp->greased = 1; - if (obj->cursed && !nohands(u.umonst->data)) { + if (obj->cursed && !nohands(gy.youmonst.data)) { make_glib(oldglib + rn1(6, 10)); /* + 10..15 */ pline("Some of the grease gets all over your %s.", fingers_or_gloves(TRUE)); @@ -2826,7 +2826,7 @@ use_trap(struct obj *otmp) int levtyp = levl[u.ux][u.uy].typ; const char *occutext = "setting the trap"; - if (nohands(u.umonst->data)) + if (nohands(gy.youmonst.data)) what = "without hands"; else if (Stunned) what = "while stunned"; @@ -3108,7 +3108,7 @@ use_whip(struct obj *obj) cc.y = ry; You("wrap your bullwhip around %s.", wrapped_what); if (proficient && rn2(proficient + 2)) { - if (!mtmp || enexto(&cc, rx, ry, u.umonst->data)) { + if (!mtmp || enexto(&cc, rx, ry, gy.youmonst.data)) { You("yank yourself out of the pit!"); reset_utrap(TRUE); /* [was after teleds(); do this before * in case it has no alternative other @@ -3192,7 +3192,7 @@ use_whip(struct obj *obj) so proficient at catching weapons */ int dam, hitvalu, hitu; - dam = dmgval(otmp, u.umonst); + dam = dmgval(otmp, &gy.youmonst); hitvalu = 8 + otmp->spe; hitu = thitu(hitvalu, Maybe_Half_Phys(dam), &otmp, (char *) 0); @@ -3210,7 +3210,7 @@ use_whip(struct obj *obj) if (otmp->otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm]) && !uarmg && !Stone_resistance - && !(poly_when_stoned(u.umonst->data) + && !(poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM))) { char kbuf[BUFSZ]; @@ -3581,7 +3581,7 @@ use_cream_pie(struct obj *obj) You("immerse your %s in %s%s.", body_part(FACE), several ? "one of " : "", several ? makeplural(the(xname(obj))) : the(xname(obj))); - if (can_blnd((struct monst *) 0, u.umonst, AT_WEAP, obj)) { + if (can_blnd((struct monst *) 0, &gy.youmonst, AT_WEAP, obj)) { int blindinc = rnd(25); u.ucreamed += blindinc; @@ -3921,7 +3921,7 @@ do_break_wand(struct obj *obj) boolean is_fragile = (objdescr_is(obj, "balsa") || objdescr_is(obj, "glass")); - if (nohands(u.umonst->data)) { + if (nohands(gy.youmonst.data)) { You_cant("break %s without hands!", yname(obj)); return ECMD_OK; } else if (!freehand()) { @@ -4216,7 +4216,7 @@ doapply(void) struct obj *obj; int res = ECMD_TIME; - if (nohands(u.umonst->data)) { + if (nohands(gy.youmonst.data)) { You("aren't able to use or apply tools in your current form."); return ECMD_OK; } diff --git a/src/artifact.c b/src/artifact.c index 17715e10c..e0e3df173 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -914,7 +914,7 @@ touch_artifact(struct obj *obj, struct monst *mon) if (oart == &artilist[ART_NONARTIFACT]) return 1; - yours = (mon == u.umonst); + yours = (mon == &gy.youmonst); /* all quest artifacts are self-willed; if this ever changes, `badclass' will have to be extended to explicitly include quest artifacts */ self_willed = ((oart->spfx & SPFX_INTEL) != 0); @@ -1014,7 +1014,7 @@ spec_applies(const struct artifact *weap, struct monst *mtmp) if (!(weap->spfx & (SPFX_DBONUS | SPFX_ATTK))) return (weap->attk.adtyp == AD_PHYS); - yours = (mtmp == u.umonst); + yours = (mtmp == &gy.youmonst); ptr = mtmp->data; if (weap->spfx & SPFX_DMONS) { @@ -1256,8 +1256,8 @@ Mb_hit(struct monst *magr, /* attacker */ { struct permonst *old_mdat; const char *verb; - boolean youattack = (magr == u.umonst), - youdefend = (mdef == u.umonst), + boolean youattack = (magr == &gy.youmonst), + youdefend = (mdef == &gy.youmonst), resisted = FALSE, do_stun, do_confuse, result; int attack_indx, fakeidx, scare_dieroll = MB_MAX_DIEROLL / 2; @@ -1313,7 +1313,7 @@ Mb_hit(struct monst *magr, /* attacker */ /* now perform special effects */ switch (attack_indx) { case MB_INDEX_CANCEL: - old_mdat = youdefend ? u.umonst->data : mdef->data; + old_mdat = youdefend ? gy.youmonst.data : mdef->data; /* No mdef->mcan check: even a cancelled monster can be polymorphed * into a golem, and the "cancel" effect acts as if some magical * energy remains in spellcasting defenders to be absorbed later. @@ -1323,7 +1323,7 @@ Mb_hit(struct monst *magr, /* attacker */ } else { do_stun = FALSE; if (youdefend) { - if (u.umonst->data != old_mdat) + if (gy.youmonst.data != old_mdat) *dmgptr = 0; /* rehumanized, so no more damage */ if (u.uenmax > 0) { u.uenmax--; @@ -1359,7 +1359,7 @@ Mb_hit(struct monst *magr, /* attacker */ nomul(-3); gm.multi_reason = "being scared stiff"; gn.nomovemsg = ""; - if (magr && magr == u.ustuck && sticks(u.umonst->data)) { + if (magr && magr == u.ustuck && sticks(gy.youmonst.data)) { set_ustuck((struct monst *) 0); You("release %s!", mon_nam(magr)); } @@ -1445,14 +1445,14 @@ DISABLE_WARNING_FORMAT_NONLITERAL */ boolean artifact_hit( - struct monst *magr, /* attacker; might be Null if 'mdef' is u.umonst */ + struct monst *magr, /* attacker; might be Null if 'mdef' is youmonst */ struct monst *mdef, /* defender */ struct obj *otmp, /* artifact weapon */ int *dmgptr, /* output */ int dieroll) /* needed for Magicbane and vorpal blades */ { - boolean youattack = (magr == u.umonst); - boolean youdefend = (mdef == u.umonst); + boolean youattack = (magr == &gy.youmonst); + boolean youdefend = (mdef == &gy.youmonst); boolean vis = (!youattack && magr && cansee(magr->mx, magr->my)) || (!youdefend && cansee(mdef->mx, mdef->my)) || (youattack && engulfing_u(mdef) && !Blind); @@ -1575,7 +1575,7 @@ artifact_hit( observe_object(otmp); return TRUE; } else { - if (bigmonst(u.umonst->data)) { + if (bigmonst(gy.youmonst.data)) { pline("%s cuts deeply into you!", magr ? Monnam(magr) : wepdesc); *dmgptr *= 2; @@ -1622,14 +1622,14 @@ artifact_hit( observe_object(otmp); return TRUE; } else { - if (!has_head(u.umonst->data)) { + if (!has_head(gy.youmonst.data)) { pline("Somehow, %s misses you wildly.", magr ? mon_nam(magr) : wepdesc); *dmgptr = 0; return TRUE; } - if (noncorporeal(u.umonst->data) - || amorphous(u.umonst->data)) { + if (noncorporeal(gy.youmonst.data) + || amorphous(gy.youmonst.data)) { pline("%s slices through your %s.", wepdesc, body_part(NECK)); return TRUE; @@ -2517,11 +2517,11 @@ retouch_object( return 1; } - if (touch_artifact(obj, u.umonst)) { + if (touch_artifact(obj, &gy.youmonst)) { char buf[BUFSZ]; int dmg = 0, tmp; boolean ag = (objects[obj->otyp].oc_material == SILVER && Hate_silver), - bane = bane_applies(get_artifact(obj), u.umonst); + bane = bane_applies(get_artifact(obj), &gy.youmonst); /* nothing else to do if hero can successfully handle this object */ if (!ag && !bane) @@ -2776,7 +2776,7 @@ is_magic_key(struct monst *mon, /* if null, non-rogue is assumed */ struct obj *obj) { if (is_art(obj, ART_MASTER_KEY_OF_THIEVERY)) { - if ((mon == u.umonst) ? Role_if(PM_ROGUE) + if ((mon == &gy.youmonst) ? Role_if(PM_ROGUE) : (mon && mon->data == &mons[PM_ROGUE])) return !obj->cursed; /* a rogue; non-cursed suffices for magic */ /* not a rogue; key must be blessed to behave as a magic one */ @@ -2785,7 +2785,7 @@ is_magic_key(struct monst *mon, /* if null, non-rogue is assumed */ return FALSE; } -/* figure out whether 'mon' (usually u.umonst) is carrying the magic key */ +/* figure out whether 'mon' (usually youmonst) is carrying the magic key */ struct obj * has_magic_key(struct monst *mon) /* if null, hero assumed */ { @@ -2793,8 +2793,8 @@ has_magic_key(struct monst *mon) /* if null, hero assumed */ short key = artilist[ART_MASTER_KEY_OF_THIEVERY].otyp; if (!mon) - mon = u.umonst; - for (o = ((mon == u.umonst) ? gi.invent : mon->minvent); o; + mon = &gy.youmonst; + for (o = ((mon == &gy.youmonst) ? gi.invent : mon->minvent); o; o = nxtobj(o, key, FALSE)) { if (is_magic_key(mon, o)) return o; diff --git a/src/attrib.c b/src/attrib.c index bebb46327..27f454fd8 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -893,7 +893,7 @@ is_innate(int propidx) ignore innateness if equipment is going to claim responsibility */ && !u.uprops[propidx].extrinsic) return FROM_ROLE; - if ((propidx == BLINDED && !haseyes(u.umonst->data)) + if ((propidx == BLINDED && !haseyes(gy.youmonst.data)) || (propidx == BLND_RES && (HBlnd_resist & FROMFORM) != 0)) return FROM_FORM; return FROM_NONE; @@ -1219,7 +1219,7 @@ acurr(int chridx) there would limit Str to 18/07 [18 + 7] */ result = max(tmp, 3); } else if (chridx == A_CHA) { - if (tmp < 18 && (u.umonst->data->mlet == S_NYMPH + if (tmp < 18 && (gy.youmonst.data->mlet == S_NYMPH || u.umonnum == PM_AMOROUS_DEMON)) result = 18; } else if (chridx == A_CON) { diff --git a/src/botl.c b/src/botl.c index b6e72c896..66c4b8950 100644 --- a/src/botl.c +++ b/src/botl.c @@ -256,7 +256,7 @@ bot(void) return; /* dosave() flags completion by setting u.uhp to -1; suppress_map_output() covers program_state.restoring and is used for status as well as map */ - if (u.uhp != -1 && u.umonst->data + if (u.uhp != -1 && gy.youmonst.data && iflags.status_updates && !suppress_map_output()) { if (VIA_WINDOWPORT()) { bot_via_windowport(); @@ -487,7 +487,7 @@ weapon_status(char *outbuf) /* no weapon; gloves imply hands; humanoid also implies hands; otherwise make no assumptions */ res = uarmg ? "Empty-hnd" /* empty handed means "gloves only" */ - : humanoid(u.umonst->data) ? "Bare-hnds" /* bare hands */ + : humanoid(gy.youmonst.data) ? "Bare-hnds" /* bare hands */ : "No-weapon"; } else if (u.twoweap) { /* two-weaponing implies hands and a weapon or wep-tool @@ -1179,7 +1179,7 @@ bot_via_windowport(void) #else test_if_enabled(bl_held) = TRUE; #endif - } else if (Upolyd && sticks(u.umonst->data)) { + } else if (Upolyd && sticks(gy.youmonst.data)) { test_if_enabled(bl_holding) = TRUE; } else { /* grab == hero is held by sea monster and about to be drowned; diff --git a/src/cmd.c b/src/cmd.c index 705e2dbc4..a2ddb69e3 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -889,7 +889,7 @@ RESTORE_WARNING_FORMAT_NONLITERAL int domonability(void) { - struct permonst *uptr = u.umonst->data; + struct permonst *uptr = gy.youmonst.data; boolean might_hide = (is_hider(uptr) || hides_under(uptr)); char c = '\0'; @@ -917,12 +917,12 @@ domonability(void) return domindblast(); else if (u.umonnum == PM_GREMLIN) { if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)) { - if (split_mon(u.umonst, (struct monst *) 0)) + if (split_mon(&gy.youmonst, (struct monst *) 0)) dryup(u.ux, u.uy, TRUE); } else if (is_pool(u.ux, u.uy)) { /* is_pool: might be wearing water walking boots or amulet of magical breathing */ - (void) split_mon(u.umonst, (struct monst *) 0); + (void) split_mon(&gy.youmonst, (struct monst *) 0); } else { There("is no fountain here."); } @@ -935,7 +935,7 @@ domonability(void) pline("Unfortunately sound does not carry well through rock."); else aggravate(); - } else if (is_vampire(uptr) || is_vampshifter(u.umonst)) { + } else if (is_vampire(uptr) || is_vampshifter(&gy.youmonst)) { return dopoly(); } else if (u.usteed && can_breathe(u.usteed->data)) { (void) pet_ranged_attk(u.usteed, TRUE); diff --git a/src/dbridge.c b/src/dbridge.c index 6afcac7d5..72d39be82 100644 --- a/src/dbridge.c +++ b/src/dbridge.c @@ -320,10 +320,10 @@ m_to_e(struct monst *mtmp, coordxy x, coordxy y, struct entity *etmp) staticfn void u_to_e(struct entity *etmp) { - etmp->emon = u.umonst; + etmp->emon = &gy.youmonst; etmp->ex = u.ux; etmp->ey = u.uy; - etmp->edata = u.umonst->data; + etmp->edata = gy.youmonst.data; } staticfn void @@ -337,7 +337,7 @@ set_entity( m_to_e(m_at(x, y), x, y, etmp); } -#define is_u(etmp) (etmp->emon == u.umonst) +#define is_u(etmp) (etmp->emon == &gy.youmonst) #define e_canseemon(etmp) (is_u(etmp) || canseemon(etmp->emon)) /* diff --git a/src/decl.c b/src/decl.c index 43d7143b9..b8852795f 100644 --- a/src/decl.c +++ b/src/decl.c @@ -842,6 +842,7 @@ static const struct instance_globals_x g_init_x = { static const struct instance_globals_y g_init_y = { /* decl.c */ (ROWNO - 1) & ~1, /* y_maze_max */ + DUMMY, /* youmonst */ /* pline.c */ NULL, /* you_buf */ 0, /* you_buf_siz */ diff --git a/src/detect.c b/src/detect.c index ea077b91a..bf536e127 100644 --- a/src/detect.c +++ b/src/detect.c @@ -386,7 +386,7 @@ gold_detect(struct obj *sobj) adjust message if you have gold in your inventory */ char buf[BUFSZ]; - if (u.umonst->data == &mons[PM_GOLD_GOLEM]) + if (gy.youmonst.data == &mons[PM_GOLD_GOLEM]) Sprintf(buf, "You feel like a million %s!", currency(2L)); else if (money_cnt(gi.invent) || hidden_gold(TRUE)) Strcpy(buf, @@ -1227,7 +1227,7 @@ use_crystal_ball(struct obj **optr) make_confused((HConfusion & TIMEOUT) + impair, FALSE); break; case 3: - if (!resists_blnd(u.umonst)) { + if (!resists_blnd(&gy.youmonst)) { pline("%s your vision!", Tobjnam(obj, "damage")); make_blinded(BlindedTimeout + impair, FALSE); if (!Blind) @@ -1776,7 +1776,7 @@ openone(coordxy zx, coordxy zy, genericptr_t num) newsym(zx, zy); (*num_p)++; } - mon = u_at(zx, zy) ? u.umonst : m_at(zx, zy); + mon = u_at(zx, zy) ? &gy.youmonst : m_at(zx, zy); if (openholdingtrap(mon, &dummy) || openfallingtrap(mon, TRUE, &dummy)) (*num_p)++; diff --git a/src/dig.c b/src/dig.c index 1c0ff6ceb..5e5fc1a74 100644 --- a/src/dig.c +++ b/src/dig.c @@ -200,7 +200,7 @@ is_digging(void) return FALSE; } -#define BY_YOU (u.umonst) +#define BY_YOU (&gy.youmonst) #define BY_OBJECT ((struct monst *) 0) enum digcheck_result @@ -392,7 +392,7 @@ dig(void) } else if (ttmp && ttmp->ttyp == BEAR_TRAP && u.utrap) { if (rnl(7) > (Fumbling ? 1 : 4)) { char kbuf[BUFSZ]; - int dmg = dmgval(uwep, u.umonst) + dbon(); + int dmg = dmgval(uwep, &gy.youmonst) + dbon(); if (dmg < 1) dmg = 1; @@ -2181,8 +2181,8 @@ rot_corpse(anything *arg, long timeout) && hides_under(mtmp->data)) { mtmp->mundetected = 0; } else if (u_at(x, y) - && u.uundetected && hides_under(u.umonst->data)) - (void) hideunder(u.umonst); + && u.uundetected && hides_under(gy.youmonst.data)) + (void) hideunder(&gy.youmonst); newsym(x, y); } else if (in_invent) update_inventory(); @@ -2241,27 +2241,27 @@ void escape_tomb(void) { debugpline0("escape_tomb"); - if ((Teleportation || can_teleport(u.umonst->data)) + if ((Teleportation || can_teleport(gy.youmonst.data)) && (Teleport_control || rn2(3) < Luck+2)) { You("attempt a teleport spell."); (void) dotele(FALSE); /* calls unearth_you() */ } else if (u.uburied) { /* still buried after 'port attempt */ boolean good; - if (amorphous(u.umonst->data) || Passes_walls - || noncorporeal(u.umonst->data) - || (unsolid(u.umonst->data) - && u.umonst->data != &mons[PM_WATER_ELEMENTAL]) - || (tunnels(u.umonst->data) && !needspick(u.umonst->data))) { + if (amorphous(gy.youmonst.data) || Passes_walls + || noncorporeal(gy.youmonst.data) + || (unsolid(gy.youmonst.data) + && gy.youmonst.data != &mons[PM_WATER_ELEMENTAL]) + || (tunnels(gy.youmonst.data) && !needspick(gy.youmonst.data))) { You("%s up through the %s.", - (tunnels(u.umonst->data) && !needspick(u.umonst->data)) + (tunnels(gy.youmonst.data) && !needspick(gy.youmonst.data)) ? "try to tunnel" - : (amorphous(u.umonst->data)) + : (amorphous(gy.youmonst.data)) ? "ooze" : "phase", surface(u.ux, u.uy)); - good = (tunnels(u.umonst->data) && !needspick(u.umonst->data)) + good = (tunnels(gy.youmonst.data) && !needspick(gy.youmonst.data)) ? dighole(TRUE, FALSE, (coord *) 0) : TRUE; if (good) unearth_you(); diff --git a/src/do.c b/src/do.c index b5aac1445..cacab11c7 100644 --- a/src/do.c +++ b/src/do.c @@ -228,7 +228,7 @@ flooreffects( } mtmp->mtrapped = 0; } else { - if (!Passes_walls && !throws_rocks(u.umonst->data)) { + if (!Passes_walls && !throws_rocks(gy.youmonst.data)) { losehp(Maybe_Half_Phys(rnd(15)), "squished under a boulder", NO_KILLER_PREFIX); goto deletedwithboulder; @@ -1110,7 +1110,7 @@ staticfn boolean u_stuck_cannot_go(const char *updn) { if (u.ustuck) { - if (u.uswallow || !sticks(u.umonst->data)) { + if (u.uswallow || !sticks(gy.youmonst.data)) { You("are %s, and cannot go %s.", !u.uswallow ? "being held" : digests(u.ustuck->data) ? "swallowed" @@ -1257,7 +1257,7 @@ dodown(void) const char *down_or_thru = trap->ttyp == HOLE ? "down" : "through"; const char *actn = u_locomotion("jump"); - if (u.umonst->data->msize >= MZ_HUGE) { + if (gy.youmonst.data->msize >= MZ_HUGE) { char qbuf[QBUFSZ]; You("don't fit %s easily.", down_or_thru); @@ -1426,7 +1426,7 @@ u_collide_m(struct monst *mtmp) it was already here. Randomly move you to an adjacent spot or else the monster to any nearby location. Prior to 3.3.0 the latter was done unconditionally. */ - if (!rn2(2) && enexto(&cc, u.ux, u.uy, u.umonst->data) + if (!rn2(2) && enexto(&cc, u.ux, u.uy, gy.youmonst.data) && next2u(cc.x, cc.y)) u_on_newpos(cc.x, cc.y); /*[maybe give message here?]*/ else @@ -2008,7 +2008,7 @@ hellish_smoke_mesg(void) if (In_hell(&u.uz) && svl.level.flags.temperature > 0) You("%s smoke...", - olfaction(u.umonst->data) ? "smell" : "sense"); + olfaction(gy.youmonst.data) ? "smell" : "sense"); } /* give a message when the level temperature is different from previous */ diff --git a/src/do_name.c b/src/do_name.c index 8ef9f7294..7116e0705 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -689,7 +689,7 @@ namefloorobj(void) been moved off the hero's '@' yet, but there's no way to adjust the help text once getpos() has started */ Sprintf(buf, "object on map (or '.' for one %s you)", - (u.uundetected && hides_under(u.umonst->data)) + (u.uundetected && hides_under(gy.youmonst.data)) ? "over" : "under"); if (getpos(&cc, FALSE, buf) < 0 || cc.x <= 0) return; @@ -840,7 +840,7 @@ x_monnam( mappear_as_mon = (M_AP_TYPE(mtmp) == M_AP_MONSTER); char *bp, buf2[BUFSZ]; - if (mtmp == u.umonst) + if (mtmp == &gy.youmonst) return strcpy(buf, "you"); /* ignore article, "invisible", &c */ if (program_state.gameover) @@ -1290,7 +1290,7 @@ Mgender(struct monst *mtmp) { int mgender = MALE; - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { if (Upolyd ? u.mfemale : flags.female) mgender = FEMALE; } else if (mtmp->female) { diff --git a/src/do_wear.c b/src/do_wear.c index 59e62927d..382b17741 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -281,7 +281,7 @@ Boots_off(void) /* check for lava since fireproofed boots make it viable */ if ((is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) && !Levitation && !Flying - && !(is_clinger(u.umonst->data) && has_ceiling(&u.uz)) + && !(is_clinger(gy.youmonst.data) && has_ceiling(&u.uz)) && !svc.context.takeoff.cancelled_don /* avoid recursive call to lava_effects() */ && !iflags.in_lava_effects) { @@ -1035,7 +1035,7 @@ Amulet_on(struct obj *amul) } case AMULET_OF_STRANGULATION: /* note: might already be Strangled (via #wizintrinsic) */ - if (can_be_strangled(u.umonst) && !Strangled) { + if (can_be_strangled(&gy.youmonst) && !Strangled) { makeknown(AMULET_OF_STRANGULATION); Strangled = 6L; disp.botl = TRUE; @@ -1118,7 +1118,7 @@ Amulet_off(void) early_off_msg = TRUE; if (Underwater) { - if (!cant_drown(u.umonst->data) && !Swimming) { + if (!cant_drown(gy.youmonst.data) && !Swimming) { You("suddenly inhale an unhealthy amount of %s!", hliquid("water")); mkn = TRUE; /* in case of life-saving */ @@ -2034,7 +2034,7 @@ canwearobj(struct obj *otmp, long *mask, boolean noisy) /* this is the same check as for 'W' (dowear), but different message, in case we get here via 'P' (doputon) */ - if (verysmall(u.umonst->data) || nohands(u.umonst->data)) { + if (verysmall(gy.youmonst.data) || nohands(gy.youmonst.data)) { if (noisy) You("can't wear any armor in your current form."); return 0; @@ -2044,13 +2044,13 @@ canwearobj(struct obj *otmp, long *mask, boolean noisy) : is_shirt(otmp) ? c_shirt : is_suit(otmp) ? c_suit : 0; - if (which && cantweararm(u.umonst->data) + if (which && cantweararm(gy.youmonst.data) /* same exception for cloaks as used in m_dowear() */ && (which != c_cloak || ((otmp->otyp != MUMMY_WRAPPING) - ? u.umonst->data->msize != MZ_SMALL - : !WrappingAllowed(u.umonst->data))) - && (racial_exception(u.umonst, otmp) < 1)) { + ? gy.youmonst.data->msize != MZ_SMALL + : !WrappingAllowed(gy.youmonst.data))) + && (racial_exception(&gy.youmonst, otmp) < 1)) { if (noisy) pline_The("%s will not fit on your body.", which); return 0; @@ -2072,12 +2072,12 @@ canwearobj(struct obj *otmp, long *mask, boolean noisy) if (noisy) already_wearing(an(helm_simple_name(uarmh))); err++; - } else if (Upolyd && has_horns(u.umonst->data) && !is_flimsy(otmp)) { + } else if (Upolyd && has_horns(gy.youmonst.data) && !is_flimsy(otmp)) { /* (flimsy exception matches polyself handling) */ if (noisy) pline_The("%s won't fit over your horn%s.", helm_simple_name(otmp), - plur(num_horns(u.umonst->data))); + plur(num_horns(gy.youmonst.data))); err++; } else *mask = W_ARMH; @@ -2104,11 +2104,11 @@ canwearobj(struct obj *otmp, long *mask, boolean noisy) if (noisy) already_wearing(c_boots); err++; - } else if (Upolyd && slithy(u.umonst->data)) { + } else if (Upolyd && slithy(gy.youmonst.data)) { if (noisy) You("have no feet..."); /* not body_part(FOOT) */ err++; - } else if (Upolyd && u.umonst->data->mlet == S_CENTAUR) { + } else if (Upolyd && gy.youmonst.data->mlet == S_CENTAUR) { /* break_armor() pushes boots off for centaurs, so don't let dowear() put them back on; makeplural(body_part(FOOT)) would yield "rear hooves" here, @@ -2251,13 +2251,13 @@ accessory_or_armor_on(struct obj *obj) char answer, qbuf[QBUFSZ]; int res = 0; - if (nolimbs(u.umonst->data)) { + if (nolimbs(gy.youmonst.data)) { You("cannot make the ring stick to your body."); return ECMD_OK; } if (uleft && uright) { There("are no more %s%s to fill.", - humanoid(u.umonst->data) ? "ring-" : "", + humanoid(gy.youmonst.data) ? "ring-" : "", fingers_or_gloves(FALSE)); return ECMD_OK; } @@ -2268,7 +2268,7 @@ accessory_or_armor_on(struct obj *obj) } else { do { Sprintf(qbuf, "Which %s%s, Right or Left?", - humanoid(u.umonst->data) ? "ring-" : "", + humanoid(gy.youmonst.data) ? "ring-" : "", body_part(FINGER)); answer = yn_function(qbuf, rightleftchars, '\0', TRUE); switch (answer) { @@ -2321,7 +2321,7 @@ accessory_or_armor_on(struct obj *obj) return ECMD_OK; } } else if (eyewear) { - if (!has_head(u.umonst->data)) { + if (!has_head(gy.youmonst.data)) { You("have no head to wear %s on.", ansimpleoname(obj)); return ECMD_OK; } @@ -2435,7 +2435,7 @@ dowear(void) /* cantweararm() checks for suits of armor, not what we want here; verysmall() or nohands() checks for shields, gloves, etc... */ - if (verysmall(u.umonst->data) || nohands(u.umonst->data)) { + if (verysmall(gy.youmonst.data) || nohands(gy.youmonst.data)) { pline("Don't even bother."); return ECMD_OK; } @@ -2459,7 +2459,7 @@ doputon(void) && uarm && uarmu && uarmc && uarmh && uarms && uarmg && uarmf) { /* 'P' message doesn't mention armor */ Your("%s%s are full, and you're already wearing an amulet and %s.", - humanoid(u.umonst->data) ? "ring-" : "", + humanoid(gy.youmonst.data) ? "ring-" : "", fingers_or_gloves(FALSE), (ublindf->otyp == LENSES) ? "some lenses" : "a blindfold"); return ECMD_OK; @@ -2544,7 +2544,7 @@ glibr(void) rightfall = (uright && !uright->cursed && (!welded(uwep))); */ - if (!uarmg && (leftfall || rightfall) && !nolimbs(u.umonst->data)) { + if (!uarmg && (leftfall || rightfall) && !nolimbs(gy.youmonst.data)) { /* changed so cursed rings don't fall off, GAN 10/30/86 */ Your("%s off your %s.", (leftfall && rightfall) ? "rings slip" : "ring slips", @@ -2631,22 +2631,22 @@ some_armor(struct monst *victim) { struct obj *otmph, *otmp; - otmph = (victim == u.umonst) ? uarmc : which_armor(victim, W_ARMC); + otmph = (victim == &gy.youmonst) ? uarmc : which_armor(victim, W_ARMC); if (!otmph) - otmph = (victim == u.umonst) ? uarm : which_armor(victim, W_ARM); + otmph = (victim == &gy.youmonst) ? uarm : which_armor(victim, W_ARM); if (!otmph) - otmph = (victim == u.umonst) ? uarmu : which_armor(victim, W_ARMU); + otmph = (victim == &gy.youmonst) ? uarmu : which_armor(victim, W_ARMU); - otmp = (victim == u.umonst) ? uarmh : which_armor(victim, W_ARMH); + otmp = (victim == &gy.youmonst) ? uarmh : which_armor(victim, W_ARMH); if (otmp && (!otmph || !rn2(4))) otmph = otmp; - otmp = (victim == u.umonst) ? uarmg : which_armor(victim, W_ARMG); + otmp = (victim == &gy.youmonst) ? uarmg : which_armor(victim, W_ARMG); if (otmp && (!otmph || !rn2(4))) otmph = otmp; - otmp = (victim == u.umonst) ? uarmf : which_armor(victim, W_ARMF); + otmp = (victim == &gy.youmonst) ? uarmf : which_armor(victim, W_ARMF); if (otmp && (!otmph || !rn2(4))) otmph = otmp; - otmp = (victim == u.umonst) ? uarms : which_armor(victim, W_ARMS); + otmp = (victim == &gy.youmonst) ? uarms : which_armor(victim, W_ARMS); if (otmp && (!otmph || !rn2(4))) otmph = otmp; return otmph; @@ -2664,7 +2664,7 @@ stuck_ring(struct obj *ring, int otyp) if (ring && ring->otyp == otyp) { /* reasons ring can't be removed match those checked by select_off(); limbless case has extra checks because ordinarily it's temporary */ - if (nolimbs(u.umonst->data) && uamul + if (nolimbs(gy.youmonst.data) && uamul && uamul->otyp == AMULET_OF_UNCHANGING && uamul->cursed) return uamul; if (welded(uwep) && ((ring == RING_ON_PRIMARY) || bimanual(uwep))) @@ -2706,7 +2706,7 @@ select_off(struct obj *otmp) if (otmp == uright || otmp == uleft) { struct obj glibdummy; - if (nolimbs(u.umonst->data)) { + if (nolimbs(gy.youmonst.data)) { pline_The("ring is stuck."); return 0; } diff --git a/src/dog.c b/src/dog.c index 742af8dc8..856a2d14f 100644 --- a/src/dog.c +++ b/src/dog.c @@ -1185,7 +1185,7 @@ tamedog( if (mtmp == u.ustuck) { if (u.uswallow) expels(mtmp, mtmp->data, TRUE); - else if (!(Upolyd && sticks(u.umonst->data))) + else if (!(Upolyd && sticks(gy.youmonst.data))) unstuck(mtmp); } @@ -1243,7 +1243,7 @@ tamedog( with each other anymore] */ || mtmp->isshk || mtmp->isgd || mtmp->ispriest || mtmp->isminion || is_covetous(mtmp->data) || is_human(mtmp->data) - || (is_demon(mtmp->data) && !is_demon(u.umonst->data)) + || (is_demon(mtmp->data) && !is_demon(gy.youmonst.data)) || (obj && dogfood(mtmp, obj) >= MANFOOD)) return FALSE; @@ -1313,7 +1313,7 @@ wary_dog(struct monst *mtmp, boolean was_dead) if (!rn2(edog->abuse + 1)) mtmp->mpeaceful = 1; if (!quietly && cansee(mtmp->mx, mtmp->my)) { - if (haseyes(u.umonst->data)) { + if (haseyes(gy.youmonst.data)) { if (haseyes(mtmp->data)) pline_mon(mtmp, "%s %s to look you in the %s.", Monnam(mtmp), diff --git a/src/dogmove.c b/src/dogmove.c index fa209f1d3..1218c305e 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -675,7 +675,7 @@ find_targ( break; if (curx == mtmp->mux && cury == mtmp->muy) - return u.umonst; + return &gy.youmonst; if ((targ = m_at(curx, cury)) != 0) { /* Is the monster visible to the pet? */ @@ -778,7 +778,7 @@ score_targ(struct monst *mtmp, struct monst *mtarg) return score; } /* Is the monster peaceful or tame? */ - if (/*mtarg->mpeaceful ||*/ mtarg->mtame || mtarg == u.umonst) { + if (/*mtarg->mpeaceful ||*/ mtarg->mtame || mtarg == &gy.youmonst) { /* Pets will never be targeted */ score -= 3000L; return score; @@ -907,7 +907,7 @@ pet_ranged_attk(struct monst *mtmp, boolean forced) if (mtarg && (!hungry || !rn2(5))) { int mstatus = M_ATTK_MISS; - if (mtarg == u.umonst) { + if (mtarg == &gy.youmonst) { if (mattacku(mtmp)) return MMOVE_DIED; /* Treat this as the pet having initiated an attack even if it @@ -931,7 +931,7 @@ pet_ranged_attk(struct monst *mtmp, boolean forced) * nothing will happen. */ if ((mstatus & M_ATTK_HIT) && !(mstatus & M_ATTK_DEF_DIED) - && rn2(4) && mtarg != u.umonst) { + && rn2(4) && mtarg != &gy.youmonst) { /* Can monster see? If it can, it can retaliate * even if the pet is invisible, since it'll see @@ -1054,7 +1054,7 @@ dog_move( } #if 0 /* [this is now handled in dochug()] */ if (!Conflict && !mtmp->mconf - && mtmp == u.ustuck && !sticks(u.umonst->data)) { + && mtmp == u.ustuck && !sticks(gy.youmonst.data)) { unstuck(mtmp); /* swallowed case handled above */ You("get released!"); } diff --git a/src/dokick.c b/src/dokick.c index e20f83100..45d0b097c 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -6,7 +6,7 @@ #define is_bigfoot(x) ((x) == &mons[PM_SASQUATCH]) #define martial() \ - (martial_bonus() || is_bigfoot(u.umonst->data) \ + (martial_bonus() || is_bigfoot(gy.youmonst.data) \ || (uarmf && uarmf->otyp == KICKING_BOOTS)) /* gk.kickedobj (decl.c) tracks a kicked object until placed or destroyed */ @@ -53,7 +53,7 @@ kickdmg(struct monst *mon, boolean clumsy) if (mon->data == &mons[PM_SHADE]) dmg = 0; - specialdmg = special_dmgval(u.umonst, mon, W_ARMF, (long *) 0); + specialdmg = special_dmgval(&gy.youmonst, mon, W_ARMF, (long *) 0); if (mon->data == &mons[PM_SHADE] && !specialdmg) { pline_The("%s.", kick_passes_thru); @@ -180,7 +180,7 @@ kick_monster(struct monst *mon, coordxy x, coordxy y) * normally, getting all your attacks _including_ all your kicks. * If you have >1 kick attack, you get all of them. */ - if (Upolyd && attacktype(u.umonst->data, AT_KICK)) { + if (Upolyd && attacktype(gy.youmonst.data, AT_KICK)) { struct attack *uattk; int sum, kickdieroll, armorpenalty, specialdmg, attknum = 0, @@ -194,13 +194,13 @@ kick_monster(struct monst *mon, coordxy x, coordxy y) if (gm.multi < 0) break; - uattk = &u.umonst->data->mattk[i]; + uattk = &gy.youmonst.data->mattk[i]; /* we only care about kicking attacks here */ if (uattk->aatyp != AT_KICK) continue; kickdieroll = rnd(20); - specialdmg = special_dmgval(u.umonst, mon, W_ARMF, + specialdmg = special_dmgval(&gy.youmonst, mon, W_ARMF, (long *) 0); if (mon->data == &mons[PM_SHADE] && !specialdmg) { /* doesn't matter whether it would have hit or missed, @@ -545,7 +545,7 @@ really_kick_object(coordxy x, coordxy y) You("kick %s with your bare %s.", corpse_xname(gk.kickedobj, (const char *) 0, CXN_PFX_THE), makeplural(body_part(FOOT))); - if (poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM)) { + if (poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM)) { ; /* hero has been transformed but kick continues */ } else { /* normalize body shape here; foot, not body_part(FOOT) */ @@ -924,7 +924,7 @@ kick_door(coordxy x, coordxy y, int avrg_attrib) } exercise(A_DEX, TRUE); - doorbuster = Upolyd && is_giant(u.umonst->data); + doorbuster = Upolyd && is_giant(gy.youmonst.data); /* door is known to be CLOSED or LOCKED */ if (doorbuster || (rnl(35) < avrg_attrib + (!martial() ? 0 : ACURR(A_DEX)))) { @@ -1262,10 +1262,10 @@ dokick(void) struct monst *mtmp; boolean no_kick = FALSE; - if (nolimbs(u.umonst->data) || slithy(u.umonst->data)) { + if (nolimbs(gy.youmonst.data) || slithy(gy.youmonst.data)) { You("have no legs to kick with."); no_kick = TRUE; - } else if (verysmall(u.umonst->data)) { + } else if (verysmall(gy.youmonst.data)) { You("are too small to do any kicking."); no_kick = TRUE; } else if (u.usteed) { @@ -1282,7 +1282,7 @@ dokick(void) } else if (near_capacity() > SLT_ENCUMBER) { Your("load is too heavy to balance yourself for a kick."); no_kick = TRUE; - } else if (u.umonst->data->mlet == S_LIZARD) { + } else if (gy.youmonst.data->mlet == S_LIZARD) { Your("legs cannot kick effectively."); no_kick = TRUE; } else if (u.uinwater && !rn2(2)) { @@ -1429,7 +1429,7 @@ dokick(void) int range; range = - ((int) u.umonst->data->cwt + (weight_cap() + inv_weight())); + ((int) gy.youmonst.data->cwt + (weight_cap() + inv_weight())); if (range < 1) range = 1; /* divide by zero avoidance */ range = (3 * (int) mdat->cwt) / range; diff --git a/src/dothrow.c b/src/dothrow.c index e3ff3457c..952913a43 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -125,7 +125,7 @@ throw_obj(struct obj *obj, int shotlimit) goto unsplit_stack; } if ((is_art(obj, ART_MJOLLNIR) && ACURR(A_STR) < STR19(25)) - || (obj->otyp == BOULDER && !throws_rocks(u.umonst->data))) { + || (obj->otyp == BOULDER && !throws_rocks(gy.youmonst.data))) { pline("It's too heavy."); res = ECMD_TIME; goto unsplit_stack; @@ -299,10 +299,10 @@ ok_to_throw(int *shotlimit_p) /* (see dothrow()) */ *shotlimit_p = LIMIT_TO_RANGE_INT(0, LARGEST_INT, gc.command_count); gm.multi = 0; /* reset; it's been used up */ - if (notake(u.umonst->data)) { + if (notake(gy.youmonst.data)) { You("are physically incapable of throwing or shooting anything."); return FALSE; - } else if (nohands(u.umonst->data)) { + } else if (nohands(gy.youmonst.data)) { You_cant("throw or shoot without hands."); /* not body_part(HAND) */ return FALSE; /*[what about !freehand(), aside from cursed missile launcher?]*/ @@ -341,7 +341,7 @@ throw_ok(struct obj *obj) if (uslinging() && obj->oclass == GEM_CLASS) return GETOBJ_SUGGEST; - if (throws_rocks(u.umonst->data) && obj->otyp == BOULDER) + if (throws_rocks(gy.youmonst.data) && obj->otyp == BOULDER) return GETOBJ_SUGGEST; return GETOBJ_DOWNPLAY; @@ -820,12 +820,12 @@ hurtle_step(genericptr_t arg, coordxy x, coordxy y) why = "touching the edge of the universe"; You("smack into something!"); } else if (diagonal - && bad_rock(u.umonst->data, u.ux, y) - && bad_rock(u.umonst->data, x, u.uy)) { + && bad_rock(gy.youmonst.data, u.ux, y) + && bad_rock(gy.youmonst.data, x, u.uy)) { boolean too_much = (gi.invent && (inv_weight() + weight_cap() > WT_TOOMUCH_DIAGONAL)); - if (bigmonst(u.umonst->data) || too_much) { + if (bigmonst(gy.youmonst.data) || too_much) { why = "wedging into a narrow crevice"; You("%sget forcefully wedged into a crevice.", too_much ? "and all your belongings " : ""); @@ -874,7 +874,7 @@ hurtle_step(genericptr_t arg, coordxy x, coordxy y) an(pmname(mon->data, NEUTRAL))); instapetrify(svk.killer.name); } - if (touch_petrifies(u.umonst->data) + if (touch_petrifies(gy.youmonst.data) && !which_armor(mon, W_ARMU | W_ARM | W_ARMC)) { minstapetrify(mon, TRUE); } @@ -883,8 +883,8 @@ hurtle_step(genericptr_t arg, coordxy x, coordxy y) } if ((u.ux - x) && (u.uy - y) - && bad_rock(u.umonst->data, u.ux, y) - && bad_rock(u.umonst->data, x, u.uy)) { + && bad_rock(gy.youmonst.data, u.ux, y) + && bad_rock(gy.youmonst.data, x, u.uy)) { /* Move at a diagonal. */ if (Sokoban) { You("come to an abrupt halt!"); @@ -1045,7 +1045,7 @@ mhurtle_step(genericptr_t arg, coordxy x, coordxy y) pline("%s bumps into you.", Some_Monnam(mon)); stop_occupation(); /* check whether 'mon' is turned to stone by touching poly'd hero */ - if (Upolyd && touch_petrifies(u.umonst->data) + if (Upolyd && touch_petrifies(gy.youmonst.data) && !which_armor(mon, W_ARMU | W_ARM | W_ARMC)) { /* give poly'd hero credit/blame despite a monster causing it */ minstapetrify(mon, TRUE); @@ -1287,14 +1287,14 @@ toss_up(struct obj *obj, boolean hitsroof) /* object now hits you */ if (obj->oclass == POTION_CLASS) { - potionhit(u.umonst, obj, POTHIT_HERO_THROW); + potionhit(&gy.youmonst, obj, POTHIT_HERO_THROW); } else if (breaktest(obj)) { int blindinc; /* need to check for blindness result prior to destroying obj */ blindinc = ((otyp == CREAM_PIE || otyp == BLINDING_VENOM) /* AT_WEAP is ok here even if attack type was AT_SPIT */ - && can_blnd(u.umonst, u.umonst, AT_WEAP, obj)) + && can_blnd(&gy.youmonst, &gy.youmonst, AT_WEAP, obj)) ? rnd(25) : 0; breakmsg(obj, !Blind); @@ -1304,7 +1304,7 @@ toss_up(struct obj *obj, boolean hitsroof) switch (otyp) { case EGG: if (petrifier && !Stone_resistance - && !(poly_when_stoned(u.umonst->data) + && !(poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM))) { /* egg ends up "all over your face"; perhaps visored helmet should still save you here */ @@ -1344,13 +1344,13 @@ toss_up(struct obj *obj, boolean hitsroof) less_damage = (hard_helmet(uarmh) && (!is_silver || !Hate_silver)), harmless = (stone_missile(obj) - && passes_rocks(u.umonst->data)), + && passes_rocks(gy.youmonst.data)), artimsg = FALSE; - int dmg = dmgval(obj, u.umonst); + int dmg = dmgval(obj, &gy.youmonst); if (obj->oartifact && !harmless) /* need a fake die roll here; rn1(18,2) avoids 1 and 20 */ - artimsg = artifact_hit((struct monst *) 0, u.umonst, obj, + artimsg = artifact_hit((struct monst *) 0, &gy.youmonst, obj, &dmg, rn1(18, 2)); if (!dmg) { /* probably wasn't a weapon; base damage on weight */ @@ -1364,9 +1364,9 @@ toss_up(struct obj *obj, boolean hitsroof) dmgval()'s artifact light against gremlin or axe against woody creature since both involve weapons; hero-as-shade is hypothetical because hero can't polymorph into that form */ - if (u.umonst->data == &mons[PM_SHADE] && !is_silver) + if (gy.youmonst.data == &mons[PM_SHADE] && !is_silver) dmg = 0; - if (obj->blessed && mon_hates_blessings(u.umonst)) + if (obj->blessed && mon_hates_blessings(&gy.youmonst)) dmg += rnd(4); if (is_silver && Hate_silver) dmg += rnd(20); @@ -1399,7 +1399,7 @@ toss_up(struct obj *obj, boolean hitsroof) harmless, but hitting a worn helmet negates that */ harmless = FALSE; } else if (petrifier && !Stone_resistance - && !(poly_when_stoned(u.umonst->data) + && !(poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM))) { petrify: svk.killer.format = KILLED_BY; @@ -1415,7 +1415,7 @@ toss_up(struct obj *obj, boolean hitsroof) if (is_silver && Hate_silver) pline_The("silver sears you!"); if (harmless) - hit(thesimpleoname(obj), u.umonst, " but doesn't hurt."); + hit(thesimpleoname(obj), &gy.youmonst, " but doesn't hurt."); hitfloor(obj, TRUE); gt.thrownobj = 0; @@ -1603,7 +1603,7 @@ throwit( hurtle(-u.dx, -u.dy, 1, TRUE); mon = boomhit(obj, u.dx, u.dy); iflags.returning_missile = 0; /* has returned or isn't going to */ - if (mon == u.umonst) { /* the thing was caught */ + if (mon == &gy.youmonst) { /* the thing was caught */ exercise(A_DEX, TRUE); obj = return_throw_to_inv(obj, wep_mask, twoweap, oldslot); throwit_return(TRUE); @@ -1743,7 +1743,7 @@ throwit( body_part(ARM)); if (obj->oartifact) (void) artifact_hit((struct monst *) 0, - u.umonst, obj, &dmg, 0); + &gy.youmonst, obj, &dmg, 0); losehp(Maybe_Half_Phys(dmg), killer_xname(obj), KILLED_BY); } @@ -2034,7 +2034,7 @@ thitmonst( * Distance and monster size affect chance to hit. */ tmp = -1 + Luck + find_mac(mon) + u.uhitinc - + maybe_polyd(u.umonst->data->mlevel, u.ulevel); + + maybe_polyd(gy.youmonst.data->mlevel, u.ulevel); if (ACURR(A_DEX) < 4) tmp -= 3; else if (ACURR(A_DEX) < 6) @@ -2073,7 +2073,7 @@ thitmonst( tmp += omon_adj(mon, obj, TRUE); if (is_orc(mon->data) - && maybe_polyd(is_elf(u.umonst->data), Race_if(PM_ELF))) + && maybe_polyd(is_elf(gy.youmonst.data), Race_if(PM_ELF))) tmp++; if (guaranteed_hit) { tmp += 1000; /* Guaranteed hit */ @@ -2170,7 +2170,7 @@ thitmonst( * Polymorphing won't make you a bow expert. */ if ((Race_if(PM_ELF) || Role_if(PM_SAMURAI)) - && (!Upolyd || your_race(u.umonst->data)) + && (!Upolyd || your_race(gy.youmonst.data)) && objects[uwep->otyp].oc_skill == P_BOW) { ++tmp; if ((Race_if(PM_ELF) && uwep->otyp == ELVEN_BOW) @@ -2500,16 +2500,16 @@ breakobj( if (obj->otyp == POT_OIL && obj->lamplit) { explode_oil(obj, x, y); } else if (next2u(x, y)) { - if (!breathless(u.umonst->data) || haseyes(u.umonst->data)) { + if (!breathless(gy.youmonst.data) || haseyes(gy.youmonst.data)) { /* wet towel protects both eyes and breathing */ if (obj->otyp != POT_WATER && !Half_gas_damage) { - if (!breathless(u.umonst->data)) { + if (!breathless(gy.youmonst.data)) { /* [what about "familiar odor" when known?] */ You("smell a peculiar odor..."); } else { const char *eyes = body_part(EYE); - if (eyecount(u.umonst->data) != 1) + if (eyecount(gy.youmonst.data) != 1) eyes = makeplural(eyes); Your("%s %s.", eyes, vtense(eyes, "water")); } diff --git a/src/eat.c b/src/eat.c index 9a93b212f..f23ea50e9 100644 --- a/src/eat.c +++ b/src/eat.c @@ -97,12 +97,12 @@ is_edible(struct obj *obj) /* above also prevents the Amulet from being eaten, so we must never allow fake amulets to be eaten either [which is already the case] */ - if (u.umonst->data == &mons[PM_FIRE_ELEMENTAL] + if (gy.youmonst.data == &mons[PM_FIRE_ELEMENTAL] && is_flammable(obj)) return TRUE; - if (metallivorous(u.umonst->data) && is_metallic(obj) - && (u.umonst->data != &mons[PM_RUST_MONSTER] || is_rustprone(obj))) + if (metallivorous(gy.youmonst.data) && is_metallic(obj) + && (gy.youmonst.data != &mons[PM_RUST_MONSTER] || is_rustprone(obj))) return TRUE; /* Ghouls only eat non-veggy corpses or eggs (see dogfood()) */ @@ -170,7 +170,7 @@ eatmdone(void) } /* update display */ if (U_AP_TYPE) { - u.umonst->m_ap_type = M_AP_NOTHING; + gy.youmonst.m_ap_type = M_AP_NOTHING; newsym(u.ux, u.uy); } return 0; @@ -186,11 +186,11 @@ eatmupdate(void) if (!ge.eatmbuf || gn.nomovemsg != ge.eatmbuf) return; - if (is_obj_mappear(u.umonst,ORANGE) && !Hallucination) { + if (is_obj_mappear(&gy.youmonst,ORANGE) && !Hallucination) { /* revert from hallucinatory to "normal" mimicking */ altmsg = "You now prefer mimicking yourself."; altapp = GOLD_PIECE; - } else if (is_obj_mappear(u.umonst,GOLD_PIECE) && Hallucination) { + } else if (is_obj_mappear(&gy.youmonst,GOLD_PIECE) && Hallucination) { /* won't happen; anything which might make immobilized hero begin hallucinating (black light attack, theft of Grayswandir) will terminate the mimicry first */ @@ -207,7 +207,7 @@ eatmupdate(void) } gn.nomovemsg = strcpy(ge.eatmbuf, altmsg); /* update current image */ - u.umonst->mappearance = altapp; + gy.youmonst.mappearance = altapp; newsym(u.ux, u.uy); } } @@ -343,12 +343,12 @@ adj_victual_nutrition(void) assert(nut > 0); if (otyp == LEMBAS_WAFER) { - if (maybe_polyd(is_elf(u.umonst->data), Race_if(PM_ELF))) + if (maybe_polyd(is_elf(gy.youmonst.data), Race_if(PM_ELF))) nut += (nut + 2) / 4; /* 800 -> 1000 */ - else if (maybe_polyd(is_orc(u.umonst->data), Race_if(PM_ORC))) + else if (maybe_polyd(is_orc(gy.youmonst.data), Race_if(PM_ORC))) nut -= (nut + 2) / 4; /* 800 -> 600 */ } else if (otyp == CRAM_RATION) { - if (maybe_polyd(is_dwarf(u.umonst->data), Race_if(PM_DWARF))) + if (maybe_polyd(is_dwarf(gy.youmonst.data), Race_if(PM_DWARF))) nut += (nut + 3) / 6; /* 600 -> 700 */ } nut = max(nut, 1); @@ -554,7 +554,7 @@ done_eating(boolean message) gn.nomovemsg = 0; } else if (message) { You("finish %s %s.", - (u.umonst->data == &mons[PM_FIRE_ELEMENTAL]) ? "consuming" + (gy.youmonst.data == &mons[PM_FIRE_ELEMENTAL]) ? "consuming" : "eating", food_xname(piece, TRUE)); } @@ -612,18 +612,18 @@ eat_brains( /* previous tentacle attack might have triggered fatal passive counterattack [callers ought to be updated to avoid this situation] */ - if (magr != u.umonst && DEADMONSTER(magr)) { + if (magr != &gy.youmonst && DEADMONSTER(magr)) { return M_ATTK_AGR_DIED; } if (noncorporeal(pd)) { if (visflag) pline("%s brain is unharmed.", - (mdef == u.umonst) ? "Your" : s_suffix(Monnam(mdef))); + (mdef == &gy.youmonst) ? "Your" : s_suffix(Monnam(mdef))); return M_ATTK_MISS; /* side-effects can't occur */ - } else if (magr == u.umonst) { + } else if (magr == &gy.youmonst) { You("eat %s brain!", s_suffix(mon_nam(mdef))); - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { Your("brain is eaten!"); } else { /* monster against monster */ if (visflag && canspotmon(mdef)) @@ -634,7 +634,7 @@ eat_brains( /* mind flayer has attempted to eat the brains of a petrification inducing critter (most likely Medusa; attacking a cockatrice via tentacle-touch should have been caught before reaching this far) */ - if (magr == u.umonst) { + if (magr == &gy.youmonst) { if (!Stone_resistance && !Stoned) make_stoned(5L, (char *) 0, KILLED_BY_AN, pmname(pd, Mgender(mdef))); @@ -656,7 +656,7 @@ eat_brains( } } - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* * player mind flayer is eating something's brain */ @@ -690,7 +690,7 @@ eat_brains( is cannibalism */ (void) maybe_cannibal(monsndx(pd), TRUE); - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* * monster mind flayer is eating hero's brain */ @@ -773,7 +773,7 @@ maybe_cannibal(int pm, boolean allowmsg) (even if having the form of something which doesn't care about cannibalism--hero's innate traits aren't altered) */ && (your_race(fptr) - || (Upolyd && same_race(u.umonst->data, fptr)) + || (Upolyd && same_race(gy.youmonst.data, fptr)) || (ismnum(u.ulycn) && were_beastie(pm) == u.ulycn))) { if (allowmsg) { if (Upolyd && your_race(fptr)) @@ -793,7 +793,7 @@ cprefx(int pm) (void) maybe_cannibal(pm, TRUE); if (flesh_petrifies(&mons[pm])) { if (!Stone_resistance - && !(poly_when_stoned(u.umonst->data) + && !(poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM))) { /* if food was a tin, use it up early to keep it out of bones */ if (svc.context.tin.tin) @@ -849,7 +849,7 @@ cprefx(int pm) return; } case PM_GREEN_SLIME: - if (!Slimed && !Unchanging && !slimeproof(u.umonst->data)) { + if (!Slimed && !Unchanging && !slimeproof(gy.youmonst.data)) { You("don't feel very well."); make_slimed(10L, (char *) 0); delayed_killer(SLIMED, KILLED_BY_AN, ""); @@ -1191,7 +1191,7 @@ cpostfx(int pm) /*FALLTHRU*/ case PM_SMALL_MIMIC: tmp += 20; - if (u.umonst->data->mlet != S_MIMIC && !Unchanging) { + if (gy.youmonst.data->mlet != S_MIMIC && !Unchanging) { char buf[BUFSZ]; const char *tempshape = !Hallucination ? "a pile of gold" : "an orange"; @@ -1210,14 +1210,14 @@ cpostfx(int pm) Hallucination ? "You suddenly dread being peeled and mimic %s again!" : "You now prefer mimicking %s again.", - an(Upolyd ? pmname(u.umonst->data, Ugender) + an(Upolyd ? pmname(gy.youmonst.data, Ugender) : gu.urace.noun)); ge.eatmbuf = dupstr(buf); gn.nomovemsg = ge.eatmbuf; ga.afternmv = eatmdone; /* ??? what if this was set before? */ - u.umonst->m_ap_type = M_AP_OBJECT; - u.umonst->mappearance = Hallucination ? ORANGE : GOLD_PIECE; + gy.youmonst.m_ap_type = M_AP_OBJECT; + gy.youmonst.mappearance = Hallucination ? ORANGE : GOLD_PIECE; newsym(u.ux, u.uy); curs_on_u(); /* make gold symbol show up now */ @@ -1253,7 +1253,7 @@ cpostfx(int pm) if (svc.context.tin.tin) { use_up_tin(svc.context.tin.tin); /* most tin effects end up being skipped */ - lesshungry(200 + (metallivorous(u.umonst->data) ? 5 : 0)); + lesshungry(200 + (metallivorous(gy.youmonst.data) ? 5 : 0)); } You("%s.", (pm == PM_GENETIC_ENGINEER) @@ -1530,7 +1530,7 @@ consume_tin(const char *mesg) const char *what; int which, mnum, r, nutamt; /* if you've eaten tin itself, chance to not eat contents gets bypassed */ - boolean always_eat = metallivorous(u.umonst->data); + boolean always_eat = metallivorous(gy.youmonst.data); struct obj *tin = svc.context.tin.tin; r = tin_variety(tin, FALSE); @@ -1725,10 +1725,10 @@ start_tin(struct obj *otmp) const char *mesg = 0; int tmp; - if (metallivorous(u.umonst->data)) { + if (metallivorous(gy.youmonst.data)) { mesg = "You bite right into the metal tin..."; tmp = 0; - } else if (cantwield(u.umonst->data)) { /* nohands || verysmall */ + } else if (cantwield(gy.youmonst.data)) { /* nohands || verysmall */ You("cannot handle the tin properly to open it."); return; } else if (otmp->blessed) { @@ -1859,12 +1859,12 @@ eatcorpse(struct obj *otmp) int ll_conduct = 0; boolean stoneable, slimeable = (mnum == PM_GREEN_SLIME && !Slimed && !Unchanging - && !slimeproof(u.umonst->data)), + && !slimeproof(gy.youmonst.data)), glob = otmp->globby ? TRUE : FALSE; assert(ismnum(mnum)); stoneable = (flesh_petrifies(&mons[mnum]) && !Stone_resistance - && !poly_when_stoned(u.umonst->data)); + && !poly_when_stoned(gy.youmonst.data)); /* KMH, conduct */ if (!vegan(&mons[mnum])) @@ -1978,13 +1978,13 @@ eatcorpse(struct obj *otmp) } else { /* yummy is always False for omnivores, palatable always True */ boolean yummy = (vegan(&mons[mnum]) - ? (!carnivorous(u.umonst->data) - && herbivorous(u.umonst->data)) - : (carnivorous(u.umonst->data) - && !herbivorous(u.umonst->data))), + ? (!carnivorous(gy.youmonst.data) + && herbivorous(gy.youmonst.data)) + : (carnivorous(gy.youmonst.data) + && !herbivorous(gy.youmonst.data))), palatable = ((vegetarian(&mons[mnum]) - ? herbivorous(u.umonst->data) - : carnivorous(u.umonst->data)) + ? herbivorous(gy.youmonst.data) + : carnivorous(gy.youmonst.data)) && rn2(10) && (rotted < 1 || !rn2((int) rotted + 1))); const char *pmxnam = food_xname(otmp, FALSE); @@ -2129,9 +2129,9 @@ fprefx(struct obj *otmp) /* [satiation message may be inaccurate if eating gets interrupted] */ break; case TRIPE_RATION: - if (carnivorous(u.umonst->data) && !humanoid(u.umonst->data)) { + if (carnivorous(gy.youmonst.data) && !humanoid(gy.youmonst.data)) { pline("This tripe ration is surprisingly good!"); - } else if (maybe_polyd(is_orc(u.umonst->data), Race_if(PM_ORC))) { + } else if (maybe_polyd(is_orc(gy.youmonst.data), Race_if(PM_ORC))) { pline(Hallucination ? "Tastes great! Less filling!" : "Mmm, tripe... not bad!"); } else { @@ -2146,10 +2146,10 @@ fprefx(struct obj *otmp) } break; case LEMBAS_WAFER: - if (maybe_polyd(is_orc(u.umonst->data), Race_if(PM_ORC))) { + if (maybe_polyd(is_orc(gy.youmonst.data), Race_if(PM_ORC))) { pline("%s", "!#?&* elf kibble!"); break; - } else if (maybe_polyd(is_elf(u.umonst->data), Race_if(PM_ELF))) { + } else if (maybe_polyd(is_elf(gy.youmonst.data), Race_if(PM_ELF))) { pline("A little goes a long way."); break; } @@ -2160,7 +2160,7 @@ fprefx(struct obj *otmp) case MEAT_RING: goto give_feedback; case CLOVE_OF_GARLIC: - if (is_undead(u.umonst->data)) { + if (is_undead(gy.youmonst.data)) { make_vomiting((long) rn1(svc.context.victual.reqtime, 5), FALSE); break; } @@ -2293,7 +2293,7 @@ eataccessory(struct obj *otmp) set_mimic_blocking(); see_monsters(); if (Invis && !oldprop && !ESee_invisible - && !perceives(u.umonst->data) && !Blind) { + && !perceives(gy.youmonst.data) && !Blind) { newsym(u.ux, u.uy); pline("Suddenly you can see yourself."); makeknown(typ); @@ -2511,7 +2511,7 @@ fpostfx(struct obj *otmp) { switch (otmp->otyp) { case SPRIG_OF_WOLFSBANE: - if (ismnum(u.ulycn) || is_were(u.umonst->data)) + if (ismnum(u.ulycn) || is_were(gy.youmonst.data)) you_unwere(TRUE); break; case CARROT: @@ -2527,7 +2527,7 @@ fpostfx(struct obj *otmp) "became literate by reading the fortune inside a cookie"); break; case LUMP_OF_ROYAL_JELLY: - if (u.umonst->data == &mons[PM_KILLER_BEE] && !Unchanging + if (gy.youmonst.data == &mons[PM_KILLER_BEE] && !Unchanging && polymon(PM_QUEEN_BEE)) break; @@ -2561,7 +2561,7 @@ fpostfx(struct obj *otmp) if (ismnum(otmp->corpsenm) && flesh_petrifies(&mons[otmp->corpsenm])) { if (!Stone_resistance - && !(poly_when_stoned(u.umonst->data) + && !(poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM))) { if (!Stoned) { Sprintf(svk.killer.name, "%s egg", @@ -2646,10 +2646,10 @@ edibility_prompts(struct obj *otmp) stoneorslime = (ismnum(mnum) && flesh_petrifies(&mons[mnum]) && !Stone_resistance - && !poly_when_stoned(u.umonst->data)); + && !poly_when_stoned(gy.youmonst.data)); if (mnum == PM_GREEN_SLIME || otmp->otyp == GLOB_OF_GREEN_SLIME) - stoneorslime = (!Unchanging && !slimeproof(u.umonst->data)); + stoneorslime = (!Unchanging && !slimeproof(gy.youmonst.data)); if (cadaver && !nonrotting_corpse(mnum)) { long age = peek_at_iced_corpse_age(otmp); @@ -2870,7 +2870,7 @@ doeat(void) You_cant("eat %s you're wearing.", something); return ECMD_OK; } else if (!(carried(otmp) ? retouch_object(&otmp, FALSE) - : touch_artifact(otmp, u.umonst))) { + : touch_artifact(otmp, &gy.youmonst))) { return ECMD_TIME; /* got blasted so use a turn */ } if (is_metallic(otmp) && u.umonnum == PM_RUST_MONSTER @@ -3172,9 +3172,9 @@ gethungry(void) will need to wear an Amulet of Unchanging so still burn a small amount of nutrition in the 'moves % 20' ring/amulet check below */ if ((!Unaware || !rn2(10)) /* slow metabolic rate while asleep */ - && (carnivorous(u.umonst->data) - || herbivorous(u.umonst->data) - || metallivorous(u.umonst->data)) + && (carnivorous(gy.youmonst.data) + || herbivorous(gy.youmonst.data) + || metallivorous(gy.youmonst.data)) && !Slow_digestion) u.uhunger--; /* ordinary food consumption */ @@ -3583,7 +3583,7 @@ floorfood( struct obj *otmp; char qbuf[QBUFSZ]; char c; - struct permonst *uptr = u.umonst->data; + struct permonst *uptr = gy.youmonst.data; boolean feeding = !strcmp(verb, "eat"), /* corpsecheck==0 */ offering = !strcmp(verb, "sacrifice"); /* corpsecheck==1 */ @@ -3737,7 +3737,7 @@ vomit(void) /* A good idea from David Neves */ { boolean spewed = FALSE; - if (cantvomit(u.umonst->data)) { + if (cantvomit(gy.youmonst.data)) { /* doesn't cure food poisoning; message assumes that we aren't dealing with some esoteric body_part() */ Your("jaw gapes convulsively."); @@ -3764,7 +3764,7 @@ vomit(void) /* A good idea from David Neves */ if (spewed) { struct attack - *mattk = attacktype_fordmg(u.umonst->data, AT_BREA, AD_ACID); + *mattk = attacktype_fordmg(gy.youmonst.data, AT_BREA, AD_ACID); /* currently, only yellow dragons can breathe acid */ if (mattk) { @@ -3775,7 +3775,7 @@ vomit(void) /* A good idea from David Neves */ if (IS_ALTAR(levl[u.ux][u.uy].typ)) altar_wrath(u.ux, u.uy); /* if poly'd into acidic form, stomach acid is stronger than normal */ - if (acidic(u.umonst->data)) { + if (acidic(gy.youmonst.data)) { /* TODO: if there's a web here, destroy that too (before ice) */ if (is_ice(u.ux, u.uy)) melt_ice(u.ux, u.uy, diff --git a/src/end.c b/src/end.c index c567fd716..e66a53fc3 100644 --- a/src/end.c +++ b/src/end.c @@ -747,7 +747,7 @@ savelife(int how) /* might drop hero onto a trap that kills her all over again */ expels(u.ustuck, u.ustuck->data, TRUE); } else if (u.ustuck) { - if (Upolyd && sticks(u.umonst->data)) + if (Upolyd && sticks(gy.youmonst.data)) You("release %s.", mon_nam(u.ustuck)); else pline("%s releases you.", Monnam(u.ustuck)); diff --git a/src/engrave.c b/src/engrave.c index 9768b00b6..22ca30aaf 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -189,7 +189,7 @@ can_reach_floor(boolean check_pit) struct trap *t; if (u.uswallow - || (u.ustuck && !sticks(u.umonst->data) + || (u.ustuck && !sticks(gy.youmonst.data) /* assume that arms are pinned rather than that the hero has been lifted up above the floor [doesn't explain how hero can attack the creature holding him or her; @@ -200,10 +200,10 @@ can_reach_floor(boolean check_pit) /* Restricted/unskilled riders can't reach the floor */ if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) return FALSE; - if (u.uundetected && ceiling_hider(u.umonst->data)) + if (u.uundetected && ceiling_hider(gy.youmonst.data)) return FALSE; - if (Flying || u.umonst->data->msize >= MZ_HUGE) + if (Flying || gy.youmonst.data->msize >= MZ_HUGE) return TRUE; if (check_pit && (t = t_at(u.ux, u.uy)) != 0 @@ -531,7 +531,7 @@ u_can_engrave(void) return FALSE; } - if (cantwield(u.umonst->data)) { + if (cantwield(gy.youmonst.data)) { You_cant("even hold anything!"); return FALSE; } @@ -570,7 +570,7 @@ doengrave_ctx_init(struct _doengrave_ctx *de) if (de->oep) de->oetype = de->oep->engr_type; - if (is_demon(u.umonst->data) || is_vampire(u.umonst->data)) + if (is_demon(gy.youmonst.data) || is_vampire(gy.youmonst.data)) de->type = ENGR_BLOOD; de->jello = (u.uswallow && !(is_animal(u.ustuck->data) @@ -1245,7 +1245,7 @@ doengrave(void) if (de->post_engr_text[0]) pline("%s", de->post_engr_text); - if (de->doblind && !resists_blnd(u.umonst)) { + if (de->doblind && !resists_blnd(&gy.youmonst)) { You("are blinded by the flash!"); make_blinded((long) rnd(50), FALSE); if (!Blind) diff --git a/src/exper.c b/src/exper.c index 14312e691..aee851126 100644 --- a/src/exper.c +++ b/src/exper.c @@ -213,7 +213,7 @@ losexp( wizard mode request to reduce level; never fatal though */ if (drainer && !strcmp(drainer, "#levelchange")) drainer = 0; - else if (resists_drli(u.umonst)) + else if (resists_drli(&gy.youmonst)) return; /* level-loss message; "Goodbye level 1." is fatal; divine anger @@ -280,7 +280,7 @@ losexp( u.uexp = newuexp(u.ulevel) - 1; if (Upolyd) { - num = monhp_per_lvl(u.umonst); + num = monhp_per_lvl(&gy.youmonst); u.mhmax -= num; u.mh -= num; if (u.mh <= 0) @@ -317,7 +317,7 @@ pluslvl( /* increase hit points (when polymorphed, do monster form first in order to retain normal human/whatever increase for later) */ if (Upolyd) { - hpinc = monhp_per_lvl(u.umonst); + hpinc = monhp_per_lvl(&gy.youmonst); u.mh += hpinc; setuhpmax(u.mhmax, FALSE); /* acts as setmhmax() when Upolyd */ } diff --git a/src/explode.c b/src/explode.c index 41ef8a4df..70f4c8307 100644 --- a/src/explode.c +++ b/src/explode.c @@ -24,13 +24,13 @@ enum explode_action { /* check if shield effects are needed for location affected by explosion */ staticfn int explosionmask( - struct monst *m, /* target monster (might be u.umonst) */ + struct monst *m, /* target monster (might be youmonst) */ uchar adtyp, /* damage type */ char olet) /* object class (only matters for AD_DISN) */ { int res = EXPL_NONE; - if (m == u.umonst) { + if (m == &gy.youmonst) { switch (adtyp) { case AD_PHYS: /* leave 'res' with EXPL_NONE */ @@ -274,7 +274,7 @@ explode( so might get hit by double damage */ grabbed = grabbing = FALSE; if (u.ustuck && !u.uswallow) { - if (Upolyd && sticks(u.umonst->data)) + if (Upolyd && sticks(gy.youmonst.data)) grabbing = TRUE; else grabbed = TRUE; @@ -363,7 +363,7 @@ explode( explmask[i][j] = EXPL_NONE; if (u_at(xx, yy)) { - explmask[i][j] = explosionmask(u.umonst, adtyp, olet); + explmask[i][j] = explosionmask(&gy.youmonst, adtyp, olet); } /* can be both you and mtmp if you're swallowed or riding */ mtmp = m_at(xx, yy); @@ -611,10 +611,10 @@ explode( } else if (adtyp == AD_PHYS || adtyp == AD_ACID) damu = Maybe_Half_Phys(damu); if (adtyp == AD_FIRE) { - (void) burnarmor(u.umonst); + (void) burnarmor(&gy.youmonst); ignite_items(gi.invent); } - (void) destroy_items(u.umonst, (int) adtyp, dam); + (void) destroy_items(&gy.youmonst, (int) adtyp, dam); ugolemeffects((int) adtyp, damu); if (uhurt == 2) { @@ -869,9 +869,9 @@ scatter( if (gm.multi) nomul(0); - dam = dmgval(stmp->obj, u.umonst); + dam = dmgval(stmp->obj, &gy.youmonst); hitvalu = 8 + stmp->obj->spe; - if (bigmonst(u.umonst->data)) + if (bigmonst(gy.youmonst.data)) hitvalu++; hitu = thitu(hitvalu, Maybe_Half_Phys(dam), &stmp->obj, (char *) 0); @@ -936,8 +936,8 @@ scatter( newsym(x, y); } newsym(sx, sy); - if (u_at(sx, sy) && u.uundetected && hides_under(u.umonst->data)) - (void) hideunder(u.umonst); + if (u_at(sx, sy) && u.uundetected && hides_under(gy.youmonst.data)) + (void) hideunder(&gy.youmonst); if (((mtmp = m_at(sx, sy)) != 0) && mtmp->mtrapped) mtmp->mtrapped = 0; maybe_unhide_at(sx, sy); diff --git a/src/fountain.c b/src/fountain.c index aeef118bb..78925b04c 100644 --- a/src/fountain.c +++ b/src/fountain.c @@ -791,7 +791,7 @@ dipsink(struct obj *obj) breathless for this message */ pline("A wisp of vapor rises up..."); /* NB: potionbreathe calls trycall or makeknown as appropriate */ - if (!breathless(u.umonst->data) || haseyes(u.umonst->data)) + if (!breathless(gy.youmonst.data) || haseyes(gy.youmonst.data)) potionbreathe(obj); break; } diff --git a/src/hack.c b/src/hack.c index 4e5ff410b..367591eff 100644 --- a/src/hack.c +++ b/src/hack.c @@ -152,11 +152,11 @@ could_move_onto_boulder(coordxy sx, coordxy sy) return FALSE; /* can if a giant, unless doing so allows hero to pass into a diagonal squeeze at the same time */ - if (throws_rocks(u.umonst->data)) + if (throws_rocks(gy.youmonst.data)) return (!u.dx || !u.dy || !(IS_OBSTRUCTED(levl[u.ux][sy].typ) && IS_OBSTRUCTED(levl[sx][u.uy].typ))); /* can if tiny (implies carrying very little else couldn't move at all) */ - if (verysmall(u.umonst->data)) + if (verysmall(gy.youmonst.data)) return TRUE; /* can squeeze to spot if carrying extremely little, otherwise can't */ return squeezeablylightinvent(); @@ -189,7 +189,7 @@ dopush( || svm.moves < gb.bldrpushtime); what = givemesg ? the(xname(otmp)) : 0; if (!u.usteed) { - easypush = throws_rocks(u.umonst->data); + easypush = throws_rocks(gy.youmonst.data); if (givemesg) pline("With %s effort you move %s.", easypush ? "little" : "great", what); @@ -261,7 +261,7 @@ cannot_push_msg(struct obj *otmp, coordxy sx, coordxy sy) staticfn int cannot_push(struct obj *otmp, coordxy sx, coordxy sy) { - if (throws_rocks(u.umonst->data)) { + if (throws_rocks(gy.youmonst.data)) { boolean canpickup = (!Sokoban /* similar exception as in can_lift(): @@ -388,7 +388,7 @@ moverock_core(coordxy sx, coordxy sy) int res; feel_location(sx, sy); /* same for all 3 if/else-if/else cases */ - if (throws_rocks(u.umonst->data)) { + if (throws_rocks(gy.youmonst.data)) { /* player has used 'm' to move, so step to boulder's spot without pushing it; hero is poly'd into a giant, so exotic forms of locomotion are out, but might be @@ -423,7 +423,7 @@ moverock_core(coordxy sx, coordxy sy) /* Give them a chance to climb over it? */ return -1; } - if (verysmall(u.umonst->data) && !u.usteed) { + if (verysmall(gy.youmonst.data) && !u.usteed) { if (Blind) feel_location(sx, sy); pline("You're too small to push that %s.", xname(otmp)); @@ -667,7 +667,7 @@ still_chewing(coordxy x, coordxy y) nomul(0); return 1; } else if (lev->typ == IRONBARS - && metallivorous(u.umonst->data) && u.uhunger > 1500) { + && metallivorous(gy.youmonst.data) && u.uhunger > 1500) { /* finishing eating via 'morehungry()' doesn't handle choking */ You("are too full to eat the bars."); nomul(0); @@ -767,7 +767,7 @@ still_chewing(coordxy x, coordxy y) digtxt = "chew through the tree."; lev->typ = ROOM; } else if (lev->typ == IRONBARS) { - if (metallivorous(u.umonst->data)) { /* should always be True here */ + if (metallivorous(gy.youmonst.data)) { /* should always be True here */ /* arbitrary amount; unlike proper eating, nutrition is bestowed in a lump sum at the end */ int nut = (int) objects[HEAVY_IRON_BALL].oc_weight; @@ -955,7 +955,7 @@ cant_squeeze_thru(struct monst *mon) int amt; struct permonst *ptr = mon->data; - if ((mon == u.umonst) ? Passes_walls : passes_walls(ptr)) + if ((mon == &gy.youmonst) ? Passes_walls : passes_walls(ptr)) return 0; /* too big? */ @@ -965,13 +965,13 @@ cant_squeeze_thru(struct monst *mon) return 1; /* lugging too much junk? */ - amt = (mon == u.umonst) ? inv_weight() + weight_cap() + amt = (mon == &gy.youmonst) ? inv_weight() + weight_cap() : curr_mon_load(mon); if (amt > WT_TOOMUCH_DIAGONAL) return 2; /* Sokoban restriction applies to hero only */ - if (mon == u.umonst && Sokoban) + if (mon == &gy.youmonst && Sokoban) return 3; /* can squeeze through */ @@ -1023,19 +1023,19 @@ test_move( return FALSE; } else if (tmpr->typ == IRONBARS) { if (mode == DO_MOVE - && (dmgtype(u.umonst->data, AD_RUST) - || dmgtype(u.umonst->data, AD_CORR) - || metallivorous(u.umonst->data)) + && (dmgtype(gy.youmonst.data, AD_RUST) + || dmgtype(gy.youmonst.data, AD_CORR) + || metallivorous(gy.youmonst.data)) && still_chewing(x, y)) { return FALSE; } - if (!(Passes_walls || passes_bars(u.umonst->data))) { + if (!(Passes_walls || passes_bars(gy.youmonst.data))) { if (mode == DO_MOVE && flags.mention_walls) You("cannot pass through the bars."); return FALSE; } - } else if (tunnels(u.umonst->data) - && !needspick(u.umonst->data)) { + } else if (tunnels(gy.youmonst.data) + && !needspick(gy.youmonst.data)) { /* Eat the rock. */ if (mode == DO_MOVE && still_chewing(x, y)) return FALSE; @@ -1077,21 +1077,21 @@ test_move( feel_location(x, y); if (Passes_walls) { ; /* do nothing */ - } else if (can_ooze(u.umonst)) { + } else if (can_ooze(&gy.youmonst)) { if (mode == DO_MOVE) You("ooze under the door."); } else if (Underwater) { if (mode == DO_MOVE) pline("There is an obstacle there."); return FALSE; - } else if (tunnels(u.umonst->data) - && !needspick(u.umonst->data)) { + } else if (tunnels(gy.youmonst.data) + && !needspick(gy.youmonst.data)) { /* Eat the door. */ if (mode == DO_MOVE && still_chewing(x, y)) return FALSE; } else { if (mode == DO_MOVE) { - if (amorphous(u.umonst->data)) + if (amorphous(gy.youmonst.data)) You("try to ooze under the door," " but can't squeeze your possessions through."); if (flags.autoopen && !svc.context.run @@ -1150,10 +1150,10 @@ test_move( } } } - if (dx && dy && bad_rock(u.umonst->data, ux, y) - && bad_rock(u.umonst->data, x, uy)) { + if (dx && dy && bad_rock(gy.youmonst.data, ux, y) + && bad_rock(gy.youmonst.data, x, uy)) { /* Move at a diagonal. */ - switch (cant_squeeze_thru(u.umonst)) { + switch (cant_squeeze_thru(&gy.youmonst)) { case 3: if (mode == DO_MOVE) You("cannot pass that way."); @@ -1222,7 +1222,7 @@ test_move( } if (mode == DO_MOVE) { /* tunneling monsters will chew before pushing */ - if (tunnels(u.umonst->data) && !needspick(u.umonst->data) + if (tunnels(gy.youmonst.data) && !needspick(gy.youmonst.data) && !Sokoban) { if (still_chewing(x, y)) return FALSE; @@ -1239,8 +1239,8 @@ test_move( if (sobj_at(BOULDER, ux, uy) && !Sokoban) { if (!Passes_walls && !could_move_onto_boulder(ux, uy) - && !(tunnels(u.umonst->data) - && !needspick(u.umonst->data)) + && !(tunnels(gy.youmonst.data) + && !needspick(gy.youmonst.data)) && !carrying(PICK_AXE) && !carrying(DWARVISH_MATTOCK) && !((obj = carrying(WAN_DIGGING)) && !objects[obj->otyp].oc_name_known)) @@ -1372,7 +1372,7 @@ findtravelpath(int mode) if (!isok(nx, ny) || ((mode == TRAVP_GUESS) && !couldsee(nx, ny))) continue; - if ((!Passes_walls && !can_ooze(u.umonst) + if ((!Passes_walls && !can_ooze(&gy.youmonst) && closed_door(x, y)) || (sobj_at(BOULDER, x, y) && !could_move_onto_boulder(x, y)) @@ -1693,7 +1693,7 @@ trapmove( boolean u_rooted(void) { - if (!u.umonst->data->mmove) { + if (!gy.youmonst.data->mmove) { You("are rooted %s.", Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) ? "in place" @@ -1825,14 +1825,14 @@ u_locomotion(const char *def) or boots/ring/spell of levitation */ return Levitation ? (capitalize ? "Float" : "float") : Flying ? (capitalize ? "Fly" : "fly") - : locomotion(u.umonst->data, def); + : locomotion(gy.youmonst.data, def); } /* Return a simplified floor solid/liquid state based on hero's state */ staticfn schar u_simple_floortyp(coordxy x, coordxy y) { - boolean u_in_air = (Levitation || Flying || !grounded(u.umonst->data)); + boolean u_in_air = (Levitation || Flying || !grounded(gy.youmonst.data)); if (is_waterwall(x, y)) return WATER; /* wall of water, fly/lev does not matter */ @@ -1978,8 +1978,8 @@ domove_attackmon_at( && (NODIAG(u.umonnum) || (bad_rock(mtmp->data, x, u.uy0) && bad_rock(mtmp->data, u.ux0, y)) - || (bad_rock(u.umonst->data, u.ux0, y) - && bad_rock(u.umonst->data, x, u.uy0)))) + || (bad_rock(gy.youmonst.data, u.ux0, y) + && bad_rock(gy.youmonst.data, x, u.uy0)))) && goodpos(u.ux0, u.uy0, mtmp, GP_ALLOW_U)); /* if not displacing, try to attack; note that it might evade; also, we don't attack tame or peaceful when safemon() */ @@ -2244,7 +2244,7 @@ domove_fight_empty(coordxy x, coordxy y) || (glyph_is_invisible(glyph) && !m_at(x, y) && !svc.context.nopick)) { struct obj *boulder = 0; - boolean explo = (Upolyd && attacktype(u.umonst->data, AT_EXPL)), + boolean explo = (Upolyd && attacktype(gy.youmonst.data, AT_EXPL)), solid = (off_edge || (!accessible(x, y) || IS_FURNITURE(levl[x][y].typ))); char buf[BUFSZ]; @@ -2323,7 +2323,7 @@ domove_fight_empty(coordxy x, coordxy y) nomul(0); if (explo) { struct attack *attk - = attacktype_fordmg(u.umonst->data, AT_EXPL, AD_ANY); + = attacktype_fordmg(gy.youmonst.data, AT_EXPL, AD_ANY); /* no monster has been attacked so we have bypassed explum() */ wake_nearto(u.ux, u.uy, 7 * 7); /* same radius as explum() */ @@ -2396,7 +2396,7 @@ staticfn void slippery_ice_fumbling(void) { boolean on_ice = !Levitation && is_ice(u.ux, u.uy); - struct monst *iceskater = u.usteed ? u.usteed : u.umonst; + struct monst *iceskater = u.usteed ? u.usteed : &gy.youmonst; if (on_ice) { if ((uarmf && objdescr_is(uarmf, "snow boots")) @@ -2435,7 +2435,7 @@ impaired_movement(coordxy *x, coordxy *y) confdir(TRUE); *x = u.ux + u.dx; *y = u.uy + u.dy; - } while (!isok(*x, *y) || bad_rock(u.umonst->data, *x, *y)); + } while (!isok(*x, *y) || bad_rock(gy.youmonst.data, *x, *y)); } return FALSE; } @@ -2475,7 +2475,7 @@ avoid_moving_on_liquid( /* and you know you won't fall in */ && (in_air || Known_lwalking || (is_pool(x, y) && Known_wwalking)) && !(IS_WATERWALL(levl[x][y].typ) || levl[x][y].typ == LAVAWALL)) { - /* XXX: should send 'is_clinger(u.umonst->data)' here once clinging + /* XXX: should send 'is_clinger(gy.youmonst.data)' here once clinging polyforms are allowed to move over water */ return FALSE; /* liquid is safe to traverse */ } else if (is_pool_or_lava(x, y) && levl[x][y].seenv) { @@ -2558,7 +2558,7 @@ avoid_trap_andor_region(coordxy x, coordxy y) /* check whether attempted move will be viable */ && test_move(u.ux, u.uy, u.dx, u.dy, TEST_MOVE) /* override confirmation if the trap is harmless to the hero */ - && (immune_to_trap(u.umonst, trap->ttyp) != TRAP_CLEARLY_IMMUNE + && (immune_to_trap(&gy.youmonst, trap->ttyp) != TRAP_CLEARLY_IMMUNE /* Hallucination: all traps still show as ^, but the hero can't tell what they are, so treat as dangerous */ || Hallucination)) { @@ -2644,7 +2644,7 @@ escape_from_sticky_mon(coordxy x, coordxy y) if (!m_next2u(u.ustuck)) { /* perhaps it fled (or was teleported or ... ) */ set_ustuck((struct monst *) 0); - } else if (sticks(u.umonst->data)) { + } else if (sticks(gy.youmonst.data)) { /* When polymorphed into a sticking monster, * u.ustuck means it's stuck to you, not you to it. */ @@ -2874,7 +2874,7 @@ domove_core(void) u.ux += u.dx; u.uy += u.dy; - m_postmove_effect(u.umonst); + m_postmove_effect(&gy.youmonst); if (u.usteed) { u.usteed->mx = u.ux; @@ -2943,12 +2943,12 @@ domove_core(void) /* your tread on the ground may disturb the slumber of nearby zombies */ if (!Levitation && !Flying && !Stealth - && u.umonst->data->cwt >= (WT_ELF / 2)) + && gy.youmonst.data->cwt >= (WT_ELF / 2)) disturb_buried_zombies(u.ux, u.uy); - if (hides_under(u.umonst->data) || u.umonst->data->mlet == S_EEL + if (hides_under(gy.youmonst.data) || gy.youmonst.data->mlet == S_EEL || u.dx || u.dy) - (void) hideunder(u.umonst); + (void) hideunder(&gy.youmonst); /* * Mimics (or whatever) become noticeable if they move and are @@ -2957,7 +2957,7 @@ domove_core(void) */ if ((u.dx || u.dy) && (U_AP_TYPE == M_AP_OBJECT || U_AP_TYPE == M_AP_FURNITURE)) - u.umonst->m_ap_type = M_AP_NOTHING; + gy.youmonst.m_ap_type = M_AP_NOTHING; check_leash(u.ux0, u.uy0); @@ -3804,8 +3804,8 @@ pickup_checks(void) } } if (is_pool(u.ux, u.uy)) { - if (Wwalking || is_floater(u.umonst->data) - || is_clinger(u.umonst->data) || (Flying && !Breathless)) { + if (Wwalking || is_floater(gy.youmonst.data) + || is_clinger(gy.youmonst.data) || (Flying && !Breathless)) { You("cannot dive into the %s to pick things up.", hliquid("water")); return 0; @@ -3815,11 +3815,11 @@ pickup_checks(void) } } if (is_lava(u.ux, u.uy)) { - if (Wwalking || is_floater(u.umonst->data) - || is_clinger(u.umonst->data) || (Flying && !Breathless)) { + if (Wwalking || is_floater(gy.youmonst.data) + || is_clinger(gy.youmonst.data) || (Flying && !Breathless)) { You_cant("reach the bottom to pick things up."); return 0; - } else if (!likes_lava(u.umonst->data)) { + } else if (!likes_lava(gy.youmonst.data)) { You("would burn to a crisp trying to pick things up."); return 0; } @@ -4079,7 +4079,7 @@ boolean crawl_destination(coordxy x, coordxy y) { /* is location ok in general? */ - if (!goodpos(x, y, u.umonst, 0)) + if (!goodpos(x, y, &gy.youmonst, 0)) return FALSE; /* orthogonal movement is unrestricted when destination is ok */ @@ -4095,9 +4095,9 @@ crawl_destination(coordxy x, coordxy y) if (IS_DOOR(levl[x][y].typ) && (!doorless_door(x, y) || block_door(x, y))) return FALSE; /* finally, are we trying to squeeze through a too-narrow gap? */ - return !(bad_rock(u.umonst->data, u.ux, y) - && bad_rock(u.umonst->data, x, u.uy) - && cant_squeeze_thru(u.umonst)); + return !(bad_rock(gy.youmonst.data, u.ux, y) + && bad_rock(gy.youmonst.data, x, u.uy) + && cant_squeeze_thru(&gy.youmonst)); } /* something like lookaround, but we are not running */ @@ -4367,14 +4367,14 @@ weight_cap(void) + WT_WEIGHTCAP_SPARE; if (Upolyd) { /* consistent with can_carry() in mon.c */ - if (u.umonst->data->mlet == S_NYMPH) + if (gy.youmonst.data->mlet == S_NYMPH) carrcap = MAX_CARR_CAP; - else if (!u.umonst->data->cwt) - carrcap = (carrcap * (long) u.umonst->data->msize) / MZ_HUMAN; - else if (!strongmonst(u.umonst->data) - || (strongmonst(u.umonst->data) - && (u.umonst->data->cwt > WT_HUMAN))) - carrcap = (carrcap * (long) u.umonst->data->cwt / WT_HUMAN); + else if (!gy.youmonst.data->cwt) + carrcap = (carrcap * (long) gy.youmonst.data->msize) / MZ_HUMAN; + else if (!strongmonst(gy.youmonst.data) + || (strongmonst(gy.youmonst.data) + && (gy.youmonst.data->cwt > WT_HUMAN))) + carrcap = (carrcap * (long) gy.youmonst.data->cwt / WT_HUMAN); } if (Levitation || Is_airlevel(&u.uz) /* pugh@cornell */ @@ -4411,7 +4411,7 @@ inv_weight(void) while (otmp) { if (otmp->oclass == COIN_CLASS) wt += (int) (((long) otmp->quan + 50L) / 100L); - else if (otmp->otyp != BOULDER || !throws_rocks(u.umonst->data)) + else if (otmp->otyp != BOULDER || !throws_rocks(gy.youmonst.data)) wt += otmp->owt; otmp = otmp->nobj; } diff --git a/src/iactions.c b/src/iactions.c index b12b61c18..ca00a2be6 100644 --- a/src/iactions.c +++ b/src/iactions.c @@ -605,7 +605,7 @@ itemactions(struct obj *otmp) /* w: wield, hold in hands, works on everything but with different advice text; not mentioned for things that are already wielded */ - if (otmp == uwep || cantwield(u.umonst->data)) { + if (otmp == uwep || cantwield(gy.youmonst.data)) { ; /* either already wielded or can't wield anything; skip 'w' */ } else if (otmp->oclass == WEAPON_CLASS || is_weptool(otmp) || is_wet_towel(otmp) || otmp->otyp == HEAVY_IRON_BALL) { @@ -674,7 +674,7 @@ itemactions(struct obj *otmp) /* if already two-weaponing, no special checks needed to toggle off */ && (u.twoweap /* but if not, try to filter most "you can't do that" here */ - || (could_twoweap(u.umonst->data) && !uarms + || (could_twoweap(gy.youmonst.data) && !uarms && uwep && MAYBETWOWEAPON(uwep) && uswapwep && MAYBETWOWEAPON(uswapwep)))) { Sprintf(buf, "Toggle two-weapon combat %s", u.twoweap ? "off" : "on"); diff --git a/src/insight.c b/src/insight.c index 12fc1e773..ab2bcd1a1 100644 --- a/src/insight.c +++ b/src/insight.c @@ -489,8 +489,8 @@ background_enlightenment(int unused_mode UNUSED, int final) the player to know he's not a samurai at the moment... */ if (Upolyd) { char anbuf[20]; /* includes trailing space; [4] suffices */ - struct permonst *uasmon = u.umonst->data; - boolean altphrasing = vampshifted(u.umonst); + struct permonst *uasmon = gy.youmonst.data; + boolean altphrasing = vampshifted(&gy.youmonst); tmpbuf[0] = '\0'; /* here we always use current gender, not saved role gender */ @@ -498,7 +498,7 @@ background_enlightenment(int unused_mode UNUSED, int final) Sprintf(tmpbuf, "%s ", genders[flags.female ? 1 : 0].adj); if (altphrasing) Sprintf(eos(tmpbuf), "%s in ", - pmname(&mons[u.umonst->cham], + pmname(&mons[gy.youmonst.cham], flags.female ? FEMALE : MALE)); Snprintf(buf, sizeof(buf), "%s%s%s%s form", !final ? "currently " : "", @@ -1068,7 +1068,7 @@ status_enlightenment(int mode, int final) if (wizard && (HBlinded == BlindedTimeout && !Blindfolded)) Sprintf(eos(buf), " (%ld)", BlindedTimeout); /* !haseyes: avoid "you are innately blind innately" */ - you_are(buf, !haseyes(u.umonst->data) ? "" : from_what(BLINDED)); + you_are(buf, !haseyes(gy.youmonst.data) ? "" : from_what(BLINDED)); } if (Deaf) you_are("deaf", from_what(DEAF)); @@ -1122,7 +1122,7 @@ status_enlightenment(int mode, int final) Sprintf(eos(buf), " (%u)", u.uswldtim); you_are(buf, ""); } else if (u.ustuck) { - boolean ustick = (Upolyd && sticks(u.umonst->data)); + boolean ustick = (Upolyd && sticks(gy.youmonst.data)); int dx = u.ustuck->mx - u.ux, dy = u.ustuck->my - u.uy; Snprintf(buf, sizeof buf, "%s %s (%s)", @@ -1736,7 +1736,7 @@ attributes_enlightenment( } /* including this might bring attention to the fact that ceiling clinging has inconsistencies... */ - if (is_clinger(u.umonst->data)) { + if (is_clinger(gy.youmonst.data)) { boolean has_lid = has_ceiling(&u.uz); if (has_lid && !u.uinwater) { @@ -1797,7 +1797,7 @@ attributes_enlightenment( if (prot) you_have(enlght_combatinc("defense", prot, final, buf), ""); } - if ((armpro = magic_negation(u.umonst)) > 0) { + if ((armpro = magic_negation(&gy.youmonst)) > 0) { /* magic cancellation factor, conferred by worn armor */ static const char *const mc_types[] = { "" /*ordinary*/, "warded", "guarded", "protected", @@ -1863,20 +1863,20 @@ attributes_enlightenment( && !(final == ENL_GAMEOVERDEAD && u.umonnum == PM_GREEN_SLIME && !Unchanging)) { /* foreign shape (except were-form which is handled below) */ - if (!vampshifted(u.umonst)) + if (!vampshifted(&gy.youmonst)) Sprintf(buf, "polymorphed into %s", - an(pmname(u.umonst->data, + an(pmname(gy.youmonst.data, flags.female ? FEMALE : MALE))); else Sprintf(buf, "polymorphed into %s in %s form", - an(pmname(&mons[u.umonst->cham], + an(pmname(&mons[gy.youmonst.cham], flags.female ? FEMALE : MALE)), - pmname(u.umonst->data, flags.female ? FEMALE : MALE)); + pmname(gy.youmonst.data, flags.female ? FEMALE : MALE)); if (wizard) Sprintf(eos(buf), " (%d)", u.mtimedone); you_are(buf, ""); } - if (lays_eggs(u.umonst->data) && flags.female) /* Upolyd */ + if (lays_eggs(gy.youmonst.data) && flags.female) /* Upolyd */ you_can("lay eggs", ""); if (ismnum(u.ulycn)) { /* "you are a werecreature [in beast form]" */ @@ -2046,7 +2046,7 @@ youhiding(boolean via_enlghtmt, /* enlightenment line vs topl message */ for the hypothetical furniture and monster cases */ bp = eos(strcpy(buf, "mimicking")); if (U_AP_TYPE == M_AP_OBJECT) { - Sprintf(bp, " %s", an(simple_typename(u.umonst->mappearance))); + Sprintf(bp, " %s", an(simple_typename(gy.youmonst.mappearance))); } else if (U_AP_TYPE == M_AP_FURNITURE) { Strcpy(bp, " something"); } else if (U_AP_TYPE == M_AP_MONSTER) { @@ -2056,15 +2056,15 @@ youhiding(boolean via_enlghtmt, /* enlightenment line vs topl message */ } } else if (u.uundetected) { bp = eos(buf); /* points past "hiding" */ - if (u.umonst->data->mlet == S_EEL) { + if (gy.youmonst.data->mlet == S_EEL) { if (is_pool(u.ux, u.uy)) Sprintf(bp, " in the %s", waterbody_name(u.ux, u.uy)); - } else if (hides_under(u.umonst->data)) { + } else if (hides_under(gy.youmonst.data)) { struct obj *o = svl.level.objects[u.ux][u.uy]; if (o) Sprintf(bp, " underneath %s", ansimpleoname(o)); - } else if (is_clinger(u.umonst->data) || Flying) { + } else if (is_clinger(gy.youmonst.data) || Flying) { /* Flying: 'lurker above' hides on ceiling but doesn't cling */ Sprintf(bp, " on the %s", ceiling(u.ux, u.uy)); } else { @@ -3368,7 +3368,7 @@ mstatusline(struct monst *mtmp) if (mtmp == u.ustuck) { struct permonst *pm = u.ustuck->data; - /* being swallowed/engulfed takes priority over sticks(u.umonst); + /* being swallowed/engulfed takes priority over sticks(youmonst); this used to have that backwards and checked sticks() first */ Strcat(info, u.uswallow ? (digests(pm) ? ", digesting you" @@ -3380,9 +3380,9 @@ mstatusline(struct monst *mtmp) : (is_animal(pm) && !enfolds(pm)) ? ", swallowing you" : ", engulfing you") - /* !u.uswallow; if both u.umonst and ustuck are holders, - u.umonst wins */ - : (!sticks(u.umonst->data) ? ", holding you" + /* !u.uswallow; if both youmonst and ustuck are holders, + youmonst wins */ + : (!sticks(gy.youmonst.data) ? ", holding you" : ", held by you")); } if (mtmp == u.usteed) { @@ -3445,7 +3445,7 @@ ustatusline(void) Strcat(info, ", blind"); if (u.ucreamed) { if ((long) u.ucreamed < BlindedTimeout || Blindfolded - || !haseyes(u.umonst->data)) + || !haseyes(gy.youmonst.data)) Strcat(info, ", cover"); Strcat(info, "ed by sticky goop"); } /* note: "goop" == "glop"; variation is intentional */ @@ -3481,7 +3481,7 @@ ustatusline(void) if (u.uswallow) Strcat(info, digests(u.ustuck->data) ? ", being digested by " : ", engulfed by "); - else if (!sticks(u.umonst->data)) + else if (!sticks(gy.youmonst.data)) Strcat(info, ", held by "); else Strcat(info, ", holding "); diff --git a/src/invent.c b/src/invent.c index 6995bfd4e..a34517acf 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1224,7 +1224,7 @@ hold_another_object( /* in case touching this object turns out to be fatal */ place_object(obj, u.ux, u.uy); - if (!touch_artifact(obj, u.umonst)) { + if (!touch_artifact(obj, &gy.youmonst)) { obj_extract_self(obj); /* remove it from the floor */ dropy(obj); /* now put it back again :-) */ return obj; @@ -1496,7 +1496,7 @@ carrying(int type) { struct obj *otmp; - /* this could be replaced by 'return m_carrying(u.umonst, type);' */ + /* this could be replaced by 'return m_carrying(&gy.youmonst, type);' */ for (otmp = gi.invent; otmp; otmp = otmp->nobj) if (otmp->otyp == type) break; @@ -4269,7 +4269,7 @@ look_here( : (otmp->quan > 1L) ? "They're" : "It's", corpse_xname(otmp, (const char *) 0, CXN_ARTICLE), - poly_when_stoned(u.umonst->data) ? "" + poly_when_stoned(gy.youmonst.data) ? "" : ", unfortunately"); feel_cockatrice(otmp, FALSE); break; @@ -4348,7 +4348,7 @@ feel_cockatrice(struct obj *otmp, boolean force_touch) /* "the corpse" */ Strcpy(kbuf, corpse_xname(otmp, (const char *) 0, CXN_PFX_THE)); - if (poly_when_stoned(u.umonst->data)) + if (poly_when_stoned(gy.youmonst.data)) You("touched %s with your bare %s.", kbuf, makeplural(body_part(HAND))); else @@ -4778,8 +4778,8 @@ useupf(struct obj *obj, long numused) (void) stolen_value(otmp, otmp->ox, otmp->oy, FALSE, FALSE); } delobj(otmp); - if (at_u && u.uundetected && hides_under(u.umonst->data)) - (void) hideunder(u.umonst); + if (at_u && u.uundetected && hides_under(gy.youmonst.data)) + (void) hideunder(&gy.youmonst); } /* @@ -5360,7 +5360,7 @@ display_minventory( /* Fool the 'weapon in hand' routine into * displaying 'weapon in claw', etc. properly. */ - u.umonst->data = mon->data; + gy.youmonst.data = mon->data; /* in case inside a shop, don't append "for sale" prices */ iflags.suppress_price++; @@ -5371,7 +5371,7 @@ display_minventory( iflags.suppress_price--; /* was 'set_uasmon();' but that potentially has side-effects */ - u.umonst->data = &mons[u.umonnum]; /* basic part of set_uasmon() */ + gy.youmonst.data = &mons[u.umonnum]; /* basic part of set_uasmon() */ } else { invdisp_nothing(title ? title : tmp, "(none)"); n = 0; diff --git a/src/light.c b/src/light.c index 640ed312a..93f7ea50a 100644 --- a/src/light.c +++ b/src/light.c @@ -13,8 +13,8 @@ * Light sources are "things" that have a physical position and range. * They have a type, which gives us information about them. Currently * they are only attached to objects and monsters. Note well: the - * polymorphed-player handling assumes that u.umonst->m_id will - * always remain 1 and u.umonst->mx will always remain 0. + * polymorphed-player handling assumes that gy.youmonst.m_id will + * always remain 1 and gy.youmonst.mx will always remain 0. * * Light sources, like timers, either follow game play (RANGE_GLOBAL) or * stay on a level (RANGE_LEVEL). Light sources are unique by their @@ -378,7 +378,7 @@ find_mid(unsigned nid, unsigned fmflags) struct monst *mtmp; if ((fmflags & FM_YOU) && nid == 1) - return u.umonst; + return &gy.youmonst; if (fmflags & FM_FMON) for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) if (!DEADMONSTER(mtmp) && mtmp->m_id == nid) @@ -399,7 +399,7 @@ whereis_mon(struct monst *mon, unsigned fmflags) { struct monst *mtmp; - if ((fmflags & FM_YOU) && mon == u.umonst) + if ((fmflags & FM_YOU) && mon == &gy.youmonst) return FM_YOU; if (fmflags & FM_FMON) for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) @@ -957,7 +957,7 @@ wiz_light_sources(void) : ls->type == LS_MONSTER ? (mon_is_local(ls->id.a_monst) ? "mon" - : (ls->id.a_monst == u.umonst) + : (ls->id.a_monst == &gy.youmonst) ? "you" /* migrating monster */ : "") diff --git a/src/lock.c b/src/lock.c index cc3183d00..2e8851754 100644 --- a/src/lock.c +++ b/src/lock.c @@ -89,7 +89,7 @@ picklock(void) } } - if (gx.xlock.usedtime++ >= 50 || nohands(u.umonst->data)) { + if (gx.xlock.usedtime++ >= 50 || nohands(gy.youmonst.data)) { You("give up your attempt at %s.", lock_action()); exercise(A_DEX, TRUE); /* even if you don't succeed */ return ((gx.xlock.usedtime = 0)); @@ -218,7 +218,7 @@ forcelock(void) if ((gx.xlock.box->ox != u.ux) || (gx.xlock.box->oy != u.uy)) return ((gx.xlock.usedtime = 0)); /* you or it moved */ - if (gx.xlock.usedtime++ >= 50 || !uwep || nohands(u.umonst->data)) { + if (gx.xlock.usedtime++ >= 50 || !uwep || nohands(gy.youmonst.data)) { You("give up your attempt to force the lock."); if (gx.xlock.usedtime >= 50) /* you made the effort */ exercise((gx.xlock.picktyp) ? A_DEX : A_STR, TRUE); @@ -315,7 +315,7 @@ autokey(boolean opening) /* True: key, pick, or card; False: key or pick */ } else { switch (o->otyp) { case SKELETON_KEY: - if (!key || is_magic_key(u.umonst, o)) + if (!key || is_magic_key(&gy.youmonst, o)) key = o; break; case LOCK_PICK: @@ -380,7 +380,7 @@ pick_lock( if (gx.xlock.usedtime && picktyp == gx.xlock.picktyp) { static char no_longer[] = "Unfortunately, you can no longer %s %s."; - if (nohands(u.umonst->data)) { + if (nohands(gy.youmonst.data)) { const char *what = (picktyp == LOCK_PICK) ? "pick" : "key"; if (picktyp == CREDIT_CARD) @@ -396,13 +396,13 @@ pick_lock( const char *action = lock_action(); You("resume your attempt at %s.", action); - gx.xlock.magic_key = is_magic_key(u.umonst, pick); + gx.xlock.magic_key = is_magic_key(&gy.youmonst, pick); set_occupation(picklock, action, 0); return PICKLOCK_DID_SOMETHING; } } - if (nohands(u.umonst->data)) { + if (nohands(gy.youmonst.data)) { You_cant("hold %s -- you have no hands!", doname(pick)); return PICKLOCK_DID_NOTHING; } else if (u.uswallow) { @@ -513,7 +513,7 @@ pick_lock( an(simple_typename(picktyp))); return PICKLOCK_LEARNED_SOMETHING; } else if (autounlock - && !touch_artifact(pick, u.umonst)) { + && !touch_artifact(pick, &gy.youmonst)) { /* note: for !autounlock, apply already did touch check */ return PICKLOCK_DID_SOMETHING; } @@ -626,7 +626,7 @@ pick_lock( return PICKLOCK_DID_NOTHING; /* note: for !autounlock, 'apply' already did touch check */ - if (autounlock && !touch_artifact(pick, u.umonst)) + if (autounlock && !touch_artifact(pick, &gy.youmonst)) return PICKLOCK_DID_SOMETHING; switch (picktyp) { @@ -649,7 +649,7 @@ pick_lock( svc.context.move = 0; gx.xlock.chance = ch; gx.xlock.picktyp = picktyp; - gx.xlock.magic_key = is_magic_key(u.umonst, pick); + gx.xlock.magic_key = is_magic_key(&gy.youmonst, pick); gx.xlock.usedtime = 0; set_occupation(picklock, lock_action(), 0); return PICKLOCK_DID_SOMETHING; @@ -785,7 +785,7 @@ doopen_indir(coordxy x, coordxy y) const char *dirprompt; int res = ECMD_OK; - if (nohands(u.umonst->data)) { + if (nohands(gy.youmonst.data)) { You_cant("open anything -- you have no hands!"); return ECMD_OK; } @@ -895,7 +895,7 @@ doopen_indir(coordxy x, coordxy y) return res; } - if (verysmall(u.umonst->data)) { + if (verysmall(gy.youmonst.data)) { pline("You're too small to pull the door open."); return res; } @@ -961,7 +961,7 @@ doclose(void) boolean portcullis; int res = ECMD_OK; - if (nohands(u.umonst->data)) { + if (nohands(gy.youmonst.data)) { You_cant("close anything -- you have no hands!"); return ECMD_OK; } @@ -1031,7 +1031,7 @@ doclose(void) } if (door->doormask == D_ISOPEN) { - if (verysmall(u.umonst->data) && !u.usteed) { + if (verysmall(gy.youmonst.data) && !u.usteed) { pline("You're too small to push the door closed."); return res; } @@ -1281,7 +1281,7 @@ chest_shatter_msg(struct obj *otmp) if (otmp->oclass == POTION_CLASS) { You("%s %s shatter!", Blind ? "hear" : "see", an(bottlename())); - if (!breathless(u.umonst->data) || haseyes(u.umonst->data)) + if (!breathless(gy.youmonst.data) || haseyes(gy.youmonst.data)) potionbreathe(otmp); return; } diff --git a/src/mcastu.c b/src/mcastu.c index 4b40fa2ff..34d839906 100644 --- a/src/mcastu.c +++ b/src/mcastu.c @@ -69,7 +69,7 @@ cursetxt(struct monst *mtmp, boolean undirected) point_msg = "all around, then curses"; else if ((Invis && !perceives(mtmp->data) && (mtmp->mux != u.ux || mtmp->muy != u.uy)) - || is_obj_mappear(u.umonst, STRANGE_OBJECT) + || is_obj_mappear(&gy.youmonst, STRANGE_OBJECT) || u.uundetected) point_msg = "and curses in your general direction"; else if (Displaced && (mtmp->mux != u.ux || mtmp->muy != u.uy)) @@ -389,7 +389,7 @@ staticfn void mcast_death_touch(struct monst *mtmp) { pline("Oh no, %s's using the touch of death!", mhe(mtmp)); - if (nonliving(u.umonst->data) || is_demon(u.umonst->data)) { + if (nonliving(gy.youmonst.data) || is_demon(gy.youmonst.data)) { You("seem no deader than before."); } else if (!Antimagic && rn2(mtmp->m_lev) > 12) { if (Hallucination) { @@ -553,9 +553,9 @@ mcast_fire_pillar(struct monst *mtmp, int dmg) if (Half_spell_damage) dmg = (dmg + 1) / 2; burn_away_slime(); - (void) burnarmor(u.umonst); + (void) burnarmor(&gy.youmonst); /* item destruction dmg */ - (void) destroy_items(u.umonst, AD_FIRE, orig_dmg); + (void) destroy_items(&gy.youmonst, AD_FIRE, orig_dmg); ignite_items(gi.invent); /* burn up flammable items on the floor, melt ice terrain */ mon_spell_hits_spot(mtmp, AD_FIRE, u.ux, u.uy); @@ -586,7 +586,7 @@ mcast_lightning(struct monst *mtmp, int dmg) } if (Half_spell_damage) dmg = (dmg + 1) / 2; - (void) destroy_items(u.umonst, AD_ELEC, orig_dmg); + (void) destroy_items(&gy.youmonst, AD_ELEC, orig_dmg); /* lightning might destroy iron bars if hero is on such a spot; reflection protects terrain here [execution won't get here due to 'if (reflects) break' above] but hero resistance doesn't; @@ -730,7 +730,7 @@ mcast_blind_you(void) { /* note: resists_blnd() doesn't apply here */ if (!Blinded) { - int num_eyes = eyecount(u.umonst->data); + int num_eyes = eyecount(gy.youmonst.data); pline("Scales cover your %s!", (num_eyes == 1) ? body_part(EYE) diff --git a/src/mhitm.c b/src/mhitm.c index c6db44600..5e8bb928e 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -607,7 +607,7 @@ failed_grab( && (mattk->aatyp == AT_HUGS || mattk->adtyp == AD_WRAP || mattk->adtyp == AD_STCK || mattk->adtyp == AD_DGST)) { if ((gv.vis && canspotmon(mdef)) /* mon-vs-mon */ - || magr == u.umonst || mdef == u.umonst) { + || magr == &gy.youmonst || mdef == &gy.youmonst) { char magrnam[BUFSZ], mdefnam[BUFSZ]; boolean tailmiss = gn.notonhead; const char *verb = (mattk->adtyp == AD_DGST) ? "gulp" @@ -618,14 +618,14 @@ failed_grab( mon_nam(x_monnam) calls s_suffix() for named ghosts and s_suffix() uses a single static buffer; make copies of both names to overcome that [note: comment predates 'tailmiss'] */ - Strcpy(magrnam, (magr == u.umonst) ? "Your" + Strcpy(magrnam, (magr == &gy.youmonst) ? "Your" : s_suffix(Monnam(magr))); if (!tailmiss) { - Strcpy(mdefnam, (mdef == u.umonst) ? "you" + Strcpy(mdefnam, (mdef == &gy.youmonst) ? "you" : mon_nam(mdef)); } else { /* hero poly'd into long worm can't grow tail - so no 'u.umonst' handling is needed here */ + so no 'youmonst' handling is needed here */ Sprintf(mdefnam, "%s tail", s_suffix(some_mon_nam(mdef))); } /* unsolid grab misses are actually somewhat iffy--how come @@ -808,8 +808,8 @@ engulf_target(struct monst *magr, struct monst *mdef) { struct rm *lev; int ax, ay, dx, dy; - boolean uatk = (magr == u.umonst), - udef = (mdef == u.umonst); + boolean uatk = (magr == &gy.youmonst), + udef = (mdef == &gy.youmonst); /* can't swallow something that's too big */ if (mdef->data->msize >= MZ_HUGE @@ -825,16 +825,16 @@ engulf_target(struct monst *magr, struct monst *mdef) might not be able to place attacker and defender both back on map; when defender is the hero, a sanity_check complaint about placing the hero on top of a monster can occur */ - dx = (mdef == u.umonst) ? u.ux : mdef->mx; - dy = (mdef == u.umonst) ? u.uy : mdef->my; + dx = (mdef == &gy.youmonst) ? u.ux : mdef->mx; + dy = (mdef == &gy.youmonst) ? u.uy : mdef->my; lev = &levl[dx][dy]; if (!(udef ? Passes_walls : passes_walls(mdef->data)) && (IS_OBSTRUCTED(lev->typ) || closed_door(dx, dy) || IS_TREE(lev->typ) /* not passes_bars(); engulfer isn't squeezing through */ || (lev->typ == IRONBARS && !is_whirly(magr->data)))) return FALSE; - ax = (magr == u.umonst) ? u.ux : magr->mx; - ay = (magr == u.umonst) ? u.uy : magr->my; + ax = (magr == &gy.youmonst) ? u.ux : magr->mx; + ay = (magr == &gy.youmonst) ? u.uy : magr->my; lev = &levl[ax][ay]; if (!(uatk ? Passes_walls : passes_walls(magr->data)) && (IS_OBSTRUCTED(lev->typ) || closed_door(ax, ay) || IS_TREE(lev->typ) @@ -1124,7 +1124,7 @@ mon_poly(struct monst *magr, struct monst *mdef, int dmg) static const char freaky[] = " undergoes a freakish metamorphosis"; struct permonst *oldform = mdef->data; - if (mdef == u.umonst) { + if (mdef == &gy.youmonst) { if (Antimagic) { shieldeff(u.ux, u.uy); } else if (Unchanging) { @@ -1166,7 +1166,7 @@ mon_poly(struct monst *magr, struct monst *mdef, int dmg) mdef->mhp -= dmg; dmg = 0; if (DEADMONSTER(mdef)) { - if (magr == u.umonst) + if (magr == &gy.youmonst) xkilled(mdef, XKILL_GIVEMSG | XKILL_NOCORPSE); else monkilled(mdef, "", AD_RBRE); @@ -1182,13 +1182,13 @@ mon_poly(struct monst *magr, struct monst *mdef, int dmg) x_monnam(mdef, ARTICLE_A, (char *) 0, (SUPPRESS_NAME | SUPPRESS_IT | SUPPRESS_INVISIBLE), FALSE)); - else if (was_seen || magr == u.umonst) + else if (was_seen || magr == &gy.youmonst) pline("%s%s%s.", Before, freaky, !was_seen ? "" : " and disappears"); } dmg = 0; if (can_teleport(magr->data)) { - if (magr == u.umonst) + if (magr == &gy.youmonst) tele(); else if (!tele_restrict(magr)) (void) rloc(magr, RLOC_MSG); @@ -1200,7 +1200,7 @@ mon_poly(struct monst *magr, struct monst *mdef, int dmg) } /* when a transformation has happened, can't attack again for poly effect during next turn or two; not enforced for poly'd hero */ - if (mdef->data != oldform && magr != u.umonst) + if (mdef->data != oldform && magr != &gy.youmonst) magr->mspec_used += rnd(2); return dmg; @@ -1250,7 +1250,7 @@ void slept_monst(struct monst *mon) { if (helpless(mon) && mon == u.ustuck - && !sticks(u.umonst->data) && !u.uswallow) { + && !sticks(gy.youmonst.data) && !u.uswallow) { pline_mon(mon, "%s grip relaxes.", s_suffix(Monnam(mon))); unstuck(mon); } diff --git a/src/mhitu.c b/src/mhitu.c index b71104cb9..71d90a8ec 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -34,7 +34,7 @@ hitmsg(struct monst *mtmp, struct attack *mattk) /* Note: if opposite gender, "seductively"; if same gender, "engagingly" for nymph, normal msg for others. */ - if ((compat = could_seduce(mtmp, u.umonst, mattk)) != 0 + if ((compat = could_seduce(mtmp, &gy.youmonst, mattk)) != 0 && !mtmp->mcan && !mtmp->mspec_used) { pline_mon(mtmp, "%s %s you %s.", Monst_name, !Blind ? "smiles at" : !Deaf ? "talks to" : "touches", @@ -45,7 +45,7 @@ hitmsg(struct monst *mtmp, struct attack *mattk) verb = "bites"; break; case AT_KICK: - if (thick_skinned(u.umonst->data)) + if (thick_skinned(gy.youmonst.data)) punct = "."; verb = "kicks"; break; @@ -90,7 +90,7 @@ missmu(struct monst *mtmp, boolean nearmiss, struct attack *mattk) if (!canspotmon(mtmp)) map_invisible(mtmp->mx, mtmp->my); - if (could_seduce(mtmp, u.umonst, mattk) && !mtmp->mcan) + if (could_seduce(mtmp, &gy.youmonst, mattk) && !mtmp->mcan) pline_mon(mtmp, "%s pretends to be friendly.", Monnam(mtmp)); else pline_mon(mtmp, "%s %smisses!", Monnam(mtmp), @@ -147,7 +147,7 @@ mpoisons_subj( struct attack *mattk) { if (mattk->aatyp == AT_WEAP) { - struct obj *mwep = (mtmp == u.umonst) ? uwep : MON_WEP(mtmp); + struct obj *mwep = (mtmp == &gy.youmonst) ? uwep : MON_WEP(mtmp); /* "Foo's attack was poisoned." is pretty lame, but at least it's better than "sting" when not a stinging attack... */ return (!mwep || !mwep->opoisoned) ? "attack" : "weapon"; @@ -200,7 +200,7 @@ wildmiss(struct monst *mtmp, struct attack *mattk) /* maybe it's attacking an image around the corner? */ compat = ((mattk->adtyp == AD_SEDU || mattk->adtyp == AD_SSEX) - ? could_seduce(mtmp, u.umonst, mattk) : 0); + ? could_seduce(mtmp, &gy.youmonst, mattk) : 0); Monst_name = Monnam(mtmp); set_msg_xy(mtmp->mx, mtmp->my); @@ -314,8 +314,8 @@ getmattk( { struct permonst *mptr = magr->data; struct attack *attk = &mptr->mattk[indx]; - struct obj *weap = (magr == u.umonst) ? uwep : MON_WEP(magr); - boolean udefend = mdef == u.umonst; + struct obj *weap = (magr == &gy.youmonst) ? uwep : MON_WEP(magr); + boolean udefend = mdef == &gy.youmonst; /* honor SEDUCE=0 */ if (!SYSOPT_SEDUCE) { @@ -396,7 +396,7 @@ getmattk( if weapon is sufficiently interesting; a few unique creatures have two weapon attacks where one does physical damage and other doesn't--avoid forcing physical damage for those */ - } else if (indx == 0 && magr != u.umonst + } else if (indx == 0 && magr != &gy.youmonst && attk->aatyp == AT_WEAP && attk->adtyp != AD_PHYS && !(mptr->mattk[1].aatyp == AT_WEAP && mptr->mattk[1].adtyp == AD_PHYS) @@ -468,7 +468,7 @@ mtrapped_in_pit(struct monst *mtmp) { struct trap *ttmp = 0; - if (mtmp == u.umonst) + if (mtmp == &gy.youmonst) ttmp = (u.utrap && u.utraptype == TT_PIT) ? t_at(u.ux, u.uy) : 0; else ttmp = mtmp->mtrapped ? t_at(mtmp->mx, mtmp->my) : 0; @@ -552,7 +552,7 @@ mattacku(struct monst *mtmp) if (!canspotmon(mtmp)) map_invisible(mtmp->mx, mtmp->my); u.uundetected = 0; - if (is_hider(u.umonst->data) && u.umonnum != PM_TRAPPER) { + if (is_hider(gy.youmonst.data) && u.umonnum != PM_TRAPPER) { /* ceiling hider */ coord cc; /* maybe we need a unexto() function? */ struct obj *obj; @@ -562,7 +562,7 @@ mattacku(struct monst *mtmp) is eligible for placing hero; we assume that a removed monster remembers its old spot */ remove_monster(mtmp->mx, mtmp->my); - if (!enexto(&cc, u.ux, u.uy, u.umonst->data) + if (!enexto(&cc, u.ux, u.uy, gy.youmonst.data) /* a fish won't voluntarily swap positions when it's in water and hero is over land */ || (mtmp->data->mlet == S_EEL @@ -587,13 +587,13 @@ mattacku(struct monst *mtmp) /* tail hasn't grown, so if it now occupies then one of its original spots must be free */ if (m_at(cc.x, cc.y)) - (void) enexto(&cc, u.ux, u.uy, u.umonst->data); + (void) enexto(&cc, u.ux, u.uy, gy.youmonst.data); } teleds(cc.x, cc.y, TELEDS_ALLOW_DRAG); /* move hero */ set_apparxy(mtmp); newsym(u.ux, u.uy); - if (u.umonst->data->mlet != S_PIERCER) + if (gy.youmonst.data->mlet != S_PIERCER) return 0; /* lurkers don't attack */ obj = which_armor(mtmp, WORN_HELMET); @@ -625,7 +625,7 @@ mattacku(struct monst *mtmp) struct obj *obj = svl.level.objects[u.ux][u.uy]; if (obj || u.umonnum == PM_TRAPPER - || (u.umonst->data->mlet == S_EEL + || (gy.youmonst.data->mlet == S_EEL && is_pool(u.ux, u.uy))) { int save_spe = 0; /* suppress warning */ @@ -636,17 +636,17 @@ mattacku(struct monst *mtmp) } /* note that m_monnam() overrides hallucination, which is what we want when message is from mtmp's perspective */ - if (u.umonst->data->mlet == S_EEL + if (gy.youmonst.data->mlet == S_EEL || u.umonnum == PM_TRAPPER) pline( "Wait, %s! There's a hidden %s named %s there!", m_monnam(mtmp), - pmname(u.umonst->data, Ugender), svp.plname); + pmname(gy.youmonst.data, Ugender), svp.plname); else pline( "Wait, %s! There's a %s named %s hiding under %s!", m_monnam(mtmp), - pmname(u.umonst->data, Ugender), + pmname(gy.youmonst.data, Ugender), svp.plname, doname(svl.level.objects[u.ux][u.uy])); if (obj) @@ -660,9 +660,9 @@ mattacku(struct monst *mtmp) } /* hero might be a mimic, concealed via #monster */ - if (u.umonst->data->mlet == S_MIMIC && U_AP_TYPE && !range2 + if (gy.youmonst.data->mlet == S_MIMIC && U_AP_TYPE && !range2 && foundyou && !u.uswallow) { - boolean sticky = sticks(u.umonst->data); + boolean sticky = sticks(gy.youmonst.data); if (!canspotmon(mtmp)) map_invisible(mtmp->mx, mtmp->my); @@ -670,11 +670,11 @@ mattacku(struct monst *mtmp) pline("It gets stuck on you."); else /* see note about m_monnam() above */ pline("Wait, %s! That's a %s named %s!", m_monnam(mtmp), - pmname(u.umonst->data, Ugender), svp.plname); + pmname(gy.youmonst.data, Ugender), svp.plname); if (sticky) set_ustuck(mtmp); - u.umonst->m_ap_type = M_AP_NOTHING; - u.umonst->mappearance = 0; + gy.youmonst.m_ap_type = M_AP_NOTHING; + gy.youmonst.mappearance = 0; newsym(u.ux, u.uy); return 0; } @@ -686,18 +686,18 @@ mattacku(struct monst *mtmp) if (!youseeit) pline("%s %s!", Something, (likes_gold(mtmp->data) - && u.umonst->mappearance == GOLD_PIECE) + && gy.youmonst.mappearance == GOLD_PIECE) ? "tries to pick you up" : "disturbs you"); else /* see note about m_monnam() above */ pline("Wait, %s! That %s is really %s named %s!", m_monnam(mtmp), - mimic_obj_name(u.umonst), + mimic_obj_name(&gy.youmonst), an(pmname(&mons[u.umonnum], Ugender)), svp.plname); if (gm.multi < 0) { /* this should always be the case */ char buf[BUFSZ]; Sprintf(buf, "You appear to be %s again.", - Upolyd ? (const char *) an(pmname(u.umonst->data, + Upolyd ? (const char *) an(pmname(gy.youmonst.data, flags.female)) : (const char *) "yourself"); unmul(buf); /* immediately stop mimicking */ @@ -783,7 +783,7 @@ mattacku(struct monst *mtmp) continue; } mon_currwep = (struct obj *) 0; - mattk = getmattk(mtmp, u.umonst, i, sum, &alt_attk); + mattk = getmattk(mtmp, &gy.youmonst, i, sum, &alt_attk); if ((u.uswallow && mattk->aatyp != AT_ENGL) || (skipnonmagc && mattk->aatyp != AT_MAGC) || (gs.skipdrin && mattk->aatyp == AT_TENT @@ -801,14 +801,14 @@ mattacku(struct monst *mtmp) if (mattk->aatyp == AT_KICK && mtrapped_in_pit(mtmp)) continue; if (!range2 && (!MON_WEP(mtmp) || mtmp->mconf || Conflict - || !touch_petrifies(u.umonst->data))) { + || !touch_petrifies(gy.youmonst.data))) { if (foundyou) { if (tmp > (j = rnd(20 + i))) { - if (unsolid(u.umonst->data) - && failed_grab(mtmp, u.umonst, mattk)) + if (unsolid(gy.youmonst.data) + && failed_grab(mtmp, &gy.youmonst, mattk)) continue; if (mattk->aatyp != AT_KICK - || !thick_skinned(u.umonst->data)) + || !thick_skinned(gy.youmonst.data)) sum[i] = hitmu(mtmp, mattk); } else missmu(mtmp, (tmp == j), mattk); @@ -824,7 +824,7 @@ mattacku(struct monst *mtmp) /* Note: if displaced, prev attacks never succeeded */ if ((!range2 && i >= 2 && sum[i - 1] && sum[i - 2]) || mtmp == u.ustuck) { - if (!failed_grab(mtmp, u.umonst, mattk)) + if (!failed_grab(mtmp, &gy.youmonst, mattk)) sum[i] = hitmu(mtmp, mattk); } break; @@ -905,7 +905,7 @@ mattacku(struct monst *mtmp) ART_SNICKERSNEE) && m_next2u(mtmp)); - hittmp = hitval(mon_currwep, u.umonst); + hittmp = hitval(mon_currwep, &gy.youmonst); tmp += hittmp; mswings(mtmp, mon_currwep, bash); } @@ -1091,7 +1091,7 @@ magic_negation(struct monst *mon) struct obj *o; long wearmask; int armpro, mc = 0; - boolean is_you = (mon == u.umonst), + boolean is_you = (mon == &gy.youmonst), via_amul = FALSE, gotprot = is_you ? (EProtection != 0L) /* high priests have innate protection */ @@ -1144,7 +1144,7 @@ staticfn int hitmu(struct monst *mtmp, struct attack *mattk) { struct permonst *mdat = mtmp->data; - struct permonst *olduasmon = u.umonst->data; + struct permonst *olduasmon = gy.youmonst.data; int res; struct mhitm_data mhm; mhm.hitflags = M_ATTK_MISS; @@ -1188,9 +1188,9 @@ hitmu(struct monst *mtmp, struct attack *mattk) if ((is_undead(mdat) || is_vampshifter(mtmp)) && midnight()) mhm.damage += d((int) mattk->damn, (int) mattk->damd); /* extra dmg */ - mhitm_adtyping(mtmp, mattk, u.umonst, &mhm); + mhitm_adtyping(mtmp, mattk, &gy.youmonst, &mhm); - (void) mhitm_knockback(mtmp, u.umonst, mattk, &mhm.hitflags, + (void) mhitm_knockback(mtmp, &gy.youmonst, mattk, &mhm.hitflags, (MON_WEP(mtmp) != 0)); if (mhm.done) @@ -1240,8 +1240,8 @@ hitmu(struct monst *mtmp, struct attack *mattk) if (Upolyd) { hpmax_p = &u.mhmax; - /* [can't use u.umonst->m_lev] */ - lowerlimit = min((int) u.umonst->data->mlevel, u.ulevel); + /* [can't use gy.youmonst.m_lev] */ + lowerlimit = min((int) gy.youmonst.data->mlevel, u.ulevel); } else { hpmax_p = &u.uhpmax; lowerlimit = minuhpmax(1); @@ -1276,7 +1276,7 @@ gulp_blnd_check(void) if (!Blinded && u.uswallow && (mattk = attacktype_fordmg(u.ustuck->data, AT_ENGL, AD_BLND)) - && can_blnd(u.ustuck, u.umonst, mattk->aatyp, (struct obj *) 0)) { + && can_blnd(u.ustuck, &gy.youmonst, mattk->aatyp, (struct obj *) 0)) { ++u.uswldtim; /* compensate for gulpmu change */ (void) gulpmu(u.ustuck, mattk); return TRUE; @@ -1298,11 +1298,11 @@ gulpmu(struct monst *mtmp, struct attack *mattk) if (!u.uswallow) { /* swallows you */ int omx = mtmp->mx, omy = mtmp->my; - if (!engulf_target(mtmp, u.umonst)) + if (!engulf_target(mtmp, &gy.youmonst)) return M_ATTK_MISS; if ((t && is_pit(t->ttyp)) && sobj_at(BOULDER, u.ux, u.uy)) return M_ATTK_MISS; - if (failed_grab(mtmp, u.umonst, mattk)) + if (failed_grab(mtmp, &gy.youmonst, mattk)) return M_ATTK_MISS; if (Punished) @@ -1354,7 +1354,7 @@ gulpmu(struct monst *mtmp, struct attack *mattk) unleash_all(); } - if (touch_petrifies(u.umonst->data) && !resists_ston(mtmp)) { + if (touch_petrifies(gy.youmonst.data) && !resists_ston(mtmp)) { /* put the attacker back where it started; the resulting statue will end up there [note: if poly'd hero could ride or non-poly'd hero could @@ -1438,13 +1438,13 @@ gulpmu(struct monst *mtmp, struct attack *mattk) physical_damage = TRUE; if (mtmp->data == &mons[PM_FOG_CLOUD]) { You("are laden with moisture and %s", - flaming(u.umonst->data) + flaming(gy.youmonst.data) ? "are smoldering out!" : Breathless ? "find it mildly uncomfortable." - : amphibious(u.umonst->data) + : amphibious(gy.youmonst.data) ? "feel comforted." : "can barely breathe!"); - if ((Amphibious || Breathless) && !flaming(u.umonst->data)) + if ((Amphibious || Breathless) && !flaming(gy.youmonst.data)) tmp = 0; } else { You("are %s!", enfolds(mtmp->data) ? "being squashed" @@ -1469,7 +1469,7 @@ gulpmu(struct monst *mtmp, struct attack *mattk) } break; case AD_BLND: - if (can_blnd(mtmp, u.umonst, mattk->aatyp, (struct obj *) 0)) { + if (can_blnd(mtmp, &gy.youmonst, mattk->aatyp, (struct obj *) 0)) { if (!Blind) { long was_blinded = Blinded; @@ -1564,13 +1564,13 @@ gulpmu(struct monst *mtmp, struct attack *mattk) if (!u.uswallow) { ; /* life-saving has already expelled swallowed hero */ - } else if (touch_petrifies(u.umonst->data) && !resists_ston(mtmp)) { + } else if (touch_petrifies(gy.youmonst.data) && !resists_ston(mtmp)) { pline("%s very hurriedly %s you!", Monnam(mtmp), digests(mtmp->data) ? "regurgitates" : enfolds(mtmp->data) ? "releases" : "expels"); expels(mtmp, mtmp->data, FALSE); - } else if (!u.uswldtim || u.umonst->data->msize >= MZ_HUGE) { + } else if (!u.uswldtim || gy.youmonst.data->msize >= MZ_HUGE) { /* As of 3.6.2: u.uswldtim used to be set to 0 by life-saving but it expels now so the !u.uswldtim case is no longer possible; however, polymorphing into a huge form while already @@ -1621,7 +1621,7 @@ explmu( kill_agr = FALSE; /* lifesaving? */ break; case AD_BLND: - not_affected = resists_blnd(u.umonst); + not_affected = resists_blnd(&gy.youmonst); if (ufound && !not_affected) { /* sometimes you're affected even if it's invisible */ if (mon_visible(mtmp) || (rnd(tmp /= 2) > u.ulevel)) { @@ -1636,7 +1636,7 @@ explmu( case AD_HALU: not_affected |= Blind || (u.umonnum == PM_BLACK_LIGHT || u.umonnum == PM_VIOLET_FUNGUS - || dmgtype(u.umonst->data, AD_STUN)); + || dmgtype(gy.youmonst.data, AD_STUN)); if (ufound && !not_affected) { boolean chg; if (!Hallucination) @@ -1748,7 +1748,7 @@ gazemu(struct monst *mtmp, struct attack *mattk) && !Stone_resistance && !Unaware) { You("meet %s gaze.", s_suffix(mon_nam(mtmp))); stop_occupation(); - if (poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM)) + if (poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM)) break; urgent_pline("You turn to stone..."); svk.killer.format = KILLED_BY; @@ -1791,7 +1791,7 @@ gazemu(struct monst *mtmp, struct attack *mattk) } break; case AD_BLND: - if (canseemon(mtmp) && !resists_blnd(u.umonst) + if (canseemon(mtmp) && !resists_blnd(&gy.youmonst) && mdistu(mtmp) <= BOLT_LIM * BOLT_LIM) { if (cancelled) { react = rn1(2, 2); /* "puzzled" || "dazzled" */ @@ -1842,9 +1842,9 @@ gazemu(struct monst *mtmp, struct attack *mattk) } burn_away_slime(); if (lev > rn2(20)) - (void) burnarmor(u.umonst); + (void) burnarmor(&gy.youmonst); if (lev > rn2(20)) { - (void) destroy_items(u.umonst, AD_FIRE, orig_dmg); + (void) destroy_items(&gy.youmonst, AD_FIRE, orig_dmg); ignite_items(gi.invent); } if (dmg) @@ -1943,8 +1943,8 @@ could_seduce( if (is_animal(magr->data)) return 0; - if (magr == u.umonst) { - pagr = u.umonst->data; + if (magr == &gy.youmonst) { + pagr = gy.youmonst.data; agrinvis = (Invis != 0); genagr = poly_gender(); } else { @@ -1952,7 +1952,7 @@ could_seduce( agrinvis = magr->minvis; genagr = gender(magr); } - if (mdef == u.umonst) { + if (mdef == &gy.youmonst) { defperc = (See_invisible != 0); gendef = poly_gender(); } else { @@ -2202,7 +2202,7 @@ doseduce(struct monst *mon) disp.botl = TRUE; break; case 3: - if (!resists_drli(u.umonst)) { + if (!resists_drli(&gy.youmonst)) { You_feel("out of shape."); losexp("overexertion"); } else { @@ -2541,7 +2541,7 @@ passiveum( && (perceives(mtmp->data) || !Invis)) { if (Blind) { pline("As a blind %s, you cannot defend yourself.", - pmname(u.umonst->data, + pmname(gy.youmonst.data, flags.female ? FEMALE : MALE)); } else { if (mon_reflects(mtmp, @@ -2571,8 +2571,8 @@ passiveum( u.mh += (tmp + rn2(2)) / 2; if (u.mhmax < u.mh) u.mhmax = u.mh; - if (u.mhmax > (((int) u.umonst->data->mlevel + 1) * 8)) - (void) split_mon(u.umonst, mtmp); + if (u.mhmax > (((int) gy.youmonst.data->mlevel + 1) * 8)) + (void) split_mon(&gy.youmonst, mtmp); break; case AD_STUN: /* Yellow mold */ if (!mtmp->mstun) { @@ -2617,20 +2617,20 @@ struct monst * cloneu(void) { struct monst *mon; - int mndx = monsndx(u.umonst->data); + int mndx = monsndx(gy.youmonst.data); if (u.mh <= 1) return (struct monst *) 0; if (svm.mvitals[mndx].mvflags & G_EXTINCT) return (struct monst *) 0; - mon = makemon(u.umonst->data, u.ux, u.uy, + mon = makemon(gy.youmonst.data, u.ux, u.uy, NO_MINVENT | MM_EDOG | MM_NOMSG); if (!mon) return NULL; mon->mcloned = 1; mon = christen_monst(mon, svp.plname); initedog(mon, TRUE); - mon->m_lev = u.umonst->data->mlevel; + mon->m_lev = gy.youmonst.data->mlevel; mon->mhpmax = u.mhmax; mon->mhp = u.mh / 2; u.mh -= mon->mhp; diff --git a/src/minion.c b/src/minion.c index 833e5597f..96f9ffe1c 100644 --- a/src/minion.c +++ b/src/minion.c @@ -296,7 +296,7 @@ demon_talk(struct monst *mtmp) } newsym(mtmp->mx, mtmp->my); } - if (u.umonst->data->mlet == S_DEMON) { /* Won't blackmail their own. */ + if (gy.youmonst.data->mlet == S_DEMON) { /* Won't blackmail their own. */ if (!Deaf) pline("%s says, \"Good hunting, %s.\"", Amonnam(mtmp), flags.female ? "Sister" : "Brother"); diff --git a/src/mon.c b/src/mon.c index 2452813e4..789ca8276 100644 --- a/src/mon.c +++ b/src/mon.c @@ -330,7 +330,7 @@ int m_poisongas_ok(struct monst *mtmp) { int px, py; - boolean is_you = (mtmp == u.umonst); + boolean is_you = (mtmp == &gy.youmonst); /* Non living, non breathing, immune monsters are not concerned */ if (nonliving(mtmp->data) || is_vampshifter(mtmp) @@ -2104,8 +2104,8 @@ mon_allowflags(struct monst *mtmp) if (passes_bars(mtmp->data) /* restrict engulfer or holder who might try to pass iron bars while carrying hero; accept small subset for poly'd hero passes_bars() */ - && (mtmp != u.ustuck || (unsolid(u.umonst->data) - || verysmall(u.umonst->data)))) + && (mtmp != u.ustuck || (unsolid(gy.youmonst.data) + || verysmall(gy.youmonst.data)))) allowflags |= ALLOW_BARS; #if 0 /* can't do this here; leave it for mfndpos() */ if (is_displacer(mtmp->data)) @@ -3209,7 +3209,7 @@ corpse_chance( if (was_swallowed && magr) { /* mdef is a gas spore (AT_BOOM) that is exploding inside an engulfer; suppress usual explosion since it's contained */ - if (magr == u.umonst) { + if (magr == &gy.youmonst) { There("is an explosion in your %s!", body_part(STOMACH)); Sprintf(svk.killer.name, "%s explosion", s_suffix(pmname(mdat, Mgender(mon)))); @@ -3617,7 +3617,7 @@ xkilled( /* corpse--none if hero was inside the monster */ if (!wasinside && corpse_chance(mtmp, (struct monst *) 0, FALSE)) { gz.zombify = (!gt.thrownobj && !gs.stoned && !uwep - && zombie_maker(u.umonst) + && zombie_maker(&gy.youmonst) && zombie_form(mtmp->data) != NON_PM); cadaver = make_corpse(mtmp, burycorpse ? CORPSTAT_BURIED : CORPSTAT_NONE); @@ -4595,7 +4595,7 @@ get_iter_mons_xy( int healmon(struct monst *mtmp, int amt, int overheal) { - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { int oldhp = Upolyd ? u.mh : u.uhp; healup(amt, 0, 0, 0); return (Upolyd ? u.mh : u.uhp) - oldhp; @@ -4704,7 +4704,7 @@ maybe_unhide_at(coordxy x, coordxy y) undetected = mtmp->mundetected; trapped = mtmp->mtrapped; } else if (u_at(x, y)) { - mtmp = u.umonst; + mtmp = &gy.youmonst; undetected = u.uundetected; trapped = u.utrap; } else { @@ -4730,7 +4730,7 @@ hideunder(struct monst *mtmp) const char *seenmon = (char *) 0, *seenobj = (char *) 0, *locomo = (char *) 0; int seeit = gi.in_mklev ? 0 : canseemon(mtmp); - boolean oldundetctd, undetected = FALSE, is_u = (mtmp == u.umonst); + boolean oldundetctd, undetected = FALSE, is_u = (mtmp == &gy.youmonst); coordxy x = is_u ? u.ux : mtmp->mx, y = is_u ? u.uy : mtmp->my; if (mtmp == u.ustuck) { @@ -5437,7 +5437,7 @@ newcham( /* update swallow glyphs for new monster */ swallowed(0); } - } else if ((!sticks(mdat) && !sticks(u.umonst->data)) + } else if ((!sticks(mdat) && !sticks(gy.youmonst.data)) /* sticky hero can't continue to hold mtmp if it has turned into a non-solid creature; we don't use uunstick() for that because its message would be @@ -5800,7 +5800,7 @@ usmellmon(struct permonst *mdat) boolean msg_given = FALSE; if (mdat) { - if (!olfaction(u.umonst->data)) + if (!olfaction(gy.youmonst.data)) return FALSE; mndx = monsndx(mdat); switch (mndx) { @@ -5895,7 +5895,7 @@ usmellmon(struct permonst *mdat) msg_given = TRUE; break; case S_ORC: - if (maybe_polyd(is_orc(u.umonst->data), Race_if(PM_ORC))) + if (maybe_polyd(is_orc(gy.youmonst.data), Race_if(PM_ORC))) You("notice an attractive smell."); else pline("A foul stench makes you feel a little nauseated."); diff --git a/src/mondata.c b/src/mondata.c index 2e6d049a2..d7ea80245 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -13,7 +13,7 @@ void set_mon_data(struct monst *mon, struct permonst *ptr) { int new_speed, old_speed = mon->data ? mon->data->mmove : 0; - short *movement_p = (mon == u.umonst) ? &u.umovement : &mon->movement; + short *movement_p = (mon == &gy.youmonst) ? &u.umovement : &mon->movement; mon->data = ptr; mon->mnum = (short) monsndx(ptr); @@ -85,14 +85,14 @@ poly_when_stoned(struct permonst *ptr) /* allow G_EXTINCT */ } -/* is 'mon' (possibly u.umonst) protected against damage type 'adtype' via +/* is 'mon' (possibly youmonst) protected against damage type 'adtype' via wielded weapon or worn dragon scales? [or by virtue of being a dragon?] */ boolean defended(struct monst *mon, int adtyp) { struct obj *o, otemp; int mndx; - boolean is_you = (mon == u.umonst); + boolean is_you = (mon == &gy.youmonst); /* is 'mon' wielding an artifact that protects against 'adtyp'? */ o = is_you ? uwep : MON_WEP(mon); @@ -130,7 +130,7 @@ Resists_Elem(struct monst *mon, int propindx) { struct obj *o; long slotmask; - boolean is_you = (mon == u.umonst); + boolean is_you = (mon == &gy.youmonst); int u_resist = 0, damgtype = 0, rsstmask = 0; /* @@ -204,7 +204,7 @@ resists_drli(struct monst *mon) if (is_undead(ptr) || is_demon(ptr) || is_were(ptr) /* is_were() doesn't handle hero in human form */ - || (mon == u.umonst && u.ulycn >= LOW_PM) + || (mon == &gy.youmonst && u.ulycn >= LOW_PM) || ptr == &mons[PM_DEATH] || is_vampshifter(mon)) return TRUE; return defended(mon, AD_DRLI); @@ -215,7 +215,7 @@ boolean resists_magm(struct monst *mon) { struct permonst *ptr = mon->data; - boolean is_you = (mon == u.umonst); + boolean is_you = (mon == &gy.youmonst); long slotmask; struct obj *o; @@ -248,7 +248,7 @@ boolean resists_blnd(struct monst *mon) { struct permonst *ptr = mon->data; - boolean is_you = (mon == u.umonst); + boolean is_you = (mon == &gy.youmonst); if (is_you ? (Blind || Unaware) : (mon->mblinded || !mon->mcansee || !haseyes(ptr) @@ -278,7 +278,7 @@ boolean resists_blnd_by_arti(struct monst *mon) { struct obj *o; - boolean is_you = (mon == u.umonst); + boolean is_you = (mon == &gy.youmonst); o = is_you ? uwep : MON_WEP(mon); if (o && o->oartifact && defends(AD_BLND, o)) @@ -308,7 +308,7 @@ can_blnd( uchar aatyp, struct obj *obj) /* aatyp == AT_WEAP, AT_SPIT */ { - boolean is_you = (mdef == u.umonst); + boolean is_you = (mdef == &gy.youmonst); boolean check_visor = FALSE; struct obj *o; @@ -354,7 +354,7 @@ can_blnd( return TRUE; /* no defense */ } else return FALSE; /* other objects cannot cause blindness yet */ - if ((magr == u.umonst) && u.uswallow) + if ((magr == &gy.youmonst) && u.uswallow) return FALSE; /* can't affect eyes while inside monster */ break; @@ -369,7 +369,7 @@ can_blnd( /* e.g. raven: all ublindf, including LENSES, protect */ if (is_you && ublindf) return FALSE; - if ((magr == u.umonst) && u.uswallow) + if ((magr == &gy.youmonst) && u.uswallow) return FALSE; /* can't affect eyes while inside monster */ check_visor = TRUE; break; @@ -387,7 +387,7 @@ can_blnd( /* check if wearing a visor (only checked if visor might help) */ if (check_visor) { - o = (mdef == u.umonst) ? gi.invent : mdef->minvent; + o = (mdef == &gy.youmonst) ? gi.invent : mdef->minvent; for (; o; o = o->nobj) if ((o->owornmask & W_ARMH) && objdescr_is(o, "visored helmet")) @@ -570,7 +570,7 @@ can_blow(struct monst *mtmp) && (breathless(mtmp->data) || verysmall(mtmp->data) || !has_head(mtmp->data) || mtmp->data->mlet == S_EEL)) return FALSE; - if ((mtmp == u.umonst) && Strangled) + if ((mtmp == &gy.youmonst) && Strangled) return FALSE; return TRUE; } @@ -579,7 +579,7 @@ can_blow(struct monst *mtmp) boolean can_chant(struct monst *mtmp) { - if ((mtmp == u.umonst && Strangled) + if ((mtmp == &gy.youmonst && Strangled) || is_silent(mtmp->data) || !has_head(mtmp->data) || mtmp->data->msound == MS_BUZZ || mtmp->data->msound == MS_BURBLE) return FALSE; @@ -602,10 +602,10 @@ can_be_strangled(struct monst *mon) are non-breathing creatures which have higher brain function. */ if (!has_head(mon->data)) return FALSE; - if (mon == u.umonst) { + if (mon == &gy.youmonst) { /* hero can't be mindless but poly'ing into mindless form can confer strangulation protection */ - nobrainer = mindless(u.umonst->data); + nobrainer = mindless(gy.youmonst.data); nonbreathing = Breathless; } else { nobrainer = mindless(mon->data); @@ -1358,7 +1358,7 @@ big_little_match(int montyp1, int montyp2) const struct permonst * raceptr(struct monst *mtmp) { - if (mtmp == u.umonst && !Upolyd) + if (mtmp == &gy.youmonst && !Upolyd) return &mons[gu.urace.mnum]; return mtmp->data; } diff --git a/src/monmove.c b/src/monmove.c index 773fa3011..bd6d62cee 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -364,7 +364,7 @@ release_hero(struct monst *mon) if (mon == u.ustuck) { if (u.uswallow) { expels(mon, mon->data, TRUE); - } else if (!sticks(u.umonst->data)) { + } else if (!sticks(gy.youmonst.data)) { unstuck(mon); /* let go */ You("get released!"); } @@ -608,8 +608,8 @@ mind_blast(struct monst *mtmp) /* hero has no way to hide as monster but check for that theoretical case anyway */ && U_AP_TYPE != M_AP_MONSTER) { - u.umonst->m_ap_type = M_AP_NOTHING; - u.umonst->mappearance = 0; + gy.youmonst.m_ap_type = M_AP_NOTHING; + gy.youmonst.mappearance = 0; newsym(u.ux, u.uy); } pline("It locks on to your %s!", @@ -649,7 +649,7 @@ mind_blast(struct monst *mtmp) void m_everyturn_effect(struct monst *mtmp) { - boolean is_u = (mtmp == u.umonst) ? TRUE : FALSE; + boolean is_u = (mtmp == &gy.youmonst) ? TRUE : FALSE; coordxy x = is_u ? u.ux : mtmp->mx, y = is_u ? u.uy : mtmp->my; @@ -671,7 +671,7 @@ m_everyturn_effect(struct monst *mtmp) void m_postmove_effect(struct monst *mtmp) { - boolean is_u = (mtmp == u.umonst) ? TRUE : FALSE; + boolean is_u = (mtmp == &gy.youmonst) ? TRUE : FALSE; coordxy x = is_u ? u.ux0 : mtmp->mx, y = is_u ? u.uy0 : mtmp->my; @@ -806,7 +806,7 @@ dochug(struct monst *mtmp) pline("%s whispers at thin air.", cansee(mtmp->mux, mtmp->muy) ? Monnam(mtmp) : "It"); - if (is_demon(u.umonst->data)) { + if (is_demon(gy.youmonst.data)) { /* "Good hunting, brother" */ if (!tele_restrict(mtmp)) (void) rloc(mtmp, RLOC_MSG); @@ -1052,7 +1052,7 @@ mon_would_consume_item(struct monst *mtmp, struct obj *otmp) boolean itsstuck(struct monst *mtmp) { - if (sticks(u.umonst->data) && mtmp == u.ustuck && !u.uswallow) { + if (sticks(gy.youmonst.data) && mtmp == u.ustuck && !u.uswallow) { pline_mon(mtmp, "%s cannot escape from you!", Monnam(mtmp)); return TRUE; } @@ -1864,8 +1864,8 @@ m_move(struct monst *mtmp, int after) if (!mtmp->mcansee || (should_see && Invis && !perceives(ptr) && rn2(11)) - || is_obj_mappear(u.umonst, STRANGE_OBJECT) || u.uundetected - || (is_obj_mappear(u.umonst, GOLD_PIECE) && !likes_gold(ptr)) + || is_obj_mappear(&gy.youmonst, STRANGE_OBJECT) || u.uundetected + || (is_obj_mappear(&gy.youmonst, GOLD_PIECE) && !likes_gold(ptr)) || (mtmp->mpeaceful && !mtmp->isshk) /* allow shks to follow */ || ((monsndx(ptr) == PM_STALKER || ptr->mlet == S_BAT || ptr->mlet == S_LIGHT) && !rn2(3))) @@ -1891,7 +1891,7 @@ m_move(struct monst *mtmp, int after) if ((!mtmp->mpeaceful || !rn2(10)) && (!Is_rogue_level(&u.uz))) { boolean in_line = (lined_up(mtmp) && (distmin(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) - <= (throws_rocks(u.umonst->data) ? 20 + <= (throws_rocks(gy.youmonst.data) ? 20 : (ACURRSTR / 2 + 1)))); if (appr != 1 || !in_line) { @@ -2320,7 +2320,7 @@ stuff_prevents_passage(struct monst *mtmp) { struct obj *chain, *obj; - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { chain = gi.invent; } else { chain = mtmp->minvent; diff --git a/src/mthrowu.c b/src/mthrowu.c index 850abac8a..6f8ed721c 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -124,7 +124,7 @@ thitu( pline("It doesn't seem to hurt you."); monstseesu(M_SEEN_ACID); } else if (obj && stone_missile(obj) - && passes_rocks(u.umonst->data)) { + && passes_rocks(gy.youmonst.data)) { /* use 'named' as an approximation for "hitting from above"; we avoid "passes through you" for horizontal flight path because missile stops and that wording would suggest that @@ -134,7 +134,7 @@ thitu( } else if (obj && obj->oclass == POTION_CLASS) { /* an explosion which scatters objects might hit hero with one (potions deliberately thrown at hero are handled by m_throw) */ - potionhit(u.umonst, obj, POTHIT_OTHER_THROW); + potionhit(&gy.youmonst, obj, POTHIT_OTHER_THROW); *objp = obj = 0; /* potionhit() uses up the potion */ } else { if (obj && objects[obj->otyp].oc_material == SILVER @@ -184,7 +184,7 @@ drop_throw( if (!(broken = flooreffects(obj, x, y, "fall"))) { place_object(obj, x, y); if (!mtmp && u_at(x, y)) - mtmp = u.umonst; + mtmp = &gy.youmonst; if (mtmp && ohit) passive_obj(mtmp, obj, (struct attack *) 0); stackobj(obj); @@ -508,7 +508,7 @@ ucatchgem( struct monst *mon) { /* won't catch rock or gray stone; catch (then drop) worthless glass */ - if (gem->otyp <= LAST_GLASS_GEM && is_unicorn(u.umonst->data)) { + if (gem->otyp <= LAST_GLASS_GEM && is_unicorn(gy.youmonst.data)) { char *gem_xname = xname(gem), *mon_s_name = s_suffix(mon_nam(mon)); @@ -537,7 +537,7 @@ u_catch_thrown_obj(struct obj *otmp) if (!Blind && !Confusion && !Stunned && !Fumbling && otmp->oclass != VENOM_CLASS - && !nohands(u.umonst->data) && freehand() + && !nohands(gy.youmonst.data) && freehand() && calc_capacity(otmp->owt) <= SLT_ENCUMBER && !rn2(catch_chance)) { char buf[BUFSZ]; @@ -696,7 +696,7 @@ m_throw( break; if (singleobj->oclass == POTION_CLASS) { - potionhit(u.umonst, singleobj, POTHIT_MONST_THROW); + potionhit(&gy.youmonst, singleobj, POTHIT_MONST_THROW); break; } oldumort = u.umortality; @@ -719,7 +719,7 @@ m_throw( { int dam, hitv; - dam = dmgval(singleobj, u.umonst); + dam = dmgval(singleobj, &gy.youmonst); hitv = 3 - distmin(u.ux, u.uy, mon->mx, mon->my); if (hitv < -4) hitv = -4; @@ -732,7 +732,7 @@ m_throw( if (singleobj->otyp == ELVEN_ARROW) dam++; } - if (bigmonst(u.umonst->data)) + if (bigmonst(gy.youmonst.data)) hitv++; hitv += 8 + singleobj->spe; if (dam < 1) @@ -752,7 +752,7 @@ m_throw( poison is limited to attrib loss */ (u.umortality > oldumort) ? 0 : 10, TRUE); } - if (hitu && can_blnd((struct monst *) 0, u.umonst, + if (hitu && can_blnd((struct monst *) 0, &gy.youmonst, (uchar) ((singleobj->otyp == BLINDING_VENOM) ? AT_SPIT : AT_WEAP), @@ -767,7 +767,7 @@ m_throw( } else if (singleobj->otyp == BLINDING_VENOM) { const char *eyes = body_part(EYE); - if (eyecount(u.umonst->data) != 1) + if (eyecount(gy.youmonst.data) != 1) eyes = makeplural(eyes); /* venom in the eyes */ if (!Blind) @@ -778,7 +778,7 @@ m_throw( } if (hitu && singleobj->otyp == EGG) { if (!Stoned && !Stone_resistance - && !(poly_when_stoned(u.umonst->data) + && !(poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM))) { make_stoned(5L, (char *) 0, KILLED_BY, ""); } @@ -1030,7 +1030,7 @@ spitmm(struct monst *mtmp, struct attack *mattk, struct monst *mtarg) return M_ATTK_MISS; } if (m_lined_up(mtarg, mtmp)) { - boolean utarg = (mtarg == u.umonst); + boolean utarg = (mtarg == &gy.youmonst); coordxy tx = utarg ? mtmp->mux : mtarg->mx; coordxy ty = utarg ? mtmp->muy : mtarg->my; @@ -1093,7 +1093,7 @@ int breamm(struct monst *mtmp, struct attack *mattk, struct monst *mtarg) { int typ = get_atkdam_type(mattk->adtyp); - boolean utarget = (mtarg == u.umonst); + boolean utarget = (mtarg == &gy.youmonst); if (m_lined_up(mtarg, mtmp)) { if (mtmp->mcan) { @@ -1225,11 +1225,11 @@ thrwmu(struct monst *mtmp) obj_is_pname(otmp) ? the(onm) : an(onm)); } - dam = dmgval(otmp, u.umonst); + dam = dmgval(otmp, &gy.youmonst); hitv = 3 - distmin(u.ux, u.uy, mtmp->mx, mtmp->my); if (hitv < -4) hitv = -4; - if (bigmonst(u.umonst->data)) + if (bigmonst(gy.youmonst.data)) hitv++; hitv += 8 + otmp->spe; if (dam < 1) @@ -1267,14 +1267,14 @@ thrwmu(struct monst *mtmp) int spitmu(struct monst *mtmp, struct attack *mattk) { - return spitmm(mtmp, mattk, u.umonst); + return spitmm(mtmp, mattk, &gy.youmonst); } /* monster breathes at you (ranged) */ int breamu(struct monst *mtmp, struct attack *mattk) { - return breamm(mtmp, mattk, u.umonst); + return breamm(mtmp, mattk, &gy.youmonst); } /* return TRUE if terrain at x,y blocks linedup checks */ @@ -1375,7 +1375,7 @@ linedup( staticfn int m_lined_up(struct monst *mtarg, struct monst *mtmp) { - boolean utarget = (mtarg == u.umonst); + boolean utarget = (mtarg == &gy.youmonst); coordxy tx = utarget ? mtmp->mux : mtarg->mx; coordxy ty = utarget ? mtmp->muy : mtarg->my; boolean ignore_boulders = utarget && (throws_rocks(mtmp->data) @@ -1397,7 +1397,7 @@ m_lined_up(struct monst *mtarg, struct monst *mtmp) boolean lined_up(struct monst *mtmp) { - return m_lined_up(u.umonst, mtmp) ? TRUE : FALSE; + return m_lined_up(&gy.youmonst, mtmp) ? TRUE : FALSE; } /* check if a monster is carrying an item of a particular type */ @@ -1406,7 +1406,7 @@ m_carrying(struct monst *mtmp, int type) { struct obj *otmp; - for (otmp = (mtmp == u.umonst) ? gi.invent : mtmp->minvent; otmp; + for (otmp = (mtmp == &gy.youmonst) ? gi.invent : mtmp->minvent; otmp; otmp = otmp->nobj) if (otmp->otyp == type) break; diff --git a/src/muse.c b/src/muse.c index 07cc865da..78b61c10b 100644 --- a/src/muse.c +++ b/src/muse.c @@ -252,7 +252,7 @@ mreadmsg(struct monst *mtmp, struct obj *otmp) pline_mon(mtmp, "%s reads %s!", Monnam(mtmp), onambuf); } else { /* !Deaf, otherwise we wouldn't reach here */ char blindbuf[BUFSZ]; - boolean similar = same_race(u.umonst->data, mtmp->data), + boolean similar = same_race(gy.youmonst.data, mtmp->data), uniqmon = ((mtmp->data->geno & G_UNIQ) != 0 /* shopkeepers aren't unique monsters but since they have distinct names, treat them as such */ @@ -1565,8 +1565,8 @@ find_offensive(struct monst *mtmp) } nomore(MUSE_CAMERA); if (obj->otyp == EXPENSIVE_CAMERA - && ((!Blind && !resists_blnd(u.umonst)) - || hates_light(u.umonst->data)) + && ((!Blind && !resists_blnd(&gy.youmonst)) + || hates_light(gy.youmonst.data)) && dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 2 && obj->spe > 0 && !rn2(6)) { gm.m.offensive = obj; @@ -1598,7 +1598,7 @@ mbhitm(struct monst *mtmp, struct obj *otmp) { int tmp; boolean reveal_invis = FALSE, learnit = FALSE, - hits_you = (mtmp == u.umonst); + hits_you = (mtmp == &gy.youmonst); if (!hits_you && otmp->otyp != WAN_UNDEAD_TURNING) { mtmp->msleeping = 0; @@ -1761,7 +1761,7 @@ mbhit( break; } if (u_at(gb.bhitpos.x, gb.bhitpos.y)) { - (*fhitm)(u.umonst, obj); + (*fhitm)(&gy.youmonst, obj); range -= 3; } else if ((mtmp = m_at(gb.bhitpos.x, gb.bhitpos.y)) != 0) { if (cansee(gb.bhitpos.x, gb.bhitpos.y) && !canspotmon(mtmp)) @@ -1944,7 +1944,7 @@ use_offensive(struct monst *mtmp) Monnam(mtmp), an(xname(otmp))); } gm.m_using = TRUE; - if (!Blind && !resists_blnd(u.umonst)) { + if (!Blind && !resists_blnd(&gy.youmonst)) { You("are blinded by the flash of light!"); make_blinded(BlindedTimeout + (long) rnd(1 + 50), FALSE); } @@ -2857,7 +2857,7 @@ ureflects(const char *fmt, const char *str) if (fmt && str) pline(fmt, str, uskin ? "luster" : "armor"); return TRUE; - } else if (u.umonst->data == &mons[PM_SILVER_DRAGON]) { + } else if (gy.youmonst.data == &mons[PM_SILVER_DRAGON]) { if (fmt && str) pline(fmt, str, "scales"); return TRUE; diff --git a/src/music.c b/src/music.c index 7034577a5..21614860d 100644 --- a/src/music.c +++ b/src/music.c @@ -165,7 +165,7 @@ awaken_soldiers(struct monst *bugler /* monster that played instrument */) int distance, distm; /* distance of affected non-soldier monsters to bugler */ - distance = ((bugler == u.umonst) ? u.ulevel + distance = ((bugler == &gy.youmonst) ? u.ulevel : bugler->data->mlevel) * 30; for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { @@ -182,7 +182,7 @@ awaken_soldiers(struct monst *bugler /* monster that played instrument */) else if (!Deaf) Norep("%s the rattle of battle gear being readied.", "You hear"); /* Deaf-aware */ - } else if ((distm = ((bugler == u.umonst) + } else if ((distm = ((bugler == &gy.youmonst) ? mdistu(mtmp) : dist2(bugler->mx, bugler->my, mtmp->mx, mtmp->my))) < distance) { @@ -301,7 +301,7 @@ do_pit(coordxy x, coordxy y, unsigned tu_pit) Your("chain breaks!"); reset_utrap(TRUE); } - if (Levitation || Flying || is_clinger(u.umonst->data)) { + if (Levitation || Flying || is_clinger(gy.youmonst.data)) { if (!tu_pit) { /* no pit here previously */ pline("A chasm opens up under you!"); You("don't fall in!"); @@ -327,8 +327,8 @@ do_pit(coordxy x, coordxy y, unsigned tu_pit) if (keepfooting) exercise(A_DEX, TRUE); else - selftouch((Upolyd && (slithy(u.umonst->data) - || nolimbs(u.umonst->data))) + selftouch((Upolyd && (slithy(gy.youmonst.data) + || nolimbs(gy.youmonst.data))) ? "Shaken, you" : "Falling down, you"); } @@ -653,7 +653,7 @@ do_improvisation(struct obj *instr) else You("blow into the bugle."); Hero_playnotes(obj_to_instr(&itmp), improvisation, 80); - awaken_soldiers(u.umonst); + awaken_soldiers(&gy.youmonst); exercise(A_WIS, FALSE); break; case MAGIC_HARP: /* Charm monsters */ @@ -769,7 +769,7 @@ do_play_instrument(struct obj *instr) } else if ((instr->otyp == WOODEN_FLUTE || instr->otyp == MAGIC_FLUTE || instr->otyp == TOOLED_HORN || instr->otyp == FROST_HORN || instr->otyp == FIRE_HORN || instr->otyp == BUGLE) - && !can_blow(u.umonst)) { + && !can_blow(&gy.youmonst)) { You("are incapable of playing %s.", thesimpleoname(instr)); return ECMD_OK; } diff --git a/src/pager.c b/src/pager.c index ac8b5f61e..82b8bc7eb 100644 --- a/src/pager.c +++ b/src/pager.c @@ -121,7 +121,7 @@ self_lookat(char *outbuf) Sprintf(eos(outbuf), ", mounted on %s", y_monnam(u.usteed)); if (u.uundetected || (Upolyd && U_AP_TYPE) || visible_region_at(u.ux, u.uy)) - mhidden_description(u.umonst, + mhidden_description(&gy.youmonst, MHID_PREFIX | MHID_ARTICLE | MHID_REGION, eos(outbuf)); if (Punished) @@ -196,7 +196,7 @@ mhidden_description( incl_article = (mhid_flags & MHID_ARTICLE) != 0, show_altmon = (mhid_flags & MHID_ALTMON) != 0, force_region = (mhid_flags & MHID_REGION) != 0; - boolean fakeobj, isyou = (mon == u.umonst); + boolean fakeobj, isyou = (mon == &gy.youmonst); coordxy x = isyou ? u.ux : mon->mx, y = isyou ? u.uy : mon->my; int glyph = (svl.level.flags.hero_memory && !isyou) ? levl[x][y].glyph : glyph_at(x, y); @@ -446,7 +446,7 @@ look_at_monster( Strcat(buf, digests(mtmp->data) ? ", swallowing you" : ", engulfing you"); else - Strcat(buf, (Upolyd && sticks(u.umonst->data)) + Strcat(buf, (Upolyd && sticks(gy.youmonst.data)) ? ", being held" : ", holding you"); } /* if mtmp isn't able to move (other than because it is a type of @@ -1167,7 +1167,7 @@ add_cmap_descr( /* grab a scratch buffer we can safely return (via *firstmatch when applicable) */ - mbuf = mon_nam(u.umonst); + mbuf = mon_nam(&gy.youmonst); if (absidx == S_pool) { levl[cc.x][cc.y].typ = (idx == S_pool) ? POOL : MOAT; diff --git a/src/pickup.c b/src/pickup.c index 5cc2fbcef..2cb66dab3 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -287,7 +287,7 @@ fatal_corpse_mistake(struct obj *obj, boolean remotely) if (u_safe_from_fatal_corpse(obj, st_all) || remotely) return FALSE; - if (poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM)) { + if (poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM)) { display_nhwindow(WIN_MESSAGE, FALSE); /* --More-- */ return FALSE; } @@ -723,9 +723,9 @@ pickup(int what) /* should be a long */ */ if ((gm.multi && !svc.context.run) || (autopickup && !flags.pickup) - || notake(u.umonst->data)) { + || notake(gy.youmonst.data)) { check_here(FALSE); - if (notake(u.umonst->data) && OBJ_AT(u.ux, u.uy) + if (notake(gy.youmonst.data) && OBJ_AT(u.ux, u.uy) && (autopickup || flags.pickup)) You("are physically incapable of picking anything up."); return 0; @@ -892,8 +892,8 @@ pickup(int what) /* should be a long */ } if (!u.uswallow) { - if (hides_under(u.umonst->data)) - (void) hideunder(u.umonst); + if (hides_under(gy.youmonst.data)) + (void) hideunder(&gy.youmonst); /* position may need updating (invisible hero) */ if (n_picked) @@ -1155,7 +1155,7 @@ query_objlist(const char *qstr, /* query string */ fake_hero_object = cg.zeroobj; fake_hero_object.quan = 1L; /* not strictly necessary... */ any.a_obj = &fake_hero_object; - tmpglyph = mon_to_glyph(u.umonst, rn2_on_display_rng); + tmpglyph = mon_to_glyph(&gy.youmonst, rn2_on_display_rng); map_glyphinfo(0, 0, tmpglyph, 0U, &tmpglyphinfo); add_menu(win, &tmpglyphinfo, &any, /* fake inventory letter, no group accelerator */ @@ -1719,7 +1719,7 @@ lift_object( and for boulder picked up by hero poly'd into a giant; override availability of open inventory slot iff not already carrying one */ if (obj->otyp == LOADSTONE - || (obj->otyp == BOULDER && throws_rocks(u.umonst->data))) { + || (obj->otyp == BOULDER && throws_rocks(gy.youmonst.data))) { if (inv_cnt(FALSE) < invlet_basic || !carrying(obj->otyp) || merge_choice(gi.invent, obj)) return 1; /* lift regardless of current situation */ @@ -1823,7 +1823,7 @@ pickup_object( && engulfing_u(obj->ocarry)) { You_cant("pick %s up.", ysimple_name(obj)); return 0; - } else if (obj->oartifact && !touch_artifact(obj, u.umonst)) { + } else if (obj->oartifact && !touch_artifact(obj, &gy.youmonst)) { return 0; } else if (obj->otyp == CORPSE) { if (fatal_corpse_mistake(obj, telekinesis) @@ -1989,7 +1989,7 @@ encumber_msg(void) break; case 3: You("%s under your heavy load. Movement is very hard.", - stagger(u.umonst->data, "stagger")); + stagger(gy.youmonst.data, "stagger")); break; default: You("%s move a handspan with this load!", @@ -2010,7 +2010,7 @@ encumber_msg(void) break; case 3: You("%s under your load. Movement is still very hard.", - stagger(u.umonst->data, "stagger")); + stagger(gy.youmonst.data, "stagger")); break; } disp.botl = TRUE; @@ -2057,7 +2057,7 @@ able_to_loot( You("cannot %s things that are deep in the %s.", verb, hliquid(is_lava(x, y) ? "lava" : "water")); return FALSE; - } else if (nolimbs(u.umonst->data)) { + } else if (nolimbs(gy.youmonst.data)) { pline("Without limbs, you cannot %s anything.", verb); return FALSE; } else if (looting && !freehand()) { @@ -2195,7 +2195,7 @@ doloot_core(void) /* "Can't do that while carrying so much stuff." */ return ECMD_OK; } - if (nohands(u.umonst->data)) { + if (nohands(gy.youmonst.data)) { You("have no hands!"); /* not `body_part(HAND)' */ return ECMD_OK; } @@ -2446,7 +2446,7 @@ loot_mon(struct monst *mtmp, int *passed_info, boolean *prev_loot) x_monnam(mtmp, ARTICLE_THE, (char *) 0, SUPPRESS_SADDLE, FALSE)); if ((c = yn_function(qbuf, ynqchars, 'n', TRUE)) == 'y') { - if (nolimbs(u.umonst->data)) { + if (nolimbs(gy.youmonst.data)) { You_cant("do that without limbs."); /* not body_part(HAND) */ return 0; } @@ -2738,7 +2738,7 @@ out_container(struct obj *obj) obj->owt = weight(obj); } - if (obj->oartifact && !touch_artifact(obj, u.umonst)) + if (obj->oartifact && !touch_artifact(obj, &gy.youmonst)) return 0; if (fatal_corpse_mistake(obj, FALSE)) @@ -2942,7 +2942,7 @@ explain_container_prompt(boolean more_containers) boolean u_handsy(void) { - if (nohands(u.umonst->data)) { + if (nohands(gy.youmonst.data)) { You("have no hands!"); /* not `body_part(HAND)' */ return FALSE; } else if (!freehand()) { diff --git a/src/pline.c b/src/pline.c index c8d61b09d..79dd8b28b 100644 --- a/src/pline.c +++ b/src/pline.c @@ -139,7 +139,7 @@ pline_mon(struct monst *mtmp, const char *line, ...) { va_list the_args; - if (mtmp == u.umonst) + if (mtmp == &gy.youmonst) set_msg_xy(0, 0); else set_msg_xy(mtmp->mx, mtmp->my); diff --git a/src/polyself.c b/src/polyself.c index db3824bb4..ff9a69e65 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -5,8 +5,8 @@ /* * Polymorph self routine. * - * Note: the light source handling code assumes that u.umonst->m_id - * always remains 1 and u.umonst->mx will always remain 0 when it handles + * Note: the light source handling code assumes that gy.youmonst.m_id + * always remains 1 and gy.youmonst.mx will always remain 0 when it handles * the case of the player polymorphed into a light-emitting monster. * * Transformation sequences: @@ -33,24 +33,24 @@ staticfn void polysense(void); static const char no_longer_petrify_resistant[] = "No longer petrify-resistant, you"; -/* update the u.umonst->data structure pointer and intrinsics */ +/* update the gy.youmonst.data structure pointer and intrinsics */ void set_uasmon(void) { struct permonst *mdat = &mons[u.umonnum]; - boolean was_vampshifter = valid_vampshiftform(u.umonst->cham, u.umonnum); + boolean was_vampshifter = valid_vampshiftform(gy.youmonst.cham, u.umonnum); - set_mon_data(u.umonst, mdat); - u.umonst->m_id = 1; + set_mon_data(&gy.youmonst, mdat); + gy.youmonst.m_id = 1; if (Protection_from_shape_changers) - u.umonst->cham = NON_PM; - else if (is_vampire(u.umonst->data)) - u.umonst->cham = u.umonst->mnum; + gy.youmonst.cham = NON_PM; + else if (is_vampire(gy.youmonst.data)) + gy.youmonst.cham = gy.youmonst.mnum; /* assume hero-as-chameleon/doppelganger/sandestin doesn't change shape */ else if (!was_vampshifter) - u.umonst->cham = NON_PM; - u.mcham = u.umonst->cham; /* for save/restore since u.umonst isn't */ + gy.youmonst.cham = NON_PM; + u.mcham = gy.youmonst.cham; /* for save/restore since youmonst isn't */ #define PROPSET(PropIndx, ON) \ do { \ @@ -59,7 +59,7 @@ set_uasmon(void) else \ u.uprops[PropIndx].intrinsic &= ~FROMFORM; \ } while (0) -#define resist_from_form(MRtyp) ((u.umonst->data->mresists & (MRtyp)) != 0) +#define resist_from_form(MRtyp) ((gy.youmonst.data->mresists & (MRtyp)) != 0) PROPSET(FIRE_RES, resist_from_form(MR_FIRE)); PROPSET(COLD_RES, resist_from_form( MR_COLD)); @@ -74,7 +74,7 @@ set_uasmon(void) struct obj *save_uwep = uwep; uwep = 0; - PROPSET(DRAIN_RES, resists_drli(u.umonst)); + PROPSET(DRAIN_RES, resists_drli(&gy.youmonst)); uwep = save_uwep; } /* resists_magm() takes wielded, worn, and carried equipment into @@ -174,7 +174,7 @@ check_strangling(boolean on) /* when Strangled is already set, polymorphing from one vulnerable form into another causes the counter to be reset */ if (uamul && uamul->otyp == AMULET_OF_STRANGULATION - && can_be_strangled(u.umonst)) { + && can_be_strangled(&gy.youmonst)) { Strangled = 6L; disp.botl = TRUE; Your("%s %s your %s!", simpleonames(uamul), @@ -185,7 +185,7 @@ check_strangling(boolean on) /* off -- maybe block strangling */ } else { - if (Strangled && !can_be_strangled(u.umonst)) { + if (Strangled && !can_be_strangled(&gy.youmonst)) { Strangled = 0L; disp.botl = TRUE; You("are no longer being strangled."); @@ -199,7 +199,7 @@ DISABLE_WARNING_FORMAT_NONLITERAL staticfn void polyman(const char *fmt, const char *arg) { - boolean sticking = (sticks(u.umonst->data) && u.ustuck && !u.uswallow), + boolean sticking = (sticks(gy.youmonst.data) && u.ustuck && !u.uswallow), was_mimicking = (U_AP_TYPE != M_AP_NOTHING); boolean was_blind = !!Blind, had_see_invis = !!See_invisible; @@ -223,8 +223,8 @@ polyman(const char *fmt, const char *arg) if (was_mimicking) { if (gm.multi < 0) unmul(""); - u.umonst->m_ap_type = M_AP_NOTHING; - u.umonst->mappearance = 0; + gy.youmonst.m_ap_type = M_AP_NOTHING; + gy.youmonst.mappearance = 0; } newsym(u.ux, u.uy); @@ -249,7 +249,7 @@ polyman(const char *fmt, const char *arg) if (!!See_invisible ^ had_see_invis) set_mimic_blocking(); /* See_invisible just toggled */ - if (u.twoweap && !could_twoweap(u.umonst->data)) + if (u.twoweap && !could_twoweap(gy.youmonst.data)) untwoweapon(); if (u.utrap && u.utraptype == TT_PIT) { @@ -279,8 +279,8 @@ change_sex(void) * may be true for certain roles */ if (!Upolyd - || (!is_male(u.umonst->data) && !is_female(u.umonst->data) - && !is_neuter(u.umonst->data))) + || (!is_male(gy.youmonst.data) && !is_female(gy.youmonst.data) + && !is_neuter(gy.youmonst.data))) flags.female = !flags.female; if (Upolyd) /* poly'd: also change saved sex */ u.mfemale = !u.mfemale; @@ -476,8 +476,8 @@ polyself(int psflags) formrevert = ((psflags & POLY_REVERT) != 0), draconian = (uarm && Is_dragon_armor(uarm)), iswere = (ismnum(u.ulycn)), - isvamp = (is_vampire(u.umonst->data) - || is_vampshifter(u.umonst)), + isvamp = (is_vampire(gy.youmonst.data) + || is_vampshifter(&gy.youmonst)), controllable_poly = Polymorph_control && !(Stunned || Unaware); if (Unchanging) { @@ -494,11 +494,11 @@ polyself(int psflags) return; } } - old_light = emits_light(u.umonst->data); + old_light = emits_light(gy.youmonst.data); mntmp = NON_PM; if (formrevert) { - mntmp = u.umonst->cham; + mntmp = gy.youmonst.cham; monsterpoly = TRUE; controllable_poly = FALSE; } @@ -670,13 +670,13 @@ polyself(int psflags) } else if (isvamp) { do_vampyr: if (mntmp < LOW_PM || (mons[mntmp].geno & G_UNIQ)) { - mntmp = (u.umonst->data == &mons[PM_VAMPIRE_LEADER] + mntmp = (gy.youmonst.data == &mons[PM_VAMPIRE_LEADER] && !rn2(10)) ? PM_WOLF : !rn2(4) ? PM_FOG_CLOUD : PM_VAMPIRE_BAT; - if (ismnum(u.umonst->cham) - && !is_vampire(u.umonst->data) && !rn2(2)) - mntmp = u.umonst->cham; + if (ismnum(gy.youmonst.cham) + && !is_vampire(gy.youmonst.data) && !rn2(2)) + mntmp = gy.youmonst.cham; } if (controllable_poly) { Sprintf(buf, "Become %s?", @@ -718,15 +718,15 @@ polyself(int psflags) gs.sex_change_ok--; /* reset */ made_change: - new_light = emits_light(u.umonst->data); + new_light = emits_light(gy.youmonst.data); if (old_light != new_light) { if (old_light) - del_light_source(LS_MONSTER, monst_to_any(u.umonst)); + del_light_source(LS_MONSTER, monst_to_any(&gy.youmonst)); if (new_light == 1) ++new_light; /* otherwise it's undetectable */ if (new_light) new_light_source(u.ux, u.uy, new_light, LS_MONSTER, - monst_to_any(u.umonst)); + monst_to_any(&gy.youmonst)); } } @@ -735,9 +735,9 @@ int polymon(int mntmp) { char buf[BUFSZ], ustuckNam[BUFSZ]; - boolean sticking = sticks(u.umonst->data) && u.ustuck && !u.uswallow, + boolean sticking = sticks(gy.youmonst.data) && u.ustuck && !u.uswallow, was_blind = !!Blind, dochange = FALSE, was_expelled = FALSE, - was_hiding_under = u.uundetected && hides_under(u.umonst->data); + was_hiding_under = u.uundetected && hides_under(gy.youmonst.data); int mlvl, newMaxStr; if (svm.mvitals[mntmp].mvflags & G_GENOD) { /* allow G_EXTINCT */ @@ -774,13 +774,13 @@ polymon(int mntmp) /* if stuck mimicking gold, stop immediately */ if (gm.multi < 0 && U_AP_TYPE == M_AP_OBJECT - && u.umonst->data->mlet != S_MIMIC) + && gy.youmonst.data->mlet != S_MIMIC) unmul(""); /* if becoming a non-mimic, stop mimicking anything */ if (mons[mntmp].mlet != S_MIMIC) { /* as in polyman() */ - u.umonst->m_ap_type = M_AP_NOTHING; - u.umonst->mappearance = 0; + gy.youmonst.m_ap_type = M_AP_NOTHING; + gy.youmonst.mappearance = 0; } if (is_male(&mons[mntmp])) { if (flags.female) @@ -840,7 +840,7 @@ polymon(int mntmp) You("no longer feel sick."); } if (Slimed) { - if (flaming(u.umonst->data)) { + if (flaming(gy.youmonst.data)) { make_slimed(0L, "The slime burns away!"); } else if (mntmp == PM_GREEN_SLIME) { /* do it silently */ @@ -848,7 +848,7 @@ polymon(int mntmp) } } check_strangling(FALSE); /* maybe stop strangling */ - if (nohands(u.umonst->data)) + if (nohands(gy.youmonst.data)) make_glib(0); /* @@ -857,9 +857,9 @@ polymon(int mntmp) * "experience level of you as a monster" for a polymorphed character. */ mlvl = (int) mons[mntmp].mlevel; - if (u.umonst->data->mlet == S_DRAGON && mntmp >= PM_GRAY_DRAGON) { + if (gy.youmonst.data->mlet == S_DRAGON && mntmp >= PM_GRAY_DRAGON) { u.mhmax = In_endgame(&u.uz) ? (8 * mlvl) : (4 * mlvl + d(mlvl, 4)); - } else if (is_golem(u.umonst->data)) { + } else if (is_golem(gy.youmonst.data)) { u.mhmax = golemhp(mntmp); } else { if (!mlvl) @@ -891,7 +891,7 @@ polymon(int mntmp) /* if hiding under something and can't hide anymore, unhide now; but don't auto-hide when not already hiding-under */ if (was_hiding_under) - (void) hideunder(u.umonst); + (void) hideunder(&gy.youmonst); if (u.utrap && u.utraptype == TT_PIT) { set_utrap(rn1(6, 2), TT_PIT); /* time to escape resets */ @@ -904,7 +904,7 @@ polymon(int mntmp) /* you now know what an egg of your type looks like; [moved from below in case expels() -> spoteffects() drops hero onto any eggs] */ - if (lays_eggs(u.umonst->data)) { + if (lays_eggs(gy.youmonst.data)) { learn_egg_type(u.umonnum); /* make queen bees recognize killer bee eggs */ learn_egg_type(egg_type_from_parent(u.umonnum, TRUE)); @@ -914,13 +914,13 @@ polymon(int mntmp) uchar usiz; /* if new form can't be swallowed, make engulfer expel hero */ - if (unsolid(u.umonst->data) + if (unsolid(gy.youmonst.data) /* subset of engulf_target() */ - || (usiz = u.umonst->data->msize) >= MZ_HUGE + || (usiz = gy.youmonst.data->msize) >= MZ_HUGE || (u.ustuck->data->msize < usiz && !is_whirly(u.ustuck->data))) { boolean expels_mesg = TRUE; - if (unsolid(u.umonst->data)) { + if (unsolid(gy.youmonst.data)) { if (canspotmon(u.ustuck)) /* [see below for explanation] */ Strcpy(ustuckNam, Monnam(u.ustuck)); pline("%s can no longer contain you.", ustuckNam); @@ -939,7 +939,7 @@ polymon(int mntmp) /* being held; if now capable of holding, make holder release so that hero doesn't automagically start holding it; or, release if no longer capable of being held */ - && (sticks(u.umonst->data) || unsolid(u.umonst->data))) { + && (sticks(gy.youmonst.data) || unsolid(gy.youmonst.data))) { /* u.ustuck name was saved above in case we're changing from can-see to can't-see; but might have changed from can't-see to can-see so override here if hero knows who u.ustuck is */ @@ -947,7 +947,7 @@ polymon(int mntmp) Strcpy(ustuckNam, Monnam(u.ustuck)); set_ustuck((struct monst *) 0); pline("%s loses its grip on you.", ustuckNam); - } else if (sticking && !sticks(u.umonst->data)) { + } else if (sticking && !sticks(gy.youmonst.data)) { /* was holding onto u.ustuck but no longer capable of that */ uunstick(); } @@ -982,13 +982,13 @@ polymon(int mntmp) buried_ball_to_freedom(); } reset_utrap(TRUE); - } else if (likes_lava(u.umonst->data) && u.utrap + } else if (likes_lava(gy.youmonst.data) && u.utrap && u.utraptype == TT_LAVA) { pline_The("%s now feels soothing.", hliquid("lava")); reset_utrap(TRUE); } - if (amorphous(u.umonst->data) || is_whirly(u.umonst->data) - || unsolid(u.umonst->data)) { + if (amorphous(gy.youmonst.data) || is_whirly(gy.youmonst.data) + || unsolid(gy.youmonst.data)) { if (Punished) { You("slip out of the iron chain."); unpunish(); @@ -998,16 +998,16 @@ polymon(int mntmp) } } if (u.utrap && (u.utraptype == TT_WEB || u.utraptype == TT_BEARTRAP) - && (amorphous(u.umonst->data) || is_whirly(u.umonst->data) - || unsolid(u.umonst->data) - || (u.umonst->data->msize <= MZ_SMALL + && (amorphous(gy.youmonst.data) || is_whirly(gy.youmonst.data) + || unsolid(gy.youmonst.data) + || (gy.youmonst.data->msize <= MZ_SMALL && u.utraptype == TT_BEARTRAP))) { You("are no longer stuck in the %s.", u.utraptype == TT_WEB ? "web" : "bear trap"); /* probably should burn webs too if PM_FIRE_ELEMENTAL */ reset_utrap(TRUE); } - if (webmaker(u.umonst->data) && u.utrap && u.utraptype == TT_WEB) { + if (webmaker(gy.youmonst.data) && u.utrap && u.utraptype == TT_WEB) { You("orient yourself on the web."); reset_utrap(TRUE); } @@ -1031,7 +1031,7 @@ polymon(int mntmp) if (flags.verbose) { static const char use_thec[] = "Use the command #%s to %s."; static const char monsterc[] = "monster"; - struct permonst *uptr = u.umonst->data; + struct permonst *uptr = gy.youmonst.data; boolean might_hide = (is_hider(uptr) || hides_under(uptr)); if (can_breathe(uptr)) @@ -1058,7 +1058,7 @@ polymon(int mntmp) pline(use_thec, monsterc, "emit a mental blast"); if (uptr->msound == MS_SHRIEK) /* worthless, actually */ pline(use_thec, monsterc, "shriek"); - if (is_vampire(uptr) || is_vampshifter(u.umonst)) + if (is_vampire(uptr) || is_vampshifter(&gy.youmonst)) pline(use_thec, monsterc, "change shape"); if (lays_eggs(uptr) && flags.female @@ -1157,7 +1157,7 @@ staticfn void break_armor(void) { struct obj *otmp; - struct permonst *uptr = u.umonst->data; + struct permonst *uptr = gy.youmonst.data; if (breakarm(uptr)) { if ((otmp = uarm) != 0) { @@ -1196,7 +1196,7 @@ break_armor(void) useup(uarmu); } } else if (sliparm(uptr)) { - if ((otmp = uarm) != 0 && racial_exception(u.umonst, otmp) < 1) { + if ((otmp = uarm) != 0 && racial_exception(&gy.youmonst, otmp) < 1) { if (donning(otmp)) cancel_don(); Your("armor falls around you!"); @@ -1313,7 +1313,7 @@ drop_weapon(int alone) * future it might not be so if there are monsters which cannot * wear gloves but can wield weapons */ - if (!alone || cantwield(u.umonst->data)) { + if (!alone || cantwield(gy.youmonst.data)) { candropwep = canletgo(uwep, ""); candropswapwep = !u.twoweap || canletgo(uswapwep, ""); if (alone) { @@ -1355,7 +1355,7 @@ drop_weapon(int alone) if (updateinv) update_inventory(); - } else if (!could_twoweap(u.umonst->data)) { + } else if (!could_twoweap(gy.youmonst.data)) { untwoweapon(); } } @@ -1390,8 +1390,8 @@ rehumanize(void) * reverts to human rather than to vampire. */ - if (emits_light(u.umonst->data)) - del_light_source(LS_MONSTER, monst_to_any(u.umonst)); + if (emits_light(gy.youmonst.data)) + del_light_source(LS_MONSTER, monst_to_any(&gy.youmonst)); polyman("You return to %s form!", gu.urace.adj); if (u.uhp < 1) { @@ -1436,7 +1436,7 @@ dobreathe(void) if (!getdir((char *) 0)) return ECMD_CANCEL; - mattk = attacktype_fordmg(u.umonst->data, AT_BREA, AD_ANY); + mattk = attacktype_fordmg(gy.youmonst.data, AT_BREA, AD_ANY); if (!mattk) impossible("bad breath attack?"); /* mouthwash needed... */ else if (!u.dx && !u.dy && !u.dz) @@ -1454,7 +1454,7 @@ dospit(void) if (!getdir((char *) 0)) return ECMD_CANCEL; - mattk = attacktype_fordmg(u.umonst->data, AT_SPIT, AD_ANY); + mattk = attacktype_fordmg(gy.youmonst.data, AT_SPIT, AD_ANY); if (!mattk) { impossible("bad spit attack?"); } else { @@ -1633,7 +1633,7 @@ dosummon(void) You("call upon your brethren for help!"); exercise(A_WIS, TRUE); - if (!were_summon(u.umonst->data, TRUE, &placeholder, (char *) 0)) + if (!were_summon(gy.youmonst.data, TRUE, &placeholder, (char *) 0)) pline("But none arrive."); return ECMD_TIME; } @@ -1648,8 +1648,8 @@ dogaze(void) uchar adtyp = 0; for (i = 0; i < NATTK; i++) { - if (u.umonst->data->mattk[i].aatyp == AT_GAZE) { - adtyp = u.umonst->data->mattk[i].adtyp; + if (gy.youmonst.data->mattk[i].aatyp == AT_GAZE) { + adtyp = gy.youmonst.data->mattk[i].adtyp; break; } } @@ -1776,8 +1776,8 @@ dogaze(void) int dohide(void) { - boolean ismimic = u.umonst->data->mlet == S_MIMIC, - on_ceiling = is_clinger(u.umonst->data) || Flying; + boolean ismimic = gy.youmonst.data->mlet == S_MIMIC, + on_ceiling = is_clinger(gy.youmonst.data) || Flying; /* can't hide while being held (or holding) or while trapped (except for floor hiders [trapper or mimic] in pits) */ @@ -1786,19 +1786,19 @@ dohide(void) !u.ustuck ? "trapped" : u.uswallow ? (digests(u.ustuck->data) ? "swallowed" : "engulfed") - : !sticks(u.umonst->data) ? "being held" + : !sticks(gy.youmonst.data) ? "being held" : (humanoid(u.ustuck->data) ? "holding someone" : "holding that creature")); if (u.uundetected || (ismimic && U_AP_TYPE != M_AP_NOTHING)) { u.uundetected = 0; - u.umonst->m_ap_type = M_AP_NOTHING; + gy.youmonst.m_ap_type = M_AP_NOTHING; newsym(u.ux, u.uy); } return ECMD_OK; } /* note: hero-as-eel handling is incomplete but unnecessary; such critters aren't offered the option of hiding via #monster */ - if (u.umonst->data->mlet == S_EEL && !is_pool(u.ux, u.uy)) { + if (gy.youmonst.data->mlet == S_EEL && !is_pool(u.ux, u.uy)) { if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)) pline_The("fountain is not deep enough to hide in."); else @@ -1806,7 +1806,7 @@ dohide(void) u.uundetected = 0; return ECMD_OK; } - if (hides_under(u.umonst->data)) { + if (hides_under(gy.youmonst.data)) { long ct = 0L; struct obj *otmp, *otop = svl.level.objects[u.ux][u.uy]; @@ -1847,7 +1847,7 @@ dohide(void) u.uundetected = 0; return ECMD_OK; } - if ((is_hider(u.umonst->data) && !Flying) /* floor hider */ + if ((is_hider(gy.youmonst.data) && !Flying) /* floor hider */ && (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz))) { There("is nowhere to hide beneath you."); u.uundetected = 0; @@ -1864,8 +1864,8 @@ dohide(void) if (ismimic) { /* should bring up a dialog "what would you like to imitate?" */ - u.umonst->m_ap_type = M_AP_OBJECT; - u.umonst->mappearance = STRANGE_OBJECT; + gy.youmonst.m_ap_type = M_AP_OBJECT; + gy.youmonst.mappearance = STRANGE_OBJECT; } else u.uundetected = 1; newsym(u.ux, u.uy); @@ -1876,13 +1876,13 @@ dohide(void) int dopoly(void) { - struct permonst *savedat = u.umonst->data; + struct permonst *savedat = gy.youmonst.data; - if (is_vampire(u.umonst->data) || is_vampshifter(u.umonst)) { + if (is_vampire(gy.youmonst.data) || is_vampshifter(&gy.youmonst)) { polyself(POLY_MONSTER); - if (savedat != u.umonst->data) { + if (savedat != gy.youmonst.data) { You("transform into %s.", - an(pmname(u.umonst->data, Ugender))); + an(pmname(gy.youmonst.data, Ugender))); newsym(u.ux, u.uy); } } @@ -2142,7 +2142,7 @@ mbodypart(struct monst *mon, int part) const char * body_part(int part) { - return mbodypart(u.umonst, part); + return mbodypart(&gy.youmonst, part); } int @@ -2151,7 +2151,7 @@ poly_gender(void) /* Returns gender of polymorphed player; * 0/1=same meaning as flags.female, 2=none. */ - if (is_neuter(u.umonst->data) || !humanoid(u.umonst->data)) + if (is_neuter(gy.youmonst.data) || !humanoid(gy.youmonst.data)) return 2; return flags.female; } @@ -2276,9 +2276,9 @@ udeadinside(void) seems silly when you're polymorphed into something undead; monkilled() distinguishes between living (killed) and non (destroyed) for monster death message; we refine the nonliving aspect a bit */ - return !nonliving(u.umonst->data) + return !nonliving(gy.youmonst.data) ? "dead" /* living, including demons */ - : !weirdnonliving(u.umonst->data) + : !weirdnonliving(gy.youmonst.data) ? "condemned" /* undead plus manes */ : "empty"; /* golems plus vortices */ } diff --git a/src/potion.c b/src/potion.c index 3ac39333a..d56b64155 100644 --- a/src/potion.c +++ b/src/potion.c @@ -121,7 +121,7 @@ make_stunned(long xtime, boolean talk) if (u.usteed) You("wobble in the saddle."); else - You("%s...", stagger(u.umonst->data, "stagger")); + You("%s...", stagger(gy.youmonst.data, "stagger")); } } if ((!xtime && old) || (xtime && !old)) @@ -210,9 +210,9 @@ make_slimed(long xtime, const char *msg) dealloc_killer(find_delayed_killer(SLIMED)); /* fake appearance is set late in turn-to-slime countdown */ if (U_AP_TYPE == M_AP_MONSTER - && u.umonst->mappearance == PM_GREEN_SLIME) { - u.umonst->m_ap_type = M_AP_NOTHING; - u.umonst->mappearance = 0; + && gy.youmonst.mappearance == PM_GREEN_SLIME) { + gy.youmonst.m_ap_type = M_AP_NOTHING; + gy.youmonst.mappearance = 0; } } } @@ -284,11 +284,11 @@ make_blinded(long xtime, boolean talk) } else if (old && !xtime) { /* clearing temporary blindness without toggling blindness */ if (talk) { - if (!haseyes(u.umonst->data) || PermaBlind) { + if (!haseyes(gy.youmonst.data) || PermaBlind) { strange_feeling((struct obj *) 0, (char *) 0); } else if (Blindfolded) { eyes = body_part(EYE); - if (eyecount(u.umonst->data) != 1) + if (eyecount(gy.youmonst.data) != 1) eyes = makeplural(eyes); Your(eyemsg, eyes, vtense(eyes, "itch")); } else { /* Eyes of the Overworld */ @@ -310,11 +310,11 @@ make_blinded(long xtime, boolean talk) } else if (!old && xtime) { /* setting temporary blindness without toggling blindness */ if (talk) { - if (!haseyes(u.umonst->data) || PermaBlind) { + if (!haseyes(gy.youmonst.data) || PermaBlind) { strange_feeling((struct obj *) 0, (char *) 0); } else if (Blindfolded) { eyes = body_part(EYE); - if (eyecount(u.umonst->data) != 1) + if (eyecount(gy.youmonst.data) != 1) eyes = makeplural(eyes); Your(eyemsg, eyes, vtense(eyes, "twitch")); } else { /* Eyes of the Overworld */ @@ -397,12 +397,12 @@ make_hallucinated( /* clearing temporary hallucination without toggling vision */ if (!changed && !HHallucination && old && talk) { - if (!haseyes(u.umonst->data)) { + if (!haseyes(gy.youmonst.data)) { strange_feeling((struct obj *) 0, (char *) 0); } else if (Blind) { const char *eyes = body_part(EYE); - if (eyecount(u.umonst->data) != 1) + if (eyecount(gy.youmonst.data) != 1) eyes = makeplural(eyes); Your(eyemsg, eyes, vtense(eyes, "itch")); } else { /* Grayswandir */ @@ -723,7 +723,7 @@ peffect_water(struct obj *otmp) return; } gp.potion_unkn++; - if (mon_hates_blessings(u.umonst) /* undead or demon */ + if (mon_hates_blessings(&gy.youmonst) /* undead or demon */ || u.ualign.type == A_CHAOTIC) { if (otmp->blessed) { pline("This burns like %s!", hliquid("acid")); @@ -731,7 +731,7 @@ peffect_water(struct obj *otmp) if (ismnum(u.ulycn)) { Your("affinity to %s disappears!", makeplural(mons[u.ulycn].pmnames[NEUTRAL])); - if (u.umonst->data == &mons[u.ulycn]) + if (gy.youmonst.data == &mons[u.ulycn]) you_unwere(FALSE); set_ulycn(NON_PM); /* cure lycanthropy */ } @@ -1262,7 +1262,7 @@ peffect_oil(struct obj *otmp) boolean good_for_you = FALSE, vulnerable; if (otmp->lamplit) { - if (likes_fire(u.umonst->data)) { + if (likes_fire(gy.youmonst.data)) { pline("Ahh, a refreshing drink."); good_for_you = TRUE; } else { @@ -1620,12 +1620,12 @@ impact_arti_light( return; } -/* potion obj hits monster mon, which might be u.umonst; obj always used up */ +/* potion obj hits monster mon, which might be youmonst; obj always used up */ void potionhit(struct monst *mon, struct obj *obj, int how) { const char *botlnam = bottlename(); - boolean isyou = (mon == u.umonst); + boolean isyou = (mon == &gy.youmonst); int distance, tx, ty; struct obj *saddle = (struct obj *) 0; boolean hit_saddle = FALSE, your_fault = (how <= POTHIT_HERO_THROW); @@ -1905,7 +1905,7 @@ potionhit(struct monst *mon, struct obj *obj, int how) /* Note: potionbreathe() does its own docall() */ if ((distance == 0 || (distance < 3 && !rn2((1+ACURR(A_DEX))/2))) - && (!breathless(u.umonst->data) || haseyes(u.umonst->data))) + && (!breathless(gy.youmonst.data) || haseyes(gy.youmonst.data))) potionbreathe(obj); else if (obj->dknown && cansee(tx, ty)) trycall(obj); @@ -1950,12 +1950,12 @@ potionbreathe(struct obj *obj) case POT_RESTORE_ABILITY: case POT_GAIN_ABILITY: if (obj->cursed) { - if (!breathless(u.umonst->data)) { + if (!breathless(gy.youmonst.data)) { pline("Ulch! That potion smells terrible!"); - } else if (haseyes(u.umonst->data)) { + } else if (haseyes(gy.youmonst.data)) { const char *eyes = body_part(EYE); - if (eyecount(u.umonst->data) != 1) + if (eyecount(gy.youmonst.data) != 1) eyes = makeplural(eyes); Your("%s %s!", eyes, vtense(eyes, "sting")); } @@ -2079,11 +2079,11 @@ potionbreathe(struct obj *obj) break; case POT_WATER: if (u.umonnum == PM_GREMLIN) { - (void) split_mon(u.umonst, (struct monst *) 0); + (void) split_mon(&gy.youmonst, (struct monst *) 0); } else if (ismnum(u.ulycn)) { /* vapor from [un]holy water will trigger transformation but won't cure lycanthropy */ - if (obj->blessed && u.umonst->data == &mons[u.ulycn]) + if (obj->blessed && gy.youmonst.data == &mons[u.ulycn]) you_unwere(FALSE); else if (obj->cursed && !Upolyd) you_were(); @@ -2427,7 +2427,7 @@ dip_potion_explosion(struct obj *obj, int dmg) pline("%sThey explode!", !Deaf ? "BOOM! " : ""); wake_nearto(u.ux, u.uy, (BOLT_LIM + 1) * (BOLT_LIM + 1)); exercise(A_STR, FALSE); - if (!breathless(u.umonst->data) || haseyes(u.umonst->data)) + if (!breathless(gy.youmonst.data) || haseyes(gy.youmonst.data)) potionbreathe(obj); useupall(obj); losehp(dmg, /* not physical damage */ @@ -2880,10 +2880,10 @@ split_mon( reason[0] = '\0'; if (mtmp) Sprintf(reason, " from %s heat", - (mtmp == u.umonst) ? the_your[1] + (mtmp == &gy.youmonst) ? the_your[1] : (const char *) s_suffix(mon_nam(mtmp))); - if (mon == u.umonst) { + if (mon == &gy.youmonst) { if (u.mh > u.mhmax) /* sanity precaution */ u.mh = u.mhmax; mtmp2 = (u.mh > 1) ? cloneu() : (struct monst *) 0; diff --git a/src/pray.c b/src/pray.c index c008e3205..55e95e096 100644 --- a/src/pray.c +++ b/src/pray.c @@ -173,7 +173,7 @@ stuck_in_wall(void) if (!isok(x, y) || (IS_OBSTRUCTED(levl[x][y].typ) && (levl[x][y].typ != SDOOR && levl[x][y].typ != SCORR)) - || (blocked_boulder(i, j) && !throws_rocks(u.umonst->data))) + || (blocked_boulder(i, j) && !throws_rocks(gy.youmonst.data))) ++count; } } @@ -229,13 +229,13 @@ in_trouble(void) || stuck_ring(uleft, RIN_LEVITATION) || stuck_ring(uright, RIN_LEVITATION)) return TROUBLE_CURSED_LEVITATION; - if (nohands(u.umonst->data) || !freehand()) { + if (nohands(gy.youmonst.data) || !freehand()) { /* for bag/box access [cf use_container()]... make sure it's a case that we know how to handle; otherwise "fix all troubles" would get stuck in a loop */ if (welded(uwep)) return TROUBLE_UNUSEABLE_HANDS; - if (Upolyd && nohands(u.umonst->data) + if (Upolyd && nohands(gy.youmonst.data) && (!Unchanging || ((otmp = unchanger()) != 0 && otmp->cursed))) return TROUBLE_UNUSEABLE_HANDS; } @@ -494,7 +494,7 @@ fix_worst_trouble(int trouble) fix_curse_trouble(otmp, what); break; } - if (Upolyd && nohands(u.umonst->data)) { + if (Upolyd && nohands(gy.youmonst.data)) { if (!Unchanging) { Your("shape becomes uncertain."); rehumanize(); /* "You return to {normal} form." */ @@ -504,7 +504,7 @@ fix_worst_trouble(int trouble) break; } } - if (nohands(u.umonst->data) || !freehand()) + if (nohands(gy.youmonst.data) || !freehand()) impossible("fix_worst_trouble: couldn't cure hands."); break; case TROUBLE_CURSED_BLINDFOLD: @@ -559,7 +559,7 @@ fix_worst_trouble(int trouble) msgbuf[0] = '\0'; if (Blinded) { - if (eyecount(u.umonst->data) != 1) + if (eyecount(gy.youmonst.data) != 1) eyes = makeplural(eyes); Sprintf(msgbuf, "Your %s %s better", eyes, vtense(eyes, "feel")); u.ucreamed = 0; @@ -735,7 +735,7 @@ angrygods(aligntyp resp_god) (ugod_is_angry() && resp_god == u.ualign.type) ? "hast strayed from the path" : "art arrogant", - u.umonst->data->mlet == S_HUMAN ? "mortal" : "creature"); + gy.youmonst.data->mlet == S_HUMAN ? "mortal" : "creature"); SetVoice((struct monst *) 0, 0, 80, voice_deity); verbalize("Thou must relearn thy lessons!"); (void) adjattrib(A_WIS, -1, FALSE); @@ -767,7 +767,7 @@ angrygods(aligntyp resp_god) : "call upon"); /* [why isn't this using verbalize()?] */ pline("\"Then die, %s!\"", - (u.umonst->data->mlet == S_HUMAN) ? "mortal" : "creature"); + (gy.youmonst.data->mlet == S_HUMAN) ? "mortal" : "creature"); summon_minion(resp_god, FALSE); break; @@ -1224,7 +1224,7 @@ pleased(aligntyp g_align) if (u.uevent.uheard_tune < 1) { godvoice(g_align, (char *) 0); SetVoice((struct monst *) 0, 0, 80, voice_deity); - verbalize("Hark, %s!", is_human(u.umonst->data) + verbalize("Hark, %s!", is_human(gy.youmonst.data) ? "mortal" : "creature"); SetVoice((struct monst *) 0, 0, 80, voice_deity); @@ -1702,7 +1702,7 @@ sacrifice_your_race( { int pm; - if (is_demon(u.umonst->data)) { + if (is_demon(gy.youmonst.data)) { You("find the idea very satisfying."); exercise(A_WIS, TRUE); } else if (u.ualign.type != A_CHAOTIC) { @@ -2128,7 +2128,7 @@ can_pray(boolean praying) /* false means no messages should be given */ gp.p_aligntyp = on_altar() ? a_align(u.ux, u.uy) : u.ualign.type; gp.p_trouble = in_trouble(); - if (is_demon(u.umonst->data) /* ok if chaotic or none (Moloch) */ + if (is_demon(gy.youmonst.data) /* ok if chaotic or none (Moloch) */ && (gp.p_aligntyp == A_LAWFUL || gp.p_aligntyp != A_NEUTRAL)) { if (praying) pline_The("very idea of praying to a %s god is repugnant to you.", @@ -2161,7 +2161,7 @@ can_pray(boolean praying) /* false means no messages should be given */ gp.p_type = 3; } - if (is_undead(u.umonst->data) && !Inhell + if (is_undead(gy.youmonst.data) && !Inhell && (gp.p_aligntyp == A_LAWFUL || (gp.p_aligntyp == A_NEUTRAL && !rn2(10)))) gp.p_type = -1; @@ -2429,7 +2429,7 @@ doturn(void) Gname = halu_gname(u.ualign.type); /* [What about needing free hands (does #turn involve any gesturing)?] */ - if (!can_chant(u.umonst)) { + if (!can_chant(&gy.youmonst)) { /* "evilness": "demons and undead" is too verbose and too precise */ You("are %s upon %s to turn aside evilness.", Strangled ? "not able to call" : "incapable of calling", Gname); @@ -2439,8 +2439,8 @@ doturn(void) return (u.uconduct.gnostic == 1) ? ECMD_TIME : ECMD_OK; } if ((u.ualign.type != A_CHAOTIC - && (is_demon(u.umonst->data) - || is_undead(u.umonst->data) || is_vampshifter(u.umonst))) + && (is_demon(gy.youmonst.data) + || is_undead(gy.youmonst.data) || is_vampshifter(&gy.youmonst))) || u.ugangr > 6) { /* "Die, mortal!" */ pline("For some reason, %s seems to ignore you.", Gname); aggravate(); diff --git a/src/read.c b/src/read.c index e9b98eb31..b422ee082 100644 --- a/src/read.c +++ b/src/read.c @@ -610,7 +610,7 @@ doread(void) } scroll->in_use = TRUE; /* scroll, not spellbook, now being read */ if (otyp != SCR_BLANK_PAPER) { - boolean silently = !can_chant(u.umonst); + boolean silently = !can_chant(&gy.youmonst); /* a few scroll feedback messages describe something happening to the scroll itself, so avoid "it disappears" for those */ @@ -1118,7 +1118,7 @@ seffect_enchant_armor(struct obj **sobjp) schar s; boolean special_armor; boolean same_color; - struct obj *otmp = some_armor(u.umonst); + struct obj *otmp = some_armor(&gy.youmonst); boolean sblessed = sobj->blessed; boolean scursed = sobj->cursed; boolean confused = (Confusion != 0); @@ -1324,7 +1324,7 @@ staticfn void seffect_destroy_armor(struct obj **sobjp) { struct obj *sobj = *sobjp; - struct obj *otmp = some_armor(u.umonst); + struct obj *otmp = some_armor(&gy.youmonst); boolean scursed = sobj->cursed; boolean confused = (Confusion != 0); boolean old_erodeproof, new_erodeproof; @@ -1405,7 +1405,7 @@ seffect_confuse_monster(struct obj **sobjp) altfeedback = (Blind || Invisible); const char *const hands = makeplural(body_part(HAND)); - if (u.umonst->data->mlet != S_HUMAN || scursed) { + if (gy.youmonst.data->mlet != S_HUMAN || scursed) { if (!HConfusion) You_feel("confused."); make_confused(HConfusion + rnd(100), FALSE); @@ -2311,10 +2311,10 @@ drop_boulder_on_player( return; otmp2->quan = confused ? rn1(5, 2) : 1; otmp2->owt = weight(otmp2); - if (!amorphous(u.umonst->data) && !Passes_walls - && !noncorporeal(u.umonst->data) && !unsolid(u.umonst->data)) { + if (!amorphous(gy.youmonst.data) && !Passes_walls + && !noncorporeal(gy.youmonst.data) && !unsolid(gy.youmonst.data)) { You("are hit by %s!", doname(otmp2)); - dmg = (int) (dmgval(otmp2, u.umonst) * otmp2->quan); + dmg = (int) (dmgval(otmp2, &gy.youmonst) * otmp2->quan); if (uarmh && helmet_protects) { if (hard_helmet(uarmh)) { pline("Fortunately, you are wearing a hard helmet."); @@ -2749,9 +2749,9 @@ do_class_genocide(void) kill_genocided_monsters(); update_inventory(); /* eggs & tins */ pline("Wiped out all %s.", nam); - if (Upolyd && vampshifted(u.umonst) + if (Upolyd && vampshifted(&gy.youmonst) /* current shifted form or base vampire form */ - && (i == u.umonnum || i == u.umonst->cham)) + && (i == u.umonnum || i == gy.youmonst.cham)) polyself(POLY_REVERT); /* vampshifter to vampire */ if (Upolyd && i == u.umonnum) { u.mh = -1; @@ -2895,8 +2895,8 @@ do_genocide( } ptr = &mons[mndx]; /* first revert if current shifted form or base vampire form */ - if (Upolyd && vampshifted(u.umonst) - && (mndx == u.umonnum || mndx == u.umonst->cham)) + if (Upolyd && vampshifted(&gy.youmonst) + && (mndx == u.umonnum || mndx == gy.youmonst.cham)) polyself(POLY_REVERT); /* vampshifter (bat, &c) to vampire */ /* Although "genus" is Latin for race, the hero benefits * from both race and role; thus genocide affects either. @@ -2926,7 +2926,7 @@ do_genocide( continue; } /* KMH -- Unchanging prevents rehumanization */ - if (Unchanging && ptr == u.umonst->data) + if (Unchanging && ptr == gy.youmonst.data) killplayer++; break; } @@ -2938,7 +2938,7 @@ do_genocide( if (Hallucination) { /* hallucinate hero's type */ if (Upolyd) { - Strcpy(buf, pmname(u.umonst->data, + Strcpy(buf, pmname(gy.youmonst.data, flags.female ? FEMALE : MALE)); } else { Strcpy(buf, (flags.female && gu.urole.name.f) ? gu.urole.name.f @@ -2981,13 +2981,13 @@ do_genocide( /* Polymorphed characters will die as soon as they're rehumanized. KMH -- Unchanging prevents rehumanization. */ - if (Upolyd && ptr != u.umonst->data) { + if (Upolyd && ptr != gy.youmonst.data) { delayed_killer(POLYMORPH, svk.killer.format, svk.killer.name); You_feel("%s inside.", udeadinside()); } else { done(GENOCIDED); } - } else if (ptr == u.umonst->data) { + } else if (ptr == gy.youmonst.data) { rehumanize(); } kill_genocided_monsters(); @@ -3033,8 +3033,8 @@ punish(struct obj *sobj) uball->owt += WT_IRON_BALL_INCR * (1 + cursed_levy); return; } - if (amorphous(u.umonst->data) || is_whirly(u.umonst->data) - || unsolid(u.umonst->data)) { + if (amorphous(gy.youmonst.data) || is_whirly(gy.youmonst.data) + || unsolid(gy.youmonst.data)) { if (!reuse_ball) { pline("A ball and chain appears, then falls away."); dropy(mkobj(BALL_CLASS, TRUE)); diff --git a/src/region.c b/src/region.c index 938a3e2bf..796d48fc1 100644 --- a/src/region.c +++ b/src/region.c @@ -1092,7 +1092,7 @@ inside_gas_cloud(genericptr_t p1, genericptr_t p2) { NhRegion *reg = (NhRegion *) p1; struct monst *mtmp = (struct monst *) p2; - struct monst *umon = mtmp ? mtmp : u.umonst; + struct monst *umon = mtmp ? mtmp : &gy.youmonst; int dam = reg->arg.a_int; /* @@ -1107,8 +1107,8 @@ inside_gas_cloud(genericptr_t p1, genericptr_t p2) if (dam < 1) return FALSE; /* if no damage then there's nothing to do here... */ - if (!mtmp) { /* hero is indicated by Null rather than by u.umonst */ - if (m_poisongas_ok(u.umonst) == M_POISONGAS_OK) + if (!mtmp) { /* hero is indicated by Null rather than by &youmonst */ + if (m_poisongas_ok(&gy.youmonst) == M_POISONGAS_OK) return FALSE; if (!Blind) { Your("%s sting.", makeplural(body_part(EYE))); @@ -1232,7 +1232,7 @@ create_gas_cloud( probably a natural cause of being polyed. don't message about it */ if (!svc.context.mon_moving && u_at(x, y) && cloudsize == 1 && (!damage - || (damage && m_poisongas_ok(u.umonst) == M_POISONGAS_OK))) + || (damage && m_poisongas_ok(&gy.youmonst) == M_POISONGAS_OK))) inside_cloud = TRUE; if (cloudsize > MAX_CLOUD_SIZE) { @@ -1350,7 +1350,7 @@ region_danger(void) /* the only type of region we understand is gas_cloud */ if (f_indx == INSIDE_GAS_CLOUD) { /* completely harmless if you don't need to breathe */ - if (nonliving(u.umonst->data) || Breathless) + if (nonliving(gy.youmonst.data) || Breathless) continue; /* minor inconvenience if you're poison resistant; not harmful enough to be a prayer-level trouble */ diff --git a/src/restore.c b/src/restore.c index 35ebaee10..8dbb53511 100644 --- a/src/restore.c +++ b/src/restore.c @@ -22,7 +22,6 @@ staticfn struct fruit *loadfruitchn(NHFILE *); staticfn void freefruitchn(struct fruit *); staticfn void rest_levl(NHFILE *); staticfn void rest_stairs(NHFILE *); -staticfn void rest_u(NHFILE *, boolean); #ifndef SFCTOOL staticfn void ghostfruit(struct obj *); staticfn boolean restgamestate(NHFILE *); @@ -528,11 +527,11 @@ restgamestate(NHFILE *nhfp) int i; struct flag newgameflags; struct context_info newgamecontext; /* all 0, but has some pointers */ - unsigned long uid = 0; struct obj *bc_obj; - boolean restoring_special = (wizard || discover); + char timebuf[15]; + unsigned long uid = 0; #ifndef SFCTOOL - boolean defer_perm_invent; + boolean defer_perm_invent, restoring_special; struct obj *otmp; #endif @@ -586,6 +585,7 @@ restgamestate(NHFILE *nhfp) in the discover case, we don't want to set that for a normal game until after the save file has been removed */ iflags.deferred_X = (newgameflags.explore && !discover); + restoring_special = (wizard || discover); if (newgameflags.debug) { /* authorized by startup code; wizard mode exists and is allowed */ wizard = TRUE, discover = iflags.deferred_X = FALSE; @@ -598,9 +598,31 @@ restgamestate(NHFILE *nhfp) amii_setpens(amii_numcolors); /* use colors from save file */ #endif #endif /* !SFCTOOL */ - rest_u(nhfp, restoring_special); + Sfi_you(nhfp, &u, "gamestate-you"); + gy.youmonst.cham = u.mcham; #ifndef SFCTOOL + if (restoring_special && iflags.explore_error_flag) { + /* savefile has wizard or explore mode, but player is no longer + authorized to access either; can't downgrade mode any further, so + fail restoration. */ + u.uhp = 0; + } +#endif + + Sfi_char(nhfp, timebuf, "gamestate-ubirthday", 14); + timebuf[14] = '\0'; + ubirthday = time_from_yyyymmddhhmmss(timebuf); + Sfi_long(nhfp, &urealtime.realtime, "gamestate-realtime"); + Sfi_char(nhfp, timebuf, "gamestate-start_timing", 14); + timebuf[14] = '\0'; +#ifndef SFCTOOL + urealtime.start_timing = time_from_yyyymmddhhmmss(timebuf); + + /* current time is the time to use for next urealtime.realtime update */ + urealtime.start_timing = getnow(); + + set_uasmon(); #ifdef CLIPPING cliparound(u.ux, u.uy); #endif @@ -618,7 +640,7 @@ restgamestate(NHFILE *nhfp) iflags.perm_invent = defer_perm_invent; flags = newgameflags; svc.context = newgamecontext; - free((genericptr_t) u.umonst), u.umonst = 0; + gy.youmonst = cg.zeromonst; return FALSE; } /* in case hangup save occurred in midst of level change */ @@ -643,8 +665,7 @@ restgamestate(NHFILE *nhfp) setworn(bc_obj, bc_obj->owornmask); bc_obj = nobj; } -#endif /* !SFCTOOL */ - +#endif gm.migrating_objs = restobjchn(nhfp, FALSE); gm.migrating_mons = restmonchn(nhfp); @@ -712,43 +733,6 @@ restgamestate(NHFILE *nhfp) return TRUE; } -void -rest_u(NHFILE *nhfp, boolean restoring_special) -{ - char timebuf[15]; - - Sfi_you(nhfp, &u, "gamestate-you"); -#ifndef SFCTOOL - if (restoring_special && iflags.explore_error_flag) { - /* savefile has wizard or explore mode, but player is no longer - authorized to access either; can't downgrade mode any further, so - fail restoration. */ - u.uhp = 0; - } -#endif - - Sfi_char(nhfp, timebuf, "gamestate-ubirthday", 14); - timebuf[14] = '\0'; - ubirthday = time_from_yyyymmddhhmmss(timebuf); - Sfi_long(nhfp, &urealtime.realtime, "gamestate-realtime"); - Sfi_char(nhfp, timebuf, "gamestate-start_timing", 14); - timebuf[14] = '\0'; -#ifndef SFCTOOL - urealtime.start_timing = time_from_yyyymmddhhmmss(timebuf); - - /* current time is the time to use for next urealtime.realtime update */ - urealtime.start_timing = getnow(); - - u.umonst = newmonst(); - *u.umonst = cg.zeromonst; - u.umonst->cham = u.mcham; - set_uasmon(); -#else - nhUse(restoring_special); -#endif /* !SFCTOOL */ -} - - #ifndef SFCTOOL /* update game state pointers to those valid for the current level (so we don't dereference a wild u.ustuck when saving game state, for instance) */ diff --git a/src/save.c b/src/save.c index b6d09f432..1ac9e9098 100644 --- a/src/save.c +++ b/src/save.c @@ -31,7 +31,6 @@ staticfn void save_gamelog(NHFILE *); staticfn void savegamestate(NHFILE *); staticfn void savelev_core(NHFILE *, xint8); staticfn void save_msghistory(NHFILE *); -staticfn void save_u(NHFILE *); staticfn void save_adjust_levelflags(void); #if defined(HANGUPHANDLING) #define HUP if (!program_state.done_hup) @@ -262,27 +261,6 @@ save_gamelog(NHFILE *nhfp) gg.gamelog = NULL; } -staticfn void -save_u(NHFILE *nhfp) -{ - struct monst *save_umonst; - - urealtime.finish_time = getnow(); - urealtime.realtime += timet_delta(urealtime.finish_time, - urealtime.start_timing); - - save_umonst = u.umonst; - u.umonst = (struct monst *) 0; - Sfo_you(nhfp, &u, "gamestate-you"); - u.umonst = save_umonst; - - Sfo_char(nhfp, yyyymmddhhmmss(ubirthday), "gamestate-ubirthday", 14); - Sfo_long(nhfp, &urealtime.realtime, "gamestate-realtime"); - Sfo_char(nhfp, yyyymmddhhmmss(urealtime.start_timing), "gamestate-start_timing", 14); - /* this is the value to use for the next update of urealtime.realtime */ - urealtime.start_timing = urealtime.finish_time; -} - staticfn void savegamestate(NHFILE *nhfp) { @@ -299,8 +277,17 @@ savegamestate(NHFILE *nhfp) Sfo_context_info(nhfp, &svc.context, "gamestate-context"); relative_time_to_moves(&svc.context.seer_turn); relative_time_to_moves(&svc.context.digging.lastdigtime); + Sfo_flag(nhfp, &flags, "gamestate-flags"); - save_u(nhfp); + urealtime.finish_time = getnow(); + urealtime.realtime += timet_delta(urealtime.finish_time, + urealtime.start_timing); + Sfo_you(nhfp, &u, "gamestate-you"); + Sfo_char(nhfp, yyyymmddhhmmss(ubirthday), "gamestate-ubirthday", 14); + Sfo_long(nhfp, &urealtime.realtime, "gamestate-realtime"); + Sfo_char(nhfp, yyyymmddhhmmss(urealtime.start_timing), "gamestate-start_timing", 14); + /* this is the value to use for the next update of urealtime.realtime */ + urealtime.start_timing = urealtime.finish_time; save_killers(nhfp); /* must come before gm.migrating_objs and gm.migrating_mons are freed */ @@ -1186,9 +1173,6 @@ freedynamicdata(void) if (options_set_window_colors_flag) options_free_window_colors(); - if (u.umonst) - free((genericptr_t) u.umonst), u.umonst = 0; - if (glyphid_cache_status()) free_glyphid_cache(); diff --git a/src/shk.c b/src/shk.c index 69a716df7..927352971 100644 --- a/src/shk.c +++ b/src/shk.c @@ -3609,12 +3609,12 @@ append_honorific(char *buf) }; Strcat(buf, honored[rn2(SIZE(honored) - 1) + u.uevent.udemigod]); - if (is_vampire(u.umonst->data)) + if (is_vampire(gy.youmonst.data)) Strcat(buf, (flags.female) ? " dark lady" : " dark lord"); - else if (maybe_polyd(is_elf(u.umonst->data), Race_if(PM_ELF))) + else if (maybe_polyd(is_elf(gy.youmonst.data), Race_if(PM_ELF))) Strcat(buf, (flags.female) ? " hiril" : " hir"); else - Strcat(buf, !is_human(u.umonst->data) ? " creature" + Strcat(buf, !is_human(gy.youmonst.data) ? " creature" : (flags.female) ? " lady" : " sir"); } @@ -5910,7 +5910,7 @@ cad( { const char *res = 0; - switch (is_demon(u.umonst->data) ? 3 : poly_gender()) { + switch (is_demon(gy.youmonst.data) ? 3 : poly_gender()) { case 0: res = "cad"; break; @@ -5929,7 +5929,7 @@ cad( break; } if (altusage) { - char *cadbuf = mon_nam(u.umonst); /* snag an output buffer */ + char *cadbuf = mon_nam(&gy.youmonst); /* snag an output buffer */ /* alternate usage adds a leading double quote and trailing exclamation point plus sentence separating spaces */ diff --git a/src/sit.c b/src/sit.c index 8f355d95a..15c16dbdf 100644 --- a/src/sit.c +++ b/src/sit.c @@ -157,7 +157,7 @@ throne_sit_effect(void) if (!Blind) { Your("vision becomes clear."); } else { - int num_of_eyes = eyecount(u.umonst->data); + int num_of_eyes = eyecount(gy.youmonst.data); const char *eye = body_part(EYE); /* note: 1 eye case won't actually happen--can't @@ -208,7 +208,7 @@ throne_sit_effect(void) break; } } else { - if (is_prince(u.umonst->data) || u.uevent.uhand_of_elbereth) + if (is_prince(gy.youmonst.data) || u.uevent.uhand_of_elbereth) You_feel("very comfortable here."); else You_feel("somehow out of place..."); @@ -325,7 +325,7 @@ special_throne_effect(int effect) { case 11: /* polymorph effect (not blocked by magic resistance, but other things that protect from polymorphs work) */ - if (is_vampire(u.umonst->data)) { + if (is_vampire(gy.youmonst.data)) { You_feel("unworthy."); } else { pline("This throne was not meant for those such as you!"); @@ -368,14 +368,14 @@ lay_an_egg(void) } else if (u.uhunger < (int) objects[EGG].oc_nutrition) { You("don't have enough energy to lay an egg."); return ECMD_OK; - } else if (eggs_in_water(u.umonst->data)) { + } else if (eggs_in_water(gy.youmonst.data)) { if (!(Underwater || Is_waterlevel(&u.uz))) { pline("A splash tetra you are not."); return ECMD_OK; } if (Upolyd - && (u.umonst->data == &mons[PM_GIANT_EEL] - || u.umonst->data == &mons[PM_ELECTRIC_EEL])) { + && (gy.youmonst.data == &mons[PM_GIANT_EEL] + || gy.youmonst.data == &mons[PM_ELECTRIC_EEL])) { You("yearn for the Sargasso Sea."); return ECMD_OK; } @@ -388,7 +388,7 @@ lay_an_egg(void) set_corpsenm(uegg, egg_type_from_parent(u.umonnum, FALSE)); uegg->known = 1; observe_object(uegg); - You("%s an egg.", eggs_in_water(u.umonst->data) ? "spawn" : "lay"); + You("%s an egg.", eggs_in_water(gy.youmonst.data) ? "spawn" : "lay"); dropy(uegg); stackobj(uegg); morehungry((int) objects[EGG].oc_nutrition); @@ -407,7 +407,7 @@ dosit(void) You("are already sitting on %s.", mon_nam(u.usteed)); return ECMD_OK; } - if (u.uundetected && is_hider(u.umonst->data) + if (u.uundetected && is_hider(gy.youmonst.data) && u.umonnum != PM_TRAPPER) /* trapper can stay hidden on floor */ u.uundetected = 0; /* no longer on the ceiling */ @@ -419,7 +419,7 @@ dosit(void) else You("are sitting on air."); return ECMD_OK; - } else if (u.ustuck && !sticks(u.umonst->data)) { + } else if (u.ustuck && !sticks(gy.youmonst.data)) { /* holding monster is next to hero rather than beneath, but hero is in no condition to actually sit at has/her own spot */ if (humanoid(u.ustuck->data)) @@ -440,14 +440,14 @@ dosit(void) struct obj *obj; obj = svl.level.objects[u.ux][u.uy]; - if (u.umonst->data->mlet == S_DRAGON && obj->oclass == COIN_CLASS) { + if (gy.youmonst.data->mlet == S_DRAGON && obj->oclass == COIN_CLASS) { You("coil up around your %shoard.", (obj->quan + money_cnt(gi.invent) < u.ulevel * 1000) ? "meager " : ""); } else if (obj->otyp == TOWEL) { pline("It's probably not a good time for a picnic..."); } else { - if (slithy(u.umonst->data)) + if (slithy(gy.youmonst.data)) You("coil up around %s.", the(xname(obj))); else You("sit on %s.", the(xname(obj))); @@ -503,16 +503,16 @@ dosit(void) dotrap(trap, VIASITTING); } } else if ((Underwater || Is_waterlevel(&u.uz)) - && !eggs_in_water(u.umonst->data)) { + && !eggs_in_water(gy.youmonst.data)) { if (Is_waterlevel(&u.uz)) There("are no cushions floating nearby."); else You("sit down on the muddy bottom."); - } else if (is_pool(u.ux, u.uy) && !eggs_in_water(u.umonst->data)) { + } else if (is_pool(u.ux, u.uy) && !eggs_in_water(gy.youmonst.data)) { in_water: You("sit in the %s.", hliquid("water")); if (Upolyd && u.umonnum == PM_GREMLIN) { - if (split_mon(u.umonst, (struct monst *) 0)) { + if (split_mon(&gy.youmonst, (struct monst *) 0)) { if (levl[u.ux][u.uy].typ == FOUNTAIN) dryup(u.ux, u.uy, TRUE); } @@ -526,7 +526,7 @@ dosit(void) } else if (IS_SINK(typ)) { You(sit_message, defsyms[S_sink].explanation); Your("%s gets wet.", - humanoid(u.umonst->data) ? "rump" : "underside"); + humanoid(gy.youmonst.data) ? "rump" : "underside"); } else if (IS_ALTAR(typ)) { You(sit_message, defsyms[S_altar].explanation); altar_wrath(u.ux, u.uy); @@ -540,7 +540,7 @@ dosit(void) /* must be WWalking */ You(sit_message, hliquid("lava")); burn_away_slime(); - if (likes_lava(u.umonst->data)) { + if (likes_lava(gy.youmonst.data)) { pline_The("%s feels warm.", hliquid("lava")); return ECMD_TIME; } @@ -556,7 +556,7 @@ dosit(void) } else if (IS_THRONE(typ)) { You(sit_message, defsyms[S_throne].explanation); throne_sit_effect(); - } else if (lays_eggs(u.umonst->data)) { + } else if (lays_eggs(gy.youmonst.data)) { return lay_an_egg(); } else { pline("Having fun sitting on the %s?", surface(u.ux, u.uy)); diff --git a/src/sounds.c b/src/sounds.c index 002cd8854..5e4a0e1cd 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -591,7 +591,7 @@ maybe_gasp(struct monst *mon) case MS_VAMPIRE: /* vampire in its own form */ case MS_WERE: /* lycanthrope in human form */ case MS_SPELL: /* titan, barrow wight, Nazgul, nalfeshnee */ - dogasp = (mptr->mlet == u.umonst->data->mlet); + dogasp = (mptr->mlet == gy.youmonst.data->mlet); break; /* capable of speech but don't care if you attack peacefuls */ case MS_BRIBE: @@ -703,7 +703,7 @@ domonnoise(struct monst *mtmp) msound = MS_SELL; /* some normally non-speaking types can/will speak if hero is similar */ else if (msound == MS_ORC - && ((same_race(ptr, u.umonst->data) /* current form, */ + && ((same_race(ptr, gy.youmonst.data) /* current form, */ || same_race(ptr, &mons[Race_switch])) /* unpoly'd form */ || Hallucination)) msound = MS_HUMANOID; @@ -794,12 +794,12 @@ domonnoise(struct monst *mtmp) if (kindred) { verbl_msg = "This is my hunting ground" " that you dare to prowl!"; - } else if (u.umonst->data == &mons[PM_SILVER_DRAGON] - || u.umonst->data == &mons[PM_BABY_SILVER_DRAGON]) { + } else if (gy.youmonst.data == &mons[PM_SILVER_DRAGON] + || gy.youmonst.data == &mons[PM_BABY_SILVER_DRAGON]) { /* Silver dragons are silver in color, not made of silver */ Sprintf(verbuf, "%s! Your silver sheen"" does not frighten me!", - (u.umonst->data == &mons[PM_SILVER_DRAGON]) + (gy.youmonst.data == &mons[PM_SILVER_DRAGON]) ? "Fool" : "Young Fool"); verbl_msg = verbuf; @@ -1107,7 +1107,7 @@ domonnoise(struct monst *mtmp) if (SYSOPT_SEDUCE) { if (ptr->mlet != S_NYMPH - && (could_seduce(mtmp, u.umonst, (struct attack *) 0) + && (could_seduce(mtmp, &gy.youmonst, (struct attack *) 0) == 1)) { (void) doseduce(mtmp); break; @@ -1260,9 +1260,9 @@ dochat(void) int tx, ty; struct obj *otmp; - if (is_silent(u.umonst->data)) { + if (is_silent(gy.youmonst.data)) { pline("As %s, you cannot speak.", - an(pmname(u.umonst->data, flags.female ? FEMALE : MALE))); + an(pmname(gy.youmonst.data, flags.female ? FEMALE : MALE))); return ECMD_OK; } if (Strangled) { @@ -1395,7 +1395,7 @@ dochat(void) return ECMD_OK; } if (Deaf) { - const char *xresponse = humanoid(u.umonst->data) + const char *xresponse = humanoid(gy.youmonst.data) ? "falls on deaf ears" : "is inaudible"; diff --git a/src/spell.c b/src/spell.c index 4d489a123..43c2acd51 100644 --- a/src/spell.c +++ b/src/spell.c @@ -316,7 +316,7 @@ deadbook(struct obj *book2) set_malign(mtmp); } /* next handle the affect on things you're carrying */ - (void) unturn_dead(u.umonst); + (void) unturn_dead(&gy.youmonst); /* last place some monsters around you */ mm.x = u.ux; mm.y = u.uy; @@ -483,7 +483,7 @@ study_book(struct obj *spellbook) if (dullbook > 0) { eyes = body_part(EYE); - if (eyecount(u.umonst->data) > 1) + if (eyecount(gy.youmonst.data) > 1) eyes = makeplural(eyes); pline("This book is so dull that you can't keep your %s open.", eyes); @@ -690,7 +690,7 @@ rejectcasting(void) if (Stunned) { You("are too impaired to cast a spell."); return TRUE; - } else if (!can_chant(u.umonst)) { + } else if (!can_chant(&gy.youmonst)) { You("are unable to chant the incantation."); return TRUE; } else if (!freehand() && !(uwep && uwep->otyp == QUARTERSTAFF)) { diff --git a/src/steal.c b/src/steal.c index 1c9fcb305..fd53ff1b7 100644 --- a/src/steal.c +++ b/src/steal.c @@ -79,7 +79,7 @@ stealgold(struct monst *mtmp) whose = s_suffix(y_monnam(who)); what = makeplural(mbodypart(who, FOOT)); } else { - who = u.umonst; + who = &gy.youmonst; whose = "your"; what = makeplural(body_part(FOOT)); } @@ -387,7 +387,7 @@ steal(struct monst *mtmp, char *objnambuf) /* buried ball is not tracked via 'uball' and there is no chain at all (hence no uchain to take off) */ pline("%s takes off your unseen chain.", Monnambuf); - (void) openholdingtrap(u.umonst, &dummy); + (void) openholdingtrap(&gy.youmonst, &dummy); } else if (Blind) { pline("Somebody tries to rob you, but finds nothing to steal."); } else if (inv_cnt(TRUE) > inv_cnt(FALSE)) { diff --git a/src/steed.c b/src/steed.c index 553e1df3a..835a8562f 100644 --- a/src/steed.c +++ b/src/steed.c @@ -68,7 +68,7 @@ use_saddle(struct obj *otmp) char kbuf[BUFSZ]; You("touch %s.", mon_nam(mtmp)); - if (!(poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM))) { + if (!(poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM))) { Sprintf(kbuf, "attempting to saddle %s", an(pmname(mtmp->data, Mgender(mtmp)))); instapetrify(kbuf); @@ -168,8 +168,8 @@ put_saddle_on_mon(struct obj *saddle, struct monst *mtmp) boolean can_ride(struct monst *mtmp) { - return (mtmp->mtame && humanoid(u.umonst->data) - && !verysmall(u.umonst->data) && !bigmonst(u.umonst->data) + return (mtmp->mtame && humanoid(gy.youmonst.data) + && !verysmall(gy.youmonst.data) && !bigmonst(gy.youmonst.data) && (!Underwater || is_swimmer(mtmp->data))); } @@ -238,10 +238,10 @@ mount_steed( return (FALSE); } - if (Upolyd && (!humanoid(u.umonst->data) - || verysmall(u.umonst->data) - || bigmonst(u.umonst->data) - || slithy(u.umonst->data))) { + if (Upolyd && (!humanoid(gy.youmonst.data) + || verysmall(gy.youmonst.data) + || bigmonst(gy.youmonst.data) + || slithy(gy.youmonst.data))) { You("won't fit on a saddle."); return (FALSE); } @@ -545,7 +545,7 @@ landing_spot( kn_trap = i == 0 && ((t = t_at(x, y)) != 0 && t->tseen && t->ttyp != VIBRATING_SQUARE); boulder = i <= 1 && (sobj_at(BOULDER, x, y) - && !throws_rocks(u.umonst->data)); + && !throws_rocks(gy.youmonst.data)); if (!kn_trap && !boulder) { spot->x = x; spot->y = y; @@ -566,7 +566,7 @@ landing_spot( /* If we didn't find a good spot and forceit is on, try enexto(). */ if (forceit && !found) - found = enexto(spot, u.ux, u.uy, u.umonst->data); + found = enexto(spot, u.ux, u.uy, gy.youmonst.data); return found; } diff --git a/src/teleport.c b/src/teleport.c index 3384fa204..7b4a363b2 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -105,7 +105,7 @@ goodpos( * oh well. */ if (!allow_u) { - if (u_at(x, y) && mtmp != u.umonst + if (u_at(x, y) && mtmp != &gy.youmonst && (mtmp != u.ustuck || !u.uswallow) && (!u.usteed || mtmp != u.usteed)) return FALSE; @@ -133,7 +133,7 @@ goodpos( mdat = mtmp->data; if (is_pool(x, y) && !ignorewater) { /* [what about Breathless?] */ - if (mtmp == u.umonst) + if (mtmp == &gy.youmonst) return (Swimming || Amphibious || (!Is_waterlevel(&u.uz) && !is_waterwall(x, y) @@ -152,11 +152,11 @@ goodpos( that due the effect of the heat causing it to dry out */ if (mdat == &mons[PM_FLOATING_EYE]) return FALSE; - else if (mtmp == u.umonst) + else if (mtmp == &gy.youmonst) return (Levitation || Flying || (Fire_resistance && Wwalking && uarmf && uarmf->oerodeproof) - || (Upolyd && likes_lava(u.umonst->data))); + || (Upolyd && likes_lava(gy.youmonst.data))); else return (m_in_air(mtmp) || likes_lava(mdat)); } @@ -435,7 +435,7 @@ teleok(coordxy x, coordxy y, boolean trapok) if (!trapok) return FALSE; } - if (!goodpos(x, y, u.umonst, 0)) + if (!goodpos(x, y, &gy.youmonst, 0)) return FALSE; if (!tele_jump_ok(u.ux, u.uy, x, y)) return FALSE; @@ -490,9 +490,9 @@ teleds(coordxy nux, coordxy nuy, int teleds_flags) u.ux0 = u.ux; u.uy0 = u.uy; - if (!hideunder(u.umonst) && u.umonst->data->mlet == S_MIMIC) { + if (!hideunder(&gy.youmonst) && gy.youmonst.data->mlet == S_MIMIC) { /* mimics stop being unnoticed */ - u.umonst->m_ap_type = M_AP_NOTHING; + gy.youmonst.m_ap_type = M_AP_NOTHING; } if (was_swallowed) { @@ -816,7 +816,7 @@ tele_to_rnd_pet(void) struct monst *mtmp, *pet = (struct monst *) 0; int cnt = 0; - if (noteleport_level(u.umonst)) { + if (noteleport_level(&gy.youmonst)) { impossible("%s", "attempt to teleport hero to be near a pet" " on no-teleport level"); return; @@ -851,7 +851,7 @@ scrolltele(struct obj *scroll) coord cc; /* Disable teleportation in stronghold && Vlad's Tower */ - if (noteleport_level(u.umonst) && !wizard) { + if (noteleport_level(&gy.youmonst) && !wizard) { pline("A mysterious force prevents you from teleporting!"); if (scroll) learnscroll(scroll); /* this is obviously a teleport scroll */ @@ -1072,7 +1072,7 @@ dotele( int energy = 0; if (!Teleportation || (u.ulevel < (Role_if(PM_WIZARD) ? 8 : 12) - && !can_teleport(u.umonst->data))) { + && !can_teleport(gy.youmonst.data))) { /* Try to use teleport away spell. */ int knownsp = known_spell(SPE_TELEPORT_AWAY); @@ -1257,7 +1257,7 @@ level_tele(void) if (ynq("Go to Nowhere. Are you sure?") != 'y') return; You("%s in agony as your body begins to warp...", - is_silent(u.umonst->data) ? "writhe" : "scream"); + is_silent(gy.youmonst.data) ? "writhe" : "scream"); display_nhwindow(WIN_MESSAGE, FALSE); You("cease to exist."); if (gi.invent) @@ -1499,7 +1499,7 @@ tele_trap(struct trap *trap) return; in_tele_trap = TRUE; - if (In_endgame(&u.uz) || Antimagic || noteleport_level(u.umonst)) { + if (In_endgame(&u.uz) || Antimagic || noteleport_level(&gy.youmonst)) { if (Antimagic) shieldeff(u.ux, u.uy); You_feel("a wrenching sensation."); diff --git a/src/timeout.c b/src/timeout.c index 34d11d601..af974c84e 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -142,7 +142,7 @@ stoned_dialogue(void) char buf[BUFSZ]; Strcpy(buf, stoned_texts[SIZE(stoned_texts) - i]); - if (nolimbs(u.umonst->data) && strstri(buf, "limbs")) + if (nolimbs(gy.youmonst.data) && strstri(buf, "limbs")) (void) strsubst(buf, "limbs", "extremities"); urgent_pline("%s", buf); } @@ -232,7 +232,7 @@ vomiting_dialogue(void) break; case 2: txt = vomiting_texts[4]; - if (cantvomit(u.umonst->data)) + if (cantvomit(gy.youmonst.data)) txt = "gag uncontrollably."; else if (Hallucination) /* "hurl" is short for "hurl chunks" which is slang for @@ -241,7 +241,7 @@ vomiting_dialogue(void) break; case 0: stop_occupation(); - if (!cantvomit(u.umonst->data)) { + if (!cantvomit(gy.youmonst.data)) { morehungry(20); /* case 2 used to be "You suddenly vomit!" but it wasn't sudden since you've just been through the earlier messages of the @@ -332,8 +332,8 @@ sickness_dialogue(void) if ((u.usick_type & SICK_NONVOMITABLE) == 0) (void) strsubst(buf, "illness", "sickness"); if (Hallucination && strstri(buf, "Death's door")) { - /* u.umonst: for Hallucination, mhe()'s mon argument isn't used */ - Strcpy(pronounbuf, mhe(u.umonst)); + /* youmonst: for Hallucination, mhe()'s mon argument isn't used */ + Strcpy(pronounbuf, mhe(&gy.youmonst)); Sprintf(eos(buf), " %s %s inviting you in.", /* upstart() modifies its argument but vtense() doesn't care whether or not that has already happened */ @@ -394,8 +394,8 @@ slime_dialogue(void) /* display as green slime during "You have become green slime." but don't worry about not being able to see self; if already mimicking something else at the time, implicitly be revealed */ - u.umonst->m_ap_type = M_AP_MONSTER; - u.umonst->mappearance = PM_GREEN_SLIME; + gy.youmonst.m_ap_type = M_AP_MONSTER; + gy.youmonst.mappearance = PM_GREEN_SLIME; /* no message given when 't' is odd, so no automatic update of self; force one */ newsym(u.ux, u.uy); @@ -405,7 +405,7 @@ slime_dialogue(void) char buf[BUFSZ]; Strcpy(buf, slime_texts[SIZE(slime_texts) - i - 1L]); - if (nolimbs(u.umonst->data) && strstri(buf, "limbs")) + if (nolimbs(gy.youmonst.data) && strstri(buf, "limbs")) (void) strsubst(buf, "limbs", "extremities"); if (strchr(buf, '%')) { @@ -459,7 +459,7 @@ slimed_to_death(struct kinfo *kptr) uchar save_mvflags; /* redundant: polymon() cures sliming when polying into green slime */ - if (Upolyd && u.umonst->data == &mons[PM_GREEN_SLIME]) { + if (Upolyd && gy.youmonst.data == &mons[PM_GREEN_SLIME]) { dealloc_killer(kptr); return; } @@ -485,11 +485,11 @@ slimed_to_death(struct kinfo *kptr) * [formerly implicit] change of form; polymon() takes care of that. * Temporarily ungenocide if necessary. */ - if (emits_light(u.umonst->data)) - del_light_source(LS_MONSTER, monst_to_any(u.umonst)); + if (emits_light(gy.youmonst.data)) + del_light_source(LS_MONSTER, monst_to_any(&gy.youmonst)); save_mvflags = svm.mvitals[PM_GREEN_SLIME].mvflags; svm.mvitals[PM_GREEN_SLIME].mvflags = save_mvflags & ~G_GENOD; - /* become a green slime; also resets u.umonst.m_ap_type+.mappearance */ + /* become a green slime; also resets youmonst.m_ap_type+.mappearance */ (void) polymon(PM_GREEN_SLIME); svm.mvitals[PM_GREEN_SLIME].mvflags = save_mvflags; done_timeout(TURNED_SLIME, SLIMED); @@ -640,8 +640,8 @@ nh_timeout(void) sleep_dialogue(); if (u.mtimedone && !--u.mtimedone) { if (Unchanging) - u.mtimedone = rnd(100 * u.umonst->data->mlevel + 1); - else if (is_were(u.umonst->data)) + u.mtimedone = rnd(100 * gy.youmonst.data->mlevel + 1); + else if (is_were(gy.youmonst.data)) you_unwere(FALSE); /* if polycontrl, asks whether to rehumanize */ else rehumanize(); diff --git a/src/trap.c b/src/trap.c index 5ff6c0747..88f6bc279 100644 --- a/src/trap.c +++ b/src/trap.c @@ -94,7 +94,7 @@ burnarmor(struct monst *victim) if (!victim) return 0; - hitting_u = (victim == u.umonst); + hitting_u = (victim == &gy.youmonst); /* burning damage may dry wet towel */ item = hitting_u ? carrying(TOWEL) : m_carrying(victim, TOWEL); @@ -190,11 +190,11 @@ erode_obj( if (!otmp) return ER_NOTHING; - victim = carried(otmp) ? u.umonst + victim = carried(otmp) ? &gy.youmonst : mcarried(otmp) ? otmp->ocarry : (struct monst *) 0; - uvictim = (victim == u.umonst); - vismon = victim && (victim != u.umonst) && canseemon(victim); + uvictim = (victim == &gy.youmonst); + vismon = victim && (victim != &gy.youmonst) && canseemon(victim); /* Is gb.bhitpos correct here? Ugh. */ visobj = (!victim && cansee(gb.bhitpos.x, gb.bhitpos.y) && (!is_pool(gb.bhitpos.x, gb.bhitpos.y) @@ -269,7 +269,7 @@ erode_obj( */ if (otmp->oerodeproof) { otmp->rknown = TRUE; - if (victim == u.umonst) + if (victim == &gy.youmonst) update_inventory(); } @@ -294,7 +294,7 @@ erode_obj( else otmp->oeroded2++; - if (victim == u.umonst) + if (victim == &gy.youmonst) update_inventory(); return ER_DAMAGED; @@ -363,15 +363,15 @@ grease_protect( struct monst *victim) { static const char txt[] = "protected by the layer of grease!"; - boolean vismon = victim && (victim != u.umonst) && canseemon(victim); + boolean vismon = victim && (victim != &gy.youmonst) && canseemon(victim); if (ostr) { - if (victim == u.umonst) + if (victim == &gy.youmonst) Your("%s %s %s", ostr, vtense(ostr, "are"), txt); else if (vismon) pline("%s's %s %s %s", Monnam(victim), ostr, vtense(ostr, "are"), txt); - } else if (victim == u.umonst || vismon) { + } else if (victim == &gy.youmonst || vismon) { pline("%s %s", Yobjnam2(otmp, "are"), txt); } if (!rn2(2)) { @@ -634,11 +634,11 @@ fall_through( ; /* KMH -- You can't escape the Sokoban level traps */ } else if (Levitation || u.ustuck || (!Can_fall_thru(&u.uz) && !levl[u.ux][u.uy].candig) - || ((Flying || is_clinger(u.umonst->data) - || (ceiling_hider(u.umonst->data) && u.uundetected)) + || ((Flying || is_clinger(gy.youmonst.data) + || (ceiling_hider(gy.youmonst.data) && u.uundetected)) && !(ftflags & TOOKPLUNGE))) { dont_fall = "don't fall in."; - } else if (u.umonst->data->msize >= MZ_HUGE) { + } else if (gy.youmonst.data->msize >= MZ_HUGE) { dont_fall = "don't fit through."; } else if (!next_to_u()) { dont_fall = "are jerked back by your pet!"; @@ -653,7 +653,7 @@ fall_through( } return; } - if ((Flying || is_clinger(u.umonst->data)) + if ((Flying || is_clinger(gy.youmonst.data)) && (ftflags & TOOKPLUNGE) && td && t) { if (Flying) controlled_flight = TRUE; @@ -890,7 +890,7 @@ animate_statue( delobj(statue); /* avoid hiding under nothing */ - if (u_at(x, y) && Upolyd && hides_under(u.umonst->data) + if (u_at(x, y) && Upolyd && hides_under(gy.youmonst.data) && !OBJ_AT(x, y)) u.uundetected = 0; @@ -974,7 +974,7 @@ mu_maybe_destroy_web( boolean domsg, struct trap *trap) { - boolean isyou = (mtmp == u.umonst); + boolean isyou = (mtmp == &gy.youmonst); struct permonst *mptr = mtmp->data; if (amorphous(mptr) || is_whirly(mptr) || flaming(mptr) @@ -1085,7 +1085,7 @@ floor_trigger(int ttyp) staticfn boolean check_in_air(struct monst *mtmp, unsigned trflags) { - boolean is_you = mtmp == u.umonst, + boolean is_you = mtmp == &gy.youmonst, plunged = (trflags & (TOOKPLUNGE | VIASITTING)) != 0; return ((trflags & HURTLING) != 0 @@ -1195,7 +1195,7 @@ trapeffect_arrow_trap( struct obj *otmp; int dam; - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { if (trap->once && trap->tseen && !rn2(15)) { Soundeffect(se_loud_click, 100); You_hear("a loud click!"); @@ -1207,7 +1207,7 @@ trapeffect_arrow_trap( seetrap(trap); pline("An arrow shoots out at you!"); otmp = t_missile(ARROW, trap); - dam = dmgval(otmp, u.umonst); + dam = dmgval(otmp, &gy.youmonst); if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { ; /* nothing */ } else if (thitu(8, Maybe_Half_Phys(dam), &otmp, "arrow")) { @@ -1256,7 +1256,7 @@ trapeffect_dart_trap( struct obj *otmp; int dam; - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { int oldumort = u.umortality; if (trap->once && trap->tseen && !rn2(15)) { @@ -1272,7 +1272,7 @@ trapeffect_dart_trap( otmp = t_missile(DART, trap); if (!rn2(6)) otmp->opoisoned = 1; - dam = dmgval(otmp, u.umonst); + dam = dmgval(otmp, &gy.youmonst); if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { ; /* nothing */ } else if (thitu(7, Maybe_Half_Phys(dam), &otmp, "little dart")) { @@ -1329,7 +1329,7 @@ trapeffect_rocktrap( struct obj *otmp; boolean harmless = FALSE; - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { if (trap->once && trap->tseen && !rn2(15)) { pline("A trap door in %s opens, but nothing falls out!", the(ceiling(u.ux, u.uy))); @@ -1348,7 +1348,7 @@ trapeffect_rocktrap( if (uarmh) { /* normally passes_rocks() would protect against a falling rock, but not when wearing a helmet */ - if (passes_rocks(u.umonst->data)) { + if (passes_rocks(gy.youmonst.data)) { pline("Unfortunately, you are wearing %s.", an(helm_simple_name(uarmh))); /* helm or hat */ dmg = 2; @@ -1358,7 +1358,7 @@ trapeffect_rocktrap( } else if (flags.verbose) { pline("%s does not protect you.", Yname2(uarmh)); } - } else if (passes_rocks(u.umonst->data)) { + } else if (passes_rocks(gy.youmonst.data)) { pline("It passes harmlessly through you."); harmless = TRUE; } @@ -1415,7 +1415,7 @@ trapeffect_sqky_board( || (trflags & FAILEDUNTRAP) != 0 || (Flying && (trflags & VIASITTING) != 0)); - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { if ((Levitation || Flying) && !forcetrap) { if (!Blind) { seetrap(trap); @@ -1481,7 +1481,7 @@ trapeffect_bear_trap( struct trap *trap, unsigned trflags) { - boolean is_you = mtmp == u.umonst, + boolean is_you = mtmp == &gy.youmonst, forcetrap = ((trflags & FORCETRAP) != 0 || (trflags & FAILEDUNTRAP) != 0 || (is_you && (trflags & VIASITTING) != 0)); @@ -1492,13 +1492,13 @@ trapeffect_bear_trap( if ((Levitation || Flying) && !forcetrap) return Trap_Effect_Finished; feeltrap(trap); - if (amorphous(u.umonst->data) || is_whirly(u.umonst->data) - || unsolid(u.umonst->data)) { + if (amorphous(gy.youmonst.data) || is_whirly(gy.youmonst.data) + || unsolid(gy.youmonst.data)) { pline("%s bear trap closes harmlessly through you.", A_Your[trap->madeby_u]); return Trap_Effect_Finished; } - if (!u.usteed && u.umonst->data->msize <= MZ_SMALL) { + if (!u.usteed && gy.youmonst.data->msize <= MZ_SMALL) { pline("%s bear trap closes harmlessly over you.", A_Your[trap->madeby_u]); return Trap_Effect_Finished; @@ -1565,9 +1565,9 @@ trapeffect_slp_gas_trap( struct trap *trap, unsigned int trflags UNUSED) { - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { seetrap(trap); - if (Sleep_resistance || breathless(u.umonst->data)) { + if (Sleep_resistance || breathless(gy.youmonst.data)) { You("are enveloped in a cloud of gas!"); monstseesu(M_SEEN_SLEEP); } else { @@ -1599,7 +1599,7 @@ trapeffect_rust_trap( { struct obj *otmp, *nextobj; - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { seetrap(trap); /* Unlike monsters, traps cannot aim their rust attacks at @@ -1650,7 +1650,7 @@ trapeffect_rust_trap( You("are covered with rust!"); losehp(Maybe_Half_Phys(dam), "rusting away", KILLED_BY); } else if (u.umonnum == PM_GREMLIN && rn2(3)) { - (void) split_mon(u.umonst, (struct monst *) 0); + (void) split_mon(&gy.youmonst, (struct monst *) 0); } } else { boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); @@ -1732,7 +1732,7 @@ trapeffect_fire_trap( struct trap *trap, unsigned int trflags UNUSED) { - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { seetrap(trap); dofiretrap((struct obj *) 0); } else { @@ -1832,7 +1832,7 @@ trapeffect_pit( set to false if the spikes are found to not be relevant */ boolean relevant_spikes = ttype == SPIKED_PIT; - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { boolean plunged = (trflags & TOOKPLUNGE) != 0; boolean viasitting = (trflags & VIASITTING) != 0; boolean conj_pit = conjoined_pits(trap, t_at(u.ux0, u.uy0), TRUE); @@ -1850,7 +1850,7 @@ trapeffect_pit( if (!Sokoban && (Levitation || (Flying && !plunged && !viasitting))) return Trap_Effect_Finished; feeltrap(trap); - if (!Sokoban && is_clinger(u.umonst->data) && !plunged) { + if (!Sokoban && is_clinger(gy.youmonst.data) && !plunged) { if (already_known) { You_see("%s %spit below you.", a_your[trap->madeby_u], ttype == SPIKED_PIT ? "spiked " : ""); @@ -1946,7 +1946,7 @@ trapeffect_pit( } else { /* plunging flyers take spike damage but not pit damage */ if (!conj_pit && !deliberate - && !(plunged && (Flying || is_clinger(u.umonst->data)))) + && !(plunged && (Flying || is_clinger(gy.youmonst.data)))) losehp(Maybe_Half_Phys(rnd(adj_pit ? 3 : 6)), plunged ? "deliberately plunged into a pit" : "fell into a pit", @@ -2015,7 +2015,7 @@ trapeffect_hole( struct trap *trap, unsigned int trflags) { - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { if (!Can_fall_thru(&u.uz)) { seetrap(trap); /* normally done in fall_through */ impossible("dotrap: %ss cannot exist on this level.", @@ -2072,7 +2072,7 @@ trapeffect_telep_trap( struct trap *trap, unsigned int trflags UNUSED) { - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { seetrap(trap); tele_trap(trap); } else { @@ -2090,7 +2090,7 @@ trapeffect_level_telep( struct trap *trap, unsigned int trflags) { - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { seetrap(trap); level_tele_trap(trap, trflags); } else { @@ -2108,7 +2108,7 @@ trapeffect_web( struct trap *trap, unsigned int trflags) { - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { boolean webmsgok = (trflags & NOWEBMSG) == 0; boolean forcetrap = ((trflags & FORCETRAP) != 0 || (trflags & FAILEDUNTRAP) != 0); @@ -2121,9 +2121,9 @@ trapeffect_web( steed_article = ARTICLE_NONE; feeltrap(trap); - if (mu_maybe_destroy_web(u.umonst, webmsgok, trap)) + if (mu_maybe_destroy_web(&gy.youmonst, webmsgok, trap)) return Trap_Effect_Finished; - if (webmaker(u.umonst->data)) { + if (webmaker(gy.youmonst.data)) { if (webmsgok) pline(trap->madeby_u ? "You take a walk on your web." : "There is a spider web here."); @@ -2281,7 +2281,7 @@ trapeffect_statue_trap( struct trap *trap, unsigned int trflags UNUSED) { - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { (void) activate_statue_trap(trap, u.ux, u.uy, FALSE); } else { /* monsters don't trigger statue traps */ @@ -2295,7 +2295,7 @@ trapeffect_magic_trap( struct trap *trap, unsigned int trflags) { - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { seetrap(trap); if (!rn2(30)) { deltrap(trap); @@ -2332,7 +2332,7 @@ trapeffect_anti_magic( rather than the wearer */ if (shoes->spe > 0) { /* no message if a monster does this, it isn't visible enough */ - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { seetrap(trap); pline("A lethargic aura surrounds %s.", yname(shoes)); costly_alteration(shoes, COST_DECHNT); @@ -2343,7 +2343,7 @@ trapeffect_anti_magic( } } - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { int drain, halfd; boolean exclaim_it = FALSE; @@ -2455,7 +2455,7 @@ trapeffect_poly_trap( struct trap *trap, unsigned int trflags) { - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { boolean viasitting = (trflags & VIASITTING) != 0; int steed_article = ARTICLE_THE; char verbbuf[BUFSZ]; @@ -2537,7 +2537,7 @@ trapeffect_landmine( if (wearing_iron_shoes(mtmp)) damage = (damage + 3) / 4; - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { boolean already_seen = trap->tseen; boolean forcetrap = ((trflags & FORCETRAP) != 0 || (trflags & FAILEDUNTRAP) != 0); @@ -2663,7 +2663,7 @@ trapeffect_rolling_boulder_trap( struct trap *trap, unsigned int trflags UNUSED) { - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { int style = ROLL | (trap->tseen ? LAUNCH_KNOWN : 0); feeltrap(trap); @@ -2712,7 +2712,7 @@ trapeffect_magic_portal( struct trap *trap, unsigned int trflags) { - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { feeltrap(trap); domagicportal(trap); } else { @@ -2727,7 +2727,7 @@ trapeffect_vibrating_square( struct trap *trap, unsigned int trflags UNUSED) { - if (mtmp == u.umonst) { + if (mtmp == &gy.youmonst) { feeltrap(trap); /* messages handled elsewhere; the trap symbol is merely to mark the square for future reference */ @@ -2791,7 +2791,7 @@ immune_to_trap(struct monst *mon, unsigned ttype) return TRAP_NOT_IMMUNE; } pm = mon->data; - is_you = (mon == u.umonst); + is_you = (mon == &gy.youmonst); switch (ttype) { case ARROW_TRAP: @@ -2986,7 +2986,7 @@ trapeffect_selector( return trapeffect_vibrating_square(mtmp, trap, trflags); default: impossible("%s encountered a strange trap of type %d.", - (mtmp == u.umonst) ? "You" : "Some monster", + (mtmp == &gy.youmonst) ? "You" : "Some monster", trap->ttyp); } return Trap_Effect_Finished; @@ -3023,7 +3023,7 @@ dotrap(struct trap *trap, unsigned trflags) trapname(ttype, TRUE)); /* do force "pit" while hallucinating */ /* then proceed to normal trap effect */ } else if (!forcetrap) { - if (floor_trigger(ttype) && check_in_air(u.umonst, trflags)) { + if (floor_trigger(ttype) && check_in_air(&gy.youmonst, trflags)) { if (already_seen) { You("%s over %s %s.", u_locomotion("step"), (ttype == ARROW_TRAP && !trap->madeby_u) @@ -3035,7 +3035,7 @@ dotrap(struct trap *trap, unsigned trflags) if (already_seen && !Fumbling && !undestroyable_trap(ttype) && ttype != ANTI_MAGIC && !forcebungle && !plunged && !conj_pit && !adj_pit - && (!rn2(5) || (is_pit(ttype) && is_clinger(u.umonst->data)))) { + && (!rn2(5) || (is_pit(ttype) && is_clinger(gy.youmonst.data)))) { You("escape %s %s.", (ttype == ARROW_TRAP && !trap->madeby_u) ? "an" : a_your[trap->madeby_u], @@ -3056,7 +3056,7 @@ dotrap(struct trap *trap, unsigned trflags) * would be somewhat harsh for what's usually a minor impairment. */ - (void) trapeffect_selector(u.umonst, trap, trflags); + (void) trapeffect_selector(&gy.youmonst, trap, trflags); } staticfn char * @@ -3412,7 +3412,7 @@ launch_obj( break; } } else if (u_at(x, y)) { - int dam = dmgval(singleobj, u.umonst); + int dam = dmgval(singleobj, &gy.youmonst); if (gm.multi) nomul(0); @@ -3845,7 +3845,7 @@ instapetrify(const char *str) { if (Stone_resistance) return; - if (poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM)) + if (poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM)) return; urgent_pline("You turn to stone..."); svk.killer.format = KILLED_BY; @@ -4085,7 +4085,7 @@ float_down( /* check for falling into pool - added by GAN 10/20/86 */ if (!Flying) { if (!u.uswallow && u.ustuck) { - if (sticks(u.umonst->data)) + if (sticks(gy.youmonst.data)) You("aren't able to maintain your hold on %s.", mon_nam(u.ustuck)); else @@ -4199,14 +4199,14 @@ climb_pit(void) display_nhwindow(WIN_MESSAGE, FALSE); clear_nhwindow(WIN_MESSAGE); You("free your %s.", body_part(LEG)); - } else if ((Flying || is_clinger(u.umonst->data)) && !Sokoban) { + } else if ((Flying || is_clinger(gy.youmonst.data)) && !Sokoban) { /* eg fell in pit, then poly'd to a flying monster; or used '>' to deliberately enter it */ You("%s from the %s.", u_locomotion("climb"), pitname); reset_utrap(FALSE); fill_pit(u.ux, u.uy); gv.vision_full_recalc = 1; /* vision limits change */ - } else if (!(--u.utrap) || m_easy_escape_pit(u.umonst)) { + } else if (!(--u.utrap) || m_easy_escape_pit(&gy.youmonst)) { reset_utrap(FALSE); You("%s to the edge of the %s.", (Sokoban && Levitation) @@ -4303,8 +4303,8 @@ dofiretrap( losehp(num, tower_of_flame, KILLED_BY_AN); /* fire damage */ burn_away_slime(); - if (burnarmor(u.umonst) || rn2(3)) { - (void) destroy_items(u.umonst, AD_FIRE, orig_dmg); + if (burnarmor(&gy.youmonst) || rn2(3)) { + (void) destroy_items(&gy.youmonst, AD_FIRE, orig_dmg); ignite_items(gi.invent); } if (!box && burn_floor_objects(u.ux, u.uy, see_it, TRUE) && !see_it) @@ -4325,7 +4325,7 @@ domagictrap(void) int cnt = rnd(4); /* blindness effects */ - if (!resists_blnd(u.umonst)) { + if (!resists_blnd(&gy.youmonst)) { You("are momentarily blinded by a flash of light!"); make_blinded((long) rn1(5, 10), FALSE); if (!Blind) @@ -4362,7 +4362,7 @@ domagictrap(void) if (!Invis) { if (!Blind) self_invis_message(); - } else if (!EInvis && !pm_invisible(u.umonst->data)) { + } else if (!EInvis && !pm_invisible(gy.youmonst.data)) { if (!Blind) { if (!See_invisible) You("can see yourself again!"); @@ -4393,7 +4393,7 @@ domagictrap(void) if (on_level(&u.uz, &qstart_level)) You_feel( "%slike the prodigal son.", - (flags.female || (Upolyd && is_neuter(u.umonst->data))) + (flags.female || (Upolyd && is_neuter(gy.youmonst.data))) ? "oddly " : ""); else @@ -4624,10 +4624,10 @@ acid_damage(struct obj *obj) if (!obj) return; - victim = carried(obj) ? u.umonst : mcarried(obj) ? obj->ocarry : NULL; - vismon = victim && (victim != u.umonst) && canseemon(victim); + victim = carried(obj) ? &gy.youmonst : mcarried(obj) ? obj->ocarry : NULL; + vismon = victim && (victim != &gy.youmonst) && canseemon(victim); - if (victim == u.umonst && inventory_resistance_check(AD_ACID)) + if (victim == &gy.youmonst && inventory_resistance_check(AD_ACID)) return; if (obj->greased) { @@ -4639,7 +4639,7 @@ acid_damage(struct obj *obj) #endif ) { if (!Blind) { - if (victim == u.umonst) + if (victim == &gy.youmonst) Your("%s.", aobjnam(obj, "fade")); else if (vismon) pline("%s %s.", s_suffix(Monnam(victim)), @@ -4941,13 +4941,13 @@ emergency_disrobe(boolean *lostsome) } /* pick a random goodpos() next to x,y for monster mtmp. - mtmp could be u.umonst, uses then crawl_destination(). + mtmp could be &gy.youmonst, uses then crawl_destination(). returns TRUE if any good position found, with the coord in x,y */ boolean rnd_nextto_goodpos(coordxy *x, coordxy *y, struct monst *mtmp) { int i, j; - boolean is_u = (mtmp == u.umonst); + boolean is_u = (mtmp == &gy.youmonst); coordxy nx, ny, k, dirs[N_DIRS]; for (i = 0; i < N_DIRS; ++i) @@ -5086,7 +5086,7 @@ drown(void) water_damage_chain(gi.invent, FALSE); if (u.umonnum == PM_GREMLIN && rn2(3)) { - (void) split_mon(u.umonst, (struct monst *) 0); + (void) split_mon(&gy.youmonst, (struct monst *) 0); } else if (u.umonnum == PM_IRON_GOLEM) { You("rust!"); i = Maybe_Half_Phys(d(2, 6)); @@ -5124,10 +5124,10 @@ drown(void) gv.vision_full_recalc = 1; return FALSE; } - if ((Teleportation || can_teleport(u.umonst->data)) && !Unaware + if ((Teleportation || can_teleport(gy.youmonst.data)) && !Unaware && (Teleport_control || rn2(3) < Luck + 2)) { You("attempt a teleport spell."); /* utcsri!carroll */ - if (!noteleport_level(u.umonst)) { + if (!noteleport_level(&gy.youmonst)) { (void) dotele(FALSE); if (!is_pool(u.ux, u.uy)) return TRUE; @@ -5150,8 +5150,8 @@ drown(void) x = u.ux, y = u.uy; /* have to be able to move in order to crawl */ - if (gm.multi >= 0 && u.umonst->data->mmove - && rnd_nextto_goodpos(&x, &y, u.umonst)) { + if (gm.multi >= 0 && gy.youmonst.data->mmove + && rnd_nextto_goodpos(&x, &y, &gy.youmonst)) { boolean lost = FALSE; /* time to do some strip-tease... */ boolean succ = Is_waterlevel(&u.uz) ? TRUE : emergency_disrobe(&lost); @@ -5262,10 +5262,10 @@ could_untrap(boolean verbosely, boolean check_floor) buf[0] = '\0'; if (near_capacity() >= HVY_ENCUMBER) { Strcpy(buf, "You're too strained to do that."); - } else if ((nohands(u.umonst->data) && !webmaker(u.umonst->data)) - || !u.umonst->data->mmove) { + } else if ((nohands(gy.youmonst.data) && !webmaker(gy.youmonst.data)) + || !gy.youmonst.data->mmove) { Strcpy(buf, "And just how do you expect to do that?"); - } else if (u.ustuck && sticks(u.umonst->data)) { + } else if (u.ustuck && sticks(gy.youmonst.data)) { Sprintf(buf, "You'll have to let go of %s first.", mon_nam(u.ustuck)); } else if (u.ustuck || (welded(uwep) && bimanual(uwep))) { Sprintf(buf, "Your %s seem to be too busy for that.", @@ -5307,7 +5307,7 @@ untrap_prob( if (u_wield_art(ART_STING) || attacks(AD_FIRE, wep)) chance = 1; /* else chance stays 3 */ - } else if (!webmaker(u.umonst->data)) { + } else if (!webmaker(gy.youmonst.data)) { chance = 7; /* 3.7: used to be 30 */ } } @@ -5458,10 +5458,10 @@ try_disarm( return 0; } /* duplicate tight-space checks from test_move */ - if (u.dx && u.dy && bad_rock(u.umonst->data, u.ux, ttmp->ty) - && bad_rock(u.umonst->data, ttmp->tx, u.uy)) { + if (u.dx && u.dy && bad_rock(gy.youmonst.data, u.ux, ttmp->ty) + && bad_rock(gy.youmonst.data, ttmp->tx, u.uy)) { if ((gi.invent && (inv_weight() + weight_cap() > WT_TOOMUCH_DIAGONAL)) - || bigmonst(u.umonst->data)) { + || bigmonst(gy.youmonst.data)) { /* don't allow untrap if they can't get thru to it */ You("are unable to reach the %s!", trapname(ttype, FALSE)); return 0; @@ -5490,7 +5490,7 @@ try_disarm( } else if (ttype == WEB) { struct trap *ttmp2 = t_at(u.ux, u.uy); - if (!webmaker(u.umonst->data) + if (!webmaker(gy.youmonst.data) /* don't always try to spread the web */ && !rn2(3) /* is there already a trap at hero's spot? @@ -5736,7 +5736,7 @@ help_monster_out( You("grab the trapped %s using your bare %s.", mtmp_pmname, makeplural(body_part(HAND))); - if (poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM)) { + if (poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM)) { display_nhwindow(WIN_MESSAGE, FALSE); } else { char kbuf[BUFSZ]; @@ -5864,7 +5864,7 @@ untrap( /* 'force' is true for #invoke; if carrying MKoT, make it be true for #untrap or autounlock */ - if (!force && has_magic_key(u.umonst)) + if (!force && has_magic_key(&gy.youmonst)) force = TRUE; if (!rx && !container) { @@ -6106,7 +6106,7 @@ openholdingtrap( struct trap *t, tdummy; char buf[BUFSZ], whichbuf[20]; const char *trapdescr = 0, *which = 0; - boolean ishero = (mon == u.umonst); + boolean ishero = (mon == &gy.youmonst); if (!mon) return FALSE; @@ -6214,7 +6214,7 @@ closeholdingtrap( { struct trap *t; unsigned dotrapflags; - boolean ishero = (mon == u.umonst), result; + boolean ishero = (mon == &gy.youmonst), result; if (!mon) return FALSE; @@ -6255,7 +6255,7 @@ openfallingtrap( boolean *noticed) /* set to true iff hero notices the effect; */ { /* otherwise left with its previous value intact */ struct trap *t; - boolean ishero = (mon == u.umonst), result; + boolean ishero = (mon == &gy.youmonst), result; if (!mon) return FALSE; @@ -6451,7 +6451,7 @@ chest_trap( } else { monstunseesu(M_SEEN_ELEC); } - (void) destroy_items(u.umonst, AD_ELEC, orig_dmg); + (void) destroy_items(&gy.youmonst, AD_ELEC, orig_dmg); if (dmg) losehp(dmg, "electric shock", KILLED_BY_AN); break; @@ -6478,7 +6478,7 @@ chest_trap( if (Hallucination) pline("What a groovy feeling!"); else - You("%s%s...", stagger(u.umonst->data, "stagger"), + You("%s%s...", stagger(gy.youmonst.data, "stagger"), Halluc_resistance ? "" : Blind ? " and get dizzy" : " and your vision blurs"); @@ -6805,7 +6805,7 @@ lava_effects(void) } feel_newsym(u.ux, u.uy); /* in case Blind, map the lava here */ burn_away_slime(); - if (likes_lava(u.umonst->data)) + if (likes_lava(gy.youmonst.data)) return FALSE; usurvive = Fire_resistance || (Wwalking && dmg < u.uhp); @@ -6981,7 +6981,7 @@ lava_effects(void) } burn_stuff: - (void) destroy_items(u.umonst, AD_FIRE, dmg); + (void) destroy_items(&gy.youmonst, AD_FIRE, dmg); ignite_items(gi.invent); return FALSE; } diff --git a/src/u_init.c b/src/u_init.c index 1d5a5c80f..2b322b497 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -956,9 +956,6 @@ u_init_misc(void) (void) memset((genericptr_t) &ubirthday, 0, sizeof(ubirthday)); (void) memset((genericptr_t) &urealtime, 0, sizeof(urealtime)); - u.umonst = newmonst(); - *u.umonst = cg.zeromonst; - u.umonst->cham = u.mcham = NON_PM; u.uroleplay = tmpuroleplay; /* restore options set via rcfile */ #if 0 /* documentation of more zero values as desirable */ diff --git a/src/uhitm.c b/src/uhitm.c index eb04e0d1a..00858508e 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -79,8 +79,8 @@ mhitm_mgc_atk_negated( int armpro; boolean negated; - /* mcan doesn't apply to u.umonst; hero can't be cancelled */ - if (magr != u.umonst && magr->mcan) + /* mcan doesn't apply to youmonst; hero can't be cancelled */ + if (magr != &gy.youmonst && magr->mcan) return TRUE; /* no message if attacker has been cancelled */ armpro = magic_negation(mdef); @@ -88,7 +88,7 @@ mhitm_mgc_atk_negated( if (negated) { /* attack has been thwarted by negation, aka magical cancellation */ if (verbosely) { - if (mdef == u.umonst) + if (mdef == &gy.youmonst) You("avoid harm."); else if (gv.vis && canseemon(mdef)) pline_mon(mdef, "%s avoids harm.", Monnam(mdef)); @@ -375,7 +375,7 @@ find_roll_to_hit( tmp = 1 + abon() + find_mac(mtmp) + u.uhitinc + (sgn(Luck) * ((abs(Luck) + 2) / 3)) - + maybe_polyd(u.umonst->data->mlevel, u.ulevel); + + maybe_polyd(gy.youmonst.data->mlevel, u.ulevel); /* some actions should occur only once during multiple attacks */ if (!(*attk_count)++) { @@ -401,7 +401,7 @@ find_roll_to_hit( tmp += (u.ulevel / 3) + 2; } if (is_orc(mtmp->data) - && maybe_polyd(is_elf(u.umonst->data), Race_if(PM_ELF))) + && maybe_polyd(is_elf(gy.youmonst.data), Race_if(PM_ELF))) tmp++; /* encumbrance: with a lot of luggage, your agility diminishes */ @@ -521,7 +521,7 @@ do_attack(struct monst *mtmp) if (attack_checks(mtmp, uwep)) return TRUE; - if (Upolyd && noattacks(u.umonst->data)) { + if (Upolyd && noattacks(gy.youmonst.data)) { /* certain "pacifist" monsters don't attack */ You("have no way to attack monsters physically."); mtmp->mstrategy &= ~STRAT_WAITMASK; @@ -541,7 +541,7 @@ do_attack(struct monst *mtmp) if (flags.verbose) { if (uwep) You("begin bashing monsters with %s.", yname(uwep)); - else if (!cantwield(u.umonst->data)) + else if (!cantwield(gy.youmonst.data)) You("begin %s monsters with your %s %s.", ing_suffix(Role_if(PM_MONK) ? "strike" : "bash"), uarmg ? "gloved" : "bare", /* Del Lamb */ @@ -565,7 +565,7 @@ do_attack(struct monst *mtmp) if (Upolyd) (void) hmonas(mtmp); else - (void) hitum(mtmp, u.umonst->data->mattk); + (void) hitum(mtmp, gy.youmonst.data->mattk); mtmp->mstrategy &= ~STRAT_WAITMASK; atk_done: @@ -628,7 +628,7 @@ known_hitum( monflee(mon, !rn2(3) ? rnd(100) : 0, FALSE, TRUE); if (u.ustuck == mon && !u.uswallow - && !sticks(u.umonst->data)) + && !sticks(gy.youmonst.data)) set_ustuck((struct monst *) 0); } /* Vorpal Blade hit converted to miss */ @@ -858,7 +858,7 @@ hmon_hitmon_barehands(struct _hitmon_data *hmd, struct monst *mon) spcdmgflg = uarmg ? W_ARMG : (((hmd->twohits == 0 || hmd->twohits == 1) ? W_RINGR : 0L) | ((hmd->twohits == 0 || hmd->twohits == 2) ? W_RINGL : 0L)); - hmd->dmg += special_dmgval(u.umonst, mon, spcdmgflg, &silverhit); + hmd->dmg += special_dmgval(&gy.youmonst, mon, spcdmgflg, &silverhit); /* copy silverhit info back into struct _hitmon_data *hmd */ switch (hmd->twohits) { @@ -1013,7 +1013,7 @@ hmon_hitmon_weapon_melee( } if (obj->oartifact - && artifact_hit(u.umonst, mon, obj, &hmd->dmg, hmd->dieroll)) { + && artifact_hit(&gy.youmonst, mon, obj, &hmd->dmg, hmd->dieroll)) { /* artifact_hit updates 'tmp' but doesn't inflict any damage; however, it might cause carried items to be destroyed and they might do so */ @@ -1265,7 +1265,7 @@ hmon_hitmon_misc_obj( case CREAM_PIE: case BLINDING_VENOM: mon->msleeping = 0; - if (can_blnd(u.umonst, mon, + if (can_blnd(&gy.youmonst, mon, (uchar) ((obj->otyp == BLINDING_VENOM) ? AT_SPIT : AT_WEAP), @@ -1819,7 +1819,7 @@ hmon_hitmon( && thrown != HMON_THROWN && thrown != HMON_KICKED) /* this gives "harmlessly passes through" feedback even when hero doesn't see it happen; presumably sensed by touch? */ - hmd.hittxt = shade_miss(u.umonst, mon, obj, FALSE, TRUE); + hmd.hittxt = shade_miss(&gy.youmonst, mon, obj, FALSE, TRUE); } if (hmd.jousting) { @@ -1925,7 +1925,7 @@ hmon_hitmon( wakeup(mon, TRUE); if (maybe_knockback - && mhitm_knockback(u.umonst, mon, u.umonst->data->mattk, + && mhitm_knockback(&gy.youmonst, mon, gy.youmonst.data->mattk, &hitflags, TRUE)) { if ((hitflags & M_ATTK_DEF_DIED) != 0) hmd.destroyed = TRUE; @@ -2021,7 +2021,7 @@ shade_miss( boolean verbose) { const char *what, *whose, *target; - boolean youagr = (magr == u.umonst), youdef = (mdef == u.umonst); + boolean youagr = (magr == &gy.youmonst), youdef = (mdef == &gy.youmonst); /* we're using dmgval() for zero/not-zero, not for actual damage amount */ if (mdef->data != &mons[PM_SHADE] || (obj && dmgval(obj, mdef))) @@ -2029,7 +2029,7 @@ shade_miss( if (verbose && ((youdef || cansee(mdef->mx, mdef->my) || sensemon(mdef)) - || (magr == u.umonst && m_next2u(mdef)))) { + || (magr == &gy.youmonst && m_next2u(mdef)))) { static const char harmlessly_thru[] = " harmlessly through "; what = (!obj || shade_aware(obj)) ? "attack" : cxname(obj); @@ -2138,7 +2138,7 @@ demonpet(void) pline("Some hell-p has arrived!"); i = !rn2(6) ? ndemon(u.ualign.type) : NON_PM; - pm = i != NON_PM ? &mons[i] : u.umonst->data; + pm = i != NON_PM ? &mons[i] : gy.youmonst.data; if ((dtmp = makemon(pm, u.ux, u.uy, NO_MM_FLAGS)) != 0) (void) tamedog(dtmp, (struct obj *) 0, FALSE); exercise(A_WIS, TRUE); @@ -2152,7 +2152,7 @@ theft_petrifies(struct obj *otmp) return FALSE; #if 0 /* no poly_when_stoned() critter has theft capability */ - if (poly_when_stoned(u.umonst->data) && polymon(PM_STONE_GOLEM)) { + if (poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM)) { display_nhwindow(WIN_MESSAGE, FALSE); /* --More-- */ return TRUE; } @@ -2182,7 +2182,7 @@ steal_it(struct monst *mdef, struct attack *mattk) /* look for worn body armor */ ustealo = (struct obj *) 0; - if (could_seduce(u.umonst, mdef, mattk) && mdef->mcanmove) { + if (could_seduce(&gy.youmonst, mdef, mattk) && mdef->mcanmove) { /* find armor, and move it to end of inventory in the process */ minvent_ptr = &mdef->minvent; while ((otmp = *minvent_ptr) != 0) @@ -2206,7 +2206,7 @@ steal_it(struct monst *mdef, struct attack *mattk) but was using hardcoded pronouns She/her for target monster; switch to dynamic pronoun */ if (gender(mdef) == (int) u.mfemale - && u.umonst->data->mlet == S_NYMPH) + && gy.youmonst.data->mlet == S_NYMPH) You("charm %s. %s gladly hands over %s%s possessions.", mon_nam(mdef), upstart(strcpy(heshe, mhe(mdef))), !gold ? "" : "most of ", mhis(mdef)); @@ -2284,7 +2284,7 @@ mhitm_ad_rust( { struct permonst *pd = mdef->data; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (completelyrusts(pd)) { /* iron golem */ /* note: the life-saved case is hypothetical because @@ -2296,7 +2296,7 @@ mhitm_ad_rust( } erode_armor(mdef, ERODE_RUST); mhm->damage = 0; /* damageum(), int tmp */ - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (magr->mcan) { @@ -2308,7 +2308,7 @@ mhitm_ad_rust( rehumanize(); return; } - erode_armor(u.umonst, ERODE_RUST); + erode_armor(&gy.youmonst, ERODE_RUST); } else { /* mhitm */ if (magr->mcan) @@ -2339,11 +2339,11 @@ mhitm_ad_corr( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ erode_armor(mdef, ERODE_CORRODE); mhm->damage = 0; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (magr->mcan) @@ -2366,7 +2366,7 @@ mhitm_ad_dcay( { struct permonst *pd = mdef->data; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (completelyrots(pd)) { /* wood golem or leather golem */ pline("%s %s to pieces!", Monnam(mdef), @@ -2375,7 +2375,7 @@ mhitm_ad_dcay( } erode_armor(mdef, ERODE_ROT); mhm->damage = 0; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (magr->mcan) @@ -2421,12 +2421,12 @@ mhitm_ad_dren( { boolean negated = mhitm_mgc_atk_negated(magr, mdef, FALSE); - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (!negated && !rn2(4)) xdrainenergym(mdef, TRUE); mhm->damage = 0; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (!negated && !rn2(4)) /* 25% chance */ @@ -2446,7 +2446,7 @@ mhitm_ad_drli( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (!rn2(3) && !(resists_drli(mdef) || defended(mdef, AD_DRLI)) && !mhitm_mgc_atk_negated(magr, mdef, TRUE)) { @@ -2476,7 +2476,7 @@ mhitm_ad_drli( /* unlike hitting with Stormbringer, wounded hero doesn't heal any from the drained life */ } - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (!rn2(3) && !Drain_resistance @@ -2525,7 +2525,7 @@ mhitm_ad_fire( struct permonst *pd = mdef->data; const int orig_dmg = mhm->damage; /* damage coming into the function */ - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (mhitm_mgc_atk_negated(magr, mdef, TRUE)) { mhm->damage = 0; @@ -2558,7 +2558,7 @@ mhitm_ad_fire( } mhm->damage += destroy_items(mdef, AD_FIRE, orig_dmg); ignite_items(mdef->minvent); - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (!mhitm_mgc_atk_negated(magr, mdef, TRUE)) { @@ -2577,7 +2577,7 @@ mhitm_ad_fire( monstunseesu(M_SEEN_FIRE); } if ((int) magr->m_lev > rn2(20)) { - (void) destroy_items(u.umonst, AD_FIRE, orig_dmg); + (void) destroy_items(&gy.youmonst, AD_FIRE, orig_dmg); ignite_items(gi.invent); } burn_away_slime(); @@ -2629,7 +2629,7 @@ mhitm_ad_cold( { const int orig_dmg = mhm->damage; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (mhitm_mgc_atk_negated(magr, mdef, TRUE)) { mhm->damage = 0; @@ -2645,7 +2645,7 @@ mhitm_ad_cold( mhm->damage = 0; } mhm->damage += destroy_items(mdef, AD_COLD, orig_dmg); - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (!mhitm_mgc_atk_negated(magr, mdef, TRUE)) { @@ -2658,7 +2658,7 @@ mhitm_ad_cold( monstunseesu(M_SEEN_COLD); } if ((int) magr->m_lev > rn2(20)) - (void) destroy_items(u.umonst, AD_COLD, orig_dmg); + (void) destroy_items(&gy.youmonst, AD_COLD, orig_dmg); } else mhm->damage = 0; } else { @@ -2687,7 +2687,7 @@ mhitm_ad_elec( { const int orig_dmg = mhm->damage; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (mhitm_mgc_atk_negated(magr, mdef, TRUE)) { mhm->damage = 0; @@ -2703,7 +2703,7 @@ mhitm_ad_elec( mhm->damage = 0; } mhm->damage += destroy_items(mdef, AD_ELEC, orig_dmg); - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (!mhitm_mgc_atk_negated(magr, mdef, TRUE)) { @@ -2716,7 +2716,7 @@ mhitm_ad_elec( monstunseesu(M_SEEN_ELEC); } if ((int) magr->m_lev > rn2(20)) - (void) destroy_items(u.umonst, AD_ELEC, orig_dmg); + (void) destroy_items(&gy.youmonst, AD_ELEC, orig_dmg); } else mhm->damage = 0; } else { @@ -2743,11 +2743,11 @@ mhitm_ad_acid( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (resists_acid(mdef) || defended(mdef, AD_ACID)) mhm->damage = 0; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (!magr->mcan && !rn2(3)) @@ -2794,7 +2794,7 @@ mhitm_ad_sgld( struct permonst *pa = magr->data; struct permonst *pd = mdef->data; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ struct obj *mongold = findgold(mdef->minvent); @@ -2812,7 +2812,7 @@ mhitm_ad_sgld( } exercise(A_DEX, TRUE); mhm->damage = 0; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (pd->mlet == pa->mlet) @@ -2860,7 +2860,7 @@ mhitm_ad_tlpt( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (mhm->damage <= 0) mhm->damage = 1; @@ -2881,7 +2881,7 @@ mhitm_ad_tlpt( mhm->damage = mdef->mhp - 1; } } - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ int tmphp; @@ -2961,7 +2961,7 @@ mhitm_ad_blnd( struct monst *mdef, /* defender */ struct mhitm_data *mhm) /* optional for monster vs monster */ { - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (can_blnd(magr, mdef, mattk->aatyp, (struct obj *) 0)) { if (!Blind && mdef->mcansee) @@ -2973,7 +2973,7 @@ mhitm_ad_blnd( mdef->mblinded = mhm->damage; } mhm->damage = 0; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ if (can_blnd(magr, mdef, mattk->aatyp, (struct obj *) 0)) { if (!Blind) @@ -3019,7 +3019,7 @@ mhitm_ad_curs( struct permonst *pa = magr->data; struct permonst *pd = mdef->data; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (night() && !rn2(10) && !mdef->mcan) { if (pd == &mons[PM_CLAY_GOLEM]) { @@ -3034,7 +3034,7 @@ mhitm_ad_curs( } } mhm->damage = 0; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (!night() && pa == &mons[PM_GREMLIN]) @@ -3126,7 +3126,7 @@ mhitm_ad_drst( boolean negated = mhitm_mgc_atk_negated(magr, mdef, FALSE); struct permonst *pa = magr->data; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (!negated && !rn2(8)) { Your("%s was poisoned!", mpoisons_subj(magr, mattk)); @@ -3140,7 +3140,7 @@ mhitm_ad_drst( mhm->damage += rn1(10, 6); } } - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ int ptmp = A_STR; /* A_STR == 0 */ char buf[BUFSZ]; @@ -3182,7 +3182,7 @@ mhitm_ad_drin( * attack and no longer wearing any amulet after the attack. */ - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ struct obj *helmet; @@ -3213,13 +3213,13 @@ mhitm_ad_drin( amu = which_armor(mdef, W_AMUL); lifsav = amu && amu->otyp == AMULET_OF_LIFE_SAVING; - (void) eat_brains(u.umonst, mdef, TRUE, &mhm->damage); + (void) eat_brains(&gy.youmonst, mdef, TRUE, &mhm->damage); /* skip further AD_DRIN if amulet of life-saving got used up */ if (lifsav && !which_armor(mdef, W_AMUL)) gs.skipdrin = TRUE; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (defends(AD_DRIN, uwep) || !has_head(pd)) { @@ -3311,14 +3311,14 @@ mhitm_ad_stck( struct permonst *pd = mdef->data; boolean barbs = (magr->data == &mons[PM_BARBED_DEVIL]); - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (!negated && !sticks(pd) && m_next2u(mdef)) { set_ustuck(mdef); /* it's now stuck to you */ if (barbs) Your("barbs stick to %s!", y_monnam(mdef)); } - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (!negated && !u.ustuck && !sticks(pd)) { @@ -3341,7 +3341,7 @@ mhitm_ad_wrap( struct permonst *pd = mdef->data, *pa = magr->data; boolean coil = slithy(pa) && (pa->mlet == S_SNAKE || pa->mlet == S_NAGA); - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (!sticks(pd)) { boolean tailmiss = !gn.notonhead; @@ -3373,7 +3373,7 @@ mhitm_ad_wrap( } } else mhm->damage = 0; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ if ((!magr->mcan || u.ustuck == magr) && !sticks(pd)) { if (!u.ustuck && !rn2(10)) { @@ -3432,7 +3432,7 @@ mhitm_ad_plys( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (!rn2(3) && mhm->damage < mdef->mhp && !mhitm_mgc_atk_negated(magr, mdef, TRUE)) { @@ -3440,7 +3440,7 @@ mhitm_ad_plys( pline("%s is frozen by you!", Monnam(mdef)); paralyze_monst(mdef, rnd(10)); } - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (gm.multi >= 0 && !rn2(3) @@ -3481,7 +3481,7 @@ mhitm_ad_slee( struct monst *mdef, struct mhitm_data *mhm UNUSED) { - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (!mdef->msleeping && !mhitm_mgc_atk_negated(magr, mdef, FALSE) && sleep_monst(mdef, rnd(10), -1)) { @@ -3489,7 +3489,7 @@ mhitm_ad_slee( pline("%s is put to sleep by you!", Monnam(mdef)); slept_monst(mdef); } - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (gm.multi >= 0 && !rn2(5) @@ -3530,7 +3530,7 @@ mhitm_ad_slim( boolean negated = mhitm_mgc_atk_negated(magr, mdef, FALSE); struct permonst *pd = mdef->data; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (negated) return; /* physical damage only */ @@ -3550,7 +3550,7 @@ mhitm_ad_slim( } mhm->damage = 0; } - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (negated) { @@ -3605,10 +3605,10 @@ mhitm_ad_ench( struct monst *mdef, struct mhitm_data *mhm UNUSED) { - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ /* there's no msomearmor() function, so just do damage */ - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ boolean negated = mhitm_mgc_atk_negated(magr, mdef, FALSE); @@ -3659,7 +3659,7 @@ mhitm_ad_slow( if (defended(mdef, AD_SLOW)) return; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (!negated && mdef->mspeed != MSLOW) { unsigned int oldspeed = mdef->mspeed; @@ -3668,7 +3668,7 @@ mhitm_ad_slow( if (mdef->mspeed != oldspeed && canseemon(mdef)) pline("%s slows down.", Monnam(mdef)); } - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (!negated && HFast && !rn2(4)) @@ -3691,14 +3691,14 @@ mhitm_ad_conf( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (!mdef->mconf) { if (canseemon(mdef)) pline("%s looks confused.", Monnam(mdef)); mdef->mconf = 1; } - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (!magr->mcan && !rn2(4) && !magr->mspec_used) { @@ -3733,7 +3733,7 @@ mhitm_ad_poly( boolean negated = (mhitm_mgc_atk_negated(magr, mdef, FALSE) || magr->mspec_used); - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ /* require weaponless attack in order to honor AD_POLY */ if (!uwep && mhm->damage < mdef->mhp) { @@ -3741,14 +3741,14 @@ mhitm_ad_poly( /* assume that you can tell by touch if blinded */ pline("%s is not transformed.", Monnam(mdef)); } else { - mhm->damage = mon_poly(u.umonst, mdef, mhm->damage); + mhm->damage = mon_poly(&gy.youmonst, mdef, mhm->damage); if (DEADMONSTER(mdef)) mhm->hitflags |= M_ATTK_DEF_DIED; mhm->hitflags |= M_ATTK_HIT; mhm->done = TRUE; } } - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (Maybe_Half_Phys(mhm->damage) < (Upolyd ? u.mh : u.uhp)) { @@ -3756,7 +3756,7 @@ mhitm_ad_poly( if (magr->mcan) You("aren't transformed."); } else { - mhm->damage = mon_poly(magr, u.umonst, mhm->damage); + mhm->damage = mon_poly(magr, &gy.youmonst, mhm->damage); mhm->hitflags |= M_ATTK_HIT; mhm->done = TRUE; } @@ -3781,12 +3781,12 @@ mhitm_ad_famn( { struct permonst *pd = mdef->data; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm; hero can't polymorph into anything with this attack so this won't happen; if it could, it would be the same as the mhitm case except for messaging */ goto mhitm_famn; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ pline_mon(magr, "%s reaches out, and your body shrivels.", Monnam(magr)); @@ -3812,12 +3812,12 @@ mhitm_ad_pest( struct attack alt_attk; struct permonst *pa = magr->data; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm; hero can't polymorph into anything with this attack so this won't happen; if it could, it would be the same as the mhitm case except for messaging */ goto mhitm_pest; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ pline_mon(magr, "%s reaches out, and you feel fever and chills.", Monnam(magr)); @@ -3841,12 +3841,12 @@ mhitm_ad_deth( { struct permonst *pd = mdef->data; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm; hero can't polymorph into anything with this attack so this won't happen; if it could, it would be the same as the mhitm case except for messaging */ goto mhitm_deth; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ pline_mon(magr, "%s reaches out with its deadly touch.", Monnam(magr)); if (is_undead(pd)) { @@ -3901,10 +3901,10 @@ mhitm_ad_halu( { struct permonst *pd = mdef->data; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ mhm->damage = 0; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ mhm->damage = 0; } else { @@ -3924,7 +3924,7 @@ boolean do_stone_u(struct monst *mtmp) { if (!Stoned && !Stone_resistance - && !(poly_when_stoned(u.umonst->data) + && !(poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM))) { int kformat = KILLED_BY_AN; const char *kname = pmname(mtmp->data, Mgender(mtmp)); @@ -3985,7 +3985,7 @@ mhitm_ad_phys( struct permonst *pa = magr->data; struct permonst *pd = mdef->data; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (pd == &mons[PM_SHADE]) { mhm->damage = 0; @@ -4018,7 +4018,7 @@ mhitm_ad_phys( mhm->damage = 1; } } - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ if (mattk->aatyp == AT_HUGS && !sticks(pd)) { if (!u.ustuck && rn2(2)) { @@ -4103,7 +4103,7 @@ mhitm_ad_phys( if (cloneu()) You("divide as %s hits you!", mon_nam(magr)); } - rustm(u.umonst, otmp); + rustm(&gy.youmonst, otmp); if (was_poisoned && gm.mhitu_dieroll <= 5) { char buf[BUFSZ]; @@ -4204,12 +4204,12 @@ mhitm_ad_ston( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (!munstone(mdef, TRUE)) minstapetrify(mdef, TRUE); mhm->damage = 0; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (!rn2(3)) { @@ -4268,12 +4268,12 @@ mhitm_ad_were( { struct permonst *pa = magr->data; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ mhitm_ad_phys(magr, mattk, mdef, mhm); if (mhm->done) return; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (!rn2(4) && u.ulycn == NON_PM @@ -4299,12 +4299,12 @@ mhitm_ad_heal( { struct permonst *pd = mdef->data; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ mhitm_ad_phys(magr, mattk, mdef, mhm); if (mhm->done) return; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ /* a cancelled nurse is just an ordinary monster, * nurses don't heal those that cause petrification */ @@ -4391,7 +4391,7 @@ mhitm_ad_stun( { struct permonst *pd = mdef->data; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ if (!Blind) pline("%s %s for a moment.", Monnam(mdef), @@ -4400,7 +4400,7 @@ mhitm_ad_stun( mhitm_ad_phys(magr, mattk, mdef, mhm); if (mhm->done) return; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (!magr->mcan && !rn2(4)) { @@ -4426,7 +4426,7 @@ mhitm_ad_legs( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ #if 0 if (u.ucancelled) { @@ -4437,7 +4437,7 @@ mhitm_ad_legs( mhitm_ad_phys(magr, mattk, mdef, mhm); if (mhm->done) return; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; const char *sidestr = (side == RIGHT_SIDE) ? "right" : "left", @@ -4496,10 +4496,10 @@ mhitm_ad_dgst( { struct permonst *pd = mdef->data; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ mhm->damage = 0; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ mhm->damage = 0; } else { @@ -4571,10 +4571,10 @@ mhitm_ad_samu( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ mhm->damage = 0; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); /* when the Wizard or quest nemesis hits, there's a 1/20 chance @@ -4596,12 +4596,12 @@ mhitm_ad_dise( { struct permonst *pa = magr->data, *pd = mdef->data; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm; hero can't polymorph into anything with this attack so this won't happen; if it could, it would be the same as the mhitm case except for messaging */ goto mhitm_dise; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ hitmsg(magr, mattk); if (!diseasemu(pa)) @@ -4626,11 +4626,11 @@ mhitm_ad_sedu( { struct permonst *pa = magr->data; - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ steal_it(mdef, mattk); mhm->damage = 0; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ char buf[BUFSZ]; @@ -4639,11 +4639,11 @@ mhitm_ad_sedu( if (magr->mcan) return; /* Continue below */ - } else if (dmgtype(u.umonst->data, AD_SEDU) + } else if (dmgtype(gy.youmonst.data, AD_SEDU) /* !SYSOPT_SEDUCE: when hero is attacking and AD_SSEX is disabled, it would be changed to another damage type, but when defending, it remains as-is */ - || dmgtype(u.umonst->data, AD_SSEX)) { + || dmgtype(gy.youmonst.data, AD_SSEX)) { pline_mon(magr, "%s %s.", Monnam(magr), Deaf ? "says something but you can't hear it" : magr->minvent @@ -4751,12 +4751,12 @@ void mhitm_ad_ssex(struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { - if (magr == u.umonst) { + if (magr == &gy.youmonst) { /* uhitm */ mhitm_ad_sedu(magr, mattk, mdef, mhm); if (mhm->done) return; - } else if (mdef == u.umonst) { + } else if (mdef == &gy.youmonst) { /* mhitu */ if (SYSOPT_SEDUCE) { if (could_seduce(magr, mdef, mattk) == 1 && !magr->mcan) @@ -4845,13 +4845,13 @@ damageum( mhm.specialdmg = specialdmg; mhm.done = FALSE; - if (is_demon(u.umonst->data) && !rn2(13) && !uwep + if (is_demon(gy.youmonst.data) && !rn2(13) && !uwep && u.umonnum != PM_AMOROUS_DEMON && u.umonnum != PM_BALROG) { demonpet(); return M_ATTK_MISS; } - mhitm_adtyping(u.umonst, mattk, mdef, &mhm); + mhitm_adtyping(&gy.youmonst, mattk, mdef, &mhm); if (mhm.done) return mhm.hitflags; @@ -4930,12 +4930,12 @@ explum(struct monst *mdef, struct attack *mattk) staticfn void start_engulf(struct monst *mdef) { - boolean u_digest = digests(u.umonst->data), - u_enfold = enfolds(u.umonst->data); + boolean u_digest = digests(gy.youmonst.data), + u_enfold = enfolds(gy.youmonst.data); if (!Invisible) { map_location(u.ux, u.uy, TRUE); - tmp_at(DISP_ALWAYS, mon_to_glyph(u.umonst, rn2_on_display_rng)); + tmp_at(DISP_ALWAYS, mon_to_glyph(&gy.youmonst, rn2_on_display_rng)); tmp_at(mdef->mx, mdef->my); } You("%s %s%s!", @@ -4961,8 +4961,8 @@ gulpum(struct monst *mdef, struct attack *mattk) int tmp; int dam = d((int) mattk->damn, (int) mattk->damd); boolean fatal_gulp, - u_digest = digests(u.umonst->data), - u_enfold = enfolds(u.umonst->data); + u_digest = digests(gy.youmonst.data), + u_enfold = enfolds(gy.youmonst.data); struct obj *otmp; struct permonst *pd = mdef->data; const char *expel_verb = u_digest ? "regurgitate" @@ -4977,11 +4977,11 @@ gulpum(struct monst *mdef, struct attack *mattk) * after exactly 1 round of attack otherwise. -KAA */ - if (!engulf_target(u.umonst, mdef)) + if (!engulf_target(&gy.youmonst, mdef)) return M_ATTK_MISS; if (!(u_digest && u.uhunger >= 1500) && !u.uswallow) { - if (!flaming(u.umonst->data)) { + if (!flaming(gy.youmonst.data)) { for (otmp = mdef->minvent; otmp; otmp = otmp->nobj) (void) snuff_lit(otmp); } @@ -5060,14 +5060,14 @@ gulpum(struct monst *mdef, struct attack *mattk) "you totally digest " will be coming soon (after several turns) but the level-gain message seems out of order if the kill message is left implicit */ - gm.mswallower = u.umonst; + gm.mswallower = &gy.youmonst; xkilled(mdef, XKILL_GIVEMSG | XKILL_NOCORPSE); if (!DEADMONSTER(mdef)) { /* monster lifesaved */ You("hurriedly regurgitate the sizzling in your %s.", body_part(STOMACH)); } else { tmp = 1 + (pd->cwt >> 8); - if (corpse_chance(mdef, u.umonst, TRUE) + if (corpse_chance(mdef, &gy.youmonst, TRUE) && !(svm.mvitals[monsndx(pd)].mvflags & G_NOCORPSE)) { /* nutrition only if there can be a corpse */ u.uhunger += (pd->cnutrit + 1) / 2; @@ -5105,7 +5105,7 @@ gulpum(struct monst *mdef, struct attack *mattk) end_engulf(); return M_ATTK_DEF_DIED; case AD_PHYS: - if (u.umonst->data == &mons[PM_FOG_CLOUD]) { + if (gy.youmonst.data == &mons[PM_FOG_CLOUD]) { pline("%s is laden with your moisture.", Monnam(mdef)); if ((breathless(pd) || amphibious(pd)) && !flaming(pd)) { dam = 0; @@ -5113,7 +5113,7 @@ gulpum(struct monst *mdef, struct attack *mattk) } } else { pline("%s is %s!", Monnam(mdef), - enfolds(u.umonst->data) ? "being squashed" + enfolds(gy.youmonst.data) ? "being squashed" : "pummeled with your debris"); } break; @@ -5125,7 +5125,7 @@ gulpum(struct monst *mdef, struct attack *mattk) } break; case AD_BLND: - if (can_blnd(u.umonst, mdef, mattk->aatyp, + if (can_blnd(&gy.youmonst, mdef, mattk->aatyp, (struct obj *) 0)) { if (mdef->mcansee) pline("%s can't see in there!", Monnam(mdef)); @@ -5185,7 +5185,7 @@ gulpum(struct monst *mdef, struct attack *mattk) return M_ATTK_DEF_DIED; } You("%s %s!", expel_verb, mon_nam(mdef)); - if ((Slow_digestion || is_animal(u.umonst->data)) && u_digest) { + if ((Slow_digestion || is_animal(gy.youmonst.data)) && u_digest) { pline("Obviously, you didn't like %s taste.", s_suffix(mon_nam(mdef))); } @@ -5203,7 +5203,7 @@ missum( if (wouldhavehit) /* monk is missing due to penalty for wearing suit */ Your("armor is rather cumbersome..."); - if (could_seduce(u.umonst, mdef, mattk)) + if (could_seduce(&gy.youmonst, mdef, mattk)) You("pretend to be friendly to %s.", mon_nam(mdef)); else if (canspotmon(mdef) && flags.verbose) You("miss %s.", mon_nam(mdef)); @@ -5217,7 +5217,7 @@ missum( boolean m_is_steadfast(struct monst *mtmp) { - boolean is_u = (mtmp == u.umonst); + boolean is_u = (mtmp == &gy.youmonst); struct obj *otmp = is_u ? uwep : MON_WEP(mtmp); /* must be on the ground (or in water) */ @@ -5231,7 +5231,7 @@ m_is_steadfast(struct monst *mtmp) return TRUE; /* steadfast if carrying any loadstone (and not floating or flying); - 'is_u' test not needed here; m_carrying() is 'u.umonst' aware */ + 'is_u' test not needed here; m_carrying() is 'youmonst' aware */ if (m_carrying(mtmp, LOADSTONE)) return TRUE; /* when mounted and steed is target of knockback, check the rider for @@ -5257,8 +5257,8 @@ mhitm_knockback( coordxy dx, dy, defx, defy; int knockdistance = rn2(3) ? 1 : 2; /* 67%: 1 step, 33%: 2 steps */ int chance = 6; /* 1/6 chance of attack knocking back a monster */ - boolean u_agr = (magr == u.umonst); - boolean u_def = (mdef == u.umonst); + boolean u_agr = (magr == &gy.youmonst); + boolean u_def = (mdef == &gy.youmonst); boolean was_u = FALSE, dismount = FALSE; struct obj *wep = weapon_used ? (u_agr ? uwep : MON_WEP(magr)) : (struct obj *) 0; @@ -5438,7 +5438,7 @@ hmonas(struct monst *mon) whether silver ring causes successful hit */ for (i = 0; i < NATTK; i++) { sum[i] = M_ATTK_MISS; - mattk = getmattk(u.umonst, mon, i, sum, &alt_attk); + mattk = getmattk(&gy.youmonst, mon, i, sum, &alt_attk); if (mattk->aatyp == AT_WEAP) ++multi_weap; if (mattk->aatyp == AT_WEAP @@ -5460,7 +5460,7 @@ hmonas(struct monst *mon) || DEADMONSTER(mon))) continue; - mattk = getmattk(u.umonst, mon, i, sum, &alt_attk); + mattk = getmattk(&gy.youmonst, mon, i, sum, &alt_attk); if (gs.skipdrin && mattk->aatyp == AT_TENT && mattk->adtyp == AD_DRIN) continue; weapon = 0; @@ -5546,17 +5546,17 @@ hmonas(struct monst *mon) sum[i] = damageum(mon, mattk, 0); break; case AT_CLAW: - if (uwep && !cantwield(u.umonst->data) && !weapon_used) + if (uwep && !cantwield(gy.youmonst.data) && !weapon_used) goto use_weapon; FALLTHROUGH; /*FALLTHRU*/ case AT_TUCH: - if (uwep && u.umonst->data->mlet == S_LICH && !weapon_used) + if (uwep && gy.youmonst.data->mlet == S_LICH && !weapon_used) goto use_weapon; FALLTHROUGH; /*FALLTHRU*/ case AT_KICK: - if (mattk->aatyp == AT_KICK && mtrapped_in_pit(u.umonst)) + if (mattk->aatyp == AT_KICK && mtrapped_in_pit(&gy.youmonst)) continue; FALLTHROUGH; /*FALLTHRU*/ @@ -5576,7 +5576,7 @@ hmonas(struct monst *mon) const char *verb = 0; /* verb or body part */ if (!u.uswallow - && (compat = could_seduce(u.umonst, mon, mattk)) + && (compat = could_seduce(&gy.youmonst, mon, mattk)) != 0) { You("%s %s %s.", (mon->mcansee && haseyes(mon->data)) ? "smile at" @@ -5604,7 +5604,7 @@ hmonas(struct monst *mon) {bite,claw,claw} instead of {claw,claw,bite} doesn't make poly'd hero mysteriously switch handedness */ odd_claw = !odd_claw; - specialdmg = special_dmgval(u.umonst, mon, + specialdmg = special_dmgval(&gy.youmonst, mon, W_ARMG | ((odd_claw || !multi_claw) ? W_RINGL : 0L) @@ -5619,7 +5619,7 @@ hmonas(struct monst *mon) break; case AT_KICK: verb = "kick"; - specialdmg = special_dmgval(u.umonst, mon, W_ARMF, + specialdmg = special_dmgval(&gy.youmonst, mon, W_ARMF, &silverhit); break; case AT_BUTT: @@ -5627,7 +5627,7 @@ hmonas(struct monst *mon) /* hypothetical; if any form with a head-butt attack could wear a helmet, it would hit shades when wearing a blessed (or silver) one */ - specialdmg = special_dmgval(u.umonst, mon, W_ARMH, + specialdmg = special_dmgval(&gy.youmonst, mon, W_ARMH, &silverhit); break; case AT_BITE: @@ -5649,7 +5649,7 @@ hmonas(struct monst *mon) } else { /* either not a shade or no special silver/blessed damage, other unsolid monsters are immune to AT_TUCH+AD_WRAP */ - if (failed_grab(u.umonst, mon, mattk)) + if (failed_grab(&gy.youmonst, mon, mattk)) break; /* miss; message already given */ if (mattk->aatyp == AT_TENT) { @@ -5659,7 +5659,7 @@ hmonas(struct monst *mon) verb = "hit"; /* not "claws" */ You("%s %s.", verb, mon_nam(mon)); if (silverhit && flags.verbose) - silver_sears(u.umonst, mon, silverhit); + silver_sears(&gy.youmonst, mon, silverhit); } sum[i] = damageum(mon, mattk, specialdmg); } @@ -5694,7 +5694,7 @@ hmonas(struct monst *mon) wakeup(mon, TRUE); /* choking hug/throttling grab uses hands (gloves or rings); normal hug uses outermost of cloak/suit/shirt */ - specialdmg = special_dmgval(u.umonst, mon, + specialdmg = special_dmgval(&gy.youmonst, mon, byhand ? (W_ARMG | W_RINGL | W_RINGR) : (W_ARMC | W_ARM | W_ARMU), &silverhit); @@ -5723,7 +5723,7 @@ hmonas(struct monst *mon) if (specialdmg) { You("%s %s%s", verb, mon_nam(mon), exclam(specialdmg)); if (silverhit && flags.verbose) - silver_sears(u.umonst, mon, silverhit); + silver_sears(&gy.youmonst, mon, silverhit); sum[i] = damageum(mon, mattk, specialdmg); } else { Your("%s passes harmlessly through %s.", @@ -5732,7 +5732,7 @@ hmonas(struct monst *mon) break; } /* can't grab unsolid creatures (checked after shade handling) */ - if (failed_grab(u.umonst, mon, mattk)) + if (failed_grab(&gy.youmonst, mon, mattk)) break; /* hug attack against ordinary foe */ if (mon == u.ustuck) { @@ -5741,7 +5741,7 @@ hmonas(struct monst *mon) /* extra feedback for non-breather being choked */ unconcerned ? " but doesn't seem concerned" : ""); if (silverhit && flags.verbose) - silver_sears(u.umonst, mon, silverhit); + silver_sears(&gy.youmonst, mon, silverhit); sum[i] = damageum(mon, mattk, specialdmg); } else if (i >= 2 && (sum[i - 1] > M_ATTK_MISS) && (sum[i - 2] > M_ATTK_MISS)) { @@ -5753,7 +5753,7 @@ hmonas(struct monst *mon) You("grab %s!", mon_nam(mon)); set_ustuck(mon); if (silverhit && flags.verbose) - silver_sears(u.umonst, mon, silverhit); + silver_sears(&gy.youmonst, mon, silverhit); sum[i] = damageum(mon, mattk, specialdmg); } break; /* AT_HUGS */ @@ -5776,7 +5776,7 @@ hmonas(struct monst *mon) if (mon->data == &mons[PM_SHADE]) { /* no specialdmg check needed */ Your("attempt to surround %s is harmless.", mon_nam(mon)); - } else if (failed_grab(u.umonst, mon, mattk)) { + } else if (failed_grab(&gy.youmonst, mon, mattk)) { ; /* non-shade miss; message already given */ } else { sum[i] = gulpum(mon, mattk); @@ -5797,9 +5797,9 @@ hmonas(struct monst *mon) /* No check for uwep; if wielding nothing we want to * do the normal 1-2 points bare hand damage... */ - if ((u.umonst->data->mlet == S_KOBOLD - || u.umonst->data->mlet == S_ORC - || u.umonst->data->mlet == S_GNOME) && !weapon_used) + if ((gy.youmonst.data->mlet == S_KOBOLD + || gy.youmonst.data->mlet == S_ORC + || gy.youmonst.data->mlet == S_GNOME) && !weapon_used) goto use_weapon; FALLTHROUGH; /*FALLTHRU*/ @@ -5830,7 +5830,7 @@ hmonas(struct monst *mon) mattk->aatyp, FALSE); } - if (mhitm_knockback(u.umonst, mon, mattk, &sum[i], weapon_used)) + if (mhitm_knockback(&gy.youmonst, mon, mattk, &sum[i], weapon_used)) break; /* don't use sum[i] beyond this point; @@ -5918,7 +5918,7 @@ passive( monstseesu(M_SEEN_ACID); } if (!rn2(30)) - erode_armor(u.umonst, ERODE_CORRODE); + erode_armor(&gy.youmonst, ERODE_CORRODE); } if (mhitb && weapon) { if (aatyp == AT_KICK) { @@ -5947,7 +5947,7 @@ passive( || (protector == W_ARMH && !uarmh) || (protector == (W_ARMC | W_ARMG) && (!uarmc || !uarmg))) { if (!Stone_resistance - && !(poly_when_stoned(u.umonst->data) + && !(poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM))) { done_in_by(mon, STONING); /* "You turn to stone..." */ return M_ATTK_DEF_DIED; @@ -6079,7 +6079,7 @@ passive( healmon(mon, (tmp + rn2(2)) / 2, (tmp + 1) / 2); /* at a certain point, the monster will reproduce! */ if (mon->mhpmax > (((int) mon->m_lev) + 1) * 8) - (void) split_mon(mon, u.umonst); + (void) split_mon(mon, &gy.youmonst); } break; case AD_STUN: /* specifically yellow mold */ diff --git a/src/vault.c b/src/vault.c index ef4065805..90157b7fa 100644 --- a/src/vault.c +++ b/src/vault.c @@ -466,18 +466,18 @@ invault(void) } if (U_AP_TYPE == M_AP_OBJECT || u.uundetected) { if (U_AP_TYPE == M_AP_OBJECT - && u.umonst->mappearance != GOLD_PIECE) + && gy.youmonst.mappearance != GOLD_PIECE) if (!Deaf) { SetVoice(guard, 0, 80, 0); verbalize("Hey! Who left that %s in here?", - mimic_obj_name(u.umonst)); + mimic_obj_name(&gy.youmonst)); } /* You're mimicking some object or you're hidden. */ pline("Puzzled, %s turns around and leaves.", mhe(guard)); mongone(guard); return; } - if (Strangled || is_silent(u.umonst->data) || gm.multi < 0) { + if (Strangled || is_silent(gy.youmonst.data) || gm.multi < 0) { /* [we ought to record whether this message has already been given in order to vary it upon repeat visits, but discarding the monster and its egd data renders that hard] */ @@ -1065,7 +1065,7 @@ gd_move(struct monst *grd) } if (um_dist(grd->mx, grd->my, 1) || egrd->gddone) { if (!egrd->gddone && !rn2(10) && !Deaf && !u.uswallow - && !(u.ustuck && !sticks(u.umonst->data))) { + && !(u.ustuck && !sticks(gy.youmonst.data))) { SetVoice(grd, 0, 80, 0); verbalize("Move along!"); } diff --git a/src/weapon.c b/src/weapon.c index 708e2bc3a..1c738e17e 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -405,7 +405,7 @@ special_dmgval( } /* when no gloves we check for silver rings (blessed rings ignored) */ - } else if ((left_ring || right_ring) && magr == u.umonst) { + } else if ((left_ring || right_ring) && magr == &gy.youmonst) { if (left_ring && uleft) { if (objects[uleft->otyp].oc_material == SILVER && mon_hates_silver(mdef)) { diff --git a/src/were.c b/src/were.c index df6ebc15c..59197177f 100644 --- a/src/were.c +++ b/src/were.c @@ -218,12 +218,12 @@ you_unwere(boolean purify) You_feel("purified."); set_ulycn(NON_PM); /* cure lycanthropy */ } - if (!Unchanging && is_were(u.umonst->data) + if (!Unchanging && is_were(gy.youmonst.data) && !monster_nearby() && (!controllable_poly || !paranoid_query(ParanoidWerechange, "Remain in beast form?"))) rehumanize(); - else if (is_were(u.umonst->data) && !u.mtimedone) + else if (is_were(gy.youmonst.data) && !u.mtimedone) u.mtimedone = rn1(200, 200); /* 40% of initial were change */ } diff --git a/src/wield.c b/src/wield.c index b6fbdc83a..21aad53c4 100644 --- a/src/wield.c +++ b/src/wield.c @@ -158,7 +158,7 @@ const char * empty_handed(void) { return uarmg ? "empty handed" /* gloves imply hands */ - : humanoid(u.umonst->data) + : humanoid(gy.youmonst.data) /* hands but no weapon and no gloves */ ? "bare handed" /* alternate phrasing for paws or lack of hands */ @@ -360,7 +360,7 @@ dowield(void) /* May we attempt this? */ gm.multi = 0; - if (cantwield(u.umonst->data)) { + if (cantwield(gy.youmonst.data)) { pline("Don't be ridiculous!"); return ECMD_FAIL; } @@ -465,7 +465,7 @@ doswapweapon(void) /* May we attempt this? */ gm.multi = 0; - if (cantwield(u.umonst->data)) { + if (cantwield(gy.youmonst.data)) { pline("Don't be ridiculous!"); return ECMD_FAIL; } @@ -716,7 +716,7 @@ wield_tool(struct obj *obj, } return FALSE; } - if (cantwield(u.umonst->data)) { + if (cantwield(gy.youmonst.data)) { You_cant("hold %s strongly enough.", more_than_1 ? "them" : "it"); return FALSE; } @@ -762,7 +762,7 @@ can_twoweapon(void) { struct obj *otmp; - if (!could_twoweap(u.umonst->data)) { + if (!could_twoweap(gy.youmonst.data)) { if (Upolyd) You_cant("use two weapons in your current form."); else diff --git a/src/wizcmds.c b/src/wizcmds.c index 2c8554a8a..d9b99dcfc 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -892,7 +892,7 @@ wiz_smell(void) cc.x = u.ux; cc.y = u.uy; - if (!olfaction(u.umonst->data)) { + if (!olfaction(gy.youmonst.data)) { You("are incapable of detecting odors in your present form."); return ECMD_OK; } @@ -909,7 +909,7 @@ wiz_smell(void) if (u.usteed) { mptr = u.usteed->data; } else { - mptr = u.umonst->data; + mptr = gy.youmonst.data; is_you = TRUE; } } else if ((mtmp = m_at(cc.x, cc.y)) != (struct monst *) 0) { diff --git a/src/worn.c b/src/worn.c index 9ffcb8c24..a481f3372 100644 --- a/src/worn.c +++ b/src/worn.c @@ -459,7 +459,7 @@ check_wornmask_slots(void) why = "uswapwep is not a melee weapon"; else if (bimanual(uswapwep)) why = "uswapwep is two-handed"; - else if (!could_twoweap(u.umonst->data)) + else if (!could_twoweap(gy.youmonst.data)) why = "without two weapon attacks"; if (why) @@ -1005,7 +1005,7 @@ m_dowear_type( struct obj * which_armor(struct monst *mon, long flag) { - if (mon == u.umonst) { + if (mon == &gy.youmonst) { switch (flag) { case W_ARM: return uarm; diff --git a/src/write.c b/src/write.c index dc7ccbd36..d7a1eddb4 100644 --- a/src/write.c +++ b/src/write.c @@ -84,7 +84,7 @@ dowrite(struct obj *pen) const char *typeword; int spell_knowledge; - if (nohands(u.umonst->data)) { + if (nohands(gy.youmonst.data)) { You("need hands to be able to write!"); return ECMD_OK; } else if (Glib) { diff --git a/src/zap.c b/src/zap.c index 163ee6c38..bdaa54cec 100644 --- a/src/zap.c +++ b/src/zap.c @@ -590,7 +590,7 @@ release_hold(void) } /* gives "you get regurgitated" or "you get expelled from " */ expels(mtmp, mtmp->data, TRUE); - } else if (sticks(u.umonst->data)) { + } else if (sticks(gy.youmonst.data)) { /* order matters if 'holding' status condition is enabled; set_ustuck() will set flag for botl update, You() pline will trigger a status update with "UHold" removed */ @@ -694,7 +694,7 @@ get_mon_location( coordxy *xp, coordxy *yp, int locflags) /* non-zero means get location even if monster is buried */ { - if (mon == u.umonst || (u.usteed && mon == u.usteed)) { + if (mon == &gy.youmonst || (u.usteed && mon == u.usteed)) { *xp = u.ux; *yp = u.uy; return TRUE; @@ -1159,7 +1159,7 @@ unturn_dead(struct monst *mon) struct monst *mtmp2; char owner[BUFSZ], corpse[BUFSZ]; unsigned save_norevive; - boolean youseeit, different_type, is_u = (mon == u.umonst); + boolean youseeit, different_type, is_u = (mon == &gy.youmonst); int corpsenm, res = 0; youseeit = is_u ? TRUE : canseemon(mon); @@ -1224,9 +1224,9 @@ unturn_dead(struct monst *mon) void unturn_you(void) { - (void) unturn_dead(u.umonst); /* hit carried corpses and eggs */ + (void) unturn_dead(&gy.youmonst); /* hit carried corpses and eggs */ - if (is_undead(u.umonst->data)) { + if (is_undead(gy.youmonst.data)) { You_feel("frightened and %sstunned.", Stunned ? "even more " : ""); make_stunned((HStun & TIMEOUT) + (long) rnd(30), FALSE); } else { @@ -2102,7 +2102,7 @@ stone_to_flesh_obj(struct obj *obj) /* nonnull */ non-omnivorous form, regardless of whether it's herbivorous, non-eating, or something stranger) */ if (Role_if(PM_MONK) || !u.uconduct.unvegetarian - || !carnivorous(u.umonst->data)) + || !carnivorous(gy.youmonst.data)) Norep("You smell the odor of meat."); else Norep("You smell a delicious smell."); @@ -2206,14 +2206,14 @@ bhito(struct obj *obj, struct obj *otmp) if (obj_shudders(obj)) { boolean cover = ((obj == svl.level.objects[u.ux][u.uy]) && u.uundetected - && hides_under(u.umonst->data)); + && hides_under(gy.youmonst.data)); if (cansee(obj->ox, obj->oy)) learn_it = TRUE; do_osshock(obj); /* eek - your cover might have been blown */ if (cover) - (void) hideunder(u.umonst); + (void) hideunder(&gy.youmonst); break; } obj = poly_obj(obj, STRANGE_OBJECT); @@ -2440,7 +2440,7 @@ bhitpile( /* if hiding underneath an object and zapping up or down, the top item is either the only thing hit (up) or is skipped (down) */ - hidingunder = (zz != 0 && u.uundetected && hides_under(u.umonst->data)); + hidingunder = (zz != 0 && u.uundetected && hides_under(gy.youmonst.data)); first = TRUE; if (obj->otyp == SPE_FORCE_BOLT || obj->otyp == WAN_STRIKING) { @@ -2629,7 +2629,7 @@ dozap(void) struct obj *obj; int damage, need_dir; - if (nohands(u.umonst->data)) { + if (nohands(gy.youmonst.data)) { You("aren't able to zap anything in your current form."); return ECMD_OK; } @@ -2741,7 +2741,7 @@ zapyourself(struct obj *obj, boolean ordinary) monstseesu(M_SEEN_ELEC); ugolemeffects(AD_ELEC, orig_dmg); } - (void) destroy_items(u.umonst, AD_ELEC, orig_dmg); + (void) destroy_items(&gy.youmonst, AD_ELEC, orig_dmg); (void) flashburn((long) rnd(100), TRUE); break; @@ -2764,8 +2764,8 @@ zapyourself(struct obj *obj, boolean ordinary) monstunseesu(M_SEEN_FIRE); } burn_away_slime(); - (void) burnarmor(u.umonst); - (void) destroy_items(u.umonst, AD_FIRE, orig_dmg); + (void) burnarmor(&gy.youmonst); + (void) destroy_items(&gy.youmonst, AD_FIRE, orig_dmg); ignite_items(gi.invent); break; @@ -2784,7 +2784,7 @@ zapyourself(struct obj *obj, boolean ordinary) damage = orig_dmg; monstunseesu(M_SEEN_COLD); } - (void) destroy_items(u.umonst, AD_COLD, orig_dmg); + (void) destroy_items(&gy.youmonst, AD_COLD, orig_dmg); break; case WAN_MAGIC_MISSILE: @@ -2811,7 +2811,7 @@ zapyourself(struct obj *obj, boolean ordinary) case WAN_CANCELLATION: case SPE_CANCELLATION: - (void) cancel_monst(u.umonst, obj, TRUE, TRUE, TRUE); + (void) cancel_monst(&gy.youmonst, obj, TRUE, TRUE, TRUE); break; case SPE_DRAIN_LIFE: @@ -2884,7 +2884,7 @@ zapyourself(struct obj *obj, boolean ordinary) case WAN_DEATH: case SPE_FINGER_OF_DEATH: - if (nonliving(u.umonst->data) || is_demon(u.umonst->data)) { + if (nonliving(gy.youmonst.data) || is_demon(gy.youmonst.data)) { pline((obj->otyp == WAN_DEATH) ? "The wand shoots an apparently harmless beam at you." : "You seem no deader than before."); @@ -2939,16 +2939,16 @@ zapyourself(struct obj *obj, boolean ordinary) unpunish(); } /* invent is hit iff hero doesn't escape from a trap */ - if (!u.utrap || !openholdingtrap(u.umonst, &learn_it)) { + if (!u.utrap || !openholdingtrap(&gy.youmonst, &learn_it)) { boxlock_invent(obj); /* trigger previously escaped trapdoor */ - (void) openfallingtrap(u.umonst, TRUE, &learn_it); + (void) openfallingtrap(&gy.youmonst, TRUE, &learn_it); } break; case WAN_LOCKING: case SPE_WIZARD_LOCK: /* similar logic to opening; invent is hit iff no trap triggered */ - if (u.utrap || !closeholdingtrap(u.umonst, &learn_it)) { + if (u.utrap || !closeholdingtrap(&gy.youmonst, &learn_it)) { boxlock_invent(obj); } break; @@ -3032,7 +3032,7 @@ lightdamage( const char *how; int dmg = amt; - if (dmg && u.umonst->data == &mons[PM_GREMLIN]) { + if (dmg && gy.youmonst.data == &mons[PM_GREMLIN]) { /* reduce high values (from destruction of wand with many charges) */ dmg = rnd(dmg); if (dmg > 10) @@ -3059,7 +3059,7 @@ lightdamage( boolean flashburn(long duration, boolean via_lightning) { - if (!resists_blnd(u.umonst)) { + if (!resists_blnd(&gy.youmonst)) { You(are_blinded_by_the_flash); make_blinded(duration, FALSE); if (!Blind) @@ -3072,7 +3072,7 @@ flashburn(long duration, boolean via_lightning) if hero is both lightning resistant and blindness resistant, or worse, have a single sparkle where the player confuses blindness resistance for lightning resistance */ - if (!via_lightning && resists_blnd_by_arti(u.umonst)) { + if (!via_lightning && resists_blnd_by_arti(&gy.youmonst)) { shieldeff(u.ux, u.uy); return TRUE; } @@ -3153,7 +3153,7 @@ cancel_monst(struct monst *mdef, struct obj *obj, boolean youattack, static const char writing_vanishes[] = "Some writing vanishes from %s head!", your[] = "your"; /* should be extern */ - boolean youdefend = (mdef == u.umonst); + boolean youdefend = (mdef == &gy.youmonst); if (youdefend ? (!youattack && Antimagic) : resist(mdef, obj->oclass, 0, NOTELL)) @@ -3281,10 +3281,10 @@ zap_updown(struct obj *obj) /* wand or spell, nonnull */ } /* down will release you from bear trap or web */ if (u.dz > 0 && u.utrap) { - (void) openholdingtrap(u.umonst, &disclose); + (void) openholdingtrap(&gy.youmonst, &disclose); /* down will trigger trapdoor, hole, or [spiked-] pit */ } else if (u.dz > 0 && !u.utrap) { - (void) openfallingtrap(u.umonst, FALSE, &disclose); + (void) openfallingtrap(&gy.youmonst, FALSE, &disclose); } break; case WAN_STRIKING: @@ -3319,7 +3319,7 @@ zap_updown(struct obj *obj) /* wand or spell, nonnull */ } newsym(x, y); } else if (u.dz > 0 && ttmp) { - if (!striking && closeholdingtrap(u.umonst, &disclose)) { + if (!striking && closeholdingtrap(&gy.youmonst, &disclose)) { ; /* now stuck in web or bear trap */ } else if (striking && ttmp->ttyp == TRAPDOOR) { /* striking transforms trapdoor into hole */ @@ -3394,14 +3394,14 @@ zap_updown(struct obj *obj) /* wand or spell, nonnull */ /* game flavor: if you're hiding under "something" * a zap upward should hit that "something". */ - if (u.uundetected && hides_under(u.umonst->data)) { + if (u.uundetected && hides_under(gy.youmonst.data)) { int hitit = 0; otmp = svl.level.objects[u.ux][u.uy]; if (otmp) hitit = bhito(otmp, obj); if (hitit) { - (void) hideunder(u.umonst); + (void) hideunder(&gy.youmonst); disclose = TRUE; } } @@ -3558,7 +3558,7 @@ hit( struct monst *mtmp, /* target; for missile, might be hero */ const char *force) /* usually either "." or "!" via exclam() */ { - boolean verbosely = (mtmp == u.umonst + boolean verbosely = (mtmp == &gy.youmonst || (flags.verbose && (cansee(gb.bhitpos.x, gb.bhitpos.y) || canspotmon(mtmp) || engulfing_u(mtmp)))); @@ -3982,7 +3982,7 @@ bhit( they will be aiming at the monster */ xyglyph = glyph_at(x, y); if (mtmp && (((weapon == THROWN_WEAPON || weapon == KICKED_WEAPON) - && (shade_miss(u.umonst, mtmp, obj, TRUE, TRUE) + && (shade_miss(&gy.youmonst, mtmp, obj, TRUE, TRUE) || (M_AP_TYPE(mtmp) == M_AP_OBJECT && !glyph_is_monster(xyglyph) && !glyph_is_warning(xyglyph) @@ -4201,7 +4201,7 @@ boomhit(struct obj *obj, int dx, int dy) } if (u_at(gb.bhitpos.x, gb.bhitpos.y)) { /* ct == 9 */ if (Fumbling || rn2(20) >= ACURR(A_DEX)) { - int dam = dmgval(obj, u.umonst); + int dam = dmgval(obj, &gy.youmonst); /* we hit ourselves */ (void) thitu(10 + obj->spe, Maybe_Half_Phys(dam), &obj, @@ -4211,7 +4211,7 @@ boomhit(struct obj *obj, int dx, int dy) } else { /* we catch it */ tmp_at(DISP_END, 0); You("skillfully catch the boomerang."); - return u.umonst; + return &gy.youmonst; } } tmp_at(gb.bhitpos.x, gb.bhitpos.y); @@ -4430,9 +4430,9 @@ zhitu( monstunseesu(M_SEEN_FIRE); } burn_away_slime(); - if (burnarmor(u.umonst)) { /* "body hit" */ + if (burnarmor(&gy.youmonst)) { /* "body hit" */ if (!rn2(3)) - (void) destroy_items(u.umonst, AD_FIRE, orig_dam); + (void) destroy_items(&gy.youmonst, AD_FIRE, orig_dam); if (!rn2(3)) ignite_items(gi.invent); } @@ -4449,7 +4449,7 @@ zhitu( monstunseesu(M_SEEN_COLD); } if (!rn2(3)) - (void) destroy_items(u.umonst, AD_COLD, orig_dam); + (void) destroy_items(&gy.youmonst, AD_COLD, orig_dam); break; case ZT_SLEEP: if (Sleep_resistance) { @@ -4490,7 +4490,7 @@ zhitu( (void) disintegrate_arm(uarmc); if (uarmu) (void) disintegrate_arm(uarmu); - } else if (nonliving(u.umonst->data) || is_demon(u.umonst->data)) { + } else if (nonliving(gy.youmonst.data) || is_demon(gy.youmonst.data)) { shieldeff(sx, sy); You("seem unaffected."); break; @@ -4520,7 +4520,7 @@ zhitu( monstunseesu(M_SEEN_ELEC); } if (!rn2(3)) - (void) destroy_items(u.umonst, AD_ELEC, orig_dam); + (void) destroy_items(&gy.youmonst, AD_ELEC, orig_dam); break; case ZT_POISON_GAS: poisoned("blast", A_DEX, "poisoned blast", 15, FALSE); @@ -4542,7 +4542,7 @@ zhitu( if (u.twoweap && !rn2(3)) acid_damage(uswapwep); if (!rn2(6)) - erode_armor(u.umonst, ERODE_CORRODE); + erode_armor(&gy.youmonst, ERODE_CORRODE); break; } @@ -4891,7 +4891,7 @@ dobuzz( pline("%s disintegrates.", Monnam(mon)); pline("%s body reintegrates before your %s!", s_suffix(Monnam(mon)), - (eyecount(u.umonst->data) == 1) + (eyecount(gy.youmonst.data) == 1) ? body_part(EYE) : makeplural(body_part(EYE))); pline("%s resurrects!", Monnam(mon)); @@ -5803,7 +5803,7 @@ maybe_destroy_item( long i, cnt, quan; int dmg, xresist, skip, dindx; const char *mult; - boolean u_carry = (carrier == u.umonst); + boolean u_carry = (carrier == &gy.youmonst); boolean vis = !u_carry && canseemon(carrier); boolean chargeit = FALSE; @@ -5912,8 +5912,8 @@ maybe_destroy_item( } if (u_carry) { /* effects that happen only to the player */ if (osym == POTION_CLASS && dmgtyp != AD_COLD - && (!breathless(u.umonst->data) - || haseyes(u.umonst->data))) { + && (!breathless(gy.youmonst.data) + || haseyes(gy.youmonst.data))) { potionbreathe(obj); } if (obj->owornmask) { /* m_useup handles these for monster */ @@ -5977,7 +5977,7 @@ destroy_items( boolean deferred; } items_to_destroy[MAX_ITEMS_DESTROYED]; int elig_stacks = 0; /* number of destroyable objects found so far */ - boolean u_carry = (mon == u.umonst); + boolean u_carry = (mon == &gy.youmonst); /* this is a struct obj** because we might destroy the first item in it */ struct obj **objchn = u_carry ? &gi.invent : &mon->minvent; int dmg_out = 0; /* damage caused by items getting destroyed */ From ec7781b996c66a9c600ed7a7f40dad88d1bc0c4d Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Sat, 2 May 2026 10:25:39 +0100 Subject: [PATCH 118/702] Remove saving grace This feature was no longer fulfilling its intended purpose: the issue is that when players are aware of it, instead of creating interesting stories, it becomes a resource the player can rely on. Alternative mitigation for some "unfair" early-game deaths has been added (such as the warning shot for early-game attack wands and the ability of iron shoes to protect against certain early traps), and the warning shot in particular can create interesting gameplay moments and stories of its own, especially when saving grace is *not* present (discovering that a monster has a wand of fire and can oneshot you is an interesting emergency situation, but less scary if you know that its first attempt to oneshot you will fail). The feature was also proving quite hard to code correctly, because there are numerous cases that it "obviously" shouldn't affect (most notably beheading due to Vorpal Blade, but also things like purple worm digestion) which would need to be special-cased, and because there are grey areas like wand zap bounces (which might or might not be an intentional attempt by the player to hit themself with the bounce) and damage from traps. Removing it saves the need to work out, for every new damage source, whether and when saving grace should interact with it. Breaks save compatibility. --- doc/fixes3-7-0.txt | 8 ------- include/decl.h | 6 ----- include/extern.h | 1 - include/patchlevel.h | 2 +- include/you.h | 1 - src/allmain.c | 5 ---- src/decl.c | 4 ---- src/hack.c | 55 -------------------------------------------- src/insight.c | 15 ------------ src/mhitu.c | 1 - 10 files changed, 1 insertion(+), 97 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 65da5b0cf..916ee7177 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -2219,9 +2219,6 @@ uncursed genocide while hallucinating deliberately mis-reports hero's role as target but was also inappropriately showing it to livelog/#chronicle livelog/#chronicle for bribing a demon lord reported random monster and currency if hero was hallucinating -livelog/#chronicle for saving-grace: if saving-grace prevents hero's death, - report it [at present, it uses the livelog classification for breaking - a conduct] naming a type of item, unnaming it (with name of ), naming it again (new name or re-use of old one), then unnaming it again would issue impossible: "named object not in disco" @@ -2904,11 +2901,6 @@ pyrolisk eggs explode when broken pauper-option to start the character with no possessions wand of secret door detection, spell of detect unseen, and wizard mode ^E now flash the cursor at each location where detection finds something -saving-grace: once per game if receiving a killing blow from full or nearly - full HP, survive with 1 HP -enlightenment/attribute disclosure for saving-grace: include a line for have - or haven't been saved (game in progress) or did or didn't get saved - (game over) via saving-grace 'selectsaved' lists "name-role-race-gend-algn" instead of just "name" in the menu of save files available to be restored 'selectsaved' prefixes "name-role-race-gend-algn" with "- " for normal play, diff --git a/include/decl.h b/include/decl.h index 9f9478052..d1b4cafe6 100644 --- a/include/decl.h +++ b/include/decl.h @@ -840,9 +840,6 @@ struct instance_globals_r { struct instance_globals_s { - /* allmain.c */ - boolean saving_grace_turn; /* saving grace was triggered this turn */ - /* artifact.c */ int spec_dbon_applies; /* coordinate effects from spec_dbon() with messages in artifact_hit() */ @@ -974,9 +971,6 @@ struct instance_globals_t { struct instance_globals_u { - /* allmain.c */ - int uhp_at_start_of_monster_turn; - /* botl.c */ boolean update_all; diff --git a/include/extern.h b/include/extern.h index 4843b3731..3ad80a5de 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1236,7 +1236,6 @@ extern int monster_nearby(void); extern void end_running(boolean); extern void nomul(int); extern void unmul(const char *); -extern int saving_grace(int); extern void showdamage(int); extern void losehp(int, const char *, schar) ; extern int weight_cap(void); diff --git a/include/patchlevel.h b/include/patchlevel.h index fd3dafc09..c2b43469d 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -17,7 +17,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 142 +#define EDITLEVEL 143 /* * Development status possibilities. diff --git a/include/you.h b/include/you.h index a073e5c57..d71cb6e63 100644 --- a/include/you.h +++ b/include/you.h @@ -428,7 +428,6 @@ struct you { Bitfield(uinvulnerable, 1); /* you're invulnerable (praying) */ Bitfield(uburied, 1); /* you're buried */ Bitfield(uedibility, 1); /* blessed food detect; sense unsafe food */ - Bitfield(usaving_grace, 1); /* prevents death once */ Bitfield(uhandedness, 1); /* There is no advantage for either handedness. The distinction is only for flavor variation and for use in messages. */ diff --git a/src/allmain.c b/src/allmain.c index 48dc040ef..7b82d86a8 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -208,7 +208,6 @@ moveloop_core(void) encumber_msg(); svc.context.mon_moving = TRUE; - gu.uhp_at_start_of_monster_turn = u.uhp; do { monscanmove = movemon(); if (u.umovement >= NORMAL_SPEED) @@ -277,8 +276,6 @@ moveloop_core(void) if (u.ublesscnt) u.ublesscnt--; - gs.saving_grace_turn = FALSE; - /* One possible result of prayer is healing. Whether or * not you get healed depends on your current hit points. * If you are allowed to regenerate during the prayer, @@ -430,8 +427,6 @@ moveloop_core(void) else if (!u.umoved) (void) pooleffects(FALSE); - gs.saving_grace_turn = FALSE; - /* vision while buried or underwater is updated here */ if (Underwater) under_water(0); diff --git a/src/decl.c b/src/decl.c index b8852795f..558ad66ab 100644 --- a/src/decl.c +++ b/src/decl.c @@ -675,8 +675,6 @@ static const struct instance_globals_r g_init_r = { }; static const struct instance_globals_s g_init_s = { - /* allmain.c */ - FALSE, /* saving_grace_turn */ /* artifact.c */ 0, /* spec_dbon_applies */ /* decl.c */ @@ -767,8 +765,6 @@ static const struct instance_globals_t g_init_t = { }; static const struct instance_globals_u g_init_u = { - /* allmain.c */ - 0, /* uhp_at_start_of_monster_turn */ /* botl.c */ FALSE, /* update_all */ /* decl.c */ diff --git a/src/hack.c b/src/hack.c index 367591eff..f4d108d95 100644 --- a/src/hack.c +++ b/src/hack.c @@ -4242,60 +4242,6 @@ maybe_wail(void) } } -/* once per game, if receiving a killing blow from above 90% HP, - allow the hero to survive with 1 HP */ -int -saving_grace(int dmg) -{ - if (dmg < 0) { - impossible("saving_grace check for negative damage? (%d)", dmg); - return 0; - } -#if 0 /* saving grace _does_ protect hero during own actions */ - if (!svc.context.mon_moving) { - /* saving grace doesn't protect you from your own actions */ - return dmg; - } -#endif - if (dmg < u.uhp || u.uhp <= 0) { - /* no need for saving grace */ - return dmg; - } - - if (gs.saving_grace_turn) { - /* saving grace already triggered and prevents HP reducing below 1 - this turn (specifically: until the next player action or turn - boundary), don't print further messages or livelog entries */ - return u.uhp - 1; - } - - if (!u.usaving_grace && - (gu.uhp_at_start_of_monster_turn * 100 / u.uhpmax) >= 90) { - /* saving_grace doesn't have it's own livelog classification; - we might invent one, or perhaps use LL_LIFESAVE, but surviving - certain death (or preserving worn amulet of life saving) via - saving-grace feels like breaking a conduct; not sure how best - to phrase this though; classifying it as a spoiler will hide it - from #chronicle during play but show it to livelog observers */ - livelog_printf(LL_CONDUCT | LL_SPOILER, "%s (%d damage, %d/%d HP)", - "survived one-shot death via saving-grace", - /* include damage that happened earlier this turn */ - gu.uhp_at_start_of_monster_turn - u.uhp + dmg, - gu.uhp_at_start_of_monster_turn, u.uhpmax); - - /* note: this could reduce dmg to 0 if u.uhpmax==1 */ - dmg = u.uhp - 1; - u.usaving_grace = 1; /* used up */ - gs.saving_grace_turn = TRUE; - end_running(TRUE); - if (u.usleep) - unmul("Suddenly you wake up!"); - if (is_fainted()) - reset_faint(); - } - return dmg; -} - /* show a message how much damage you received */ void showdamage(int dmg) @@ -4330,7 +4276,6 @@ losehp(int n, const char *knam, schar k_format) return; } - n = saving_grace(n); u.uhp -= n; showdamage(n); if (u.uhp > u.uhpmax) diff --git a/src/insight.c b/src/insight.c index ab2bcd1a1..35351a5f3 100644 --- a/src/insight.c +++ b/src/insight.c @@ -1974,21 +1974,6 @@ attributes_enlightenment( } #endif - /* saving-grace: show during final disclosure, hide during normal play */ - if (final || wizard || discover) { - static const char *verbchoices[2][2] = { - { "might avoid", "have avoided" }, - { "could have avoided", "avoided" }, - }; - /* u.usaving_grace will always be 0 or 1; final is 0 (game in - progress), 1 (game over, survived), or 2 (game over, died) */ - const char *verb = verbchoices[!!final][u.usaving_grace]; - - /* 'verb' has already been set for present or past but enl_msg() - needs it twice, one for in progress, the other for game over */ - enl_msg(You_, verb, verb, " a one-shot death via saving-grace", ""); - } - { const char *p; diff --git a/src/mhitu.c b/src/mhitu.c index 71d90a8ec..feb29ffbd 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1916,7 +1916,6 @@ mdamageu(struct monst *mtmp, int n) if (u.mh < 1) rehumanize(); } else { - n = saving_grace(n); u.uhp -= n; showdamage(n); /* caller might have reduced uhpmax before calling mdamageu() */ From 0c9382e704a03ec564b73a79899d8790fd939fca Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 2 May 2026 08:25:58 -0400 Subject: [PATCH 119/702] placeholders --- include/decl.h | 7 +++++++ src/decl.c | 7 +++++++ src/restore.c | 2 ++ src/save.c | 2 ++ 4 files changed, 18 insertions(+) diff --git a/include/decl.h b/include/decl.h index 1904ecfd1..70727a2bf 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1221,6 +1221,12 @@ struct instance_globals_saved_u { dest_area updest; }; +struct instance_globals_saved_w { + /* reserved */ + long wreserve; + int32_t wtreserved; +}; + struct instance_globals_saved_x { /* mkmaze.c */ int xmin, xmax; /* level boundaries x */ @@ -1274,6 +1280,7 @@ extern struct instance_globals_saved_r svr; extern struct instance_globals_saved_s svs; extern struct instance_globals_saved_t svt; extern struct instance_globals_saved_u svu; +extern struct instance_globals_saved_w svw; extern struct instance_globals_saved_x svx; extern struct instance_globals_saved_y svy; extern struct sinfo program_state; /* flags describing game's current state */ diff --git a/src/decl.c b/src/decl.c index a3298c4ef..4fe4585f0 100644 --- a/src/decl.c +++ b/src/decl.c @@ -987,6 +987,11 @@ static const struct instance_globals_saved_x init_svx = { UNDEFINED_VALUE /* xmax */ }; +static const struct instance_globals_saved_w init_svw = { + 0, /* wreserve */ + 100, /* wtreserved, not used currently */ +}; + static const struct instance_globals_saved_y init_svy = { /* mkmaze.c */ UNDEFINED_VALUE, /* ymin */ @@ -1042,6 +1047,7 @@ struct instance_globals_saved_r svr; struct instance_globals_saved_s svs; struct instance_globals_saved_t svt; struct instance_globals_saved_u svu; +struct instance_globals_saved_w svw; struct instance_globals_saved_x svx; struct instance_globals_saved_y svy; struct sinfo program_state; @@ -1119,6 +1125,7 @@ decl_globals_init(void) svs = init_svs; svt = init_svt; svu = init_svu; + svw = init_svw; svx = init_svx; svy = init_svy; diff --git a/src/restore.c b/src/restore.c index 5023816cc..fab825de3 100644 --- a/src/restore.c +++ b/src/restore.c @@ -598,6 +598,8 @@ restgamestate(NHFILE *nhfp) amii_setpens(amii_numcolors); /* use colors from save file */ #endif #endif /* !SFCTOOL */ + Sfi_long(nhfp, &svw.wreserve, "wreserve"); + Sfi_int32(nhfp, &svw.wtreserved, "wtreserved"); Sfi_you(nhfp, &u, "gamestate-you"); gy.youmonst.cham = u.mcham; diff --git a/src/save.c b/src/save.c index fdbb0011a..1d61ee751 100644 --- a/src/save.c +++ b/src/save.c @@ -282,6 +282,8 @@ savegamestate(NHFILE *nhfp) urealtime.finish_time = getnow(); urealtime.realtime += timet_delta(urealtime.finish_time, urealtime.start_timing); + Sfo_long(nhfp, &svw.wreserve, "wreserve"); + Sfo_int32(nhfp, &svw.wtreserved, "wtreserved"); Sfo_you(nhfp, &u, "gamestate-you"); Sfo_char(nhfp, yyyymmddhhmmss(ubirthday), "gamestate-ubirthday", 14); Sfo_long(nhfp, &urealtime.realtime, "gamestate-realtime"); From a127ec7dca1c42a626df0c2e776ff9de9ec7034a Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 2 May 2026 09:54:12 -0400 Subject: [PATCH 120/702] Windows MSGSTOP bit This is a stop gap fix. --- win/win32/mswproc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index 55ba2f696..b0efee536 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -881,7 +881,8 @@ mswin_display_nhwindow(winid wid, boolean block) if (!block) { UpdateWindow(GetNHApp()->windowlist[wid].win); } else { - if (GetNHApp()->windowlist[wid].type == NHW_MAP) { + if ((GetNHApp()->windowlist[wid].type == NHW_MAP) + || (GetNHApp()->windowlist[wid].type == NHW_MESSAGE)) { (void) mswin_nhgetch(); } } From ce15b9644eac333c5d8be090f89c0f8aa26fd3c7 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 2 May 2026 10:05:02 -0400 Subject: [PATCH 121/702] README update --- README | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README b/README index 8dac1f905..055026aea 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ - NetHack 5.0.0 work-in-progress -- General information + NetHack 5.0.0 -- General information NetHack 5.0 is an enhancement to the dungeon exploration game NetHack, which is a distant descendent of Rogue and Hack, and a direct descendent @@ -18,6 +18,8 @@ Along with the game improvements and bug fixes, NetHack 5.0 strives to make some general architectural improvements to the game or to its building process. Among them, 5.0 has: + * The source code is standard C99. + * removes barriers to building NetHack on one platform and operating system, for later execution on another (possibly quite different) platform and/or operating system. That capability is generally known as "cross-compiling." From f6e2690a7a509b3a8846fbdbfe1f78d7b74b24af Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 2 May 2026 10:14:56 -0400 Subject: [PATCH 122/702] Guidebook.txt update --- doc/Guidebook.txt | 3284 +++++++++++++++++++++++---------------------- 1 file changed, 1675 insertions(+), 1609 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index f46ff0ca4..ae19710a4 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for NetHack 5.0.0 by Mike Stephenson and others) - April 16, 2026 + May 2, 2026 @@ -126,7 +126,7 @@ employ to great advantage. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -192,7 +192,7 @@ NetHack continues this fine tradition. Unlike text adventure games - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -258,7 +258,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -324,7 +324,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -390,7 +390,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -456,7 +456,7 @@ The number of turns elapsed so far, displayed if you have the - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -522,7 +522,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -588,7 +588,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -654,7 +654,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -720,7 +720,7 @@ instead. Only these one-step movement commands cause you to - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -786,7 +786,7 @@ ing . ^ is used as shorthand elsewhere in the - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -852,7 +852,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -918,7 +918,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -984,7 +984,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1050,7 +1050,7 @@ at an adjacent "remembered, unseen monster" marker. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1102,21 +1102,21 @@ ^T Teleport, if you have the ability. - v Display version number. + v Display a list of significant events in the current game, also + shown by #chronicle. - V Display the game history. + `v' used to display the game's version number. Use `V' for that + now. - w Wield weapon. + V Display version number. - w- - wield nothing, use your bare (or gloved) hands. - - Some characters can wield two weapons at once; use the `X' com- - mand (or the "#twoweapon" extended command) to do so. + `V' used to display a summary of the game's history. Still + available via #history. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1126,40 +1126,47 @@ + w Wield weapon. + + w- - wield nothing, use your bare (or gloved) hands. + + Some characters can wield two weapons at once; use the `X' com- + mand (or the "#twoweapon" extended command) to do so. + W Wear armor. - This command may also be used to put on an accessory (ring, - amulet, or blindfold). The prompt for which inventory item to + This command may also be used to put on an accessory (ring, + amulet, or blindfold). The prompt for which inventory item to use will only list armor, but choosing an unlisted accessory will - attempt to put it on. (See the `P' command above. It lists - accessories as the inventory choices but will accept an item of + attempt to put it on. (See the `P' command above. It lists + accessories as the inventory choices but will accept an item of armor and attempt to wear it.) - x Exchange your wielded weapon with the item in your alternate + x Exchange your wielded weapon with the item in your alternate weapon slot. The latter is used as your secondary weapon when engaging in two- - weapon combat. Note that if one of these slots is empty, the + weapon combat. Note that if one of these slots is empty, the exchange still takes place. - X Toggle two-weapon combat, if your character can do it. Also + X Toggle two-weapon combat, if your character can do it. Also available via the "#twoweapon" extended command. - (In versions prior to 3.6 this keystroke ran the command to + (In versions prior to 3.6 this keystroke ran the command to switch from normal play to "explore mode", also known as "discov- ery mode", which has now been moved to "#exploremode" and M-X.) ^X Display basic information about your character. - Displays name, role, race, gender (unless role name makes that - redundant, such as Caveman or Priestess), and alignment, along - with your patron deity and his or her opposition. It also shows - most of the various items of information from the status line(s) - in a less terse form, including several additional things which + Displays name, role, race, gender (unless role name makes that + redundant, such as Caveman or Priestess), and alignment, along + with your patron deity and his or her opposition. It also shows + most of the various items of information from the status line(s) + in a less terse form, including several additional things which don't appear in the normal status display due to space considera- tions. - In normal play, that's all that `^X' displays. In explore mode, + In normal play, that's all that `^X' displays. In explore mode, the role and status feedback is augmented by the information pro- vided by enlightenment magic. @@ -1171,18 +1178,11 @@ Z. - to cast at yourself, use `.' for the direction. - ^Z Suspend the game (UNIX(R) versions with job control only). See - "#suspend" below for more details. - - : Look at what is here. - __________ - (R)UNIX is a registered trademark of The Open Group. - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1192,6 +1192,11 @@ + ^Z Suspend the game (UNIX(R) versions with job control only). See + "#suspend" below for more details. + + : Look at what is here. + ; Show what type of thing a visible symbol corresponds to. , Pick up some things from the floor beneath you. @@ -1221,15 +1226,15 @@ + List the spells you know. - Using this command, you can also rearrange the order in which - your spells are listed, either by sorting the entire list or by - picking one spell from the menu then picking another to swap - places with it. Swapping pairs of spells changes their casting - letters, so the change lasts after the current `+' command fin- - ishes. Sorting the whole list is temporary. To make the most - recent sort order persist beyond the current `+' command, choose - the sort option again and then pick "reassign casting letters". - (Any spells learned after that will be added to the end of the + Using this command, you can also rearrange the order in which + your spells are listed, either by sorting the entire list or by + picking one spell from the menu then picking another to swap + places with it. Swapping pairs of spells changes their casting + letters, so the change lasts after the current `+' command fin- + ishes. Sorting the whole list is temporary. To make the most + recent sort order persist beyond the current `+' command, choose + the sort option again and then pick "reassign casting letters". + (Any spells learned after that will be added to the end of the list rather than be inserted into the sorted ordering.) \ Show what types of objects have been discovered. @@ -1238,17 +1243,12 @@ ` Show discovered types for one class of objects. - May be preceded by `m' to select preferred display order. - | If persistent inventory display is supported and enabled (with - the perm_invent option), interact with it instead of with the - map. - - Allows scrolling with the menu_first_page, menu_previous_page, - menu_next_page, and menu_last_page keys (`^', `<', `>', `|' by + __________ + (R)UNIX is a registered trademark of The Open Group. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1258,8 +1258,16 @@ + May be preceded by `m' to select preferred display order. + + | If persistent inventory display is supported and enabled (with + the perm_invent option), interact with it instead of with the + map. + + Allows scrolling with the menu_first_page, menu_previous_page, + menu_next_page, and menu_last_page keys (`^', `<', `>', `|' by default). Some interfaces also support menu_shift_left and - menu_shift_right keys (`{' and `}' by default). Use the Return + menu_shift_right keys (`{' and `}' by default). Use the Return (aka Enter) or Escape key to resume play. ! Escape to a shell. See "#shell" below for more details. @@ -1268,53 +1276,45 @@ of the current level's map without monsters; without monsters and objects; or without monsters, objects, and traps. - The key is also shown as on some keyboards or - on others. It is sometimes displayed as ^? even though + The key is also shown as on some keyboards or + on others. It is sometimes displayed as ^? even though that is not an actual control character. - Many terminals have an option to swap the and - keys, so typing the key might not execute this - command. If that happens, you can use the extended command + Many terminals have an option to swap the and + keys, so typing the key might not execute this + command. If that happens, you can use the extended command "#terrain" instead. # Perform an extended command. - As you can see, the authors of NetHack used up all the letters, + As you can see, the authors of NetHack used up all the letters, so this is a way to introduce the less frequently used commands. What - extended commands are available depends on what features the game was + extended commands are available depends on what features the game was compiled with. #adjust - Adjust inventory letters (most useful when the fixinv option is + Adjust inventory letters (most useful when the fixinv option is "on"). Autocompletes. Default key is `M-a'. - This command allows you to move an item from one particular - inventory slot to another so that it has a letter which is more - meaningful for you or that it will appear in a particular loca- - tion when inventory listings are displayed. You can move to a - currently empty slot, or if the destination is occupied--and - won't merge--the item there will swap slots with the one being - moved. "#adjust" can also be used to split a stack of objects; + This command allows you to move an item from one particular + inventory slot to another so that it has a letter which is more + meaningful for you or that it will appear in a particular loca- + tion when inventory listings are displayed. You can move to a + currently empty slot, or if the destination is occupied--and + won't merge--the item there will swap slots with the one being + moved. "#adjust" can also be used to split a stack of objects; when choosing the item to adjust, enter a count prior to its let- ter. - Adjusting without a count used to collect all compatible stacks - when moving to the destination. That behavior has been changed; - to gather compatible stacks, "#adjust" a stack into its own + Adjusting without a count used to collect all compatible stacks + when moving to the destination. That behavior has been changed; + to gather compatible stacks, "#adjust" a stack into its own inventory slot. If it has a name assigned, other stacks with the - same name or with no name will merge provided that all their - other attributes match. If it does not have a name, only other - stacks with no name are eligible. In either case, otherwise com- - patible stacks with a different name will not be merged. This - contrasts with using "#adjust" to move from one slot to a differ- - ent slot. In that situation, moving (no count given) a compati- - ble stack will merge if either stack has a name when the other - doesn't and give that name to the result, while splitting (count - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1324,16 +1324,24 @@ - given) will ignore the source stack's name when deciding whether + same name or with no name will merge provided that all their + other attributes match. If it does not have a name, only other + stacks with no name are eligible. In either case, otherwise com- + patible stacks with a different name will not be merged. This + contrasts with using "#adjust" to move from one slot to a differ- + ent slot. In that situation, moving (no count given) a compati- + ble stack will merge if either stack has a name when the other + doesn't and give that name to the result, while splitting (count + given) will ignore the source stack's name when deciding whether to merge with the destination stack. #annotate Allows you to specify one line of text to associate with the cur- rent dungeon level. All levels with annotations are displayed by - the "#overview" command. Autocompletes. Default key is `M-A', + the "#overview" command. Autocompletes. Default key is `M-A', and also `^N' if number_pad is on. - Preceding #annotate with the `m' prefix is the same as #overview + Preceding #annotate with the `m' prefix is the same as #overview with the prefix. #apply @@ -1343,7 +1351,7 @@ If the tool used acts on items on the floor, using the `m' prefix skips those items. - If used on a wand, that wand will be broken, releasing its magic + If used on a wand, that wand will be broken, releasing its magic in the process. Confirmation is required. #attributes @@ -1353,14 +1361,14 @@ Toggle the autopickup option on/off. Default key is `@'. #bugreport - Bring up a browser window to submit a report to the NetHack - Development Team. Can be disabled at the time the program is - built; when enabled, CRASHREPORTURL must be set in the system + Bring up a browser window to submit a report to the NetHack + Development Team. Can be disabled at the time the program is + built; when enabled, CRASHREPORTURL must be set in the system configuration file. #call - Call (name) a monster, or an object in inventory, on the floor, - or in the discoveries list, or add an annotation for the current + Call (name) a monster, or an object in inventory, on the floor, + or in the discoveries list, or add an annotation for the current level (same as "#annotate"). Default key is `C'. #cast @@ -1369,18 +1377,10 @@ #chat Talk to someone. Default key is `M-c'. - #chronicle - Show a list of important game events. Default key is `v'. - - #close - Close a door. Default key is `c'. - - #conduct - List voluntary challenges you have maintained. Autocompletes. - Default key is `M-C'. - NetHack 5.0.0 April 16, 2026 + + NetHack 5.0.0 May 2, 2026 @@ -1390,6 +1390,16 @@ + #chronicle + Show a list of important game events. Default key is `v'. + + #close + Close a door. Default key is `c'. + + #conduct + List voluntary challenges you have maintained. Autocompletes. + Default key is `M-C'. + See the section below entitled "Conduct" for details. #debugfuzzer @@ -1399,7 +1409,7 @@ Dip an object into something. Autocompletes. Default key is `M- d'. - The `m' prefix skips dipping into a fountain or pool if there is + The `m' prefix skips dipping into a fountain or pool if there is one at your location. #down @@ -1412,22 +1422,22 @@ Drop specific item types. Default key is `D'. #eat - Eat something. Default key is `e'. The `m' prefix skips eating + Eat something. Default key is `e'. The `m' prefix skips eating items on the floor. #engrave Engrave writing on the floor. Default key is `E'. #enhance - Advance or check weapon and spell skills. Autocompletes. + Advance or check weapon and spell skills. Autocompletes. Default key is `M-e'. #exploremode Switch from normal play to non-scoring explore mode. Default key is `M-X'. - Requires confirmation; default response is n (no). To really - switch to explore mode, respond with y. You can set the para- + Requires confirmation; default response is n (no). To really + switch to explore mode, respond with y. You can set the para- noid_confirmation:quit option to require a response of yes instead. @@ -1435,18 +1445,8 @@ Prefix key to force fight a direction, even if you see nothing to fight there. Default key is `F', or `-' with number_pad - #fire - Fire ammunition from quiver, possibly autowielding a launcher, or - hit with a wielded polearm. Default key is `f'. - #force - Force a lock. Autocompletes. Default key is `M-f'. - - #genocided - List any monster types which have been genocided. In explore - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1456,17 +1456,26 @@ - mode and debug mode it also shows types which have become + #fire + Fire ammunition from quiver, possibly autowielding a launcher, or + hit with a wielded polearm. Default key is `f'. + + #force + Force a lock. Autocompletes. Default key is `M-f'. + + #genocided + List any monster types which have been genocided. In explore + mode and debug mode it also shows types which have become extinct. The display order is the same as is used by #vanquished. The `m' - prefix brings up a menu of available sorting orders, and doing - that for either #genocided or #vanquished changes the order for + prefix brings up a menu of available sorting orders, and doing + that for either #genocided or #vanquished changes the order for both. - If the sorting order is "count high to low" or "count low to - high" (which are applicable for #vanquished), that will be - ignored for #genocided and alphabetical will be used instead. + If the sorting order is "count high to low" or "count low to + high" (which are applicable for #vanquished), that will be + ignored for #genocided and alphabetical will be used instead. The menu omits those two choices when used for #genocide. Autocompletes. Default key is `M-g'. @@ -1476,20 +1485,20 @@ is `;'. #help - Show the help menu. Default key is `?', and also `h' if num- + Show the help menu. Default key is `?', and also `h' if num- ber_pad is on. #herecmdmenu - Show a menu of possible actions directed at your current loca- - tion. The menu is limited to a subset of the likeliest actions, + Show a menu of possible actions directed at your current loca- + tion. The menu is limited to a subset of the likeliest actions, not an exhaustive set of all possibilities. Autocompletes. - If mouse support is enabled and the herecmd_menu option is On, - clicking on the hero (or steed when mounted) will execute this + If mouse support is enabled and the herecmd_menu option is On, + clicking on the hero (or steed when mounted) will execute this command. #history - Show long version and game history. + Show a summary of the game's development. #inventory Show your inventory. Default key is `i'. @@ -1498,21 +1507,12 @@ Inventory specific item types. Default key is `I'. #invoke - Invoke an object's special powers. Autocompletes. Default key + Invoke an object's special powers. Autocompletes. Default key is `M-i'. - #jump - Jump to another location. Autocompletes. Default key is `M-j', - and also `j' if number_pad is on. - - #kick - Kick something. Default key is `^D', and `k' if number_pad is - on. - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1522,15 +1522,23 @@ + #jump + Jump to another location. Autocompletes. Default key is `M-j', + and also `j' if number_pad is on. + + #kick + Kick something. Default key is `^D', and `k' if number_pad is + on. + #known Show what object types have been discovered. Default key is `\'. - The `m' prefix allows assigning a new value to the sortdiscover- + The `m' prefix allows assigning a new value to the sortdiscover- ies option to control the order in which the discoveries are dis- played. #knownclass - Show discovered types for one class of objects. Default key is + Show discovered types for one class of objects. Default key is ``'. The `m' prefix operates the same as for "#known". @@ -1548,37 +1556,29 @@ Describe what you can see, or remember, of your surroundings. #loot - Loot a box or bag on the floor beneath you, or the saddle from a + Loot a box or bag on the floor beneath you, or the saddle from a steed standing next to you. Autocompletes. Precede with the `m' - prefix to skip containers at your location and go directly to - removing a saddle. Default key is `M-l', and also `l' if num- + prefix to skip containers at your location and go directly to + removing a saddle. Default key is `M-l', and also `l' if num- ber_pad is on. #monster - Use a monster's special ability (when polymorphed into monster + Use a monster's special ability (when polymorphed into monster form). Autocompletes. Default key is `M-m'. #name - Name a monster, an individual object, or a type of object. Same + Name a monster, an individual object, or a type of object. Same as "#call". Autocompletes. Default keys are `N', `M-n', and `M- N'. #offer - Offer a sacrifice to the gods. Autocompletes. Default key is + Offer a sacrifice to the gods. Autocompletes. Default key is `M-o'. - You'll need to find an altar to have any chance at success. - Corpses of recently killed monsters are the fodder of choice. - - The `m' prefix skips offering any items which are on the altar. - - #open - Open a door. Default key is `o'. - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1588,37 +1588,45 @@ + You'll need to find an altar to have any chance at success. + Corpses of recently killed monsters are the fodder of choice. + + The `m' prefix skips offering any items which are on the altar. + + #open + Open a door. Default key is `o'. + #options - Show and change option settings. Default key is `O'. Precede + Show and change option settings. Default key is `O'. Precede with the `m' prefix to show advanced options. #optionsfull - Show advanced game option settings. No default key. Precede - with the `m' prefix to execute the simpler options command. - (Mainly useful if you use BINDING=O:optionsfull to switch `O' + Show advanced game option settings. No default key. Precede + with the `m' prefix to execute the simpler options command. + (Mainly useful if you use BINDING=O:optionsfull to switch `O' from simple options back to traditional advanced options.) #overview - Display information you've discovered about the dungeon. Any - visited level with an annotation is included, and many things - (altars, thrones, fountains, and so on; extra stairs leading to + Display information you've discovered about the dungeon. Any + visited level with an annotation is included, and many things + (altars, thrones, fountains, and so on; extra stairs leading to another dungeon branch) trigger an automatic annotation. If dun- geon overview is chosen during end-of-game disclosure, every vis- ited level will be included regardless of annotations. - Precede #overview with the `m' prefix to display the dungeon - overview as a menu where you can select any visited level to add - or remove an annotation without needing to return to that level. - This will also force all visited levels to be displayed rather + Precede #overview with the `m' prefix to display the dungeon + overview as a menu where you can select any visited level to add + or remove an annotation without needing to return to that level. + This will also force all visited levels to be displayed rather than just the "interesting" subset. Autocompletes. Default keys are `^O', and `M-O'. #panic - Test the panic routine. Terminates the current game. Autocom- + Test the panic routine. Terminates the current game. Autocom- pletes. Debug mode only. - Asks for confirmation; default is n (no); continue playing. To + Asks for confirmation; default is n (no); continue playing. To really panic, respond with y. You can set the paranoid_confirma- tion:quit option to require a response of yes instead. @@ -1626,25 +1634,17 @@ Pay your shopping bill. Default key is `p'. #perminv - If persistent inventory display is supported and enabled (with - the perm_invent option), interact with it instead of with the - map. You'll be prompted for menu scrolling keystrokes such as - `>' and `<'. Press Return or Escape to resume normal play. + If persistent inventory display is supported and enabled (with + the perm_invent option), interact with it instead of with the + map. You'll be prompted for menu scrolling keystrokes such as + `>' and `<'. Press Return or Escape to resume normal play. Default key is `|'. #pickup Pick up things at the current location. Default key is `,'. The - `m' prefix forces use of a menu. - - #polyself - Polymorph self. Autocompletes. Debug mode only. - - #pray - Pray to the gods for help. Autocompletes. Default key is `M-p'. - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1654,12 +1654,20 @@ - Praying too soon after receiving prior help is a bad idea. - (Hint: entering the dungeon alive is treated as having received - help. You probably shouldn't start off a new game by praying - right away.) Since using this command by accident can cause - trouble, there is an option to make you confirm your intent - before praying. It is enabled by default, and you can reset the + `m' prefix forces use of a menu. + + #polyself + Polymorph self. Autocompletes. Debug mode only. + + #pray + Pray to the gods for help. Autocompletes. Default key is `M-p'. + + Praying too soon after receiving prior help is a bad idea. + (Hint: entering the dungeon alive is treated as having received + help. You probably shouldn't start off a new game by praying + right away.) Since using this command by accident can cause + trouble, there is an option to make you confirm your intent + before praying. It is enabled by default, and you can reset the paranoid_confirmation option to disable it. #prevmsg @@ -1678,20 +1686,20 @@ Quit the program without saving your game. Autocompletes. Since using this command by accident would throw away the current - game, you are asked to confirm your intent before quitting. - Default response is n (no); continue playing. To really quit, - respond with y. You can set the paranoid_confirmation:quit + game, you are asked to confirm your intent before quitting. + Default response is n (no); continue playing. To really quit, + respond with y. You can set the paranoid_confirmation:quit option to require a response of yes instead. #quiver Select ammunition for quiver. Default key is `Q'. #read - Read a scroll, a spellbook, or something else. Default key is + Read a scroll, a spellbook, or something else. Default key is `r'. #redraw - Redraw the screen. Default key is `^R', and also `^L' if num- + Redraw the screen. Default key is `^R', and also `^L' if num- ber_pad is on. #remove @@ -1700,17 +1708,9 @@ #repeat Repeat the previous command. Default key is `^A'. - #reqmenu - Prefix key to modify the behavior or request menu from some com- - mands. Prevents autopickup when used with movement commands. - Default key is `m'. - - #retravel - Travel to a previously selected travel destination. Default key - is `C-_'. See also #travel. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1720,16 +1720,25 @@ + #reqmenu + Prefix key to modify the behavior or request menu from some com- + mands. Prevents autopickup when used with movement commands. + Default key is `m'. + + #retravel + Travel to a previously selected travel destination. Default key + is `C-_'. See also #travel. + #ride - Ride (or stop riding) a saddled creature. Autocompletes. + Ride (or stop riding) a saddled creature. Autocompletes. Default key is `M-R'. #rub Rub a lamp or a stone. Autocompletes. Default key is `M-r'. #run - Prefix key to run towards a direction. Default key is `G' when - number_pad is off, `5' when number_pad is set to 1 or 3, other- + Prefix key to run towards a direction. Default key is `G' when + number_pad is off, `5' when number_pad is set to 1 or 3, other- wise `M-5' when it is set to 2 or 4. #rush @@ -1741,12 +1750,12 @@ Save the game and exit the program. Default key is `S'. #saveoptions - Save configuration options to the config file. This will over- - write the file, removing all comments, so if you have manually + Save configuration options to the config file. This will over- + write the file, removing all comments, so if you have manually edited the config file, don't use this. #search - Search for traps and secret doors around you. Default key is + Search for traps and secret doors around you. Default key is `s'. #seeall @@ -1763,20 +1772,11 @@ #seearmor Show the armor currently worn. Default key is `['. - Will display worn armor in a menu even when there is only thing + Will display worn armor in a menu even when there is only thing worn. - #seerings - Show the ring(s) currently worn. Default key is `='. - Will display worn rings in a menu if there are two (or there is - just one and is a meat ring rather than a "real" ring). Use the - `m' prefix to force a menu for one ring. - - - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1786,10 +1786,17 @@ + #seerings + Show the ring(s) currently worn. Default key is `='. + + Will display worn rings in a menu if there are two (or there is + just one and is a meat ring rather than a "real" ring). Use the + `m' prefix to force a menu for one ring. + #seetools Show the tools currently in use. Default key is `('. - Will display the result in a message if there is one tool in use + Will display the result in a message if there is one tool in use (worn blindfold or towel or lenses, lit lamp(s) and/or candle(s), leashes attached to pets). Will display a menu if there are more than one or if the command is preceded by the `m' prefix. @@ -1797,32 +1804,32 @@ #seeweapon Show the weapon currently wielded. Default key is `)'. - If dual-wielding, a separate message about the secondary weapon - will be given. Using the `m' prefix will force a menu and it + If dual-wielding, a separate message about the secondary weapon + will be given. Using the `m' prefix will force a menu and it will include primary weapon, alternate weapon even when not dual- - wielding, and also whatever is currently assigned to the quiver + wielding, and also whatever is currently assigned to the quiver slot. #shell - Do a shell escape, switching from NetHack to a subprocess. Can - be disabled at the time the program is built. When enabled, + Do a shell escape, switching from NetHack to a subprocess. Can + be disabled at the time the program is built. When enabled, access for specific users can be controlled by the system config- - uration file. Use the shell command `exit' to return to the + uration file. Use the shell command `exit' to return to the game. Default key is `!'. #showgold - Report the gold in your inventory, including gold you know about - in containers you're carrying. If you are inside a shop, report + Report the gold in your inventory, including gold you know about + in containers you're carrying. If you are inside a shop, report any credit or debt you have in that shop. Default key is `$'. #showspells List and reorder known spells. Default key is `+'. #showtrap - Describe an adjacent trap, possibly covered by objects or a mon- + Describe an adjacent trap, possibly covered by objects or a mon- ster. To be eligible, the trap must already be discovered. (The "#terrain" command can display your map with all objects and mon- - sters temporarily removed, making it possible to see all discov- + sters temporarily removed, making it possible to see all discov- ered traps.) Default key is `^'. #sit @@ -1832,17 +1839,10 @@ Show memory usage statistics. Autocompletes. Debug mode only. #suspend - Suspend the game, switching from NetHack to the terminal it was - started from without performing save-and-exit. Can be disabled - at the time the program is built. When enabled, mainly useful - for tty and curses interfaces on UNIX. Use the shell command - `fg' to return to the game. Default key is `^Z'. - - #swap - Swap wielded and secondary weapons. Default key is `x'. + Suspend the game, switching from NetHack to the terminal it was - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1852,6 +1852,14 @@ + started from without performing save-and-exit. Can be disabled + at the time the program is built. When enabled, mainly useful + for tty and curses interfaces on UNIX. Use the shell command + `fg' to return to the game. Default key is `^Z'. + + #swap + Swap wielded and secondary weapons. Default key is `x'. + #takeoff Take off one piece of armor. Default key is `T'. @@ -1862,25 +1870,25 @@ Teleport around the level. Default key is `^T'. #terrain - Show map without obstructions. In normal play you can view the - explored portion of the current level's map without monsters; - without monsters and objects; or without monsters, objects, and + Show map without obstructions. In normal play you can view the + explored portion of the current level's map without monsters; + without monsters and objects; or without monsters, objects, and traps. If there are visible clouds of gas in view, they are treated like - traps when deciding whether to show them or the floor underneath + traps when deciding whether to show them or the floor underneath them. - In explore mode, you can choose to view the full map rather than - just its explored portion. In debug mode there are additional + In explore mode, you can choose to view the full map rather than + just its explored portion. In debug mode there are additional choices. - Autocompletes. Default key is `' or `' (see Del + Autocompletes. Default key is `' or `' (see Del above). #therecmdmenu - Show a menu of possible actions directed at a location next to - you. The menu is limited to a subset of the likeliest actions, + Show a menu of possible actions directed at a location next to + you. The menu is limited to a subset of the likeliest actions, not an exhaustive set of all possibilities. Autocompletes. #throw @@ -1891,24 +1899,16 @@ #tip Tip over a container (bag or box) to pour out its contents. When - there are containers on the floor, the game will prompt to pick - one of them or "tip something being carried". If the latter is - chosen, there will be another prompt for which item from inven- + there are containers on the floor, the game will prompt to pick + one of them or "tip something being carried". If the latter is + chosen, there will be another prompt for which item from inven- tory to tip. The `m' prefix makes the command skip containers on the floor and - pick one from inventory, except for the special case of - menustyle:traditional with two or more containers present; that - situation will start with the floor container menu. - - Autocompletes. Default key is `M-T'. - - #toggle - Toggle a boolean option on or off. Requires a parameter in - parenthesis, the name of the option to toggle. The option must + pick one from inventory, except for the special case of - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1918,6 +1918,14 @@ + menustyle:traditional with two or more containers present; that + situation will start with the floor container menu. + + Autocompletes. Default key is `M-T'. + + #toggle + Toggle a boolean option on or off. Requires a parameter in + parenthesis, the name of the option to toggle. The option must be settable in-game. For example: @@ -1926,10 +1934,10 @@ BIND=@:toggle(autopickup) #travel - Travel to a specific location on the map. Default key is `_'. - Using the "request menu" prefix shows a menu of interesting tar- - gets in sight without asking to move the cursor. When picking a - target with cursor and the autodescribe option is on, the top + Travel to a specific location on the map. Default key is `_'. + Using the "request menu" prefix shows a menu of interesting tar- + gets in sight without asking to move the cursor. When picking a + target with cursor and the autodescribe option is on, the top line will show "(no travel path)" if your character does not know of a path to that location. See also #retravel. @@ -1937,17 +1945,17 @@ Turn undead away. Autocompletes. Default key is `M-t'. #twoweapon - Toggle two-weapon combat on or off. Autocompletes. Default key + Toggle two-weapon combat on or off. Autocompletes. Default key is `X', and also `M-2' if number_pad is off. - Note that you must use suitable weapons for this type of combat, + Note that you must use suitable weapons for this type of combat, or it will be automatically turned off. #untrap - Untrap something (trap, door, or chest). Default key is `M-u', + Untrap something (trap, door, or chest). Default key is `M-u', and `u' if number_pad is on. - In some circumstances it can also be used to rescue trapped mon- + In some circumstances it can also be used to rescue trapped mon- sters. #up @@ -1956,25 +1964,17 @@ #vanquished List vanquished monsters by type and count. - Note that the vanquished monsters list includes all monsters - killed by traps and each other as well as by you, and omits any - which got removed from the game without being killed (perhaps by - genocide, or by a mollified shopkeeper dismissing summoned Kops) + Note that the vanquished monsters list includes all monsters + killed by traps and each other as well as by you, and omits any + which got removed from the game without being killed (perhaps by + genocide, or by a mollified shopkeeper dismissing summoned Kops) or were already corpses when placed on the map. - Using the "request menu" prefix prior to #vanquished brings up a - menu of sorting orders available (provided that the vanquished - monsters list contains at least two types of monsters). Which- - ever ordering is picked gets assigned to the sortvanquished - option so is remembered for subsequent #vanquished requests. The - "#genocided" command shares this sorting order. - - During end-of-game disclosure, when asked whether to show van- - quished monsters answering `a' will let you choose from the sort - menu. + Using the "request menu" prefix prior to #vanquished brings up a + menu of sorting orders available (provided that the vanquished - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1984,6 +1984,15 @@ + monsters list contains at least two types of monsters). Which- + ever ordering is picked gets assigned to the sortvanquished + option so is remembered for subsequent #vanquished requests. The + "#genocided" command shares this sorting order. + + During end-of-game disclosure, when asked whether to show van- + quished monsters answering `a' will let you choose from the sort + menu. + Autocompletes. Default key is `M-V'. #version @@ -1991,21 +2000,21 @@ The second paragraph lists the user interface(s) that are included. If there are more than one, you can use the windowtype - option in your run-time configuration file to select the one you + option in your run-time configuration file to select the one you want. Autocompletes. Default key is `M-v'. #versionshort - Show the program's version number, plus the date and time that - the running copy was built from sources (not the version's + Show the program's version number, plus the date and time that + the running copy was built from sources (not the version's release date). Default key is `V'. #vision Show vision array. Autocompletes. Debug mode only. #wait - Rest one move while doing nothing. Default key is `.', and also + Rest one move while doing nothing. Default key is `.', and also ` ' if rest_on_space is on. #wear @@ -2015,7 +2024,7 @@ Tell what a key does. Default key is `&'. #whatis - Show what type of thing a symbol corresponds to. Default key is + Show what type of thing a symbol corresponds to. Default key is `/'. #wield @@ -2025,22 +2034,13 @@ Wipe off your face. Autocompletes. Default key is `M-w'. #wizborn - Show monster birth, death, genocide, and extinct statistics. + Show monster birth, death, genocide, and extinct statistics. Debug mode only. - #wizbury - Bury objects under and around you. Autocompletes. Debug mode - only. - - #wizcast - Cast any spell. Debug mode only. - - #wizdetect - Reveal hidden things (secret doors or traps or unseen monsters) - within a modest radius. No time elapses. Autocompletes. Debug - NetHack 5.0.0 April 16, 2026 + + NetHack 5.0.0 May 2, 2026 @@ -2050,6 +2050,16 @@ + #wizbury + Bury objects under and around you. Autocompletes. Debug mode + only. + + #wizcast + Cast any spell. Debug mode only. + + #wizdetect + Reveal hidden things (secret doors or traps or unseen monsters) + within a modest radius. No time elapses. Autocompletes. Debug mode only. Default key is `^E'. #wizgenesis @@ -2057,7 +2067,7 @@ one. Autocompletes. Debug mode only. Default key is `^G'. #wizidentify - Identify all items in inventory. Autocompletes. Debug mode + Identify all items in inventory. Autocompletes. Debug mode only. Default key is `^I'. #wizintrinsic @@ -2065,48 +2075,38 @@ only. #wizkill - Remove monsters from play by just pointing at them. By default - the hero gets credit or blame for killing the targets. Precede - this command with the `m' prefix to override that. Autocom- + Remove monsters from play by just pointing at them. By default + the hero gets credit or blame for killing the targets. Precede + this command with the `m' prefix to override that. Autocom- pletes. Debug mode only. #wizlevelport - Teleport to another level. Autocompletes. Debug mode only. + Teleport to another level. Autocompletes. Debug mode only. Default key is `^V'. #wizmap - Map the level. Autocompletes. Debug mode only. Default key is + Map the level. Autocompletes. Debug mode only. Default key is `^F'. #wizrumorcheck - Verify rumor boundaries by displaying first and last true rumors + Verify rumor boundaries by displaying first and last true rumors and first and last false rumors. - Also displays first, second, and last random engravings, epi- + Also displays first, second, and last random engravings, epi- taphs, and hallucinatory monsters. Autocompletes. Debug mode only. #wizseenv - Show map locations' seen vectors. Autocompletes. Debug mode + Show map locations' seen vectors. Autocompletes. Debug mode only. #wizsmell Smell monster. Autocompletes. Debug mode only. - #wizwhere - Show locations of special levels. Autocompletes. Debug mode - only. - - #wizwish - Wish for something. Autocompletes. Debug mode only. Default - key is `^W'. Precede this command with the `m' prefix to show a - wish history menu. - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2116,6 +2116,15 @@ + #wizwhere + Show locations of special levels. Autocompletes. Debug mode + only. + + #wizwish + Wish for something. Autocompletes. Debug mode only. Default + key is `^W'. Precede this command with the `m' prefix to show a + wish history menu. + #wmode Show wall modes. Autocompletes. Debug mode only. @@ -2127,23 +2136,23 @@ - If your keyboard has a meta key (which, when pressed in combina- - tion with another key, modifies it by setting the "meta" [8th, or - "high"] bit), you can invoke many extended commands by meta-ing the + If your keyboard has a meta key (which, when pressed in combina- + tion with another key, modifies it by setting the "meta" [8th, or + "high"] bit), you can invoke many extended commands by meta-ing the first letter of the command. On Windows and MS-DOS, the "Alt" key can be used in this fashion. - On other systems, if typing "Alt" plus another key transmits a two - character sequence consisting of an Escape followed by the other key, - you may set the altmeta option to have NetHack combine them into - meta+. (This combining action only takes place when NetHack is + On other systems, if typing "Alt" plus another key transmits a two + character sequence consisting of an Escape followed by the other key, + you may set the altmeta option to have NetHack combine them into + meta+. (This combining action only takes place when NetHack is expecting a command to execute, not when accepting input to name some- thing or to make a wish.) Unlike control characters, where ^x and ^X denote the same thing, - meta characters are case-sensitive: M-x and M-X represent different - things. Some commands which can be run via a meta character require - that the letter be capitalized because the lower-case equivalent is + meta characters are case-sensitive: M-x and M-X represent different + things. Some commands which can be run via a meta character require + that the letter be capitalized because the lower-case equivalent is used for another command, so the three key combination meta+Shift+ is needed. @@ -2163,16 +2172,7 @@ - - - - - - - - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2238,7 +2238,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2252,7 +2252,7 @@ - If the number_pad option is on, some additional letter commands + If the number_pad option is on, some additional letter commands are available: h #help @@ -2304,7 +2304,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2316,61 +2316,61 @@ 5. Rooms and corridors - Rooms and corridors in the dungeon are either lit or dark. Any - lit areas within your line of sight will be displayed; dark areas are - only displayed if they are within one space of you. Walls and corri- + Rooms and corridors in the dungeon are either lit or dark. Any + lit areas within your line of sight will be displayed; dark areas are + only displayed if they are within one space of you. Walls and corri- dors remain on the map as you explore them. Secret corridors are hidden and appear to be solid rock. You can find them with the `s' (search) command when adjacent to them. Multi- - ple search attempts may be needed. When searching is successful, - secret corridors become ordinary open corridor locations. Mapping - magic reveals secret corridors, so converts them into ordinary corri- + ple search attempts may be needed. When searching is successful, + secret corridors become ordinary open corridor locations. Mapping + magic reveals secret corridors, so converts them into ordinary corri- dors and shows them as such. 5.1. Doorways - Doorways connect rooms and corridors. Some doorways have no - doors; you can walk right through. Others have doors in them, which - may be open, closed, or locked. To open a closed door, use the `o' - (open) command; to close it again, use the `c' (close) command. By - default the autoopen option is enabled, so simply attempting to walk - onto a closed door's location will attempt to open it without needing - `o'. Opening via autoopen will not work if you are confused or + Doorways connect rooms and corridors. Some doorways have no + doors; you can walk right through. Others have doors in them, which + may be open, closed, or locked. To open a closed door, use the `o' + (open) command; to close it again, use the `c' (close) command. By + default the autoopen option is enabled, so simply attempting to walk + onto a closed door's location will attempt to open it without needing + `o'. Opening via autoopen will not work if you are confused or stunned or suffer from the fumbling attribute. - Open doors cannot be entered diagonally; you must approach them - straight on, horizontally or vertically. Doorways without doors are + Open doors cannot be entered diagonally; you must approach them + straight on, horizontally or vertically. Doorways without doors are not restricted in this fashion except on one particular level (described by "#overview" as "a primitive area"). - Unlocking magic exists but usually won't be available early on. - You can get through a locked door without magic by first using an - unlocking tool with the `a' (apply) command, and then opening it. By - default the autounlock option is also enabled, so if you attempt to - open (via `o' or autoopen) a locked door while carrying an unlocking - tool, you'll be asked whether to use it on the door's lock. Alterna- - tively, you can break a closed door (whether locked or not) down by - kicking it via the `^D' (kick) command. Kicking down a door destroys + Unlocking magic exists but usually won't be available early on. + You can get through a locked door without magic by first using an + unlocking tool with the `a' (apply) command, and then opening it. By + default the autounlock option is also enabled, so if you attempt to + open (via `o' or autoopen) a locked door while carrying an unlocking + tool, you'll be asked whether to use it on the door's lock. Alterna- + tively, you can break a closed door (whether locked or not) down by + kicking it via the `^D' (kick) command. Kicking down a door destroys it and makes a lot of noise which might wake sleeping monsters. - Some closed doors are booby-trapped and will explode if an - attempt is made to open (when unlocked) or unlock (when locked) or - kick down. Like kicking, an explosion destroys the door and makes a - lot of noise. The "#untrap" command can be used to search a door for - traps but might take multiple attempts to find one. When one is - found, you'll be asked whether to try to disarm it. If you accede, - success will eliminate the trap but failure will set off the trap's - explosion. (If you decline, you effectively forget that a trap was + Some closed doors are booby-trapped and will explode if an + attempt is made to open (when unlocked) or unlock (when locked) or + kick down. Like kicking, an explosion destroys the door and makes a + lot of noise. The "#untrap" command can be used to search a door for + traps but might take multiple attempts to find one. When one is + found, you'll be asked whether to try to disarm it. If you accede, + success will eliminate the trap but failure will set off the trap's + explosion. (If you decline, you effectively forget that a trap was found there.) - Closed doors can be useful for shutting out monsters. Most mon- - sters cannot open closed doors, although a few don't need to (for - example, ghosts can walk through doors and fog clouds can flow under + Closed doors can be useful for shutting out monsters. Most mon- + sters cannot open closed doors, although a few don't need to (for + example, ghosts can walk through doors and fog clouds can flow under them). Some monsters who can open doors can also use unlocking tools. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2382,61 +2382,61 @@ And some (giants) can smash doors. - Secret doors are hidden and appear to be ordinary wall (from - inside a room) or solid rock (from outside). You can find them with - the `s' (search) command but it might take multiple tries (possibly - many tries if your luck is poor). Once found they are in all ways - equivalent to normal doors. Mapping magic does not reveal secret + Secret doors are hidden and appear to be ordinary wall (from + inside a room) or solid rock (from outside). You can find them with + the `s' (search) command but it might take multiple tries (possibly + many tries if your luck is poor). Once found they are in all ways + equivalent to normal doors. Mapping magic does not reveal secret doors. 5.2. Traps (`^') - There are traps throughout the dungeon to snare the unwary - intruder. For example, you may suddenly fall into a pit and be stuck + There are traps throughout the dungeon to snare the unwary + intruder. For example, you may suddenly fall into a pit and be stuck for a few turns trying to climb out (see below). A trap usually won't - appear on your map until you trigger it by moving onto it, you see + appear on your map until you trigger it by moving onto it, you see someone else trigger it, or you discover it with the `s' (search) com- - mand (multiple attempts are often needed; if your luck is poor, many - attempts might be needed). Wands of secret door detection and spell - of detect unseen also reveal traps within a modest radius but only if + mand (multiple attempts are often needed; if your luck is poor, many + attempts might be needed). Wands of secret door detection and spell + of detect unseen also reveal traps within a modest radius but only if the trap is also within line-of-sight (whether you can see at the time or not). There is also other magic which can reveal traps. - Monsters can fall prey to traps, too, which can potentially be - used as a defensive strategy. Unfortunately traps can be harmful to - your pet(s) as well. Monsters, including pets, usually will avoid + Monsters can fall prey to traps, too, which can potentially be + used as a defensive strategy. Unfortunately traps can be harmful to + your pet(s) as well. Monsters, including pets, usually will avoid moving onto a trap which is shown on your map if they have encountered that type of trap before. - Some traps such as pits, bear traps, and webs hold you in one - place. You can escape by simply trying to move to an adjacent spot + Some traps such as pits, bear traps, and webs hold you in one + place. You can escape by simply trying to move to an adjacent spot and repeat as needed; eventually you will get free. - Other traps can send you to different locations. Teleporters - send you elsewhere on the same dungeon level. Level teleporters send - you to a random dungeon level, the destination chosen from a few lev- - els lower all the way to the top. These traps choose a new destina- - tion each time they're activated. Trap doors and holes also send you - to another level, but one which is always below the current level. - Usually that will be the next level down but it can be farther. + Other traps can send you to different locations. Teleporters + send you elsewhere on the same dungeon level. Level teleporters send + you to a random dungeon level, the destination chosen from a few lev- + els lower all the way to the top. These traps choose a new destina- + tion each time they're activated. Trap doors and holes also send you + to another level, but one which is always below the current level. + Usually that will be the next level down but it can be farther. Unlike (level) teleporters, the destination level of a particular trap - door or hole is persistent, so falling into one will bring you to the - same level each time--though not necessarily the same spot on the + door or hole is persistent, so falling into one will bring you to the + same level each time--though not necessarily the same spot on the level. Magic portals behave similarly, but with some additional vari- - ation. Some portals are two-way and their remote destination is - always the same: another portal which can take you back. Others are + ation. Some portals are two-way and their remote destination is + always the same: another portal which can take you back. Others are one-way and send you to a specific destination level but not necessar- ily to a specific location there. - There is a special multi-level branch of the dungeon with pre- - mapped levels based on the classic computer game "Sokoban." In that - game, you operate as a warehouse worker who pushes crates around - obstacles to position them at designated locations. In NetHack, the + There is a special multi-level branch of the dungeon with pre- + mapped levels based on the classic computer game "Sokoban." In that + game, you operate as a warehouse worker who pushes crates around + obstacles to position them at designated locations. In NetHack, the goal is to push boulders into pits or holes until those traps have all - been nullified, giving access to whatever is beyond them. In the + been nullified, giving access to whatever is beyond them. In the - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2446,63 +2446,63 @@ - Sokoban game, you can only move in the four cardinal compass direc- - tions, and a crate in its final destination blocks further access to - that spot. In the Sokoban levels of NetHack, you can move diagonally - (unless that would let you pass between two neighboring boulders) but - you can only push boulders in the four cardinal directions, and a - boulder which fills a pit or hole removes both the boulder and the - trap so opens up normal access to that spot. With careful foresight, - it is possible to complete all of the levels according to the tradi- - tional rules of Sokoban. (Hint: to solve Sokoban puzzles, you often - need to move things away from their eventual destinations in order to - open up more room to maneuver.) Since NetHack does not support an - undo capability, some allowances are permitted in case you get stuck. - For example, each level has at least one extra boulder. Also, it is - possible to drop everything in order to be able to squeeze into the - same location as a boulder (and then presumably move past it), or to - destroy a boulder with magic or tools, or to create new boulders with - a scroll of earth. However, doing such things will lower your luck - without any specific message given about that. See the Conduct sec- - tion for information about getting feedback for your actions in + Sokoban game, you can only move in the four cardinal compass direc- + tions, and a crate in its final destination blocks further access to + that spot. In the Sokoban levels of NetHack, you can move diagonally + (unless that would let you pass between two neighboring boulders) but + you can only push boulders in the four cardinal directions, and a + boulder which fills a pit or hole removes both the boulder and the + trap so opens up normal access to that spot. With careful foresight, + it is possible to complete all of the levels according to the tradi- + tional rules of Sokoban. (Hint: to solve Sokoban puzzles, you often + need to move things away from their eventual destinations in order to + open up more room to maneuver.) Since NetHack does not support an + undo capability, some allowances are permitted in case you get stuck. + For example, each level has at least one extra boulder. Also, it is + possible to drop everything in order to be able to squeeze into the + same location as a boulder (and then presumably move past it), or to + destroy a boulder with magic or tools, or to create new boulders with + a scroll of earth. However, doing such things will lower your luck + without any specific message given about that. See the Conduct sec- + tion for information about getting feedback for your actions in Sokoban. 5.3. Stairs and ladders (`<', `>') In general, each level in the dungeon will have a staircase going - up (`<') to the previous level and another going down (`>') to the - next level. There are some exceptions though. For instance, fairly - early in the dungeon you will find a level with two down staircases, - one continuing into the dungeon and the other branching into an area + up (`<') to the previous level and another going down (`>') to the + next level. There are some exceptions though. For instance, fairly + early in the dungeon you will find a level with two down staircases, + one continuing into the dungeon and the other branching into an area known as the Gnomish Mines. Those mines eventually hit a dead end, so - after exploring them (if you choose to do so), you'll need to climb + after exploring them (if you choose to do so), you'll need to climb back up to the main dungeon. - When you traverse a set of stairs, or trigger a trap which sends + When you traverse a set of stairs, or trigger a trap which sends you to another level, the level you're leaving will be deactivated and - stored in a file on disk. If you're moving to a previously visited - level, it will be loaded from its file on disk and reactivated. If - you're moving to a level which has not yet been visited, it will be + stored in a file on disk. If you're moving to a previously visited + level, it will be loaded from its file on disk and reactivated. If + you're moving to a level which has not yet been visited, it will be created (from scratch for most random levels, from a template for some - "special" levels, or loaded from the remains of an earlier game for a - "bones" level as briefly described below). Monsters are only active - on the current level; those on other levels are essentially placed + "special" levels, or loaded from the remains of an earlier game for a + "bones" level as briefly described below). Monsters are only active + on the current level; those on other levels are essentially placed into stasis. Ordinarily when you climb a set of stairs, you will arrive on the - corresponding staircase at your destination. However, pets (see - below) and some other monsters will follow along if they're close - enough when you travel up or down stairs, and occasionally one of + corresponding staircase at your destination. However, pets (see + below) and some other monsters will follow along if they're close + enough when you travel up or down stairs, and occasionally one of these creatures will displace you during the climb. When that occurs, the pet or other monster will arrive on the staircase and you will end up nearby. - Ladders serve the same purpose as staircases, and the two types - of inter-level connections are nearly indistinguishable during game + Ladders serve the same purpose as staircases, and the two types + of inter-level connections are nearly indistinguishable during game play. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2514,36 +2514,36 @@ 5.4. Shops and shopping - Occasionally you will run across a room with a shopkeeper near - the door and many items lying on the floor. You can buy items by + Occasionally you will run across a room with a shopkeeper near + the door and many items lying on the floor. You can buy items by picking them up and then using the `p' command. You can inquire about - the price of an item prior to picking it up by using the "#chat" com- - mand while standing on it. Using an item prior to paying for it will - incur a charge, and the shopkeeper won't allow you to leave the shop + the price of an item prior to picking it up by using the "#chat" com- + mand while standing on it. Using an item prior to paying for it will + incur a charge, and the shopkeeper won't allow you to leave the shop until you have paid any debt you owe. - You can sell items to a shopkeeper by dropping them to the floor + You can sell items to a shopkeeper by dropping them to the floor while inside a shop. You will either be offered an amount of gold and asked whether you're willing to sell, or you'll be told that the shop- - keeper isn't interested (generally, your item needs to be compatible + keeper isn't interested (generally, your item needs to be compatible with the type of merchandise carried by the shop). - If you drop something in a shop by accident, the shopkeeper will - usually claim ownership without offering any compensation. You'll + If you drop something in a shop by accident, the shopkeeper will + usually claim ownership without offering any compensation. You'll have to buy it back if you want to reclaim it. Shopkeepers sometime run out of money. When that happens, you'll - be offered credit instead of gold when you try to sell something. - Credit can be used to pay for purchases, but it is only good in the + be offered credit instead of gold when you try to sell something. + Credit can be used to pay for purchases, but it is only good in the shop where it was obtained; other shopkeepers won't honor it. (If you - happen to find a "credit card" in the dungeon, don't bother trying to + happen to find a "credit card" in the dungeon, don't bother trying to use it in shops; shopkeepers will not accept it.) - The `$' command, which reports the amount of gold you are carry- - ing, will also show current shop debt or credit, if any. The "Iu" - command lists unpaid items (those which still belong to the shop) if - you are carrying any. The "Ix" command shows an inventory-like dis- - play of any unpaid items which have been used up, along with other + The `$' command, which reports the amount of gold you are carry- + ing, will also show current shop debt or credit, if any. The "Iu" + command lists unpaid items (those which still belong to the shop) if + you are carrying any. The "Ix" command shows an inventory-like dis- + play of any unpaid items which have been used up, along with other shop fees, if any. 5.4.1. Shop idiosyncrasies @@ -2552,23 +2552,23 @@ * The price of a given item can vary due to a variety of factors. - * A shopkeeper treats the spot immediately inside the door as if it + * A shopkeeper treats the spot immediately inside the door as if it were outside the shop. - * While the shopkeeper watches you like a hawk, he or she will gener- + * While the shopkeeper watches you like a hawk, he or she will gener- ally ignore any other customers. - * If a shop is "closed for inventory," it will not open of its own + * If a shop is "closed for inventory," it will not open of its own accord. - * Shops do not get restocked with new items, regardless of inventory + * Shops do not get restocked with new items, regardless of inventory depletion. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2580,61 +2580,61 @@ 5.5. Movement feedback - Moving around the map usually provides no feedback--other than - drawing the hero at the new location--unless you step on an object or - pile of objects, or on a trap, or attempt to move onto a spot where a - monster is located. There are several options which can be used to + Moving around the map usually provides no feedback--other than + drawing the hero at the new location--unless you step on an object or + pile of objects, or on a trap, or attempt to move onto a spot where a + monster is located. There are several options which can be used to augment the normal feedback. - The pile_limit option controls how many objects can be in a - pile--sharing the same map location--for the game to state "there are - objects here" instead of listing them. The default is 5. Setting it - to 1 would always give that message instead of listing any objects. - Setting it to 0 is a special case which will always list all objects + The pile_limit option controls how many objects can be in a + pile--sharing the same map location--for the game to state "there are + objects here" instead of listing them. The default is 5. Setting it + to 1 would always give that message instead of listing any objects. + Setting it to 0 is a special case which will always list all objects no matter how big a pile is. Note that the number refers to the count of separate stacks of objects present rather than the sum of the quan- - tities of those stacks (so 7 arrows or 25 gold pieces will each count - as 1 rather than as 7 and 25, respectively, and total to 2 when both + tities of those stacks (so 7 arrows or 25 gold pieces will each count + as 1 rather than as 7 and 25, respectively, and total to 2 when both are at the same location). - The "nopickup" command prefix (default `m') can be used before a - movement direction to step on objects without attempting auto-pickup + The "nopickup" command prefix (default `m') can be used before a + movement direction to step on objects without attempting auto-pickup and without giving feedback about them. The mention_walls option controls whether you get feedback if you - try to walk into a wall or solid stone or off the edge of the map. - Normally nothing happens (unless the hero is blind and no wall is - shown, then the wall that is being bumped into will be drawn on the - map). This option also gives feedback when rushing or running stops + try to walk into a wall or solid stone or off the edge of the map. + Normally nothing happens (unless the hero is blind and no wall is + shown, then the wall that is being bumped into will be drawn on the + map). This option also gives feedback when rushing or running stops for some non-obvious reason. - The mention_decor option controls whether you get feedback when - walking on "furniture." Normally stepping onto stairs or a fountain - or an altar or various other things doesn't elicit anything unless it - is covered by one or more objects so is obscured on the map. Setting - this option to true will describe such things even when they aren't - obscured. Doorless doorways and open doors aren't considered worthy + The mention_decor option controls whether you get feedback when + walking on "furniture." Normally stepping onto stairs or a fountain + or an altar or various other things doesn't elicit anything unless it + is covered by one or more objects so is obscured on the map. Setting + this option to true will describe such things even when they aren't + obscured. Doorless doorways and open doors aren't considered worthy of mention; closed doors (if you can move onto their spots) and broken - doors are. Assuming that you're able to do so, moving onto water or - lava or ice will give feedback if not yet on that type of terrain but - not repeat it (unless there has been some intervening message) when - moving from water to another water spot, or lava to lava, or ice to - ice. Moving off of any of those back onto "normal" terrain will give - one message too, unless there is feedback about one or more objects, + doors are. Assuming that you're able to do so, moving onto water or + lava or ice will give feedback if not yet on that type of terrain but + not repeat it (unless there has been some intervening message) when + moving from water to another water spot, or lava to lava, or ice to + ice. Moving off of any of those back onto "normal" terrain will give + one message too, unless there is feedback about one or more objects, in which case the back on land circumstance is implied. - The confirm and safe_pet options control what happens when you + The confirm and safe_pet options control what happens when you try to move onto a peaceful monster's spot or a tame one's spot. - The "nopickup" command prefix (default `m') is also the move- + The "nopickup" command prefix (default `m') is also the move- without-attacking prefix and can be used to try to step onto a visible - monster's spot without the move being considered an attack (see the - Fighting subsection of Monsters below). The "fight" command prefix - (default `F'; also `-' if number_pad is on) can be used to force an - attack, when guessing where an unseen monster is or when deliberately + monster's spot without the move being considered an attack (see the + Fighting subsection of Monsters below). The "fight" command prefix + (default `F'; also `-' if number_pad is on) can be used to force an + attack, when guessing where an unseen monster is or when deliberately - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2646,22 +2646,22 @@ attacking a peaceful or tame creature. - The run_mode option controls how frequently the map gets redrawn - when moving more than one step in a single command (so when rushing, + The run_mode option controls how frequently the map gets redrawn + when moving more than one step in a single command (so when rushing, running, or traveling). 5.6. Rogue level - One dungeon level (occurring in mid to late teens of the main + One dungeon level (occurring in mid to late teens of the main dungeon) is a tribute to the ancestor game hack's inspiration rogue. - It is usually displayed differently from other levels: possibly - in characters instead of tiles, or without line-drawing symbols if - already in characters; also, gold is shown as * rather than $ and - stairs are shown as % rather than < and >. There are some minor dif- - ferences in actual game play: doorways lack doors; a scroll, wand, or - spell of light used in a room lights up the whole room rather than - within a radius around your character. And monsters represented by + It is usually displayed differently from other levels: possibly + in characters instead of tiles, or without line-drawing symbols if + already in characters; also, gold is shown as * rather than $ and + stairs are shown as % rather than < and >. There are some minor dif- + ferences in actual game play: doorways lack doors; a scroll, wand, or + spell of light used in a room lights up the whole room rather than + within a radius around your character. And monsters represented by lower-case letters aren't randomly generated on the rogue level. The slight strangeness of this level is a feature, not a bug.... @@ -2669,38 +2669,38 @@ 6. Monsters Monsters you cannot see are not displayed on the screen. Beware! - You may suddenly come upon one in a dark place. Some magic items can - help you locate them before they locate you (which some monsters can + You may suddenly come upon one in a dark place. Some magic items can + help you locate them before they locate you (which some monsters can do very well). - The commands `/' and `;' may be used to obtain information about - those monsters who are displayed on the screen. The command "#name" - (by default bound to `C'), allows you to assign a name to a monster, + The commands `/' and `;' may be used to obtain information about + those monsters who are displayed on the screen. The command "#name" + (by default bound to `C'), allows you to assign a name to a monster, which may be useful to help distinguish one from another when multiple - monsters are present. Assigning a name which is just a space will + monsters are present. Assigning a name which is just a space will remove any prior name. - The extended command "#chat" can be used to interact with an - adjacent monster. There is no actual dialog (in other words, you - don't get to choose what you'll say), but chatting with some monsters - such as a shopkeeper or the Oracle of Delphi can produce useful + The extended command "#chat" can be used to interact with an + adjacent monster. There is no actual dialog (in other words, you + don't get to choose what you'll say), but chatting with some monsters + such as a shopkeeper or the Oracle of Delphi can produce useful results. 6.1. Fighting - If you see a monster and you wish to fight it, just attempt to - walk into it. Many monsters you find will mind their own business + If you see a monster and you wish to fight it, just attempt to + walk into it. Many monsters you find will mind their own business unless you attack them. Some of them are very dangerous when angered. Remember: discretion is the better part of valor. - In most circumstances, if you attempt to attack a peaceful mon- - ster by moving into its location, you'll be asked to confirm your - intent. By default an answer of `y' acknowledges that intent, which + In most circumstances, if you attempt to attack a peaceful mon- + ster by moving into its location, you'll be asked to confirm your + intent. By default an answer of `y' acknowledges that intent, which can be error prone if you're using `y' to move. You can set the para- - noid_confirmation:attack option to require a response of "yes" + noid_confirmation:attack option to require a response of "yes" - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2712,61 +2712,61 @@ instead. - If you can't see a monster (if it is invisible, or if you are + If you can't see a monster (if it is invisible, or if you are blinded), the symbol `I' will be shown when you learn of its presence. - If you attempt to walk into it, you will try to fight it just like a - monster that you can see; of course, if the monster has moved, you - will attack empty air. If you guess that the monster has moved and - you don't wish to fight, you can use the `m' command to move without - fighting; likewise, if you don't remember a monster but want to try + If you attempt to walk into it, you will try to fight it just like a + monster that you can see; of course, if the monster has moved, you + will attack empty air. If you guess that the monster has moved and + you don't wish to fight, you can use the `m' command to move without + fighting; likewise, if you don't remember a monster but want to try fighting anyway, you can use the `F' command. 6.2. Your pet You start the game with a little dog (`d'), kitten (`f'), or pony - (`u'), which follows you about the dungeon and fights monsters with + (`u'), which follows you about the dungeon and fights monsters with you. Like you, your pet needs food to survive. Dogs and cats usually feed themselves on fresh carrion and other meats; horses need vegetar- ian food which is harder to come by. If you're worried about your pet - or want to train it, you can feed it, too, by throwing it food. A + or want to train it, you can feed it, too, by throwing it food. A properly trained pet can be very useful under certain circumstances. - Your pet also gains experience from killing monsters, and can - grow over time, gaining hit points and doing more damage. Initially, - your pet may even be better at killing things than you, which makes + Your pet also gains experience from killing monsters, and can + grow over time, gaining hit points and doing more damage. Initially, + your pet may even be better at killing things than you, which makes pets useful for low-level characters. - Your pet will follow you up and down staircases if it is next to + Your pet will follow you up and down staircases if it is next to you when you move. Otherwise your pet will be stranded and may become - wild. Similarly, when you trigger certain types of traps which alter - your location (for instance, a trap door which drops you to a lower - dungeon level), any adjacent pet will accompany you and any non-adja- + wild. Similarly, when you trigger certain types of traps which alter + your location (for instance, a trap door which drops you to a lower + dungeon level), any adjacent pet will accompany you and any non-adja- cent pet will be left behind. Your pet may trigger such traps itself; you will not be carried along with it even if adjacent at the time. 6.3. Steeds - Some types of creatures in the dungeon can actually be ridden if - you have the right equipment and skill. Convincing a wild beast to + Some types of creatures in the dungeon can actually be ridden if + you have the right equipment and skill. Convincing a wild beast to let you saddle it up is difficult to say the least. Many a dungeoneer - has had to resort to magic and wizardry in order to forge the - alliance. Once you do have the beast under your control however, you - can easily climb in and out of the saddle with the "#ride" command. - Lead the beast around the dungeon when riding, in the same manner as - you would move yourself. It is the beast that you will see displayed + has had to resort to magic and wizardry in order to forge the + alliance. Once you do have the beast under your control however, you + can easily climb in and out of the saddle with the "#ride" command. + Lead the beast around the dungeon when riding, in the same manner as + you would move yourself. It is the beast that you will see displayed on the map. - Riding skill is managed by the "#enhance" command. See the sec- + Riding skill is managed by the "#enhance" command. See the sec- tion on Weapon proficiency for more information about that. - Use the `a' (apply) command and pick a saddle in your inventory + Use the `a' (apply) command and pick a saddle in your inventory to attempt to put that saddle on an adjacent creature. If successful, it will be transferred to that creature's inventory. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2776,63 +2776,63 @@ - Use the "#loot" command while adjacent to a saddled creature to - try to remove the saddle from that creature. If successful, it will + Use the "#loot" command while adjacent to a saddled creature to + try to remove the saddle from that creature. If successful, it will be transferred to your inventory. 6.4. Bones levels You may encounter the shades and corpses of other adventurers (or - even former incarnations of yourself!) and their personal effects. - Ghosts are hard to kill, but easy to avoid, since they're slow and do + even former incarnations of yourself!) and their personal effects. + Ghosts are hard to kill, but easy to avoid, since they're slow and do little damage. You can plunder the deceased adventurer's possessions; - however, they are likely to be cursed. Beware of whatever killed the - former player; it is probably still lurking around, gloating over its + however, they are likely to be cursed. Beware of whatever killed the + former player; it is probably still lurking around, gloating over its last victory. 6.5. Persistence of Monsters - Monsters (a generic reference which also includes humans and + Monsters (a generic reference which also includes humans and pets) are only shown while they can be seen or otherwise sensed. Mov- ing to a location where you can't see or sense a monster any more will - result in it disappearing from your map, similarly if it is the one + result in it disappearing from your map, similarly if it is the one who moved rather than you. - However, if you encounter a monster which you can't see or + However, if you encounter a monster which you can't see or sense--perhaps it is invisible and has just tapped you on the noggin-- a special "remembered, unseen monster" marker will be displayed at the - location where you think it is. That will persist until you have - proven that there is no monster there, even if the unseen monster - moves to another location or you move to a spot where the marker's + location where you think it is. That will persist until you have + proven that there is no monster there, even if the unseen monster + moves to another location or you move to a spot where the marker's location ordinarily wouldn't be seen any more. 7. Objects - When you find something in the dungeon, it is common to want to - pick it up. In NetHack, this is accomplished by using the `,' com- - mand. If autopickup option is on, you will automatically pick up the + When you find something in the dungeon, it is common to want to + pick it up. In NetHack, this is accomplished by using the `,' com- + mand. If autopickup option is on, you will automatically pick up the object by walking over, unless you move with the `m' prefix. - If you're carrying too many items, NetHack will tell you so and - you won't be able to pick up anything more. Otherwise, it will add + If you're carrying too many items, NetHack will tell you so and + you won't be able to pick up anything more. Otherwise, it will add the object(s) to your pack and tell you what you just picked up. - As you add items to your inventory, you also add the weight of - that object to your load. The amount that you can carry depends on - your strength and your constitution. The stronger and sturdier you - are, the less the additional load will affect you. There comes a - point, though, when the weight of all of that stuff you are carrying + As you add items to your inventory, you also add the weight of + that object to your load. The amount that you can carry depends on + your strength and your constitution. The stronger and sturdier you + are, the less the additional load will affect you. There comes a + point, though, when the weight of all of that stuff you are carrying around with you through the dungeon will encumber you. Your reactions - will get slower and you'll burn calories faster, requiring food more - frequently to cope with it. Eventually, you'll be so overloaded that + will get slower and you'll burn calories faster, requiring food more + frequently to cope with it. Eventually, you'll be so overloaded that you'll either have to discard some of what you're carrying or collapse under its weight. NetHack will tell you how badly you have loaded yourself. If you - are encumbered, one of the conditions Burdened, Stressed, Strained, + are encumbered, one of the conditions Burdened, Stressed, Strained, - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2842,63 +2842,63 @@ - Overtaxed, or Overloaded will be shown on the bottom line status dis- + Overtaxed, or Overloaded will be shown on the bottom line status dis- play. - When you pick up an object, it is assigned an inventory letter. - Many commands that operate on objects must ask you to find out which - object you want to use. When NetHack asks you to choose a particular - object you are carrying, you are usually presented with a list of + When you pick up an object, it is assigned an inventory letter. + Many commands that operate on objects must ask you to find out which + object you want to use. When NetHack asks you to choose a particular + object you are carrying, you are usually presented with a list of inventory letters to choose from (see Commands, above). - Some objects, such as weapons, are easily differentiated. Oth- - ers, like scrolls and potions, are given descriptions which vary - according to type. During a game, any two objects with the same - description are the same type. However, the descriptions will vary + Some objects, such as weapons, are easily differentiated. Oth- + ers, like scrolls and potions, are given descriptions which vary + according to type. During a game, any two objects with the same + description are the same type. However, the descriptions will vary from game to game. - When you use one of these objects, if its effect is obvious, - NetHack will remember what it is for you. If its effect isn't - extremely obvious, you will be asked what you want to call this type - of object so you will recognize it later. You can also use the + When you use one of these objects, if its effect is obvious, + NetHack will remember what it is for you. If its effect isn't + extremely obvious, you will be asked what you want to call this type + of object so you will recognize it later. You can also use the "#name" command, for the same purpose at any time, to name all objects - of a particular type or just an individual object. When you use - "#name" on an object which has already been named, specifying a space - as the value will remove the prior name instead of assigning a new + of a particular type or just an individual object. When you use + "#name" on an object which has already been named, specifying a space + as the value will remove the prior name instead of assigning a new one. 7.1. Curses and Blessings - Any object that you find may be cursed, even if the object is - otherwise helpful. The most common effect of a curse is being stuck - with (and to) the item. Cursed weapons weld themselves to your hand + Any object that you find may be cursed, even if the object is + otherwise helpful. The most common effect of a curse is being stuck + with (and to) the item. Cursed weapons weld themselves to your hand when wielded, so you cannot unwield them. Any cursed item you wear is - not removable by ordinary means. In addition, cursed arms and armor - usually, but not always, bear negative enchantments that make them - less effective in combat. Other cursed objects may act poorly or + not removable by ordinary means. In addition, cursed arms and armor + usually, but not always, bear negative enchantments that make them + less effective in combat. Other cursed objects may act poorly or detrimentally in other ways. - Objects can also be blessed instead. Blessed items usually work - better or more beneficially than normal uncursed items. For example, + Objects can also be blessed instead. Blessed items usually work + better or more beneficially than normal uncursed items. For example, a blessed weapon will do slightly more damage against demons. - Objects which are neither cursed nor blessed are referred to as + Objects which are neither cursed nor blessed are referred to as uncursed. They could just as easily have been described as unblessed, - but the uncursed designation is what you will see within the game. A + but the uncursed designation is what you will see within the game. A "glass half full versus glass half empty" situation; make of that what you will. - There are magical means of bestowing or removing curses upon - objects, so even if you are stuck with one, you can still have the - curse lifted and the item removed. Priests and Priestesses have an - innate sensitivity to this property in any object, so they can more - easily avoid cursed objects than other character roles. Dropping - objects onto an altar will reveal their bless or curse state provided + There are magical means of bestowing or removing curses upon + objects, so even if you are stuck with one, you can still have the + curse lifted and the item removed. Priests and Priestesses have an + innate sensitivity to this property in any object, so they can more + easily avoid cursed objects than other character roles. Dropping + objects onto an altar will reveal their bless or curse state provided that you can see them land. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2908,44 +2908,44 @@ - An item with unknown status will be reported in your inventory - with no prefix. An item which you know the state of will be distin- - guished in your inventory by the presence of the word cursed, - uncursed, or blessed in the description of the item. In some cases + An item with unknown status will be reported in your inventory + with no prefix. An item which you know the state of will be distin- + guished in your inventory by the presence of the word cursed, + uncursed, or blessed in the description of the item. In some cases uncursed will be omitted as being redundant when enough other informa- - tion is displayed. The implicit_uncursed option can be used to con- - trol this; toggle it off to have uncursed be displayed even when that + tion is displayed. The implicit_uncursed option can be used to con- + trol this; toggle it off to have uncursed be displayed even when that can be deduced from other attributes. - Sometimes the bless or curse state of objects is referred to as - their "BUC" attribute, for Blessed, Uncursed, or Cursed state, or + Sometimes the bless or curse state of objects is referred to as + their "BUC" attribute, for Blessed, Uncursed, or Cursed state, or "BUCX" for Blessed, Uncursed, Cursed, or unknown. (The term beatitude is occasionally used as well.) 7.2. Artifacts - Some objects have been imbued with special powers and are known - as Artifacts. They have specific types (such as long sword or orcish + Some objects have been imbued with special powers and are known + as Artifacts. They have specific types (such as long sword or orcish dagger) and distinct names such as Giantslayer or Grimtooth. Artifact - weapons typically do more damage than their ordinary counterparts. - Some do extra damage against all monsters, others only against spe- - cific types of monsters so aren't better than regular weapons against - other types. Some confer defensive capabilities when wielded or have + weapons typically do more damage than their ordinary counterparts. + Some do extra damage against all monsters, others only against spe- + cific types of monsters so aren't better than regular weapons against + other types. Some confer defensive capabilities when wielded or have other powers that aren't listed here. - You might find them simply lying on the floor, including but not - limited to inside shops, or be granted as a reward for "#offer" on an - altar to your patron deity. A few might be dropped by monsters, or - might be converted from an ordinary object of the same type via - assigning the right name. Or you might wish for them, if you happen + You might find them simply lying on the floor, including but not + limited to inside shops, or be granted as a reward for "#offer" on an + altar to your patron deity. A few might be dropped by monsters, or + might be converted from an ordinary object of the same type via + assigning the right name. Or you might wish for them, if you happen to be granted a wish, but such wishes can fail. - Some artifacts have a specific alignment, others don't. You - won't obtain aligned ones that have a different alignment from yours - via offering and might get a shock if you attempt to wish for any of + Some artifacts have a specific alignment, others don't. You + won't obtain aligned ones that have a different alignment from yours + via offering and might get a shock if you attempt to wish for any of those or find one and attempt to use it. - Each role has a distinct artifact that is contained in the Quest + Each role has a distinct artifact that is contained in the Quest dungeon branch. These are commonly known as quest artifacts. All are aligned and most are non-weapons. They won't be found randomly. @@ -2955,16 +2955,16 @@ 7.3. Relics There are three unique items that are named and have limited spe- - cial powers but aren't classified as artifacts. Each is guarded by a - particular monster and you'll need to collect all three for use late - in the game. They are the Bell of Opening, the Book of the Dead, and - the Candelabrum of Invocation. Their corresponding descriptions when - not yet identified are silver bell, papyrus spellbook, and cande- + cial powers but aren't classified as artifacts. Each is guarded by a + particular monster and you'll need to collect all three for use late + in the game. They are the Bell of Opening, the Book of the Dead, and + the Candelabrum of Invocation. Their corresponding descriptions when + not yet identified are silver bell, papyrus spellbook, and cande- labrum. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2976,61 +2976,61 @@ 7.4. Weapons (`)') - Given a chance, most monsters in the Mazes of Menace will gratu- - itously try to kill you. You need weapons for self-defense (killing - them first). Without a weapon, you do only 1-2 hit points of damage - (plus bonuses, if any). Monk characters are an exception; they nor- - mally do more damage with bare (or gloved) hands than they do with + Given a chance, most monsters in the Mazes of Menace will gratu- + itously try to kill you. You need weapons for self-defense (killing + them first). Without a weapon, you do only 1-2 hit points of damage + (plus bonuses, if any). Monk characters are an exception; they nor- + mally do more damage with bare (or gloved) hands than they do with weapons. - There are wielded weapons, like maces and swords, and thrown - weapons, like arrows and spears. To hit monsters with a weapon, you - must wield it and attack them, or throw it at them. You can simply - elect to throw a spear. To shoot an arrow, you should first wield a - bow, then throw the arrow. Crossbows shoot crossbow bolts. Slings + There are wielded weapons, like maces and swords, and thrown + weapons, like arrows and spears. To hit monsters with a weapon, you + must wield it and attack them, or throw it at them. You can simply + elect to throw a spear. To shoot an arrow, you should first wield a + bow, then throw the arrow. Crossbows shoot crossbow bolts. Slings hurl rocks and (other) stones (like gems). - Enchanted weapons have a "plus" (or "to hit enhancement" which - can be either positive or negative) that adds to your chance to hit - and the damage you do to a monster. The only way to determine a + Enchanted weapons have a "plus" (or "to hit enhancement" which + can be either positive or negative) that adds to your chance to hit + and the damage you do to a monster. The only way to determine a weapon's enchantment is to have it magically identified somehow. Most - weapons are subject to some type of damage like rust. Such "erosion" + weapons are subject to some type of damage like rust. Such "erosion" damage can be repaired. - The chance that an attack will successfully hit a monster, and - the amount of damage such a hit will do, depends upon many factors. - Among them are: type of weapon, quality of weapon (enchantment and/or + The chance that an attack will successfully hit a monster, and + the amount of damage such a hit will do, depends upon many factors. + Among them are: type of weapon, quality of weapon (enchantment and/or erosion), experience level, strength, dexterity, encumbrance, and pro- - ficiency (see below). The monster's armor class--a general defense - rating, not necessarily due to wearing of armor--is a factor too; - also, some monsters are particularly vulnerable to certain types of + ficiency (see below). The monster's armor class--a general defense + rating, not necessarily due to wearing of armor--is a factor too; + also, some monsters are particularly vulnerable to certain types of weapons. Many weapons can be wielded in one hand; some require both hands. When wielding a two-handed weapon, you can not wear a shield, and vice versa. When wielding a one-handed weapon, you can have another weapon - ready to use by setting things up with the `x' command, which - exchanges your primary (the one being wielded) and alternate weapons. - And if you have proficiency in the "two weapon combat" skill, you may - wield both weapons simultaneously as primary and secondary; use the - `X' command to engage or disengage that. Only some types of charac- - ters (barbarians, for instance) have the necessary skill available. - Even with that skill, using two weapons at once incurs a penalty in - the chance to hit your target compared to using just one weapon at a + ready to use by setting things up with the `x' command, which + exchanges your primary (the one being wielded) and alternate weapons. + And if you have proficiency in the "two weapon combat" skill, you may + wield both weapons simultaneously as primary and secondary; use the + `X' command to engage or disengage that. Only some types of charac- + ters (barbarians, for instance) have the necessary skill available. + Even with that skill, using two weapons at once incurs a penalty in + the chance to hit your target compared to using just one weapon at a time. - There might be times when you'd rather not wield any weapon at + There might be times when you'd rather not wield any weapon at all. To accomplish that, wield `-', or else use the `A' command which - allows you to unwield the current weapon in addition to taking off + allows you to unwield the current weapon in addition to taking off other worn items. - Those of you in the audience who are AD&D players, be aware that + Those of you in the audience who are AD&D players, be aware that each weapon which existed in AD&D does roughly the same damage to mon- - sters in NetHack. Some of the more obscure weapons (such as the + sters in NetHack. Some of the more obscure weapons (such as the aklys, lucern hammer, and bec-de-corbin) are defined in an appendix to - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3042,61 +3042,61 @@ Unearthed Arcana, an AD&D supplement. - Some interfaces support the weaponstatus option. When it is - enabled, an extra status condition is displayed, describing the cur- + Some interfaces support the weaponstatus option. When it is + enabled, an extra status condition is displayed, describing the cur- rently wielded weapon. - The commands to use weapons are `w' (wield), `t' (throw), `f' - (fire), `Q' (quiver), `x' (exchange), `X' (twoweapon), and "#enhance" + The commands to use weapons are `w' (wield), `t' (throw), `f' + (fire), `Q' (quiver), `x' (exchange), `X' (twoweapon), and "#enhance" (see below). 7.4.1. Throwing and shooting - You can throw just about anything via the `t' command. It will - prompt for the item to throw; picking `?' will list things in your - inventory which are considered likely to be thrown, or picking `*' - will list your entire inventory. After you've chosen what to throw, - you will be prompted for a direction rather than for a specific tar- - get. The distance something can be thrown depends mainly on the type + You can throw just about anything via the `t' command. It will + prompt for the item to throw; picking `?' will list things in your + inventory which are considered likely to be thrown, or picking `*' + will list your entire inventory. After you've chosen what to throw, + you will be prompted for a direction rather than for a specific tar- + get. The distance something can be thrown depends mainly on the type of object and your strength. Arrows can be thrown by hand, but can be - thrown much farther and will be more likely to hit when thrown while + thrown much farther and will be more likely to hit when thrown while you are wielding a bow. - Some weapons will return when thrown. A boomerang--provided it - fails to hit anything--is an obvious example. If an aklys (thonged - club) is thrown while it is wielded, it will return even when it hits - something. A sufficiently strong hero can throw the warhammer Mjoll- - nir; when thrown by a Valkyrie it will return too. However, aklyses - and Mjollnir occasionally fail to return. Returning thrown objects - occasionally fail to be caught, sometimes even hitting the thrower, + Some weapons will return when thrown. A boomerang--provided it + fails to hit anything--is an obvious example. If an aklys (thonged + club) is thrown while it is wielded, it will return even when it hits + something. A sufficiently strong hero can throw the warhammer Mjoll- + nir; when thrown by a Valkyrie it will return too. However, aklyses + and Mjollnir occasionally fail to return. Returning thrown objects + occasionally fail to be caught, sometimes even hitting the thrower, but when caught they become re-wielded. - You can simplify the throwing operation by using the `Q' command - to select your preferred "missile", then using the `f' command to - throw it. You'll be prompted for a direction as above, but you don't - have to specify which item to throw each time you use `f'. There is - also an option, autoquiver, which has NetHack choose another item to - automatically fill your quiver (or quiver sack, or have at the ready) - when the inventory slot used for `Q' runs out. If your quiver is - empty, autoquiver is false, and you are wielding a weapon which + You can simplify the throwing operation by using the `Q' command + to select your preferred "missile", then using the `f' command to + throw it. You'll be prompted for a direction as above, but you don't + have to specify which item to throw each time you use `f'. There is + also an option, autoquiver, which has NetHack choose another item to + automatically fill your quiver (or quiver sack, or have at the ready) + when the inventory slot used for `Q' runs out. If your quiver is + empty, autoquiver is false, and you are wielding a weapon which returns when thrown, you will throw that weapon instead of filling the - quiver. The fire command also has extra assistance, if fireassist is + quiver. The fire command also has extra assistance, if fireassist is on it will try to wield a launcher matching the ammo in the quiver. - Some characters have the ability to throw or shoot a volley of - multiple items (from the same stack) in a single action. Knowing how + Some characters have the ability to throw or shoot a volley of + multiple items (from the same stack) in a single action. Knowing how to load several rounds of ammunition at once--or hold several missiles in your hand--and still hit a target is not an easy task. Rangers are among those who are adept at this task, as are those with a high level - of proficiency in the relevant weapon skill (in bow skill if you're + of proficiency in the relevant weapon skill (in bow skill if you're wielding one to shoot arrows, in crossbow skill if you're wielding one - to shoot bolts, or in sling skill if you're wielding one to shoot - stones). The number of items that the character has a chance to fire - varies from turn to turn. You can explicitly limit the number of - shots by using a numeric prefix before the `t' or `f' command. For + to shoot bolts, or in sling skill if you're wielding one to shoot + stones). The number of items that the character has a chance to fire + varies from turn to turn. You can explicitly limit the number of + shots by using a numeric prefix before the `t' or `f' command. For - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3108,61 +3108,61 @@ example, "2f" (or "n2f" if using number_pad mode) would ensure that at most 2 arrows are shot even if you could have fired 3. If you specify - a larger number than would have been shot ("4f" in this example), - you'll just end up shooting the same number (3, here) as if no limit - had been specified. Once the volley is in motion, all of the items - will travel in the same direction; if the first ones kill a monster, + a larger number than would have been shot ("4f" in this example), + you'll just end up shooting the same number (3, here) as if no limit + had been specified. Once the volley is in motion, all of the items + will travel in the same direction; if the first ones kill a monster, the others can still continue beyond that spot. 7.4.2. Weapon proficiency - You will have varying degrees of skill in the weapons available. + You will have varying degrees of skill in the weapons available. Weapon proficiency, or weapon skills, affect how well you can use par- ticular types of weapons, and you'll be able to improve your skills as - you progress through a game, depending on your role, your experience + you progress through a game, depending on your role, your experience level, and use of the weapons. - For the purposes of proficiency, weapons have been divided up - into various groups such as daggers, broadswords, and polearms. Each - role has a limit on what level of proficiency a character can achieve - for each group. For instance, wizards can become highly skilled in + For the purposes of proficiency, weapons have been divided up + into various groups such as daggers, broadswords, and polearms. Each + role has a limit on what level of proficiency a character can achieve + for each group. For instance, wizards can become highly skilled in daggers or staves but not in swords or bows. The "#enhance" extended command is used to review current weapons - proficiency (also spell proficiency) and to choose which skill(s) to - improve when you've used one or more skills enough to become eligible - to do so. The skill rankings are "none" (sometimes also referred to - as "restricted", because you won't be able to advance), "unskilled", - "basic", "skilled", and "expert". Restricted skills simply will not - appear in the list shown by "#enhance". (Divine intervention might - unrestrict a particular skill, in which case it will start at + proficiency (also spell proficiency) and to choose which skill(s) to + improve when you've used one or more skills enough to become eligible + to do so. The skill rankings are "none" (sometimes also referred to + as "restricted", because you won't be able to advance), "unskilled", + "basic", "skilled", and "expert". Restricted skills simply will not + appear in the list shown by "#enhance". (Divine intervention might + unrestrict a particular skill, in which case it will start at unskilled and be limited to basic.) Some characters can enhance their - barehanded combat or martial arts skill beyond expert to "master" or + barehanded combat or martial arts skill beyond expert to "master" or "grand master". - Use of a weapon in which you're restricted or unskilled will - incur a modest penalty in the chance to hit a monster and also in the - amount of damage done when you do hit; at basic level, there is no - penalty or bonus; at skilled level, you receive a modest bonus in the + Use of a weapon in which you're restricted or unskilled will + incur a modest penalty in the chance to hit a monster and also in the + amount of damage done when you do hit; at basic level, there is no + penalty or bonus; at skilled level, you receive a modest bonus in the chance to hit and amount of damage done; at expert level, the bonus is - higher. A successful hit has a chance to boost your training towards + higher. A successful hit has a chance to boost your training towards the next skill level (unless you've already reached the limit for this skill). Once such training reaches the threshold for that next level, - you'll be told that you feel more confident in your skills. At that - point you can use "#enhance" to increase one or more skills. Such - skills are not increased automatically because there is a limit to + you'll be told that you feel more confident in your skills. At that + point you can use "#enhance" to increase one or more skills. Such + skills are not increased automatically because there is a limit to your total overall skills, so you need to actively choose which skills to enhance and which to ignore. 7.4.3. Two-Weapon combat - Some characters can use two weapons at once. Setting things up - to do so can seem cumbersome but becomes second nature with use. To - wield two weapons, you need to use the "#twoweapon" command. But - first you need to have a weapon in each hand. (Note that your two + Some characters can use two weapons at once. Setting things up + to do so can seem cumbersome but becomes second nature with use. To + wield two weapons, you need to use the "#twoweapon" command. But + first you need to have a weapon in each hand. (Note that your two - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3172,44 +3172,44 @@ - weapons are not fully equal; the one in the hand you normally wield - with is considered primary and the other one is considered secondary. + weapons are not fully equal; the one in the hand you normally wield + with is considered primary and the other one is considered secondary. The most noticeable difference is after you stop--or before you begin, - for that matter--wielding two weapons at once. The primary is your - wielded weapon and the secondary is just an item in your inventory + for that matter--wielding two weapons at once. The primary is your + wielded weapon and the secondary is just an item in your inventory that's been designated as alternate weapon.) - If your primary weapon is wielded but your off hand is empty or - has the wrong weapon, use the sequence `x', `w', `x' to first swap - your primary into your off hand, wield whatever you want as secondary - weapon, then swap them both back into the intended hands. If your - secondary or alternate weapon is correct but your primary one is not, - simply use `w' to wield the primary. Lastly, if neither hand holds + If your primary weapon is wielded but your off hand is empty or + has the wrong weapon, use the sequence `x', `w', `x' to first swap + your primary into your off hand, wield whatever you want as secondary + weapon, then swap them both back into the intended hands. If your + secondary or alternate weapon is correct but your primary one is not, + simply use `w' to wield the primary. Lastly, if neither hand holds the correct weapon, use `w', `x', `w' to first wield the intended sec- ondary, swap it to off hand, and then wield the primary. - The whole process can be simplified via use of the pushweapon - option. When it is enabled, then using `w' to wield something causes - the currently wielded weapon to become your alternate weapon. So the - sequence `w', `w' can be used to first wield the weapon you intend to - be secondary, and then wield the one you want as primary which will + The whole process can be simplified via use of the pushweapon + option. When it is enabled, then using `w' to wield something causes + the currently wielded weapon to become your alternate weapon. So the + sequence `w', `w' can be used to first wield the weapon you intend to + be secondary, and then wield the one you want as primary which will push the first into secondary position. - When in two-weapon combat mode, using the `X' command toggles - back to single-weapon mode. Throwing or dropping either of the weap- - ons or having one of them be stolen or destroyed will also make you + When in two-weapon combat mode, using the `X' command toggles + back to single-weapon mode. Throwing or dropping either of the weap- + ons or having one of them be stolen or destroyed will also make you revert to single-weapon combat. 7.5. Armor (`[') - Lots of unfriendly things lurk about; you need armor to protect - yourself from their blows. Some types of armor offer better protec- - tion than others. Your armor class is a measure of this protection. - Armor class (AC) is measured as in AD&D, with 10 being the equivalent - of no armor, and lower numbers meaning better armor. Each suit of + Lots of unfriendly things lurk about; you need armor to protect + yourself from their blows. Some types of armor offer better protec- + tion than others. Your armor class is a measure of this protection. + Armor class (AC) is measured as in AD&D, with 10 being the equivalent + of no armor, and lower numbers meaning better armor. Each suit of armor which exists in AD&D gives the same protection in NetHack. - Here is a list of the armor class values provided by suits of + Here is a list of the armor class values provided by suits of armor: Dragon scale mail 1 Plate mail, Crystal plate mail 3 @@ -3223,12 +3223,12 @@ Leather jacket 9 none 10 - You can also wear other pieces of armor (cloak over suit, shirt - under suit, helmet, gloves, boots, shield) to lower your armor class + You can also wear other pieces of armor (cloak over suit, shirt + under suit, helmet, gloves, boots, shield) to lower your armor class even further. Most of these provide a one or two point improvement to - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3238,63 +3238,63 @@ - AC (making the overall value smaller and eventually negative) but can - also be enchanted. Shirts are an exception; they don't provide any - protection unless enchanted. Some cloaks also don't improve AC when - unenchanted but all cloaks offer some protection against rust or cor- - rosion to suits worn under them and against some monster touch + AC (making the overall value smaller and eventually negative) but can + also be enchanted. Shirts are an exception; they don't provide any + protection unless enchanted. Some cloaks also don't improve AC when + unenchanted but all cloaks offer some protection against rust or cor- + rosion to suits worn under them and against some monster touch attacks. - If a piece of armor is enchanted, its armor protection will be + If a piece of armor is enchanted, its armor protection will be better (or worse) than normal, and its "plus" (or minus) will subtract - from your armor class. For example, a +1 chain mail would give you - better protection than normal chain mail, lowering your armor class - one unit further to 4. When you put on a piece of armor, you immedi- - ately find out the armor class and any "plusses" it provides. Cursed - pieces of armor usually have negative enchantments (minuses) in addi- + from your armor class. For example, a +1 chain mail would give you + better protection than normal chain mail, lowering your armor class + one unit further to 4. When you put on a piece of armor, you immedi- + ately find out the armor class and any "plusses" it provides. Cursed + pieces of armor usually have negative enchantments (minuses) in addi- tion to being unremovable. Many types of armor are subject to some kind of damage like rust. - Such damage can be repaired. Some types of armor may inhibit spell + Such damage can be repaired. Some types of armor may inhibit spell casting. - The nudist option can be set (prior to game start) to attempt to - play the entire game without wearing any armor (a self-imposed chal- + The nudist option can be set (prior to game start) to attempt to + play the entire game without wearing any armor (a self-imposed chal- lenge which is extremely difficult to accomplish). - Some interfaces support the armorstatus option. When it is + Some interfaces support the armorstatus option. When it is enabled, an extra status condition is displayed, summarizing currently worn armor. The commands to use armor are `W' (wear) and `T' (take off). The `A' command can be used to take off armor as well as other worn items. Also, `P' (put on) and `R' (remove) which are normally for accessories - can be used for armor, but pieces of armor won't be shown as likely + can be used for armor, but pieces of armor won't be shown as likely candidates in a prompt for choosing what to put on or remove. 7.6. Food (`%') - Food is necessary to survive. If you go too long without eating - you will faint, and eventually die of starvation. Some types of food - will spoil, and become unhealthy to eat, if not protected. Food - stored in ice boxes or tins ("cans") will usually stay fresh, but ice + Food is necessary to survive. If you go too long without eating + you will faint, and eventually die of starvation. Some types of food + will spoil, and become unhealthy to eat, if not protected. Food + stored in ice boxes or tins ("cans") will usually stay fresh, but ice boxes are heavy, and tins take a while to open. When you kill monsters, they usually leave corpses which are also - "food." Many, but not all, of these are edible; some also give you - special powers when you eat them. A good rule of thumb is "you are + "food." Many, but not all, of these are edible; some also give you + special powers when you eat them. A good rule of thumb is "you are what you eat." - Some character roles and some monsters are vegetarian. Vegetar- + Some character roles and some monsters are vegetarian. Vegetar- ian monsters will typically never eat animal corpses, while vegetarian players can, but with some rather unpleasant side-effects. - You can name one food item after something you like to eat with + You can name one food item after something you like to eat with the fruit option. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3308,33 +3308,33 @@ 7.7. Scrolls (`?') - Scrolls are labeled with various titles, probably chosen by - ancient wizards for their amusement value (for example "READ ME," or - "THANX MAUD" backwards). Scrolls disappear after you read them + Scrolls are labeled with various titles, probably chosen by + ancient wizards for their amusement value (for example "READ ME," or + "THANX MAUD" backwards). Scrolls disappear after you read them (except for blank ones, without magic spells on them). - One of the most useful of these is the scroll of identify, which - can be used to determine what another object is, whether it is cursed - or blessed, and how many uses it has left. Some objects of subtle + One of the most useful of these is the scroll of identify, which + can be used to determine what another object is, whether it is cursed + or blessed, and how many uses it has left. Some objects of subtle enchantment are difficult to identify without these. - A scroll whose label is known can be read even when the hero is - blind. If a scroll has been discovered, it will be listed in inven- + A scroll whose label is known can be read even when the hero is + blind. If a scroll has been discovered, it will be listed in inven- tory by type rather than by label, but the label is known in that sit- uation even though it isn't shown. - Many scrolls produce a different effect from usual if they are + Many scrolls produce a different effect from usual if they are blessed or cursed, or read while the hero is confused. - A mail daemon may run up and deliver mail to you as a scroll of + A mail daemon may run up and deliver mail to you as a scroll of mail (on versions compiled with this feature). To use this feature on - versions where NetHack mail delivery is triggered by electronic mail - appearing in your system mailbox, you must let NetHack know where to - look for new mail by setting the "MAIL" environment variable to the - file name of your mailbox. You may also want to set the "MAILREADER" - environment variable to the file name of your favorite reader, so - NetHack can shell to it when you read the scroll. On versions of - NetHack where mail is randomly generated internal to the game, these + versions where NetHack mail delivery is triggered by electronic mail + appearing in your system mailbox, you must let NetHack know where to + look for new mail by setting the "MAIL" environment variable to the + file name of your mailbox. You may also want to set the "MAILREADER" + environment variable to the file name of your favorite reader, so + NetHack can shell to it when you read the scroll. On versions of + NetHack where mail is randomly generated internal to the game, these environment variables are ignored. You can disable the mail daemon by turning off the mail option. @@ -3342,13 +3342,13 @@ 7.8. Potions (`!') - Potions are distinguished by the color of the liquid inside the + Potions are distinguished by the color of the liquid inside the flask. They disappear after you quaff them. - Clear potions are potions of water. Sometimes these are blessed - or cursed, resulting in holy or unholy water. Holy water is the bane + Clear potions are potions of water. Sometimes these are blessed + or cursed, resulting in holy or unholy water. Holy water is the bane of the undead, so potions of holy water are good things to throw (`t') - at them. It is also sometimes very useful to dip ("#dip") an object + at them. It is also sometimes very useful to dip ("#dip") an object into a potion. The command to drink a potion is `q' (quaff). @@ -3356,11 +3356,11 @@ 7.9. Wands (`/') Wands usually have multiple magical charges. Some types of wands - require a direction in which to zap them. You can also zap them at - yourself (just give a `.' or `s' for the direction). Be warned, how- + require a direction in which to zap them. You can also zap them at + yourself (just give a `.' or `s' for the direction). Be warned, how- - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3370,63 +3370,63 @@ - ever, for this is often unwise. Other types of wands don't require a + ever, for this is often unwise. Other types of wands don't require a direction. The number of charges in a wand is random and decreases by one whenever you use it. - When the number of charges left in a wand becomes zero, attempts - to use the wand will usually result in nothing happening. Occasion- - ally, however, it may be possible to squeeze the last few mana points - from an otherwise spent wand, destroying it in the process. A wand - may be recharged by using suitable magic, but doing so runs the risk + When the number of charges left in a wand becomes zero, attempts + to use the wand will usually result in nothing happening. Occasion- + ally, however, it may be possible to squeeze the last few mana points + from an otherwise spent wand, destroying it in the process. A wand + may be recharged by using suitable magic, but doing so runs the risk of causing it to explode. The chance for such an explosion starts out very small and increases each time the wand is recharged. - In a truly desperate situation, when your back is up against the - wall, you might decide to go for broke and break your wand. This is - not for the faint of heart. Doing so will almost certainly cause a + In a truly desperate situation, when your back is up against the + wall, you might decide to go for broke and break your wand. This is + not for the faint of heart. Doing so will almost certainly cause a catastrophic release of magical energies. - When you have fully identified a particular wand, inventory dis- + When you have fully identified a particular wand, inventory dis- play will include additional information in parentheses: the number of - times it has been recharged followed by a colon and then by its cur- - rent number of charges. A current charge count of -1 is a special + times it has been recharged followed by a colon and then by its cur- + rent number of charges. A current charge count of -1 is a special case indicating that the wand has been cancelled. - The command to use a wand is `z' (zap). To break one, use the + The command to use a wand is `z' (zap). To break one, use the `a' (apply) command. 7.10. Rings (`=') - Rings are very useful items, since they are relatively permanent - magic, unlike the usually fleeting effects of potions, scrolls, and + Rings are very useful items, since they are relatively permanent + magic, unlike the usually fleeting effects of potions, scrolls, and wands. - Putting on a ring activates its magic. You can wear at most two + Putting on a ring activates its magic. You can wear at most two rings at any time, one on the ring finger of each hand. - Most worn rings also cause you to grow hungry more rapidly, the + Most worn rings also cause you to grow hungry more rapidly, the rate varying with the type of ring. - When wearing gloves, rings are worn underneath. If the gloves - are cursed, rings cannot be put on and any already being worn cannot - be removed. When worn gloves aren't cursed, you don't have to manu- - ally take them off before putting on or removing a ring and then re- + When wearing gloves, rings are worn underneath. If the gloves + are cursed, rings cannot be put on and any already being worn cannot + be removed. When worn gloves aren't cursed, you don't have to manu- + ally take them off before putting on or removing a ring and then re- wear them after. That's done implicitly to avoid unnecessary tedium. - The commands to use rings are `P' (put on) and `R' (remove). + The commands to use rings are `P' (put on) and `R' (remove). `A', `W', and `T' can also be used; see Amulets. 7.11. Spellbooks (`+') - Spellbooks are tomes of mighty magic. When studied with the `r' - (read) command, they transfer to the reader the knowledge of a spell + Spellbooks are tomes of mighty magic. When studied with the `r' + (read) command, they transfer to the reader the knowledge of a spell (and therefore eventually become unreadable)--unless the attempt back- - fires. Reading a cursed spellbook or one with mystic runes beyond + fires. Reading a cursed spellbook or one with mystic runes beyond your ken can be harmful to your health! - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3436,63 +3436,63 @@ - A spell (even when learned) can also backfire when you cast it. + A spell (even when learned) can also backfire when you cast it. If you attempt to cast a spell well above your experience level, or if you have little skill with the appropriate spell type, or cast it at a - time when your luck is particularly bad, you can end up wasting both + time when your luck is particularly bad, you can end up wasting both the energy and the time required in casting. - Casting a spell calls forth magical energies and focuses them - with your naked mind. Some of the magical energy released comes from + Casting a spell calls forth magical energies and focuses them + with your naked mind. Some of the magical energy released comes from within you. Casting temporarily drains your magical power, which will - slowly be recovered, and causes you to need additional food. Casting - of spells also requires practice. With practice, your skill in each + slowly be recovered, and causes you to need additional food. Casting + of spells also requires practice. With practice, your skill in each category of spell casting will improve. Over time, however, your mem- ory of each spell will dim, and you will need to relearn it. Some spells require a direction in which to cast them, similar to wands. To cast one at yourself, just give a `.' or `s' for the direc- - tion. A few spells require you to pick a target location rather than - just specify a particular direction. Other spells don't require any + tion. A few spells require you to pick a target location rather than + just specify a particular direction. Other spells don't require any direction or target. - Just as weapons are divided into groups in which a character can - become proficient (to varying degrees), spells are similarly grouped. - Successfully casting a spell exercises its skill group; using the - "#enhance" command to advance a sufficiently exercised skill will - affect all spells within the group. Advanced skill may increase the - potency of spells, reduce their risk of failure during casting + Just as weapons are divided into groups in which a character can + become proficient (to varying degrees), spells are similarly grouped. + Successfully casting a spell exercises its skill group; using the + "#enhance" command to advance a sufficiently exercised skill will + affect all spells within the group. Advanced skill may increase the + potency of spells, reduce their risk of failure during casting attempts, and improve the accuracy of the estimate for how much longer - they will be retained in your memory. Skill slots are shared with + they will be retained in your memory. Skill slots are shared with weapons skills. (See also the section on "Weapon proficiency".) Casting a spell also requires flexible movement, and wearing var- ious types of armor may interfere with that. - The command to read a spellbook is the same as for scrolls, `r' - (read). The `+' command lists each spell you know along with its + The command to read a spellbook is the same as for scrolls, `r' + (read). The `+' command lists each spell you know along with its level, skill category, chance of failure when casting, and an estimate - of how strongly it is remembered. The `Z' (cast) command casts a + of how strongly it is remembered. The `Z' (cast) command casts a spell. 7.12. Tools (`(') - Tools are miscellaneous objects with various purposes. Some - tools have a limited number of uses, akin to wand charges. For exam- - ple, lamps burn out after a while. Other tools are containers, which + Tools are miscellaneous objects with various purposes. Some + tools have a limited number of uses, akin to wand charges. For exam- + ple, lamps burn out after a while. Other tools are containers, which objects can be placed into or taken out of. - Some tools (such as a blindfold) can be worn and can be put on - and removed like other accessories (rings, amulets); see Amulets. - Other tools (such as pick-axe) can be wielded as weapons in addition - to being applied for their usual purpose, and in some cases (again, + Some tools (such as a blindfold) can be worn and can be put on + and removed like other accessories (rings, amulets); see Amulets. + Other tools (such as pick-axe) can be wielded as weapons in addition + to being applied for their usual purpose, and in some cases (again, pick-axe) become wielded as a weapon even when applied. - The blind option can be set (prior to game start) to attempt to - play the entire game without being able to see (a self-imposed chal- + The blind option can be set (prior to game start) to attempt to + play the entire game without being able to see (a self-imposed chal- - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3508,57 +3508,57 @@ 7.12.1. Containers - You may encounter bags, boxes, and chests in your travels. A + You may encounter bags, boxes, and chests in your travels. A tool of this sort can be opened with the "#loot" extended command when - you are standing on top of it (that is, on the same floor spot), or - with the `a' (apply) command when you are carrying it. However, - chests are often locked, and are in any case unwieldy objects. You - must set one down before unlocking it by using a key or lock-picking - tool with the `a' (apply) command, by kicking it with the `^D' com- - mand, or by using a weapon to force the lock with the "#force" + you are standing on top of it (that is, on the same floor spot), or + with the `a' (apply) command when you are carrying it. However, + chests are often locked, and are in any case unwieldy objects. You + must set one down before unlocking it by using a key or lock-picking + tool with the `a' (apply) command, by kicking it with the `^D' com- + mand, or by using a weapon to force the lock with the "#force" extended command. - Some chests are trapped, causing nasty things to happen when you - unlock or open them. You can check for and try to deactivate traps + Some chests are trapped, causing nasty things to happen when you + unlock or open them. You can check for and try to deactivate traps with the "#untrap" extended command. - When the contents of a container are known, that container will - be described as something like "a sack containing 3 items". In this - example, the 3 refers to number of stacks of compatible items, not to - the total number of individual items. So a sack holding 2 sky blue - potions, 7 arrows, and 350 gold pieces would be described as having 3 - items rather than 10 or 359. And you would need to have 3 unused - inventory slots available in order to take everything out (for the - case where the items you remove don't combine into bigger stacks with + When the contents of a container are known, that container will + be described as something like "a sack containing 3 items". In this + example, the 3 refers to number of stacks of compatible items, not to + the total number of individual items. So a sack holding 2 sky blue + potions, 7 arrows, and 350 gold pieces would be described as having 3 + items rather than 10 or 359. And you would need to have 3 unused + inventory slots available in order to take everything out (for the + case where the items you remove don't combine into bigger stacks with things you're already carrying). If a chest or large box is described as "broken", that means that - it can't be locked rather than that it no longer functions as a con- + it can't be locked rather than that it no longer functions as a con- tainer. - The apply and loot commands allow you to take out and/or put in - an arbitrary number of items in a single operation. If you want to - take everything out of a container, you can use the "#tip" command to - pour the contents onto the floor. This may be your only way to get - things out if your hands are stuck to a cursed two-handed weapon. - When your hands aren't stuck, you have the potential to pour the con- - tents into another container. (As of this writing, the other con- + The apply and loot commands allow you to take out and/or put in + an arbitrary number of items in a single operation. If you want to + take everything out of a container, you can use the "#tip" command to + pour the contents onto the floor. This may be your only way to get + things out if your hands are stuck to a cursed two-handed weapon. + When your hands aren't stuck, you have the potential to pour the con- + tents into another container. (As of this writing, the other con- tainer must be carried rather than on the floor.) 7.13. Amulets (`"') Amulets are very similar to rings, and often more powerful. Like - rings, amulets have various magical properties, some beneficial, some + rings, amulets have various magical properties, some beneficial, some harmful, which are activated by putting them on. - Only one amulet may be worn at a time, around your neck. Like - wearing rings, wearing an amulet affects your metabolism, causing you + Only one amulet may be worn at a time, around your neck. Like + wearing rings, wearing an amulet affects your metabolism, causing you to grow hungry more rapidly. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3568,63 +3568,63 @@ - The commands to use amulets are the same as for rings, `P' (put - on) and `R' (remove). `A' can be used to remove various worn items + The commands to use amulets are the same as for rings, `P' (put + on) and `R' (remove). `A' can be used to remove various worn items including amulets. Also, `W' (wear) and `T' (take off) which are nor- - mally for armor can be used for amulets and other accessories (rings + mally for armor can be used for amulets and other accessories (rings and eyewear), but accessories won't be shown as likely candidates in a prompt for choosing what to wear or take off. 7.14. Gems (`*') - Some gems are valuable, and can be sold for a lot of gold. They - are also a far more efficient way of carrying your riches. Valuable + Some gems are valuable, and can be sold for a lot of gold. They + are also a far more efficient way of carrying your riches. Valuable gems increase your score if you bring them with you when you exit. Other small rocks are also categorized as gems, but they are much - less valuable. All rocks, however, can be used as projectile weapons - (if you have a sling). In the most desperate of cases, you can still + less valuable. All rocks, however, can be used as projectile weapons + (if you have a sling). In the most desperate of cases, you can still throw them by hand. 7.15. Large rocks (``') - Statues and boulders are not particularly useful, and are gener- + Statues and boulders are not particularly useful, and are gener- ally heavy. It is rumored that some statues are not what they seem. - Boulders occasionally block your path. You can push one forward + Boulders occasionally block your path. You can push one forward (by attempting to walk onto its spot) when nothing blocks its path, or - you can smash it into a pile of small rocks with breaking magic or a + you can smash it into a pile of small rocks with breaking magic or a pick-axe. It is possible to move onto a boulder's location if certain conditions are met; ordinarily one of those conditions is that pushing - it any further be blocked. Using the move-without-picking-up prefix - (default key `m') prior to the direction of movement will attempt to - move to a boulder's location without pushing it in addition to the + it any further be blocked. Using the move-without-picking-up prefix + (default key `m') prior to the direction of movement will attempt to + move to a boulder's location without pushing it in addition to the prefix's usual action of suppressing auto-pickup at the destination. - Very large humanoids (giants and their ilk) have been known to + Very large humanoids (giants and their ilk) have been known to pick up boulders and use them as missile weapons. - Unlike boulders, statues can't be pushed, but don't need to be - because they don't block movement. They can be smashed into rocks + Unlike boulders, statues can't be pushed, but don't need to be + because they don't block movement. They can be smashed into rocks though. - For some configurations of the program, statues are no longer - shown as ``' but by the letter representing the monster they depict + For some configurations of the program, statues are no longer + shown as ``' but by the letter representing the monster they depict instead. 7.16. Gold (`$') Gold adds to your score, and you can buy things in shops with it. - There are a number of monsters in the dungeon that may be influenced + There are a number of monsters in the dungeon that may be influenced by the amount of gold you are carrying (shopkeepers aside). - Gold pieces are the only type of object where bless/curse state - does not apply. They're always uncursed but never described as - uncursed even if you turn off the implicit_uncursed option. You can - set the goldX option if you prefer to have gold pieces be treated as + Gold pieces are the only type of object where bless/curse state + does not apply. They're always uncursed but never described as + uncursed even if you turn off the implicit_uncursed option. You can + set the goldX option if you prefer to have gold pieces be treated as - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3634,63 +3634,63 @@ - bless/curse state unknown rather than as known to be uncursed. Only - matters when you're using an object selection prompt that can filter + bless/curse state unknown rather than as known to be uncursed. Only + matters when you're using an object selection prompt that can filter by "BUCX" state. 7.17. Persistence of Objects Normally, if you have seen an object at a particular map location - and move to another location where you can't directly see that object - any more, it will continue to be displayed on your map. That remains - the case even if it is not actually there any more--perhaps a monster + and move to another location where you can't directly see that object + any more, it will continue to be displayed on your map. That remains + the case even if it is not actually there any more--perhaps a monster has picked it up or it has rotted away--until you can see or feel that location again. One notable exception is that if the object gets cov- - ered by the "remembered, unseen monster" marker. When that marker is + ered by the "remembered, unseen monster" marker. When that marker is later removed after you've verified that no monster is there, you will - have forgotten that there was any object there regardless of whether - the unseen monster actually took the object. If the object is still - there, then once you see or feel that location again you will re-dis- + have forgotten that there was any object there regardless of whether + the unseen monster actually took the object. If the object is still + there, then once you see or feel that location again you will re-dis- cover the object and resume remembering it. The situation is the same for a pile of objects, except that only - the top item of the pile is displayed. The hilite_pile option can be + the top item of the pile is displayed. The hilite_pile option can be enabled in order to show an item differently when it is the top one of a pile. 8. Conduct - As if winning NetHack were not difficult enough, certain players - seek to challenge themselves by imposing restrictions on the way they - play the game. The game automatically tracks some of these chal- - lenges, which can be checked at any time with the #conduct command or - at the end of the game. When you perform an action which breaks a - challenge, it will no longer be listed. This gives players extra - "bragging rights" for winning the game with these challenges. Note - that it is perfectly acceptable to win the game without resorting to - these restrictions and that it is unusual for players to adhere to + As if winning NetHack were not difficult enough, certain players + seek to challenge themselves by imposing restrictions on the way they + play the game. The game automatically tracks some of these chal- + lenges, which can be checked at any time with the #conduct command or + at the end of the game. When you perform an action which breaks a + challenge, it will no longer be listed. This gives players extra + "bragging rights" for winning the game with these challenges. Note + that it is perfectly acceptable to win the game without resorting to + these restrictions and that it is unusual for players to adhere to challenges the first time they win the game. - Several of the challenges are related to eating behavior. The + Several of the challenges are related to eating behavior. The most difficult of these is the foodless challenge. Although creatures - can survive long periods of time without food, there is a physiologi- - cal need for water; thus there is no restriction on drinking bever- - ages, even if they provide some minor food benefits. Calling upon + can survive long periods of time without food, there is a physiologi- + cal need for water; thus there is no restriction on drinking bever- + ages, even if they provide some minor food benefits. Calling upon your god for help with starvation does not violate any food challenges either. - A strict vegan diet is one which avoids any food derived from - animals. The primary source of nutrition is fruits and vegetables. - The corpses and tins of blobs (`b'), jellies (`j'), and fungi (`F') - are also considered to be vegetable matter. Certain human food is + A strict vegan diet is one which avoids any food derived from + animals. The primary source of nutrition is fruits and vegetables. + The corpses and tins of blobs (`b'), jellies (`j'), and fungi (`F') + are also considered to be vegetable matter. Certain human food is prepared without animal products; namely, lembas wafers, cram rations, - food rations (gunyoki), K-rations, and C-rations. Metal or another + food rations (gunyoki), K-rations, and C-rations. Metal or another normally indigestible material eaten while polymorphed into a creature - that can digest it is also considered vegan food. Note however that + that can digest it is also considered vegan food. Note however that eating such items still counts against foodless conduct. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3700,63 +3700,63 @@ - Vegetarians do not eat animals; however, they are less selective - about eating animal byproducts than vegans. In addition to the vegan - items listed above, they may eat any kind of pudding (`P') other than - the black puddings, eggs and food made from eggs (fortune cookies and - pancakes), food made with milk (cream pies and candy bars), and lumps + Vegetarians do not eat animals; however, they are less selective + about eating animal byproducts than vegans. In addition to the vegan + items listed above, they may eat any kind of pudding (`P') other than + the black puddings, eggs and food made from eggs (fortune cookies and + pancakes), food made with milk (cream pies and candy bars), and lumps of royal jelly. Monks are expected to observe a vegetarian diet. Eating any kind of meat violates the vegetarian, vegan, and food- - less conducts. This includes tripe rations, the corpses or tins of + less conducts. This includes tripe rations, the corpses or tins of any monsters not mentioned above, and the various other chunks of meat - found in the dungeon. Swallowing and digesting a monster while poly- - morphed is treated as if you ate the creature's corpse. Eating - leather, dragon hide, or bone items while polymorphed into a creature - that can digest it, or eating monster brains while polymorphed into a - mind flayer, is considered eating an animal, although wax is only an + found in the dungeon. Swallowing and digesting a monster while poly- + morphed is treated as if you ate the creature's corpse. Eating + leather, dragon hide, or bone items while polymorphed into a creature + that can digest it, or eating monster brains while polymorphed into a + mind flayer, is considered eating an animal, although wax is only an animal byproduct. - Regardless of conduct, there will be some items which are indi- + Regardless of conduct, there will be some items which are indi- gestible, and others which are hazardous to eat. Using a swallow-and- - digest attack against a monster is equivalent to eating the monster's - corpse. Please note that the term "vegan" is used here only in the - context of diet. You are still free to choose not to use or wear - items derived from animals (e.g. leather, dragon hide, bone, horns, - coral), but the game will not keep track of this for you. Also note - that "milky" potions may be a translucent white, but they do not con- - tain milk, so they are compatible with a vegan diet. Slime molds or - player-defined "fruits", although they could be anything from "cher- + digest attack against a monster is equivalent to eating the monster's + corpse. Please note that the term "vegan" is used here only in the + context of diet. You are still free to choose not to use or wear + items derived from animals (e.g. leather, dragon hide, bone, horns, + coral), but the game will not keep track of this for you. Also note + that "milky" potions may be a translucent white, but they do not con- + tain milk, so they are compatible with a vegan diet. Slime molds or + player-defined "fruits", although they could be anything from "cher- ries" to "pork chops", are also assumed to be vegan. An atheist is one who rejects religion. This means that you can- not #pray, #offer sacrifices to any god, #turn undead, or #chat with a priest. Particularly selective readers may argue that playing Monk or - Priest characters should violate this conduct; that is a choice left + Priest characters should violate this conduct; that is a choice left to the player. Offering the Amulet of Yendor to your god is necessary to win the game and is not counted against this conduct. You are also - not penalized for being spoken to by an angry god, priest(ess), or + not penalized for being spoken to by an angry god, priest(ess), or other religious figure; a true atheist would hear the words but attach no special meaning to them. - A pauper starts the game with no possessions, no spells, and no + A pauper starts the game with no possessions, no spells, and no weapon or spell skills (and if playing as a knight, your pony will not - have a saddle). Can only be initiated by starting a new game with - OPTIONS=pauper set in your run-time configurtion file or NETHACKOP- - TIONS environment variable. Once the game is underway, you can + have a saddle). Can only be initiated by starting a new game with + OPTIONS=pauper set in your run-time configurtion file or NETHACKOP- + TIONS environment variable. Once the game is underway, you can acquire and use items, spells, and skills in the usual way. - Most players fight with a wielded weapon (or tool intended to be - wielded as a weapon). Another challenge is to win the game without - using such a wielded weapon. You are still permitted to throw, fire, - and kick weapons; use a wand, spell, or other type of item; or fight + Most players fight with a wielded weapon (or tool intended to be + wielded as a weapon). Another challenge is to win the game without + using such a wielded weapon. You are still permitted to throw, fire, + and kick weapons; use a wand, spell, or other type of item; or fight with your hands and feet. - In NetHack, a pacifist refuses to cause the death of any other - monster (i.e. if you would get experience for the death). This is a + In NetHack, a pacifist refuses to cause the death of any other + monster (i.e. if you would get experience for the death). This is a - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3766,55 +3766,55 @@ - particularly difficult challenge, although it is still possible to + particularly difficult challenge, although it is still possible to gain experience by other means. - An illiterate character does not read or write. This includes + An illiterate character does not read or write. This includes reading a scroll, spellbook, fortune cookie message, or t-shirt; writ- - ing a scroll; or making an engraving of anything other than a single - "X" (the traditional signature of an illiterate person). Reading an - engraving, or any item that is absolutely necessary to win the game, - is not counted against this conduct. The identity of scrolls and - spellbooks (and knowledge of spells) in your starting inventory is - assumed to be learned from your teachers prior to the start of the + ing a scroll; or making an engraving of anything other than a single + "X" (the traditional signature of an illiterate person). Reading an + engraving, or any item that is absolutely necessary to win the game, + is not counted against this conduct. The identity of scrolls and + spellbooks (and knowledge of spells) in your starting inventory is + assumed to be learned from your teachers prior to the start of the game and isn't counted. - There is a side-branch to the main dungeon called "Sokoban," - briefly described in the earlier section about Traps. As mentioned - there, the goal is to push boulders into pits and/or holes to plug - those in order to both get the boulders out of the way and be able to - go past the traps. There are some special "rules" that are active - when in that branch of the dungeon. Some rules can't be bypassed, - such as being unable to push a boulder diagonally. Other rules can, + There is a side-branch to the main dungeon called "Sokoban," + briefly described in the earlier section about Traps. As mentioned + there, the goal is to push boulders into pits and/or holes to plug + those in order to both get the boulders out of the way and be able to + go past the traps. There are some special "rules" that are active + when in that branch of the dungeon. Some rules can't be bypassed, + such as being unable to push a boulder diagonally. Other rules can, such as not smashing boulders with magic or tools, but doing so causes - you to receive a luck penalty. No message about that is given at the + you to receive a luck penalty. No message about that is given at the time, but it is tracked as a conduct. The #conduct command and end of - game disclosure will report whether you have abided by the special - rules of Sokoban, and if not, how many times you violated them, pro- + game disclosure will report whether you have abided by the special + rules of Sokoban, and if not, how many times you violated them, pro- viding you with a way to discover which actions incur bad luck so that - you can be better informed about whether or not to avoid repeating + you can be better informed about whether or not to avoid repeating those actions in the future. (Note: the Sokoban conduct will only be displayed if you have entered the Sokoban branch of the dungeon during - the current game. Once that has happened, it becomes part of dis- - closed conduct even if you haven't done anything interesting there. - Ending the game with "never broke the Sokoban rules" conduct is most - meaningful if you also manage to perform the "obtained the Sokoban + the current game. Once that has happened, it becomes part of dis- + closed conduct even if you haven't done anything interesting there. + Ending the game with "never broke the Sokoban rules" conduct is most + meaningful if you also manage to perform the "obtained the Sokoban prize" achievement (see Achievements below).) - There are several other challenges tracked by the game. It is - possible to eliminate one or more species of monsters by genocide; + There are several other challenges tracked by the game. It is + possible to eliminate one or more species of monsters by genocide; playing without this feature is considered a challenge. When the game - offers you an opportunity to genocide monsters, you may respond with - the monster type "none" if you want to decline. You can change the - form of an item into another item of the same type ("polypiling") or - the form of your own body into another creature ("polyself") by wand, + offers you an opportunity to genocide monsters, you may respond with + the monster type "none" if you want to decline. You can change the + form of an item into another item of the same type ("polypiling") or + the form of your own body into another creature ("polyself") by wand, spell, or potion of polymorph; avoiding these effects are each consid- - ered challenges. Polymorphing monsters, including pets, does not - break either of these challenges. Finally, you may sometimes receive - wishes; a game without an attempt to wish for any items is a chal- + ered challenges. Polymorphing monsters, including pets, does not + break either of these challenges. Finally, you may sometimes receive + wishes; a game without an attempt to wish for any items is a chal- lenge, as is a game without wishing for an artifact (even if the arti- fact immediately disappears). When the game offers you an opportunity - to make a wish for an item, you may choose "nothing" if you want to + to make a wish for an item, you may choose "nothing" if you want to decline. @@ -3822,7 +3822,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3834,12 +3834,12 @@ 8.1. Achievements - End of game disclosure will also display various achievements - representing progress toward ultimate ascension, if any have been - attained. They aren't directly related to conduct but are grouped - with it because they fall into the same category of "bragging rights" - and to limit the number of questions during disclosure. Listed here - roughly in order of difficulty and not necessarily in the order in + End of game disclosure will also display various achievements + representing progress toward ultimate ascension, if any have been + attained. They aren't directly related to conduct but are grouped + with it because they fall into the same category of "bragging rights" + and to limit the number of questions during disclosure. Listed here + roughly in order of difficulty and not necessarily in the order in which you might accomplish them. Rank - Attained rank title Rank. @@ -3851,12 +3851,12 @@ Novel - Read a passage from a Discworld Novel. Sokoban - Entered Sokoban. Big Room - Entered the Big Room. - Soko-Prize - Explored to the top of Sokoban and found a + Soko-Prize - Explored to the top of Sokoban and found a special item there. - Mines' End - Explored to the bottom of the Gnomish Mines + Mines' End - Explored to the bottom of the Gnomish Mines and found a special item there. Medusa - Defeated Medusa. - Tune - Discovered the tune that can be used to open + Tune - Discovered the tune that can be used to open and close the drawbridge on the Castle level. Bell - Acquired the Bell of Opening. Gehennom - Entered Gehennom. @@ -3876,19 +3876,19 @@ Notes: - Achievements are recorded and subsequently reported in the order - in which they happen during your current game rather than the order + Achievements are recorded and subsequently reported in the order + in which they happen during your current game rather than the order listed here. - There are nine titles for each role, bestowed at experi- - ence levels 1, 3, 6, 10, 14, 18, 22, 26, and 30. The one for experi- - ence level 1 is not recorded as an achievement. Losing enough levels + There are nine titles for each role, bestowed at experi- + ence levels 1, 3, 6, 10, 14, 18, 22, 26, and 30. The one for experi- + ence level 1 is not recorded as an achievement. Losing enough levels to revert to lower rank(s) does not discard the corresponding achieve- ment(s). - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3898,63 +3898,63 @@ - There's no guaranteed Novel so the achievement to read one might - not always be attainable (except perhaps by wishing). Similarly, the - Big Room level is not always present. Unlike with the Novel, there's + There's no guaranteed Novel so the achievement to read one might + not always be attainable (except perhaps by wishing). Similarly, the + Big Room level is not always present. Unlike with the Novel, there's no way to wish for this opportunity. - The "special items" hidden in Mines' End and Sokoban are not - unique but are considered to be prizes or rewards for exploring those - levels since doing so is not necessary to complete the game. Finding - other instances of the same objects doesn't record the corresponding + The "special items" hidden in Mines' End and Sokoban are not + unique but are considered to be prizes or rewards for exploring those + levels since doing so is not necessary to complete the game. Finding + other instances of the same objects doesn't record the corresponding achievement. - The Medusa achievement is recorded if she dies for any reason, + The Medusa achievement is recorded if she dies for any reason, even if you are not directly responsible, and only if she dies. The 5-note tune can be learned via trial and error with a musical - instrument played closely enough--but not too close!--to the Castle + instrument played closely enough--but not too close!--to the Castle level's drawbridge or can be given to you via prayer boon. - Blind, Deaf, Nudist, and Pauper are also conducts, and they can - only be enabled by setting the correspondingly named option in + Blind, Deaf, Nudist, and Pauper are also conducts, and they can + only be enabled by setting the correspondingly named option in NETHACKOPTIONS or run-time configuration file prior to game start. In - the case of Blind and Deaf, the option also enforces the conduct. - They aren't really significant accomplishments unless/until you make + the case of Blind and Deaf, the option also enforces the conduct. + They aren't really significant accomplishments unless/until you make substantial progress into the dungeon. 9. Options - Due to variations in personal tastes and conceptions of how - NetHack should do things, there are options you can set to change how + Due to variations in personal tastes and conceptions of how + NetHack should do things, there are options you can set to change how NetHack behaves. 9.1. Setting the options Options may be set in a number of ways. Within the game, the `O' - command allows you to view all options and change most of them. You - can also set options automatically by placing them in a configuration + command allows you to view all options and change most of them. You + can also set options automatically by placing them in a configuration file, or in the NETHACKOPTIONS environment variable. Some versions of - NetHack also have front-end programs that allow you to set options + NetHack also have front-end programs that allow you to set options before starting the game or a global configuration for system adminis- trators. 9.2. Using a configuration file - The default name of the configuration file varies on different + The default name of the configuration file varies on different operating systems. - On UNIX, Linux, and macOS it is ".nethackrc" in the user's home + On UNIX, Linux, and macOS it is ".nethackrc" in the user's home directory. The file may not exist, but it is a normal ASCII text file and can be created with any text editor. - On Windows, the name is ".nethackrc" located in the folder - "%USERPROFILE%\NetHack\". The file may not exist, but it is a normal - ASCII text file can can be created with any text editor. After run- - ning NetHack for the first time, you should find a default template + On Windows, the name is ".nethackrc" located in the folder + "%USERPROFILE%\NetHack\". The file may not exist, but it is a normal + ASCII text file can can be created with any text editor. After run- + ning NetHack for the first time, you should find a default template - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3964,40 +3964,40 @@ - for the configuration file named ".nethackrc.template" in - "%USERPROFILE%\NetHack\". If you have not created the configuration + for the configuration file named ".nethackrc.template" in + "%USERPROFILE%\NetHack\". If you have not created the configuration file, NetHack will create one for you using the default template file. On MS-DOS, it is "defaults.nh" in the same folder as nethack.exe. - Any line in the configuration file starting with `#' is treated + Any line in the configuration file starting with `#' is treated as a comment and ignored. Empty lines are ignored. Any line beginning with `[' and ending in `]' is a section marker - (the closing `]' can be followed by whitespace and then an arbitrary - comment beginning with `#'). The text between the square brackets is - the section name. Section markers are only valid after a CHOOSE + (the closing `]' can be followed by whitespace and then an arbitrary + comment beginning with `#'). The text between the square brackets is + the section name. Section markers are only valid after a CHOOSE directive and their names are case-insensitive. Lines after a section - marker belong to that section up until another section starts or a - marker without a name is encountered or the file ends. Lines within - sections are ignored unless a CHOOSE directive has selected that sec- + marker belong to that section up until another section starts or a + marker without a name is encountered or the file ends. Lines within + sections are ignored unless a CHOOSE directive has selected that sec- tion. - You can use different configuration directives in the file, some - of which can be used multiple times. In general, the directives are - written in capital letters, followed by an equals sign, followed by + You can use different configuration directives in the file, some + of which can be used multiple times. In general, the directives are + written in capital letters, followed by an equals sign, followed by settings particular to that directive. Here is a list of allowed directives: OPTIONS There are two types of options, boolean and compound options. Bool- - ean options toggle a setting on or off, while compound options take - more diverse values. Prefix a boolean option with "no" or `!' to - turn it off. For compound options, the option name and value are - separated by a colon. Some options are persistent, and apply only + ean options toggle a setting on or off, while compound options take + more diverse values. Prefix a boolean option with "no" or `!' to + turn it off. For compound options, the option name and value are + separated by a colon. Some options are persistent, and apply only to new games. You can specify multiple OPTIONS directives, and mul- - tiple options separated by commas in a single OPTIONS directive. + tiple options separated by commas in a single OPTIONS directive. (Comma separated options are processed from right to left.) Example: @@ -4007,20 +4007,20 @@ HACKDIR Default location of files NetHack needs. On Windows HACKDIR defaults - to the location of the NetHack.exe or NetHackw.exe file so setting + to the location of the NetHack.exe or NetHackw.exe file so setting HACKDIR to override that is not usually necessary or recommended. LEVELDIR - The location that in-progress level files are stored. Defaults to + The location that in-progress level files are stored. Defaults to HACKDIR, must be writable. SAVEDIR - The location where saved games are kept. Defaults to HACKDIR, must + The location where saved games are kept. Defaults to HACKDIR, must be writable. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4039,13 +4039,13 @@ HACKDIR, must be writable. TROUBLEDIR - The location that a record of game aborts and self-diagnosed game + The location that a record of game aborts and self-diagnosed game problems is kept. Defaults to HACKDIR, must be writable. AUTOCOMPLETE - Enable or disable an extended command autocompletion. Autocomple- + Enable or disable an extended command autocompletion. Autocomple- tion has no effect for the X11 windowport. You can specify multiple - autocompletions. To enable autocompletion, list the extended com- + autocompletions. To enable autocompletion, list the extended com- mand. Prefix the command with "!" to disable the autocompletion for that command. @@ -4054,13 +4054,13 @@ AUTOCOMPLETE=zap,!annotate AUTOPICKUP_EXCEPTION - Set exceptions to the pickup_types option. See the "Configuring + Set exceptions to the pickup_types option. See the "Configuring Autopickup Exceptions" section. BINDINGS - Change the key bindings of some special keys, menu accelerators, + Change the key bindings of some special keys, menu accelerators, extended commands, or mouse buttons. You can specify multiple bind- - ings. Format is key followed by the command, separated by a colon. + ings. Format is key followed by the command, separated by a colon. See the "Changing Key Bindings" section for more information. Example: @@ -4083,10 +4083,10 @@ OPTIONS=!rest_on_space If [] is present, the preceding section is closed and no new section - begins; whatever follows will be common to all sections. Otherwise + begins; whatever follows will be common to all sections. Otherwise - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4099,7 +4099,7 @@ the last section extends to the end of the options file. MENUCOLOR - Highlight menu lines with different colors. See the "Configuring + Highlight menu lines with different colors. See the "Configuring Menu Colors" section. MSGTYPE @@ -4113,12 +4113,12 @@ Define a sound mapping. See the "Configuring User Sounds" section. SOUNDDIR - Define the directory that contains the sound files. See the "Con- + Define the directory that contains the sound files. See the "Con- figuring User Sounds" section. SYMBOLS - Override one or more symbols in the symbol set used for all dungeon - levels except for the special rogue level. See the "Modifying + Override one or more symbols in the symbol set used for all dungeon + levels except for the special rogue level. See the "Modifying NetHack Symbols" section. Example: @@ -4128,9 +4128,9 @@ WIZKIT Debug mode only: extra items to add to initial inventory. Value is - the name of a text file containing a list of item names, one per - line, up to a maximum of 128 lines. Each line is processed by the - function that handles wishing. Entries are added to the wish his- + the name of a text file containing a list of item names, one per + line, up to a maximum of 128 lines. Each line is processed by the + function that handles wishing. Entries are added to the wish his- tory; see the wizwish-command. Example: @@ -4152,7 +4152,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4183,22 +4183,22 @@ 9.3. Using the NETHACKOPTIONS environment variable - The NETHACKOPTIONS variable is a comma-separated list of initial - values for the various options. Some can only be turned on or off. + The NETHACKOPTIONS variable is a comma-separated list of initial + values for the various options. Some can only be turned on or off. You turn one of these on by adding the name of the option to the list, - and turn it off by typing a `!' or "no" before the name. Others take - a character string as a value. You can set string options by typing - the option name, a colon or equals sign, and then the value of the - string. The value is terminated by the next comma or the end of + and turn it off by typing a `!' or "no" before the name. Others take + a character string as a value. You can set string options by typing + the option name, a colon or equals sign, and then the value of the + string. The value is terminated by the next comma or the end of string. - For example, to set up an environment variable so that color is - on, legacy is off, character name is set to "Blue Meanie", and named + For example, to set up an environment variable so that color is + on, legacy is off, character name is set to "Blue Meanie", and named fruit is set to "lime", you would enter the command % setenv NETHACKOPTIONS "color,\!leg,name:Blue Meanie,fruit:lime" - in csh (note the need to escape the `!' since it's special to that + in csh (note the need to escape the `!' since it's special to that shell), or the pair of commands $ NETHACKOPTIONS="color,!leg,name:Blue Meanie,fruit:lime" @@ -4206,19 +4206,19 @@ in sh, ksh, or bash. - The NETHACKOPTIONS value is effectively the same as a single - OPTIONS directive in a configuration file. The "OPTIONS=" prefix is - implied and comma separated options are processed from right to left. - Other types of configuration directives such as BIND or MSGTYPE are + The NETHACKOPTIONS value is effectively the same as a single + OPTIONS directive in a configuration file. The "OPTIONS=" prefix is + implied and comma separated options are processed from right to left. + Other types of configuration directives such as BIND or MSGTYPE are not allowed. - Instead of a comma-separated list of options, NETHACKOPTIONS can - be set to the full name of a configuration file you want to use. If - that full name doesn't start with a slash, precede it with `@' (at- - sign) to let NetHack know that the rest is intended as a file name. + Instead of a comma-separated list of options, NETHACKOPTIONS can + be set to the full name of a configuration file you want to use. If + that full name doesn't start with a slash, precede it with `@' (at- + sign) to let NetHack know that the rest is intended as a file name. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4232,11 +4232,11 @@ 9.4. Customization options - Here are explanations of what the various options do. Character - strings that are too long may be truncated. Some of the options + Here are explanations of what the various options do. Character + strings that are too long may be truncated. Some of the options listed may be inactive in your dungeon. - Some options are persistent, and are saved and reloaded along + Some options are persistent, and are saved and reloaded along with the game. Changing a persistent option in the configuration file applies only to new games. @@ -4244,25 +4244,25 @@ Add location or direction information to messages (default is off). acoustics - Enable messages about what your character hears (default on). Note + Enable messages about what your character hears (default on). Note that this has nothing to do with your computer's audio capabilities. Persistent. alignment - Your starting alignment (align:lawful, align:neutral, or - align:chaotic). You may specify just the first letter. Many roles - and the non-human races restrict which alignments are allowed. See + Your starting alignment (align:lawful, align:neutral, or + align:chaotic). You may specify just the first letter. Many roles + and the non-human races restrict which alignments are allowed. See role for a description of how to use negation to exclude choices. If align is not specified, there is no default value; player will be - prompted unless role and/or race forces a choice for alignment. + prompted unless role and/or race forces a choice for alignment. Cannot be set with the `O' command. Persistent. armorstatus - Display an extra status condition which summarizes currently worn + Display an extra status condition which summarizes currently worn armor (default off, not supported by all interfaces). - For the usual case where more than one piece of armor is worn, a + For the usual case where more than one piece of armor is worn, a list of letters is shown in the following order: G - gloves; @@ -4274,8 +4274,8 @@ S - shield. autodescribe - Automatically describe the terrain under cursor when asked to get a - location on the map (default true). The whatis_coord option con- + Automatically describe the terrain under cursor when asked to get a + location on the map (default true). The whatis_coord option con- trols whether the description includes map coordinates. autodig @@ -4284,7 +4284,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4299,58 +4299,58 @@ sistent. autopickup - Automatically pick up things onto which you move (default off). + Automatically pick up things onto which you move (default off). Persistent. - See pickup_types and also autopickup_exception for ways to refine + See pickup_types and also autopickup_exception for ways to refine the behavior. Note: prior to version 5.0.0, the default for autopickup was on. autoquiver - This option controls what happens when you attempt the `f' (fire) - command when nothing is quivered or readied (default false). When - true, the computer will fill your quiver or quiver sack or make + This option controls what happens when you attempt the `f' (fire) + command when nothing is quivered or readied (default false). When + true, the computer will fill your quiver or quiver sack or make ready some suitable weapon. Note that it will not take into account - the blessed/cursed status, enchantment, damage, or quality of the - weapon; you are free to manually fill your quiver or quiver sack or - make ready with the `Q' command instead. If no weapon is found or - the option is false, the `t' (throw) command is executed instead. + the blessed/cursed status, enchantment, damage, or quality of the + weapon; you are free to manually fill your quiver or quiver sack or + make ready with the `Q' command instead. If no weapon is found or + the option is false, the `t' (throw) command is executed instead. Persistent. autounlock - Controls what action to take when attempting to walk into a locked - door or to loot a locked container. Takes a plus-sign separated + Controls what action to take when attempting to walk into a locked + door or to loot a locked container. Takes a plus-sign separated list of values: Untrap - prompt about whether to attempt to find a trap; it might fail to find one even when present; if it does find one, - it will ask whether you want to try to disarm the trap; + it will ask whether you want to try to disarm the trap; if you decline, your character will forget that the door or box is trapped; - Apply-Key - if carrying a key or other unlocking tool, prompt about + Apply-Key - if carrying a key or other unlocking tool, prompt about using it; - Kick - kick the door (if you omit untrap or decline to attempt - untrap and you omit apply-key or you lack a key or you - decline to use the key; has no effect on containers); - Force - try to force a container's lid with your currently - wielded weapon (if you omit untrap or decline to attempt + Kick - kick the door (if you omit untrap or decline to attempt untrap and you omit apply-key or you lack a key or you + decline to use the key; has no effect on containers); + Force - try to force a container's lid with your currently + wielded weapon (if you omit untrap or decline to attempt + untrap and you omit apply-key or you lack a key or you decline to use the key; has no effect on doors); - None - none of the above; can't be combined with the other + None - none of the above; can't be combined with the other choices. Omitting the value is treated as if autounlock:apply-key. Preceding autounlock with `!' or "no" is treated as autounlock:none. - Applying a key might set off a trap if the door or container is - trapped. Successfully kicking a door will break it and wake up - nearby monsters. Successfully forcing a container open will break - its lock and might also destroy some of its contents or damage your + Applying a key might set off a trap if the door or container is + trapped. Successfully kicking a door will break it and wake up + nearby monsters. Successfully forcing a container open will break + its lock and might also destroy some of its contents or damage your weapon or both. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4369,15 +4369,15 @@ Allow saving and loading bones files (default true). Persistent. boulder - Set the character used to display boulders (default is the "large + Set the character used to display boulders (default is the "large rock" class symbol, ``'). catname - Name your starting cat (for example "catname:Morris"). Cannot be + Name your starting cat (for example "catname:Morris"). Cannot be set with the `O' command. character - Synonym for "role" to pick the type of your character (for example + Synonym for "role" to pick the type of your character (for example "character:Monk"). See role for more details. checkpoint @@ -4385,11 +4385,11 @@ program crash (default on). Persistent. cmdassist - Have the game provide some additional command assistance for new + Have the game provide some additional command assistance for new players if it detects some anticipated mistakes (default on). confirm - Have user confirm attacks on pets, shopkeepers, and other peaceable + Have user confirm attacks on pets, shopkeepers, and other peaceable creatures (default on). Persistent. dark_room @@ -4399,13 +4399,13 @@ Start the character permanently deaf (default false). Persistent. dropped_nopick - If this option is on, items you dropped will not be automatically - picked up, even if autopickup is also on and they are in - pickup_types or match a positive autopickup exception (default on). + If this option is on, items you dropped will not be automatically + picked up, even if autopickup is also on and they are in + pickup_types or match a positive autopickup exception (default on). Persistent. disclose - Controls what information the program reveals when the game ends. + Controls what information the program reveals when the game ends. Value is a space separated list of prompting/category pairs (default is "ni na nv ng nc no", prompt with default response of `n' for each candidate). Persistent. The possibilities are: @@ -4416,7 +4416,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4433,7 +4433,7 @@ c - display your conduct; also achievements, if any; o - display dungeon overview. - Each disclosure possibility can optionally be preceded by a prefix + Each disclosure possibility can optionally be preceded by a prefix which lets you refine how it behaves. Here are the valid prefixes: y - prompt you and default to yes on the prompt; @@ -4441,48 +4441,48 @@ + - disclose it without prompting; - - do not disclose it and do not prompt. - The listings of vanquished monsters and of genocided types can be + The listings of vanquished monsters and of genocided types can be sorted, so there are two additional choices for `v' and `g': ? - prompt you and default to ask on the prompt; # - disclose it without prompting, ask for sort order. - Asking refers to picking one of the orderings from a menu. The `+' - disclose without prompting choice, or being prompted and answering - `y' rather than `a', will default to showing monsters in the order + Asking refers to picking one of the orderings from a menu. The `+' + disclose without prompting choice, or being prompted and answering + `y' rather than `a', will default to showing monsters in the order specified by the sortvanquished option. - Omitted categories are implicitly added with `n' prefix. Specified - categories with omitted prefix implicitly use `+' prefix. Order of - the disclosure categories does not matter, program display for end- + Omitted categories are implicitly added with `n' prefix. Specified + categories with omitted prefix implicitly use `+' prefix. Order of + the disclosure categories does not matter, program display for end- of-game disclosure follows a set sequence. (for example "disclose:yi na +v -g o") The example sets inventory to - prompt and default to yes, attributes to prompt and default to no, - vanquished to disclose without prompting, genocided to not disclose - and not prompt, conduct to implicitly prompt and default to no, and + prompt and default to yes, attributes to prompt and default to no, + vanquished to disclose without prompting, genocided to not disclose + and not prompt, conduct to implicitly prompt and default to no, and overview to disclose without prompting. - Note that the vanquished monsters list includes all monsters killed + Note that the vanquished monsters list includes all monsters killed by traps and each other as well as by you. And the dungeon overview - shows all levels you had visited but does not reveal things about + shows all levels you had visited but does not reveal things about them that you hadn't discovered. dogname - Name your starting dog (for example "dogname:Fang"). Cannot be set + Name your starting dog (for example "dogname:Fang"). Cannot be set with the `O' command. extmenu - Changes the extended commands interface to pop-up a menu of avail- - able commands. It is keystroke compatible with the traditional + Changes the extended commands interface to pop-up a menu of avail- + able commands. It is keystroke compatible with the traditional interface except that it does not require that you hit Enter. It is implemented for the tty interface (default off). - For the X11 interface, which always uses a menu for choosing an - extended command, it controls whether the menu shows all available + For the X11 interface, which always uses a menu for choosing an + extended command, it controls whether the menu shows all available - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4492,7 +4492,7 @@ - commands (on) or just the subset of commands which have tradition- + commands (on) or just the subset of commands which have tradition- ally been considered extended ones (off). female @@ -4500,55 +4500,55 @@ command. fireassist - This option controls what happens when you attempt the `f' (fire) - and don't have an appropriate launcher, such as a bow or a sling, - wielded. If on, you will automatically wield the launcher. Default + This option controls what happens when you attempt the `f' (fire) + and don't have an appropriate launcher, such as a bow or a sling, + wielded. If on, you will automatically wield the launcher. Default is on. fixinv An object's inventory letter sticks to it when it's dropped (default - on). If this is off, dropping an object shifts all the remaining + on). If this is off, dropping an object shifts all the remaining inventory letters. Persistent. force_invmenu - Commands asking for an inventory item show a menu instead of a text + Commands asking for an inventory item show a menu instead of a text query with possible menu letters. Default is off. fruit - Name a fruit after something you enjoy eating (for example + Name a fruit after something you enjoy eating (for example "fruit:mango") (default "slime mold"). Basically a nostalgic whimsy - that NetHack uses from time to time. You should set this to some- - thing you find more appetizing than slime mold. Apples, oranges, - pears, bananas, and melons already exist in NetHack, so don't use + that NetHack uses from time to time. You should set this to some- + thing you find more appetizing than slime mold. Apples, oranges, + pears, bananas, and melons already exist in NetHack, so don't use those. gender - Your starting gender (gender:male or gender:female). You may spec- - ify just the first letter. Although you can still denote your gen- - der using either of the deprecated male and female options, if the + Your starting gender (gender:male or gender:female). You may spec- + ify just the first letter. Although you can still denote your gen- + der using either of the deprecated male and female options, if the gender option is also present it will take precedence. See role for a description of how to use negation to exclude choices. - If gender is not specified, there is no default value; player will - be prompted unless role and/or race forces a choice for gender. + If gender is not specified, there is no default value; player will + be prompted unless role and/or race forces a choice for gender. Cannot be set with the `O' command. Persistent. goldX When filtering objects based on bless/curse state (BUCX), whether to - treat gold pieces as X (unknown bless/curse state, when "on") or U - (known to be uncursed, when "off", the default). Gold is never - blessed or cursed, but it is not described as "uncursed" even when + treat gold pieces as X (unknown bless/curse state, when "on") or U + (known to be uncursed, when "off", the default). Gold is never + blessed or cursed, but it is not described as "uncursed" even when the implicit_uncursed option is "off". help - If more information is available for an object looked at with the - `/' command, ask if you want to see it (default on). Turning help - off makes just looking at things faster, since you aren't inter- - rupted with the "More info?" prompt, but it also means that you - might miss some interesting and/or important information. Persis- + If more information is available for an object looked at with the + `/' command, ask if you want to see it (default on). Turning help + off makes just looking at things faster, since you aren't inter- + rupted with the "More info?" prompt, but it also means that you + might miss some interesting and/or important information. Persis- - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4562,59 +4562,59 @@ herecmd_menu When using a windowport that supports mouse and clicking on yourself - or next to you, show a menu of possible actions for the location. + or next to you, show a menu of possible actions for the location. Same as "#herecmdmenu" and "#therecmdmenu" commands. hilite_pet - Visually distinguish pets from similar animals (default off). The - behavior of this option depends on the type of windowing you use. + Visually distinguish pets from similar animals (default off). The + behavior of this option depends on the type of windowing you use. In text windowing, text highlighting or inverse video is often used; with tiles, generally displays a heart symbol near pets. With the tty or curses interface, the petattr option controls how to - highlight pets and setting it will turn the hilite_pet option on or + highlight pets and setting it will turn the hilite_pet option on or off as warranted. hilite_pile Visually distinguish piles of objects from individual objects - (default off). The behavior of this option depends on the type of - windowing you use. In text windowing, text highlighting or inverse - video is often used; with tiles, generally displays a small plus- + (default off). The behavior of this option depends on the type of + windowing you use. In text windowing, text highlighting or inverse + video is often used; with tiles, generally displays a small plus- symbol beside the object on the top of the pile. hitpointbar - Show a hit point bar graph behind your name and title in the status + Show a hit point bar graph behind your name and title in the status display (default off). - The "curses" interface supports it even if the status highlighting - feature has been disabled when building the program. The "tty" and - "mswin" (aka "Windows GUI") interfaces support it only if status - highlighting is left enabled when building. You don't need to set - up any highlighting rules in order to display the bar. If there is - one for hitpoints in effect and it specifies color, that color will + The "curses" interface supports it even if the status highlighting + feature has been disabled when building the program. The "tty" and + "mswin" (aka "Windows GUI") interfaces support it only if status + highlighting is left enabled when building. You don't need to set + up any highlighting rules in order to display the bar. If there is + one for hitpoints in effect and it specifies color, that color will be used for the bar. However if it specifies video attributes, they will be ignored in favor of inverse. For tty and curses, blink will also be used if the current hitpoint value is at or below the criti- cal HP threshold. The "Qt" interface also supports hitpointbar, by drawing a solid bar - above the name and title with a hard-coded color scheme. (As of + above the name and title with a hard-coded color scheme. (As of this writing, having the bar enabled unintentionally inhibits resiz- - ing the status panel. To resize that, use the #optionsfull command - to toggle the hitpointbar option off, perform the resize while it's + ing the status panel. To resize that, use the #optionsfull command + to toggle the hitpointbar option off, perform the resize while it's off, then use the same command to toggle it back on.) horsename - Name your starting horse (for example "horsename:Trigger"). Cannot + Name your starting horse (for example "horsename:Trigger"). Cannot be set with the `O' command. ignintr - Ignore interrupt signals, including breaks (default off). Persis- + Ignore interrupt signals, including breaks (default off). Persis- tent. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4639,48 +4639,48 @@ your character as lit (default off). Persistent. lootabc - When using a menu to interact with a container, use the old `a', - `b', and `c' keyboard shortcuts rather than the mnemonics `o', `i', + When using a menu to interact with a container, use the old `a', + `b', and `c' keyboard shortcuts rather than the mnemonics `o', `i', and `b' (default off). Persistent. mail Enable mail delivery during the game (default on). Persistent. male - An obsolete synonym for "gender:male". Cannot be set with the `O' + An obsolete synonym for "gender:male". Cannot be set with the `O' command. mention_decor - Give feedback when walking onto various dungeon features such as - stairs, fountains, or altars which are ordinarily only described - when covered by one or more objects (default off). Cannot be set + Give feedback when walking onto various dungeon features such as + stairs, fountains, or altars which are ordinarily only described + when covered by one or more objects (default off). Cannot be set with the `O' command. Persistent. mention_map Give feedback when interesting map locations change (default off). mention_walls - Give feedback when walking against a wall (default off). Persis- + Give feedback when walking against a wall (default off). Persis- tent. menucolors - Enable coloring menu lines (default off). See "Configuring Menu + Enable coloring menu lines (default off). See "Configuring Menu Colors" on how to configure the colors. menustyle Controls the method used when you need to choose various objects (in - response to the Drop (aka droptype) command, for instance). The - value specified should be the first letter of one of the following: - traditional, combination, full, or partial. Default is full. Per- + response to the Drop (aka droptype) command, for instance). The + value specified should be the first letter of one of the following: + traditional, combination, full, or partial. Default is full. Per- sistent. - Traditional was the only method available for very early versions; - it consists of a prompt for object class characters, followed by an - object-by-object prompt for all items matching the selected object + Traditional was the only method available for very early versions; + it consists of a prompt for object class characters, followed by an + object-by-object prompt for all items matching the selected object class(es). Combination starts with a prompt for object class(es) of - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4690,12 +4690,12 @@ - interest, but then displays a menu of matching objects rather than + interest, but then displays a menu of matching objects rather than prompting one-by-one. Full displays a menu of object classes rather - than a character prompt, and then a menu of matching objects for + than a character prompt, and then a menu of matching objects for selection. (Choosing its `A' (Autoselect-All) choice skips the sec- - ond menu. To avoid choosing that by accident, set paranoid_con- - firm:AutoAll to require confirmation.) Partial skips the object + ond menu. To avoid choosing that by accident, set paranoid_con- + firm:AutoAll to require confirmation.) Partial skips the object class filtering and immediately displays a menu of all objects. menu_deselect_all @@ -4708,9 +4708,9 @@ Key to jump to the first page in a menu. Default `^'. menu_headings - Controls how the headings in a menu are highlighted. Takes a text - attribute, or text color and attribute separated by ampersand. For - allowed attributes and colors, see "Configuring Menu Colors". Not + Controls how the headings in a menu are highlighted. Takes a text + attribute, or text color and attribute separated by ampersand. For + allowed attributes and colors, see "Configuring Menu Colors". Not all ports can actually display all types. menu_invert_all @@ -4726,13 +4726,13 @@ Key to go to the next menu page. Default `>'. menu_objsyms - Inventory and other object menus are normally separated by object + Inventory and other object menus are normally separated by object class (weapons, armor, and so forth), with a menu header line at the - beginning of each group. You can have menus add the display symbol + beginning of each group. You can have menus add the display symbol for the class of objects for each header line. You can also add the - display symbol for the individual item in each menu entry. For a + display symbol for the individual item in each menu entry. For a tiles map, that would be a small rendition of an object's tile. For - a text map, it is the same character as is used for the object's + a text map, it is the same character as is used for the object's class, which would be most useful when there are no headers separat- ing objects among classes. Possible values are @@ -4741,12 +4741,12 @@ 1 - Headers - show symbols on header lines but not entries; 2 - Entries - show symbols on menu entry lines but not headers; 3 - Both - show symbols on headers and entries; - 4 - Conditional - only show symbols for entries if there are no + 4 - Conditional - only show symbols for entries if there are no headers; - 5 - One-or-other - show symbols on headers, or on entries if no + 5 - One-or-other - show symbols on headers, or on entries if no - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4758,8 +4758,8 @@ headers. - Supported by tty and curses. When setting the value, it can be - specified by digit or keyword. The default value is Conditional + Supported by tty and curses. When setting the value, it can be + specified by digit or keyword. The default value is Conditional (4). menu_overlay @@ -4770,7 +4770,7 @@ Key to go to the previous menu page. Default `<'. menu_search - Key to search for some text and toggle selection state of matching + Key to search for some text and toggle selection state of matching menu items. Default `:'. menu_select_all @@ -4781,20 +4781,20 @@ menu_shift_left Key to scroll a menu--one which has been scrolled right--back to the - left. Implemented for perm_invent only by curses and X11. Default + left. Implemented for perm_invent only by curses and X11. Default `{'. menu_shift_right - Key to scroll a menu which has text beyond the right edge to the + Key to scroll a menu which has text beyond the right edge to the right. Implemented for perm_invent only by curses and X11. Default `}'. mon_movement - Show a message when hero notices a monster movement (default is + Show a message when hero notices a monster movement (default is off). monpolycontrol - Prompt for new form whenever any monster changes shape (default + Prompt for new form whenever any monster changes shape (default off). Debug mode only. montelecontrol @@ -4812,7 +4812,7 @@ port is the same as specifying 0. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4823,12 +4823,12 @@ msghistory - The number of top line messages to keep (and be able to recall with + The number of top line messages to keep (and be able to recall with `^P') (default 20). Cannot be set with the `O' command. msg_window - Allows you to change the way recalled messages are displayed. Cur- - rently it is only supported for tty (all four choices) and for + Allows you to change the way recalled messages are displayed. Cur- + rently it is only supported for tty (all four choices) and for curses (`f' and `r' choices, default `r'). The possible values are: s - single message (default; only choice prior to 3.4.0); @@ -4836,25 +4836,25 @@ f - full window, oldest message first; r - full window reversed, newest message first. - For backward compatibility, no value needs to be specified (which - defaults to "full"), or it can be negated (which defaults to "sin- + For backward compatibility, no value needs to be specified (which + defaults to "full"), or it can be negated (which defaults to "sin- gle"). name - Set your character's name (defaults to your user name). You can - also set your character's role by appending a dash and one or more - letters of the role (that is, by suffixing one of -A -B -C -H -K -M - -P -Ra -Ro -S -T -V -W). If -@ is used for the role, then a random + Set your character's name (defaults to your user name). You can + also set your character's role by appending a dash and one or more + letters of the role (that is, by suffixing one of -A -B -C -H -K -M + -P -Ra -Ro -S -T -V -W). If -@ is used for the role, then a random one will be automatically chosen. - On some systems, the default is the player's user name; on others, + On some systems, the default is the player's user name; on others, there is no default and the player will be prompted. The former can - made to behave like the latter by specifying a generic name such as + made to behave like the latter by specifying a generic name such as ``player''. Cannot be set with the `O' command. news Read the NetHack news file, if present (default on). Since the news - is shown at the beginning of the game, there's no point in setting + is shown at the beginning of the game, there's no point in setting this with the `O' command. nudist @@ -4875,10 +4875,10 @@ -1 - by letters but use `z' to go northwest, `y' to zap wands For backward compatibility, omitting a value is the same as specify- - ing 1 and negating number_pad is the same as specifying 0. (Set- + ing 1 and negating number_pad is the same as specifying 0. (Set- - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4888,63 +4888,63 @@ - tings 2 and 4 are for compatibility with MS-DOS or old PC Hack; in - addition to the different behavior for `5', `Alt-5' acts as `G' and - `Alt-0' acts as `I'. Setting -1 is to accommodate some QWERTZ key- - boards which have the location of the `y' and `z' keys swapped.) - When moving by numbers, to enter a count prefix for those commands - which accept one (such as "12s" to search twelve times), precede it + tings 2 and 4 are for compatibility with MS-DOS or old PC Hack; in + addition to the different behavior for `5', `Alt-5' acts as `G' and + `Alt-0' acts as `I'. Setting -1 is to accommodate some QWERTZ key- + boards which have the location of the `y' and `z' keys swapped.) + When moving by numbers, to enter a count prefix for those commands + which accept one (such as "12s" to search twelve times), precede it with the letter `n' ("n12s"). packorder - Specify the order to list object types in (default + Specify the order to list object types in (default "")[%?+!=/(*`0_"). The value of this option should be a string con- taining the symbols for the various object types. Any omitted types are filled in at the end from the previous order. paranoid_confirmation - A space separated list of specific situations where alternate - prompting is desired. The default is "paranoid_confirmation:pray + A space separated list of specific situations where alternate + prompting is desired. The default is "paranoid_confirmation:pray swim trap". - Confirm - for any prompts which are set to require "yes" rather - than `y', also require "no" to reject instead of + Confirm - for any prompts which are set to require "yes" rather + than `y', also require "no" to reject instead of accepting any non-yes response as no; changes pray and AutoAll to require "yes" or `no' too; - quit - require "yes" rather than `y' to confirm quitting the + quit - require "yes" rather than `y' to confirm quitting the game or switching into non-scoring explore mode; - die - require "yes" rather than `y' to confirm dying (not + die - require "yes" rather than `y' to confirm dying (not useful in normal play; applies to explore mode); - bones - require "yes" rather than `y' to confirm saving bones + bones - require "yes" rather than `y' to confirm saving bones data when dying in debug mode; - attack - require "yes" rather than `y' to confirm attacking a + attack - require "yes" rather than `y' to confirm attacking a peaceful monster; - wand-break - require "yes" rather than `y' to confirm breaking a + wand-break - require "yes" rather than `y' to confirm breaking a wand with the apply command; - eating - require "yes" rather than `y' to confirm whether to + eating - require "yes" rather than `y' to confirm whether to continue eating; Were-change - require "yes" rather than `y' to confirm changing form due to lycanthropy when hero has polymorph control; - pray - require `y' to confirm an attempt to pray rather than - immediately praying; on by default; (to require "yes" + pray - require `y' to confirm an attempt to pray rather than + immediately praying; on by default; (to require "yes" rather than just `y', set Confirm too); trap - require `y' to confirm an attempt to move into or onto - a known trap, unless doing so is considered to be + a known trap, unless doing so is considered to be harmless; when enabled, this confirmation is also used for moving into visible gas cloud regions; (to require - "yes" rather than just `y', set Confirm too); confir- - mation can be skipped by using the `m' movement pre- + "yes" rather than just `y', set Confirm too); confir- + mation can be skipped by using the `m' movement pre- fix; swim - prevent walking into water or lava; on by default; (to - deliberately step onto/into such terrain when this is + deliberately step onto/into such terrain when this is set, use the `m' movement prefix when adjacent); - AutoAll - require confirmation when the `A' (Autoselect-All) + AutoAll - require confirmation when the `A' (Autoselect-All) choice is selected in object class filtering menus for - menustyle:Full; (to require "yes" rather than just + menustyle:Full; (to require "yes" rather than just `y', set Confirm too); - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4954,39 +4954,39 @@ - Remove - require selection from inventory for `R' and `T' com- + Remove - require selection from inventory for `R' and `T' com- mands even when wearing just one applicable item; all - turn on all of the above. By default, the pray, swim, and trap choices are enabled, the others disabled. To disable them without setting any of the other choices, - use paranoid_confirmation:none. To keep them enabled while setting - any of the others, you can include them in the new list, such as + use paranoid_confirmation:none. To keep them enabled while setting + any of the others, you can include them in the new list, such as paranoid_confirmation:attack pray swim Remove or you can precede the - first entry in the list with a plus sign, paranoid_confirma- - tion:+attack Remove. To remove an entry that has been previously - set without removing others, precede the first entry in the list - with a minus sign, paranoid_confirmation:-swim. To both add some - new entries and remove some old ones, you can use multiple para- - noid_confirmation option settings, or you can use the `+' form and - list entries to be added by their name and entries to be removed by + first entry in the list with a plus sign, paranoid_confirma- + tion:+attack Remove. To remove an entry that has been previously + set without removing others, precede the first entry in the list + with a minus sign, paranoid_confirmation:-swim. To both add some + new entries and remove some old ones, you can use multiple para- + noid_confirmation option settings, or you can use the `+' form and + list entries to be added by their name and entries to be removed by `!' and name. The positive (no `!') and negative (with `!') entries can be intermixed. pauper - Start the character with no possessions (default false). Persis- + Start the character with no possessions (default false). Persis- tent. - Also start with no spells or skills, which are tied to starting - equipment. Does not inhibit acquiring and using items, spells, and + Also start with no spells or skills, which are tied to starting + equipment. Does not inhibit acquiring and using items, spells, and skills once play has started. perm_invent - If true, always display your current inventory in a window (default + If true, always display your current inventory in a window (default false). This only makes sense for windowing system interfaces that implement - this feature. For those that do, the perminv_mode option can be + this feature. For those that do, the perminv_mode option can be used to refine what gets displayed for perm_invent. Setting that to a value other than none while perm_invent is false will change it to true. @@ -5010,7 +5010,7 @@ ing pets on the map. Effectively a superset of the hilite_pet bool- - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5020,63 +5020,63 @@ - ean option. Curses or tty interface only; value is one of none, - bold, dim, underline, italic, blink, and inverse. Some of those + ean option. Curses or tty interface only; value is one of none, + bold, dim, underline, italic, blink, and inverse. Some of those choices might not work, depending upon terminal hardware or terminal emulation software. pettype Specify the type of your initial pet, if you are playing a character class that uses multiple types of pets; or choose to have no initial - pet at all. Possible values are "cat", "dog", "horse", and "none". + pet at all. Possible values are "cat", "dog", "horse", and "none". If the choice is not allowed for the role you are currently playing, it will be silently ignored. For example, "horse" will only be hon- ored when playing a knight. Cannot be set with the `O' command. pickup_burden - When you pick up an item that would exceed this encumbrance level - (Unencumbered, Burdened, streSsed, straiNed, overTaxed, or over- - Loaded), you will be asked if you want to continue. (Default `S'). + When you pick up an item that would exceed this encumbrance level + (Unencumbered, Burdened, streSsed, straiNed, overTaxed, or over- + Loaded), you will be asked if you want to continue. (Default `S'). Persistent. pickup_stolen - If this option is on and autopickup is also on, try to pick up - things that a monster stole from you, even if they aren't in + If this option is on and autopickup is also on, try to pick up + things that a monster stole from you, even if they aren't in pickup_types or match an autopickup exception. Default is on. Per- sistent. pickup_thrown - If this option is on and autopickup is also on, try to pick up - things that you threw, even if they aren't in pickup_types or match + If this option is on and autopickup is also on, try to pick up + things that you threw, even if they aren't in pickup_types or match an autopickup exception. Default is on. Persistent. pickup_types - Specify the object types to be picked up when autopickup is on. + Specify the object types to be picked up when autopickup is on. Default is all types. Persistent. - The value is a list of object symbols, such as pickup_types:$?! to - pick up gold, scrolls, and potions. You can use autopickup_excep- + The value is a list of object symbols, such as pickup_types:$?! to + pick up gold, scrolls, and potions. You can use autopickup_excep- tion configuration file lines to further refine autopickup behavior. - There is no way to set pickup_types to "none". (Setting it to an - empty value reverts to "all".) If you want to avoid automatically - picking up any types of items but do want to have autopickup on in - order to have autopickup_exception settings control what you do and - don't pick up, you can set pickup_types to `.'. That is the type - symbol for venom and you won't come across any venom items so won't + There is no way to set pickup_types to "none". (Setting it to an + empty value reverts to "all".) If you want to avoid automatically + picking up any types of items but do want to have autopickup on in + order to have autopickup_exception settings control what you do and + don't pick up, you can set pickup_types to `.'. That is the type + symbol for venom and you won't come across any venom items so won't unintentionally pick such up. pile_limit - When walking across a pile of objects on the floor, threshold at + When walking across a pile of objects on the floor, threshold at which the message "there are few/several/many objects here" is given - instead of showing a popup list of those objects. A value of 0 + instead of showing a popup list of those objects. A value of 0 means "no limit" (always list the objects); a value of 1 effectively means "never show the objects" since the pile size will always be at least that big; default value is 5. Persistent. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5087,28 +5087,28 @@ playmode - Values are "normal", "explore", or "debug". Allows selection of - explore mode (also known as discovery mode) or debug mode (also + Values are "normal", "explore", or "debug". Allows selection of + explore mode (also known as discovery mode) or debug mode (also known as wizard mode) instead of normal play. Debug mode might only - be allowed for someone logged in under a particular user name (on - multi-user systems) or specifying a particular character name (on - single-user systems) or it might be disabled entirely. Requesting + be allowed for someone logged in under a particular user name (on + multi-user systems) or specifying a particular character name (on + single-user systems) or it might be disabled entirely. Requesting it when not allowed or not possible results in explore mode instead. Default is normal play. price_quotes Whenever the game mentions the name of an object you haven't identi- fied yet, it also mentions the range of buy and sell prices you have - seen for that item (to help narrow down what it could be). The - price shown is the unit price for one item (even when you are look- - ing at a stack of multiple items). Many players may want to turn - this on while identifying objects, and then turn it back off again + seen for that item (to help narrow down what it could be). The + price shown is the unit price for one item (even when you are look- + ing at a stack of multiple items). Many players may want to turn + this on while identifying objects, and then turn it back off again for general play. Default is off. pushweapon Using the `w' (wield) command when already wielding something pushes - the old item into your alternate weapon slot (default off). Like- - wise for the `a' (apply) command if it causes the applied item to + the old item into your alternate weapon slot (default off). Like- + wise for the `a' (apply) command if it causes the applied item to become wielded. Persistent. query_menu @@ -5116,33 +5116,33 @@ quick_farsight When set, usually prevents the "you sense your surroundings" message - where play pauses to allow you to browse the map whenever clairvoy- - ance randomly activates. Some situations, such as being underwater - or engulfed, ignore this option. It does not affect the clairvoy- - ance spell where pausing to examine revealed objects or monsters is + where play pauses to allow you to browse the map whenever clairvoy- + ance randomly activates. Some situations, such as being underwater + or engulfed, ignore this option. It does not affect the clairvoy- + ance spell where pausing to examine revealed objects or monsters is less intrusive. Default is off. Persistent. race - Selects your race (for example, race:human). Choices are human, + Selects your race (for example, race:human). Choices are human, dwarf, elf, gnome, and orc but most roles restrict which of the non- - human races are allowed. See role for a description of how to use + human races are allowed. See role for a description of how to use negation to exclude choices. - If race is not specified, there is no default value; player will be - prompted unless role forces a choice for race. Cannot be set with + If race is not specified, there is no default value; player will be + prompted unless role forces a choice for race. Cannot be set with the `O' command. Persistent. reroll - Allows rerolling your character's starting inventory and attributes + Allows rerolling your character's starting inventory and attributes (default false). Persistent. - Note that rerolling your character is not a recommended way to play - if aiming merely to win (a lucky start has a much smaller influence - on whether or not you win the game than your actions later in the - game). This option exists partly as an acknowledgement that some + Note that rerolling your character is not a recommended way to play + if aiming merely to win (a lucky start has a much smaller influence + on whether or not you win the game than your actions later in the + game). This option exists partly as an acknowledgement that some - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5156,17 +5156,17 @@ may be necessary for certain types of challenge games. rest_on_space - Make the space bar a synonym for the `.' (#wait) command (default + Make the space bar a synonym for the `.' (#wait) command (default off). Persistent. role Pick your type of character (for example, role:Samurai); synonym for - character. See name for an alternate method of specifying your + character. See name for an alternate method of specifying your role. - This option can also be used to limit selection when role is chosen - randomly. Use a space-separated list of roles and either negate - each one or negate the option itself instead. Negation is accom- + This option can also be used to limit selection when role is chosen + randomly. Use a space-separated list of roles and either negate + each one or negate the option itself instead. Negation is accom- plished in the same manner as with boolean options, by prefixing the option or its value(s) with `!' or "no". Examples: @@ -5174,10 +5174,10 @@ OPTIONS=role:!arc !bar !kni OPTIONS=!role:arc bar kni - There can be multiple instances of the role option if they're all + There can be multiple instances of the role option if they're all negations. - If role is not specified, there is no default value; player will be + If role is not specified, there is no default value; player will be prompted. Cannot be set with the `O' command. Persistent. roguesymset @@ -5186,14 +5186,14 @@ rogue level. rlecomp - When writing out a save file, perform run length compression of the + When writing out a save file, perform run length compression of the map. Not all ports support run length compression. It has no effect on reading an existing save file. runmode - Controls the amount of screen updating for the map window when - engaged in multi-turn movement (running via shift+direction or con- - trol+direction and so forth, or via the travel command or mouse + Controls the amount of screen updating for the map window when + engaged in multi-turn movement (running via shift+direction or con- + trol+direction and so forth, or via the travel command or mouse click). The possible values are: teleport - update the map after movement has finished; @@ -5201,14 +5201,14 @@ walk - update the map after each step; crawl - like walk, but pause briefly after each step. - This option only affects the game's screen display, not the actual - results of moving. The default is "run"; versions prior to 3.4.1 - used "teleport" only. Whether or not the effect is noticeable will - depend upon the window port used or on the type of terminal. Per- + This option only affects the game's screen display, not the actual + results of moving. The default is "run"; versions prior to 3.4.1 + used "teleport" only. Whether or not the effect is noticeable will + depend upon the window port used or on the type of terminal. Per- sistent. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5223,58 +5223,58 @@ sistent. safe_wait - Prevents you from waiting or searching when next to a hostile mon- + Prevents you from waiting or searching when next to a hostile mon- ster (default on). Persistent. sanity_check - Evaluate monsters, objects, and map prior to each turn (default + Evaluate monsters, objects, and map prior to each turn (default off). Debug mode only. scores - Control what parts of the score list you are shown at the end (for - example "scores:5 top scores/4 around my score/own scores"). Only - the first letter of each category (`t', `a', or `o') is necessary. + Control what parts of the score list you are shown at the end (for + example "scores:5 top scores/4 around my score/own scores"). Only + the first letter of each category (`t', `a', or `o') is necessary. Persistent. showdamage - Whenever your character takes damage, show a message of the damage + Whenever your character takes damage, show a message of the damage taken, and the amount of hit points left. showexp - Show your accumulated experience points on bottom line (default + Show your accumulated experience points on bottom line (default off). Persistent. showrace - Display yourself as the glyph for your race, rather than the glyph - for your role (default off). Note that this setting affects only - the appearance of the display, not the way the game treats you. + Display yourself as the glyph for your race, rather than the glyph + for your role (default off). Note that this setting affects only + the appearance of the display, not the way the game treats you. Persistent. showscore - Show your approximate accumulated score on bottom line (default + Show your approximate accumulated score on bottom line (default off). By default, this feature is suppressed when building the pro- gram. Persistent. showvers Include the game's version number on the status lines (default off). Potentially useful if you switch between different versions or vari- - ants, or you are making screenshots or streaming video. Using the - statuslines:3 option is recommended so that there will be more room - available for status information, unless you're using NetHack's Qt - interface or your terminal emulator window displays fewer than 25 + ants, or you are making screenshots or streaming video. Using the + statuslines:3 option is recommended so that there will be more room + available for status information, unless you're using NetHack's Qt + interface or your terminal emulator window displays fewer than 25 lines. Persistent. + The versinfo option provides limited control over what information + showvers displays. + silent Suppress terminal beeps (default on). Persistent. sortdiscoveries Controls the sorting behavior for the output of the `\' and ``' com- - mands. Persistent. - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5284,6 +5284,8 @@ + mands. Persistent. + The possible values are: o - list object types by class, in discovery order within each @@ -5335,12 +5337,10 @@ prefix before either the #vanquished command or the #genocided com- mand. - sounds - Allow sounds to be emitted from an integrated sound library (default - on). - NetHack 5.0.0 April 16, 2026 + + NetHack 5.0.0 May 2, 2026 @@ -5350,6 +5350,10 @@ + sounds + Allow sounds to be emitted from an integrated sound library (default + on). + sparkle Display a sparkly effect when a monster (including yourself) is hit by an attack to which it is resistant (default on). Persistent. @@ -5400,13 +5404,9 @@ tombstone Draw a tombstone graphic upon your death (default on). Persistent. - toptenwin - Put the ending display in a NetHack window instead of on stdout - (default off). Setting this option makes the score list visible - when a windowing version of NetHack is started without a parent win- - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5416,6 +5416,10 @@ + toptenwin + Put the ending display in a NetHack window instead of on stdout + (default off). Setting this option makes the score list visible + when a windowing version of NetHack is started without a parent win- dow, but it no longer leaves the score list around after game end on a terminal or emulating window. @@ -5432,6 +5436,9 @@ verbose Provide more commentary during the game (default on). Persistent. + versinfo + Controls what the showvers option displays on the status lines. + weaponstatus Display an extra status condition which describes currently wielded weapon (default off, not supported by all interfaces). @@ -5464,15 +5471,8 @@ through next and previous targets, allows filtering the possible targets. - n - no filtering [default] - v - in view only - a - in same area only - The area-filter tries to be slightly predictive--if you're standing - on a doorway, it will consider the area on the side of the door you - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5482,6 +5482,12 @@ + n - no filtering [default] + v - in view only + a - in same area only + + The area-filter tries to be slightly predictive--if you're standing + on a doorway, it will consider the area on the side of the door you were last moving towards. Filtering can also be changed when getting a location with the "get- @@ -5530,15 +5536,9 @@ will attempt to do so. If it can't it will silently ignore it. You can find out if an option is supported by the window port that you are currently using by checking to see if it shows up in the Options list. - Some options are dynamic and can be specified during the game with the - `O' command. - - align_message - Where to align or place the message window (top, bottom, left, or - right) - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5548,6 +5548,13 @@ + Some options are dynamic and can be specified during the game with the + `O' command. + + align_message + Where to align or place the message window (top, bottom, left, or + right) + align_status Where to align or place the status window (top, bottom, left, or right). @@ -5595,16 +5602,9 @@ font_size_menu If NetHack can, it should use this size font for menu windows. - font_size_message - If NetHack can, it should use this size font for the message window. - - font_size_status - If NetHack can, it should use this size font for the status window. - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5614,6 +5614,12 @@ + font_size_message + If NetHack can, it should use this size font for the message window. + + font_size_status + If NetHack can, it should use this size font for the status window. + font_size_text If NetHack can, it should use this size font for text windows. @@ -5663,14 +5669,8 @@ Display an onscreen keyboard. Handhelds are most likely to support this option. - splash_screen - If NetHack can, it should display an opening splash screen when it - starts up (default yes). - - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5680,6 +5680,10 @@ + splash_screen + If NetHack can, it should display an opening splash screen when it + starts up (default yes). + statuslines Number of lines for traditional below-the-map status display. Acceptable values are 2 and 3 (default is 2). @@ -5730,13 +5734,9 @@ augmented by line-drawing symbols). Setting tiled_map to True forces ascii_map to be False. - use_darkgray - Use bold black instead of blue for black glyphs (TTY only). - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5746,6 +5746,9 @@ + use_darkgray + Use bold black instead of blue for black glyphs (TTY only). + use_inverse If NetHack can, it should display inverse when the game specifies it. @@ -5796,13 +5799,10 @@ light, highlighttext, inactiveborder, inactivecaption, menu, menu- text, scrollbar, window, windowframe, windowtext). - wraptext - If NetHack can, it should wrap long lines of text if they don't fit - in the visible area of the window. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5812,6 +5812,10 @@ + wraptext + If NetHack can, it should wrap long lines of text if they don't fit + in the visible area of the window. + 9.6. Crash Report Options Please note that NetHack does not send any information off your @@ -5863,12 +5867,8 @@ (default off, OS/2, PC, and ST NetHack only). Note: DEC Rainbows hang if this is turned on. Cannot be set with the `O' command. - subkeyvalue - (Win32 tty NetHack only). May be used to alter the value of key- - strokes that the operating system returns to NetHack to help compen- - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5878,6 +5878,9 @@ + subkeyvalue + (Win32 tty NetHack only). May be used to alter the value of key- + strokes that the operating system returns to NetHack to help compen- sate for international keyboard issues. OPTIONS=subkeyvalue:171/92 will return 92 to NetHack, if 171 was originally going to be returned. You can use multiple subkeyvalue assignments in the con- @@ -5929,12 +5932,9 @@ By placing autopickup_exception lines in your configuration file, you can define patterns to be checked when the game is about to - autopickup something. - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5944,6 +5944,8 @@ + autopickup something. + autopickup_exception Sets an exception to the pickup_types option. The autopickup_excep- tion option should be followed by a regular expression to be used as @@ -5996,11 +5998,9 @@ key by using "nothing" as the extended command to bind to. You can also bind the "", "", and "" keys. - Menu accelerator keys - The menu control or accelerator keys can also be rebound via OPTIONS - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6010,6 +6010,8 @@ + Menu accelerator keys + The menu control or accelerator keys can also be rebound via OPTIONS lines in the configuration file. You cannot bind object symbols or selection letters into menu accelerators. Some interfaces only sup- port some of the menu accelerators. @@ -6062,11 +6064,9 @@ getpos.door.next When asked for a location, the key to go to next closest door or - doorway. Default is `d'. - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6076,6 +6076,8 @@ + doorway. Default is `d'. + getpos.door.prev When asked for a location, the key to go to previous closest door or doorway. Default is `D'. @@ -6127,12 +6129,10 @@ asked for a direction, the key to respond as left click. Default is `,'. - getpos.pick.quick - When asked for a location, the key to choose the location, skip ask- - ing for more info, and exit the location asking loop. Default is - NetHack 5.0.0 April 16, 2026 + + NetHack 5.0.0 May 2, 2026 @@ -6142,6 +6142,9 @@ + getpos.pick.quick + When asked for a location, the key to choose the location, skip ask- + ing for more info, and exit the location asking loop. Default is `;'. getpos.pick.verbose @@ -6193,12 +6196,9 @@ norep - show the message once, but not again if no other message is shown in between. - Here's an example of message types using NetHack's internal pattern - matching facility: - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6208,6 +6208,9 @@ + Here's an example of message types using NetHack's internal pattern + matching facility: + MSGTYPE=stop "You feel hungry." MSGTYPE=hide "You displaced *." @@ -6259,12 +6262,9 @@ and lines with " cursed " followed by "(being worn)" on the same line will be shown in red color and underlined. You can have multi- ple MENUCOLOR entries in your configuration file, and the last MENU- - COLOR line that matches a menu line will be used for the line. - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6274,6 +6274,8 @@ + COLOR line that matches a menu line will be used for the line. + Note that if you intend to have one or more color specifications match " uncursed ", you will probably want to turn the implicit_uncursed option off so that all items known to be uncursed @@ -6326,11 +6328,9 @@ OPTION=hilite_status:field-name/behavior/color&attributes - For example, the following line in your configuration file will - cause the hitpoints field to display in the color red if your hit- - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6340,6 +6340,8 @@ + For example, the following line in your configuration file will + cause the hitpoints field to display in the color red if your hit- points drop to or below a threshold of 30%: OPTION=hilite_status:hitpoints/<=30%/red/normal @@ -6394,9 +6396,7 @@ depending upon your other option settings. - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6462,7 +6462,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6528,7 +6528,7 @@ value, and the ^ prefix causes the following character to be treated - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6594,7 +6594,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6660,7 +6660,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6726,7 +6726,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6792,7 +6792,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6858,7 +6858,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6924,7 +6924,7 @@ seen via the "#attributes" command. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6990,7 +6990,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7056,7 +7056,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7122,7 +7122,7 @@ connection between "wizard mode" and the Wizard role). Attempting to - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7188,7 +7188,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7254,7 +7254,7 @@ were distinct for specific types of monsters and objects rather than - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7320,7 +7320,7 @@ file layout which prevented score entries from being read back in cor- - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7386,7 +7386,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7452,7 +7452,7 @@ Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir maintained the - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7502,23 +7502,23 @@ NetHack 3.6.7 was released on February 16, 2023 containing a security fix and some bug fixes. - The official NetHack web site is maintained by Ken Lorber at - https://www.nethack.org/. + Development work for the major release to follow NetHack 3.6 + began in 2015 around the same time as NetHack 3.6.0 was being + released. That development work continued in parallel to each of the + NetHack 3.6 releases from 2015 through 2023, and continued until the + end of April 2026. For the first time, that development was shared + publicly on GitHub and SourceForge as it occurred. It was done under + the label NetHack-3.7 work-in-progress (WIP), although the version + number for the next release had not yet been solidified. + + Exposure of the development to the public brought many good + things, and some challenges. People were able to observe and criticize + changes and new features almost immediately, and they often did. The + GitHub pull request system made it straightforward for people to con- + tribute directly to development. Contributions resolved many, many - - - - - - - - - - - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7528,6 +7528,72 @@ + bugs in the game and we thank all the contributors. + + In early 2026, with the game development getting stable enough to + consider initiating an official release, the devteam reviewed the + nature and number of changes in the game. It was clear that there was + sufficient depth and breadth to warrant a major release and version + 5.0 was decided on. That's a new major release over 3.x, without + opening up any ambiguity or confusion with existing variants that + there might have been had it been released as version 4.0. + + NetHack 5.0.0 was released on May 2, 2026. + + The source code for NetHack 5.0.0 was modified and modernized to + be compliant with standard C99. The 5.0.0 release contained over 3100 + fixes, changes, and updated features. + + NetHack 5.0 was the first version to replace the lex and yacc + level and dungeon compilers of past versions, with a new Lua inter- + preter-based approach to provide those elements. Lua is also used for + the quest texts in NetHack 5.0.0. The entire development team acknowl- + edges the work done by Pasi Kallinen to make that happen. + + At the time of the NetHack 5.0 release, the core development + team, active and erstwhile, included Warwick Allison, Michael Allison, + Ken Arromdee, David Cohrs, Jessie Collet, Bart House, Kevin Hugo, Pasi + Kallinen, Ken Lorber, Dean Luick, Pat Rankin, Derek S. Ray, Alex + Smith, Patric Mueller, Mike Stephenson, Janet Walz, Paul Winner. + + Ken Lorber, Pat Rankin, Patrick Mueller and Michael Allison + helped ensure that NetHack 5.0 would run on macOS. + + Ingo Paschke somehow managed to revive a NetHack 5.0 port for the + Amiga, using a cross-compiler on a modern platform to do so. His work + was shared so others can straightforwardly produce NetHack 5.0 for the + Amiga thanks to his efforts. + + Ray Chason contributed the majority of maintenance work for the + NetHack 5.0 MS-DOS port, including porting the curses interface to it. + Michael Allison ensured that NetHack 5.0 core changes continued to + work with the msdos port and keep it alive. Cross-compiling the MS- + DOS port has helped make that possible and mostly painless. + + People that contributed to the Windows port of NetHack 5.0 since + the development of NetHack 5.0 begain over eleven years ago, included + Michael Allison, David Cohrs, Bart House, Pasi Kallinen, Alex Kompel, + Dion Nicolaas, Derek S. Ray and Yitzhak Sapir. + + With sadness, the devteam would like to acknowledge and remember + the past contributions from the late Ron Van Iwaarden, who was the + sole maintainer of NetHack for OS/2 for several past NetHack releases. + Ron will be missed. + + The official NetHack web site is maintained by Ken Lorber at + https://www.nethack.org/. + + + NetHack 5.0.0 May 2, 2026 + + + + + + NetHack Guidebook 116 + + + 12.1. Special Thanks On behalf of the NetHack community, thank you very much once @@ -7584,13 +7650,13 @@ sends a particularly intriguing modification to help out with the - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 - NetHack Guidebook 116 + NetHack Guidebook 117 @@ -7636,87 +7702,21 @@ - Adam Aronow Izchak Miller Mike Stephenson - Alex Kompel J. Ali Harlow Mikko Juola - Alex Smith Janet Walz Nathan Eady - Andreas Dorn Janne Salmijarvi Norm Meluch - Andy Church Jean-Christophe Collet Olaf Seibert - Andy Swanson Jeff Bailey Pasi Kallinen - Andy Thomson Jochen Erwied Pat Rankin - Ari Huttunen John Kallen Patric Mueller - Bart House John Rupley Paul Winner - Benson I. Margulies John S. Bien Pierre Martineau - Bill Dyer Johnny Lee Ralf Brown + Adam Aronow Irina Rempt-Drijfhout Mike Gallop + Alex Kompel Izchak Miller Mike Passaretti + Alex Smith J. Ali Harlow Mike Stephenson + Andreas Dorn Janet Walz Mikko Juola + Andy Church Janne Salmijarvi Nathan Eady + Andy Swanson Jean-Christophe Collet Norm Meluch + Andy Thomson Jeff Bailey Olaf Seibert + Ari Huttunen Jochen Erwied Pasi Kallinen + Bart House John Kallen Pat Rankin + Benson I. Margulies John Rupley Patric Mueller + Bill Dyer John S. Bien Paul Winner - NetHack 5.0.0 April 16, 2026 - - - - - - NetHack Guidebook 117 - - - - Boudewijn Waijers Jon W{tte Ray Chason - Bruce Cox Jonathan Handler Richard Addison - Bruce Holloway Joshua Delahunty Richard Beigel - Bruce Mewborne Karl Garrison Richard P. Hughey - Carl Schelin Keizo Yamamoto Rob Menke - Chris Russo Keith Simpson Robin Bandy - David Cohrs Ken Arnold Robin Johnson - David Damerell Ken Arromdee Roderick Schertler - David Gentzel Ken Lorber Roland McGrath - David Hairston Ken Washikita Ron Van Iwaarden - Dean Luick Kevin Darcy Ronnen Miller - Del Lamb Kevin Hugo Ross Brown - Derek S. Ray Kevin Sitze Sascha Wostmann - Deron Meranda Kevin Smolkowski Scott Bigham - Dion Nicolaas Kevin Sweet Scott R. Turner - Dylan O'Donnell Lars Huttar Sean Hunt - Eric Backus Leon Arnott Stephen Spackman - Eric Hendrickson M. Drew Streib Stefan Thielscher - Eric R. Smith Malcolm Ryan Stephen White - Eric S. Raymond Mark Gooderum Steve Creps - Erik Andersen Mark Modrall Steve Linhart - Fredrik Ljungdahl Marvin Bressler Steve VanDevender - Frederick Roeber Matthew Day Teemu Suikki - G. Branden Robinson Merlyn LeRoy Tim Lennan - Gil Neiger Michael Allison Timo Hakulinen - Greg Laskin Michael Feir Tom Almy - Greg Olson Michael Hamel Tom West - Gregg Wonderly Michael Meyer Warren Cheung - Hao-yang Wang Michael Sokolov Warwick Allison - Helge Hafting Mike Engber Yitzhak Sapir - Ingo Paschke Mike Gallop - Irina Rempt-Drijfhout Mike Passaretti - - - - - - - - - - - - - - - - - - - - - - - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7726,6 +7726,72 @@ + Boudewijn Waijers Johnny Lee Pierre Martineau + Bruce Cox Jon W{tte Ralf Brown + Bruce Holloway Jonathan Handler Ray Chason + Bruce Mewborne Joshua Delahunty Richard Addison + Cameron Root Karl Garrison Richard Beigel + Carl Schelin Keizo Yamamoto Richard P. Hughey + Chris Russo Keith Simpson Rob Menke + David Cohrs Ken Arnold Robin Bandy + David Damerell Ken Arromdee Robin Johnson + David Gentzel Ken Lorber Roderick Schertler + David Hairston Ken Washikita Roland McGrath + Dean Luick Kestrel Gregorich-Trevor Ron Van Iwaarden + Del Lamb Kevin Darcy Ronnen Miller + Derek S. Ray Kevin Hugo Ross Brown + Deron Meranda Kevin Sitze Sascha Wostmann + Dion Nicolaas Kevin Smolkowski Scott Bigham + Dylan O'Donnell Kevin Sweet Scott R. Turner + Eric Backus Lars Huttar Sean Hunt + Eric Hendrickson Leon Arnott Stephen Spackman + Eric R. Smith M. Drew Streib Stefan Thielscher + Eric S. Raymond Malcolm Ryan Stephen White + Erik Andersen Mark Gooderum Steve Creps + Fredrik Ljungdahl Mark Modrall Steve Linhart + Frederick Roeber Marvin Bressler Steve VanDevender + G. Branden Robinson Matthew Day Teemu Suikki + Gil Neiger Merlyn LeRoy Tim Lennan + Greg Laskin Michael Allison Timo Hakulinen + Greg Olson Michael Feir Tom Almy + Gregg Wonderly Michael Hamel Tom West + Hao-yang Wang Michael Meyer Warren Cheung + Helge Hafting Michael Sokolov Warwick Allison + Ingo Paschke Mike Engber Yitzhak Sapir + + + + + + + + + + + + + + + + + + + + + + + + + NetHack 5.0.0 May 2, 2026 + + + + + + NetHack Guidebook 119 + + + Brand and product names are trademarks or registered trademarks of their respective holders. @@ -7782,7 +7848,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 From 5228a01cdebc3ef19c30309b1d6133510501667c Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 2 May 2026 10:14:56 -0400 Subject: [PATCH 123/702] Guidebook.txt update --- doc/Guidebook.txt | 3284 +++++++++++++++++++++++---------------------- 1 file changed, 1675 insertions(+), 1609 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index f46ff0ca4..ae19710a4 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for NetHack 5.0.0 by Mike Stephenson and others) - April 16, 2026 + May 2, 2026 @@ -126,7 +126,7 @@ employ to great advantage. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -192,7 +192,7 @@ NetHack continues this fine tradition. Unlike text adventure games - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -258,7 +258,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -324,7 +324,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -390,7 +390,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -456,7 +456,7 @@ The number of turns elapsed so far, displayed if you have the - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -522,7 +522,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -588,7 +588,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -654,7 +654,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -720,7 +720,7 @@ instead. Only these one-step movement commands cause you to - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -786,7 +786,7 @@ ing . ^ is used as shorthand elsewhere in the - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -852,7 +852,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -918,7 +918,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -984,7 +984,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1050,7 +1050,7 @@ at an adjacent "remembered, unseen monster" marker. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1102,21 +1102,21 @@ ^T Teleport, if you have the ability. - v Display version number. + v Display a list of significant events in the current game, also + shown by #chronicle. - V Display the game history. + `v' used to display the game's version number. Use `V' for that + now. - w Wield weapon. + V Display version number. - w- - wield nothing, use your bare (or gloved) hands. - - Some characters can wield two weapons at once; use the `X' com- - mand (or the "#twoweapon" extended command) to do so. + `V' used to display a summary of the game's history. Still + available via #history. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1126,40 +1126,47 @@ + w Wield weapon. + + w- - wield nothing, use your bare (or gloved) hands. + + Some characters can wield two weapons at once; use the `X' com- + mand (or the "#twoweapon" extended command) to do so. + W Wear armor. - This command may also be used to put on an accessory (ring, - amulet, or blindfold). The prompt for which inventory item to + This command may also be used to put on an accessory (ring, + amulet, or blindfold). The prompt for which inventory item to use will only list armor, but choosing an unlisted accessory will - attempt to put it on. (See the `P' command above. It lists - accessories as the inventory choices but will accept an item of + attempt to put it on. (See the `P' command above. It lists + accessories as the inventory choices but will accept an item of armor and attempt to wear it.) - x Exchange your wielded weapon with the item in your alternate + x Exchange your wielded weapon with the item in your alternate weapon slot. The latter is used as your secondary weapon when engaging in two- - weapon combat. Note that if one of these slots is empty, the + weapon combat. Note that if one of these slots is empty, the exchange still takes place. - X Toggle two-weapon combat, if your character can do it. Also + X Toggle two-weapon combat, if your character can do it. Also available via the "#twoweapon" extended command. - (In versions prior to 3.6 this keystroke ran the command to + (In versions prior to 3.6 this keystroke ran the command to switch from normal play to "explore mode", also known as "discov- ery mode", which has now been moved to "#exploremode" and M-X.) ^X Display basic information about your character. - Displays name, role, race, gender (unless role name makes that - redundant, such as Caveman or Priestess), and alignment, along - with your patron deity and his or her opposition. It also shows - most of the various items of information from the status line(s) - in a less terse form, including several additional things which + Displays name, role, race, gender (unless role name makes that + redundant, such as Caveman or Priestess), and alignment, along + with your patron deity and his or her opposition. It also shows + most of the various items of information from the status line(s) + in a less terse form, including several additional things which don't appear in the normal status display due to space considera- tions. - In normal play, that's all that `^X' displays. In explore mode, + In normal play, that's all that `^X' displays. In explore mode, the role and status feedback is augmented by the information pro- vided by enlightenment magic. @@ -1171,18 +1178,11 @@ Z. - to cast at yourself, use `.' for the direction. - ^Z Suspend the game (UNIX(R) versions with job control only). See - "#suspend" below for more details. - - : Look at what is here. - __________ - (R)UNIX is a registered trademark of The Open Group. - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1192,6 +1192,11 @@ + ^Z Suspend the game (UNIX(R) versions with job control only). See + "#suspend" below for more details. + + : Look at what is here. + ; Show what type of thing a visible symbol corresponds to. , Pick up some things from the floor beneath you. @@ -1221,15 +1226,15 @@ + List the spells you know. - Using this command, you can also rearrange the order in which - your spells are listed, either by sorting the entire list or by - picking one spell from the menu then picking another to swap - places with it. Swapping pairs of spells changes their casting - letters, so the change lasts after the current `+' command fin- - ishes. Sorting the whole list is temporary. To make the most - recent sort order persist beyond the current `+' command, choose - the sort option again and then pick "reassign casting letters". - (Any spells learned after that will be added to the end of the + Using this command, you can also rearrange the order in which + your spells are listed, either by sorting the entire list or by + picking one spell from the menu then picking another to swap + places with it. Swapping pairs of spells changes their casting + letters, so the change lasts after the current `+' command fin- + ishes. Sorting the whole list is temporary. To make the most + recent sort order persist beyond the current `+' command, choose + the sort option again and then pick "reassign casting letters". + (Any spells learned after that will be added to the end of the list rather than be inserted into the sorted ordering.) \ Show what types of objects have been discovered. @@ -1238,17 +1243,12 @@ ` Show discovered types for one class of objects. - May be preceded by `m' to select preferred display order. - | If persistent inventory display is supported and enabled (with - the perm_invent option), interact with it instead of with the - map. - - Allows scrolling with the menu_first_page, menu_previous_page, - menu_next_page, and menu_last_page keys (`^', `<', `>', `|' by + __________ + (R)UNIX is a registered trademark of The Open Group. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1258,8 +1258,16 @@ + May be preceded by `m' to select preferred display order. + + | If persistent inventory display is supported and enabled (with + the perm_invent option), interact with it instead of with the + map. + + Allows scrolling with the menu_first_page, menu_previous_page, + menu_next_page, and menu_last_page keys (`^', `<', `>', `|' by default). Some interfaces also support menu_shift_left and - menu_shift_right keys (`{' and `}' by default). Use the Return + menu_shift_right keys (`{' and `}' by default). Use the Return (aka Enter) or Escape key to resume play. ! Escape to a shell. See "#shell" below for more details. @@ -1268,53 +1276,45 @@ of the current level's map without monsters; without monsters and objects; or without monsters, objects, and traps. - The key is also shown as on some keyboards or - on others. It is sometimes displayed as ^? even though + The key is also shown as on some keyboards or + on others. It is sometimes displayed as ^? even though that is not an actual control character. - Many terminals have an option to swap the and - keys, so typing the key might not execute this - command. If that happens, you can use the extended command + Many terminals have an option to swap the and + keys, so typing the key might not execute this + command. If that happens, you can use the extended command "#terrain" instead. # Perform an extended command. - As you can see, the authors of NetHack used up all the letters, + As you can see, the authors of NetHack used up all the letters, so this is a way to introduce the less frequently used commands. What - extended commands are available depends on what features the game was + extended commands are available depends on what features the game was compiled with. #adjust - Adjust inventory letters (most useful when the fixinv option is + Adjust inventory letters (most useful when the fixinv option is "on"). Autocompletes. Default key is `M-a'. - This command allows you to move an item from one particular - inventory slot to another so that it has a letter which is more - meaningful for you or that it will appear in a particular loca- - tion when inventory listings are displayed. You can move to a - currently empty slot, or if the destination is occupied--and - won't merge--the item there will swap slots with the one being - moved. "#adjust" can also be used to split a stack of objects; + This command allows you to move an item from one particular + inventory slot to another so that it has a letter which is more + meaningful for you or that it will appear in a particular loca- + tion when inventory listings are displayed. You can move to a + currently empty slot, or if the destination is occupied--and + won't merge--the item there will swap slots with the one being + moved. "#adjust" can also be used to split a stack of objects; when choosing the item to adjust, enter a count prior to its let- ter. - Adjusting without a count used to collect all compatible stacks - when moving to the destination. That behavior has been changed; - to gather compatible stacks, "#adjust" a stack into its own + Adjusting without a count used to collect all compatible stacks + when moving to the destination. That behavior has been changed; + to gather compatible stacks, "#adjust" a stack into its own inventory slot. If it has a name assigned, other stacks with the - same name or with no name will merge provided that all their - other attributes match. If it does not have a name, only other - stacks with no name are eligible. In either case, otherwise com- - patible stacks with a different name will not be merged. This - contrasts with using "#adjust" to move from one slot to a differ- - ent slot. In that situation, moving (no count given) a compati- - ble stack will merge if either stack has a name when the other - doesn't and give that name to the result, while splitting (count - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1324,16 +1324,24 @@ - given) will ignore the source stack's name when deciding whether + same name or with no name will merge provided that all their + other attributes match. If it does not have a name, only other + stacks with no name are eligible. In either case, otherwise com- + patible stacks with a different name will not be merged. This + contrasts with using "#adjust" to move from one slot to a differ- + ent slot. In that situation, moving (no count given) a compati- + ble stack will merge if either stack has a name when the other + doesn't and give that name to the result, while splitting (count + given) will ignore the source stack's name when deciding whether to merge with the destination stack. #annotate Allows you to specify one line of text to associate with the cur- rent dungeon level. All levels with annotations are displayed by - the "#overview" command. Autocompletes. Default key is `M-A', + the "#overview" command. Autocompletes. Default key is `M-A', and also `^N' if number_pad is on. - Preceding #annotate with the `m' prefix is the same as #overview + Preceding #annotate with the `m' prefix is the same as #overview with the prefix. #apply @@ -1343,7 +1351,7 @@ If the tool used acts on items on the floor, using the `m' prefix skips those items. - If used on a wand, that wand will be broken, releasing its magic + If used on a wand, that wand will be broken, releasing its magic in the process. Confirmation is required. #attributes @@ -1353,14 +1361,14 @@ Toggle the autopickup option on/off. Default key is `@'. #bugreport - Bring up a browser window to submit a report to the NetHack - Development Team. Can be disabled at the time the program is - built; when enabled, CRASHREPORTURL must be set in the system + Bring up a browser window to submit a report to the NetHack + Development Team. Can be disabled at the time the program is + built; when enabled, CRASHREPORTURL must be set in the system configuration file. #call - Call (name) a monster, or an object in inventory, on the floor, - or in the discoveries list, or add an annotation for the current + Call (name) a monster, or an object in inventory, on the floor, + or in the discoveries list, or add an annotation for the current level (same as "#annotate"). Default key is `C'. #cast @@ -1369,18 +1377,10 @@ #chat Talk to someone. Default key is `M-c'. - #chronicle - Show a list of important game events. Default key is `v'. - - #close - Close a door. Default key is `c'. - - #conduct - List voluntary challenges you have maintained. Autocompletes. - Default key is `M-C'. - NetHack 5.0.0 April 16, 2026 + + NetHack 5.0.0 May 2, 2026 @@ -1390,6 +1390,16 @@ + #chronicle + Show a list of important game events. Default key is `v'. + + #close + Close a door. Default key is `c'. + + #conduct + List voluntary challenges you have maintained. Autocompletes. + Default key is `M-C'. + See the section below entitled "Conduct" for details. #debugfuzzer @@ -1399,7 +1409,7 @@ Dip an object into something. Autocompletes. Default key is `M- d'. - The `m' prefix skips dipping into a fountain or pool if there is + The `m' prefix skips dipping into a fountain or pool if there is one at your location. #down @@ -1412,22 +1422,22 @@ Drop specific item types. Default key is `D'. #eat - Eat something. Default key is `e'. The `m' prefix skips eating + Eat something. Default key is `e'. The `m' prefix skips eating items on the floor. #engrave Engrave writing on the floor. Default key is `E'. #enhance - Advance or check weapon and spell skills. Autocompletes. + Advance or check weapon and spell skills. Autocompletes. Default key is `M-e'. #exploremode Switch from normal play to non-scoring explore mode. Default key is `M-X'. - Requires confirmation; default response is n (no). To really - switch to explore mode, respond with y. You can set the para- + Requires confirmation; default response is n (no). To really + switch to explore mode, respond with y. You can set the para- noid_confirmation:quit option to require a response of yes instead. @@ -1435,18 +1445,8 @@ Prefix key to force fight a direction, even if you see nothing to fight there. Default key is `F', or `-' with number_pad - #fire - Fire ammunition from quiver, possibly autowielding a launcher, or - hit with a wielded polearm. Default key is `f'. - #force - Force a lock. Autocompletes. Default key is `M-f'. - - #genocided - List any monster types which have been genocided. In explore - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1456,17 +1456,26 @@ - mode and debug mode it also shows types which have become + #fire + Fire ammunition from quiver, possibly autowielding a launcher, or + hit with a wielded polearm. Default key is `f'. + + #force + Force a lock. Autocompletes. Default key is `M-f'. + + #genocided + List any monster types which have been genocided. In explore + mode and debug mode it also shows types which have become extinct. The display order is the same as is used by #vanquished. The `m' - prefix brings up a menu of available sorting orders, and doing - that for either #genocided or #vanquished changes the order for + prefix brings up a menu of available sorting orders, and doing + that for either #genocided or #vanquished changes the order for both. - If the sorting order is "count high to low" or "count low to - high" (which are applicable for #vanquished), that will be - ignored for #genocided and alphabetical will be used instead. + If the sorting order is "count high to low" or "count low to + high" (which are applicable for #vanquished), that will be + ignored for #genocided and alphabetical will be used instead. The menu omits those two choices when used for #genocide. Autocompletes. Default key is `M-g'. @@ -1476,20 +1485,20 @@ is `;'. #help - Show the help menu. Default key is `?', and also `h' if num- + Show the help menu. Default key is `?', and also `h' if num- ber_pad is on. #herecmdmenu - Show a menu of possible actions directed at your current loca- - tion. The menu is limited to a subset of the likeliest actions, + Show a menu of possible actions directed at your current loca- + tion. The menu is limited to a subset of the likeliest actions, not an exhaustive set of all possibilities. Autocompletes. - If mouse support is enabled and the herecmd_menu option is On, - clicking on the hero (or steed when mounted) will execute this + If mouse support is enabled and the herecmd_menu option is On, + clicking on the hero (or steed when mounted) will execute this command. #history - Show long version and game history. + Show a summary of the game's development. #inventory Show your inventory. Default key is `i'. @@ -1498,21 +1507,12 @@ Inventory specific item types. Default key is `I'. #invoke - Invoke an object's special powers. Autocompletes. Default key + Invoke an object's special powers. Autocompletes. Default key is `M-i'. - #jump - Jump to another location. Autocompletes. Default key is `M-j', - and also `j' if number_pad is on. - - #kick - Kick something. Default key is `^D', and `k' if number_pad is - on. - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1522,15 +1522,23 @@ + #jump + Jump to another location. Autocompletes. Default key is `M-j', + and also `j' if number_pad is on. + + #kick + Kick something. Default key is `^D', and `k' if number_pad is + on. + #known Show what object types have been discovered. Default key is `\'. - The `m' prefix allows assigning a new value to the sortdiscover- + The `m' prefix allows assigning a new value to the sortdiscover- ies option to control the order in which the discoveries are dis- played. #knownclass - Show discovered types for one class of objects. Default key is + Show discovered types for one class of objects. Default key is ``'. The `m' prefix operates the same as for "#known". @@ -1548,37 +1556,29 @@ Describe what you can see, or remember, of your surroundings. #loot - Loot a box or bag on the floor beneath you, or the saddle from a + Loot a box or bag on the floor beneath you, or the saddle from a steed standing next to you. Autocompletes. Precede with the `m' - prefix to skip containers at your location and go directly to - removing a saddle. Default key is `M-l', and also `l' if num- + prefix to skip containers at your location and go directly to + removing a saddle. Default key is `M-l', and also `l' if num- ber_pad is on. #monster - Use a monster's special ability (when polymorphed into monster + Use a monster's special ability (when polymorphed into monster form). Autocompletes. Default key is `M-m'. #name - Name a monster, an individual object, or a type of object. Same + Name a monster, an individual object, or a type of object. Same as "#call". Autocompletes. Default keys are `N', `M-n', and `M- N'. #offer - Offer a sacrifice to the gods. Autocompletes. Default key is + Offer a sacrifice to the gods. Autocompletes. Default key is `M-o'. - You'll need to find an altar to have any chance at success. - Corpses of recently killed monsters are the fodder of choice. - - The `m' prefix skips offering any items which are on the altar. - - #open - Open a door. Default key is `o'. - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1588,37 +1588,45 @@ + You'll need to find an altar to have any chance at success. + Corpses of recently killed monsters are the fodder of choice. + + The `m' prefix skips offering any items which are on the altar. + + #open + Open a door. Default key is `o'. + #options - Show and change option settings. Default key is `O'. Precede + Show and change option settings. Default key is `O'. Precede with the `m' prefix to show advanced options. #optionsfull - Show advanced game option settings. No default key. Precede - with the `m' prefix to execute the simpler options command. - (Mainly useful if you use BINDING=O:optionsfull to switch `O' + Show advanced game option settings. No default key. Precede + with the `m' prefix to execute the simpler options command. + (Mainly useful if you use BINDING=O:optionsfull to switch `O' from simple options back to traditional advanced options.) #overview - Display information you've discovered about the dungeon. Any - visited level with an annotation is included, and many things - (altars, thrones, fountains, and so on; extra stairs leading to + Display information you've discovered about the dungeon. Any + visited level with an annotation is included, and many things + (altars, thrones, fountains, and so on; extra stairs leading to another dungeon branch) trigger an automatic annotation. If dun- geon overview is chosen during end-of-game disclosure, every vis- ited level will be included regardless of annotations. - Precede #overview with the `m' prefix to display the dungeon - overview as a menu where you can select any visited level to add - or remove an annotation without needing to return to that level. - This will also force all visited levels to be displayed rather + Precede #overview with the `m' prefix to display the dungeon + overview as a menu where you can select any visited level to add + or remove an annotation without needing to return to that level. + This will also force all visited levels to be displayed rather than just the "interesting" subset. Autocompletes. Default keys are `^O', and `M-O'. #panic - Test the panic routine. Terminates the current game. Autocom- + Test the panic routine. Terminates the current game. Autocom- pletes. Debug mode only. - Asks for confirmation; default is n (no); continue playing. To + Asks for confirmation; default is n (no); continue playing. To really panic, respond with y. You can set the paranoid_confirma- tion:quit option to require a response of yes instead. @@ -1626,25 +1634,17 @@ Pay your shopping bill. Default key is `p'. #perminv - If persistent inventory display is supported and enabled (with - the perm_invent option), interact with it instead of with the - map. You'll be prompted for menu scrolling keystrokes such as - `>' and `<'. Press Return or Escape to resume normal play. + If persistent inventory display is supported and enabled (with + the perm_invent option), interact with it instead of with the + map. You'll be prompted for menu scrolling keystrokes such as + `>' and `<'. Press Return or Escape to resume normal play. Default key is `|'. #pickup Pick up things at the current location. Default key is `,'. The - `m' prefix forces use of a menu. - - #polyself - Polymorph self. Autocompletes. Debug mode only. - - #pray - Pray to the gods for help. Autocompletes. Default key is `M-p'. - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1654,12 +1654,20 @@ - Praying too soon after receiving prior help is a bad idea. - (Hint: entering the dungeon alive is treated as having received - help. You probably shouldn't start off a new game by praying - right away.) Since using this command by accident can cause - trouble, there is an option to make you confirm your intent - before praying. It is enabled by default, and you can reset the + `m' prefix forces use of a menu. + + #polyself + Polymorph self. Autocompletes. Debug mode only. + + #pray + Pray to the gods for help. Autocompletes. Default key is `M-p'. + + Praying too soon after receiving prior help is a bad idea. + (Hint: entering the dungeon alive is treated as having received + help. You probably shouldn't start off a new game by praying + right away.) Since using this command by accident can cause + trouble, there is an option to make you confirm your intent + before praying. It is enabled by default, and you can reset the paranoid_confirmation option to disable it. #prevmsg @@ -1678,20 +1686,20 @@ Quit the program without saving your game. Autocompletes. Since using this command by accident would throw away the current - game, you are asked to confirm your intent before quitting. - Default response is n (no); continue playing. To really quit, - respond with y. You can set the paranoid_confirmation:quit + game, you are asked to confirm your intent before quitting. + Default response is n (no); continue playing. To really quit, + respond with y. You can set the paranoid_confirmation:quit option to require a response of yes instead. #quiver Select ammunition for quiver. Default key is `Q'. #read - Read a scroll, a spellbook, or something else. Default key is + Read a scroll, a spellbook, or something else. Default key is `r'. #redraw - Redraw the screen. Default key is `^R', and also `^L' if num- + Redraw the screen. Default key is `^R', and also `^L' if num- ber_pad is on. #remove @@ -1700,17 +1708,9 @@ #repeat Repeat the previous command. Default key is `^A'. - #reqmenu - Prefix key to modify the behavior or request menu from some com- - mands. Prevents autopickup when used with movement commands. - Default key is `m'. - - #retravel - Travel to a previously selected travel destination. Default key - is `C-_'. See also #travel. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1720,16 +1720,25 @@ + #reqmenu + Prefix key to modify the behavior or request menu from some com- + mands. Prevents autopickup when used with movement commands. + Default key is `m'. + + #retravel + Travel to a previously selected travel destination. Default key + is `C-_'. See also #travel. + #ride - Ride (or stop riding) a saddled creature. Autocompletes. + Ride (or stop riding) a saddled creature. Autocompletes. Default key is `M-R'. #rub Rub a lamp or a stone. Autocompletes. Default key is `M-r'. #run - Prefix key to run towards a direction. Default key is `G' when - number_pad is off, `5' when number_pad is set to 1 or 3, other- + Prefix key to run towards a direction. Default key is `G' when + number_pad is off, `5' when number_pad is set to 1 or 3, other- wise `M-5' when it is set to 2 or 4. #rush @@ -1741,12 +1750,12 @@ Save the game and exit the program. Default key is `S'. #saveoptions - Save configuration options to the config file. This will over- - write the file, removing all comments, so if you have manually + Save configuration options to the config file. This will over- + write the file, removing all comments, so if you have manually edited the config file, don't use this. #search - Search for traps and secret doors around you. Default key is + Search for traps and secret doors around you. Default key is `s'. #seeall @@ -1763,20 +1772,11 @@ #seearmor Show the armor currently worn. Default key is `['. - Will display worn armor in a menu even when there is only thing + Will display worn armor in a menu even when there is only thing worn. - #seerings - Show the ring(s) currently worn. Default key is `='. - Will display worn rings in a menu if there are two (or there is - just one and is a meat ring rather than a "real" ring). Use the - `m' prefix to force a menu for one ring. - - - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1786,10 +1786,17 @@ + #seerings + Show the ring(s) currently worn. Default key is `='. + + Will display worn rings in a menu if there are two (or there is + just one and is a meat ring rather than a "real" ring). Use the + `m' prefix to force a menu for one ring. + #seetools Show the tools currently in use. Default key is `('. - Will display the result in a message if there is one tool in use + Will display the result in a message if there is one tool in use (worn blindfold or towel or lenses, lit lamp(s) and/or candle(s), leashes attached to pets). Will display a menu if there are more than one or if the command is preceded by the `m' prefix. @@ -1797,32 +1804,32 @@ #seeweapon Show the weapon currently wielded. Default key is `)'. - If dual-wielding, a separate message about the secondary weapon - will be given. Using the `m' prefix will force a menu and it + If dual-wielding, a separate message about the secondary weapon + will be given. Using the `m' prefix will force a menu and it will include primary weapon, alternate weapon even when not dual- - wielding, and also whatever is currently assigned to the quiver + wielding, and also whatever is currently assigned to the quiver slot. #shell - Do a shell escape, switching from NetHack to a subprocess. Can - be disabled at the time the program is built. When enabled, + Do a shell escape, switching from NetHack to a subprocess. Can + be disabled at the time the program is built. When enabled, access for specific users can be controlled by the system config- - uration file. Use the shell command `exit' to return to the + uration file. Use the shell command `exit' to return to the game. Default key is `!'. #showgold - Report the gold in your inventory, including gold you know about - in containers you're carrying. If you are inside a shop, report + Report the gold in your inventory, including gold you know about + in containers you're carrying. If you are inside a shop, report any credit or debt you have in that shop. Default key is `$'. #showspells List and reorder known spells. Default key is `+'. #showtrap - Describe an adjacent trap, possibly covered by objects or a mon- + Describe an adjacent trap, possibly covered by objects or a mon- ster. To be eligible, the trap must already be discovered. (The "#terrain" command can display your map with all objects and mon- - sters temporarily removed, making it possible to see all discov- + sters temporarily removed, making it possible to see all discov- ered traps.) Default key is `^'. #sit @@ -1832,17 +1839,10 @@ Show memory usage statistics. Autocompletes. Debug mode only. #suspend - Suspend the game, switching from NetHack to the terminal it was - started from without performing save-and-exit. Can be disabled - at the time the program is built. When enabled, mainly useful - for tty and curses interfaces on UNIX. Use the shell command - `fg' to return to the game. Default key is `^Z'. - - #swap - Swap wielded and secondary weapons. Default key is `x'. + Suspend the game, switching from NetHack to the terminal it was - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1852,6 +1852,14 @@ + started from without performing save-and-exit. Can be disabled + at the time the program is built. When enabled, mainly useful + for tty and curses interfaces on UNIX. Use the shell command + `fg' to return to the game. Default key is `^Z'. + + #swap + Swap wielded and secondary weapons. Default key is `x'. + #takeoff Take off one piece of armor. Default key is `T'. @@ -1862,25 +1870,25 @@ Teleport around the level. Default key is `^T'. #terrain - Show map without obstructions. In normal play you can view the - explored portion of the current level's map without monsters; - without monsters and objects; or without monsters, objects, and + Show map without obstructions. In normal play you can view the + explored portion of the current level's map without monsters; + without monsters and objects; or without monsters, objects, and traps. If there are visible clouds of gas in view, they are treated like - traps when deciding whether to show them or the floor underneath + traps when deciding whether to show them or the floor underneath them. - In explore mode, you can choose to view the full map rather than - just its explored portion. In debug mode there are additional + In explore mode, you can choose to view the full map rather than + just its explored portion. In debug mode there are additional choices. - Autocompletes. Default key is `' or `' (see Del + Autocompletes. Default key is `' or `' (see Del above). #therecmdmenu - Show a menu of possible actions directed at a location next to - you. The menu is limited to a subset of the likeliest actions, + Show a menu of possible actions directed at a location next to + you. The menu is limited to a subset of the likeliest actions, not an exhaustive set of all possibilities. Autocompletes. #throw @@ -1891,24 +1899,16 @@ #tip Tip over a container (bag or box) to pour out its contents. When - there are containers on the floor, the game will prompt to pick - one of them or "tip something being carried". If the latter is - chosen, there will be another prompt for which item from inven- + there are containers on the floor, the game will prompt to pick + one of them or "tip something being carried". If the latter is + chosen, there will be another prompt for which item from inven- tory to tip. The `m' prefix makes the command skip containers on the floor and - pick one from inventory, except for the special case of - menustyle:traditional with two or more containers present; that - situation will start with the floor container menu. - - Autocompletes. Default key is `M-T'. - - #toggle - Toggle a boolean option on or off. Requires a parameter in - parenthesis, the name of the option to toggle. The option must + pick one from inventory, except for the special case of - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1918,6 +1918,14 @@ + menustyle:traditional with two or more containers present; that + situation will start with the floor container menu. + + Autocompletes. Default key is `M-T'. + + #toggle + Toggle a boolean option on or off. Requires a parameter in + parenthesis, the name of the option to toggle. The option must be settable in-game. For example: @@ -1926,10 +1934,10 @@ BIND=@:toggle(autopickup) #travel - Travel to a specific location on the map. Default key is `_'. - Using the "request menu" prefix shows a menu of interesting tar- - gets in sight without asking to move the cursor. When picking a - target with cursor and the autodescribe option is on, the top + Travel to a specific location on the map. Default key is `_'. + Using the "request menu" prefix shows a menu of interesting tar- + gets in sight without asking to move the cursor. When picking a + target with cursor and the autodescribe option is on, the top line will show "(no travel path)" if your character does not know of a path to that location. See also #retravel. @@ -1937,17 +1945,17 @@ Turn undead away. Autocompletes. Default key is `M-t'. #twoweapon - Toggle two-weapon combat on or off. Autocompletes. Default key + Toggle two-weapon combat on or off. Autocompletes. Default key is `X', and also `M-2' if number_pad is off. - Note that you must use suitable weapons for this type of combat, + Note that you must use suitable weapons for this type of combat, or it will be automatically turned off. #untrap - Untrap something (trap, door, or chest). Default key is `M-u', + Untrap something (trap, door, or chest). Default key is `M-u', and `u' if number_pad is on. - In some circumstances it can also be used to rescue trapped mon- + In some circumstances it can also be used to rescue trapped mon- sters. #up @@ -1956,25 +1964,17 @@ #vanquished List vanquished monsters by type and count. - Note that the vanquished monsters list includes all monsters - killed by traps and each other as well as by you, and omits any - which got removed from the game without being killed (perhaps by - genocide, or by a mollified shopkeeper dismissing summoned Kops) + Note that the vanquished monsters list includes all monsters + killed by traps and each other as well as by you, and omits any + which got removed from the game without being killed (perhaps by + genocide, or by a mollified shopkeeper dismissing summoned Kops) or were already corpses when placed on the map. - Using the "request menu" prefix prior to #vanquished brings up a - menu of sorting orders available (provided that the vanquished - monsters list contains at least two types of monsters). Which- - ever ordering is picked gets assigned to the sortvanquished - option so is remembered for subsequent #vanquished requests. The - "#genocided" command shares this sorting order. - - During end-of-game disclosure, when asked whether to show van- - quished monsters answering `a' will let you choose from the sort - menu. + Using the "request menu" prefix prior to #vanquished brings up a + menu of sorting orders available (provided that the vanquished - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -1984,6 +1984,15 @@ + monsters list contains at least two types of monsters). Which- + ever ordering is picked gets assigned to the sortvanquished + option so is remembered for subsequent #vanquished requests. The + "#genocided" command shares this sorting order. + + During end-of-game disclosure, when asked whether to show van- + quished monsters answering `a' will let you choose from the sort + menu. + Autocompletes. Default key is `M-V'. #version @@ -1991,21 +2000,21 @@ The second paragraph lists the user interface(s) that are included. If there are more than one, you can use the windowtype - option in your run-time configuration file to select the one you + option in your run-time configuration file to select the one you want. Autocompletes. Default key is `M-v'. #versionshort - Show the program's version number, plus the date and time that - the running copy was built from sources (not the version's + Show the program's version number, plus the date and time that + the running copy was built from sources (not the version's release date). Default key is `V'. #vision Show vision array. Autocompletes. Debug mode only. #wait - Rest one move while doing nothing. Default key is `.', and also + Rest one move while doing nothing. Default key is `.', and also ` ' if rest_on_space is on. #wear @@ -2015,7 +2024,7 @@ Tell what a key does. Default key is `&'. #whatis - Show what type of thing a symbol corresponds to. Default key is + Show what type of thing a symbol corresponds to. Default key is `/'. #wield @@ -2025,22 +2034,13 @@ Wipe off your face. Autocompletes. Default key is `M-w'. #wizborn - Show monster birth, death, genocide, and extinct statistics. + Show monster birth, death, genocide, and extinct statistics. Debug mode only. - #wizbury - Bury objects under and around you. Autocompletes. Debug mode - only. - - #wizcast - Cast any spell. Debug mode only. - - #wizdetect - Reveal hidden things (secret doors or traps or unseen monsters) - within a modest radius. No time elapses. Autocompletes. Debug - NetHack 5.0.0 April 16, 2026 + + NetHack 5.0.0 May 2, 2026 @@ -2050,6 +2050,16 @@ + #wizbury + Bury objects under and around you. Autocompletes. Debug mode + only. + + #wizcast + Cast any spell. Debug mode only. + + #wizdetect + Reveal hidden things (secret doors or traps or unseen monsters) + within a modest radius. No time elapses. Autocompletes. Debug mode only. Default key is `^E'. #wizgenesis @@ -2057,7 +2067,7 @@ one. Autocompletes. Debug mode only. Default key is `^G'. #wizidentify - Identify all items in inventory. Autocompletes. Debug mode + Identify all items in inventory. Autocompletes. Debug mode only. Default key is `^I'. #wizintrinsic @@ -2065,48 +2075,38 @@ only. #wizkill - Remove monsters from play by just pointing at them. By default - the hero gets credit or blame for killing the targets. Precede - this command with the `m' prefix to override that. Autocom- + Remove monsters from play by just pointing at them. By default + the hero gets credit or blame for killing the targets. Precede + this command with the `m' prefix to override that. Autocom- pletes. Debug mode only. #wizlevelport - Teleport to another level. Autocompletes. Debug mode only. + Teleport to another level. Autocompletes. Debug mode only. Default key is `^V'. #wizmap - Map the level. Autocompletes. Debug mode only. Default key is + Map the level. Autocompletes. Debug mode only. Default key is `^F'. #wizrumorcheck - Verify rumor boundaries by displaying first and last true rumors + Verify rumor boundaries by displaying first and last true rumors and first and last false rumors. - Also displays first, second, and last random engravings, epi- + Also displays first, second, and last random engravings, epi- taphs, and hallucinatory monsters. Autocompletes. Debug mode only. #wizseenv - Show map locations' seen vectors. Autocompletes. Debug mode + Show map locations' seen vectors. Autocompletes. Debug mode only. #wizsmell Smell monster. Autocompletes. Debug mode only. - #wizwhere - Show locations of special levels. Autocompletes. Debug mode - only. - - #wizwish - Wish for something. Autocompletes. Debug mode only. Default - key is `^W'. Precede this command with the `m' prefix to show a - wish history menu. - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2116,6 +2116,15 @@ + #wizwhere + Show locations of special levels. Autocompletes. Debug mode + only. + + #wizwish + Wish for something. Autocompletes. Debug mode only. Default + key is `^W'. Precede this command with the `m' prefix to show a + wish history menu. + #wmode Show wall modes. Autocompletes. Debug mode only. @@ -2127,23 +2136,23 @@ - If your keyboard has a meta key (which, when pressed in combina- - tion with another key, modifies it by setting the "meta" [8th, or - "high"] bit), you can invoke many extended commands by meta-ing the + If your keyboard has a meta key (which, when pressed in combina- + tion with another key, modifies it by setting the "meta" [8th, or + "high"] bit), you can invoke many extended commands by meta-ing the first letter of the command. On Windows and MS-DOS, the "Alt" key can be used in this fashion. - On other systems, if typing "Alt" plus another key transmits a two - character sequence consisting of an Escape followed by the other key, - you may set the altmeta option to have NetHack combine them into - meta+. (This combining action only takes place when NetHack is + On other systems, if typing "Alt" plus another key transmits a two + character sequence consisting of an Escape followed by the other key, + you may set the altmeta option to have NetHack combine them into + meta+. (This combining action only takes place when NetHack is expecting a command to execute, not when accepting input to name some- thing or to make a wish.) Unlike control characters, where ^x and ^X denote the same thing, - meta characters are case-sensitive: M-x and M-X represent different - things. Some commands which can be run via a meta character require - that the letter be capitalized because the lower-case equivalent is + meta characters are case-sensitive: M-x and M-X represent different + things. Some commands which can be run via a meta character require + that the letter be capitalized because the lower-case equivalent is used for another command, so the three key combination meta+Shift+ is needed. @@ -2163,16 +2172,7 @@ - - - - - - - - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2238,7 +2238,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2252,7 +2252,7 @@ - If the number_pad option is on, some additional letter commands + If the number_pad option is on, some additional letter commands are available: h #help @@ -2304,7 +2304,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2316,61 +2316,61 @@ 5. Rooms and corridors - Rooms and corridors in the dungeon are either lit or dark. Any - lit areas within your line of sight will be displayed; dark areas are - only displayed if they are within one space of you. Walls and corri- + Rooms and corridors in the dungeon are either lit or dark. Any + lit areas within your line of sight will be displayed; dark areas are + only displayed if they are within one space of you. Walls and corri- dors remain on the map as you explore them. Secret corridors are hidden and appear to be solid rock. You can find them with the `s' (search) command when adjacent to them. Multi- - ple search attempts may be needed. When searching is successful, - secret corridors become ordinary open corridor locations. Mapping - magic reveals secret corridors, so converts them into ordinary corri- + ple search attempts may be needed. When searching is successful, + secret corridors become ordinary open corridor locations. Mapping + magic reveals secret corridors, so converts them into ordinary corri- dors and shows them as such. 5.1. Doorways - Doorways connect rooms and corridors. Some doorways have no - doors; you can walk right through. Others have doors in them, which - may be open, closed, or locked. To open a closed door, use the `o' - (open) command; to close it again, use the `c' (close) command. By - default the autoopen option is enabled, so simply attempting to walk - onto a closed door's location will attempt to open it without needing - `o'. Opening via autoopen will not work if you are confused or + Doorways connect rooms and corridors. Some doorways have no + doors; you can walk right through. Others have doors in them, which + may be open, closed, or locked. To open a closed door, use the `o' + (open) command; to close it again, use the `c' (close) command. By + default the autoopen option is enabled, so simply attempting to walk + onto a closed door's location will attempt to open it without needing + `o'. Opening via autoopen will not work if you are confused or stunned or suffer from the fumbling attribute. - Open doors cannot be entered diagonally; you must approach them - straight on, horizontally or vertically. Doorways without doors are + Open doors cannot be entered diagonally; you must approach them + straight on, horizontally or vertically. Doorways without doors are not restricted in this fashion except on one particular level (described by "#overview" as "a primitive area"). - Unlocking magic exists but usually won't be available early on. - You can get through a locked door without magic by first using an - unlocking tool with the `a' (apply) command, and then opening it. By - default the autounlock option is also enabled, so if you attempt to - open (via `o' or autoopen) a locked door while carrying an unlocking - tool, you'll be asked whether to use it on the door's lock. Alterna- - tively, you can break a closed door (whether locked or not) down by - kicking it via the `^D' (kick) command. Kicking down a door destroys + Unlocking magic exists but usually won't be available early on. + You can get through a locked door without magic by first using an + unlocking tool with the `a' (apply) command, and then opening it. By + default the autounlock option is also enabled, so if you attempt to + open (via `o' or autoopen) a locked door while carrying an unlocking + tool, you'll be asked whether to use it on the door's lock. Alterna- + tively, you can break a closed door (whether locked or not) down by + kicking it via the `^D' (kick) command. Kicking down a door destroys it and makes a lot of noise which might wake sleeping monsters. - Some closed doors are booby-trapped and will explode if an - attempt is made to open (when unlocked) or unlock (when locked) or - kick down. Like kicking, an explosion destroys the door and makes a - lot of noise. The "#untrap" command can be used to search a door for - traps but might take multiple attempts to find one. When one is - found, you'll be asked whether to try to disarm it. If you accede, - success will eliminate the trap but failure will set off the trap's - explosion. (If you decline, you effectively forget that a trap was + Some closed doors are booby-trapped and will explode if an + attempt is made to open (when unlocked) or unlock (when locked) or + kick down. Like kicking, an explosion destroys the door and makes a + lot of noise. The "#untrap" command can be used to search a door for + traps but might take multiple attempts to find one. When one is + found, you'll be asked whether to try to disarm it. If you accede, + success will eliminate the trap but failure will set off the trap's + explosion. (If you decline, you effectively forget that a trap was found there.) - Closed doors can be useful for shutting out monsters. Most mon- - sters cannot open closed doors, although a few don't need to (for - example, ghosts can walk through doors and fog clouds can flow under + Closed doors can be useful for shutting out monsters. Most mon- + sters cannot open closed doors, although a few don't need to (for + example, ghosts can walk through doors and fog clouds can flow under them). Some monsters who can open doors can also use unlocking tools. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2382,61 +2382,61 @@ And some (giants) can smash doors. - Secret doors are hidden and appear to be ordinary wall (from - inside a room) or solid rock (from outside). You can find them with - the `s' (search) command but it might take multiple tries (possibly - many tries if your luck is poor). Once found they are in all ways - equivalent to normal doors. Mapping magic does not reveal secret + Secret doors are hidden and appear to be ordinary wall (from + inside a room) or solid rock (from outside). You can find them with + the `s' (search) command but it might take multiple tries (possibly + many tries if your luck is poor). Once found they are in all ways + equivalent to normal doors. Mapping magic does not reveal secret doors. 5.2. Traps (`^') - There are traps throughout the dungeon to snare the unwary - intruder. For example, you may suddenly fall into a pit and be stuck + There are traps throughout the dungeon to snare the unwary + intruder. For example, you may suddenly fall into a pit and be stuck for a few turns trying to climb out (see below). A trap usually won't - appear on your map until you trigger it by moving onto it, you see + appear on your map until you trigger it by moving onto it, you see someone else trigger it, or you discover it with the `s' (search) com- - mand (multiple attempts are often needed; if your luck is poor, many - attempts might be needed). Wands of secret door detection and spell - of detect unseen also reveal traps within a modest radius but only if + mand (multiple attempts are often needed; if your luck is poor, many + attempts might be needed). Wands of secret door detection and spell + of detect unseen also reveal traps within a modest radius but only if the trap is also within line-of-sight (whether you can see at the time or not). There is also other magic which can reveal traps. - Monsters can fall prey to traps, too, which can potentially be - used as a defensive strategy. Unfortunately traps can be harmful to - your pet(s) as well. Monsters, including pets, usually will avoid + Monsters can fall prey to traps, too, which can potentially be + used as a defensive strategy. Unfortunately traps can be harmful to + your pet(s) as well. Monsters, including pets, usually will avoid moving onto a trap which is shown on your map if they have encountered that type of trap before. - Some traps such as pits, bear traps, and webs hold you in one - place. You can escape by simply trying to move to an adjacent spot + Some traps such as pits, bear traps, and webs hold you in one + place. You can escape by simply trying to move to an adjacent spot and repeat as needed; eventually you will get free. - Other traps can send you to different locations. Teleporters - send you elsewhere on the same dungeon level. Level teleporters send - you to a random dungeon level, the destination chosen from a few lev- - els lower all the way to the top. These traps choose a new destina- - tion each time they're activated. Trap doors and holes also send you - to another level, but one which is always below the current level. - Usually that will be the next level down but it can be farther. + Other traps can send you to different locations. Teleporters + send you elsewhere on the same dungeon level. Level teleporters send + you to a random dungeon level, the destination chosen from a few lev- + els lower all the way to the top. These traps choose a new destina- + tion each time they're activated. Trap doors and holes also send you + to another level, but one which is always below the current level. + Usually that will be the next level down but it can be farther. Unlike (level) teleporters, the destination level of a particular trap - door or hole is persistent, so falling into one will bring you to the - same level each time--though not necessarily the same spot on the + door or hole is persistent, so falling into one will bring you to the + same level each time--though not necessarily the same spot on the level. Magic portals behave similarly, but with some additional vari- - ation. Some portals are two-way and their remote destination is - always the same: another portal which can take you back. Others are + ation. Some portals are two-way and their remote destination is + always the same: another portal which can take you back. Others are one-way and send you to a specific destination level but not necessar- ily to a specific location there. - There is a special multi-level branch of the dungeon with pre- - mapped levels based on the classic computer game "Sokoban." In that - game, you operate as a warehouse worker who pushes crates around - obstacles to position them at designated locations. In NetHack, the + There is a special multi-level branch of the dungeon with pre- + mapped levels based on the classic computer game "Sokoban." In that + game, you operate as a warehouse worker who pushes crates around + obstacles to position them at designated locations. In NetHack, the goal is to push boulders into pits or holes until those traps have all - been nullified, giving access to whatever is beyond them. In the + been nullified, giving access to whatever is beyond them. In the - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2446,63 +2446,63 @@ - Sokoban game, you can only move in the four cardinal compass direc- - tions, and a crate in its final destination blocks further access to - that spot. In the Sokoban levels of NetHack, you can move diagonally - (unless that would let you pass between two neighboring boulders) but - you can only push boulders in the four cardinal directions, and a - boulder which fills a pit or hole removes both the boulder and the - trap so opens up normal access to that spot. With careful foresight, - it is possible to complete all of the levels according to the tradi- - tional rules of Sokoban. (Hint: to solve Sokoban puzzles, you often - need to move things away from their eventual destinations in order to - open up more room to maneuver.) Since NetHack does not support an - undo capability, some allowances are permitted in case you get stuck. - For example, each level has at least one extra boulder. Also, it is - possible to drop everything in order to be able to squeeze into the - same location as a boulder (and then presumably move past it), or to - destroy a boulder with magic or tools, or to create new boulders with - a scroll of earth. However, doing such things will lower your luck - without any specific message given about that. See the Conduct sec- - tion for information about getting feedback for your actions in + Sokoban game, you can only move in the four cardinal compass direc- + tions, and a crate in its final destination blocks further access to + that spot. In the Sokoban levels of NetHack, you can move diagonally + (unless that would let you pass between two neighboring boulders) but + you can only push boulders in the four cardinal directions, and a + boulder which fills a pit or hole removes both the boulder and the + trap so opens up normal access to that spot. With careful foresight, + it is possible to complete all of the levels according to the tradi- + tional rules of Sokoban. (Hint: to solve Sokoban puzzles, you often + need to move things away from their eventual destinations in order to + open up more room to maneuver.) Since NetHack does not support an + undo capability, some allowances are permitted in case you get stuck. + For example, each level has at least one extra boulder. Also, it is + possible to drop everything in order to be able to squeeze into the + same location as a boulder (and then presumably move past it), or to + destroy a boulder with magic or tools, or to create new boulders with + a scroll of earth. However, doing such things will lower your luck + without any specific message given about that. See the Conduct sec- + tion for information about getting feedback for your actions in Sokoban. 5.3. Stairs and ladders (`<', `>') In general, each level in the dungeon will have a staircase going - up (`<') to the previous level and another going down (`>') to the - next level. There are some exceptions though. For instance, fairly - early in the dungeon you will find a level with two down staircases, - one continuing into the dungeon and the other branching into an area + up (`<') to the previous level and another going down (`>') to the + next level. There are some exceptions though. For instance, fairly + early in the dungeon you will find a level with two down staircases, + one continuing into the dungeon and the other branching into an area known as the Gnomish Mines. Those mines eventually hit a dead end, so - after exploring them (if you choose to do so), you'll need to climb + after exploring them (if you choose to do so), you'll need to climb back up to the main dungeon. - When you traverse a set of stairs, or trigger a trap which sends + When you traverse a set of stairs, or trigger a trap which sends you to another level, the level you're leaving will be deactivated and - stored in a file on disk. If you're moving to a previously visited - level, it will be loaded from its file on disk and reactivated. If - you're moving to a level which has not yet been visited, it will be + stored in a file on disk. If you're moving to a previously visited + level, it will be loaded from its file on disk and reactivated. If + you're moving to a level which has not yet been visited, it will be created (from scratch for most random levels, from a template for some - "special" levels, or loaded from the remains of an earlier game for a - "bones" level as briefly described below). Monsters are only active - on the current level; those on other levels are essentially placed + "special" levels, or loaded from the remains of an earlier game for a + "bones" level as briefly described below). Monsters are only active + on the current level; those on other levels are essentially placed into stasis. Ordinarily when you climb a set of stairs, you will arrive on the - corresponding staircase at your destination. However, pets (see - below) and some other monsters will follow along if they're close - enough when you travel up or down stairs, and occasionally one of + corresponding staircase at your destination. However, pets (see + below) and some other monsters will follow along if they're close + enough when you travel up or down stairs, and occasionally one of these creatures will displace you during the climb. When that occurs, the pet or other monster will arrive on the staircase and you will end up nearby. - Ladders serve the same purpose as staircases, and the two types - of inter-level connections are nearly indistinguishable during game + Ladders serve the same purpose as staircases, and the two types + of inter-level connections are nearly indistinguishable during game play. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2514,36 +2514,36 @@ 5.4. Shops and shopping - Occasionally you will run across a room with a shopkeeper near - the door and many items lying on the floor. You can buy items by + Occasionally you will run across a room with a shopkeeper near + the door and many items lying on the floor. You can buy items by picking them up and then using the `p' command. You can inquire about - the price of an item prior to picking it up by using the "#chat" com- - mand while standing on it. Using an item prior to paying for it will - incur a charge, and the shopkeeper won't allow you to leave the shop + the price of an item prior to picking it up by using the "#chat" com- + mand while standing on it. Using an item prior to paying for it will + incur a charge, and the shopkeeper won't allow you to leave the shop until you have paid any debt you owe. - You can sell items to a shopkeeper by dropping them to the floor + You can sell items to a shopkeeper by dropping them to the floor while inside a shop. You will either be offered an amount of gold and asked whether you're willing to sell, or you'll be told that the shop- - keeper isn't interested (generally, your item needs to be compatible + keeper isn't interested (generally, your item needs to be compatible with the type of merchandise carried by the shop). - If you drop something in a shop by accident, the shopkeeper will - usually claim ownership without offering any compensation. You'll + If you drop something in a shop by accident, the shopkeeper will + usually claim ownership without offering any compensation. You'll have to buy it back if you want to reclaim it. Shopkeepers sometime run out of money. When that happens, you'll - be offered credit instead of gold when you try to sell something. - Credit can be used to pay for purchases, but it is only good in the + be offered credit instead of gold when you try to sell something. + Credit can be used to pay for purchases, but it is only good in the shop where it was obtained; other shopkeepers won't honor it. (If you - happen to find a "credit card" in the dungeon, don't bother trying to + happen to find a "credit card" in the dungeon, don't bother trying to use it in shops; shopkeepers will not accept it.) - The `$' command, which reports the amount of gold you are carry- - ing, will also show current shop debt or credit, if any. The "Iu" - command lists unpaid items (those which still belong to the shop) if - you are carrying any. The "Ix" command shows an inventory-like dis- - play of any unpaid items which have been used up, along with other + The `$' command, which reports the amount of gold you are carry- + ing, will also show current shop debt or credit, if any. The "Iu" + command lists unpaid items (those which still belong to the shop) if + you are carrying any. The "Ix" command shows an inventory-like dis- + play of any unpaid items which have been used up, along with other shop fees, if any. 5.4.1. Shop idiosyncrasies @@ -2552,23 +2552,23 @@ * The price of a given item can vary due to a variety of factors. - * A shopkeeper treats the spot immediately inside the door as if it + * A shopkeeper treats the spot immediately inside the door as if it were outside the shop. - * While the shopkeeper watches you like a hawk, he or she will gener- + * While the shopkeeper watches you like a hawk, he or she will gener- ally ignore any other customers. - * If a shop is "closed for inventory," it will not open of its own + * If a shop is "closed for inventory," it will not open of its own accord. - * Shops do not get restocked with new items, regardless of inventory + * Shops do not get restocked with new items, regardless of inventory depletion. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2580,61 +2580,61 @@ 5.5. Movement feedback - Moving around the map usually provides no feedback--other than - drawing the hero at the new location--unless you step on an object or - pile of objects, or on a trap, or attempt to move onto a spot where a - monster is located. There are several options which can be used to + Moving around the map usually provides no feedback--other than + drawing the hero at the new location--unless you step on an object or + pile of objects, or on a trap, or attempt to move onto a spot where a + monster is located. There are several options which can be used to augment the normal feedback. - The pile_limit option controls how many objects can be in a - pile--sharing the same map location--for the game to state "there are - objects here" instead of listing them. The default is 5. Setting it - to 1 would always give that message instead of listing any objects. - Setting it to 0 is a special case which will always list all objects + The pile_limit option controls how many objects can be in a + pile--sharing the same map location--for the game to state "there are + objects here" instead of listing them. The default is 5. Setting it + to 1 would always give that message instead of listing any objects. + Setting it to 0 is a special case which will always list all objects no matter how big a pile is. Note that the number refers to the count of separate stacks of objects present rather than the sum of the quan- - tities of those stacks (so 7 arrows or 25 gold pieces will each count - as 1 rather than as 7 and 25, respectively, and total to 2 when both + tities of those stacks (so 7 arrows or 25 gold pieces will each count + as 1 rather than as 7 and 25, respectively, and total to 2 when both are at the same location). - The "nopickup" command prefix (default `m') can be used before a - movement direction to step on objects without attempting auto-pickup + The "nopickup" command prefix (default `m') can be used before a + movement direction to step on objects without attempting auto-pickup and without giving feedback about them. The mention_walls option controls whether you get feedback if you - try to walk into a wall or solid stone or off the edge of the map. - Normally nothing happens (unless the hero is blind and no wall is - shown, then the wall that is being bumped into will be drawn on the - map). This option also gives feedback when rushing or running stops + try to walk into a wall or solid stone or off the edge of the map. + Normally nothing happens (unless the hero is blind and no wall is + shown, then the wall that is being bumped into will be drawn on the + map). This option also gives feedback when rushing or running stops for some non-obvious reason. - The mention_decor option controls whether you get feedback when - walking on "furniture." Normally stepping onto stairs or a fountain - or an altar or various other things doesn't elicit anything unless it - is covered by one or more objects so is obscured on the map. Setting - this option to true will describe such things even when they aren't - obscured. Doorless doorways and open doors aren't considered worthy + The mention_decor option controls whether you get feedback when + walking on "furniture." Normally stepping onto stairs or a fountain + or an altar or various other things doesn't elicit anything unless it + is covered by one or more objects so is obscured on the map. Setting + this option to true will describe such things even when they aren't + obscured. Doorless doorways and open doors aren't considered worthy of mention; closed doors (if you can move onto their spots) and broken - doors are. Assuming that you're able to do so, moving onto water or - lava or ice will give feedback if not yet on that type of terrain but - not repeat it (unless there has been some intervening message) when - moving from water to another water spot, or lava to lava, or ice to - ice. Moving off of any of those back onto "normal" terrain will give - one message too, unless there is feedback about one or more objects, + doors are. Assuming that you're able to do so, moving onto water or + lava or ice will give feedback if not yet on that type of terrain but + not repeat it (unless there has been some intervening message) when + moving from water to another water spot, or lava to lava, or ice to + ice. Moving off of any of those back onto "normal" terrain will give + one message too, unless there is feedback about one or more objects, in which case the back on land circumstance is implied. - The confirm and safe_pet options control what happens when you + The confirm and safe_pet options control what happens when you try to move onto a peaceful monster's spot or a tame one's spot. - The "nopickup" command prefix (default `m') is also the move- + The "nopickup" command prefix (default `m') is also the move- without-attacking prefix and can be used to try to step onto a visible - monster's spot without the move being considered an attack (see the - Fighting subsection of Monsters below). The "fight" command prefix - (default `F'; also `-' if number_pad is on) can be used to force an - attack, when guessing where an unseen monster is or when deliberately + monster's spot without the move being considered an attack (see the + Fighting subsection of Monsters below). The "fight" command prefix + (default `F'; also `-' if number_pad is on) can be used to force an + attack, when guessing where an unseen monster is or when deliberately - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2646,22 +2646,22 @@ attacking a peaceful or tame creature. - The run_mode option controls how frequently the map gets redrawn - when moving more than one step in a single command (so when rushing, + The run_mode option controls how frequently the map gets redrawn + when moving more than one step in a single command (so when rushing, running, or traveling). 5.6. Rogue level - One dungeon level (occurring in mid to late teens of the main + One dungeon level (occurring in mid to late teens of the main dungeon) is a tribute to the ancestor game hack's inspiration rogue. - It is usually displayed differently from other levels: possibly - in characters instead of tiles, or without line-drawing symbols if - already in characters; also, gold is shown as * rather than $ and - stairs are shown as % rather than < and >. There are some minor dif- - ferences in actual game play: doorways lack doors; a scroll, wand, or - spell of light used in a room lights up the whole room rather than - within a radius around your character. And monsters represented by + It is usually displayed differently from other levels: possibly + in characters instead of tiles, or without line-drawing symbols if + already in characters; also, gold is shown as * rather than $ and + stairs are shown as % rather than < and >. There are some minor dif- + ferences in actual game play: doorways lack doors; a scroll, wand, or + spell of light used in a room lights up the whole room rather than + within a radius around your character. And monsters represented by lower-case letters aren't randomly generated on the rogue level. The slight strangeness of this level is a feature, not a bug.... @@ -2669,38 +2669,38 @@ 6. Monsters Monsters you cannot see are not displayed on the screen. Beware! - You may suddenly come upon one in a dark place. Some magic items can - help you locate them before they locate you (which some monsters can + You may suddenly come upon one in a dark place. Some magic items can + help you locate them before they locate you (which some monsters can do very well). - The commands `/' and `;' may be used to obtain information about - those monsters who are displayed on the screen. The command "#name" - (by default bound to `C'), allows you to assign a name to a monster, + The commands `/' and `;' may be used to obtain information about + those monsters who are displayed on the screen. The command "#name" + (by default bound to `C'), allows you to assign a name to a monster, which may be useful to help distinguish one from another when multiple - monsters are present. Assigning a name which is just a space will + monsters are present. Assigning a name which is just a space will remove any prior name. - The extended command "#chat" can be used to interact with an - adjacent monster. There is no actual dialog (in other words, you - don't get to choose what you'll say), but chatting with some monsters - such as a shopkeeper or the Oracle of Delphi can produce useful + The extended command "#chat" can be used to interact with an + adjacent monster. There is no actual dialog (in other words, you + don't get to choose what you'll say), but chatting with some monsters + such as a shopkeeper or the Oracle of Delphi can produce useful results. 6.1. Fighting - If you see a monster and you wish to fight it, just attempt to - walk into it. Many monsters you find will mind their own business + If you see a monster and you wish to fight it, just attempt to + walk into it. Many monsters you find will mind their own business unless you attack them. Some of them are very dangerous when angered. Remember: discretion is the better part of valor. - In most circumstances, if you attempt to attack a peaceful mon- - ster by moving into its location, you'll be asked to confirm your - intent. By default an answer of `y' acknowledges that intent, which + In most circumstances, if you attempt to attack a peaceful mon- + ster by moving into its location, you'll be asked to confirm your + intent. By default an answer of `y' acknowledges that intent, which can be error prone if you're using `y' to move. You can set the para- - noid_confirmation:attack option to require a response of "yes" + noid_confirmation:attack option to require a response of "yes" - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2712,61 +2712,61 @@ instead. - If you can't see a monster (if it is invisible, or if you are + If you can't see a monster (if it is invisible, or if you are blinded), the symbol `I' will be shown when you learn of its presence. - If you attempt to walk into it, you will try to fight it just like a - monster that you can see; of course, if the monster has moved, you - will attack empty air. If you guess that the monster has moved and - you don't wish to fight, you can use the `m' command to move without - fighting; likewise, if you don't remember a monster but want to try + If you attempt to walk into it, you will try to fight it just like a + monster that you can see; of course, if the monster has moved, you + will attack empty air. If you guess that the monster has moved and + you don't wish to fight, you can use the `m' command to move without + fighting; likewise, if you don't remember a monster but want to try fighting anyway, you can use the `F' command. 6.2. Your pet You start the game with a little dog (`d'), kitten (`f'), or pony - (`u'), which follows you about the dungeon and fights monsters with + (`u'), which follows you about the dungeon and fights monsters with you. Like you, your pet needs food to survive. Dogs and cats usually feed themselves on fresh carrion and other meats; horses need vegetar- ian food which is harder to come by. If you're worried about your pet - or want to train it, you can feed it, too, by throwing it food. A + or want to train it, you can feed it, too, by throwing it food. A properly trained pet can be very useful under certain circumstances. - Your pet also gains experience from killing monsters, and can - grow over time, gaining hit points and doing more damage. Initially, - your pet may even be better at killing things than you, which makes + Your pet also gains experience from killing monsters, and can + grow over time, gaining hit points and doing more damage. Initially, + your pet may even be better at killing things than you, which makes pets useful for low-level characters. - Your pet will follow you up and down staircases if it is next to + Your pet will follow you up and down staircases if it is next to you when you move. Otherwise your pet will be stranded and may become - wild. Similarly, when you trigger certain types of traps which alter - your location (for instance, a trap door which drops you to a lower - dungeon level), any adjacent pet will accompany you and any non-adja- + wild. Similarly, when you trigger certain types of traps which alter + your location (for instance, a trap door which drops you to a lower + dungeon level), any adjacent pet will accompany you and any non-adja- cent pet will be left behind. Your pet may trigger such traps itself; you will not be carried along with it even if adjacent at the time. 6.3. Steeds - Some types of creatures in the dungeon can actually be ridden if - you have the right equipment and skill. Convincing a wild beast to + Some types of creatures in the dungeon can actually be ridden if + you have the right equipment and skill. Convincing a wild beast to let you saddle it up is difficult to say the least. Many a dungeoneer - has had to resort to magic and wizardry in order to forge the - alliance. Once you do have the beast under your control however, you - can easily climb in and out of the saddle with the "#ride" command. - Lead the beast around the dungeon when riding, in the same manner as - you would move yourself. It is the beast that you will see displayed + has had to resort to magic and wizardry in order to forge the + alliance. Once you do have the beast under your control however, you + can easily climb in and out of the saddle with the "#ride" command. + Lead the beast around the dungeon when riding, in the same manner as + you would move yourself. It is the beast that you will see displayed on the map. - Riding skill is managed by the "#enhance" command. See the sec- + Riding skill is managed by the "#enhance" command. See the sec- tion on Weapon proficiency for more information about that. - Use the `a' (apply) command and pick a saddle in your inventory + Use the `a' (apply) command and pick a saddle in your inventory to attempt to put that saddle on an adjacent creature. If successful, it will be transferred to that creature's inventory. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2776,63 +2776,63 @@ - Use the "#loot" command while adjacent to a saddled creature to - try to remove the saddle from that creature. If successful, it will + Use the "#loot" command while adjacent to a saddled creature to + try to remove the saddle from that creature. If successful, it will be transferred to your inventory. 6.4. Bones levels You may encounter the shades and corpses of other adventurers (or - even former incarnations of yourself!) and their personal effects. - Ghosts are hard to kill, but easy to avoid, since they're slow and do + even former incarnations of yourself!) and their personal effects. + Ghosts are hard to kill, but easy to avoid, since they're slow and do little damage. You can plunder the deceased adventurer's possessions; - however, they are likely to be cursed. Beware of whatever killed the - former player; it is probably still lurking around, gloating over its + however, they are likely to be cursed. Beware of whatever killed the + former player; it is probably still lurking around, gloating over its last victory. 6.5. Persistence of Monsters - Monsters (a generic reference which also includes humans and + Monsters (a generic reference which also includes humans and pets) are only shown while they can be seen or otherwise sensed. Mov- ing to a location where you can't see or sense a monster any more will - result in it disappearing from your map, similarly if it is the one + result in it disappearing from your map, similarly if it is the one who moved rather than you. - However, if you encounter a monster which you can't see or + However, if you encounter a monster which you can't see or sense--perhaps it is invisible and has just tapped you on the noggin-- a special "remembered, unseen monster" marker will be displayed at the - location where you think it is. That will persist until you have - proven that there is no monster there, even if the unseen monster - moves to another location or you move to a spot where the marker's + location where you think it is. That will persist until you have + proven that there is no monster there, even if the unseen monster + moves to another location or you move to a spot where the marker's location ordinarily wouldn't be seen any more. 7. Objects - When you find something in the dungeon, it is common to want to - pick it up. In NetHack, this is accomplished by using the `,' com- - mand. If autopickup option is on, you will automatically pick up the + When you find something in the dungeon, it is common to want to + pick it up. In NetHack, this is accomplished by using the `,' com- + mand. If autopickup option is on, you will automatically pick up the object by walking over, unless you move with the `m' prefix. - If you're carrying too many items, NetHack will tell you so and - you won't be able to pick up anything more. Otherwise, it will add + If you're carrying too many items, NetHack will tell you so and + you won't be able to pick up anything more. Otherwise, it will add the object(s) to your pack and tell you what you just picked up. - As you add items to your inventory, you also add the weight of - that object to your load. The amount that you can carry depends on - your strength and your constitution. The stronger and sturdier you - are, the less the additional load will affect you. There comes a - point, though, when the weight of all of that stuff you are carrying + As you add items to your inventory, you also add the weight of + that object to your load. The amount that you can carry depends on + your strength and your constitution. The stronger and sturdier you + are, the less the additional load will affect you. There comes a + point, though, when the weight of all of that stuff you are carrying around with you through the dungeon will encumber you. Your reactions - will get slower and you'll burn calories faster, requiring food more - frequently to cope with it. Eventually, you'll be so overloaded that + will get slower and you'll burn calories faster, requiring food more + frequently to cope with it. Eventually, you'll be so overloaded that you'll either have to discard some of what you're carrying or collapse under its weight. NetHack will tell you how badly you have loaded yourself. If you - are encumbered, one of the conditions Burdened, Stressed, Strained, + are encumbered, one of the conditions Burdened, Stressed, Strained, - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2842,63 +2842,63 @@ - Overtaxed, or Overloaded will be shown on the bottom line status dis- + Overtaxed, or Overloaded will be shown on the bottom line status dis- play. - When you pick up an object, it is assigned an inventory letter. - Many commands that operate on objects must ask you to find out which - object you want to use. When NetHack asks you to choose a particular - object you are carrying, you are usually presented with a list of + When you pick up an object, it is assigned an inventory letter. + Many commands that operate on objects must ask you to find out which + object you want to use. When NetHack asks you to choose a particular + object you are carrying, you are usually presented with a list of inventory letters to choose from (see Commands, above). - Some objects, such as weapons, are easily differentiated. Oth- - ers, like scrolls and potions, are given descriptions which vary - according to type. During a game, any two objects with the same - description are the same type. However, the descriptions will vary + Some objects, such as weapons, are easily differentiated. Oth- + ers, like scrolls and potions, are given descriptions which vary + according to type. During a game, any two objects with the same + description are the same type. However, the descriptions will vary from game to game. - When you use one of these objects, if its effect is obvious, - NetHack will remember what it is for you. If its effect isn't - extremely obvious, you will be asked what you want to call this type - of object so you will recognize it later. You can also use the + When you use one of these objects, if its effect is obvious, + NetHack will remember what it is for you. If its effect isn't + extremely obvious, you will be asked what you want to call this type + of object so you will recognize it later. You can also use the "#name" command, for the same purpose at any time, to name all objects - of a particular type or just an individual object. When you use - "#name" on an object which has already been named, specifying a space - as the value will remove the prior name instead of assigning a new + of a particular type or just an individual object. When you use + "#name" on an object which has already been named, specifying a space + as the value will remove the prior name instead of assigning a new one. 7.1. Curses and Blessings - Any object that you find may be cursed, even if the object is - otherwise helpful. The most common effect of a curse is being stuck - with (and to) the item. Cursed weapons weld themselves to your hand + Any object that you find may be cursed, even if the object is + otherwise helpful. The most common effect of a curse is being stuck + with (and to) the item. Cursed weapons weld themselves to your hand when wielded, so you cannot unwield them. Any cursed item you wear is - not removable by ordinary means. In addition, cursed arms and armor - usually, but not always, bear negative enchantments that make them - less effective in combat. Other cursed objects may act poorly or + not removable by ordinary means. In addition, cursed arms and armor + usually, but not always, bear negative enchantments that make them + less effective in combat. Other cursed objects may act poorly or detrimentally in other ways. - Objects can also be blessed instead. Blessed items usually work - better or more beneficially than normal uncursed items. For example, + Objects can also be blessed instead. Blessed items usually work + better or more beneficially than normal uncursed items. For example, a blessed weapon will do slightly more damage against demons. - Objects which are neither cursed nor blessed are referred to as + Objects which are neither cursed nor blessed are referred to as uncursed. They could just as easily have been described as unblessed, - but the uncursed designation is what you will see within the game. A + but the uncursed designation is what you will see within the game. A "glass half full versus glass half empty" situation; make of that what you will. - There are magical means of bestowing or removing curses upon - objects, so even if you are stuck with one, you can still have the - curse lifted and the item removed. Priests and Priestesses have an - innate sensitivity to this property in any object, so they can more - easily avoid cursed objects than other character roles. Dropping - objects onto an altar will reveal their bless or curse state provided + There are magical means of bestowing or removing curses upon + objects, so even if you are stuck with one, you can still have the + curse lifted and the item removed. Priests and Priestesses have an + innate sensitivity to this property in any object, so they can more + easily avoid cursed objects than other character roles. Dropping + objects onto an altar will reveal their bless or curse state provided that you can see them land. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2908,44 +2908,44 @@ - An item with unknown status will be reported in your inventory - with no prefix. An item which you know the state of will be distin- - guished in your inventory by the presence of the word cursed, - uncursed, or blessed in the description of the item. In some cases + An item with unknown status will be reported in your inventory + with no prefix. An item which you know the state of will be distin- + guished in your inventory by the presence of the word cursed, + uncursed, or blessed in the description of the item. In some cases uncursed will be omitted as being redundant when enough other informa- - tion is displayed. The implicit_uncursed option can be used to con- - trol this; toggle it off to have uncursed be displayed even when that + tion is displayed. The implicit_uncursed option can be used to con- + trol this; toggle it off to have uncursed be displayed even when that can be deduced from other attributes. - Sometimes the bless or curse state of objects is referred to as - their "BUC" attribute, for Blessed, Uncursed, or Cursed state, or + Sometimes the bless or curse state of objects is referred to as + their "BUC" attribute, for Blessed, Uncursed, or Cursed state, or "BUCX" for Blessed, Uncursed, Cursed, or unknown. (The term beatitude is occasionally used as well.) 7.2. Artifacts - Some objects have been imbued with special powers and are known - as Artifacts. They have specific types (such as long sword or orcish + Some objects have been imbued with special powers and are known + as Artifacts. They have specific types (such as long sword or orcish dagger) and distinct names such as Giantslayer or Grimtooth. Artifact - weapons typically do more damage than their ordinary counterparts. - Some do extra damage against all monsters, others only against spe- - cific types of monsters so aren't better than regular weapons against - other types. Some confer defensive capabilities when wielded or have + weapons typically do more damage than their ordinary counterparts. + Some do extra damage against all monsters, others only against spe- + cific types of monsters so aren't better than regular weapons against + other types. Some confer defensive capabilities when wielded or have other powers that aren't listed here. - You might find them simply lying on the floor, including but not - limited to inside shops, or be granted as a reward for "#offer" on an - altar to your patron deity. A few might be dropped by monsters, or - might be converted from an ordinary object of the same type via - assigning the right name. Or you might wish for them, if you happen + You might find them simply lying on the floor, including but not + limited to inside shops, or be granted as a reward for "#offer" on an + altar to your patron deity. A few might be dropped by monsters, or + might be converted from an ordinary object of the same type via + assigning the right name. Or you might wish for them, if you happen to be granted a wish, but such wishes can fail. - Some artifacts have a specific alignment, others don't. You - won't obtain aligned ones that have a different alignment from yours - via offering and might get a shock if you attempt to wish for any of + Some artifacts have a specific alignment, others don't. You + won't obtain aligned ones that have a different alignment from yours + via offering and might get a shock if you attempt to wish for any of those or find one and attempt to use it. - Each role has a distinct artifact that is contained in the Quest + Each role has a distinct artifact that is contained in the Quest dungeon branch. These are commonly known as quest artifacts. All are aligned and most are non-weapons. They won't be found randomly. @@ -2955,16 +2955,16 @@ 7.3. Relics There are three unique items that are named and have limited spe- - cial powers but aren't classified as artifacts. Each is guarded by a - particular monster and you'll need to collect all three for use late - in the game. They are the Bell of Opening, the Book of the Dead, and - the Candelabrum of Invocation. Their corresponding descriptions when - not yet identified are silver bell, papyrus spellbook, and cande- + cial powers but aren't classified as artifacts. Each is guarded by a + particular monster and you'll need to collect all three for use late + in the game. They are the Bell of Opening, the Book of the Dead, and + the Candelabrum of Invocation. Their corresponding descriptions when + not yet identified are silver bell, papyrus spellbook, and cande- labrum. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -2976,61 +2976,61 @@ 7.4. Weapons (`)') - Given a chance, most monsters in the Mazes of Menace will gratu- - itously try to kill you. You need weapons for self-defense (killing - them first). Without a weapon, you do only 1-2 hit points of damage - (plus bonuses, if any). Monk characters are an exception; they nor- - mally do more damage with bare (or gloved) hands than they do with + Given a chance, most monsters in the Mazes of Menace will gratu- + itously try to kill you. You need weapons for self-defense (killing + them first). Without a weapon, you do only 1-2 hit points of damage + (plus bonuses, if any). Monk characters are an exception; they nor- + mally do more damage with bare (or gloved) hands than they do with weapons. - There are wielded weapons, like maces and swords, and thrown - weapons, like arrows and spears. To hit monsters with a weapon, you - must wield it and attack them, or throw it at them. You can simply - elect to throw a spear. To shoot an arrow, you should first wield a - bow, then throw the arrow. Crossbows shoot crossbow bolts. Slings + There are wielded weapons, like maces and swords, and thrown + weapons, like arrows and spears. To hit monsters with a weapon, you + must wield it and attack them, or throw it at them. You can simply + elect to throw a spear. To shoot an arrow, you should first wield a + bow, then throw the arrow. Crossbows shoot crossbow bolts. Slings hurl rocks and (other) stones (like gems). - Enchanted weapons have a "plus" (or "to hit enhancement" which - can be either positive or negative) that adds to your chance to hit - and the damage you do to a monster. The only way to determine a + Enchanted weapons have a "plus" (or "to hit enhancement" which + can be either positive or negative) that adds to your chance to hit + and the damage you do to a monster. The only way to determine a weapon's enchantment is to have it magically identified somehow. Most - weapons are subject to some type of damage like rust. Such "erosion" + weapons are subject to some type of damage like rust. Such "erosion" damage can be repaired. - The chance that an attack will successfully hit a monster, and - the amount of damage such a hit will do, depends upon many factors. - Among them are: type of weapon, quality of weapon (enchantment and/or + The chance that an attack will successfully hit a monster, and + the amount of damage such a hit will do, depends upon many factors. + Among them are: type of weapon, quality of weapon (enchantment and/or erosion), experience level, strength, dexterity, encumbrance, and pro- - ficiency (see below). The monster's armor class--a general defense - rating, not necessarily due to wearing of armor--is a factor too; - also, some monsters are particularly vulnerable to certain types of + ficiency (see below). The monster's armor class--a general defense + rating, not necessarily due to wearing of armor--is a factor too; + also, some monsters are particularly vulnerable to certain types of weapons. Many weapons can be wielded in one hand; some require both hands. When wielding a two-handed weapon, you can not wear a shield, and vice versa. When wielding a one-handed weapon, you can have another weapon - ready to use by setting things up with the `x' command, which - exchanges your primary (the one being wielded) and alternate weapons. - And if you have proficiency in the "two weapon combat" skill, you may - wield both weapons simultaneously as primary and secondary; use the - `X' command to engage or disengage that. Only some types of charac- - ters (barbarians, for instance) have the necessary skill available. - Even with that skill, using two weapons at once incurs a penalty in - the chance to hit your target compared to using just one weapon at a + ready to use by setting things up with the `x' command, which + exchanges your primary (the one being wielded) and alternate weapons. + And if you have proficiency in the "two weapon combat" skill, you may + wield both weapons simultaneously as primary and secondary; use the + `X' command to engage or disengage that. Only some types of charac- + ters (barbarians, for instance) have the necessary skill available. + Even with that skill, using two weapons at once incurs a penalty in + the chance to hit your target compared to using just one weapon at a time. - There might be times when you'd rather not wield any weapon at + There might be times when you'd rather not wield any weapon at all. To accomplish that, wield `-', or else use the `A' command which - allows you to unwield the current weapon in addition to taking off + allows you to unwield the current weapon in addition to taking off other worn items. - Those of you in the audience who are AD&D players, be aware that + Those of you in the audience who are AD&D players, be aware that each weapon which existed in AD&D does roughly the same damage to mon- - sters in NetHack. Some of the more obscure weapons (such as the + sters in NetHack. Some of the more obscure weapons (such as the aklys, lucern hammer, and bec-de-corbin) are defined in an appendix to - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3042,61 +3042,61 @@ Unearthed Arcana, an AD&D supplement. - Some interfaces support the weaponstatus option. When it is - enabled, an extra status condition is displayed, describing the cur- + Some interfaces support the weaponstatus option. When it is + enabled, an extra status condition is displayed, describing the cur- rently wielded weapon. - The commands to use weapons are `w' (wield), `t' (throw), `f' - (fire), `Q' (quiver), `x' (exchange), `X' (twoweapon), and "#enhance" + The commands to use weapons are `w' (wield), `t' (throw), `f' + (fire), `Q' (quiver), `x' (exchange), `X' (twoweapon), and "#enhance" (see below). 7.4.1. Throwing and shooting - You can throw just about anything via the `t' command. It will - prompt for the item to throw; picking `?' will list things in your - inventory which are considered likely to be thrown, or picking `*' - will list your entire inventory. After you've chosen what to throw, - you will be prompted for a direction rather than for a specific tar- - get. The distance something can be thrown depends mainly on the type + You can throw just about anything via the `t' command. It will + prompt for the item to throw; picking `?' will list things in your + inventory which are considered likely to be thrown, or picking `*' + will list your entire inventory. After you've chosen what to throw, + you will be prompted for a direction rather than for a specific tar- + get. The distance something can be thrown depends mainly on the type of object and your strength. Arrows can be thrown by hand, but can be - thrown much farther and will be more likely to hit when thrown while + thrown much farther and will be more likely to hit when thrown while you are wielding a bow. - Some weapons will return when thrown. A boomerang--provided it - fails to hit anything--is an obvious example. If an aklys (thonged - club) is thrown while it is wielded, it will return even when it hits - something. A sufficiently strong hero can throw the warhammer Mjoll- - nir; when thrown by a Valkyrie it will return too. However, aklyses - and Mjollnir occasionally fail to return. Returning thrown objects - occasionally fail to be caught, sometimes even hitting the thrower, + Some weapons will return when thrown. A boomerang--provided it + fails to hit anything--is an obvious example. If an aklys (thonged + club) is thrown while it is wielded, it will return even when it hits + something. A sufficiently strong hero can throw the warhammer Mjoll- + nir; when thrown by a Valkyrie it will return too. However, aklyses + and Mjollnir occasionally fail to return. Returning thrown objects + occasionally fail to be caught, sometimes even hitting the thrower, but when caught they become re-wielded. - You can simplify the throwing operation by using the `Q' command - to select your preferred "missile", then using the `f' command to - throw it. You'll be prompted for a direction as above, but you don't - have to specify which item to throw each time you use `f'. There is - also an option, autoquiver, which has NetHack choose another item to - automatically fill your quiver (or quiver sack, or have at the ready) - when the inventory slot used for `Q' runs out. If your quiver is - empty, autoquiver is false, and you are wielding a weapon which + You can simplify the throwing operation by using the `Q' command + to select your preferred "missile", then using the `f' command to + throw it. You'll be prompted for a direction as above, but you don't + have to specify which item to throw each time you use `f'. There is + also an option, autoquiver, which has NetHack choose another item to + automatically fill your quiver (or quiver sack, or have at the ready) + when the inventory slot used for `Q' runs out. If your quiver is + empty, autoquiver is false, and you are wielding a weapon which returns when thrown, you will throw that weapon instead of filling the - quiver. The fire command also has extra assistance, if fireassist is + quiver. The fire command also has extra assistance, if fireassist is on it will try to wield a launcher matching the ammo in the quiver. - Some characters have the ability to throw or shoot a volley of - multiple items (from the same stack) in a single action. Knowing how + Some characters have the ability to throw or shoot a volley of + multiple items (from the same stack) in a single action. Knowing how to load several rounds of ammunition at once--or hold several missiles in your hand--and still hit a target is not an easy task. Rangers are among those who are adept at this task, as are those with a high level - of proficiency in the relevant weapon skill (in bow skill if you're + of proficiency in the relevant weapon skill (in bow skill if you're wielding one to shoot arrows, in crossbow skill if you're wielding one - to shoot bolts, or in sling skill if you're wielding one to shoot - stones). The number of items that the character has a chance to fire - varies from turn to turn. You can explicitly limit the number of - shots by using a numeric prefix before the `t' or `f' command. For + to shoot bolts, or in sling skill if you're wielding one to shoot + stones). The number of items that the character has a chance to fire + varies from turn to turn. You can explicitly limit the number of + shots by using a numeric prefix before the `t' or `f' command. For - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3108,61 +3108,61 @@ example, "2f" (or "n2f" if using number_pad mode) would ensure that at most 2 arrows are shot even if you could have fired 3. If you specify - a larger number than would have been shot ("4f" in this example), - you'll just end up shooting the same number (3, here) as if no limit - had been specified. Once the volley is in motion, all of the items - will travel in the same direction; if the first ones kill a monster, + a larger number than would have been shot ("4f" in this example), + you'll just end up shooting the same number (3, here) as if no limit + had been specified. Once the volley is in motion, all of the items + will travel in the same direction; if the first ones kill a monster, the others can still continue beyond that spot. 7.4.2. Weapon proficiency - You will have varying degrees of skill in the weapons available. + You will have varying degrees of skill in the weapons available. Weapon proficiency, or weapon skills, affect how well you can use par- ticular types of weapons, and you'll be able to improve your skills as - you progress through a game, depending on your role, your experience + you progress through a game, depending on your role, your experience level, and use of the weapons. - For the purposes of proficiency, weapons have been divided up - into various groups such as daggers, broadswords, and polearms. Each - role has a limit on what level of proficiency a character can achieve - for each group. For instance, wizards can become highly skilled in + For the purposes of proficiency, weapons have been divided up + into various groups such as daggers, broadswords, and polearms. Each + role has a limit on what level of proficiency a character can achieve + for each group. For instance, wizards can become highly skilled in daggers or staves but not in swords or bows. The "#enhance" extended command is used to review current weapons - proficiency (also spell proficiency) and to choose which skill(s) to - improve when you've used one or more skills enough to become eligible - to do so. The skill rankings are "none" (sometimes also referred to - as "restricted", because you won't be able to advance), "unskilled", - "basic", "skilled", and "expert". Restricted skills simply will not - appear in the list shown by "#enhance". (Divine intervention might - unrestrict a particular skill, in which case it will start at + proficiency (also spell proficiency) and to choose which skill(s) to + improve when you've used one or more skills enough to become eligible + to do so. The skill rankings are "none" (sometimes also referred to + as "restricted", because you won't be able to advance), "unskilled", + "basic", "skilled", and "expert". Restricted skills simply will not + appear in the list shown by "#enhance". (Divine intervention might + unrestrict a particular skill, in which case it will start at unskilled and be limited to basic.) Some characters can enhance their - barehanded combat or martial arts skill beyond expert to "master" or + barehanded combat or martial arts skill beyond expert to "master" or "grand master". - Use of a weapon in which you're restricted or unskilled will - incur a modest penalty in the chance to hit a monster and also in the - amount of damage done when you do hit; at basic level, there is no - penalty or bonus; at skilled level, you receive a modest bonus in the + Use of a weapon in which you're restricted or unskilled will + incur a modest penalty in the chance to hit a monster and also in the + amount of damage done when you do hit; at basic level, there is no + penalty or bonus; at skilled level, you receive a modest bonus in the chance to hit and amount of damage done; at expert level, the bonus is - higher. A successful hit has a chance to boost your training towards + higher. A successful hit has a chance to boost your training towards the next skill level (unless you've already reached the limit for this skill). Once such training reaches the threshold for that next level, - you'll be told that you feel more confident in your skills. At that - point you can use "#enhance" to increase one or more skills. Such - skills are not increased automatically because there is a limit to + you'll be told that you feel more confident in your skills. At that + point you can use "#enhance" to increase one or more skills. Such + skills are not increased automatically because there is a limit to your total overall skills, so you need to actively choose which skills to enhance and which to ignore. 7.4.3. Two-Weapon combat - Some characters can use two weapons at once. Setting things up - to do so can seem cumbersome but becomes second nature with use. To - wield two weapons, you need to use the "#twoweapon" command. But - first you need to have a weapon in each hand. (Note that your two + Some characters can use two weapons at once. Setting things up + to do so can seem cumbersome but becomes second nature with use. To + wield two weapons, you need to use the "#twoweapon" command. But + first you need to have a weapon in each hand. (Note that your two - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3172,44 +3172,44 @@ - weapons are not fully equal; the one in the hand you normally wield - with is considered primary and the other one is considered secondary. + weapons are not fully equal; the one in the hand you normally wield + with is considered primary and the other one is considered secondary. The most noticeable difference is after you stop--or before you begin, - for that matter--wielding two weapons at once. The primary is your - wielded weapon and the secondary is just an item in your inventory + for that matter--wielding two weapons at once. The primary is your + wielded weapon and the secondary is just an item in your inventory that's been designated as alternate weapon.) - If your primary weapon is wielded but your off hand is empty or - has the wrong weapon, use the sequence `x', `w', `x' to first swap - your primary into your off hand, wield whatever you want as secondary - weapon, then swap them both back into the intended hands. If your - secondary or alternate weapon is correct but your primary one is not, - simply use `w' to wield the primary. Lastly, if neither hand holds + If your primary weapon is wielded but your off hand is empty or + has the wrong weapon, use the sequence `x', `w', `x' to first swap + your primary into your off hand, wield whatever you want as secondary + weapon, then swap them both back into the intended hands. If your + secondary or alternate weapon is correct but your primary one is not, + simply use `w' to wield the primary. Lastly, if neither hand holds the correct weapon, use `w', `x', `w' to first wield the intended sec- ondary, swap it to off hand, and then wield the primary. - The whole process can be simplified via use of the pushweapon - option. When it is enabled, then using `w' to wield something causes - the currently wielded weapon to become your alternate weapon. So the - sequence `w', `w' can be used to first wield the weapon you intend to - be secondary, and then wield the one you want as primary which will + The whole process can be simplified via use of the pushweapon + option. When it is enabled, then using `w' to wield something causes + the currently wielded weapon to become your alternate weapon. So the + sequence `w', `w' can be used to first wield the weapon you intend to + be secondary, and then wield the one you want as primary which will push the first into secondary position. - When in two-weapon combat mode, using the `X' command toggles - back to single-weapon mode. Throwing or dropping either of the weap- - ons or having one of them be stolen or destroyed will also make you + When in two-weapon combat mode, using the `X' command toggles + back to single-weapon mode. Throwing or dropping either of the weap- + ons or having one of them be stolen or destroyed will also make you revert to single-weapon combat. 7.5. Armor (`[') - Lots of unfriendly things lurk about; you need armor to protect - yourself from their blows. Some types of armor offer better protec- - tion than others. Your armor class is a measure of this protection. - Armor class (AC) is measured as in AD&D, with 10 being the equivalent - of no armor, and lower numbers meaning better armor. Each suit of + Lots of unfriendly things lurk about; you need armor to protect + yourself from their blows. Some types of armor offer better protec- + tion than others. Your armor class is a measure of this protection. + Armor class (AC) is measured as in AD&D, with 10 being the equivalent + of no armor, and lower numbers meaning better armor. Each suit of armor which exists in AD&D gives the same protection in NetHack. - Here is a list of the armor class values provided by suits of + Here is a list of the armor class values provided by suits of armor: Dragon scale mail 1 Plate mail, Crystal plate mail 3 @@ -3223,12 +3223,12 @@ Leather jacket 9 none 10 - You can also wear other pieces of armor (cloak over suit, shirt - under suit, helmet, gloves, boots, shield) to lower your armor class + You can also wear other pieces of armor (cloak over suit, shirt + under suit, helmet, gloves, boots, shield) to lower your armor class even further. Most of these provide a one or two point improvement to - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3238,63 +3238,63 @@ - AC (making the overall value smaller and eventually negative) but can - also be enchanted. Shirts are an exception; they don't provide any - protection unless enchanted. Some cloaks also don't improve AC when - unenchanted but all cloaks offer some protection against rust or cor- - rosion to suits worn under them and against some monster touch + AC (making the overall value smaller and eventually negative) but can + also be enchanted. Shirts are an exception; they don't provide any + protection unless enchanted. Some cloaks also don't improve AC when + unenchanted but all cloaks offer some protection against rust or cor- + rosion to suits worn under them and against some monster touch attacks. - If a piece of armor is enchanted, its armor protection will be + If a piece of armor is enchanted, its armor protection will be better (or worse) than normal, and its "plus" (or minus) will subtract - from your armor class. For example, a +1 chain mail would give you - better protection than normal chain mail, lowering your armor class - one unit further to 4. When you put on a piece of armor, you immedi- - ately find out the armor class and any "plusses" it provides. Cursed - pieces of armor usually have negative enchantments (minuses) in addi- + from your armor class. For example, a +1 chain mail would give you + better protection than normal chain mail, lowering your armor class + one unit further to 4. When you put on a piece of armor, you immedi- + ately find out the armor class and any "plusses" it provides. Cursed + pieces of armor usually have negative enchantments (minuses) in addi- tion to being unremovable. Many types of armor are subject to some kind of damage like rust. - Such damage can be repaired. Some types of armor may inhibit spell + Such damage can be repaired. Some types of armor may inhibit spell casting. - The nudist option can be set (prior to game start) to attempt to - play the entire game without wearing any armor (a self-imposed chal- + The nudist option can be set (prior to game start) to attempt to + play the entire game without wearing any armor (a self-imposed chal- lenge which is extremely difficult to accomplish). - Some interfaces support the armorstatus option. When it is + Some interfaces support the armorstatus option. When it is enabled, an extra status condition is displayed, summarizing currently worn armor. The commands to use armor are `W' (wear) and `T' (take off). The `A' command can be used to take off armor as well as other worn items. Also, `P' (put on) and `R' (remove) which are normally for accessories - can be used for armor, but pieces of armor won't be shown as likely + can be used for armor, but pieces of armor won't be shown as likely candidates in a prompt for choosing what to put on or remove. 7.6. Food (`%') - Food is necessary to survive. If you go too long without eating - you will faint, and eventually die of starvation. Some types of food - will spoil, and become unhealthy to eat, if not protected. Food - stored in ice boxes or tins ("cans") will usually stay fresh, but ice + Food is necessary to survive. If you go too long without eating + you will faint, and eventually die of starvation. Some types of food + will spoil, and become unhealthy to eat, if not protected. Food + stored in ice boxes or tins ("cans") will usually stay fresh, but ice boxes are heavy, and tins take a while to open. When you kill monsters, they usually leave corpses which are also - "food." Many, but not all, of these are edible; some also give you - special powers when you eat them. A good rule of thumb is "you are + "food." Many, but not all, of these are edible; some also give you + special powers when you eat them. A good rule of thumb is "you are what you eat." - Some character roles and some monsters are vegetarian. Vegetar- + Some character roles and some monsters are vegetarian. Vegetar- ian monsters will typically never eat animal corpses, while vegetarian players can, but with some rather unpleasant side-effects. - You can name one food item after something you like to eat with + You can name one food item after something you like to eat with the fruit option. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3308,33 +3308,33 @@ 7.7. Scrolls (`?') - Scrolls are labeled with various titles, probably chosen by - ancient wizards for their amusement value (for example "READ ME," or - "THANX MAUD" backwards). Scrolls disappear after you read them + Scrolls are labeled with various titles, probably chosen by + ancient wizards for their amusement value (for example "READ ME," or + "THANX MAUD" backwards). Scrolls disappear after you read them (except for blank ones, without magic spells on them). - One of the most useful of these is the scroll of identify, which - can be used to determine what another object is, whether it is cursed - or blessed, and how many uses it has left. Some objects of subtle + One of the most useful of these is the scroll of identify, which + can be used to determine what another object is, whether it is cursed + or blessed, and how many uses it has left. Some objects of subtle enchantment are difficult to identify without these. - A scroll whose label is known can be read even when the hero is - blind. If a scroll has been discovered, it will be listed in inven- + A scroll whose label is known can be read even when the hero is + blind. If a scroll has been discovered, it will be listed in inven- tory by type rather than by label, but the label is known in that sit- uation even though it isn't shown. - Many scrolls produce a different effect from usual if they are + Many scrolls produce a different effect from usual if they are blessed or cursed, or read while the hero is confused. - A mail daemon may run up and deliver mail to you as a scroll of + A mail daemon may run up and deliver mail to you as a scroll of mail (on versions compiled with this feature). To use this feature on - versions where NetHack mail delivery is triggered by electronic mail - appearing in your system mailbox, you must let NetHack know where to - look for new mail by setting the "MAIL" environment variable to the - file name of your mailbox. You may also want to set the "MAILREADER" - environment variable to the file name of your favorite reader, so - NetHack can shell to it when you read the scroll. On versions of - NetHack where mail is randomly generated internal to the game, these + versions where NetHack mail delivery is triggered by electronic mail + appearing in your system mailbox, you must let NetHack know where to + look for new mail by setting the "MAIL" environment variable to the + file name of your mailbox. You may also want to set the "MAILREADER" + environment variable to the file name of your favorite reader, so + NetHack can shell to it when you read the scroll. On versions of + NetHack where mail is randomly generated internal to the game, these environment variables are ignored. You can disable the mail daemon by turning off the mail option. @@ -3342,13 +3342,13 @@ 7.8. Potions (`!') - Potions are distinguished by the color of the liquid inside the + Potions are distinguished by the color of the liquid inside the flask. They disappear after you quaff them. - Clear potions are potions of water. Sometimes these are blessed - or cursed, resulting in holy or unholy water. Holy water is the bane + Clear potions are potions of water. Sometimes these are blessed + or cursed, resulting in holy or unholy water. Holy water is the bane of the undead, so potions of holy water are good things to throw (`t') - at them. It is also sometimes very useful to dip ("#dip") an object + at them. It is also sometimes very useful to dip ("#dip") an object into a potion. The command to drink a potion is `q' (quaff). @@ -3356,11 +3356,11 @@ 7.9. Wands (`/') Wands usually have multiple magical charges. Some types of wands - require a direction in which to zap them. You can also zap them at - yourself (just give a `.' or `s' for the direction). Be warned, how- + require a direction in which to zap them. You can also zap them at + yourself (just give a `.' or `s' for the direction). Be warned, how- - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3370,63 +3370,63 @@ - ever, for this is often unwise. Other types of wands don't require a + ever, for this is often unwise. Other types of wands don't require a direction. The number of charges in a wand is random and decreases by one whenever you use it. - When the number of charges left in a wand becomes zero, attempts - to use the wand will usually result in nothing happening. Occasion- - ally, however, it may be possible to squeeze the last few mana points - from an otherwise spent wand, destroying it in the process. A wand - may be recharged by using suitable magic, but doing so runs the risk + When the number of charges left in a wand becomes zero, attempts + to use the wand will usually result in nothing happening. Occasion- + ally, however, it may be possible to squeeze the last few mana points + from an otherwise spent wand, destroying it in the process. A wand + may be recharged by using suitable magic, but doing so runs the risk of causing it to explode. The chance for such an explosion starts out very small and increases each time the wand is recharged. - In a truly desperate situation, when your back is up against the - wall, you might decide to go for broke and break your wand. This is - not for the faint of heart. Doing so will almost certainly cause a + In a truly desperate situation, when your back is up against the + wall, you might decide to go for broke and break your wand. This is + not for the faint of heart. Doing so will almost certainly cause a catastrophic release of magical energies. - When you have fully identified a particular wand, inventory dis- + When you have fully identified a particular wand, inventory dis- play will include additional information in parentheses: the number of - times it has been recharged followed by a colon and then by its cur- - rent number of charges. A current charge count of -1 is a special + times it has been recharged followed by a colon and then by its cur- + rent number of charges. A current charge count of -1 is a special case indicating that the wand has been cancelled. - The command to use a wand is `z' (zap). To break one, use the + The command to use a wand is `z' (zap). To break one, use the `a' (apply) command. 7.10. Rings (`=') - Rings are very useful items, since they are relatively permanent - magic, unlike the usually fleeting effects of potions, scrolls, and + Rings are very useful items, since they are relatively permanent + magic, unlike the usually fleeting effects of potions, scrolls, and wands. - Putting on a ring activates its magic. You can wear at most two + Putting on a ring activates its magic. You can wear at most two rings at any time, one on the ring finger of each hand. - Most worn rings also cause you to grow hungry more rapidly, the + Most worn rings also cause you to grow hungry more rapidly, the rate varying with the type of ring. - When wearing gloves, rings are worn underneath. If the gloves - are cursed, rings cannot be put on and any already being worn cannot - be removed. When worn gloves aren't cursed, you don't have to manu- - ally take them off before putting on or removing a ring and then re- + When wearing gloves, rings are worn underneath. If the gloves + are cursed, rings cannot be put on and any already being worn cannot + be removed. When worn gloves aren't cursed, you don't have to manu- + ally take them off before putting on or removing a ring and then re- wear them after. That's done implicitly to avoid unnecessary tedium. - The commands to use rings are `P' (put on) and `R' (remove). + The commands to use rings are `P' (put on) and `R' (remove). `A', `W', and `T' can also be used; see Amulets. 7.11. Spellbooks (`+') - Spellbooks are tomes of mighty magic. When studied with the `r' - (read) command, they transfer to the reader the knowledge of a spell + Spellbooks are tomes of mighty magic. When studied with the `r' + (read) command, they transfer to the reader the knowledge of a spell (and therefore eventually become unreadable)--unless the attempt back- - fires. Reading a cursed spellbook or one with mystic runes beyond + fires. Reading a cursed spellbook or one with mystic runes beyond your ken can be harmful to your health! - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3436,63 +3436,63 @@ - A spell (even when learned) can also backfire when you cast it. + A spell (even when learned) can also backfire when you cast it. If you attempt to cast a spell well above your experience level, or if you have little skill with the appropriate spell type, or cast it at a - time when your luck is particularly bad, you can end up wasting both + time when your luck is particularly bad, you can end up wasting both the energy and the time required in casting. - Casting a spell calls forth magical energies and focuses them - with your naked mind. Some of the magical energy released comes from + Casting a spell calls forth magical energies and focuses them + with your naked mind. Some of the magical energy released comes from within you. Casting temporarily drains your magical power, which will - slowly be recovered, and causes you to need additional food. Casting - of spells also requires practice. With practice, your skill in each + slowly be recovered, and causes you to need additional food. Casting + of spells also requires practice. With practice, your skill in each category of spell casting will improve. Over time, however, your mem- ory of each spell will dim, and you will need to relearn it. Some spells require a direction in which to cast them, similar to wands. To cast one at yourself, just give a `.' or `s' for the direc- - tion. A few spells require you to pick a target location rather than - just specify a particular direction. Other spells don't require any + tion. A few spells require you to pick a target location rather than + just specify a particular direction. Other spells don't require any direction or target. - Just as weapons are divided into groups in which a character can - become proficient (to varying degrees), spells are similarly grouped. - Successfully casting a spell exercises its skill group; using the - "#enhance" command to advance a sufficiently exercised skill will - affect all spells within the group. Advanced skill may increase the - potency of spells, reduce their risk of failure during casting + Just as weapons are divided into groups in which a character can + become proficient (to varying degrees), spells are similarly grouped. + Successfully casting a spell exercises its skill group; using the + "#enhance" command to advance a sufficiently exercised skill will + affect all spells within the group. Advanced skill may increase the + potency of spells, reduce their risk of failure during casting attempts, and improve the accuracy of the estimate for how much longer - they will be retained in your memory. Skill slots are shared with + they will be retained in your memory. Skill slots are shared with weapons skills. (See also the section on "Weapon proficiency".) Casting a spell also requires flexible movement, and wearing var- ious types of armor may interfere with that. - The command to read a spellbook is the same as for scrolls, `r' - (read). The `+' command lists each spell you know along with its + The command to read a spellbook is the same as for scrolls, `r' + (read). The `+' command lists each spell you know along with its level, skill category, chance of failure when casting, and an estimate - of how strongly it is remembered. The `Z' (cast) command casts a + of how strongly it is remembered. The `Z' (cast) command casts a spell. 7.12. Tools (`(') - Tools are miscellaneous objects with various purposes. Some - tools have a limited number of uses, akin to wand charges. For exam- - ple, lamps burn out after a while. Other tools are containers, which + Tools are miscellaneous objects with various purposes. Some + tools have a limited number of uses, akin to wand charges. For exam- + ple, lamps burn out after a while. Other tools are containers, which objects can be placed into or taken out of. - Some tools (such as a blindfold) can be worn and can be put on - and removed like other accessories (rings, amulets); see Amulets. - Other tools (such as pick-axe) can be wielded as weapons in addition - to being applied for their usual purpose, and in some cases (again, + Some tools (such as a blindfold) can be worn and can be put on + and removed like other accessories (rings, amulets); see Amulets. + Other tools (such as pick-axe) can be wielded as weapons in addition + to being applied for their usual purpose, and in some cases (again, pick-axe) become wielded as a weapon even when applied. - The blind option can be set (prior to game start) to attempt to - play the entire game without being able to see (a self-imposed chal- + The blind option can be set (prior to game start) to attempt to + play the entire game without being able to see (a self-imposed chal- - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3508,57 +3508,57 @@ 7.12.1. Containers - You may encounter bags, boxes, and chests in your travels. A + You may encounter bags, boxes, and chests in your travels. A tool of this sort can be opened with the "#loot" extended command when - you are standing on top of it (that is, on the same floor spot), or - with the `a' (apply) command when you are carrying it. However, - chests are often locked, and are in any case unwieldy objects. You - must set one down before unlocking it by using a key or lock-picking - tool with the `a' (apply) command, by kicking it with the `^D' com- - mand, or by using a weapon to force the lock with the "#force" + you are standing on top of it (that is, on the same floor spot), or + with the `a' (apply) command when you are carrying it. However, + chests are often locked, and are in any case unwieldy objects. You + must set one down before unlocking it by using a key or lock-picking + tool with the `a' (apply) command, by kicking it with the `^D' com- + mand, or by using a weapon to force the lock with the "#force" extended command. - Some chests are trapped, causing nasty things to happen when you - unlock or open them. You can check for and try to deactivate traps + Some chests are trapped, causing nasty things to happen when you + unlock or open them. You can check for and try to deactivate traps with the "#untrap" extended command. - When the contents of a container are known, that container will - be described as something like "a sack containing 3 items". In this - example, the 3 refers to number of stacks of compatible items, not to - the total number of individual items. So a sack holding 2 sky blue - potions, 7 arrows, and 350 gold pieces would be described as having 3 - items rather than 10 or 359. And you would need to have 3 unused - inventory slots available in order to take everything out (for the - case where the items you remove don't combine into bigger stacks with + When the contents of a container are known, that container will + be described as something like "a sack containing 3 items". In this + example, the 3 refers to number of stacks of compatible items, not to + the total number of individual items. So a sack holding 2 sky blue + potions, 7 arrows, and 350 gold pieces would be described as having 3 + items rather than 10 or 359. And you would need to have 3 unused + inventory slots available in order to take everything out (for the + case where the items you remove don't combine into bigger stacks with things you're already carrying). If a chest or large box is described as "broken", that means that - it can't be locked rather than that it no longer functions as a con- + it can't be locked rather than that it no longer functions as a con- tainer. - The apply and loot commands allow you to take out and/or put in - an arbitrary number of items in a single operation. If you want to - take everything out of a container, you can use the "#tip" command to - pour the contents onto the floor. This may be your only way to get - things out if your hands are stuck to a cursed two-handed weapon. - When your hands aren't stuck, you have the potential to pour the con- - tents into another container. (As of this writing, the other con- + The apply and loot commands allow you to take out and/or put in + an arbitrary number of items in a single operation. If you want to + take everything out of a container, you can use the "#tip" command to + pour the contents onto the floor. This may be your only way to get + things out if your hands are stuck to a cursed two-handed weapon. + When your hands aren't stuck, you have the potential to pour the con- + tents into another container. (As of this writing, the other con- tainer must be carried rather than on the floor.) 7.13. Amulets (`"') Amulets are very similar to rings, and often more powerful. Like - rings, amulets have various magical properties, some beneficial, some + rings, amulets have various magical properties, some beneficial, some harmful, which are activated by putting them on. - Only one amulet may be worn at a time, around your neck. Like - wearing rings, wearing an amulet affects your metabolism, causing you + Only one amulet may be worn at a time, around your neck. Like + wearing rings, wearing an amulet affects your metabolism, causing you to grow hungry more rapidly. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3568,63 +3568,63 @@ - The commands to use amulets are the same as for rings, `P' (put - on) and `R' (remove). `A' can be used to remove various worn items + The commands to use amulets are the same as for rings, `P' (put + on) and `R' (remove). `A' can be used to remove various worn items including amulets. Also, `W' (wear) and `T' (take off) which are nor- - mally for armor can be used for amulets and other accessories (rings + mally for armor can be used for amulets and other accessories (rings and eyewear), but accessories won't be shown as likely candidates in a prompt for choosing what to wear or take off. 7.14. Gems (`*') - Some gems are valuable, and can be sold for a lot of gold. They - are also a far more efficient way of carrying your riches. Valuable + Some gems are valuable, and can be sold for a lot of gold. They + are also a far more efficient way of carrying your riches. Valuable gems increase your score if you bring them with you when you exit. Other small rocks are also categorized as gems, but they are much - less valuable. All rocks, however, can be used as projectile weapons - (if you have a sling). In the most desperate of cases, you can still + less valuable. All rocks, however, can be used as projectile weapons + (if you have a sling). In the most desperate of cases, you can still throw them by hand. 7.15. Large rocks (``') - Statues and boulders are not particularly useful, and are gener- + Statues and boulders are not particularly useful, and are gener- ally heavy. It is rumored that some statues are not what they seem. - Boulders occasionally block your path. You can push one forward + Boulders occasionally block your path. You can push one forward (by attempting to walk onto its spot) when nothing blocks its path, or - you can smash it into a pile of small rocks with breaking magic or a + you can smash it into a pile of small rocks with breaking magic or a pick-axe. It is possible to move onto a boulder's location if certain conditions are met; ordinarily one of those conditions is that pushing - it any further be blocked. Using the move-without-picking-up prefix - (default key `m') prior to the direction of movement will attempt to - move to a boulder's location without pushing it in addition to the + it any further be blocked. Using the move-without-picking-up prefix + (default key `m') prior to the direction of movement will attempt to + move to a boulder's location without pushing it in addition to the prefix's usual action of suppressing auto-pickup at the destination. - Very large humanoids (giants and their ilk) have been known to + Very large humanoids (giants and their ilk) have been known to pick up boulders and use them as missile weapons. - Unlike boulders, statues can't be pushed, but don't need to be - because they don't block movement. They can be smashed into rocks + Unlike boulders, statues can't be pushed, but don't need to be + because they don't block movement. They can be smashed into rocks though. - For some configurations of the program, statues are no longer - shown as ``' but by the letter representing the monster they depict + For some configurations of the program, statues are no longer + shown as ``' but by the letter representing the monster they depict instead. 7.16. Gold (`$') Gold adds to your score, and you can buy things in shops with it. - There are a number of monsters in the dungeon that may be influenced + There are a number of monsters in the dungeon that may be influenced by the amount of gold you are carrying (shopkeepers aside). - Gold pieces are the only type of object where bless/curse state - does not apply. They're always uncursed but never described as - uncursed even if you turn off the implicit_uncursed option. You can - set the goldX option if you prefer to have gold pieces be treated as + Gold pieces are the only type of object where bless/curse state + does not apply. They're always uncursed but never described as + uncursed even if you turn off the implicit_uncursed option. You can + set the goldX option if you prefer to have gold pieces be treated as - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3634,63 +3634,63 @@ - bless/curse state unknown rather than as known to be uncursed. Only - matters when you're using an object selection prompt that can filter + bless/curse state unknown rather than as known to be uncursed. Only + matters when you're using an object selection prompt that can filter by "BUCX" state. 7.17. Persistence of Objects Normally, if you have seen an object at a particular map location - and move to another location where you can't directly see that object - any more, it will continue to be displayed on your map. That remains - the case even if it is not actually there any more--perhaps a monster + and move to another location where you can't directly see that object + any more, it will continue to be displayed on your map. That remains + the case even if it is not actually there any more--perhaps a monster has picked it up or it has rotted away--until you can see or feel that location again. One notable exception is that if the object gets cov- - ered by the "remembered, unseen monster" marker. When that marker is + ered by the "remembered, unseen monster" marker. When that marker is later removed after you've verified that no monster is there, you will - have forgotten that there was any object there regardless of whether - the unseen monster actually took the object. If the object is still - there, then once you see or feel that location again you will re-dis- + have forgotten that there was any object there regardless of whether + the unseen monster actually took the object. If the object is still + there, then once you see or feel that location again you will re-dis- cover the object and resume remembering it. The situation is the same for a pile of objects, except that only - the top item of the pile is displayed. The hilite_pile option can be + the top item of the pile is displayed. The hilite_pile option can be enabled in order to show an item differently when it is the top one of a pile. 8. Conduct - As if winning NetHack were not difficult enough, certain players - seek to challenge themselves by imposing restrictions on the way they - play the game. The game automatically tracks some of these chal- - lenges, which can be checked at any time with the #conduct command or - at the end of the game. When you perform an action which breaks a - challenge, it will no longer be listed. This gives players extra - "bragging rights" for winning the game with these challenges. Note - that it is perfectly acceptable to win the game without resorting to - these restrictions and that it is unusual for players to adhere to + As if winning NetHack were not difficult enough, certain players + seek to challenge themselves by imposing restrictions on the way they + play the game. The game automatically tracks some of these chal- + lenges, which can be checked at any time with the #conduct command or + at the end of the game. When you perform an action which breaks a + challenge, it will no longer be listed. This gives players extra + "bragging rights" for winning the game with these challenges. Note + that it is perfectly acceptable to win the game without resorting to + these restrictions and that it is unusual for players to adhere to challenges the first time they win the game. - Several of the challenges are related to eating behavior. The + Several of the challenges are related to eating behavior. The most difficult of these is the foodless challenge. Although creatures - can survive long periods of time without food, there is a physiologi- - cal need for water; thus there is no restriction on drinking bever- - ages, even if they provide some minor food benefits. Calling upon + can survive long periods of time without food, there is a physiologi- + cal need for water; thus there is no restriction on drinking bever- + ages, even if they provide some minor food benefits. Calling upon your god for help with starvation does not violate any food challenges either. - A strict vegan diet is one which avoids any food derived from - animals. The primary source of nutrition is fruits and vegetables. - The corpses and tins of blobs (`b'), jellies (`j'), and fungi (`F') - are also considered to be vegetable matter. Certain human food is + A strict vegan diet is one which avoids any food derived from + animals. The primary source of nutrition is fruits and vegetables. + The corpses and tins of blobs (`b'), jellies (`j'), and fungi (`F') + are also considered to be vegetable matter. Certain human food is prepared without animal products; namely, lembas wafers, cram rations, - food rations (gunyoki), K-rations, and C-rations. Metal or another + food rations (gunyoki), K-rations, and C-rations. Metal or another normally indigestible material eaten while polymorphed into a creature - that can digest it is also considered vegan food. Note however that + that can digest it is also considered vegan food. Note however that eating such items still counts against foodless conduct. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3700,63 +3700,63 @@ - Vegetarians do not eat animals; however, they are less selective - about eating animal byproducts than vegans. In addition to the vegan - items listed above, they may eat any kind of pudding (`P') other than - the black puddings, eggs and food made from eggs (fortune cookies and - pancakes), food made with milk (cream pies and candy bars), and lumps + Vegetarians do not eat animals; however, they are less selective + about eating animal byproducts than vegans. In addition to the vegan + items listed above, they may eat any kind of pudding (`P') other than + the black puddings, eggs and food made from eggs (fortune cookies and + pancakes), food made with milk (cream pies and candy bars), and lumps of royal jelly. Monks are expected to observe a vegetarian diet. Eating any kind of meat violates the vegetarian, vegan, and food- - less conducts. This includes tripe rations, the corpses or tins of + less conducts. This includes tripe rations, the corpses or tins of any monsters not mentioned above, and the various other chunks of meat - found in the dungeon. Swallowing and digesting a monster while poly- - morphed is treated as if you ate the creature's corpse. Eating - leather, dragon hide, or bone items while polymorphed into a creature - that can digest it, or eating monster brains while polymorphed into a - mind flayer, is considered eating an animal, although wax is only an + found in the dungeon. Swallowing and digesting a monster while poly- + morphed is treated as if you ate the creature's corpse. Eating + leather, dragon hide, or bone items while polymorphed into a creature + that can digest it, or eating monster brains while polymorphed into a + mind flayer, is considered eating an animal, although wax is only an animal byproduct. - Regardless of conduct, there will be some items which are indi- + Regardless of conduct, there will be some items which are indi- gestible, and others which are hazardous to eat. Using a swallow-and- - digest attack against a monster is equivalent to eating the monster's - corpse. Please note that the term "vegan" is used here only in the - context of diet. You are still free to choose not to use or wear - items derived from animals (e.g. leather, dragon hide, bone, horns, - coral), but the game will not keep track of this for you. Also note - that "milky" potions may be a translucent white, but they do not con- - tain milk, so they are compatible with a vegan diet. Slime molds or - player-defined "fruits", although they could be anything from "cher- + digest attack against a monster is equivalent to eating the monster's + corpse. Please note that the term "vegan" is used here only in the + context of diet. You are still free to choose not to use or wear + items derived from animals (e.g. leather, dragon hide, bone, horns, + coral), but the game will not keep track of this for you. Also note + that "milky" potions may be a translucent white, but they do not con- + tain milk, so they are compatible with a vegan diet. Slime molds or + player-defined "fruits", although they could be anything from "cher- ries" to "pork chops", are also assumed to be vegan. An atheist is one who rejects religion. This means that you can- not #pray, #offer sacrifices to any god, #turn undead, or #chat with a priest. Particularly selective readers may argue that playing Monk or - Priest characters should violate this conduct; that is a choice left + Priest characters should violate this conduct; that is a choice left to the player. Offering the Amulet of Yendor to your god is necessary to win the game and is not counted against this conduct. You are also - not penalized for being spoken to by an angry god, priest(ess), or + not penalized for being spoken to by an angry god, priest(ess), or other religious figure; a true atheist would hear the words but attach no special meaning to them. - A pauper starts the game with no possessions, no spells, and no + A pauper starts the game with no possessions, no spells, and no weapon or spell skills (and if playing as a knight, your pony will not - have a saddle). Can only be initiated by starting a new game with - OPTIONS=pauper set in your run-time configurtion file or NETHACKOP- - TIONS environment variable. Once the game is underway, you can + have a saddle). Can only be initiated by starting a new game with + OPTIONS=pauper set in your run-time configurtion file or NETHACKOP- + TIONS environment variable. Once the game is underway, you can acquire and use items, spells, and skills in the usual way. - Most players fight with a wielded weapon (or tool intended to be - wielded as a weapon). Another challenge is to win the game without - using such a wielded weapon. You are still permitted to throw, fire, - and kick weapons; use a wand, spell, or other type of item; or fight + Most players fight with a wielded weapon (or tool intended to be + wielded as a weapon). Another challenge is to win the game without + using such a wielded weapon. You are still permitted to throw, fire, + and kick weapons; use a wand, spell, or other type of item; or fight with your hands and feet. - In NetHack, a pacifist refuses to cause the death of any other - monster (i.e. if you would get experience for the death). This is a + In NetHack, a pacifist refuses to cause the death of any other + monster (i.e. if you would get experience for the death). This is a - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3766,55 +3766,55 @@ - particularly difficult challenge, although it is still possible to + particularly difficult challenge, although it is still possible to gain experience by other means. - An illiterate character does not read or write. This includes + An illiterate character does not read or write. This includes reading a scroll, spellbook, fortune cookie message, or t-shirt; writ- - ing a scroll; or making an engraving of anything other than a single - "X" (the traditional signature of an illiterate person). Reading an - engraving, or any item that is absolutely necessary to win the game, - is not counted against this conduct. The identity of scrolls and - spellbooks (and knowledge of spells) in your starting inventory is - assumed to be learned from your teachers prior to the start of the + ing a scroll; or making an engraving of anything other than a single + "X" (the traditional signature of an illiterate person). Reading an + engraving, or any item that is absolutely necessary to win the game, + is not counted against this conduct. The identity of scrolls and + spellbooks (and knowledge of spells) in your starting inventory is + assumed to be learned from your teachers prior to the start of the game and isn't counted. - There is a side-branch to the main dungeon called "Sokoban," - briefly described in the earlier section about Traps. As mentioned - there, the goal is to push boulders into pits and/or holes to plug - those in order to both get the boulders out of the way and be able to - go past the traps. There are some special "rules" that are active - when in that branch of the dungeon. Some rules can't be bypassed, - such as being unable to push a boulder diagonally. Other rules can, + There is a side-branch to the main dungeon called "Sokoban," + briefly described in the earlier section about Traps. As mentioned + there, the goal is to push boulders into pits and/or holes to plug + those in order to both get the boulders out of the way and be able to + go past the traps. There are some special "rules" that are active + when in that branch of the dungeon. Some rules can't be bypassed, + such as being unable to push a boulder diagonally. Other rules can, such as not smashing boulders with magic or tools, but doing so causes - you to receive a luck penalty. No message about that is given at the + you to receive a luck penalty. No message about that is given at the time, but it is tracked as a conduct. The #conduct command and end of - game disclosure will report whether you have abided by the special - rules of Sokoban, and if not, how many times you violated them, pro- + game disclosure will report whether you have abided by the special + rules of Sokoban, and if not, how many times you violated them, pro- viding you with a way to discover which actions incur bad luck so that - you can be better informed about whether or not to avoid repeating + you can be better informed about whether or not to avoid repeating those actions in the future. (Note: the Sokoban conduct will only be displayed if you have entered the Sokoban branch of the dungeon during - the current game. Once that has happened, it becomes part of dis- - closed conduct even if you haven't done anything interesting there. - Ending the game with "never broke the Sokoban rules" conduct is most - meaningful if you also manage to perform the "obtained the Sokoban + the current game. Once that has happened, it becomes part of dis- + closed conduct even if you haven't done anything interesting there. + Ending the game with "never broke the Sokoban rules" conduct is most + meaningful if you also manage to perform the "obtained the Sokoban prize" achievement (see Achievements below).) - There are several other challenges tracked by the game. It is - possible to eliminate one or more species of monsters by genocide; + There are several other challenges tracked by the game. It is + possible to eliminate one or more species of monsters by genocide; playing without this feature is considered a challenge. When the game - offers you an opportunity to genocide monsters, you may respond with - the monster type "none" if you want to decline. You can change the - form of an item into another item of the same type ("polypiling") or - the form of your own body into another creature ("polyself") by wand, + offers you an opportunity to genocide monsters, you may respond with + the monster type "none" if you want to decline. You can change the + form of an item into another item of the same type ("polypiling") or + the form of your own body into another creature ("polyself") by wand, spell, or potion of polymorph; avoiding these effects are each consid- - ered challenges. Polymorphing monsters, including pets, does not - break either of these challenges. Finally, you may sometimes receive - wishes; a game without an attempt to wish for any items is a chal- + ered challenges. Polymorphing monsters, including pets, does not + break either of these challenges. Finally, you may sometimes receive + wishes; a game without an attempt to wish for any items is a chal- lenge, as is a game without wishing for an artifact (even if the arti- fact immediately disappears). When the game offers you an opportunity - to make a wish for an item, you may choose "nothing" if you want to + to make a wish for an item, you may choose "nothing" if you want to decline. @@ -3822,7 +3822,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3834,12 +3834,12 @@ 8.1. Achievements - End of game disclosure will also display various achievements - representing progress toward ultimate ascension, if any have been - attained. They aren't directly related to conduct but are grouped - with it because they fall into the same category of "bragging rights" - and to limit the number of questions during disclosure. Listed here - roughly in order of difficulty and not necessarily in the order in + End of game disclosure will also display various achievements + representing progress toward ultimate ascension, if any have been + attained. They aren't directly related to conduct but are grouped + with it because they fall into the same category of "bragging rights" + and to limit the number of questions during disclosure. Listed here + roughly in order of difficulty and not necessarily in the order in which you might accomplish them. Rank - Attained rank title Rank. @@ -3851,12 +3851,12 @@ Novel - Read a passage from a Discworld Novel. Sokoban - Entered Sokoban. Big Room - Entered the Big Room. - Soko-Prize - Explored to the top of Sokoban and found a + Soko-Prize - Explored to the top of Sokoban and found a special item there. - Mines' End - Explored to the bottom of the Gnomish Mines + Mines' End - Explored to the bottom of the Gnomish Mines and found a special item there. Medusa - Defeated Medusa. - Tune - Discovered the tune that can be used to open + Tune - Discovered the tune that can be used to open and close the drawbridge on the Castle level. Bell - Acquired the Bell of Opening. Gehennom - Entered Gehennom. @@ -3876,19 +3876,19 @@ Notes: - Achievements are recorded and subsequently reported in the order - in which they happen during your current game rather than the order + Achievements are recorded and subsequently reported in the order + in which they happen during your current game rather than the order listed here. - There are nine titles for each role, bestowed at experi- - ence levels 1, 3, 6, 10, 14, 18, 22, 26, and 30. The one for experi- - ence level 1 is not recorded as an achievement. Losing enough levels + There are nine titles for each role, bestowed at experi- + ence levels 1, 3, 6, 10, 14, 18, 22, 26, and 30. The one for experi- + ence level 1 is not recorded as an achievement. Losing enough levels to revert to lower rank(s) does not discard the corresponding achieve- ment(s). - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3898,63 +3898,63 @@ - There's no guaranteed Novel so the achievement to read one might - not always be attainable (except perhaps by wishing). Similarly, the - Big Room level is not always present. Unlike with the Novel, there's + There's no guaranteed Novel so the achievement to read one might + not always be attainable (except perhaps by wishing). Similarly, the + Big Room level is not always present. Unlike with the Novel, there's no way to wish for this opportunity. - The "special items" hidden in Mines' End and Sokoban are not - unique but are considered to be prizes or rewards for exploring those - levels since doing so is not necessary to complete the game. Finding - other instances of the same objects doesn't record the corresponding + The "special items" hidden in Mines' End and Sokoban are not + unique but are considered to be prizes or rewards for exploring those + levels since doing so is not necessary to complete the game. Finding + other instances of the same objects doesn't record the corresponding achievement. - The Medusa achievement is recorded if she dies for any reason, + The Medusa achievement is recorded if she dies for any reason, even if you are not directly responsible, and only if she dies. The 5-note tune can be learned via trial and error with a musical - instrument played closely enough--but not too close!--to the Castle + instrument played closely enough--but not too close!--to the Castle level's drawbridge or can be given to you via prayer boon. - Blind, Deaf, Nudist, and Pauper are also conducts, and they can - only be enabled by setting the correspondingly named option in + Blind, Deaf, Nudist, and Pauper are also conducts, and they can + only be enabled by setting the correspondingly named option in NETHACKOPTIONS or run-time configuration file prior to game start. In - the case of Blind and Deaf, the option also enforces the conduct. - They aren't really significant accomplishments unless/until you make + the case of Blind and Deaf, the option also enforces the conduct. + They aren't really significant accomplishments unless/until you make substantial progress into the dungeon. 9. Options - Due to variations in personal tastes and conceptions of how - NetHack should do things, there are options you can set to change how + Due to variations in personal tastes and conceptions of how + NetHack should do things, there are options you can set to change how NetHack behaves. 9.1. Setting the options Options may be set in a number of ways. Within the game, the `O' - command allows you to view all options and change most of them. You - can also set options automatically by placing them in a configuration + command allows you to view all options and change most of them. You + can also set options automatically by placing them in a configuration file, or in the NETHACKOPTIONS environment variable. Some versions of - NetHack also have front-end programs that allow you to set options + NetHack also have front-end programs that allow you to set options before starting the game or a global configuration for system adminis- trators. 9.2. Using a configuration file - The default name of the configuration file varies on different + The default name of the configuration file varies on different operating systems. - On UNIX, Linux, and macOS it is ".nethackrc" in the user's home + On UNIX, Linux, and macOS it is ".nethackrc" in the user's home directory. The file may not exist, but it is a normal ASCII text file and can be created with any text editor. - On Windows, the name is ".nethackrc" located in the folder - "%USERPROFILE%\NetHack\". The file may not exist, but it is a normal - ASCII text file can can be created with any text editor. After run- - ning NetHack for the first time, you should find a default template + On Windows, the name is ".nethackrc" located in the folder + "%USERPROFILE%\NetHack\". The file may not exist, but it is a normal + ASCII text file can can be created with any text editor. After run- + ning NetHack for the first time, you should find a default template - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -3964,40 +3964,40 @@ - for the configuration file named ".nethackrc.template" in - "%USERPROFILE%\NetHack\". If you have not created the configuration + for the configuration file named ".nethackrc.template" in + "%USERPROFILE%\NetHack\". If you have not created the configuration file, NetHack will create one for you using the default template file. On MS-DOS, it is "defaults.nh" in the same folder as nethack.exe. - Any line in the configuration file starting with `#' is treated + Any line in the configuration file starting with `#' is treated as a comment and ignored. Empty lines are ignored. Any line beginning with `[' and ending in `]' is a section marker - (the closing `]' can be followed by whitespace and then an arbitrary - comment beginning with `#'). The text between the square brackets is - the section name. Section markers are only valid after a CHOOSE + (the closing `]' can be followed by whitespace and then an arbitrary + comment beginning with `#'). The text between the square brackets is + the section name. Section markers are only valid after a CHOOSE directive and their names are case-insensitive. Lines after a section - marker belong to that section up until another section starts or a - marker without a name is encountered or the file ends. Lines within - sections are ignored unless a CHOOSE directive has selected that sec- + marker belong to that section up until another section starts or a + marker without a name is encountered or the file ends. Lines within + sections are ignored unless a CHOOSE directive has selected that sec- tion. - You can use different configuration directives in the file, some - of which can be used multiple times. In general, the directives are - written in capital letters, followed by an equals sign, followed by + You can use different configuration directives in the file, some + of which can be used multiple times. In general, the directives are + written in capital letters, followed by an equals sign, followed by settings particular to that directive. Here is a list of allowed directives: OPTIONS There are two types of options, boolean and compound options. Bool- - ean options toggle a setting on or off, while compound options take - more diverse values. Prefix a boolean option with "no" or `!' to - turn it off. For compound options, the option name and value are - separated by a colon. Some options are persistent, and apply only + ean options toggle a setting on or off, while compound options take + more diverse values. Prefix a boolean option with "no" or `!' to + turn it off. For compound options, the option name and value are + separated by a colon. Some options are persistent, and apply only to new games. You can specify multiple OPTIONS directives, and mul- - tiple options separated by commas in a single OPTIONS directive. + tiple options separated by commas in a single OPTIONS directive. (Comma separated options are processed from right to left.) Example: @@ -4007,20 +4007,20 @@ HACKDIR Default location of files NetHack needs. On Windows HACKDIR defaults - to the location of the NetHack.exe or NetHackw.exe file so setting + to the location of the NetHack.exe or NetHackw.exe file so setting HACKDIR to override that is not usually necessary or recommended. LEVELDIR - The location that in-progress level files are stored. Defaults to + The location that in-progress level files are stored. Defaults to HACKDIR, must be writable. SAVEDIR - The location where saved games are kept. Defaults to HACKDIR, must + The location where saved games are kept. Defaults to HACKDIR, must be writable. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4039,13 +4039,13 @@ HACKDIR, must be writable. TROUBLEDIR - The location that a record of game aborts and self-diagnosed game + The location that a record of game aborts and self-diagnosed game problems is kept. Defaults to HACKDIR, must be writable. AUTOCOMPLETE - Enable or disable an extended command autocompletion. Autocomple- + Enable or disable an extended command autocompletion. Autocomple- tion has no effect for the X11 windowport. You can specify multiple - autocompletions. To enable autocompletion, list the extended com- + autocompletions. To enable autocompletion, list the extended com- mand. Prefix the command with "!" to disable the autocompletion for that command. @@ -4054,13 +4054,13 @@ AUTOCOMPLETE=zap,!annotate AUTOPICKUP_EXCEPTION - Set exceptions to the pickup_types option. See the "Configuring + Set exceptions to the pickup_types option. See the "Configuring Autopickup Exceptions" section. BINDINGS - Change the key bindings of some special keys, menu accelerators, + Change the key bindings of some special keys, menu accelerators, extended commands, or mouse buttons. You can specify multiple bind- - ings. Format is key followed by the command, separated by a colon. + ings. Format is key followed by the command, separated by a colon. See the "Changing Key Bindings" section for more information. Example: @@ -4083,10 +4083,10 @@ OPTIONS=!rest_on_space If [] is present, the preceding section is closed and no new section - begins; whatever follows will be common to all sections. Otherwise + begins; whatever follows will be common to all sections. Otherwise - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4099,7 +4099,7 @@ the last section extends to the end of the options file. MENUCOLOR - Highlight menu lines with different colors. See the "Configuring + Highlight menu lines with different colors. See the "Configuring Menu Colors" section. MSGTYPE @@ -4113,12 +4113,12 @@ Define a sound mapping. See the "Configuring User Sounds" section. SOUNDDIR - Define the directory that contains the sound files. See the "Con- + Define the directory that contains the sound files. See the "Con- figuring User Sounds" section. SYMBOLS - Override one or more symbols in the symbol set used for all dungeon - levels except for the special rogue level. See the "Modifying + Override one or more symbols in the symbol set used for all dungeon + levels except for the special rogue level. See the "Modifying NetHack Symbols" section. Example: @@ -4128,9 +4128,9 @@ WIZKIT Debug mode only: extra items to add to initial inventory. Value is - the name of a text file containing a list of item names, one per - line, up to a maximum of 128 lines. Each line is processed by the - function that handles wishing. Entries are added to the wish his- + the name of a text file containing a list of item names, one per + line, up to a maximum of 128 lines. Each line is processed by the + function that handles wishing. Entries are added to the wish his- tory; see the wizwish-command. Example: @@ -4152,7 +4152,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4183,22 +4183,22 @@ 9.3. Using the NETHACKOPTIONS environment variable - The NETHACKOPTIONS variable is a comma-separated list of initial - values for the various options. Some can only be turned on or off. + The NETHACKOPTIONS variable is a comma-separated list of initial + values for the various options. Some can only be turned on or off. You turn one of these on by adding the name of the option to the list, - and turn it off by typing a `!' or "no" before the name. Others take - a character string as a value. You can set string options by typing - the option name, a colon or equals sign, and then the value of the - string. The value is terminated by the next comma or the end of + and turn it off by typing a `!' or "no" before the name. Others take + a character string as a value. You can set string options by typing + the option name, a colon or equals sign, and then the value of the + string. The value is terminated by the next comma or the end of string. - For example, to set up an environment variable so that color is - on, legacy is off, character name is set to "Blue Meanie", and named + For example, to set up an environment variable so that color is + on, legacy is off, character name is set to "Blue Meanie", and named fruit is set to "lime", you would enter the command % setenv NETHACKOPTIONS "color,\!leg,name:Blue Meanie,fruit:lime" - in csh (note the need to escape the `!' since it's special to that + in csh (note the need to escape the `!' since it's special to that shell), or the pair of commands $ NETHACKOPTIONS="color,!leg,name:Blue Meanie,fruit:lime" @@ -4206,19 +4206,19 @@ in sh, ksh, or bash. - The NETHACKOPTIONS value is effectively the same as a single - OPTIONS directive in a configuration file. The "OPTIONS=" prefix is - implied and comma separated options are processed from right to left. - Other types of configuration directives such as BIND or MSGTYPE are + The NETHACKOPTIONS value is effectively the same as a single + OPTIONS directive in a configuration file. The "OPTIONS=" prefix is + implied and comma separated options are processed from right to left. + Other types of configuration directives such as BIND or MSGTYPE are not allowed. - Instead of a comma-separated list of options, NETHACKOPTIONS can - be set to the full name of a configuration file you want to use. If - that full name doesn't start with a slash, precede it with `@' (at- - sign) to let NetHack know that the rest is intended as a file name. + Instead of a comma-separated list of options, NETHACKOPTIONS can + be set to the full name of a configuration file you want to use. If + that full name doesn't start with a slash, precede it with `@' (at- + sign) to let NetHack know that the rest is intended as a file name. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4232,11 +4232,11 @@ 9.4. Customization options - Here are explanations of what the various options do. Character - strings that are too long may be truncated. Some of the options + Here are explanations of what the various options do. Character + strings that are too long may be truncated. Some of the options listed may be inactive in your dungeon. - Some options are persistent, and are saved and reloaded along + Some options are persistent, and are saved and reloaded along with the game. Changing a persistent option in the configuration file applies only to new games. @@ -4244,25 +4244,25 @@ Add location or direction information to messages (default is off). acoustics - Enable messages about what your character hears (default on). Note + Enable messages about what your character hears (default on). Note that this has nothing to do with your computer's audio capabilities. Persistent. alignment - Your starting alignment (align:lawful, align:neutral, or - align:chaotic). You may specify just the first letter. Many roles - and the non-human races restrict which alignments are allowed. See + Your starting alignment (align:lawful, align:neutral, or + align:chaotic). You may specify just the first letter. Many roles + and the non-human races restrict which alignments are allowed. See role for a description of how to use negation to exclude choices. If align is not specified, there is no default value; player will be - prompted unless role and/or race forces a choice for alignment. + prompted unless role and/or race forces a choice for alignment. Cannot be set with the `O' command. Persistent. armorstatus - Display an extra status condition which summarizes currently worn + Display an extra status condition which summarizes currently worn armor (default off, not supported by all interfaces). - For the usual case where more than one piece of armor is worn, a + For the usual case where more than one piece of armor is worn, a list of letters is shown in the following order: G - gloves; @@ -4274,8 +4274,8 @@ S - shield. autodescribe - Automatically describe the terrain under cursor when asked to get a - location on the map (default true). The whatis_coord option con- + Automatically describe the terrain under cursor when asked to get a + location on the map (default true). The whatis_coord option con- trols whether the description includes map coordinates. autodig @@ -4284,7 +4284,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4299,58 +4299,58 @@ sistent. autopickup - Automatically pick up things onto which you move (default off). + Automatically pick up things onto which you move (default off). Persistent. - See pickup_types and also autopickup_exception for ways to refine + See pickup_types and also autopickup_exception for ways to refine the behavior. Note: prior to version 5.0.0, the default for autopickup was on. autoquiver - This option controls what happens when you attempt the `f' (fire) - command when nothing is quivered or readied (default false). When - true, the computer will fill your quiver or quiver sack or make + This option controls what happens when you attempt the `f' (fire) + command when nothing is quivered or readied (default false). When + true, the computer will fill your quiver or quiver sack or make ready some suitable weapon. Note that it will not take into account - the blessed/cursed status, enchantment, damage, or quality of the - weapon; you are free to manually fill your quiver or quiver sack or - make ready with the `Q' command instead. If no weapon is found or - the option is false, the `t' (throw) command is executed instead. + the blessed/cursed status, enchantment, damage, or quality of the + weapon; you are free to manually fill your quiver or quiver sack or + make ready with the `Q' command instead. If no weapon is found or + the option is false, the `t' (throw) command is executed instead. Persistent. autounlock - Controls what action to take when attempting to walk into a locked - door or to loot a locked container. Takes a plus-sign separated + Controls what action to take when attempting to walk into a locked + door or to loot a locked container. Takes a plus-sign separated list of values: Untrap - prompt about whether to attempt to find a trap; it might fail to find one even when present; if it does find one, - it will ask whether you want to try to disarm the trap; + it will ask whether you want to try to disarm the trap; if you decline, your character will forget that the door or box is trapped; - Apply-Key - if carrying a key or other unlocking tool, prompt about + Apply-Key - if carrying a key or other unlocking tool, prompt about using it; - Kick - kick the door (if you omit untrap or decline to attempt - untrap and you omit apply-key or you lack a key or you - decline to use the key; has no effect on containers); - Force - try to force a container's lid with your currently - wielded weapon (if you omit untrap or decline to attempt + Kick - kick the door (if you omit untrap or decline to attempt untrap and you omit apply-key or you lack a key or you + decline to use the key; has no effect on containers); + Force - try to force a container's lid with your currently + wielded weapon (if you omit untrap or decline to attempt + untrap and you omit apply-key or you lack a key or you decline to use the key; has no effect on doors); - None - none of the above; can't be combined with the other + None - none of the above; can't be combined with the other choices. Omitting the value is treated as if autounlock:apply-key. Preceding autounlock with `!' or "no" is treated as autounlock:none. - Applying a key might set off a trap if the door or container is - trapped. Successfully kicking a door will break it and wake up - nearby monsters. Successfully forcing a container open will break - its lock and might also destroy some of its contents or damage your + Applying a key might set off a trap if the door or container is + trapped. Successfully kicking a door will break it and wake up + nearby monsters. Successfully forcing a container open will break + its lock and might also destroy some of its contents or damage your weapon or both. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4369,15 +4369,15 @@ Allow saving and loading bones files (default true). Persistent. boulder - Set the character used to display boulders (default is the "large + Set the character used to display boulders (default is the "large rock" class symbol, ``'). catname - Name your starting cat (for example "catname:Morris"). Cannot be + Name your starting cat (for example "catname:Morris"). Cannot be set with the `O' command. character - Synonym for "role" to pick the type of your character (for example + Synonym for "role" to pick the type of your character (for example "character:Monk"). See role for more details. checkpoint @@ -4385,11 +4385,11 @@ program crash (default on). Persistent. cmdassist - Have the game provide some additional command assistance for new + Have the game provide some additional command assistance for new players if it detects some anticipated mistakes (default on). confirm - Have user confirm attacks on pets, shopkeepers, and other peaceable + Have user confirm attacks on pets, shopkeepers, and other peaceable creatures (default on). Persistent. dark_room @@ -4399,13 +4399,13 @@ Start the character permanently deaf (default false). Persistent. dropped_nopick - If this option is on, items you dropped will not be automatically - picked up, even if autopickup is also on and they are in - pickup_types or match a positive autopickup exception (default on). + If this option is on, items you dropped will not be automatically + picked up, even if autopickup is also on and they are in + pickup_types or match a positive autopickup exception (default on). Persistent. disclose - Controls what information the program reveals when the game ends. + Controls what information the program reveals when the game ends. Value is a space separated list of prompting/category pairs (default is "ni na nv ng nc no", prompt with default response of `n' for each candidate). Persistent. The possibilities are: @@ -4416,7 +4416,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4433,7 +4433,7 @@ c - display your conduct; also achievements, if any; o - display dungeon overview. - Each disclosure possibility can optionally be preceded by a prefix + Each disclosure possibility can optionally be preceded by a prefix which lets you refine how it behaves. Here are the valid prefixes: y - prompt you and default to yes on the prompt; @@ -4441,48 +4441,48 @@ + - disclose it without prompting; - - do not disclose it and do not prompt. - The listings of vanquished monsters and of genocided types can be + The listings of vanquished monsters and of genocided types can be sorted, so there are two additional choices for `v' and `g': ? - prompt you and default to ask on the prompt; # - disclose it without prompting, ask for sort order. - Asking refers to picking one of the orderings from a menu. The `+' - disclose without prompting choice, or being prompted and answering - `y' rather than `a', will default to showing monsters in the order + Asking refers to picking one of the orderings from a menu. The `+' + disclose without prompting choice, or being prompted and answering + `y' rather than `a', will default to showing monsters in the order specified by the sortvanquished option. - Omitted categories are implicitly added with `n' prefix. Specified - categories with omitted prefix implicitly use `+' prefix. Order of - the disclosure categories does not matter, program display for end- + Omitted categories are implicitly added with `n' prefix. Specified + categories with omitted prefix implicitly use `+' prefix. Order of + the disclosure categories does not matter, program display for end- of-game disclosure follows a set sequence. (for example "disclose:yi na +v -g o") The example sets inventory to - prompt and default to yes, attributes to prompt and default to no, - vanquished to disclose without prompting, genocided to not disclose - and not prompt, conduct to implicitly prompt and default to no, and + prompt and default to yes, attributes to prompt and default to no, + vanquished to disclose without prompting, genocided to not disclose + and not prompt, conduct to implicitly prompt and default to no, and overview to disclose without prompting. - Note that the vanquished monsters list includes all monsters killed + Note that the vanquished monsters list includes all monsters killed by traps and each other as well as by you. And the dungeon overview - shows all levels you had visited but does not reveal things about + shows all levels you had visited but does not reveal things about them that you hadn't discovered. dogname - Name your starting dog (for example "dogname:Fang"). Cannot be set + Name your starting dog (for example "dogname:Fang"). Cannot be set with the `O' command. extmenu - Changes the extended commands interface to pop-up a menu of avail- - able commands. It is keystroke compatible with the traditional + Changes the extended commands interface to pop-up a menu of avail- + able commands. It is keystroke compatible with the traditional interface except that it does not require that you hit Enter. It is implemented for the tty interface (default off). - For the X11 interface, which always uses a menu for choosing an - extended command, it controls whether the menu shows all available + For the X11 interface, which always uses a menu for choosing an + extended command, it controls whether the menu shows all available - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4492,7 +4492,7 @@ - commands (on) or just the subset of commands which have tradition- + commands (on) or just the subset of commands which have tradition- ally been considered extended ones (off). female @@ -4500,55 +4500,55 @@ command. fireassist - This option controls what happens when you attempt the `f' (fire) - and don't have an appropriate launcher, such as a bow or a sling, - wielded. If on, you will automatically wield the launcher. Default + This option controls what happens when you attempt the `f' (fire) + and don't have an appropriate launcher, such as a bow or a sling, + wielded. If on, you will automatically wield the launcher. Default is on. fixinv An object's inventory letter sticks to it when it's dropped (default - on). If this is off, dropping an object shifts all the remaining + on). If this is off, dropping an object shifts all the remaining inventory letters. Persistent. force_invmenu - Commands asking for an inventory item show a menu instead of a text + Commands asking for an inventory item show a menu instead of a text query with possible menu letters. Default is off. fruit - Name a fruit after something you enjoy eating (for example + Name a fruit after something you enjoy eating (for example "fruit:mango") (default "slime mold"). Basically a nostalgic whimsy - that NetHack uses from time to time. You should set this to some- - thing you find more appetizing than slime mold. Apples, oranges, - pears, bananas, and melons already exist in NetHack, so don't use + that NetHack uses from time to time. You should set this to some- + thing you find more appetizing than slime mold. Apples, oranges, + pears, bananas, and melons already exist in NetHack, so don't use those. gender - Your starting gender (gender:male or gender:female). You may spec- - ify just the first letter. Although you can still denote your gen- - der using either of the deprecated male and female options, if the + Your starting gender (gender:male or gender:female). You may spec- + ify just the first letter. Although you can still denote your gen- + der using either of the deprecated male and female options, if the gender option is also present it will take precedence. See role for a description of how to use negation to exclude choices. - If gender is not specified, there is no default value; player will - be prompted unless role and/or race forces a choice for gender. + If gender is not specified, there is no default value; player will + be prompted unless role and/or race forces a choice for gender. Cannot be set with the `O' command. Persistent. goldX When filtering objects based on bless/curse state (BUCX), whether to - treat gold pieces as X (unknown bless/curse state, when "on") or U - (known to be uncursed, when "off", the default). Gold is never - blessed or cursed, but it is not described as "uncursed" even when + treat gold pieces as X (unknown bless/curse state, when "on") or U + (known to be uncursed, when "off", the default). Gold is never + blessed or cursed, but it is not described as "uncursed" even when the implicit_uncursed option is "off". help - If more information is available for an object looked at with the - `/' command, ask if you want to see it (default on). Turning help - off makes just looking at things faster, since you aren't inter- - rupted with the "More info?" prompt, but it also means that you - might miss some interesting and/or important information. Persis- + If more information is available for an object looked at with the + `/' command, ask if you want to see it (default on). Turning help + off makes just looking at things faster, since you aren't inter- + rupted with the "More info?" prompt, but it also means that you + might miss some interesting and/or important information. Persis- - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4562,59 +4562,59 @@ herecmd_menu When using a windowport that supports mouse and clicking on yourself - or next to you, show a menu of possible actions for the location. + or next to you, show a menu of possible actions for the location. Same as "#herecmdmenu" and "#therecmdmenu" commands. hilite_pet - Visually distinguish pets from similar animals (default off). The - behavior of this option depends on the type of windowing you use. + Visually distinguish pets from similar animals (default off). The + behavior of this option depends on the type of windowing you use. In text windowing, text highlighting or inverse video is often used; with tiles, generally displays a heart symbol near pets. With the tty or curses interface, the petattr option controls how to - highlight pets and setting it will turn the hilite_pet option on or + highlight pets and setting it will turn the hilite_pet option on or off as warranted. hilite_pile Visually distinguish piles of objects from individual objects - (default off). The behavior of this option depends on the type of - windowing you use. In text windowing, text highlighting or inverse - video is often used; with tiles, generally displays a small plus- + (default off). The behavior of this option depends on the type of + windowing you use. In text windowing, text highlighting or inverse + video is often used; with tiles, generally displays a small plus- symbol beside the object on the top of the pile. hitpointbar - Show a hit point bar graph behind your name and title in the status + Show a hit point bar graph behind your name and title in the status display (default off). - The "curses" interface supports it even if the status highlighting - feature has been disabled when building the program. The "tty" and - "mswin" (aka "Windows GUI") interfaces support it only if status - highlighting is left enabled when building. You don't need to set - up any highlighting rules in order to display the bar. If there is - one for hitpoints in effect and it specifies color, that color will + The "curses" interface supports it even if the status highlighting + feature has been disabled when building the program. The "tty" and + "mswin" (aka "Windows GUI") interfaces support it only if status + highlighting is left enabled when building. You don't need to set + up any highlighting rules in order to display the bar. If there is + one for hitpoints in effect and it specifies color, that color will be used for the bar. However if it specifies video attributes, they will be ignored in favor of inverse. For tty and curses, blink will also be used if the current hitpoint value is at or below the criti- cal HP threshold. The "Qt" interface also supports hitpointbar, by drawing a solid bar - above the name and title with a hard-coded color scheme. (As of + above the name and title with a hard-coded color scheme. (As of this writing, having the bar enabled unintentionally inhibits resiz- - ing the status panel. To resize that, use the #optionsfull command - to toggle the hitpointbar option off, perform the resize while it's + ing the status panel. To resize that, use the #optionsfull command + to toggle the hitpointbar option off, perform the resize while it's off, then use the same command to toggle it back on.) horsename - Name your starting horse (for example "horsename:Trigger"). Cannot + Name your starting horse (for example "horsename:Trigger"). Cannot be set with the `O' command. ignintr - Ignore interrupt signals, including breaks (default off). Persis- + Ignore interrupt signals, including breaks (default off). Persis- tent. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4639,48 +4639,48 @@ your character as lit (default off). Persistent. lootabc - When using a menu to interact with a container, use the old `a', - `b', and `c' keyboard shortcuts rather than the mnemonics `o', `i', + When using a menu to interact with a container, use the old `a', + `b', and `c' keyboard shortcuts rather than the mnemonics `o', `i', and `b' (default off). Persistent. mail Enable mail delivery during the game (default on). Persistent. male - An obsolete synonym for "gender:male". Cannot be set with the `O' + An obsolete synonym for "gender:male". Cannot be set with the `O' command. mention_decor - Give feedback when walking onto various dungeon features such as - stairs, fountains, or altars which are ordinarily only described - when covered by one or more objects (default off). Cannot be set + Give feedback when walking onto various dungeon features such as + stairs, fountains, or altars which are ordinarily only described + when covered by one or more objects (default off). Cannot be set with the `O' command. Persistent. mention_map Give feedback when interesting map locations change (default off). mention_walls - Give feedback when walking against a wall (default off). Persis- + Give feedback when walking against a wall (default off). Persis- tent. menucolors - Enable coloring menu lines (default off). See "Configuring Menu + Enable coloring menu lines (default off). See "Configuring Menu Colors" on how to configure the colors. menustyle Controls the method used when you need to choose various objects (in - response to the Drop (aka droptype) command, for instance). The - value specified should be the first letter of one of the following: - traditional, combination, full, or partial. Default is full. Per- + response to the Drop (aka droptype) command, for instance). The + value specified should be the first letter of one of the following: + traditional, combination, full, or partial. Default is full. Per- sistent. - Traditional was the only method available for very early versions; - it consists of a prompt for object class characters, followed by an - object-by-object prompt for all items matching the selected object + Traditional was the only method available for very early versions; + it consists of a prompt for object class characters, followed by an + object-by-object prompt for all items matching the selected object class(es). Combination starts with a prompt for object class(es) of - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4690,12 +4690,12 @@ - interest, but then displays a menu of matching objects rather than + interest, but then displays a menu of matching objects rather than prompting one-by-one. Full displays a menu of object classes rather - than a character prompt, and then a menu of matching objects for + than a character prompt, and then a menu of matching objects for selection. (Choosing its `A' (Autoselect-All) choice skips the sec- - ond menu. To avoid choosing that by accident, set paranoid_con- - firm:AutoAll to require confirmation.) Partial skips the object + ond menu. To avoid choosing that by accident, set paranoid_con- + firm:AutoAll to require confirmation.) Partial skips the object class filtering and immediately displays a menu of all objects. menu_deselect_all @@ -4708,9 +4708,9 @@ Key to jump to the first page in a menu. Default `^'. menu_headings - Controls how the headings in a menu are highlighted. Takes a text - attribute, or text color and attribute separated by ampersand. For - allowed attributes and colors, see "Configuring Menu Colors". Not + Controls how the headings in a menu are highlighted. Takes a text + attribute, or text color and attribute separated by ampersand. For + allowed attributes and colors, see "Configuring Menu Colors". Not all ports can actually display all types. menu_invert_all @@ -4726,13 +4726,13 @@ Key to go to the next menu page. Default `>'. menu_objsyms - Inventory and other object menus are normally separated by object + Inventory and other object menus are normally separated by object class (weapons, armor, and so forth), with a menu header line at the - beginning of each group. You can have menus add the display symbol + beginning of each group. You can have menus add the display symbol for the class of objects for each header line. You can also add the - display symbol for the individual item in each menu entry. For a + display symbol for the individual item in each menu entry. For a tiles map, that would be a small rendition of an object's tile. For - a text map, it is the same character as is used for the object's + a text map, it is the same character as is used for the object's class, which would be most useful when there are no headers separat- ing objects among classes. Possible values are @@ -4741,12 +4741,12 @@ 1 - Headers - show symbols on header lines but not entries; 2 - Entries - show symbols on menu entry lines but not headers; 3 - Both - show symbols on headers and entries; - 4 - Conditional - only show symbols for entries if there are no + 4 - Conditional - only show symbols for entries if there are no headers; - 5 - One-or-other - show symbols on headers, or on entries if no + 5 - One-or-other - show symbols on headers, or on entries if no - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4758,8 +4758,8 @@ headers. - Supported by tty and curses. When setting the value, it can be - specified by digit or keyword. The default value is Conditional + Supported by tty and curses. When setting the value, it can be + specified by digit or keyword. The default value is Conditional (4). menu_overlay @@ -4770,7 +4770,7 @@ Key to go to the previous menu page. Default `<'. menu_search - Key to search for some text and toggle selection state of matching + Key to search for some text and toggle selection state of matching menu items. Default `:'. menu_select_all @@ -4781,20 +4781,20 @@ menu_shift_left Key to scroll a menu--one which has been scrolled right--back to the - left. Implemented for perm_invent only by curses and X11. Default + left. Implemented for perm_invent only by curses and X11. Default `{'. menu_shift_right - Key to scroll a menu which has text beyond the right edge to the + Key to scroll a menu which has text beyond the right edge to the right. Implemented for perm_invent only by curses and X11. Default `}'. mon_movement - Show a message when hero notices a monster movement (default is + Show a message when hero notices a monster movement (default is off). monpolycontrol - Prompt for new form whenever any monster changes shape (default + Prompt for new form whenever any monster changes shape (default off). Debug mode only. montelecontrol @@ -4812,7 +4812,7 @@ port is the same as specifying 0. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4823,12 +4823,12 @@ msghistory - The number of top line messages to keep (and be able to recall with + The number of top line messages to keep (and be able to recall with `^P') (default 20). Cannot be set with the `O' command. msg_window - Allows you to change the way recalled messages are displayed. Cur- - rently it is only supported for tty (all four choices) and for + Allows you to change the way recalled messages are displayed. Cur- + rently it is only supported for tty (all four choices) and for curses (`f' and `r' choices, default `r'). The possible values are: s - single message (default; only choice prior to 3.4.0); @@ -4836,25 +4836,25 @@ f - full window, oldest message first; r - full window reversed, newest message first. - For backward compatibility, no value needs to be specified (which - defaults to "full"), or it can be negated (which defaults to "sin- + For backward compatibility, no value needs to be specified (which + defaults to "full"), or it can be negated (which defaults to "sin- gle"). name - Set your character's name (defaults to your user name). You can - also set your character's role by appending a dash and one or more - letters of the role (that is, by suffixing one of -A -B -C -H -K -M - -P -Ra -Ro -S -T -V -W). If -@ is used for the role, then a random + Set your character's name (defaults to your user name). You can + also set your character's role by appending a dash and one or more + letters of the role (that is, by suffixing one of -A -B -C -H -K -M + -P -Ra -Ro -S -T -V -W). If -@ is used for the role, then a random one will be automatically chosen. - On some systems, the default is the player's user name; on others, + On some systems, the default is the player's user name; on others, there is no default and the player will be prompted. The former can - made to behave like the latter by specifying a generic name such as + made to behave like the latter by specifying a generic name such as ``player''. Cannot be set with the `O' command. news Read the NetHack news file, if present (default on). Since the news - is shown at the beginning of the game, there's no point in setting + is shown at the beginning of the game, there's no point in setting this with the `O' command. nudist @@ -4875,10 +4875,10 @@ -1 - by letters but use `z' to go northwest, `y' to zap wands For backward compatibility, omitting a value is the same as specify- - ing 1 and negating number_pad is the same as specifying 0. (Set- + ing 1 and negating number_pad is the same as specifying 0. (Set- - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4888,63 +4888,63 @@ - tings 2 and 4 are for compatibility with MS-DOS or old PC Hack; in - addition to the different behavior for `5', `Alt-5' acts as `G' and - `Alt-0' acts as `I'. Setting -1 is to accommodate some QWERTZ key- - boards which have the location of the `y' and `z' keys swapped.) - When moving by numbers, to enter a count prefix for those commands - which accept one (such as "12s" to search twelve times), precede it + tings 2 and 4 are for compatibility with MS-DOS or old PC Hack; in + addition to the different behavior for `5', `Alt-5' acts as `G' and + `Alt-0' acts as `I'. Setting -1 is to accommodate some QWERTZ key- + boards which have the location of the `y' and `z' keys swapped.) + When moving by numbers, to enter a count prefix for those commands + which accept one (such as "12s" to search twelve times), precede it with the letter `n' ("n12s"). packorder - Specify the order to list object types in (default + Specify the order to list object types in (default "")[%?+!=/(*`0_"). The value of this option should be a string con- taining the symbols for the various object types. Any omitted types are filled in at the end from the previous order. paranoid_confirmation - A space separated list of specific situations where alternate - prompting is desired. The default is "paranoid_confirmation:pray + A space separated list of specific situations where alternate + prompting is desired. The default is "paranoid_confirmation:pray swim trap". - Confirm - for any prompts which are set to require "yes" rather - than `y', also require "no" to reject instead of + Confirm - for any prompts which are set to require "yes" rather + than `y', also require "no" to reject instead of accepting any non-yes response as no; changes pray and AutoAll to require "yes" or `no' too; - quit - require "yes" rather than `y' to confirm quitting the + quit - require "yes" rather than `y' to confirm quitting the game or switching into non-scoring explore mode; - die - require "yes" rather than `y' to confirm dying (not + die - require "yes" rather than `y' to confirm dying (not useful in normal play; applies to explore mode); - bones - require "yes" rather than `y' to confirm saving bones + bones - require "yes" rather than `y' to confirm saving bones data when dying in debug mode; - attack - require "yes" rather than `y' to confirm attacking a + attack - require "yes" rather than `y' to confirm attacking a peaceful monster; - wand-break - require "yes" rather than `y' to confirm breaking a + wand-break - require "yes" rather than `y' to confirm breaking a wand with the apply command; - eating - require "yes" rather than `y' to confirm whether to + eating - require "yes" rather than `y' to confirm whether to continue eating; Were-change - require "yes" rather than `y' to confirm changing form due to lycanthropy when hero has polymorph control; - pray - require `y' to confirm an attempt to pray rather than - immediately praying; on by default; (to require "yes" + pray - require `y' to confirm an attempt to pray rather than + immediately praying; on by default; (to require "yes" rather than just `y', set Confirm too); trap - require `y' to confirm an attempt to move into or onto - a known trap, unless doing so is considered to be + a known trap, unless doing so is considered to be harmless; when enabled, this confirmation is also used for moving into visible gas cloud regions; (to require - "yes" rather than just `y', set Confirm too); confir- - mation can be skipped by using the `m' movement pre- + "yes" rather than just `y', set Confirm too); confir- + mation can be skipped by using the `m' movement pre- fix; swim - prevent walking into water or lava; on by default; (to - deliberately step onto/into such terrain when this is + deliberately step onto/into such terrain when this is set, use the `m' movement prefix when adjacent); - AutoAll - require confirmation when the `A' (Autoselect-All) + AutoAll - require confirmation when the `A' (Autoselect-All) choice is selected in object class filtering menus for - menustyle:Full; (to require "yes" rather than just + menustyle:Full; (to require "yes" rather than just `y', set Confirm too); - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -4954,39 +4954,39 @@ - Remove - require selection from inventory for `R' and `T' com- + Remove - require selection from inventory for `R' and `T' com- mands even when wearing just one applicable item; all - turn on all of the above. By default, the pray, swim, and trap choices are enabled, the others disabled. To disable them without setting any of the other choices, - use paranoid_confirmation:none. To keep them enabled while setting - any of the others, you can include them in the new list, such as + use paranoid_confirmation:none. To keep them enabled while setting + any of the others, you can include them in the new list, such as paranoid_confirmation:attack pray swim Remove or you can precede the - first entry in the list with a plus sign, paranoid_confirma- - tion:+attack Remove. To remove an entry that has been previously - set without removing others, precede the first entry in the list - with a minus sign, paranoid_confirmation:-swim. To both add some - new entries and remove some old ones, you can use multiple para- - noid_confirmation option settings, or you can use the `+' form and - list entries to be added by their name and entries to be removed by + first entry in the list with a plus sign, paranoid_confirma- + tion:+attack Remove. To remove an entry that has been previously + set without removing others, precede the first entry in the list + with a minus sign, paranoid_confirmation:-swim. To both add some + new entries and remove some old ones, you can use multiple para- + noid_confirmation option settings, or you can use the `+' form and + list entries to be added by their name and entries to be removed by `!' and name. The positive (no `!') and negative (with `!') entries can be intermixed. pauper - Start the character with no possessions (default false). Persis- + Start the character with no possessions (default false). Persis- tent. - Also start with no spells or skills, which are tied to starting - equipment. Does not inhibit acquiring and using items, spells, and + Also start with no spells or skills, which are tied to starting + equipment. Does not inhibit acquiring and using items, spells, and skills once play has started. perm_invent - If true, always display your current inventory in a window (default + If true, always display your current inventory in a window (default false). This only makes sense for windowing system interfaces that implement - this feature. For those that do, the perminv_mode option can be + this feature. For those that do, the perminv_mode option can be used to refine what gets displayed for perm_invent. Setting that to a value other than none while perm_invent is false will change it to true. @@ -5010,7 +5010,7 @@ ing pets on the map. Effectively a superset of the hilite_pet bool- - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5020,63 +5020,63 @@ - ean option. Curses or tty interface only; value is one of none, - bold, dim, underline, italic, blink, and inverse. Some of those + ean option. Curses or tty interface only; value is one of none, + bold, dim, underline, italic, blink, and inverse. Some of those choices might not work, depending upon terminal hardware or terminal emulation software. pettype Specify the type of your initial pet, if you are playing a character class that uses multiple types of pets; or choose to have no initial - pet at all. Possible values are "cat", "dog", "horse", and "none". + pet at all. Possible values are "cat", "dog", "horse", and "none". If the choice is not allowed for the role you are currently playing, it will be silently ignored. For example, "horse" will only be hon- ored when playing a knight. Cannot be set with the `O' command. pickup_burden - When you pick up an item that would exceed this encumbrance level - (Unencumbered, Burdened, streSsed, straiNed, overTaxed, or over- - Loaded), you will be asked if you want to continue. (Default `S'). + When you pick up an item that would exceed this encumbrance level + (Unencumbered, Burdened, streSsed, straiNed, overTaxed, or over- + Loaded), you will be asked if you want to continue. (Default `S'). Persistent. pickup_stolen - If this option is on and autopickup is also on, try to pick up - things that a monster stole from you, even if they aren't in + If this option is on and autopickup is also on, try to pick up + things that a monster stole from you, even if they aren't in pickup_types or match an autopickup exception. Default is on. Per- sistent. pickup_thrown - If this option is on and autopickup is also on, try to pick up - things that you threw, even if they aren't in pickup_types or match + If this option is on and autopickup is also on, try to pick up + things that you threw, even if they aren't in pickup_types or match an autopickup exception. Default is on. Persistent. pickup_types - Specify the object types to be picked up when autopickup is on. + Specify the object types to be picked up when autopickup is on. Default is all types. Persistent. - The value is a list of object symbols, such as pickup_types:$?! to - pick up gold, scrolls, and potions. You can use autopickup_excep- + The value is a list of object symbols, such as pickup_types:$?! to + pick up gold, scrolls, and potions. You can use autopickup_excep- tion configuration file lines to further refine autopickup behavior. - There is no way to set pickup_types to "none". (Setting it to an - empty value reverts to "all".) If you want to avoid automatically - picking up any types of items but do want to have autopickup on in - order to have autopickup_exception settings control what you do and - don't pick up, you can set pickup_types to `.'. That is the type - symbol for venom and you won't come across any venom items so won't + There is no way to set pickup_types to "none". (Setting it to an + empty value reverts to "all".) If you want to avoid automatically + picking up any types of items but do want to have autopickup on in + order to have autopickup_exception settings control what you do and + don't pick up, you can set pickup_types to `.'. That is the type + symbol for venom and you won't come across any venom items so won't unintentionally pick such up. pile_limit - When walking across a pile of objects on the floor, threshold at + When walking across a pile of objects on the floor, threshold at which the message "there are few/several/many objects here" is given - instead of showing a popup list of those objects. A value of 0 + instead of showing a popup list of those objects. A value of 0 means "no limit" (always list the objects); a value of 1 effectively means "never show the objects" since the pile size will always be at least that big; default value is 5. Persistent. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5087,28 +5087,28 @@ playmode - Values are "normal", "explore", or "debug". Allows selection of - explore mode (also known as discovery mode) or debug mode (also + Values are "normal", "explore", or "debug". Allows selection of + explore mode (also known as discovery mode) or debug mode (also known as wizard mode) instead of normal play. Debug mode might only - be allowed for someone logged in under a particular user name (on - multi-user systems) or specifying a particular character name (on - single-user systems) or it might be disabled entirely. Requesting + be allowed for someone logged in under a particular user name (on + multi-user systems) or specifying a particular character name (on + single-user systems) or it might be disabled entirely. Requesting it when not allowed or not possible results in explore mode instead. Default is normal play. price_quotes Whenever the game mentions the name of an object you haven't identi- fied yet, it also mentions the range of buy and sell prices you have - seen for that item (to help narrow down what it could be). The - price shown is the unit price for one item (even when you are look- - ing at a stack of multiple items). Many players may want to turn - this on while identifying objects, and then turn it back off again + seen for that item (to help narrow down what it could be). The + price shown is the unit price for one item (even when you are look- + ing at a stack of multiple items). Many players may want to turn + this on while identifying objects, and then turn it back off again for general play. Default is off. pushweapon Using the `w' (wield) command when already wielding something pushes - the old item into your alternate weapon slot (default off). Like- - wise for the `a' (apply) command if it causes the applied item to + the old item into your alternate weapon slot (default off). Like- + wise for the `a' (apply) command if it causes the applied item to become wielded. Persistent. query_menu @@ -5116,33 +5116,33 @@ quick_farsight When set, usually prevents the "you sense your surroundings" message - where play pauses to allow you to browse the map whenever clairvoy- - ance randomly activates. Some situations, such as being underwater - or engulfed, ignore this option. It does not affect the clairvoy- - ance spell where pausing to examine revealed objects or monsters is + where play pauses to allow you to browse the map whenever clairvoy- + ance randomly activates. Some situations, such as being underwater + or engulfed, ignore this option. It does not affect the clairvoy- + ance spell where pausing to examine revealed objects or monsters is less intrusive. Default is off. Persistent. race - Selects your race (for example, race:human). Choices are human, + Selects your race (for example, race:human). Choices are human, dwarf, elf, gnome, and orc but most roles restrict which of the non- - human races are allowed. See role for a description of how to use + human races are allowed. See role for a description of how to use negation to exclude choices. - If race is not specified, there is no default value; player will be - prompted unless role forces a choice for race. Cannot be set with + If race is not specified, there is no default value; player will be + prompted unless role forces a choice for race. Cannot be set with the `O' command. Persistent. reroll - Allows rerolling your character's starting inventory and attributes + Allows rerolling your character's starting inventory and attributes (default false). Persistent. - Note that rerolling your character is not a recommended way to play - if aiming merely to win (a lucky start has a much smaller influence - on whether or not you win the game than your actions later in the - game). This option exists partly as an acknowledgement that some + Note that rerolling your character is not a recommended way to play + if aiming merely to win (a lucky start has a much smaller influence + on whether or not you win the game than your actions later in the + game). This option exists partly as an acknowledgement that some - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5156,17 +5156,17 @@ may be necessary for certain types of challenge games. rest_on_space - Make the space bar a synonym for the `.' (#wait) command (default + Make the space bar a synonym for the `.' (#wait) command (default off). Persistent. role Pick your type of character (for example, role:Samurai); synonym for - character. See name for an alternate method of specifying your + character. See name for an alternate method of specifying your role. - This option can also be used to limit selection when role is chosen - randomly. Use a space-separated list of roles and either negate - each one or negate the option itself instead. Negation is accom- + This option can also be used to limit selection when role is chosen + randomly. Use a space-separated list of roles and either negate + each one or negate the option itself instead. Negation is accom- plished in the same manner as with boolean options, by prefixing the option or its value(s) with `!' or "no". Examples: @@ -5174,10 +5174,10 @@ OPTIONS=role:!arc !bar !kni OPTIONS=!role:arc bar kni - There can be multiple instances of the role option if they're all + There can be multiple instances of the role option if they're all negations. - If role is not specified, there is no default value; player will be + If role is not specified, there is no default value; player will be prompted. Cannot be set with the `O' command. Persistent. roguesymset @@ -5186,14 +5186,14 @@ rogue level. rlecomp - When writing out a save file, perform run length compression of the + When writing out a save file, perform run length compression of the map. Not all ports support run length compression. It has no effect on reading an existing save file. runmode - Controls the amount of screen updating for the map window when - engaged in multi-turn movement (running via shift+direction or con- - trol+direction and so forth, or via the travel command or mouse + Controls the amount of screen updating for the map window when + engaged in multi-turn movement (running via shift+direction or con- + trol+direction and so forth, or via the travel command or mouse click). The possible values are: teleport - update the map after movement has finished; @@ -5201,14 +5201,14 @@ walk - update the map after each step; crawl - like walk, but pause briefly after each step. - This option only affects the game's screen display, not the actual - results of moving. The default is "run"; versions prior to 3.4.1 - used "teleport" only. Whether or not the effect is noticeable will - depend upon the window port used or on the type of terminal. Per- + This option only affects the game's screen display, not the actual + results of moving. The default is "run"; versions prior to 3.4.1 + used "teleport" only. Whether or not the effect is noticeable will + depend upon the window port used or on the type of terminal. Per- sistent. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5223,58 +5223,58 @@ sistent. safe_wait - Prevents you from waiting or searching when next to a hostile mon- + Prevents you from waiting or searching when next to a hostile mon- ster (default on). Persistent. sanity_check - Evaluate monsters, objects, and map prior to each turn (default + Evaluate monsters, objects, and map prior to each turn (default off). Debug mode only. scores - Control what parts of the score list you are shown at the end (for - example "scores:5 top scores/4 around my score/own scores"). Only - the first letter of each category (`t', `a', or `o') is necessary. + Control what parts of the score list you are shown at the end (for + example "scores:5 top scores/4 around my score/own scores"). Only + the first letter of each category (`t', `a', or `o') is necessary. Persistent. showdamage - Whenever your character takes damage, show a message of the damage + Whenever your character takes damage, show a message of the damage taken, and the amount of hit points left. showexp - Show your accumulated experience points on bottom line (default + Show your accumulated experience points on bottom line (default off). Persistent. showrace - Display yourself as the glyph for your race, rather than the glyph - for your role (default off). Note that this setting affects only - the appearance of the display, not the way the game treats you. + Display yourself as the glyph for your race, rather than the glyph + for your role (default off). Note that this setting affects only + the appearance of the display, not the way the game treats you. Persistent. showscore - Show your approximate accumulated score on bottom line (default + Show your approximate accumulated score on bottom line (default off). By default, this feature is suppressed when building the pro- gram. Persistent. showvers Include the game's version number on the status lines (default off). Potentially useful if you switch between different versions or vari- - ants, or you are making screenshots or streaming video. Using the - statuslines:3 option is recommended so that there will be more room - available for status information, unless you're using NetHack's Qt - interface or your terminal emulator window displays fewer than 25 + ants, or you are making screenshots or streaming video. Using the + statuslines:3 option is recommended so that there will be more room + available for status information, unless you're using NetHack's Qt + interface or your terminal emulator window displays fewer than 25 lines. Persistent. + The versinfo option provides limited control over what information + showvers displays. + silent Suppress terminal beeps (default on). Persistent. sortdiscoveries Controls the sorting behavior for the output of the `\' and ``' com- - mands. Persistent. - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5284,6 +5284,8 @@ + mands. Persistent. + The possible values are: o - list object types by class, in discovery order within each @@ -5335,12 +5337,10 @@ prefix before either the #vanquished command or the #genocided com- mand. - sounds - Allow sounds to be emitted from an integrated sound library (default - on). - NetHack 5.0.0 April 16, 2026 + + NetHack 5.0.0 May 2, 2026 @@ -5350,6 +5350,10 @@ + sounds + Allow sounds to be emitted from an integrated sound library (default + on). + sparkle Display a sparkly effect when a monster (including yourself) is hit by an attack to which it is resistant (default on). Persistent. @@ -5400,13 +5404,9 @@ tombstone Draw a tombstone graphic upon your death (default on). Persistent. - toptenwin - Put the ending display in a NetHack window instead of on stdout - (default off). Setting this option makes the score list visible - when a windowing version of NetHack is started without a parent win- - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5416,6 +5416,10 @@ + toptenwin + Put the ending display in a NetHack window instead of on stdout + (default off). Setting this option makes the score list visible + when a windowing version of NetHack is started without a parent win- dow, but it no longer leaves the score list around after game end on a terminal or emulating window. @@ -5432,6 +5436,9 @@ verbose Provide more commentary during the game (default on). Persistent. + versinfo + Controls what the showvers option displays on the status lines. + weaponstatus Display an extra status condition which describes currently wielded weapon (default off, not supported by all interfaces). @@ -5464,15 +5471,8 @@ through next and previous targets, allows filtering the possible targets. - n - no filtering [default] - v - in view only - a - in same area only - The area-filter tries to be slightly predictive--if you're standing - on a doorway, it will consider the area on the side of the door you - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5482,6 +5482,12 @@ + n - no filtering [default] + v - in view only + a - in same area only + + The area-filter tries to be slightly predictive--if you're standing + on a doorway, it will consider the area on the side of the door you were last moving towards. Filtering can also be changed when getting a location with the "get- @@ -5530,15 +5536,9 @@ will attempt to do so. If it can't it will silently ignore it. You can find out if an option is supported by the window port that you are currently using by checking to see if it shows up in the Options list. - Some options are dynamic and can be specified during the game with the - `O' command. - - align_message - Where to align or place the message window (top, bottom, left, or - right) - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5548,6 +5548,13 @@ + Some options are dynamic and can be specified during the game with the + `O' command. + + align_message + Where to align or place the message window (top, bottom, left, or + right) + align_status Where to align or place the status window (top, bottom, left, or right). @@ -5595,16 +5602,9 @@ font_size_menu If NetHack can, it should use this size font for menu windows. - font_size_message - If NetHack can, it should use this size font for the message window. - - font_size_status - If NetHack can, it should use this size font for the status window. - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5614,6 +5614,12 @@ + font_size_message + If NetHack can, it should use this size font for the message window. + + font_size_status + If NetHack can, it should use this size font for the status window. + font_size_text If NetHack can, it should use this size font for text windows. @@ -5663,14 +5669,8 @@ Display an onscreen keyboard. Handhelds are most likely to support this option. - splash_screen - If NetHack can, it should display an opening splash screen when it - starts up (default yes). - - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5680,6 +5680,10 @@ + splash_screen + If NetHack can, it should display an opening splash screen when it + starts up (default yes). + statuslines Number of lines for traditional below-the-map status display. Acceptable values are 2 and 3 (default is 2). @@ -5730,13 +5734,9 @@ augmented by line-drawing symbols). Setting tiled_map to True forces ascii_map to be False. - use_darkgray - Use bold black instead of blue for black glyphs (TTY only). - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5746,6 +5746,9 @@ + use_darkgray + Use bold black instead of blue for black glyphs (TTY only). + use_inverse If NetHack can, it should display inverse when the game specifies it. @@ -5796,13 +5799,10 @@ light, highlighttext, inactiveborder, inactivecaption, menu, menu- text, scrollbar, window, windowframe, windowtext). - wraptext - If NetHack can, it should wrap long lines of text if they don't fit - in the visible area of the window. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5812,6 +5812,10 @@ + wraptext + If NetHack can, it should wrap long lines of text if they don't fit + in the visible area of the window. + 9.6. Crash Report Options Please note that NetHack does not send any information off your @@ -5863,12 +5867,8 @@ (default off, OS/2, PC, and ST NetHack only). Note: DEC Rainbows hang if this is turned on. Cannot be set with the `O' command. - subkeyvalue - (Win32 tty NetHack only). May be used to alter the value of key- - strokes that the operating system returns to NetHack to help compen- - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5878,6 +5878,9 @@ + subkeyvalue + (Win32 tty NetHack only). May be used to alter the value of key- + strokes that the operating system returns to NetHack to help compen- sate for international keyboard issues. OPTIONS=subkeyvalue:171/92 will return 92 to NetHack, if 171 was originally going to be returned. You can use multiple subkeyvalue assignments in the con- @@ -5929,12 +5932,9 @@ By placing autopickup_exception lines in your configuration file, you can define patterns to be checked when the game is about to - autopickup something. - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -5944,6 +5944,8 @@ + autopickup something. + autopickup_exception Sets an exception to the pickup_types option. The autopickup_excep- tion option should be followed by a regular expression to be used as @@ -5996,11 +5998,9 @@ key by using "nothing" as the extended command to bind to. You can also bind the "", "", and "" keys. - Menu accelerator keys - The menu control or accelerator keys can also be rebound via OPTIONS - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6010,6 +6010,8 @@ + Menu accelerator keys + The menu control or accelerator keys can also be rebound via OPTIONS lines in the configuration file. You cannot bind object symbols or selection letters into menu accelerators. Some interfaces only sup- port some of the menu accelerators. @@ -6062,11 +6064,9 @@ getpos.door.next When asked for a location, the key to go to next closest door or - doorway. Default is `d'. - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6076,6 +6076,8 @@ + doorway. Default is `d'. + getpos.door.prev When asked for a location, the key to go to previous closest door or doorway. Default is `D'. @@ -6127,12 +6129,10 @@ asked for a direction, the key to respond as left click. Default is `,'. - getpos.pick.quick - When asked for a location, the key to choose the location, skip ask- - ing for more info, and exit the location asking loop. Default is - NetHack 5.0.0 April 16, 2026 + + NetHack 5.0.0 May 2, 2026 @@ -6142,6 +6142,9 @@ + getpos.pick.quick + When asked for a location, the key to choose the location, skip ask- + ing for more info, and exit the location asking loop. Default is `;'. getpos.pick.verbose @@ -6193,12 +6196,9 @@ norep - show the message once, but not again if no other message is shown in between. - Here's an example of message types using NetHack's internal pattern - matching facility: - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6208,6 +6208,9 @@ + Here's an example of message types using NetHack's internal pattern + matching facility: + MSGTYPE=stop "You feel hungry." MSGTYPE=hide "You displaced *." @@ -6259,12 +6262,9 @@ and lines with " cursed " followed by "(being worn)" on the same line will be shown in red color and underlined. You can have multi- ple MENUCOLOR entries in your configuration file, and the last MENU- - COLOR line that matches a menu line will be used for the line. - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6274,6 +6274,8 @@ + COLOR line that matches a menu line will be used for the line. + Note that if you intend to have one or more color specifications match " uncursed ", you will probably want to turn the implicit_uncursed option off so that all items known to be uncursed @@ -6326,11 +6328,9 @@ OPTION=hilite_status:field-name/behavior/color&attributes - For example, the following line in your configuration file will - cause the hitpoints field to display in the color red if your hit- - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6340,6 +6340,8 @@ + For example, the following line in your configuration file will + cause the hitpoints field to display in the color red if your hit- points drop to or below a threshold of 30%: OPTION=hilite_status:hitpoints/<=30%/red/normal @@ -6394,9 +6396,7 @@ depending upon your other option settings. - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6462,7 +6462,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6528,7 +6528,7 @@ value, and the ^ prefix causes the following character to be treated - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6594,7 +6594,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6660,7 +6660,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6726,7 +6726,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6792,7 +6792,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6858,7 +6858,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6924,7 +6924,7 @@ seen via the "#attributes" command. - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -6990,7 +6990,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7056,7 +7056,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7122,7 +7122,7 @@ connection between "wizard mode" and the Wizard role). Attempting to - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7188,7 +7188,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7254,7 +7254,7 @@ were distinct for specific types of monsters and objects rather than - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7320,7 +7320,7 @@ file layout which prevented score entries from being read back in cor- - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7386,7 +7386,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7452,7 +7452,7 @@ Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir maintained the - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7502,23 +7502,23 @@ NetHack 3.6.7 was released on February 16, 2023 containing a security fix and some bug fixes. - The official NetHack web site is maintained by Ken Lorber at - https://www.nethack.org/. + Development work for the major release to follow NetHack 3.6 + began in 2015 around the same time as NetHack 3.6.0 was being + released. That development work continued in parallel to each of the + NetHack 3.6 releases from 2015 through 2023, and continued until the + end of April 2026. For the first time, that development was shared + publicly on GitHub and SourceForge as it occurred. It was done under + the label NetHack-3.7 work-in-progress (WIP), although the version + number for the next release had not yet been solidified. + + Exposure of the development to the public brought many good + things, and some challenges. People were able to observe and criticize + changes and new features almost immediately, and they often did. The + GitHub pull request system made it straightforward for people to con- + tribute directly to development. Contributions resolved many, many - - - - - - - - - - - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7528,6 +7528,72 @@ + bugs in the game and we thank all the contributors. + + In early 2026, with the game development getting stable enough to + consider initiating an official release, the devteam reviewed the + nature and number of changes in the game. It was clear that there was + sufficient depth and breadth to warrant a major release and version + 5.0 was decided on. That's a new major release over 3.x, without + opening up any ambiguity or confusion with existing variants that + there might have been had it been released as version 4.0. + + NetHack 5.0.0 was released on May 2, 2026. + + The source code for NetHack 5.0.0 was modified and modernized to + be compliant with standard C99. The 5.0.0 release contained over 3100 + fixes, changes, and updated features. + + NetHack 5.0 was the first version to replace the lex and yacc + level and dungeon compilers of past versions, with a new Lua inter- + preter-based approach to provide those elements. Lua is also used for + the quest texts in NetHack 5.0.0. The entire development team acknowl- + edges the work done by Pasi Kallinen to make that happen. + + At the time of the NetHack 5.0 release, the core development + team, active and erstwhile, included Warwick Allison, Michael Allison, + Ken Arromdee, David Cohrs, Jessie Collet, Bart House, Kevin Hugo, Pasi + Kallinen, Ken Lorber, Dean Luick, Pat Rankin, Derek S. Ray, Alex + Smith, Patric Mueller, Mike Stephenson, Janet Walz, Paul Winner. + + Ken Lorber, Pat Rankin, Patrick Mueller and Michael Allison + helped ensure that NetHack 5.0 would run on macOS. + + Ingo Paschke somehow managed to revive a NetHack 5.0 port for the + Amiga, using a cross-compiler on a modern platform to do so. His work + was shared so others can straightforwardly produce NetHack 5.0 for the + Amiga thanks to his efforts. + + Ray Chason contributed the majority of maintenance work for the + NetHack 5.0 MS-DOS port, including porting the curses interface to it. + Michael Allison ensured that NetHack 5.0 core changes continued to + work with the msdos port and keep it alive. Cross-compiling the MS- + DOS port has helped make that possible and mostly painless. + + People that contributed to the Windows port of NetHack 5.0 since + the development of NetHack 5.0 begain over eleven years ago, included + Michael Allison, David Cohrs, Bart House, Pasi Kallinen, Alex Kompel, + Dion Nicolaas, Derek S. Ray and Yitzhak Sapir. + + With sadness, the devteam would like to acknowledge and remember + the past contributions from the late Ron Van Iwaarden, who was the + sole maintainer of NetHack for OS/2 for several past NetHack releases. + Ron will be missed. + + The official NetHack web site is maintained by Ken Lorber at + https://www.nethack.org/. + + + NetHack 5.0.0 May 2, 2026 + + + + + + NetHack Guidebook 116 + + + 12.1. Special Thanks On behalf of the NetHack community, thank you very much once @@ -7584,13 +7650,13 @@ sends a particularly intriguing modification to help out with the - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 - NetHack Guidebook 116 + NetHack Guidebook 117 @@ -7636,87 +7702,21 @@ - Adam Aronow Izchak Miller Mike Stephenson - Alex Kompel J. Ali Harlow Mikko Juola - Alex Smith Janet Walz Nathan Eady - Andreas Dorn Janne Salmijarvi Norm Meluch - Andy Church Jean-Christophe Collet Olaf Seibert - Andy Swanson Jeff Bailey Pasi Kallinen - Andy Thomson Jochen Erwied Pat Rankin - Ari Huttunen John Kallen Patric Mueller - Bart House John Rupley Paul Winner - Benson I. Margulies John S. Bien Pierre Martineau - Bill Dyer Johnny Lee Ralf Brown + Adam Aronow Irina Rempt-Drijfhout Mike Gallop + Alex Kompel Izchak Miller Mike Passaretti + Alex Smith J. Ali Harlow Mike Stephenson + Andreas Dorn Janet Walz Mikko Juola + Andy Church Janne Salmijarvi Nathan Eady + Andy Swanson Jean-Christophe Collet Norm Meluch + Andy Thomson Jeff Bailey Olaf Seibert + Ari Huttunen Jochen Erwied Pasi Kallinen + Bart House John Kallen Pat Rankin + Benson I. Margulies John Rupley Patric Mueller + Bill Dyer John S. Bien Paul Winner - NetHack 5.0.0 April 16, 2026 - - - - - - NetHack Guidebook 117 - - - - Boudewijn Waijers Jon W{tte Ray Chason - Bruce Cox Jonathan Handler Richard Addison - Bruce Holloway Joshua Delahunty Richard Beigel - Bruce Mewborne Karl Garrison Richard P. Hughey - Carl Schelin Keizo Yamamoto Rob Menke - Chris Russo Keith Simpson Robin Bandy - David Cohrs Ken Arnold Robin Johnson - David Damerell Ken Arromdee Roderick Schertler - David Gentzel Ken Lorber Roland McGrath - David Hairston Ken Washikita Ron Van Iwaarden - Dean Luick Kevin Darcy Ronnen Miller - Del Lamb Kevin Hugo Ross Brown - Derek S. Ray Kevin Sitze Sascha Wostmann - Deron Meranda Kevin Smolkowski Scott Bigham - Dion Nicolaas Kevin Sweet Scott R. Turner - Dylan O'Donnell Lars Huttar Sean Hunt - Eric Backus Leon Arnott Stephen Spackman - Eric Hendrickson M. Drew Streib Stefan Thielscher - Eric R. Smith Malcolm Ryan Stephen White - Eric S. Raymond Mark Gooderum Steve Creps - Erik Andersen Mark Modrall Steve Linhart - Fredrik Ljungdahl Marvin Bressler Steve VanDevender - Frederick Roeber Matthew Day Teemu Suikki - G. Branden Robinson Merlyn LeRoy Tim Lennan - Gil Neiger Michael Allison Timo Hakulinen - Greg Laskin Michael Feir Tom Almy - Greg Olson Michael Hamel Tom West - Gregg Wonderly Michael Meyer Warren Cheung - Hao-yang Wang Michael Sokolov Warwick Allison - Helge Hafting Mike Engber Yitzhak Sapir - Ingo Paschke Mike Gallop - Irina Rempt-Drijfhout Mike Passaretti - - - - - - - - - - - - - - - - - - - - - - - - - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 @@ -7726,6 +7726,72 @@ + Boudewijn Waijers Johnny Lee Pierre Martineau + Bruce Cox Jon W{tte Ralf Brown + Bruce Holloway Jonathan Handler Ray Chason + Bruce Mewborne Joshua Delahunty Richard Addison + Cameron Root Karl Garrison Richard Beigel + Carl Schelin Keizo Yamamoto Richard P. Hughey + Chris Russo Keith Simpson Rob Menke + David Cohrs Ken Arnold Robin Bandy + David Damerell Ken Arromdee Robin Johnson + David Gentzel Ken Lorber Roderick Schertler + David Hairston Ken Washikita Roland McGrath + Dean Luick Kestrel Gregorich-Trevor Ron Van Iwaarden + Del Lamb Kevin Darcy Ronnen Miller + Derek S. Ray Kevin Hugo Ross Brown + Deron Meranda Kevin Sitze Sascha Wostmann + Dion Nicolaas Kevin Smolkowski Scott Bigham + Dylan O'Donnell Kevin Sweet Scott R. Turner + Eric Backus Lars Huttar Sean Hunt + Eric Hendrickson Leon Arnott Stephen Spackman + Eric R. Smith M. Drew Streib Stefan Thielscher + Eric S. Raymond Malcolm Ryan Stephen White + Erik Andersen Mark Gooderum Steve Creps + Fredrik Ljungdahl Mark Modrall Steve Linhart + Frederick Roeber Marvin Bressler Steve VanDevender + G. Branden Robinson Matthew Day Teemu Suikki + Gil Neiger Merlyn LeRoy Tim Lennan + Greg Laskin Michael Allison Timo Hakulinen + Greg Olson Michael Feir Tom Almy + Gregg Wonderly Michael Hamel Tom West + Hao-yang Wang Michael Meyer Warren Cheung + Helge Hafting Michael Sokolov Warwick Allison + Ingo Paschke Mike Engber Yitzhak Sapir + + + + + + + + + + + + + + + + + + + + + + + + + NetHack 5.0.0 May 2, 2026 + + + + + + NetHack Guidebook 119 + + + Brand and product names are trademarks or registered trademarks of their respective holders. @@ -7782,7 +7848,7 @@ - NetHack 5.0.0 April 16, 2026 + NetHack 5.0.0 May 2, 2026 From 1f7b2c0ef4704bd028f191ecab0fdd3b5c6a788f Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 2 May 2026 10:19:24 -0400 Subject: [PATCH 124/702] another README update --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 055026aea..46ddd8464 100644 --- a/README +++ b/README @@ -18,7 +18,7 @@ Along with the game improvements and bug fixes, NetHack 5.0 strives to make some general architectural improvements to the game or to its building process. Among them, 5.0 has: - * The source code is standard C99. + * The source code is compliant with the C99 standard. * removes barriers to building NetHack on one platform and operating system, for later execution on another (possibly quite different) platform and/or From c4af3448cfa3ad87cbdacd55c88cc82b58a44c30 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 2 May 2026 10:25:34 -0400 Subject: [PATCH 125/702] patchlevel.h wording bit --- include/patchlevel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/patchlevel.h b/include/patchlevel.h index f2c1a667d..599e7270d 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -67,7 +67,7 @@ /* * NetHack 5.0.0, May 2, 2026 * - * Sources changed to C99. + * Sources changed to be compliant with the C99 standard. * level compiler, dungeon compiler, and quest text all replaced with * Lua alternatives. * Refer to doc/fixes5-0-0.txt for a complete list of fixes and changes. From 5c57ac49bfe20819b882f8dd5ca072bb11b40bac Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 2 May 2026 10:27:15 -0400 Subject: [PATCH 126/702] Guidebook wording update --- doc/Guidebook.mn | 2 +- doc/Guidebook.tex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index b32144a6d..60a993cd5 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -6820,7 +6820,7 @@ been released as version 4.0. NetHack 5.0.0 was released on May 2, 2026. .pg The source code for NetHack 5.0.0 was modified and modernized to be -compliant with standard C99. The 5.0.0 release contained over 3100 fixes, +compliant with the C99 standard. The 5.0.0 release contained over 3100 fixes, changes, and updated features. .pg NetHack 5.0 was the first version to replace the lex and yacc level diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 20bd1fcaa..e0c1e43c5 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -7578,7 +7578,7 @@ been released as version 4.0. %.pg \medskip The source code for \textit{NetHack} 5.0.0 was modified and modernized to be -compliant with standard C99. The 5.0.0 release contained over 3100 fixes, +compliant with the C99 standard. The 5.0.0 release contained over 3100 fixes, changes, and updated features. %.pg From f63164efc683fa03dbc164808d8c86d1dc3ab88d Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 2 May 2026 10:37:47 -0400 Subject: [PATCH 127/702] version in NetHackProperties.props --- sys/windows/vs/NetHackProperties.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/windows/vs/NetHackProperties.props b/sys/windows/vs/NetHackProperties.props index 164cc760e..80ac3b7ab 100644 --- a/sys/windows/vs/NetHackProperties.props +++ b/sys/windows/vs/NetHackProperties.props @@ -2,8 +2,8 @@ - 3 - 7 + 5 + 0 0 $(VERSION_MAJOR).$(VERSION_MINOR).$(PATCHLEVEL) 5 From 41ba62618ad7874973482142490fc06539f8485b Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 2 May 2026 10:45:29 -0400 Subject: [PATCH 128/702] placeholder in you --- include/you.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/you.h b/include/you.h index aaddf2111..d788046bf 100644 --- a/include/you.h +++ b/include/you.h @@ -504,6 +504,7 @@ struct you { short mcham; /* vampire mndx if shapeshifted to bat/cloud */ short umovement; /* instead of youmonst.movement */ schar uachieved[N_ACH]; /* list of achievements in the order attained */ + struct monst *umonst; /* for future conversion of &gy.youmonst to u.umonst */ }; /* end of `struct you' */ From 1db2ee5104de6f37992625d141071820f2040127 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 2 May 2026 10:49:43 -0400 Subject: [PATCH 129/702] dat/history sync --- dat/history | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dat/history b/dat/history index 242781643..fba67b7c6 100644 --- a/dat/history +++ b/dat/history @@ -299,9 +299,9 @@ been released as version 4.0. NetHack 5.0.0 was released on May 2, 2026. -The source code for NetHack 5.0.0 was modified and modernized to be -compliant with standard C99. The 5.0.0 release contained over 3100 fixes, -changes, and updated features. +The source code for NetHack 5.0.0 was modified and modernized to be compliant +with the C99 standard. The 5.0.0 release contained over 3100 fixes,changes, +and updated features. NetHack 5.0 was the first version to replace the lex and yacc level and dungeon compilers of past versions, with a new Lua interpreter-based From 681bac6aa18b89953bd3b90dd58065fa1a464585 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sat, 2 May 2026 11:16:10 -0400 Subject: [PATCH 130/702] This is cron-daily v1-Apr-26-2026. 005guidebook updated: doc/Guidebook.txt --- doc/Guidebook.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index ae19710a4..456ff45ae 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -7541,8 +7541,8 @@ NetHack 5.0.0 was released on May 2, 2026. The source code for NetHack 5.0.0 was modified and modernized to - be compliant with standard C99. The 5.0.0 release contained over 3100 - fixes, changes, and updated features. + be compliant with the C99 standard. The 5.0.0 release contained over + 3100 fixes, changes, and updated features. NetHack 5.0 was the first version to replace the lex and yacc level and dungeon compilers of past versions, with a new Lua inter- From 16ff59115315917b93185d026aeefea06db9b0f4 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Sat, 2 May 2026 17:47:25 +0100 Subject: [PATCH 131/702] check_mongen_order shouldn't be compiled into release builds This function is only used during development, so if it's included in a release build, the compiler will warn that it's never used. --- src/makemon.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/makemon.c b/src/makemon.c index 718d7551e..9af36be2f 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -17,7 +17,6 @@ staticfn int align_shift(struct permonst *); staticfn int temperature_shift(struct permonst *); staticfn boolean mk_gen_ok(int, unsigned, unsigned); staticfn int QSORTCALLBACK cmp_init_mongen_order(const void *, const void *); -staticfn void check_mongen_order(void); staticfn void init_mongen_order(void); staticfn boolean wrong_elem_type(struct permonst *); staticfn void m_initgrp(struct monst *, coordxy, coordxy, int, mmflags_nht); @@ -1777,6 +1776,8 @@ cmp_init_mongen_order(const void *p1, const void *p2) return difficulty1 - difficulty2; } +#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) +staticfn void check_mongen_order(void); /* check that monsters are in correct difficulty order for mkclass() */ staticfn void check_mongen_order(void) @@ -1799,6 +1800,7 @@ check_mongen_order(void) } } } +#endif /* initialize monster order for mkclass */ staticfn void From 77040f70c7ac28589fc058ac79b0cd04f85c4349 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 2 May 2026 14:10:04 -0400 Subject: [PATCH 132/702] cross-compiler build fixes --- sys/unix/hints/include/cross-post.500 | 20 ++++++++++---------- sys/unix/hints/include/cross-pre2.500 | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sys/unix/hints/include/cross-post.500 b/sys/unix/hints/include/cross-post.500 index 28b73c8be..d42661b2b 100644 --- a/sys/unix/hints/include/cross-post.500 +++ b/sys/unix/hints/include/cross-post.500 @@ -90,8 +90,8 @@ else fi; ) endif -touch $(TARGETPFX)pkg/RECORD - cd $(TARGETPFX)pkg ; zip -9 ../NH370DOS.ZIP * ; cd ../../.. - @echo msdos package zip file $(TARGETPFX)NH370DOS.ZIP + cd $(TARGETPFX)pkg ; zip -9 ../NH500DOS.ZIP * ; cd ../../.. + @echo msdos package zip file $(TARGETPFX)NH500DOS.ZIP $(LUABIN): ( cd .. && make luabin && cd src) @@ -105,14 +105,14 @@ deploy-to-dosbox: endif .PHONY: deploytodosbox -deploytodosbox: $(TARGETPFX)NH370DOS.ZIP $(dosboxnhfolder) $(dosboxnhsrc) \ +deploytodosbox: $(TARGETPFX)NH500DOS.ZIP $(dosboxnhfolder) $(dosboxnhsrc) \ $(dosboxnhsrc)/src $(dosboxnhsrc)/include \ $(dosboxnhsrc)/sys/msdos $(dosboxnhsrc)/sys/share \ $(dosboxnhsrc)/win/share $(dosboxnhsrc)/win/curses \ $(dosboxnhsrc)/win/tty $(dosboxnhsrc)/util \ $(dosboxnhfolder)/NETHACK.EXE @echo DOS NetHack deployed to dosbox at $(dosboxnhfolder) -$(TARGETPFX)NH370DOS.ZIP: dospkg +$(TARGETPFX)NH500DOS.ZIP: dospkg $(dosboxnhfolder): mkdir -p $@ $(dosboxnhsrc): $(dosboxnhfolder) @@ -144,8 +144,8 @@ $(dosboxnhsrc)/util: $(dosboxnhsrc) mkdir -p $@ cp --preserve=timestamps $(FLDR)util/*.c $(dosboxnhsrc)/util cp --preserve=timestamps $(FLDR)util/*.h $(dosboxnhsrc)/util -$(dosboxnhfolder)/NETHACK.EXE: $(TARGETPFX)NH370DOS.ZIP - unzip -o $(TARGETPFX)NH370DOS.ZIP -d $(dosboxnhfolder) +$(dosboxnhfolder)/NETHACK.EXE: $(TARGETPFX)NH500DOS.ZIP + unzip -o $(TARGETPFX)NH500DOS.ZIP -d $(dosboxnhfolder) find $(dosboxnhfolder) -type f -name "$(dosboxconfigfile)" \ | xargs sed -i 's/#OPTIONS=video:autodetect/OPTIONS=video:autodetect/g' endif # dosbox @@ -225,8 +225,8 @@ mipspkg: dodata $(GAMEBIN) $(TARGETPFX)recover cp ../sys/msdos/sysconf $(TARGETPFX)pkg/sysconf cp ../doc/nethack.txt $(TARGETPFX)pkg/nethack.txt -touch $(TARGETPFX)pkg/record - cd $(TARGETPFX)pkg ; zip -9 ../nh370mips.zip * ; cd ../../.. - @echo MIPS package zip file $(TARGETPFX)nh370mips.zip + cd $(TARGETPFX)pkg ; zip -9 ../nh500mips.zip * ; cd ../../.. + @echo MIPS package zip file $(TARGETPFX)nh500mips.zip endif # CROSS_TO_MIPS @@ -332,8 +332,8 @@ amigapkg: $(AMITILES) ../util/uudecode -( cd $(TARGETPFX)pkg && test -f ../../../sys/amiga/HackWB.uu && \ ../../../util/uudecode ../../../sys/amiga/HackWB.uu ) touch $(TARGETPFX)pkg/record - ( cd $(TARGETPFX)pkg && zip -9r ../NH370AMI.ZIP * ) - @echo amiga package zip file $(TARGETPFX)NH370AMI.ZIP + ( cd $(TARGETPFX)pkg && zip -9r ../NH500AMI.ZIP * ) + @echo amiga package zip file $(TARGETPFX)NH500AMI.ZIP endif # CROSS_TO_AMIGA ifdef CROSS_SHARED diff --git a/sys/unix/hints/include/cross-pre2.500 b/sys/unix/hints/include/cross-pre2.500 index ddc3ba765..40fc51da1 100644 --- a/sys/unix/hints/include/cross-pre2.500 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -146,7 +146,7 @@ ifdef DOSBOX dosbox=$(DOSBOX) endif ifdef dosbox -dosboxgameid=NH370 +dosboxgameid=NH500 dosboxtop=$(dosbox) dosboxnhfolder=$(dosboxtop)/$(dosboxgameid) dosboxnhsrc=$(dosboxnhfolder)/NHSRC From 6b92be3656a11a46abd0f15108e8d96d3d9ebb95 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 2 May 2026 14:12:40 -0400 Subject: [PATCH 133/702] Windows nmake build fix for 5.0.0 --- sys/windows/Makefile.nmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index f97790e5f..f2bfe1e19 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -2785,11 +2785,11 @@ $(SndWavDir)sa2_xplevelup.wav: $(SndWavDir)sa2_xplevelup.uu $(U)uudecode.exe #=============================================================================== PKGFILES = nethackrc.template Guidebook.txt license NetHack.exe NetHack.txt \ - NetHackW.exe opthelp nhdat370 record symbols \ + NetHackW.exe opthelp nhdat500 record symbols \ sysconf.template $(SFCTOOLBASENAM) FILESTOZIP = $(BinDir)nethackrc.template $(BinDir)Guidebook.txt $(BinDir)license \ $(BinDir)NetHack.exe $(BinDir)NetHack.txt $(BinDir)NetHackW.exe \ - $(BinDir)opthelp $(BinDir)nhdat370 $(BinDir)record \ + $(BinDir)opthelp $(BinDir)nhdat500 $(BinDir)record \ $(BinDir)symbols $(BinDir)sysconf.template $(SFCTOOLPKG) DBGSYMS = NetHack.PDB NetHackW.PDB $(SFCTOOLPDBNAM) From a417ca49a2a429f6cb0a4004ada0e85ccf95b082 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 2 May 2026 19:26:05 -0400 Subject: [PATCH 134/702] tag as post-release --- include/patchlevel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/patchlevel.h b/include/patchlevel.h index 599e7270d..94bfacf74 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -30,7 +30,7 @@ /* * Development status of this NetHack version. */ -#define NH_DEVEL_STATUS NH_STATUS_RELEASED +#define NH_DEVEL_STATUS NH_STATUS_POSTRELEASE #ifndef DEBUG /* allow tool chains to define without causing warnings */ #define DEBUG From c2a7bdb3690432bc83fd193399f25fa82e963d9a Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 2 May 2026 22:05:31 -0400 Subject: [PATCH 135/702] less prone to overlooking target names next time --- sys/unix/README-hints | 4 ++-- sys/unix/hints/include/cross-post.500 | 20 ++++++++++---------- sys/unix/hints/include/cross-pre2.500 | 2 +- sys/unix/hints/include/multiw-1.500 | 4 ++++ sys/windows/GNUmakefile | 3 +-- sys/windows/Makefile.nmake | 4 ++-- 6 files changed, 20 insertions(+), 17 deletions(-) diff --git a/sys/unix/README-hints b/sys/unix/README-hints index a666bd9e8..283d1cf29 100644 --- a/sys/unix/README-hints +++ b/sys/unix/README-hints @@ -5,7 +5,7 @@ The sys/unix/hints/include subfolder contains Makefile content that is included in the distributed Makefiles. -[.370 hints] +[.500 hints] There are two .500 series hints files provided with NetHack: @@ -16,7 +16,7 @@ Those will also pull in content from sys/unix/hints/include/*.370, that is shared between the linux.500 and macOS.500 hints files. -[.370 make build options] +[.500 make build options] Here are some options that can be specified on the make command diff --git a/sys/unix/hints/include/cross-post.500 b/sys/unix/hints/include/cross-post.500 index d42661b2b..f4f236e2f 100644 --- a/sys/unix/hints/include/cross-post.500 +++ b/sys/unix/hints/include/cross-post.500 @@ -90,8 +90,8 @@ else fi; ) endif -touch $(TARGETPFX)pkg/RECORD - cd $(TARGETPFX)pkg ; zip -9 ../NH500DOS.ZIP * ; cd ../../.. - @echo msdos package zip file $(TARGETPFX)NH500DOS.ZIP + cd $(TARGETPFX)pkg ; zip -9 ../NH$(NHV)DOS.ZIP * ; cd ../../.. + @echo msdos package zip file $(TARGETPFX)NH$(NHV)DOS.ZIP $(LUABIN): ( cd .. && make luabin && cd src) @@ -105,14 +105,14 @@ deploy-to-dosbox: endif .PHONY: deploytodosbox -deploytodosbox: $(TARGETPFX)NH500DOS.ZIP $(dosboxnhfolder) $(dosboxnhsrc) \ +deploytodosbox: $(TARGETPFX)NH$(NHV)DOS.ZIP $(dosboxnhfolder) $(dosboxnhsrc) \ $(dosboxnhsrc)/src $(dosboxnhsrc)/include \ $(dosboxnhsrc)/sys/msdos $(dosboxnhsrc)/sys/share \ $(dosboxnhsrc)/win/share $(dosboxnhsrc)/win/curses \ $(dosboxnhsrc)/win/tty $(dosboxnhsrc)/util \ $(dosboxnhfolder)/NETHACK.EXE @echo DOS NetHack deployed to dosbox at $(dosboxnhfolder) -$(TARGETPFX)NH500DOS.ZIP: dospkg +$(TARGETPFX)NH$(NHV)DOS.ZIP: dospkg $(dosboxnhfolder): mkdir -p $@ $(dosboxnhsrc): $(dosboxnhfolder) @@ -144,8 +144,8 @@ $(dosboxnhsrc)/util: $(dosboxnhsrc) mkdir -p $@ cp --preserve=timestamps $(FLDR)util/*.c $(dosboxnhsrc)/util cp --preserve=timestamps $(FLDR)util/*.h $(dosboxnhsrc)/util -$(dosboxnhfolder)/NETHACK.EXE: $(TARGETPFX)NH500DOS.ZIP - unzip -o $(TARGETPFX)NH500DOS.ZIP -d $(dosboxnhfolder) +$(dosboxnhfolder)/NETHACK.EXE: $(TARGETPFX)NH$(NHV)DOS.ZIP + unzip -o $(TARGETPFX)NH$(NHV)DOS.ZIP -d $(dosboxnhfolder) find $(dosboxnhfolder) -type f -name "$(dosboxconfigfile)" \ | xargs sed -i 's/#OPTIONS=video:autodetect/OPTIONS=video:autodetect/g' endif # dosbox @@ -225,8 +225,8 @@ mipspkg: dodata $(GAMEBIN) $(TARGETPFX)recover cp ../sys/msdos/sysconf $(TARGETPFX)pkg/sysconf cp ../doc/nethack.txt $(TARGETPFX)pkg/nethack.txt -touch $(TARGETPFX)pkg/record - cd $(TARGETPFX)pkg ; zip -9 ../nh500mips.zip * ; cd ../../.. - @echo MIPS package zip file $(TARGETPFX)nh500mips.zip + cd $(TARGETPFX)pkg ; zip -9 ../nh$(NHV)mips.zip * ; cd ../../.. + @echo MIPS package zip file $(TARGETPFX)nh$(NHV)mips.zip endif # CROSS_TO_MIPS @@ -332,8 +332,8 @@ amigapkg: $(AMITILES) ../util/uudecode -( cd $(TARGETPFX)pkg && test -f ../../../sys/amiga/HackWB.uu && \ ../../../util/uudecode ../../../sys/amiga/HackWB.uu ) touch $(TARGETPFX)pkg/record - ( cd $(TARGETPFX)pkg && zip -9r ../NH500AMI.ZIP * ) - @echo amiga package zip file $(TARGETPFX)NH500AMI.ZIP + ( cd $(TARGETPFX)pkg && zip -9r ../NH$(NHV)AMI.ZIP * ) + @echo amiga package zip file $(TARGETPFX)NH$(NHV)AMI.ZIP endif # CROSS_TO_AMIGA ifdef CROSS_SHARED diff --git a/sys/unix/hints/include/cross-pre2.500 b/sys/unix/hints/include/cross-pre2.500 index 40fc51da1..d7f853721 100644 --- a/sys/unix/hints/include/cross-pre2.500 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -146,7 +146,7 @@ ifdef DOSBOX dosbox=$(DOSBOX) endif ifdef dosbox -dosboxgameid=NH500 +dosboxgameid=NH$(NHV) dosboxtop=$(dosbox) dosboxnhfolder=$(dosboxtop)/$(dosboxgameid) dosboxnhsrc=$(dosboxnhfolder)/NHSRC diff --git a/sys/unix/hints/include/multiw-1.500 b/sys/unix/hints/include/multiw-1.500 index df89d95a5..96f9173e6 100644 --- a/sys/unix/hints/include/multiw-1.500 +++ b/sys/unix/hints/include/multiw-1.500 @@ -19,5 +19,9 @@ #WANT_DEFAULT=Qt #WANT_DEFAULT=X11 +# Based on the NetHack version 5.0.0 +# Used to build some filenames subsequently in other include files +NHV=500 + #end of multiw-1.500 #------------------------------------------------------------------------------ diff --git a/sys/windows/GNUmakefile b/sys/windows/GNUmakefile index e6bc43ec0..cfbcead9e 100644 --- a/sys/windows/GNUmakefile +++ b/sys/windows/GNUmakefile @@ -1388,9 +1388,8 @@ TARGET_CPU = x86 endif endif -NHV=370 PKGFILES = nethackrc.template Guidebook.txt license NetHack.exe NetHack.txt \ - NetHackW.exe opthelp nhdat370 record symbols sysconf.template $(notdir $(LUADLL)) + NetHackW.exe opthelp nhdat$(NHV) record symbols sysconf.template $(notdir $(LUADLL)) FILESTOZIP = $(addprefix $(GAMEDIR)/, $(PKGFILES)) MAINZIP = $(PkgDir)/nethack-$(NHV)-win-$(TARGET_CPU)-msys2.zip diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index f2bfe1e19..080e530be 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -2785,11 +2785,11 @@ $(SndWavDir)sa2_xplevelup.wav: $(SndWavDir)sa2_xplevelup.uu $(U)uudecode.exe #=============================================================================== PKGFILES = nethackrc.template Guidebook.txt license NetHack.exe NetHack.txt \ - NetHackW.exe opthelp nhdat500 record symbols \ + NetHackW.exe opthelp nhdat$(NHV) record symbols \ sysconf.template $(SFCTOOLBASENAM) FILESTOZIP = $(BinDir)nethackrc.template $(BinDir)Guidebook.txt $(BinDir)license \ $(BinDir)NetHack.exe $(BinDir)NetHack.txt $(BinDir)NetHackW.exe \ - $(BinDir)opthelp $(BinDir)nhdat500 $(BinDir)record \ + $(BinDir)opthelp $(BinDir)nhdat$(NHV) $(BinDir)record \ $(BinDir)symbols $(BinDir)sysconf.template $(SFCTOOLPKG) DBGSYMS = NetHack.PDB NetHackW.PDB $(SFCTOOLPDBNAM) From 1947eb98a4a7a62ff7d529de1d69a8572ad09239 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 3 May 2026 07:37:13 -0400 Subject: [PATCH 136/702] CROSS_TO_WASM build fixes --- src/files.c | 4 ++-- sys/libnh/libnhmain.c | 30 ++++++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/files.c b/src/files.c index 5cb092340..1891ba604 100644 --- a/src/files.c +++ b/src/files.c @@ -2050,7 +2050,7 @@ problematic_savefile(int sfstatus, const char *savefilenm) /* ---------- BEGIN EXTERNAL CONVERSION HANDLING ----------- */ -static boolean cvtinit = FALSE; +/* static boolean cvtinit = FALSE; */ #ifndef SFCTOOL static char *unconverted_filename = 0, *converted_filename = 0; @@ -2171,7 +2171,7 @@ free_convert_filenames(void) free((genericptr_t) converted_filename), converted_filename = 0; if (unconverted_filename) free((genericptr_t) unconverted_filename), unconverted_filename = 0; - cvtinit = FALSE; +/* cvtinit = FALSE; */ } /* return TRUE if s contains a directory, not just a filespec */ diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index f974bc490..b0c3f5297 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -51,7 +51,7 @@ extern void init_linux_cons(void); static void wd_message(void); static struct passwd *get_unix_pw(void); -ATTRNORETURN static void opt_terminate(void) NORETURN; +/* ATTRNORETURN static void opt_terminate(void) NORETURN; */ #ifdef __EMSCRIPTEN__ /* if WebAssembly, export this API and don't optimize it out */ @@ -769,6 +769,8 @@ sys_random_seed(void) return seed; } +#if 0 +/* now found in earlyarg.c */ /* for command-line options that perform some immediate action and then terminate the program without starting play, like 'nethack --version' or 'nethack -s Zelda'; do some cleanup before that termination */ @@ -780,7 +782,6 @@ opt_terminate(void) nh_terminate(EXIT_SUCCESS); /*NOTREACHED*/ } - /* show the sysconf file name, playground directory, run-time configuration file name, dumplog file name if applicable, and some other things */ ATTRNORETURN void @@ -794,6 +795,31 @@ after_opt_showpaths(const char *dir) opt_terminate(); /*NOTREACHED*/ } +#endif + +void +get_nhuuid(void) +{ + unsigned char stmp[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + if (svn.nhuuid[0]) + return; + + /* FIXME: fill in a useful valid UUID somehow */ + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", (char *) stmp); +} + +void +free_nhuuid(void) +{ + int i; + + for (i = 0; i < SIZE(svn.nhuuid); i++) { + svn.nhuuid[i] = 0; + } +} #ifdef __EMSCRIPTEN__ /*** From d9da3196227902ec4c57415ed828b8e68ba25621 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Sun, 3 May 2026 17:48:15 +0200 Subject: [PATCH 137/702] Amiga: honor __stack under libnix Reference __stkinit so the linker pulls swapstack.o from libnix.a; without it the program runs on the inherited shell stack and crashes inside Lua / level-gen. --- sys/amiga/amistack.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/amiga/amistack.c b/sys/amiga/amistack.c index 2d38b552a..84ae496e1 100644 --- a/sys/amiga/amistack.c +++ b/sys/amiga/amistack.c @@ -22,6 +22,10 @@ #ifdef __SASC_60 long __stack = 256 * 1024; #else -/* For GCC with -noixemul (libnix), __stack is also recognized */ +/* libnix needs __stkinit referenced to pull swapstack.o from libnix.a */ unsigned long __stack = 256 * 1024; +#ifdef CROSS_TO_AMIGA +extern void __stkinit(void); +void *__nh_force_stkinit = __stkinit; +#endif #endif From 2a59726f1851120d406171618615acfce16c2d28 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Sun, 3 May 2026 17:48:22 +0200 Subject: [PATCH 138/702] Amiga: disable SYSCF, drop sysconf from package SYSCF is for multi-user system-admin lockdown; single-user Amigas don't need it, and assure_syscf_file() killing the binary when run outside NetHack: was breaking normal launches. --- include/amiconf.h | 3 +++ sys/unix/hints/include/cross-post.500 | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/amiconf.h b/include/amiconf.h index 17b03c2eb..a362c94f8 100644 --- a/include/amiconf.h +++ b/include/amiconf.h @@ -212,4 +212,7 @@ struct ami_sysflags { }; extern struct ami_sysflags sysflags; +#undef SYSCF +#undef SYSCF_FILE + #endif /* AMICONF_H */ diff --git a/sys/unix/hints/include/cross-post.500 b/sys/unix/hints/include/cross-post.500 index f4f236e2f..8e67cfa4f 100644 --- a/sys/unix/hints/include/cross-post.500 +++ b/sys/unix/hints/include/cross-post.500 @@ -318,7 +318,6 @@ amigapkg: $(AMITILES) ../util/uudecode cp $(TARGETPFX)tiles16.iff $(TARGETPFX)pkg/tiles/tiles16.iff cp $(TARGETPFX)tiles32.iff $(TARGETPFX)pkg/tiles/tiles32.iff cp $(TARGETPFX)tomb.iff $(TARGETPFX)pkg/tomb.iff - cp ../sys/msdos/sysconf $(TARGETPFX)pkg/sysconf cp ../doc/nethack.txt $(TARGETPFX)pkg/nethack.txt ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/amifont8.uu && mv 8 hack/8 ) ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/amifont.uu ) From b6747f89ca4d0c1a3da1fecf01808aec59182ab2 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Sun, 3 May 2026 17:48:30 +0200 Subject: [PATCH 139/702] Amiga: fall back to text mode when tile mode is not viable Detect Workbench depth, display-database MaxDepth, and free chip RAM; if any signals AMIV can't run (e.g. A1000 with 4-colour WB), swap windowprocs to amii_procs before opening any screens. --- sys/amiga/nethack.cnf | 5 ++++- sys/amiga/winfuncs.c | 45 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/sys/amiga/nethack.cnf b/sys/amiga/nethack.cnf index 84dd3d60b..b594c3d99 100644 --- a/sys/amiga/nethack.cnf +++ b/sys/amiga/nethack.cnf @@ -5,7 +5,10 @@ # *** DISPLAY MODE *** # -# Tile mode (graphical tiles, recommended): +# Tile mode (graphical tiles, recommended). Needs >=384 KB free chip +# RAM and a display mode that can open at 4 bitplanes (16 colours); on +# machines that can't, NetHack will automatically fall back to text +# mode at startup. OPTIONS=windowtype:amiv # # Text mode (uses hack.font line-drawing characters): diff --git a/sys/amiga/winfuncs.c b/sys/amiga/winfuncs.c index 7d451a665..e39af4a5d 100644 --- a/sys/amiga/winfuncs.c +++ b/sys/amiga/winfuncs.c @@ -886,6 +886,49 @@ int return 0; } +/* Fall back from AMIV (tile) to AMII (text) if this machine can't + * run tile mode. Probes in order of reliability. */ +static void +amii_fall_back(const char *why1, const char *why2) +{ + extern struct window_procs amii_procs; + + raw_print(why1); + raw_print(why2); + raw_print("Falling back to text mode. Set windowtype:amiv in"); + raw_print("nethack.cnf to override."); + windowprocs = amii_procs; + ami_wininit_data(WININIT); +} + +static void +amii_maybe_fall_back_to_text(void) +{ + if (!WINVERS_AMIV) + return; + + if (IntuitionBase->LibNode.lib_Version >= 37) { + struct Screen *wbscr; + int wb_depth = -1; + + if ((wbscr = LockPubScreen("Workbench")) != NULL) { + wb_depth = wbscr->BitMap.Depth; + UnlockPubScreen(NULL, wbscr); + } + if (wb_depth >= 0 && wb_depth < 4) { + amii_fall_back("Workbench screen is shallower than 16 colours", + "(tile mode requires depth >= 4)."); + return; + } + } + + if (AvailMem(MEMF_CHIP) < 384L * 1024L) { + amii_fall_back("Not enough chip RAM available for tile mode", + "(< 384 KB free)."); + return; + } +} + /* Initialize the windowing environment */ void @@ -951,6 +994,8 @@ amii_init_nhwindows(int *argcp, char **argv) Abort(AG_OpenLib); } + amii_maybe_fall_back_to_text(); + amiIDisplay = (struct amii_DisplayDesc *) alloc(sizeof(struct amii_DisplayDesc)); memset(amiIDisplay, 0, sizeof(struct amii_DisplayDesc)); From ced26a2ceaa34a6dec0dc71e82c724c34b408733 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 3 May 2026 13:06:54 -0400 Subject: [PATCH 140/702] update get_nhuuid() for libnhmain Try using emscripten_run_script_string("crypto.randomUUID()"); I need to commit this to the repository to test it elsewhere. If there isn't a revert shortly after this, it must have at least built without issue. --- sys/libnh/libnhmain.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index b0c3f5297..93062ab7e 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -800,6 +800,7 @@ after_opt_showpaths(const char *dir) void get_nhuuid(void) { + char *uuid = NULL; unsigned char stmp[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -807,8 +808,11 @@ get_nhuuid(void) if (svn.nhuuid[0]) return; - /* FIXME: fill in a useful valid UUID somehow */ - Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", (char *) stmp); + uuid = emscripten_run_script_string("crypto.randomUUID()"); + if (!uuid) { + uuid = (char *) &stmp[0]; + } + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", uuid); } void From a55ca016eb225c003e223a8b49c16b9e173136e0 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 3 May 2026 13:18:37 -0400 Subject: [PATCH 141/702] hints file update for wasm CFLAGS to include -DNHUUID --- sys/unix/hints/include/cross-pre2.500 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/unix/hints/include/cross-pre2.500 b/sys/unix/hints/include/cross-pre2.500 index d7f853721..03c35bcc7 100644 --- a/sys/unix/hints/include/cross-pre2.500 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -329,7 +329,7 @@ WASM_CFLAGS += -Wshadow # WASM_CFLAGS += -Werror # Nethack C flags WASM_CFLAGS += $(WINCFLAGS) #WINCFLAGS set from multiw-2.500 -WASM_CFLAGS += -DSYSCF -DSYSCF_FILE=\"/sysconf\" -DSECURE +WASM_CFLAGS += -DSYSCF -DSYSCF_FILE=\"/sysconf\" -DSECURE -DNHUUID #WASM_CFLAGS += -g -I../include -DNOTPARMDECL WASM_CFLAGS += -I../include -DNOTPARMDECL # NetHack sources control From b6482d09f4592a632d7683f17b8973f920ee8fe3 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 3 May 2026 13:26:36 -0400 Subject: [PATCH 142/702] libnhmain follow-up --- sys/libnh/libnhmain.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index 93062ab7e..c4516ae83 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -800,18 +800,22 @@ after_opt_showpaths(const char *dir) void get_nhuuid(void) { - char *uuid = NULL; unsigned char stmp[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + char *uuid = (char *) &stmp[0]; if (svn.nhuuid[0]) return; +#ifndef NONHUUID +#ifdef NHUUID uuid = emscripten_run_script_string("crypto.randomUUID()"); if (!uuid) { uuid = (char *) &stmp[0]; } +#endif /* NHUUID */ +#endif /* NONHUUID */ Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", uuid); } From b92c1483bbbfdf22079e5d1202f0171f6e2c1c98 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 3 May 2026 14:11:47 -0400 Subject: [PATCH 143/702] another libnhmain.c follow-up Check if it's available before calling. --- sys/libnh/libnhmain.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index c4516ae83..d75dae749 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -804,15 +804,21 @@ get_nhuuid(void) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; char *uuid = (char *) &stmp[0]; + int uuid_available = 0; if (svn.nhuuid[0]) return; #ifndef NONHUUID #ifdef NHUUID - uuid = emscripten_run_script_string("crypto.randomUUID()"); - if (!uuid) { - uuid = (char *) &stmp[0]; + uuid_available = emscripten_run_script_int( + "typeof crypto !== 'undefined'" + " && typeof crypto.randomUUID === 'function'"); + if (uuid_available) { + uuid = emscripten_run_script_string("crypto.randomUUID()"); + if (!uuid) { + uuid = (char *) &stmp[0]; + } } #endif /* NHUUID */ #endif /* NONHUUID */ From 3a753dc98e76b4d7addda9cfba3c08e066e27840 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 3 May 2026 14:13:28 -0400 Subject: [PATCH 144/702] yet another follow-up --- sys/libnh/libnhmain.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index d75dae749..90907f987 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -804,7 +804,11 @@ get_nhuuid(void) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; char *uuid = (char *) &stmp[0]; +#ifndef NONHUUID +#ifdef NHUUID int uuid_available = 0; +#endif +#endif if (svn.nhuuid[0]) return; From f1393bdf6c5318e00d32be9af3e6193c51574e55 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 4 May 2026 12:35:33 +0200 Subject: [PATCH 145/702] Amiga: wire altmeta option to sysflags.altmeta --- include/optlist.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/optlist.h b/include/optlist.h index 9cba2107c..c723e4981 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -159,6 +159,10 @@ static int optfn_##a(int, int, boolean, char *, char *); NHOPTB(altmeta, Advanced, 0, opt_out, set_in_game, Off, Yes, No, No, NoAlias, &iflags.altmeta, Term_False, "treat \"ESC c\" as M-c (Meta+c, 8th bit set)") +#elif defined(AMIGA_INTUITION) + NHOPTB(altmeta, Advanced, 0, opt_out, set_in_game, + On, Yes, No, No, NoAlias, &sysflags.altmeta, Term_False, + "treat ALT+c as M-c (Meta+c, 8th bit set)") #else NHOPTB(altmeta, Advanced, 0, opt_out, set_in_config, Off, Yes, No, No, NoAlias, (boolean *) 0, Term_False, From 691a8dd7d21f21caff345be351df8ac7e519fd60 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 4 May 2026 12:37:34 +0200 Subject: [PATCH 146/702] Amiga: promote AMIGA_INTUITION to supported so it shows up in version info --- src/mdlib.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/mdlib.c b/src/mdlib.c index 9096f6ee3..6683a28f5 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -142,6 +142,10 @@ static struct win_information window_opts[] = { #ifdef SHIM_GRAPHICS { "shim", "NetHack Library Windowing Shim", TRUE }, #endif +#ifdef AMIGA_INTUITION + { "amii", "Amiga Intuition (text)", TRUE }, + { "amiv", "Amiga Intuition (tiles)", TRUE }, +#endif #if 0 /* remainder have been retired */ #ifdef GNOME_GRAPHICS /* unmaintained/defunct */ @@ -150,9 +154,6 @@ static struct win_information window_opts[] = { #ifdef MACOS9 /* defunct OS 9 interface */ { "mac", "Mac", TRUE }, #endif -#ifdef AMIGA_INTUITION /* unmaintained/defunct */ - { "amii", "Amiga Intuition", TRUE }, -#endif #ifdef GEM_GRAPHICS /* defunct Atari interface */ { "Gem", "Gem", TRUE }, #endif From 548f356cbd0dd88faf4ce8df516c8de111fe053a Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 4 May 2026 12:38:21 +0200 Subject: [PATCH 147/702] Amiga: default number_pad:1 in shipped nethack.cnf --- sys/amiga/nethack.cnf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/amiga/nethack.cnf b/sys/amiga/nethack.cnf index b594c3d99..95952d6a6 100644 --- a/sys/amiga/nethack.cnf +++ b/sys/amiga/nethack.cnf @@ -20,6 +20,8 @@ OPTIONS=time,showexp,lit_corridor OPTIONS=boulder:0 OPTIONS=autopickup,pickup_types:$"=/!?+ OPTIONS=catname:Kaori +# Numpad for movement; '5' is the run prefix, ALT+5 the rush prefix. +OPTIONS=number_pad:1 # *** MENU COLORS *** # Colour-code inventory items by BUC status and value. From b72f5cb9a2923cd8791649b5de2b2562f0ceb8b3 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 4 May 2026 12:42:10 +0200 Subject: [PATCH 148/702] Amiga: stop rendering CLR_BLACK and CLR_WHITE as inverse video --- sys/amiga/winchar.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sys/amiga/winchar.c b/sys/amiga/winchar.c index 75c35c87b..0c9dbc6b2 100644 --- a/sys/amiga/winchar.c +++ b/sys/amiga/winchar.c @@ -837,11 +837,14 @@ static char amii_glyph_buffer[GLYPH_BUFFER_SIZE]; * See winami.c for the amiga specific colormap. */ +/* CLR_BLACK (slot 0) renders as the dim blue pen on black background, + CLR_WHITE (slot 15) uses white on black. Slots 9-14 use the inverse- + video trick (fg=black, bg=color) to fit 16 logical colors into 8 pens. */ int foreg[AMII_MAXCOLORS] = { - 0, 7, 4, 2, 6, 5, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0 + 6, 7, 4, 2, 6, 5, 3, 1, 1, 0, 0, 0, 0, 0, 0, 1 }; int backg[AMII_MAXCOLORS] = { - 1, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 1, 6, 5, 3, 1 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 1, 6, 5, 3, 0 }; #if 0 #define CLR_BLACK 0 From 82efba55f23dc460c43b651477ae0eabc5f33a08 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 4 May 2026 12:42:36 +0200 Subject: [PATCH 149/702] Amiga: fix misleading fallback warning and stale comment --- sys/amiga/winfuncs.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sys/amiga/winfuncs.c b/sys/amiga/winfuncs.c index e39af4a5d..ba7835775 100644 --- a/sys/amiga/winfuncs.c +++ b/sys/amiga/winfuncs.c @@ -886,8 +886,7 @@ int return 0; } -/* Fall back from AMIV (tile) to AMII (text) if this machine can't - * run tile mode. Probes in order of reliability. */ +/* Switch from AMIV (tile) to AMII (text) and tell the player why. */ static void amii_fall_back(const char *why1, const char *why2) { @@ -895,8 +894,8 @@ amii_fall_back(const char *why1, const char *why2) raw_print(why1); raw_print(why2); - raw_print("Falling back to text mode. Set windowtype:amiv in"); - raw_print("nethack.cnf to override."); + raw_print("Falling back to text mode. Set windowtype:amii in"); + raw_print("nethack.cnf to suppress this warning."); windowprocs = amii_procs; ami_wininit_data(WININIT); } From 60d59f4d5574c00cbb391cd58da3ed959de1ba2b Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 4 May 2026 08:23:56 -0400 Subject: [PATCH 150/702] early startup options could be run non-interactively https://github.com/NetHack/NetHack/issues/1512 Closes #1512 --- win/tty/wintty.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/win/tty/wintty.c b/win/tty/wintty.c index e7e11e9f2..f509cbc51 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -766,6 +766,8 @@ getret(void) #if defined(MICRO) || defined(WIN32CON) getreturn("to continue"); #else + if (!isatty(STDIN_FILENO)) + return; HUPSKIP(); xputs("\n"); if (flags.standout) From 400c458feef0c095451c8e7e7222eb4385bafced Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 4 May 2026 09:06:52 -0400 Subject: [PATCH 151/702] fix copyright release details GitHub issue https://github.com/NetHack/NetHack/issues/1513 Starting a new game, at the 'Shall I pick character's race, role, gender and alignment for you? [ynaq]' prompt, the game shows as 'Version 5.0.0-0 Unix Work-in-progress' but then once the game has started and you check #version you see the correct 'Unix NetHack Version 5.0.0-0 post-release' feedback. Closes #1513 --- src/mdlib.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/mdlib.c b/src/mdlib.c index 9096f6ee3..ebc3630be 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -355,14 +355,16 @@ bannerc_string(char *outbuf, size_t bufsz, const char *build_date) subbuf[0] = ' '; Strcpy(&subbuf[1], PORT_SUB_ID); #endif + #if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) #if (NH_DEVEL_STATUS == NH_STATUS_BETA) - Strcat(subbuf, " Beta"); -#else - Strcat(subbuf, " Work-in-progress"); + Strcpy(subbuf, " Beta"); +#elif (NH_DEVEL_STATUS == NH_STATUS_WIP) + Strcpy(subbuf, " Work-in-progress"); +#elif (NH_DEVEL_STATUS == NH_STATUS_POSTRELEASE) + Strcpy(subbuf, " post-release"); #endif -#endif - +#endif /* !NH_STATUS_RELEASED */ Snprintf(outbuf, bufsz, " Version %s %s%s, %s %s.", mdlib_version_string(versbuf, "."), PORT_ID, subbuf, date_via_env ? "revised" : "built", build_date); From 9a909be7c54d66198766f28a98993e4d0b8cdaae Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 4 May 2026 14:54:15 +0200 Subject: [PATCH 152/702] Amiga: auto-assign NetHack: to the program directory --- sys/amiga/amidos.c | 17 +++++++++++++++++ sys/amiga/amidos.p | 1 + sys/share/pcmain.c | 2 ++ sys/unix/hints/include/cross-pre1.500 | 1 + 4 files changed, 21 insertions(+) diff --git a/sys/amiga/amidos.c b/sys/amiga/amidos.c index 01d33343f..c07c52884 100644 --- a/sys/amiga/amidos.c +++ b/sys/amiga/amidos.c @@ -30,6 +30,23 @@ int getpid(void) { return (int)FindTask(NULL); } #endif +/* Point NetHack: at the directory we were launched from. Works for both + CLI ("nethack") and Workbench (icon double-click) launches, since + GetProgramDir() (V37+) resolves both. Any existing assign is replaced; + it would just be stale state from a previous install or session. */ +void +amiga_self_assign(void) +{ + BPTR dup; + + if (GetProgramDir() == 0) + return; + if ((dup = DupLock(GetProgramDir())) == 0) + return; + if (!AssignLock("NetHack", dup)) + UnLock(dup); +} + #ifdef AZTEC_50 #include #undef strcmpi diff --git a/sys/amiga/amidos.p b/sys/amiga/amidos.p index ed669f563..83decbc17 100644 --- a/sys/amiga/amidos.p +++ b/sys/amiga/amidos.p @@ -18,6 +18,7 @@ int abs(int ); #endif int tgetch (void); int dosh (void); +void amiga_self_assign (void); long freediskspace(char *); long filesize(char *); void eraseall(const char * , const char *); diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index 3ad30b682..56ee47938 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -255,6 +255,8 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ #endif } #ifdef AMIGA + /* Point NetHack: at our program directory; covers CLI and WB launch. */ + amiga_self_assign(); #ifdef CHDIR /* * If we're dealing with workbench, change the directory. Otherwise diff --git a/sys/unix/hints/include/cross-pre1.500 b/sys/unix/hints/include/cross-pre1.500 index b252f0843..9c8c0a24c 100644 --- a/sys/unix/hints/include/cross-pre1.500 +++ b/sys/unix/hints/include/cross-pre1.500 @@ -42,6 +42,7 @@ ifdef CROSS_TO_AMIGA CROSS=1 BUILD_TARGET_LUA=1 CROSS_SHARED=1 +HACKDIR=NetHack: override TARGET = amiga override TARGETDIR=../targets/$(TARGET) override TARGETPFX = $(TARGETDIR)/ From d94fb08f8b90f44d09e16ac838dc618c723b784b Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 4 May 2026 14:54:20 +0200 Subject: [PATCH 153/702] Amiga: ship Workbench icons for the binary and text files --- sys/amiga/NHinfo.uu | 11 +++++++++++ sys/amiga/cnf-info.uu | 23 +++++++++++++++++++++++ sys/amiga/license-info.uu | 23 +++++++++++++++++++++++ sys/amiga/txt-info.uu | 23 +++++++++++++++++++++++ sys/unix/hints/include/cross-post.500 | 12 ++++-------- 5 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 sys/amiga/NHinfo.uu create mode 100644 sys/amiga/cnf-info.uu create mode 100644 sys/amiga/license-info.uu create mode 100644 sys/amiga/txt-info.uu diff --git a/sys/amiga/NHinfo.uu b/sys/amiga/NHinfo.uu new file mode 100644 index 000000000..4659aa02f --- /dev/null +++ b/sys/amiga/NHinfo.uu @@ -0,0 +1,11 @@ +begin 664 nethack.info +MXQ```0```````````"``(``$``,``0````$````````````````````````` +M`````P```````````````````````````````````(`````````@`"```@`` +M``$#````````````````````````````#___\`]P'O`/(`3P"0``D`D!D-`/ +M?_[P"!K\D`AJ_-`/'?[P#S?^\`\\_O`/;GSP#RN\\`^>_?`/AOGP#YOY\`Y) +M]O`,9>9P")?9,`F8N9`/G'G0"3[\4`A__A`/___P```````````````````` +M`````````````````````````@```0=0``R?`2`-_T`@!8&00`?]W@`.FMP@ +M#.K80`&=_@``M\H``+S:``'N<0``JYP``-[_```&^```.]P``.G=@`&UX,`# +GG_%@"`!X``T`) +M2*@'``````````````````````@'^``(````"`?`>`@````(!^``"`````@' +MP``(````"`>`?@@````(`^``"`````@!_^`(````"`'_``@````(`?Y_"``` +M``@`__`(````"`#\``@````8`WP7___T'^UO_!?___0?Z__\%___]!_ +MO_?P7___T'____!?___0?___\%___^!__]>`7___P'___P@@```0`````/__ +M__"````(H```((%```"@```@@@`2`*```""`@```H```((!*@`"@```@@)(` +M`*```""`4A(`H```((!*0`"@```@@%```*```""`0`@`H```((````"@```@ +M@````*```!"``"APH```((```(`````(`````````!)$2#`Z5&]O;',O161I +.=%!A9``````(`````0`` +` +end diff --git a/sys/amiga/license-info.uu b/sys/amiga/license-info.uu new file mode 100644 index 000000000..398d9aed5 --- /dev/null +++ b/sys/amiga/license-info.uu @@ -0,0 +1,23 @@ +begin 644 license.info +MXQ```0``````(``4`!X`'@`&``$``0?ZD2@'^J`!X``T`) +M1X`'``````````````````````@'^``(````"`?`>`@````(!^``"`````@' +MP``(````"`>`?@@````(`^``"`````@!_^`(````"`'_``@````(`?Y_"``` +M``@`__`(````"`#\``@````8`WP7___T'^UO_!?___0?Z__\%___]!_ +MO_?P7___T'____!?___0?___\%___^!__]>`7___P'___P@@```0`````/__ +M__"````(H```((%```"@```@@@`2`*```""`@```H```((!*@`"@```@@)(` +M`*```""`4A(`H```((!*0`"@```@@%```*```""`0`@`H```((````"@```@ +M@````*```!"``"APH```((```(`````(`````````!)$2#`Z5&]O;',O161I +.=%!A9``````(`````0`` +` +end diff --git a/sys/amiga/txt-info.uu b/sys/amiga/txt-info.uu new file mode 100644 index 000000000..d898dec9d --- /dev/null +++ b/sys/amiga/txt-info.uu @@ -0,0 +1,23 @@ +begin 644 nethack.txt.info +MXQ```0``````(``4`!X`'@`&``$``4`)%KA`"1E8```````````````````` +M```!!`!`"3\8!X9\*````+(````&`````````````"`````````>`!X``T`) +M1$`'``````````````````````@'^``(````"`?`>`@````(!^``"`````@' +MP``(````"`>`?@@````(`^``"`````@!_^`(````"`'_``@````(`?Y_"``` +M``@`__`(````"`#\``@````8`WP7___T'^UO_!?___0?Z__\%___]!_ +MO_?P7___T'____!?___0?___\%___^!__]>`7___P'___P@@```0`````/__ +M__"````(H```((%```"@```@@@`2`*```""`@```H```((!*@`"@```@@)(` +M`*```""`4A(`H```((!*0`"@```@@%```*```""`0`@`H```((````"@```@ +M@````*```!"``"APH```((```(`````(`````````!)$2#`Z5&]O;',O161I +.=%!A9``````(`````0`` +` +end diff --git a/sys/unix/hints/include/cross-post.500 b/sys/unix/hints/include/cross-post.500 index 8e67cfa4f..23d96312c 100644 --- a/sys/unix/hints/include/cross-post.500 +++ b/sys/unix/hints/include/cross-post.500 @@ -322,14 +322,10 @@ amigapkg: $(AMITILES) ../util/uudecode ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/amifont8.uu && mv 8 hack/8 ) ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/amifont.uu ) cp $(AMISRC)/nethack.cnf $(TARGETPFX)pkg/nethack.cnf - -( cd $(TARGETPFX)pkg && test -f ../../../sys/amiga/dflticon.uu && \ - ../../../util/uudecode ../../../sys/amiga/dflticon.uu ) - -( cd $(TARGETPFX)pkg && test -f ../../../sys/amiga/NHinfo.uu && \ - ../../../util/uudecode ../../../sys/amiga/NHinfo.uu ) - -( cd $(TARGETPFX)pkg && test -f ../../../sys/amiga/NewGame.uu && \ - ../../../util/uudecode ../../../sys/amiga/NewGame.uu ) - -( cd $(TARGETPFX)pkg && test -f ../../../sys/amiga/HackWB.uu && \ - ../../../util/uudecode ../../../sys/amiga/HackWB.uu ) + ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/NHinfo.uu ) + ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/cnf-info.uu ) + ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/license-info.uu ) + ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/txt-info.uu ) touch $(TARGETPFX)pkg/record ( cd $(TARGETPFX)pkg && zip -9r ../NH$(NHV)AMI.ZIP * ) @echo amiga package zip file $(TARGETPFX)NH$(NHV)AMI.ZIP From 5852e8c2a079327064f83cd1d92ed30a8ed86e55 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 4 May 2026 15:28:59 +0200 Subject: [PATCH 154/702] Amiga: ship as a NetHack drawer with drawer icon and README --- sys/amiga/README.amiga | 93 ++++++++++++++------------- sys/amiga/drawer-info.uu | 17 +++++ sys/amiga/readme-info.uu | 35 ++++++++++ sys/unix/hints/include/cross-post.500 | 39 +++++------ 4 files changed, 123 insertions(+), 61 deletions(-) create mode 100644 sys/amiga/drawer-info.uu create mode 100644 sys/amiga/readme-info.uu diff --git a/sys/amiga/README.amiga b/sys/amiga/README.amiga index cc83a832d..436a4aea4 100644 --- a/sys/amiga/README.amiga +++ b/sys/amiga/README.amiga @@ -3,9 +3,9 @@ Requirements ------------ - - AmigaOS 3.0 or later (Kickstart 39+) - - 6 MB free RAM minimum (8 MB recommended) - - Hard drive with ~5 MB free space + - AmigaOS 3.0 or later (Kickstart 39+) + - 6 MB free RAM minimum (8 MB recommended) + - Hard drive with ~5 MB free space Recommended: RTG graphics card (Picasso96/CyberGraphX) for best tile rendering. Native AGA/OCS/ECS chipsets are supported. @@ -13,56 +13,62 @@ tile rendering. Native AGA/OCS/ECS chipsets are supported. Installation ------------ -Extract NH370AMI.ZIP to a directory and assign it: +Extract NH500AMI.ZIP somewhere on your hard drive (e.g. into Work:). +You'll get a NetHack drawer with everything inside. - assign NetHack: +To play from Workbench, open the NetHack drawer and double-click the +nethack icon. -The directory should contain: - nethack - game binary - nhdat - data library - symbols - symbol set definitions - sysconf - system configuration - nethack.cnf - game options - hack.font - font descriptor - hack/8 - font bitmap (8pt) - tiles/tiles16.iff - 16-color tiles (OCS/ECS) - tiles/tiles32.iff - 32-color tiles (AGA/RTG) - tomb.iff - tombstone image - record - high score file +To play from a Shell: -To play: - cd NetHack: - nethack + Work:NetHack/nethack + +To redirect to a different install -- for example to test two versions +side by side -- set the NETHACKDIR (or HACKDIR) environment variable +before launching: + + setenv NETHACKDIR Work:games/nethack-dev/ + Work:games/nethack-dev/nethack Display Modes ------------- -Two display modes are available, selected in nethack.cnf: - - Text mode (AMII): - OPTIONS=symset:AmigaFont - - Tile mode (AMIV): - OPTIONS=windowtype:amiv +The shipped nethack.cnf selects tile mode (AMIV). AMIV needs a screen +with at least 4 bitplanes (16 colours) and ~384 KB free chip RAM; on +machines that don't qualify, the binary automatically falls back to +text mode (AMII) at startup with a short note explaining why. Tile mode auto-selects tiles32.iff (32 colors, 5 bitplanes) when the screen supports 32+ colors, otherwise tiles16.iff (16 colors, 4 planes). +To force text mode unconditionally, edit nethack.cnf: + + #OPTIONS=windowtype:amiv + OPTIONS=windowtype:amii + OPTIONS=symset:AmigaFont + Configuration ------------- -Edit nethack.cnf for game options. Key settings: +Edit nethack.cnf for game options. Defaults shipped: - OPTIONS=windowtype:amiv - tile graphics (default) - OPTIONS=symset:AmigaFont - text mode with line-drawing chars - OPTIONS=menucolors - colored inventory items - OPTIONS=time,lit_corridor - show turn count, lit corridors - OPTIONS=boulder:0 - display boulders as '0' + OPTIONS=windowtype:amiv - tile graphics + OPTIONS=number_pad:1 - numpad movement; '5' is run prefix + OPTIONS=time,showexp - turn count, experience visible + OPTIONS=lit_corridor - show lit corridors + OPTIONS=menucolors - colored inventory items -Menu color examples (add after OPTIONS=menucolors): - MENUCOLOR=" blessed "=green - MENUCOLOR=" cursed "=red - MENUCOLOR=" uncursed "=cyan +ALT+letter shortcuts to extended commands (ALT+L for #loot, ALT+F for +#force, etc.) are enabled by default. On keymaps that need ALT for +typing characters (Scandinavian, German, French, ...) disable with: + + OPTIONS=!altmeta + +Menu color examples (after OPTIONS=menucolors): + + MENUCOLOR=" blessed "=green + MENUCOLOR=" cursed "=red + MENUCOLOR=" uncursed "=cyan Building from Source @@ -79,18 +85,19 @@ Cross-compilation from Linux using bebbo's m68k-amigaos-gcc toolchain make CROSS_TO_AMIGA=1 all make CROSS_TO_AMIGA=1 package -The distribution ZIP is created at targets/amiga/NH370AMI.ZIP. +The distribution ZIP is created at targets/amiga/NH500AMI.ZIP. Toolchain requirements: - - m68k-amigaos-gcc (bebbo's amigaos-cross-toolchain in /opt/amiga) - - -noixemul (libnix) for linking - - -m68000 for maximum compatibility (or -m68020/040/060) + + - m68k-amigaos-gcc (bebbo's amigaos-cross-toolchain in /opt/amiga) + - -noixemul (libnix) for linking + - -m68000 for maximum compatibility (or -m68020/040/060) Known Issues ------------ - - Native Amiga compilation (SAS/C, DICE) is not supported; - cross-compilation with GCC is required + - Native Amiga compilation (SAS/C, DICE) is not supported; + cross-compilation with GCC is required Credits diff --git a/sys/amiga/drawer-info.uu b/sys/amiga/drawer-info.uu new file mode 100644 index 000000000..cddf5a258 --- /dev/null +++ b/sys/amiga/drawer-info.uu @@ -0,0 +1,17 @@ +begin 644 NetHack.info +MXQ```0`````!HP`/`#D`#@`&``$``0`SE&``-K,H```````````````````` +M```!`@```````````(````"``````#!?4````````!```+@`30%R`$K__P`` +M```"`!!_`#:X9@``````+N.D````````````7@!!_____P`!```````````` +M`````#D`#@`"``%O4`,`````````````````#_______Y``,```````$``@` +M`````"0`"``)_R``)``(``G5(``D``@`"``@`"0`"``'_\``)``(```````D +M``G______^0`````````!``/_______\```````````````````````_____ +M___X`#```````!@`,_______^``W_______8`#?_]@#?_]@`-__V*M__V``W +M__?_W__8`#?_^``__]@`-_______V``V```````8`#________@````````` +M```````````````````````````````Y``X``@`!<#`#```````````````` +M``_______^0`&JJJJJJJM``U5555555<`'________P`0```````!`!````` +M```&`$``"?\@``8`0``)U2``!H!```@`(``&@$``!__```:`0```````!H!_ +M_______^@`*JJJJJJJJ`/_______^``P```````8`"*JJJJJJJ@`!5555555 +M4````````````#________@`/_______^``___8`W__X`#__]BK?__@`/__W +K_]__^``___@`/__X`#________@```````````````````````````$````` +` +end diff --git a/sys/amiga/readme-info.uu b/sys/amiga/readme-info.uu new file mode 100644 index 000000000..9b819be15 --- /dev/null +++ b/sys/amiga/readme-info.uu @@ -0,0 +1,35 @@ +begin 644 README.amiga.info +MXQ```0``````#P!(`"<`(P`&``$``4`&_1A`!QW@```````````````````` +M```!!`!`!QWX!X8V<(````"``````````````````!`````````G`",``T`' +M(S`'```````````$```````%````'``$@```.``$0```\``$(```8``$$``` +M0``'^``````![```````#@`!___`!@``````!@`!____A@`0````!@`!___^ +M!@``````!@`!_\``!@``````!@``````!@`!____A@``````!@`!___\!@`0 +M````!@`!____!@``````!@`!___P!@``````!@`!___^!@``````!@`````` +M!@`!_```!@``````!@``````!@``````!@#______@#______@#____X``#_ +M___[``#_[__[@`#_W__[P`#^/__[X`#_?__[\`#____[^`#____^"`#_____ +M\@#_I*J_^@#_____^@#_BPBB>@#O____^@#_(DBE^@#_____^@#_2G__^@#_ +M____^@#_____^@#_B2J*>@#_____^@#_(E$3^@#O____^@#_F15$^@#_____ +M^@#_(DBO^@#_____^@#_-(15^@#_____^@#_____^@#^D___^@#_____^@#_ +M____^@#_____^@```````@#______@`````&```````$@```&``$0```,``$ +M(``!X``$$```P``$"``````$```````!\```````"```6U5````````````` +M=/==@```````````W;=:````````````M8``````````````````````=M5U +M@```````````W:[L````````````9NJ[````````````W;=0```````````` +MRWNJ```````````````````!;`````````````````````````````"````` +M`````````````````"<`(P`#0`Z[``(```````(!NVZT``(`` +M`````(!:P````(```````(```````(`[:KK``(```````(!NUW8``(`````` +M`(`S=5V``(```````(!NVZ@``(```````(!EO=4``(```````(```````("V +M`````(```````(```````(```````,```````````!)365,Z5&]O;',O161I +.=%!A9``````(`````0`` +` +end diff --git a/sys/unix/hints/include/cross-post.500 b/sys/unix/hints/include/cross-post.500 index 23d96312c..512906d8f 100644 --- a/sys/unix/hints/include/cross-post.500 +++ b/sys/unix/hints/include/cross-post.500 @@ -310,24 +310,27 @@ UUDECODE = ../util/uudecode $(CC) $(CFLAGS) -o $@ $< amigapkg: $(AMITILES) ../util/uudecode - mkdir -p $(TARGETPFX)pkg/tiles $(TARGETPFX)pkg/hack - cp $(GAMEBIN) $(TARGETPFX)pkg/nethack - cp ../dat/nhdat $(TARGETPFX)pkg/nhdat - cp ../dat/license $(TARGETPFX)pkg/license - cp ../dat/symbols $(TARGETPFX)pkg/symbols - cp $(TARGETPFX)tiles16.iff $(TARGETPFX)pkg/tiles/tiles16.iff - cp $(TARGETPFX)tiles32.iff $(TARGETPFX)pkg/tiles/tiles32.iff - cp $(TARGETPFX)tomb.iff $(TARGETPFX)pkg/tomb.iff - cp ../doc/nethack.txt $(TARGETPFX)pkg/nethack.txt - ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/amifont8.uu && mv 8 hack/8 ) - ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/amifont.uu ) - cp $(AMISRC)/nethack.cnf $(TARGETPFX)pkg/nethack.cnf - ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/NHinfo.uu ) - ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/cnf-info.uu ) - ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/license-info.uu ) - ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/txt-info.uu ) - touch $(TARGETPFX)pkg/record - ( cd $(TARGETPFX)pkg && zip -9r ../NH$(NHV)AMI.ZIP * ) + mkdir -p $(TARGETPFX)pkg/NetHack/tiles $(TARGETPFX)pkg/NetHack/hack + cp $(GAMEBIN) $(TARGETPFX)pkg/NetHack/nethack + cp ../dat/nhdat $(TARGETPFX)pkg/NetHack/nhdat + cp ../dat/license $(TARGETPFX)pkg/NetHack/license + cp ../dat/symbols $(TARGETPFX)pkg/NetHack/symbols + cp $(TARGETPFX)tiles16.iff $(TARGETPFX)pkg/NetHack/tiles/tiles16.iff + cp $(TARGETPFX)tiles32.iff $(TARGETPFX)pkg/NetHack/tiles/tiles32.iff + cp $(TARGETPFX)tomb.iff $(TARGETPFX)pkg/NetHack/tomb.iff + cp ../doc/nethack.txt $(TARGETPFX)pkg/NetHack/nethack.txt + ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/amifont8.uu && mv 8 hack/8 ) + ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/amifont.uu ) + cp $(AMISRC)/nethack.cnf $(TARGETPFX)pkg/NetHack/nethack.cnf + cp $(AMISRC)/README.amiga $(TARGETPFX)pkg/NetHack/README.amiga + ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/NHinfo.uu ) + ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/cnf-info.uu ) + ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/license-info.uu ) + ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/txt-info.uu ) + ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/readme-info.uu ) + ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/drawer-info.uu ) + touch $(TARGETPFX)pkg/NetHack/record + ( cd $(TARGETPFX)pkg && zip -9r ../NH$(NHV)AMI.ZIP NetHack NetHack.info ) @echo amiga package zip file $(TARGETPFX)NH$(NHV)AMI.ZIP endif # CROSS_TO_AMIGA From ed4d100459dfd1bd63645f465e1bd09498dee2e1 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 4 May 2026 19:13:48 +0200 Subject: [PATCH 155/702] Amiga: provide a real v4 UUID via get_nhuuid --- sys/amiga/amidos.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++ sys/share/pcmain.c | 3 ++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/sys/amiga/amidos.c b/sys/amiga/amidos.c index c07c52884..c06fc1b1c 100644 --- a/sys/amiga/amidos.c +++ b/sys/amiga/amidos.c @@ -47,6 +47,55 @@ amiga_self_assign(void) UnLock(dup); } +/* Generate an RFC 4122 v4 UUID for this game. Entropy comes from + DateStamp + the running task's address mixed through a small LCG. */ +void +get_nhuuid(void) +{ + uchar bytes[16]; + struct DateStamp ds; + unsigned long x; + int i; + + if (svn.nhuuid[0]) + return; + + DateStamp(&ds); + x = (unsigned long) ds.ds_Days + ^ ((unsigned long) ds.ds_Minute << 16) + ^ ((unsigned long) ds.ds_Tick << 8) + ^ (unsigned long) FindTask(NULL); + /* Classic glibc/POSIX rand() LCG (Knuth, C99 7.22.2.1). Full period + 2^32; we read bits 16-23 to skip the LCG's bad low bits. */ + for (i = 0; i < 16; i++) { + x = x * 1103515245u + 12345u; + bytes[i] = (uchar) (x >> 16); + } + /* RFC 4122: version=4 (random), variant=10. */ + bytes[6] = (bytes[6] & 0x0F) | 0x40; + bytes[8] = (bytes[8] & 0x3F) | 0x80; + + Snprintf(svn.nhuuid, sizeof svn.nhuuid, + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x%02x%02x%02x%02x", + bytes[0], bytes[1], bytes[2], bytes[3], + bytes[4], bytes[5], + bytes[6], bytes[7], + bytes[8], bytes[9], + bytes[10], bytes[11], bytes[12], bytes[13], + bytes[14], bytes[15]); +} + +void +free_nhuuid(void) +{ + int i; + + for (i = 0; i < SIZE(svn.nhuuid); i++) { + svn.nhuuid[i] = 0; + } +} + #ifdef AZTEC_50 #include #undef strcmpi diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index 56ee47938..24495392b 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -35,6 +35,7 @@ long _stksize = 16 * 1024; #ifdef AMIGA extern int bigscreen; void preserve_icon(void); +void amiga_self_assign(void); #endif static void process_options(int argc, char **argv); @@ -751,7 +752,7 @@ exepath(char *str) } #endif /* EXEPATH */ -#if defined(CROSS_TO_AMIGA) || defined(CROSS_TO_MSDOS) +#if defined(CROSS_TO_MSDOS) void get_nhuuid(void) From b7735632bfdac6a502f8f2954fbe6d5bbac53e2b Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 5 May 2026 06:57:32 -0400 Subject: [PATCH 156/702] follow-up for issue #1512 The previous fix, while valid, still prompts for input during early options processing if stdin is a tty. It really shouldn't be doing that during early options such as --showpaths, so alter the placement of the program_state.earlyoptions flag within *main(). --- sys/unix/unixmain.c | 2 +- sys/windows/windmain.c | 6 +++--- win/tty/wintty.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index eca90d463..6cad795d8 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -132,7 +132,6 @@ main(int argc, char *argv[]) program_state.early_options = 1; /* handle -dalthackdir, -s , --version, --showpaths */ early_options(&argc, &argv, &dir); - program_state.early_options = 0; #ifdef CHDIR /* * Change directories before we initialize the window system so @@ -146,6 +145,7 @@ main(int argc, char *argv[]) #ifdef __linux__ check_linux_console(); #endif + program_state.early_options = 0; initoptions(); #ifdef PANICTRACE diff --git a/sys/windows/windmain.c b/sys/windows/windmain.c index b437ad98e..2ff0258f3 100644 --- a/sys/windows/windmain.c +++ b/sys/windows/windmain.c @@ -219,6 +219,8 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ // windowtype = gc.chosen_windowtype; // windowtype = gc.chosen_windowtype; + program_state.early_options = 1; + #if !defined(MSWIN_GRAPHICS) nethack_enter_consoletty(); consoletty_open(1); @@ -254,12 +256,10 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ * which clears out gp.fqn_prefix[] */ // iflags.windowtype_deferred = TRUE; - program_state.early_options = 1; /* if (GUILaunched || IsDebuggerPresent()) */ early_options(&argc, &argv, &dir); + program_state.early_options = 0; - - initoptions(); #if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS) chdir(gf.fqn_prefix[HACKPREFIX]); diff --git a/win/tty/wintty.c b/win/tty/wintty.c index f509cbc51..c9bdd4b06 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -766,7 +766,7 @@ getret(void) #if defined(MICRO) || defined(WIN32CON) getreturn("to continue"); #else - if (!isatty(STDIN_FILENO)) + if (!isatty(STDIN_FILENO) || program_state.early_options) return; HUPSKIP(); xputs("\n"); From 8fcc15a860a15e3418cff1f98e80a31c287991cc Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 5 May 2026 11:02:55 -0400 Subject: [PATCH 157/702] mention_decor and tutorial K4372 Bug report stated: "If 'mention_decor' is set in config file or NETHACKOPTIONS, starting the game tells you that you are standing on stairs which lead out of the dungeon. But if you also start the tutorial, you won't be on those stairs--they won't even exist until the tutorial is exited. The stairs message can't be suppressed until the program knows whether the tutorial will be entered, and since prompting is one of the ways to decide that." What this does: Don't heed mention_decor option during the primary rcfile() processing. Do heed it after the tutorial. Note: If mention_decor is expected to actually be active during the tutorial, then the rcfile_only_this_option(opt_mention_decor) likely has to be moved to a different line, which should be easy enough. --- include/extern.h | 1 + src/allmain.c | 6 ++++++ src/cfgfiles.c | 16 ++++++++++++++++ src/end.c | 5 ++++- src/options.c | 7 +++++++ 5 files changed, 34 insertions(+), 1 deletion(-) diff --git a/include/extern.h b/include/extern.h index ec5173c12..accecff22 100644 --- a/include/extern.h +++ b/include/extern.h @@ -339,6 +339,7 @@ extern char *get_configfile(void); extern const char *get_default_configfile(void); extern void rcfile(void); extern void rcfile_interface_options(void); +extern void rcfile_only_this_option(enum opt); extern void heed_all_config_statements(void); extern void disregard_all_config_statements(void); extern void heed_this_config_statement(int); diff --git a/src/allmain.c b/src/allmain.c index 280beb39a..f7ee742ad 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -580,6 +580,9 @@ maybe_do_tutorial(void) vision_recalc(0); docrt(); iflags.nofollowers = FALSE; + } else { + /* no tutorial, so okay to process mention_decor now */ + rcfile_only_this_option(opt_mention_decor); } } @@ -591,6 +594,9 @@ moveloop(boolean resuming) if (!resuming) maybe_do_tutorial(); + /* process one deferred option post-tutorial */ + rcfile_only_this_option(opt_mention_decor); + for (;;) { moveloop_core(); } diff --git a/src/cfgfiles.c b/src/cfgfiles.c index 4e169886b..e2ef65937 100644 --- a/src/cfgfiles.c +++ b/src/cfgfiles.c @@ -1975,6 +1975,22 @@ rcfile_interface_options(void) ignore_statement_errors = FALSE; } +void +rcfile_only_this_option(enum opt heeded_option) +{ + allopt_array_init(); + disregard_all_options(); + disregard_all_config_statements(); + heed_this_option(heeded_option); + set_ignore_errors_on_unmatched(); + ignore_statement_errors = TRUE; + rcfile(); + heed_all_config_statements(); + heed_all_options(); + clear_ignore_errors_on_unmatched(); + ignore_statement_errors = FALSE; +} + void heed_all_config_statements(void) { diff --git a/src/end.c b/src/end.c index 2573cace1..8a366d434 100644 --- a/src/end.c +++ b/src/end.c @@ -110,9 +110,12 @@ done2(void) u.usleep = 0; } - if (abandon_tutorial) + if (abandon_tutorial) { + /* mention_decor can be processed now */ + rcfile_only_this_option(opt_mention_decor); schedule_goto(&u.ucamefrom, UTOTYPE_ATSTAIRS, "Resuming regular play.", (char *) 0); + } return ECMD_OK; } diff --git a/src/options.c b/src/options.c index 05f4979ef..f5d24b1b1 100644 --- a/src/options.c +++ b/src/options.c @@ -7324,6 +7324,7 @@ void initoptions_finish(void) { nhsym sym = 0; + disregard_this_option(opt_mention_decor); /* defer this */ rcfile(); (void) fruitadd(svp.pl_fruit, (struct fruit *) 0); @@ -10184,6 +10185,9 @@ heed_all_options(void) { int i; + /* ensure OPTIONS= lines are enabled */ + heed_this_config_statement(0); /* index 0 == OPTIONS */ + for (i = 0; i < OPTCOUNT; i++) allopt[i].disregarded = FALSE; } @@ -10200,6 +10204,9 @@ disregard_all_options(void) void heed_this_option(enum opt optidx) { + /* ensure OPTIONS= lines are enabled */ + heed_this_config_statement(0); /* index 0 == OPTIONS */ + if (optidx >= 0 && optidx < (enum opt) OPTCOUNT) allopt[optidx].disregarded = FALSE; } From f6afa23e28f49d39ac1e8f86d6b995aa24780b8b Mon Sep 17 00:00:00 2001 From: Benjamin de Waal Date: Wed, 6 May 2026 07:06:41 +0100 Subject: [PATCH 158/702] libnh: fix native build of libnh.a on macOS Fixes four issues that prevented `make WANT_LIBNH=1 all` from producing a libnh.a that could be linked into a host program on macOS. Before these patches, it built but the resulting archive was unusable: macOS ld errored on a nested liblua archive member, was missing date.o and hacklib symbols (`populate_nomakedefs`, `eos`, `lcase`, `mungspaces`, ...), and had duplicate definitions of `main`, `whoami`, etc. Specific changes: 1. sys/libnh/libnhmain.c: drop `static` on `whoami()`. src/earlyarg.c declares it `extern` and calls it from `scores_only()`; the static makes it file-local and that reference goes unresolved. 2. sys/libnh/libnhmain.c: gate the emscripten-only code in get_nhuuid with `#ifdef __EMSCRIPTEN__` instead of `#ifdef NHUUID`. The macOS hints define NHUUID for the libnh build (they did so unconditionally before NO_NHUUID even existed), so on native builds the compiler tried to call `emscripten_run_script_int` / `_string` and failed with implicit-function-declaration errors. __EMSCRIPTEN__ is the real signal for "this is being cross-compiled to WASM." 3. sys/unix/hints/macOS.500: in the WANT_LIBNH block, add an explicit `recover: lua_support` dependency (gated by MAKEFILE_TOP). When $(GAME) is overridden to empty, the regular `recover: $(GAME)` chain no longer triggers `lua_support`, so include/nhlua.h never gets generated and recover.c's transitive #include of hack.h fails. 4. sys/unix/hints/macOS.500: rewrite the libnh.a rule. The previous `ar rcs libnh.a $(HOBJ) $(LIBNHSYSOBJ) liblua-$(LUA_VERSION).a` had four problems: (a) ar archives liblua.a as a single opaque member that macOS ld can't dereference, (b) date.o (DATE_O, kept separate from HOBJ) was never archived, so `populate_nomakedefs` and `nomakedefs` were missing, (c) hacklib.a was likewise omitted, and (d) HOBJ already contains $(SYSOBJ) (with unixmain.o) and $(WINOBJ) (the tty windowport), which duplicated symbols from libnhmain.o / winshim.o. The fix uses `libtool -static` so hacklib.a and liblua's archive have their members merged rather than nested, depends on $(LUALIB) so lua_support runs first, includes $(DATE_O) and $(TARGET_HACKLIB), and uses $(filter-out $(SYSOBJ) $(WINOBJ),$(HOBJ)) to drop the duplicates. Verified by clean rebuild on macOS 26 (arm64, Apple clang 17): make spotless make fetch-Lua make WANT_LIBNH=1 all and link-tested with a tiny harness that calls shim_graphics_set_callback() against the resulting libnh.a. Co-Authored-By: Claude Opus 4.7 (1M context) --- sys/libnh/libnhmain.c | 10 +++++----- sys/unix/hints/macOS.500 | 22 ++++++++++++++++++++-- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index 90907f987..67b38e4e0 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -37,7 +37,7 @@ extern struct passwd *getpwnam(const char *); #ifdef CHDIR static void chdirx(const char *, boolean); #endif /* CHDIR */ -static boolean whoami(void); +boolean whoami(void); static void process_options(int, char **); #ifdef _M_UNIX @@ -516,7 +516,7 @@ chdirx(const char *dir, boolean wr) #endif /* CHDIR */ /* returns True iff we set plname[] to username which contains a hyphen */ -static boolean +boolean whoami(void) { /* @@ -805,7 +805,7 @@ get_nhuuid(void) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; char *uuid = (char *) &stmp[0]; #ifndef NONHUUID -#ifdef NHUUID +#ifdef __EMSCRIPTEN__ int uuid_available = 0; #endif #endif @@ -814,7 +814,7 @@ get_nhuuid(void) return; #ifndef NONHUUID -#ifdef NHUUID +#ifdef __EMSCRIPTEN__ uuid_available = emscripten_run_script_int( "typeof crypto !== 'undefined'" " && typeof crypto.randomUUID === 'function'"); @@ -824,7 +824,7 @@ get_nhuuid(void) uuid = (char *) &stmp[0]; } } -#endif /* NHUUID */ +#endif /* __EMSCRIPTEN__ */ #endif /* NONHUUID */ Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", uuid); } diff --git a/sys/unix/hints/macOS.500 b/sys/unix/hints/macOS.500 index 2a400d1a3..6de98b96d 100755 --- a/sys/unix/hints/macOS.500 +++ b/sys/unix/hints/macOS.500 @@ -345,6 +345,12 @@ LIBNHSYSOBJ = $(TARGETPFX)libnhmain.o $(TARGETPFX)ioctl.o \ #without winshim override GAME= MOREALL += ( cd src ; $(MAKE) pregame ; $(MAKE) $(TARGETPFX)libnh.a ) +# With $(GAME) empty, the regular `recover: $(GAME)` chain no longer +# triggers lua_support, but recover.c still pulls in hack.h -> nhlua.h +# transitively. Make recover depend on lua_support explicitly. +ifdef MAKEFILE_TOP +recover: lua_support +endif endif # WANT_LIBNH # Lua @@ -568,8 +574,20 @@ $(TARGETPFX)macuuid.o: ../sys/unix/macuuid.m endif ifdef WANT_LIBNH -$(TARGETPFX)libnh.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua-$(LUA_VERSION).a - $(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua-$(LUA_VERSION).a +# Build libnh.a by merging the engine objects, the shim windowport, +# date.o (separate from $(HOBJ) per Makefile.src), hacklib.a, and Lua's +# static archive. Use libtool -static rather than ar so hacklib.a and +# liblua-$(LUA_VERSION).a have their members merged in -- ar would archive +# them as opaque .a members and macOS ld can't dereference those. +# Depending on $(LUALIB) triggers the lua_support build (which generates +# include/nhlua.h); without it, $(HOBJ) won't compile. +# filter-out drops $(SYSOBJ) (which carries unixmain.o) and $(WINOBJ) (the +# tty windowport) from $(HOBJ); $(LIBNHSYSOBJ) supplies libnhmain.o and +# winshim.o in their place. +$(TARGETPFX)libnh.a: $(LUALIB) $(HOBJ) $(LIBNHSYSOBJ) $(DATE_O) $(TARGET_HACKLIB) + libtool -static -o $@ \ + $(filter-out $(SYSOBJ) $(WINOBJ),$(HOBJ)) \ + $(LIBNHSYSOBJ) $(DATE_O) $(TARGET_HACKLIB) $(LUALIB) @echo "$@ built." $(TARGETPFX)libnhmain.o : ../sys/libnh/libnhmain.c $(HACK_H) $(CC) $(CFLAGS) -c -o$@ $< From 60de22761568ce248403b5941aa075163fd8ab36 Mon Sep 17 00:00:00 2001 From: Patric Mueller Date: Wed, 6 May 2026 09:58:00 +0200 Subject: [PATCH 159/702] fix ncurses build on macOS with Homebrew --- sys/unix/hints/macOS.500 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/unix/hints/macOS.500 b/sys/unix/hints/macOS.500 index 2a400d1a3..9054461b7 100755 --- a/sys/unix/hints/macOS.500 +++ b/sys/unix/hints/macOS.500 @@ -176,8 +176,8 @@ HAVE_HOMEBREW_NCURSES := $(shell expr `brew ls --versions ncurses > /dev/null; e ifeq "$(HAVE_HOMEBREW_NCURSES)" "1" # Newer versions of ncurses are commonly installed via homebrew, but intentionally unlinked. HOMEBREW_LFLAGS := -L$(shell brew --prefix)/opt/ncurses/lib -HOMEBREW_WINLIB := -I$(shell brew --prefix)/opt/ncurses/include -HOMEBREW_CFLAGS = +HOMEBREW_WINLIB := +HOMEBREW_CFLAGS = -I$(shell brew --prefix)/opt/ncurses/include endif #HAVE_HOMEBREW_NCURSES endif #HAVE_HOMEBREW ifeq "$(HAVE_MACPORTS)" "1" From 75e2a6a669e593c06108d0176ea1c6485ddd946e Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sat, 25 Oct 2025 19:19:44 -0500 Subject: [PATCH 160/702] doc/nethack.6: Fix invalid *roff syntax Also fix a case hidden by a comment. Fixes: $ nroff -ww -z -man doc/*.[67] troff:doc/nethack.6:68: warning: escape character ignored before '@' troff:doc/nethack.6:292: warning: escape character ignored before '@' --- doc/nethack.6 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index 85b99c389..605bb56ff 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -65,7 +65,7 @@ nethack \- Exploring The Mazes of Menace .I race ] [ -.B \-\@ +.B \-@ ] .PP Also @@ -240,7 +240,7 @@ character's gender. Any of the parts of the suffix may be left out. can be used to determine the character profession, also known as the role. You can specify either the male or female name for the character role, or the first three characters of the role as an abbreviation. -.\" .B "\-p \@" +.\" .B "\-p @" .\" has been retained to explicitly request that a random role be chosen. .\" It may need to be quoted with a backslash (\\@) if @ .\" is the "kill" character (see "stty") for the terminal, in order @@ -289,7 +289,7 @@ is already used for the .I Rogue role. .PP -.B \-\@ +.B \-@ tells nethack to choose any omitted characteristics (profession/role, race, gender, alignment) randomly without prompting. Otherwise, leaving out any of these characteristics will result in you From 387140956057e74790fdc4e0c80fa38d112b495e Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sat, 25 Oct 2025 19:42:51 -0500 Subject: [PATCH 161/702] doc/nethack.6: Fix poor commented-out *roff syntax MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit groff_man_style(7): Portability ... \e Format the roff escape character on the output; widely used in man pages to render a backslash glyph. It works reliably as long as the “ec†request is not used, which should never happen in man pages, and it is slightly more portable than the more explicit \[rs] (“reverse solidusâ€) special character escape sequence. This change's purpose is to put things right in case the change I'm proposing next to delete this language entirely gets reverted. --- doc/nethack.6 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index 605bb56ff..7e0ddde02 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -242,7 +242,7 @@ You can specify either the male or female name for the character role, or the first three characters of the role as an abbreviation. .\" .B "\-p @" .\" has been retained to explicitly request that a random role be chosen. -.\" It may need to be quoted with a backslash (\\@) if @ +.\" It may need to be quoted with a backslash (\e@) if @ .\" is the "kill" character (see "stty") for the terminal, in order .\" to prevent the current input line from being cleared. .PP From d90422f0ce1708c8493fcec796acf61a4cd80ea6 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sat, 25 Oct 2025 19:45:09 -0500 Subject: [PATCH 162/702] doc/nethack.6: Drop commented-out legacy remark Unix terminal drivers started transitioning away from paper terminals and toward video terminals, and therefore away from '#' and '@' as the "erase" and "kill" characters, respectively, before NetHack was born. --- doc/nethack.6 | 3 --- 1 file changed, 3 deletions(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index 7e0ddde02..c9a5bcbfb 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -242,9 +242,6 @@ You can specify either the male or female name for the character role, or the first three characters of the role as an abbreviation. .\" .B "\-p @" .\" has been retained to explicitly request that a random role be chosen. -.\" It may need to be quoted with a backslash (\e@) if @ -.\" is the "kill" character (see "stty") for the terminal, in order -.\" to prevent the current input line from being cleared. .PP Likewise, .B \-r From 723afcd51fac7d70637553ff7006f913291d5ebc Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sat, 25 Oct 2025 18:20:25 -0500 Subject: [PATCH 163/702] doc/*.6: Fix macro usage style errors Fixes: $ nroff -ww -z -rCHECKSTYLE=4 -man doc/*.[67] an.tmac:doc/dlb.6:41: style: .IR expects at least 2 arguments, got 1 an.tmac:doc/makedefs.6:125: style: .IR expects at least 2 arguments, got 1 an.tmac:doc/makedefs.6:131: style: .IR expects at least 2 arguments, got 1 an.tmac:doc/makedefs.6:137: style: .IR expects at least 2 arguments, got 1 an.tmac:doc/nethack.6:89: style: .BR expects at least 2 arguments, got 1 an.tmac:doc/nethack.6:129: style: .BR expects at least 2 arguments, got 1 an.tmac:doc/nethack.6:273: style: .BR expects at least 2 arguments, got 1 --- doc/dlb.6 | 2 +- doc/makedefs.6 | 6 +++--- doc/nethack.6 | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/dlb.6 b/doc/dlb.6 index b58b12164..d4557ae18 100644 --- a/doc/dlb.6 +++ b/doc/dlb.6 @@ -38,7 +38,7 @@ dlb \- NetHack data librarian }\c .RB [ v ]\c .B I -.IR list-file +.I list-file .PP .B dlb {\c diff --git a/doc/makedefs.6 b/doc/makedefs.6 index f33dc42e1..e2813adc8 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -122,19 +122,19 @@ Generate the .TP .B -1 Generate the -.IR epitaph +.I epitaph file. .br .TP .B -2 Generate the -.IR engrave +.I engrave file. .br .TP .B -3 Generate the -.IR bogusmon +.I bogusmon file. .br .TP diff --git a/doc/nethack.6 b/doc/nethack.6 index c9a5bcbfb..a9c46e6fc 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -86,7 +86,7 @@ Also | .BR \-R | \-Rog | -.BR \-Ran +.B \-Ran | .BR \-S | \-Sam | @@ -126,7 +126,7 @@ Also .B \-\-help ] [ -.BR \-\-showpaths +.B \-\-showpaths ] .\" force line wrap now rather than have that happen after the opening brace .br @@ -267,7 +267,7 @@ The | .BR \-R | \-Rog | -.BR \-Ran +.B \-Ran | .BR \-S | \-Sam | From c91ee79dcb721a63e5371cc0d3b0bbea16bb43ef Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sat, 25 Oct 2025 19:21:38 -0500 Subject: [PATCH 164/702] doc/nethack.6: Fix inelegant formatting Replace instances of blank line paragraphing with `PP` macro calls. There are three problems with the style of paragraphing that this commit fixes. 1. A `br` break request is redundant with an adjacent blank text line. 2. A `br` request is also redundant with a paragraphing macro call. 3. When you use a paragraphing macro call instead of a blank text line, you get the configured amount inter-paragraph space. When typesetting with the man(7) package, the default inter-paragraph space amount is 0.4v. A blank text line usually puts 1v of empty space into the document. See groff_man_style(7). Fixes: $ nroff -ww -z -rCHECKSTYLE=4 -man doc/*.[67] an.tmac:doc/nethack.6:435: style: blank line in input an.tmac:doc/nethack.6:442: style: blank line in input an.tmac:doc/nethack.6:535: style: blank line in input an.tmac:doc/nethack.6:539: style: blank line in input an.tmac:doc/nethack.6:543: style: blank line in input an.tmac:doc/nethack.6:568: style: blank line in input an.tmac:doc/nethack.6:572: style: blank line in input --- doc/nethack.6 | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index a9c46e6fc..9e9fb97e0 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -429,15 +429,13 @@ Run-time configuration options were discussed above and use a platform specific name for a file in a platform specific location. For Unix, the name is '.nethackrc' in the user's home directory. - -.br +.PP All other files are in the playground directory, normally /usr/games/lib/nethackdir. If DLB was defined during the compile, the data files and special levels will be inside a larger file, normally nhdat, instead of being separate files. - -.br +.PP .DT .\" continuation lines begin with .ta \w'cmdhelp, opthelp, wizhelp\ \ \ 'u @@ -528,16 +526,13 @@ sysconf System-wide options. Required if \ program is built with 'SYSCF' option .br \ enabled, ignored if not. -.br - +.PP The location of 'sysconf' is specified at build time and can't be changed except by updating source file "config.h" and rebuilding the program. -.br - +.PP NetHack's Guidebook might not be present if whoever packaged or installed the program distribution neglected to include it. -.br - +.PP In a perfect world, 'paniclog' would remain empty. .SH ENVIRONMENT .DT @@ -561,12 +556,10 @@ MAILREADER Replacement for default reader NETHACKDIR or HACKDIR Playground. .br NETHACKOPTIONS String predefining several NetHack options. -.br - +.PP If the same option is specified in both NETHACKOPTIONS and .nethackrc, the value assigned in NETHACKOPTIONS takes precedence. -.br - +.PP SHOPTYPE and SPLEVTYPE can be used in debugging (wizard) mode. .br DEBUGFILES can be used if the program was built with 'DEBUG' enabled. From 56d0708ac711b0ac0e3b47b618a8336701ebfe2a Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sat, 25 Oct 2025 19:31:08 -0500 Subject: [PATCH 165/702] doc/mnh.7: Migrate to use "NH_DATESUB" Aligns with other NetHack man pages and fixes: $ nroff -ww -z -rCHECKSTYLE=4 -man doc/*.[67] an.tmac:doc/mnh.7:2: style: .TH missing fourth argument; suggest package/project name and version (e.g., "groff 1.23.0") --- doc/mnh.7 | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/mnh.7 b/doc/mnh.7 index df7fe5856..23c684925 100644 --- a/doc/mnh.7 +++ b/doc/mnh.7 @@ -1,5 +1,16 @@ +.\"DO NOT REMOVE NH_DATESUB .TH MAKEDEFS 6 "Date(%-d %B %Y)" Project(uc) .\" $NHDT-Branch: NetHack-3.6.2 $:$NHDT-Revision: 1.0 $ $NHDT-Date: 1541298620 2018/11/04 02:30:20 $ -.TH MNH 7 NETHACK +.TH MNH 7 "4 November 2018" NETHACK +.\"DO NOT REMOVE NH_DATESUB .ds Nd Date(%Y) +.ds Nd 2018 +.de NB +.ds Nb \\$2 +.. +.de NR +.ds Nr \\$2 +.. +.NB $NHDT-Branch: NetHack-3.6.2 $ +.NR $NHDT-Revision: 1.0 $ .SH NAME mnh \- additional text formatting macros for the NetHack Guidebook .SH SYNOPSIS From a33da9202977f7f66d820e761d203c3850410215 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sat, 2 May 2026 03:16:36 -0500 Subject: [PATCH 166/702] doc/*.6: Tweak copyright notices in man pages Use *roff special character `\(co` for copyright sign. This special character identifier is _almost_ universally portable, dating back to Ossanna troff in 1976.[1] The exception is Plan 9 nroff, which claims to be thoroughly UTF-8 oriented and should be able to render a copyright sign.[2] If no glyph for the character is available, the output device driver degrades it to "c" (which is technically correct[3]), except for groff, which falls back to "(C)"[4] only on its "ascii" output device. All of groff's other devices have a a proper copyright sign.[5] References: [1] https://archive.org/details/unix-programmers-manual-seventh-edition-vol-2-1983/ (pp. 196ff., see esp. "Table II", p. 227) [2] https://github.com/9fans/plan9port/pull/735#issuecomment-3391733330 [3] https://www.copyright.gov/circs/circ03.pdf [4] https://github.com/GitMirroring/groff/blob/a4d6e619afc8042b12084527c3c11eae919533e2/tmac/tty.tmac#L123 [5] https://paste.c-net.org/ComradesCourage --- doc/dlb.6 | 8 +++++++- doc/makedefs.6 | 8 +++++++- doc/nethack.6 | 8 +++++++- doc/recover.6 | 8 +++++++- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/doc/dlb.6 b/doc/dlb.6 index d4557ae18..ca01bd8c7 100644 --- a/doc/dlb.6 +++ b/doc/dlb.6 @@ -152,5 +152,11 @@ Should include an optional compression facility. Not all read-only files for NetHack can be read out of an archive; examining the source is the only way to know which files can be. .SH COPYRIGHT -This file is Copyright (C) \*(Na, \*(Nd for version \*(Nb:\*(Nr. +.\" All troffs and nroffs support `\(co` except Plan 9 nroff, but Plan 9 +.\" offers no test for special character availability, and its feature +.\" set too closely resembles DWB 3.3 to test for it. Use a string with +.\" any nroff-mode formatter not claiming groff compatiblity. +.ds co \(co +.if !\n(.g .if n .ds co (C)\" in principle, should be just "c" +This file is Copyright \*(co \*(Na, \*(Nd for version \*(Nb:\*(Nr. NetHack may be freely redistributed. See license for details. diff --git a/doc/makedefs.6 b/doc/makedefs.6 index e2813adc8..1af27082f 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -272,5 +272,11 @@ end the most recent conditional .SH AUTHOR The NetHack Development Team .SH COPYRIGHT -This file is Copyright (C) \*(Na, \*(Nd for version \*(Nb:\*(Nr. +.\" All troffs and nroffs support `\(co` except Plan 9 nroff, but Plan 9 +.\" offers no test for special character availability, and its feature +.\" set too closely resembles DWB 3.3 to test for it. Use a string with +.\" any nroff-mode formatter not claiming groff compatiblity. +.ds co \(co +.if !\n(.g .if n .ds co (C)\" in principle, should be just "c" +This file is Copyright \*(co \*(Na, \*(Nd for version \*(Nb:\*(Nr. NetHack may be freely redistributed. See license for details. diff --git a/doc/nethack.6 b/doc/nethack.6 index 9e9fb97e0..290d56932 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -570,7 +570,13 @@ recover(6) .PP Probably infinite. .SH COPYRIGHT -This file is Copyright (C) \*(Na, \*(Nd for version \*(Nb:\*(Nr. +.\" All troffs and nroffs support `\(co` except Plan 9 nroff, but Plan 9 +.\" offers no test for special character availability, and its feature +.\" set too closely resembles DWB 3.3 to test for it. Use a string with +.\" any nroff-mode formatter not claiming groff compatiblity. +.ds co \(co +.if !\n(.g .if n .ds co (C)\" in principle, should be just "c" +This file is Copyright \*(co \*(Na, \*(Nd for version \*(Nb:\*(Nr. NetHack may be freely redistributed. See license for details. .PP Dungeons & Dragons is a Trademark of Wizards of the Coast, Inc. diff --git a/doc/recover.6 b/doc/recover.6 index 90d56c8c9..818ee18f1 100644 --- a/doc/recover.6 +++ b/doc/recover.6 @@ -148,5 +148,11 @@ determine. should be taught to use the nethack playground locking mechanism to avoid conflicts. .SH COPYRIGHT -This file is Copyright (C) \*(Na, \*(Nd for version \*(Nb:\*(Nr. +.\" All troffs and nroffs support `\(co` except Plan 9 nroff, but Plan 9 +.\" offers no test for special character availability, and its feature +.\" set too closely resembles DWB 3.3 to test for it. Use a string with +.\" any nroff-mode formatter not claiming groff compatiblity. +.ds co \(co +.if !\n(.g .if n .ds co (C)\" in principle, should be just "c" +This file is Copyright \*(co \*(Na, \*(Nd for version \*(Nb:\*(Nr. NetHack may be freely redistributed. See license for details. From 2566ddefdf24d54f18ccb6335fa5bb3cfff527c1 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sat, 2 May 2026 03:44:55 -0500 Subject: [PATCH 167/702] doc/*.6: Break input lines at sentence endings ...pacifying a warning from the forthcoming groff 1.25. Fixes: troff:doc/dlb.6:159: warning: end of sentence detected before end of text line [-w style] troff:doc/makedefs.6:53: warning: end of sentence detected before end of text line [-w style] troff:doc/makedefs.6:55: warning: end of sentence detected before end of text line [-w style] troff:doc/makedefs.6:58: warning: end of sentence detected before end of text line [-w style] troff:doc/makedefs.6:153: warning: end of sentence detected before end of text line [-w style] troff:doc/makedefs.6:159: warning: end of sentence detected before end of text line [-w style] troff:doc/makedefs.6:166: warning: end of sentence detected before end of text line [-w style] troff:doc/makedefs.6:222: warning: end of sentence detected before end of text line [-w style] troff:doc/makedefs.6:245: warning: end of sentence detected before end of text line [-w style] troff:doc/makedefs.6:279: warning: end of sentence detected before end of text line [-w style] troff:doc/mnh.7:30: warning: end of sentence detected before end of text line [-w style] troff:doc/nethack.6:225: warning: end of sentence detected before end of text line [-w style] troff:doc/nethack.6:226: warning: end of sentence detected before end of text line [-w style] troff:doc/nethack.6:230: warning: end of sentence detected before end of text line [-w style] troff:doc/nethack.6:234: warning: end of sentence detected before end of text line [-w style] troff:doc/nethack.6:236: warning: end of sentence detected before end of text line [-w style] troff:doc/nethack.6:524: warning: end of sentence detected before end of text line [-w style] troff:doc/nethack.6:577: warning: end of sentence detected before end of text line [-w style] troff:doc/recover.6:155: warning: end of sentence detected before end of text line [-w style] --- doc/dlb.6 | 3 ++- doc/makedefs.6 | 34 ++++++++++++++++++++++------------ doc/mnh.7 | 3 ++- doc/nethack.6 | 21 ++++++++++++++------- doc/recover.6 | 3 ++- 5 files changed, 42 insertions(+), 22 deletions(-) diff --git a/doc/dlb.6 b/doc/dlb.6 index ca01bd8c7..86ce7c6f2 100644 --- a/doc/dlb.6 +++ b/doc/dlb.6 @@ -159,4 +159,5 @@ examining the source is the only way to know which files can be. .ds co \(co .if !\n(.g .if n .ds co (C)\" in principle, should be just "c" This file is Copyright \*(co \*(Na, \*(Nd for version \*(Nb:\*(Nr. -NetHack may be freely redistributed. See license for details. +NetHack may be freely redistributed. +See license for details. diff --git a/doc/makedefs.6 b/doc/makedefs.6 index 1af27082f..260bb3ce5 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -50,14 +50,18 @@ makedefs \- NetHack miscellaneous build-time functions .B Makedefs is a build-time tool used for a variety of .BR NetHack (6) -source file creation and modification tasks. For historical reasons, +source file creation and modification tasks. +For historical reasons, .B makedefs -takes two types of command lines. When invoked with a short option, the -files operated on are determined when +takes two types of command lines. +When invoked with a short option, +the files operated on are determined when .B makedefs -is compiled. When invoked with a long option, the +is compiled. +When invoked with a long option, +the .B --input -and +and .B --output options are used to specify the files for the .BI -- command. @@ -150,20 +154,23 @@ Show debugging output. .br .TP .B --make \fR[\fIcommand\fR] -Execute a short command. Command is given without preceding dash. -.br +Execute a short command. +.I Command +is given without preceding dash. .TP .BI --input " file" Specify the input .I file -for the command (if needed). If the file is - standard +for the command (if needed). +If the file is - standard input is read. .br .TP .BI --output " file" Specify the output .I file -for the command (if needed). If the file is - standard +for the command (if needed). +If the file is - standard output is written. .br .TP @@ -219,7 +226,8 @@ command (and certain other commands) filter their input, on a line-by-line basis, according to control lines embedded in the input and on information gleaned from the .BR NetHack (6) -configuration. This allows certain changes such as embedding platform-specific +configuration. +This allows certain changes such as embedding platform-specific documentation into the master documentation files. .P Rules: @@ -242,7 +250,8 @@ Conditionals may be nested. will exit with an error code if any errors are detected; processing will continue (if it can) to allow as many errors as possible to be detected. .IP - 4 -Unknown identifiers are treated as both TRUE and as an error. Note that +Unknown identifiers are treated as both TRUE and as an error. +Note that .BR --undef " or " #undef in the .BR NetHack (6) @@ -279,4 +288,5 @@ The NetHack Development Team .ds co \(co .if !\n(.g .if n .ds co (C)\" in principle, should be just "c" This file is Copyright \*(co \*(Na, \*(Nd for version \*(Nb:\*(Nr. -NetHack may be freely redistributed. See license for details. +NetHack may be freely redistributed. +See license for details. diff --git a/doc/mnh.7 b/doc/mnh.7 index 23c684925..dd3b7e7a8 100644 --- a/doc/mnh.7 +++ b/doc/mnh.7 @@ -27,7 +27,8 @@ and .IR troff (1) macro definitions extends .IR tmac.n (7) -for the NetHack Guidebook. This document should be +for the NetHack Guidebook. +This document should be read as an addendum to the documentation for .IR tmac.n . .PP diff --git a/doc/nethack.6 b/doc/nethack.6 index 290d56932..526742958 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -222,18 +222,23 @@ Conversely, you must use the appropriate player name to restore a saved game. A .I playername suffix can be used to specify the profession, race, alignment and/or gender -of the character. The full syntax of the playername that includes a -suffix is "name-ppp-rrr-aaa-ggg". "ppp" are at least the first three letters +of the character. +The full syntax of the playername that includes a +suffix is "name-ppp-rrr-aaa-ggg". +"ppp" are at least the first three letters of the profession (this can also be specified using a separate .B \-p .I profession -option). "rrr" are at least the first three letters of the character's +option). +"rrr" are at least the first three letters of the character's race (this can also be specified using a separate .B \-r .I race -option). "aaa" are at least the first three letters of the character's +option). +"aaa" are at least the first three letters of the character's alignment, and "ggg" are at least the first three letters of the -character's gender. Any of the parts of the suffix may be left out. +character's gender. +Any of the parts of the suffix may be left out. .PP .B \-p .I profession @@ -521,7 +526,8 @@ save/ A subdirectory containing saved games. .\"following line should contain \ .br -sysconf System-wide options. Required if +sysconf System-wide options. +Required if .br \ program is built with 'SYSCF' option .br @@ -577,6 +583,7 @@ Probably infinite. .ds co \(co .if !\n(.g .if n .ds co (C)\" in principle, should be just "c" This file is Copyright \*(co \*(Na, \*(Nd for version \*(Nb:\*(Nr. -NetHack may be freely redistributed. See license for details. +NetHack may be freely redistributed. +See license for details. .PP Dungeons & Dragons is a Trademark of Wizards of the Coast, Inc. diff --git a/doc/recover.6 b/doc/recover.6 index 818ee18f1..cf116e09d 100644 --- a/doc/recover.6 +++ b/doc/recover.6 @@ -155,4 +155,5 @@ avoid conflicts. .ds co \(co .if !\n(.g .if n .ds co (C)\" in principle, should be just "c" This file is Copyright \*(co \*(Na, \*(Nd for version \*(Nb:\*(Nr. -NetHack may be freely redistributed. See license for details. +NetHack may be freely redistributed. +See license for details. From 9508a133d0ce7db6fbcfc4d733f48288265df0d3 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sat, 2 May 2026 03:59:03 -0500 Subject: [PATCH 168/702] doc/*.6: Fix unescaped hyphens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit groff_man_style(7): • Option dashes are specified with the \- escape sequence; this is an important practice to make them clearly visible and to facilitate copyâ€andâ€paste from the rendered man page to a shell prompt or text file. ... \- Minus sign. \- produces the basic Latin hyphenâ€minus (U+002D) specifying Unix commandâ€line options and frequently used in file names. “-†is a hyphen in roff; some output devices format it as U+2010 (hyphen). --- doc/dlb.6 | 2 +- doc/makedefs.6 | 86 +++++++++++++++++++++++++------------------------- doc/nethack.6 | 2 +- 3 files changed, 45 insertions(+), 45 deletions(-) diff --git a/doc/dlb.6 b/doc/dlb.6 index 86ce7c6f2..c002537ce 100644 --- a/doc/dlb.6 +++ b/doc/dlb.6 @@ -144,7 +144,7 @@ Kenneth Lorber Not a good .I tar emulation; -.B - +.B \- does not mean stdin or stdout. .IP \(bu Should include an optional compression facility. diff --git a/doc/makedefs.6 b/doc/makedefs.6 index 260bb3ce5..12774dc71 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -21,30 +21,30 @@ makedefs \- NetHack miscellaneous build-time functions .SH SYNOPSIS .B makedefs { -.B -o +.B \-o | -.B -d +.B \-d | -.B -e +.B \-e | -.B -m +.B \-m | -.B -v +.B \-v | -.B -p +.B \-p | -.B -q +.B \-q | -.B -r +.B \-r | -.B -h +.B \-h } .P -.B makedefs --input +.B makedefs \-\-input .I file -.B --output +.B \-\-output .I file -.BI -- command +.BI \-\- command .SH DESCRIPTION .PP .B Makedefs @@ -60,39 +60,39 @@ the files operated on are determined when is compiled. When invoked with a long option, the -.B --input +.B \-\-input and -.B --output +.B \-\-output options are used to specify the files for the -.BI -- command. +.BI \-\- command. Each command is only available in one of the two formats. .SH SHORT COMMANDS Upper and lower case are both accepted for the short commands. .TP -.B -o +.B \-o Generate .I onames.h. .br .TP -.B -d +.B \-d Generate .I data.base. .br .TP -.B -e +.B \-e Generate .I dungeon.pdf. The input file .I dungeon.def is passed through the same logic as that used by the -.B --grep +.B \-\-grep command; see the .B MDGREP FUNCTIONS section below for details. .br .TP -.B -m +.B \-m Generate .I date.h and @@ -108,78 +108,78 @@ info and include related preprocessor #defines in file. .br .TP -.B -p +.B \-p Generate .I pm.h .br .TP -.B -q +.B \-q Generate the .I rumors file. .br .TP -.B -s +.B \-s Generate the .IR bogusmon ", " engrave ", and " epitaph " files." .br .TP -.B -1 +.B \-1 Generate the .I epitaph file. .br .TP -.B -2 +.B \-2 Generate the .I engrave file. .br .TP -.B -3 +.B \-3 Generate the .I bogusmon file. .br .TP -.B -h +.B \-h Generate the .B oracles file. .br .SH LONG COMMANDS .TP -.B --debug +.B \-\-debug Show debugging output. .br .TP -.B --make \fR[\fIcommand\fR] +.B \-\-make \fR[\fIcommand\fR] Execute a short command. .I Command is given without preceding dash. .TP -.BI --input " file" +.BI \-\-input " file" Specify the input .I file for the command (if needed). -If the file is - standard +If the file is \- standard input is read. .br .TP -.BI --output " file" +.BI \-\-output " file" Specify the output .I file for the command (if needed). -If the file is - standard +If the file is \- standard output is written. .br .TP -.B --svs \fR[\fIdelimiter\fR] +.B \-\-svs \fR[\fIdelimiter\fR] Generate a version string to standard output without a trailing newline. If specified, the delimiter is used between each part of the version string. .br .TP -.B --grep +.B \-\-grep Filter the input .I file to the output .IR file . @@ -188,22 +188,22 @@ See the section below for information on controlling the filtering operation. .br .TP -.B --grep-showvars +.B \-\-grep\-showvars Show the name and value for each variable known to the grep option. .br .TP -.B --grep-trace +.B \-\-grep\-trace Turn on debug tracing for the grep function ( -.B --grep +.B \-\-grep must be specified as well). .br .TP -.BI --grep-defined " symbol" +.BI \-\-grep\-defined " symbol" Exit shell true (0) if .I symbol is known and defined, otherwise exit shell false (1). .TP -.BI --grep-define " symbol" +.BI \-\-grep\-define " symbol" Force the value of .I symbol to be "defined." @@ -212,7 +212,7 @@ must already be known to .BR makedefs . .br .TP -.BI --grep-undef " symbol" +.BI \-\-grep\-undef " symbol" Force the definition of .I symbol to be "undefined." @@ -221,7 +221,7 @@ must already be known to .BR makedefs . .SH MDGREP FUNCTIONS The -.B --grep +.B \-\-grep command (and certain other commands) filter their input, on a line-by-line basis, according to control lines embedded in the input and on information gleaned from the @@ -252,7 +252,7 @@ continue (if it can) to allow as many errors as possible to be detected. .IP - 4 Unknown identifiers are treated as both TRUE and as an error. Note that -.BR --undef " or " #undef +.BR \-\-undef " or " #undef in the .BR NetHack (6) configuration are different from unknown. diff --git a/doc/nethack.6 b/doc/nethack.6 index 526742958..5ad003bb2 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -224,7 +224,7 @@ A suffix can be used to specify the profession, race, alignment and/or gender of the character. The full syntax of the playername that includes a -suffix is "name-ppp-rrr-aaa-ggg". +suffix is "name\-ppp\-rrr\-aaa\-ggg". "ppp" are at least the first three letters of the profession (this can also be specified using a separate .B \-p From fc0fd459b18a3d32c12e23f01f9da3a75151b63c Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sat, 2 May 2026 04:01:20 -0500 Subject: [PATCH 169/702] doc/nethack.6: Drop spurious request arguments No *roff known to me interprets arguments to the `br` request. They don't complain, either, but some day that may change. https://savannah.gnu.org/bugs/?61450 --- doc/nethack.6 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index 5ad003bb2..fe6523896 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -36,7 +36,7 @@ nethack \- Exploring The Mazes of Menace .BR \-w | \-\-windowtype .I interface ] -.br 1 +.br [ .BI \-\-nethackrc: RC-file | @@ -48,7 +48,7 @@ nethack \- Exploring The Mazes of Menace [ .BR \-dec " | " \-ibm ] -.br 1 +.br [ .B \-u .I playername @@ -106,7 +106,7 @@ Also [ .B \-v ] -.br 1 +.br [ .B \-p .I profession @@ -347,7 +347,7 @@ and the option can be used to skip any run-time configuration file. .PP .\" extra blank line -.br 1 +.br .PP Some options provide feedback and then exit rather than play the game: .PP From 82c174a8472e5834e699d83566727c7dfd1ff8a3 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sat, 2 May 2026 04:15:08 -0500 Subject: [PATCH 170/702] doc/makedefs.6: Fix warning from DWB 3.3 nroff Not a serious issue in my opinion, but worth fixing. DWB does not misrender the document, and the "stack" referred to is not the runtime stack employed by the operating system, but one in the *roff language runtime. The diagnostic appears to be spurious in this case, but it isn't always. https://github.com/n-t-roff/DWB3.3/issues/10 --- doc/makedefs.6 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/makedefs.6 b/doc/makedefs.6 index 12774dc71..55ef956a7 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -121,7 +121,11 @@ file. .TP .B \-s Generate the -.IR bogusmon ", " engrave ", and " epitaph " files." +.IR bogusmon , +.IR engrave , +and +.I epitaph +files. .br .TP .B \-1 From 32c1b24f32b8fe87d50bc8597414250c420a7f53 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sat, 2 May 2026 04:20:02 -0500 Subject: [PATCH 171/702] doc/makedefs.6: Make punct styling consistent Elsewhere in this document, punctuation after italicized words is set in roman, not italics. --- doc/makedefs.6 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/makedefs.6 b/doc/makedefs.6 index 55ef956a7..b0176470d 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -71,17 +71,17 @@ Upper and lower case are both accepted for the short commands. .TP .B \-o Generate -.I onames.h. +.IR onames.h . .br .TP .B \-d Generate -.I data.base. +.IR data.base . .br .TP .B \-e Generate -.I dungeon.pdf. +.IR dungeon.pdf . The input file .I dungeon.def is passed through the From 0c915adea15621efbf39fb1a814987dd99460cf6 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sat, 2 May 2026 04:22:50 -0500 Subject: [PATCH 172/702] doc/makedefs.6: Break text line at end of sentence Ensure that *roff programs detect the sentence ending here. https://www.gnu.org/software/groff/manual/groff.html.node/Sentences.html --- doc/makedefs.6 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/makedefs.6 b/doc/makedefs.6 index b0176470d..0442c80dc 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -97,7 +97,8 @@ Generate .I date.h and .I options -file. It will read +file. +It will read .IR dat/gitinfo.txt , only if it is present, to obtain .B githash= From a562b80019a5a747d574f4136351469aa2a7cfb7 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sat, 2 May 2026 04:23:15 -0500 Subject: [PATCH 173/702] doc/makedefs.6: Fix style nits * End sentence with period, like others in this document. * Set literal file name in italics like all others in this document, not bold. --- doc/makedefs.6 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/makedefs.6 b/doc/makedefs.6 index 0442c80dc..fd6fe8941 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -111,7 +111,7 @@ file. .TP .B \-p Generate -.I pm.h +.IR pm.h . .br .TP .B \-q @@ -149,7 +149,7 @@ file. .TP .B \-h Generate the -.B oracles +.I oracles file. .br .SH LONG COMMANDS From 6c9e8cb1c950d7d79d317bec2e3f2c2d58b60538 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sat, 2 May 2026 05:11:18 -0500 Subject: [PATCH 174/702] doc/nethack.6: Revise "FILES" section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Define string to exercise groff's hyphenless break point feature. This helps with file names and URLs. On formatters that don't claim compatibility with groff, define the string as nothing, getting the same result as before (a _highly_ ragged right margin, jarring adjustment, or overset lines). * If the formatter does not claim compatibility with groff, define a copy of groff man(7)'s `TQ` macro to ease stacking of paragraph tags. * Set file name literals in italics. Stop quoting them (which was inconsistently done anyway). * Revise "FILES" section. - Drop redundant `PP` paragraphing call. $ mandoc -T lint doc/nethack.6 ... mandoc: doc/nethack.6:432:2: WARNING: skipping paragraph macro: PP after SH ... groff_man(7): .SH [headingâ€text] Set headingâ€text as a section heading. ... Text lines after the call are set as an ordinary paragraph (P). - Drop call of deprecated man(7) `DT` macro and invocation of `ta` request to set tab stops to attempt table-like layout. (The latter made the former nilpotent anyway.) Replace this material with calls of tagged paragraphing macro `TP` and groff man(7)'s `TQ` extension for setting multiple tags with a paragraph. The result takes up more screen lines, but renders well with more formatters. - Fine-tune styling of file names. groff_man_style(7): Use italics for file and path names, ... for variant (userâ€replaceable) portions of syntax synopses, ... and anywhere a parameter requiring replacement by the user is encountered. An exception involves variant text in a context already typeset in italics, such as file or path names with replaceable components; in such cases, follow the convention of mathematical typography: set the file or path name in italics as usual but use roman for the variant part (see IR and RI below), and italics again in running roman text when referring to the variant material. Solaris 10, DWB 3.3, and Plan 9 from User Space nroffs formatted the table of file names and descriptions quite badly. Before: nethack The program itself. Guidebook | Guidebook.txt NetHack's user manual. data, oracles, rumors Data files used by NetHack. bogusmon Another data file. engrave, epitaph, tribute Still more data files. symbols Data file holding sets of speci- fications for how to display monsters, objects, and map features. options Data file containing a descrip- tion of the build-time option settings. help, hh, cmdhelp Help data files. ('cmdhelp' is obsolete.) ... Now (pagination on AT&T nroffs is omitted): nethack The program itself. Guidebook Guidebook.txt NetHack's user manual. data oracles rumors Data files used by NetHack. bogusmon Another data file. engrave epitaph tribute Still more data files. symbols Data file holding sets of specifications for how to display monsters, objects, and map features. options Data file containing a description of the build-time option settings. help hh cmdhelp Help data files. (cmdhelp is obsolete.) Fixes: an.tmac:doc/nethack.6:444: style: use of deprecated macro: .DT --- doc/nethack.6 | 264 +++++++++++++++++++++++++++++++------------------- 1 file changed, 164 insertions(+), 100 deletions(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index fe6523896..f251a6928 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -16,6 +16,22 @@ .ie \n(.g .hy 12 .el .hy 14 .ds Na Robert Patrick Rankin +.\" Define string to exercise groff's hyphenless break point feature. +.ie \n(.g .ds : \: +.el .ds : \" empty +.\" Define local versions of groff's "an-ext.tmac" macros if needed. +.ds %% \" empty +.if \n(.g .ig %% +.\" Add supplementary paragraph tag on its own line after TP. +.de TQ +. br +. ns +. \" Do not quote the argument to `TP`; the user might specify +. \" their own quotes for multi-word tags or to exercise AT&T troff +. \" quoting rules. +. TP \\$1\" +.. +.%% .SH NAME nethack \- Exploring The Mazes of Menace .SH SYNOPSIS @@ -319,7 +335,8 @@ option, which must be the first argument if it appears, supplies a directory which is to serve as the playground. It overrides the value from NETHACKDIR, HACKDIR, or the directory specified by the game administrator during compilation -(usually /usr/games/lib/nethackdir). +(usually +.IR /usr/\*:games/\*:lib/\*:nethackdir ). This option is usually only useful to the game administrator. The playground must contain several auxiliary files such as help files, the list of top scorers, and a subdirectory @@ -429,117 +446,164 @@ development by the Usenet. Andries Brouwer has made this request for the distinction, as he may eventually release a new version of his own. .SH FILES -.PP Run-time configuration options were discussed above and use a platform specific name for a file in a platform specific location. For Unix, the -name is '.nethackrc' in the user's home directory. +name is +.I .nethackrc +in the user's home directory. .PP All other files are in the playground directory, -normally /usr/games/lib/nethackdir. -If DLB was defined during the compile, the data files and special levels -will be inside a larger file, normally nhdat, instead of being separate -files. -.PP -.DT -.\" continuation lines begin with -.ta \w'cmdhelp, opthelp, wizhelp\ \ \ 'u -nethack The program itself. -.br -Guidebook\ |\ Guidebook.txt NetHack's user manual. -.br -data, oracles, rumors Data files used by NetHack. -.br -bogusmon Another data file. -.br -engrave, epitaph, tribute Still more data files. -.br -symbols Data file holding sets of specifications -.br -\ for how to display monsters, objects, and -.br -\ map features. -.br -options Data file containing a description of the -.br -\ build-time option settings. -.br -help,\ hh,\ cmdhelp Help data files. -('cmdhelp' is obsolete.) -.br -opthelp,\ optmenu,\ wizhelp More help data files. -.br -keyhelp,\ usagehlp Even more help data files. -.br -*.lua Predefined special levels, dungeon control -.br -\ for special levels, quest texts. -.br -history A short history of NetHack. -.br -license Rules governing redistribution. -.br -record The list of top scorers. -.br -logfile An extended list of games played -.br -\ (optional). -.br -xlogfile A more detailed version of 'logfile' -.br -\ (also optional). -.br -paniclog Record of exceptional conditions -.br -\ discovered during program execution. -.br -xlock.nn Description of dungeon level 'nn' of -.br -\ active game 'x' if there's a limit on the -.br -\ number of simultaneously active games. -.br -UUcccccc.nn Alternate form for dungeon level 'nn' -.br -\ of active game by user 'UU' playing -.br -\ character named 'cccccc' when there's no -.br -\ limit on number of active games. -.br -perm Lock file for xlock.0 or UUcccccc.0. -.br -bonD0.nn Descriptions of the ghost and belongings -.br -\ of a deceased adventurer who met his or -.br -\ her demise on level 'nn'. +normally +.IR /usr/\*:games/\*:lib/\*:nethackdir . +If DLB was defined during the compile, +the data files and special levels will be inside a larger file, +normally +.IR nhdat , +instead of being separate files. +.TP +.I nethack +The program itself. +.TP +.I Guidebook +.TQ +.I Guidebook.txt +NetHack's user manual. +.TP +.I data +.TQ +.I oracles +.TQ +.I rumors +Data files used by NetHack. +.TP +.I bogusmon +Another data file. +.TP +.I engrave +.TQ +.I epitaph +.TQ +.I tribute +Still more data files. +.TP +.I symbols +Data file holding sets of specifications +for how to display monsters, objects, and +map features. +.TP +.I options +Data file containing a description of the +build-time option settings. +.TP +.I help +.TQ +.I hh +.TQ +.I cmdhelp +Help data files. +.RI ( cmdhelp +is obsolete.) +.TP +.I opthelp +.TQ +.I optmenu +.TQ +.I wizhelp +More help data files. +.TP +.I keyhelp +.TQ +.I usagehlp +Even more help data files. +.TP +.RI * .lua +Predefined special levels, dungeon control +for special levels, quest texts. +.TP +.I history +A short history of NetHack. +.TP +.I license +Rules governing redistribution. +.TP +.I record +The list of top scorers. +.TP +.I logfile +An extended list of games played +(optional). +.TP +.I xlogfile +A more detailed version of +.I logfile +(also optional). +.TP +.I paniclog +Record of exceptional conditions +discovered during program execution. +.TP +.RI x lock. nn +Description of dungeon level +.I nn +of active game +.I x +if there's a limit on the +number of simultaneously active games. +.TP +.RI UUcccccc . nn +Alternate form for dungeon level +.I nn +of active game by user +.I UU +playing character named +.I cccccc +when there's no +limit on number of active games. +.TP +.I perm +Lock file for +.RI x lock.0 +or +.RI UUcccccc .0 . +.TP +.IR bonD0. nn +Descriptions of the ghost and belongings +of a deceased adventurer who met his or +her demise on level +.IR nn . A subsequent -.br -\ character might encounter this old level. -.br -.\"following line should contain -\ -.br -save/ A subdirectory containing saved games. -.br -.\"following line should contain -\ -.br -sysconf System-wide options. +character might encounter this old level. +.TP +.I save/ +Subdirectory containing saved games. +.TP +.I sysconf +System-wide options. Required if -.br -\ program is built with 'SYSCF' option -.br -\ enabled, ignored if not. +program is built with 'SYSCF' option +enabled, ignored if not. .PP -The location of 'sysconf' is specified at build time and can't be changed -except by updating source file "config.h" and rebuilding the program. +The location of +.I sysconf +is specified at build time and can't be changed +except by updating source file +.\" We do the following in an ugly and non-idiomatic way to work around +.\" a DWB 3.3 nroff bug. +.\" troff: if-else overflow.; doc/nethack.6:623 +.\" stack: }S }S }S }S }S }S }S }S }S }S }S }S }S }S }S }S RI +.\" Even at that, DWB insists on setting the period in roman. +"\c +.I config.h\c +" +and rebuilding the program. .PP NetHack's Guidebook might not be present if whoever packaged or installed the program distribution neglected to include it. .PP -In a perfect world, 'paniclog' would remain empty. +In a perfect world, +.I paniclog +would remain empty. .SH ENVIRONMENT .DT .ta \w'NETHACKDIR or HACKDIR\ \ \ 'u From d2a49d4f8a316a639c072cab9565a0294332ca9e Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sat, 2 May 2026 05:51:11 -0500 Subject: [PATCH 175/702] doc/nethack.6: Revise "ENVIRONMENT" section Explain meaning of stacked paragraph tags naming environment variables. Drop call of deprecated man(7) `DT` macro and invocation of `ta` request to set tab stops to attempt table-like layout. (The latter made the former nilpotent anyway.) Replace this material with calls of tagged paragraphing macro `TP` and groff man(7)'s `TQ` extension for setting multiple tags with a paragraph. The result takes up more screen lines, but renders well with more formatters. Set indentation of tagged paragraph using a constant numeric expression to accommodate pseudo-roff formatters that don't implement arithmetic evaluation. (Some of these ignore _any_ indentation, regardless.) Slightly recast descriptions of environment variables. Set file name literals in italics. Protect file and environment variable names from hyphenation. Fixes: an.tmac:doc/nethack.6:608: style: use of deprecated macro: .DT --- doc/nethack.6 | 88 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 26 deletions(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index f251a6928..35a92e8bf 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -605,34 +605,70 @@ In a perfect world, .I paniclog would remain empty. .SH ENVIRONMENT -.DT -.ta \w'NETHACKDIR or HACKDIR\ \ \ 'u -USER or LOGNAME Your login name. -.br -HOME Your home directory. -.br -SHELL Your shell. -.br -TERM The type of your terminal. -.br -HACKPAGER or PAGER Replacement for default pager. -.br -MAIL Mailbox file. -.br -MAILREADER Replacement for default reader -.br -\ (probably /bin/mail or /usr/ucb/mail). -.br -NETHACKDIR or HACKDIR Playground. -.br -NETHACKOPTIONS String predefining several NetHack options. +In some cases, +.I NetHack +attempts to access multiple environment variables in sequence +(via +.IR getenv (3) +or similar) +to determine information. +.TP 16n \" "NETHACKOPTIONS" + 2n +.I USER +.TQ +.I +LOGNAME +Your login name. +.TP +.I HOME +Your home directory. +.TP +.I SHELL +Your login shell +(not necessarily the one running when you started +.IR NetHack ). +.TP +.I TERM +Your terminal type. +.TP +.I HACKPAGER +.TQ +.I PAGER +Replacement for default pager. +.TP +.I MAIL +Mailbox file. +.TP +.I MAILREADER +Replacement for default reader +(probably +.I /bin/\*:mail +or +.IR /usr/\*:ucb/\*:mail ). +.TP +.I NETHACKDIR +.TQ +.I HACKDIR +Playground. +.TP +.I NETHACKOPTIONS +Predefined +.I NetHack +options. .PP -If the same option is specified in both NETHACKOPTIONS and .nethackrc, -the value assigned in NETHACKOPTIONS takes precedence. +If the same option is specified in both +.I \%NETHACKOPTIONS +and +.IR \%.nethackrc , +the value assigned in +.I \%NETHACKOPTIONS +takes precedence. .PP -SHOPTYPE and SPLEVTYPE can be used in debugging (wizard) mode. -.br -DEBUGFILES can be used if the program was built with 'DEBUG' enabled. +.I SHOPTYPE +and +.I \%SPLEVTYPE +can be used in debugging (wizard) mode. +.I \%DEBUGFILES +can be used if the program was built with 'DEBUG' enabled. .SH "SEE ALSO" .PP recover(6) From bbcfc474d0c68138de2f58679e4e4593c9a06684 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sat, 2 May 2026 14:26:51 -0500 Subject: [PATCH 176/702] doc/*.[67]: Drop redundant calls and requests Sectioning and paragraphing macros always break the output line. (Sub)sectioning macros always set text after the heading as a paragraph. Fixes: $ mandoc -T lint doc/*.[67] # output edited doc/makedefs.6:49:2: WARNING: skipping paragraph macro: PP after SH doc/nethack.6:367:2: WARNING: skipping paragraph macro: br after PP doc/nethack.6:365:2: WARNING: skipping paragraph macro: PP empty doc/nethack.6:157:2: WARNING: skipping paragraph macro: PP after SH doc/nethack.6:431:2: WARNING: skipping paragraph macro: PP after SH doc/nethack.6:673:2: WARNING: skipping paragraph macro: PP after SH doc/nethack.6:676:2: WARNING: skipping paragraph macro: PP after SH doc/recover.6:29:2: WARNING: skipping paragraph macro: PP after SH doc/recover.6:125:2: WARNING: skipping paragraph macro: PP after SH doc/recover.6:141:2: WARNING: skipping paragraph macro: PP after SH doc/mnh.7:23:2: WARNING: skipping paragraph macro: PP after SH doc/mnh.7:46:2: WARNING: skipping paragraph macro: PP after SH --- doc/makedefs.6 | 1 - doc/mnh.7 | 2 -- doc/nethack.6 | 7 ------- doc/recover.6 | 3 --- 4 files changed, 13 deletions(-) diff --git a/doc/makedefs.6 b/doc/makedefs.6 index fd6fe8941..3cc5926df 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -46,7 +46,6 @@ makedefs \- NetHack miscellaneous build-time functions .I file .BI \-\- command .SH DESCRIPTION -.PP .B Makedefs is a build-time tool used for a variety of .BR NetHack (6) diff --git a/doc/mnh.7 b/doc/mnh.7 index dd3b7e7a8..77c8d9bfb 100644 --- a/doc/mnh.7 +++ b/doc/mnh.7 @@ -20,7 +20,6 @@ mnh \- additional text formatting macros for the NetHack Guidebook .\".B "troff \-mn" .\"[ options ] file ... .SH DESCRIPTION -.PP This package of .IR nroff (1) and @@ -43,7 +42,6 @@ mn(7) .SH AUTHOR Pat Rankin .SH REQUESTS -.PP In the .I Note column, diff --git a/doc/nethack.6 b/doc/nethack.6 index 35a92e8bf..92f813796 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -154,7 +154,6 @@ Also .\" Make sure path is not hyphenated below .hw nethackdir .SH DESCRIPTION -.PP .I NetHack is a display oriented Dungeons & Dragons(tm) - like game. The standard tty display and command structure resemble rogue. @@ -363,9 +362,6 @@ and the .B \-\-no\-nethackrc option can be used to skip any run-time configuration file. .PP -.\" extra blank line -.br -.PP Some options provide feedback and then exit rather than play the game: .PP The @@ -428,7 +424,6 @@ Use .RB \(oq "nethack \-\-usage | more" \(cq to read it a page at a time. .SH AUTHORS -.PP Jay Fenlason (+ Kenny Woodland, Mike Thome and Jon Payne) wrote the original hack, very much like rogue (but full of bugs). .PP @@ -670,10 +665,8 @@ can be used in debugging (wizard) mode. .I \%DEBUGFILES can be used if the program was built with 'DEBUG' enabled. .SH "SEE ALSO" -.PP recover(6) .SH BUGS -.PP Probably infinite. .SH COPYRIGHT .\" All troffs and nroffs support `\(co` except Plan 9 nroff, but Plan 9 diff --git a/doc/recover.6 b/doc/recover.6 index cf116e09d..b7298c015 100644 --- a/doc/recover.6 +++ b/doc/recover.6 @@ -26,7 +26,6 @@ recover \- recover a NetHack game interrupted by disaster ] .I "base1 base2" ... .SH DESCRIPTION -.PP Occasionally, a NetHack game will be interrupted by disaster when the game or the system crashes. Prior to NetHack v3.1, these games were lost because various information @@ -122,7 +121,6 @@ In either case, .I recover is easily compiled from the distribution utility directory. .SH NOTES -.PP Like .I nethack itself, @@ -138,7 +136,6 @@ will find them in the uncompressed form. .SH "SEE ALSO" nethack(6) .SH BUGS -.PP .I recover makes no attempt to find out if a base name specifies a game in progress. If multiple machines share a playground, this would be impossible to From 67e724cd75b6dc38d2e2fd4d11ce8645d5c31854 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sun, 3 May 2026 00:46:25 -0500 Subject: [PATCH 177/702] doc/*.[67]: Set man page xrefs consistently NetHack's man pages already preponderantly use man(7) `IR` macro for this purpose. Align outliers. The "SEE ALSO" section of doc/mn.7 is a partial exception. While the rest of the document sets cross-referenced man page topics in italics, this section of the page does not. It seems likely that this decision was made in deliberate imitation of Seventh Edition Unix manuals (1979) or their descendants in USG/USL and BSD Unices. That feature of the Unix man pages, however, was not deliberate per Doug McIlroy, the author of the man(7) macros and editor of Volume 1 of the Seventh Edition Unix Programmer's Manual, per his communication on the groff mailing list. But NetHack has a policy of not modifying Matt Bishop's "mn" macro file or its man page, so I leave that exception in place. References: https://lists.gnu.org/archive/html/groff/2021-08/msg00023.html https://lists.gnu.org/archive/html/groff/2021-08/msg00040.html https://github.com/NetHack/NetHack/pull/977#issuecomment-1424996578 --- doc/makedefs.6 | 4 ++-- doc/mnh.7 | 2 +- doc/nethack.6 | 2 +- doc/recover.6 | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/makedefs.6 b/doc/makedefs.6 index 3cc5926df..b8d24b7d4 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -229,7 +229,7 @@ The command (and certain other commands) filter their input, on a line-by-line basis, according to control lines embedded in the input and on information gleaned from the -.BR NetHack (6) +.IR NetHack (6) configuration. This allows certain changes such as embedding platform-specific documentation into the master documentation files. @@ -258,7 +258,7 @@ Unknown identifiers are treated as both TRUE and as an error. Note that .BR \-\-undef " or " #undef in the -.BR NetHack (6) +.IR NetHack (6) configuration are different from unknown. .RE .P diff --git a/doc/mnh.7 b/doc/mnh.7 index 77c8d9bfb..802c806ec 100644 --- a/doc/mnh.7 +++ b/doc/mnh.7 @@ -38,7 +38,7 @@ and number registers are defined below. .SH FILES doc/tmac.nh .SH "SEE ALSO" -mn(7) +.IR mn (7) .SH AUTHOR Pat Rankin .SH REQUESTS diff --git a/doc/nethack.6 b/doc/nethack.6 index 92f813796..10d681f8f 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -665,7 +665,7 @@ can be used in debugging (wizard) mode. .I \%DEBUGFILES can be used if the program was built with 'DEBUG' enabled. .SH "SEE ALSO" -recover(6) +.IR recover (6) .SH BUGS Probably infinite. .SH COPYRIGHT diff --git a/doc/recover.6 b/doc/recover.6 index b7298c015..1fcdff662 100644 --- a/doc/recover.6 +++ b/doc/recover.6 @@ -134,7 +134,7 @@ but even a compression-using .I nethack will find them in the uncompressed form. .SH "SEE ALSO" -nethack(6) +.IR nethack (6) .SH BUGS .I recover makes no attempt to find out if a base name specifies a game in progress. From 103d5f27e76a383a9b12a2e2ef5a4a2ebdd3dfe5 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sun, 3 May 2026 01:06:17 -0500 Subject: [PATCH 178/702] doc/makedefs.6: Drop redundant `br` requests Paragraphing macros in *roff systems generally break the output line, and the same is true of all of man(7)'s paragraphing macros. groff_man(7): Paragraphing macros These macros break the output line. An ordinary paragraph (P) indents all output lines by the same amount. A hanging paragraph (HP) is a cosmetic variant of P with a hanging indent. Definition lists frequently occur in man pages; these can be set as tagged paragraphs, which have one (TP) or more (TQ) leading tags followed by a paragraph that has an additional indentation. --- doc/makedefs.6 | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/doc/makedefs.6 b/doc/makedefs.6 index b8d24b7d4..fad5ed24e 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -71,12 +71,10 @@ Upper and lower case are both accepted for the short commands. .B \-o Generate .IR onames.h . -.br .TP .B \-d Generate .IR data.base . -.br .TP .B \-e Generate @@ -89,7 +87,6 @@ same logic as that used by the command; see the .B MDGREP FUNCTIONS section below for details. -.br .TP .B \-m Generate @@ -106,18 +103,15 @@ and info and include related preprocessor #defines in .I date.h file. -.br .TP .B \-p Generate .IR pm.h . -.br .TP .B \-q Generate the .I rumors file. -.br .TP .B \-s Generate the @@ -126,36 +120,30 @@ Generate the and .I epitaph files. -.br .TP .B \-1 Generate the .I epitaph file. -.br .TP .B \-2 Generate the .I engrave file. -.br .TP .B \-3 Generate the .I bogusmon file. -.br .TP .B \-h Generate the .I oracles file. -.br .SH LONG COMMANDS .TP .B \-\-debug Show debugging output. -.br .TP .B \-\-make \fR[\fIcommand\fR] Execute a short command. @@ -168,7 +156,6 @@ Specify the input for the command (if needed). If the file is \- standard input is read. -.br .TP .BI \-\-output " file" Specify the output @@ -176,12 +163,10 @@ Specify the output for the command (if needed). If the file is \- standard output is written. -.br .TP .B \-\-svs \fR[\fIdelimiter\fR] Generate a version string to standard output without a trailing newline. If specified, the delimiter is used between each part of the version string. -.br .TP .B \-\-grep Filter the input @@ -190,17 +175,14 @@ Filter the input See the .B MDGREP FUNCTIONS section below for information on controlling the filtering operation. -.br .TP .B \-\-grep\-showvars Show the name and value for each variable known to the grep option. -.br .TP .B \-\-grep\-trace Turn on debug tracing for the grep function ( .B \-\-grep must be specified as well). -.br .TP .BI \-\-grep\-defined " symbol" Exit shell true (0) if @@ -214,7 +196,6 @@ to be "defined." .I Symbol must already be known to .BR makedefs . -.br .TP .BI \-\-grep\-undef " symbol" Force the definition of From fb611b60bcd1ff76916a24b0fb0244c2dd4c8942 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sun, 3 May 2026 01:15:25 -0500 Subject: [PATCH 179/702] doc/nethack.6: Spell "NetHack" thus ...when not referring specifically to the command's file name. --- doc/nethack.6 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index 10d681f8f..aac02424c 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -307,7 +307,7 @@ is already used for the role. .PP .B \-@ -tells nethack to choose any omitted characteristics (profession/role, race, +tells NetHack to choose any omitted characteristics (profession/role, race, gender, alignment) randomly without prompting. Otherwise, leaving out any of these characteristics will result in you being prompted during game startup for the information. @@ -326,7 +326,7 @@ changing the character name to \(lqwizard\(rq, if the player is allowed. Otherwise it will switch to .BR \-X . Control of who is allowed to use debug mode is done via the -.RI "\(lq" WIZARDS= "\(rq line in nethack's " sysconf " file." +.RI "\(lq" WIZARDS= "\(rq line in NetHack's " sysconf " file." .PP The .BR \-d " or " \-\-directory From 14430511bd9de82a8642f868a1d33b96211b7d07 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sun, 3 May 2026 01:24:10 -0500 Subject: [PATCH 180/702] doc/nethack.6: Be more portable to old roffs (1/4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Favor the very old `lq` and `rq` extension _strings_ over special characters of the same name. This fixes missing punctuation and text when rendering this document with DWB and Solaris 10 nroffs, and misrendered text with Plan 9 nroff. Before (DWB, Solaris 10): discovery mode (also known as explore mode). -D will start the game in debug mode (also known as wizard mode) after changing the character name to wizard, if the player is allowed. Otherwise it will switch to -X. Control of who is allowed to use debug mode is done via the Before (Plan 9): discovery mode (also known as explore mode). -D will start the game in debug mode (also known as wizard mode) after changing the character name to lqwizardrq, if the player is allowed. Otherwise it will switch to -X. Control of who is allowed to use debug mode is done via the lqWIZARDS=rq line in NetHack's sysconf file. After (all): The -X option will start the game in a special non-scoring discovery mode (also known as explore mode). -D will start the game in debug mode (also known as wizard mode) after changing the character name to "wizard", if the player is allowed. Otherwise it will switch to -X. Control of who is allowed to use debug mode is done via the "WIZARDS=" line in NetHack's sysconf file. (There are minor differences in the page offset amount, and Plan 9 uses UTF-8 double quotation marks, U+201C and U+201D.) groff_man(7): Strings The following strings are defined for use in man pages. None of these is necessary in a contemporary man page; see groff_man_style(7). ... ... \*(lq \*(rq interpolate special character escape sequences for left and right doubleâ€quotation marks, \(lq and \(rq, respectively. (I see that I should reword the foregoing to something like "None is necessary in man pages targeting only contemporary *roff formatters".) History ... 4BSD (1980) added lq and rq strings. ... Unix System V (1988) incorporated the lq and rq strings. Except for EX/EE, James Clark implemented the foregoing features in early versions of groff. ... Plan 9 from User Space’s troff ... incorporated the lq and rq strings in 2025. groff_man_style(7): Notes Some tips on composing and troubleshooting your man pages follow. ... • When and how should I use quotation marks? As noted above in subsection “Font style macrosâ€, apply quotation marks to “brief specimens of literal text, such as article titles, inline examples, mentions of individual characters or short strings, and (sub)section headings in man pagesâ€. Multi†word literals, such as Unix commands with arguments, when set inline (as opposed to displayed between EX and EE), should be quoted to ensure that the boundaries of the literal are clear even when the material is stripped of font styling by, for example, copyâ€andâ€paste operations. groff, Heirloom Doctools troff, neatroff, and mandoc support all of the special characters \[oq], \[cq], \[lq], \[rq], \[aq], and \[dq] described in subsection “Portability†above. DWB, Plan 9, and Solaris troffs do not. Interpolating the strings \*(lq and \*(rq portably yields directional double quotation marks, if available, in all these formatters (though neatroff does not supply a man macro package), but they cannot reliably be used in macro arguments. Per the final sentence above, do a little dance to avoid using these strings in macro arguments. --- doc/nethack.6 | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index aac02424c..d25f09a0d 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -216,7 +216,7 @@ below). On other systems, the default may be different, possibly NetHack.cnf. On MS-DOS, the name is defaults.nh in NetHack's directory (folder), while -.\" on the Macintosh or BeOS, it is \(lqNetHack Defaults\(rq, and +.\" on the Macintosh or BeOS, it is \*(lqNetHack Defaults\*(rq, and on VMS|OpenVMS it is nethack.ini in your home directory. The default configuration file may be overridden via the .BI \-\-nethackrc: "rc-file" @@ -322,11 +322,22 @@ option will start the game in a special non-scoring discovery mode (also known as explore mode). .B \-D will start the game in debug mode (also known as wizard mode) after -changing the character name to \(lqwizard\(rq, if the player is allowed. +changing the character name to \*(lqwizard\*(rq, +if the player is allowed. Otherwise it will switch to .BR \-X . Control of who is allowed to use debug mode is done via the -.RI "\(lq" WIZARDS= "\(rq line in NetHack's " sysconf " file." +.\" The `lq` and `rq` strings are not reliable in macro calls, because +.\" some nroffs interpolate `"` for them, messing up macro argument +.\" delimitation. Use an (initially) uglier method than `RI`. +.\".RI "\*(lq" WIZARDS= "\*(rq line in NetHack's " sysconf " file." +\*(lq\c +.I WIZARDS=\c +\*(rq +line in +NetHack's +.I sysconf +file. .PP The .BR \-d " or " \-\-directory From afeec3dd651cbcd0c749bb53a25cdccd319329fc Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sun, 3 May 2026 01:40:41 -0500 Subject: [PATCH 181/702] doc/nethack.6: Be more portable to old roffs (2/4) Old *roffs don't support the `ti` special character. Compensate. Before (DWB, Solaris 10): The --nethackrc:RC-file option will use RC-file instead of the default run-time configuration file (typically /.nethackrc) and the --no-nethackrc option can be used to skip any run-time configuration file. Before (Plan 9): The --nethackrc:RC-file option will use RC-file instead of the default run-time configuration file (typically ti/.nethackrc) and the --no-nethackrc option can be used to skip any run-time configuration file. After (all): The --nethackrc:RC-file option will use RC-file instead of the default run-time configuration file (typically ~/.nethackrc) and the --no-nethackrc option can be used to skip any run-time configuration file. --- doc/nethack.6 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index d25f09a0d..061092fb6 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -16,6 +16,12 @@ .ie \n(.g .hy 12 .el .hy 14 .ds Na Robert Patrick Rankin +.\" DWB, Solaris 10, and Plan 9 troffs don't support `\(ti`. Assume the +.\" best, then detect these older troffs and fall back as needed. +.\" +.\" Put NO SPACE between special character and comment escape sequences. +.ds ~ \(ti\" The name "ti" is taken by *roff's `ti` request. +.if !\n(.g .ds ~ ~ .\" Define string to exercise groff's hyphenless break point feature. .ie \n(.g .ds : \: .el .ds : \" empty @@ -368,7 +374,7 @@ The option will use .I RC-file instead of the default run-time configuration file -.RI "(typically " \(ti/.nethackrc ")" +.RI "(typically " \*~/.nethackrc ")" and the .B \-\-no\-nethackrc option can be used to skip any run-time configuration file. From 1922fb687d1c37fcccf4a26d1fdb9aa85945e405 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Tue, 5 May 2026 07:12:23 -0500 Subject: [PATCH 182/702] doc/nethack.6: Be more portable to old roffs (3/4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unbreakable spaces in AT&T troff were always non-adjustable. Define a string to use groff's `\~` extension if possible. groff_man_style(7): Portability ... \~ Adjustable nonâ€breaking space. Use this escape sequence to prevent a break inside a short phrase or between a numerical quantity and its corresponding unit(s). Before starting the motor, set the output speed to\~1. There are 1,024\~bytes in 1\~KiB. CSTR\~#8 documents the B\~language. \~ is a GNU extension also supported by Heirloom Doctools troff 050915 (September 2005), mandoc 1.9.14 (2009â€11â€16), neatroff (commit 1c6ab0f6e, 2016â€09â€13), and Plan 9 from User Space troff (commit 93f8143600, 2022â€08â€12), but not by DWB or Solaris troffs. Fixes bad rendering in DWB 3.3 troff: @@ -999 +999 @@ - file. -s|-s~-v may also be followed by arguments -p + file. -s|-s -v may also be followed by arguments -p @@ -1005 +1005 @@ - entries which match both. -s|-s~-v may be followed by one + entries which match both. -s|-s -v may be followed by one Solaris 10 troff _would_ misrender as well, but a different portability problem keeps some of the foregoing text from rendering at all. --- doc/nethack.6 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index 061092fb6..0077408ec 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -25,6 +25,9 @@ .\" Define string to exercise groff's hyphenless break point feature. .ie \n(.g .ds : \: .el .ds : \" empty +.\" Define string to exercise groff's adjustable, unbreakable space. +.ie \n(.g .ds _ \~ +.el .ds _ \ \" backslash, space .\" Define local versions of groff's "an-ext.tmac" macros if needed. .ds %% \" empty .if \n(.g .ig %% @@ -387,7 +390,7 @@ option alone will print out the list of your scores on the current version. An immediately following .B \-v reports on all versions present in the score file. -.RB \(oq \-s | \-s\~\-v \(cq +.RB \(oq \-s | \-s\*_\-v \(cq may also be followed by arguments .B \-p .I profession @@ -399,7 +402,7 @@ Either can be specified multiple times to include more than one role or more than one race. When both are specified, score entries which match either the role or the race (or both) are printed rather than just entries which match both. -.RB \(oq \-s | \-s\~\-v \(cq +.RB \(oq \-s | \-s\*_\-v \(cq may be followed by one or more player names to print the scores of the players mentioned, by 'all' to print out all scores, or by a number to print that many top scores. From 4a76d66ad9eac9c81e3db60eec7b0553177e059e Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Tue, 5 May 2026 07:34:41 -0500 Subject: [PATCH 183/702] doc/nethack.6: Be more portable to old roffs (4/4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define strings for directional single quotation marks. groff_man_style(7): Notes Some tips on composing and troubleshooting your man pages follow. ... • When and how should I use quotation marks? ... Obtaining directional single quotation marks is more of a challenge. Historically, man pages used ` and ', which troff rendered on typesetters as ‘ and ’, exclusively for them. However, in recent years, some distributors of groff have chosen to override the meanings of these characters in man pages, remapping them to their Unicode Basic Latin code points. Unfortunately, ` and ' are the only reliable means of obtaining directional single quotation marks in AT&T troff; in that implementation, often no special character escape sequences exist to obtain them. Further, AT&T troff’s special character identifiers, like its font names, were deviceâ€specific. To achieve quotation portably in man pages rendered both by AT&T and more modern troffs, consider adding a preamble to your page after the TH call as follows. .ie \n(.g \{\ . ds oq \[oq]\" . ds cq \[cq]\" .\} .el \{\ . ds oq `\" . ds cq '\" .\} You must then use the \* escape sequence to interpolate the quotation mark strings. The command .RB \*(oq "while !\& git pull; do sleep 10; done" \*(cq retries an update from the repository until it succeeds. If this procedure seems complex, petition your distributor to revert their remapping of the ` and ' characters. --- doc/nethack.6 | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index 0077408ec..9a2631a41 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -16,12 +16,19 @@ .ie \n(.g .hy 12 .el .hy 14 .ds Na Robert Patrick Rankin -.\" DWB, Solaris 10, and Plan 9 troffs don't support `\(ti`. Assume the -.\" best, then detect these older troffs and fall back as needed. +.\" DWB, Solaris 10, and Plan 9 troffs don't support `\(ti`, `\(oq`, or +.\" `\(cq`. Assume the best, then detect these older troffs and fall +.\" back as needed. .\" .\" Put NO SPACE between special character and comment escape sequences. .ds ~ \(ti\" The name "ti" is taken by *roff's `ti` request. -.if !\n(.g .ds ~ ~ +.ds oq \(oq +.ds cq \(cq +.if !\n(.g \{\ +. ds ~ ~ +. ds oq ` +. ds cq ' +.\} .\" Define string to exercise groff's hyphenless break point feature. .ie \n(.g .ds : \: .el .ds : \" empty @@ -390,7 +397,7 @@ option alone will print out the list of your scores on the current version. An immediately following .B \-v reports on all versions present in the score file. -.RB \(oq \-s | \-s\*_\-v \(cq +.RB \*(oq \-s | \-s\*_\-v \*(cq may also be followed by arguments .B \-p .I profession @@ -402,7 +409,7 @@ Either can be specified multiple times to include more than one role or more than one race. When both are specified, score entries which match either the role or the race (or both) are printed rather than just entries which match both. -.RB \(oq \-s | \-s\*_\-v \(cq +.RB \*(oq \-s | \-s\*_\-v \*(cq may be followed by one or more player names to print the scores of the players mentioned, by 'all' to print out all scores, or by a number to print that many top scores. @@ -441,7 +448,7 @@ customize aspects of how the game operates. .BR \-\-usage " or " \-\-help will display information similar to this manual page, then exit. Use -.RB \(oq "nethack \-\-usage | more" \(cq +.RB \*(oq "nethack \-\-usage | more" \*(cq to read it a page at a time. .SH AUTHORS Jay Fenlason (+ Kenny Woodland, Mike Thome and Jon Payne) wrote the From 2c9bda8660b2fe377393314e5106262e08f25bba Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Tue, 5 May 2026 17:16:45 -0500 Subject: [PATCH 184/702] doc/nethack.6: Respell playername option argument Spell it as a hyphenated noun phrase. Use an ellipsis instead of pluralization to mark its repeatability. Slightly recast its description. --- doc/nethack.6 | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index 9a2631a41..b3abff111 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -83,7 +83,7 @@ nethack \- Exploring The Mazes of Menace .br [ .B \-u -.I playername +.I player-name ] [ .BR \-X " | " \-D @@ -148,8 +148,8 @@ Also .I race ] [ -.I playernames -] +.I player-name\*_\c +\&.\|.\|.] .PP .B nethack [ @@ -241,7 +241,7 @@ to a string consisting of an @ character followed by the path and filename. .PP The .B \-u -.I playername +.I player-name option supplies the answer to the question "Who are you?". It overrides any name from the options or configuration file, USER, LOGNAME, or getlogin(), which will otherwise be tried in order. @@ -251,11 +251,12 @@ so you can have several saved games under different names. Conversely, you must use the appropriate player name to restore a saved game. .PP A -.I playername +.I player-name suffix can be used to specify the profession, race, alignment and/or gender of the character. -The full syntax of the playername that includes a -suffix is "name\-ppp\-rrr\-aaa\-ggg". +The full syntax of a +.I player-name +including a suffix is "name\-ppp\-rrr\-aaa\-ggg". "ppp" are at least the first three letters of the profession (this can also be specified using a separate .B \-p From 2b4b589a63d1550611c8480844e337c392e72730 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Tue, 5 May 2026 17:20:47 -0500 Subject: [PATCH 185/702] doc/nethack.6: Spell option argument as "rc-file" ...that is, not in capitals. Lowercase seems more consistent with Unix practice. --- doc/nethack.6 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index b3abff111..0e01bf061 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -70,7 +70,7 @@ nethack \- Exploring The Mazes of Menace ] .br [ -.BI \-\-nethackrc: RC-file +.BI \-\-nethackrc: rc-file | .B \-\-no\-nethackrc ] @@ -381,9 +381,9 @@ specified in the run-time configuration file. NetHack's #version command shows available interfaces. .PP The -.BI \-\-nethackrc: RC-file +.BI \-\-nethackrc: rc-file option will use -.I RC-file +.I rc-file instead of the default run-time configuration file .RI "(typically " \*~/.nethackrc ")" and the From 2011f8b4c1afbecfa0d7a2dc6359b0797a050fa9 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Tue, 5 May 2026 17:31:07 -0500 Subject: [PATCH 186/702] doc/nethack.6: Split non-playing synopses The `--showpaths` and `--version` options can't be (usefully) combined with `--usage` or `--help`, nor with each other. --- doc/nethack.6 | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index 0e01bf061..cfac65341 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -152,19 +152,14 @@ Also \&.\|.\|.] .PP .B nethack -[ -.B \-\-usage -| -.B \-\-help -] -[ +.RB { \-\-usage | \-\-help } +.PP +.B nethack .B \-\-showpaths -] -.\" force line wrap now rather than have that happen after the opening brace -.br -[ -.BR \-\-version [ :copy | :dump | :show ] -] +.PP +.B nethack +.BR \-\-version [ :copy | :dump\c +.RB | :show ] .ad .hy 14 .\" Make sure path is not hyphenated below From e4476516cd0ad1721925916c7df844706c86ee50 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Tue, 5 May 2026 17:45:09 -0500 Subject: [PATCH 187/702] doc/nethack.6: Revise scoreboard mode synopsis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set it as a hanging paragraph, as is idiomatic for Unix command synopses. Tighten formatting: set synopsis syntax characters adjacently to operands. Since viewing the scoreboard is a separate mode of operation, arrange first the options that select this mode.[1] Also drop explicit line breaks, permitting synopsis to exercise the configured line length of the selected output device. Before and after, as rendered with Solaris 10 troff: - nethack [ -d|--directory directory ] -s|--scores [ -v ] - [ -p profession ] [ -r race ] [ player-name ...] + nethack {-s|--scores} [-d|--directory directory] [-v] + [-p profession] [-r race] [player-name ...] Before and after, as rendered with groff, mandoc, and Heirloom Doctools troff: - nethack [ -d|--directory directory ] -s|--scores [ -v ] - [ -p profession ] [ -r race ] [ playerâ€name ...] + nethack {-s|--scores} [-d|--directory directory] [-v] [-p profession] + [-r race] [playerâ€name ...] Not shown: Literal text is in bold, and option arguments in italics. [1] See, for example, . --- doc/nethack.6 | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index cfac65341..45e8dc011 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -128,27 +128,17 @@ Also | .BR \-W | \-Wiz ] -.PP +.HP .B nethack -[ -.BR \-d | \-\-directory -.I directory -] -.BR \-s | \-\-scores -[ -.B \-v -] -.br -[ -.B \-p -.I profession -] -[ -.B \-r -.I race -] -[ -.I player-name\*_\c +.RB { \-s | \-\-scores } +.RB [ \-d | \-\-directory\*_\c +.IR directory ] +.RB [ \-v ] +.RB [ \-p\*_\c +.IR profession ] +.RB [ \-r\*_\c +.IR race ] +.RI [ player-name\*_\c \&.\|.\|.] .PP .B nethack From 44c840500042ae97a5257560bed8a05ec55a6893 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Tue, 5 May 2026 18:16:36 -0500 Subject: [PATCH 188/702] doc/nethack.6: Revise primary synopsis Set it as a hanging paragraph, as is idiomatic for Unix command synopses. Tighten formatting: set synopsis syntax characters adjacently to operands. Also drop explicit line breaks, permitting synopsis to exercise the configured line length of the selected output device. Temporarily disable adjustment in a manner more friendly to the system's (or user's) configuration.[1] Stop attempting to manipulate hyphenation; there's no portable way to do that.[2] Before and after, as rendered with Solaris 10, DWB 3.3, and Plan 9 troffs: - nethack [ -d|--directory directory ] [ -w|--windowtype - interface ] - [ --nethackrc:rc-file | --no-nethackrc ] [ -n ] [ -dec | - -ibm ] - [ -u player-name ] [ -X | -D ] [ -p profession ] [ -r race ] - [ -@ ] + nethack [-d|--directory directory] + [-w|--windowtype interface] + [--nethackrc:rc-file|--no-nethackrc] [-n] [-dec|-ibm] + [-u player-name] [-X|-D] [-p profession] [-r race] [-@] Not shown: Literal text is in bold, and option arguments in italics. (Full disclosure: The aforementioned formatters use different page offsets [left margin sizes], and Plan 9 nroff doesn't render _any_ typeface changes, ever, for any document using any macro package.) Before and after, as rendered with groff, mandoc, and Heirloom Doctools troff: - [ --nethackrc:rc-file | --no-nethackrc ] [ -n ] [ -dec | -ibm ] - [ -u player-name ] [ -X | -D ] [ -p profession ] [ -r race ] [ -@ ] + nethack [-d|--directory directory] [-w|--windowtype interface] + [--nethackrc:rc-file|--no-nethackrc] [-n] [-dec|-ibm] + [-u player-name] [-X|-D] [-p profession] [-r race] [-@] (Full disclosure: groff 1.24.x man(7) uses a default line length of 80n,[3] up from the 78n of its previous releases going back to 2002, and used by Heirloom Doctools and mandoc.) [1] https://cgit.git.savannah.gnu.org/cgit/groff.git/tree/tmac/an.tmac?h=1.24.1#n159 [2] https://cgit.git.savannah.gnu.org/cgit/groff.git/tree/tmac/an.tmac?h=1.24.1#n202 [3] https://cgit.git.savannah.gnu.org/cgit/groff.git/tree/NEWS?h=1.24.1#n509 --- doc/nethack.6 | 68 ++++++++++++++++----------------------------------- 1 file changed, 21 insertions(+), 47 deletions(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index 45e8dc011..1944df6a4 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -51,54 +51,29 @@ .SH NAME nethack \- Exploring The Mazes of Menace .SH SYNOPSIS +.HP +.nr sA \n(.j \" Save the adjustment mode. .na -.hy 0 -.\" Some options ordering is explicit (-d first, -u before -D), others -.\" have been arranged to fit within an 80-column page with nearly full -.\" lines while avoiding splitting "[" and "-opt ]" or "[ -opt" and "]" -.\" across line boundaries. It would be better to do that with 'roff magic. .B nethack -[ -.BR \-d | \-\-directory -.I directory -] -.\" '.B token newline .I token' will include a space between the two tokens; -.\" '.BI token token' will not. Likewise for .BR, .RB, &c. -[ -.BR \-w | \-\-windowtype -.I interface -] -.br -[ -.BI \-\-nethackrc: rc-file -| -.B \-\-no\-nethackrc -] -[ -.B \-n -] -[ -.BR \-dec " | " \-ibm -] -.br -[ -.B \-u -.I player-name -] -[ -.BR \-X " | " \-D -] -[ -.B \-p -.I profession -] -[ -.B \-r -.I race -] -[ -.B \-@ +.RB [ \-d | \-\-directory\*_\c +.IR directory ] +.RB [ \-w | \-\-windowtype\*_\c +.IR interface ] +\%[\c +.BI \-\-nethackrc: rc-file\c +|\c +.B \-\-no\-nethackrc\c ] +.RB [ \-n ] +.RB [ \-dec | \-ibm ] +.RB [ \-u\*_\c +.IR player-name ] +.RB [ \-X | \-D ] +.RB [ \-p\*_\c +.IR profession ] +.RB [ \-r\*_\c +.IR race ] +.RB [ \-@ ] .PP Also [ @@ -150,8 +125,7 @@ Also .B nethack .BR \-\-version [ :copy | :dump\c .RB | :show ] -.ad -.hy 14 +.ad \n(sA \" Restore the adjustment mode. .\" Make sure path is not hyphenated below .hw nethackdir .SH DESCRIPTION From bdae11c61dd541d506b152b0f818d0d8b6cdf752 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Tue, 5 May 2026 18:37:27 -0500 Subject: [PATCH 189/702] doc/nethack.6: Revise role info in synopsis Revise presentation of backward-compatible role options. - Give them a metasyntactic variable name and present them in the main command synopsis. - Present the possible values in a typographical display, indented with filling disabled. --- doc/nethack.6 | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index 1944df6a4..554b8dd16 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -55,6 +55,7 @@ nethack \- Exploring The Mazes of Menace .nr sA \n(.j \" Save the adjustment mode. .na .B nethack +.RI [ role-option ] .RB [ \-d | \-\-directory\*_\c .IR directory ] .RB [ \-w | \-\-windowtype\*_\c @@ -75,34 +76,26 @@ nethack \- Exploring The Mazes of Menace .IR race ] .RB [ \-@ ] .PP -Also -[ +.I role-option +can be any of the following. +.PP +.RS +.nf .BR \-A | \-Arc -| .BR \-B | \-Bar -| .BR \-C | \-Cav -| .BR \-H | \-Hea -| .BR \-K | \-Kni -| .BR \-M | \-Mon -| .BR \-P | \-Pri -| .BR \-R | \-Rog -| .B \-Ran -| .BR \-S | \-Sam -| .BR \-T | \-Tou -| .BR \-V | \-Val -| .BR \-W | \-Wiz -] +.fi +.RE .HP .B nethack .RB { \-s | \-\-scores } From 4ab9ec36de61e8e19de70aa5a52466b2f2ea3483 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Tue, 5 May 2026 18:51:40 -0500 Subject: [PATCH 190/702] doc/makedefs.6: Tigthen formatting Set synopsis syntax characters adjacently to operands. --- doc/makedefs.6 | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/doc/makedefs.6 b/doc/makedefs.6 index fad5ed24e..fc3120a5c 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -20,24 +20,16 @@ makedefs \- NetHack miscellaneous build-time functions .SH SYNOPSIS .B makedefs -{ -.B \-o -| -.B \-d -| -.B \-e -| -.B \-m -| -.B \-v -| -.B \-p -| -.B \-q -| -.B \-r -| -.B \-h +{\c +.BR \-o |\c +.BR \-d |\c +.BR \-e |\c +.BR \-m |\c +.BR \-v |\c +.BR \-p |\c +.BR \-q |\c +.BR \-r |\c +.B \-h\c } .P .B makedefs \-\-input From b602b495bb287bbe715e607a684ae1b59952f4b7 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Tue, 5 May 2026 18:59:39 -0500 Subject: [PATCH 191/702] doc/makedefs.6: Clarify `-` as option argument Quote it, use fuller C standard I/O terminology, and use active voice. --- doc/makedefs.6 | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/doc/makedefs.6 b/doc/makedefs.6 index fc3120a5c..c9e617db6 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -146,15 +146,21 @@ is given without preceding dash. Specify the input .I file for the command (if needed). -If the file is \- standard -input is read. +If +.I file +is \*(lq\-\*(rq, +.B makedefs +reads the standard input stream. .TP .BI \-\-output " file" Specify the output .I file for the command (if needed). -If the file is \- standard -output is written. +If +.I file +is \*(lq\-\*(rq, +.B makedefs +writes to the standard input stream. .TP .B \-\-svs \fR[\fIdelimiter\fR] Generate a version string to standard output without a trailing newline. From 561d08e53b4ef50851d6dbe64addec7e72af1e7e Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Tue, 5 May 2026 19:23:30 -0500 Subject: [PATCH 192/702] doc/*.6: Improve formatting of carets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ...on typesetters and UTF-8 terminals. groff_man_style(7): Portability ... Several special characters are also widely portable. Except for \-, \[em], and \[ga], AT&T troff did not consistently define the characters listed below, but its descendants, like DWB, Plan 9, or Solaris troff, can be made to support them by defining them in font description files, making them aliases of existing glyphs if necessary; see groff_font(5). groff’s extended notation for special characters, \[xx], is also supported by mandoc(1), Heirloom Doctools troff, and neatroff, but not DWB, Plan 9, or Solaris troffs. ... \[ha] Basic Latin circumflex accent (“hatâ€). Some output devices format “^†as U+02C6 (modifier letter circumflex accent). Notes Some tips on composing and troubleshooting your man pages follow. ... • Escape sequences of the form \[xx] don’t format correctly. The \[xx] special character escape sequence is a GNU troff extension also supported by mandoc, Heirloom Doctools troff, and neatroff. DWB, Plan 9, and Solaris troffs don’t implement it. If your man page requires portability to these formatters, spell such escape sequences as “\(xxâ€; no closing parenthesis is used. xx must be exactly two characters; groff_char(7) lists portable special character identifiers. --- doc/dlb.6 | 14 ++++++++------ doc/makedefs.6 | 16 +++++++++------- doc/recover.6 | 16 +++++++++------- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/doc/dlb.6 b/doc/dlb.6 index c002537ce..e314989d2 100644 --- a/doc/dlb.6 +++ b/doc/dlb.6 @@ -11,6 +11,8 @@ .. .NB $NHDT-Branch: keni-gitset $ .NR $NHDT-Revision: 1.13 $ +.ie \n(.g .ds ^ \(ha +.el .ds ^ ^ .\" groff and AT&T-descended troffs use different hyphenation patterns. .\" Don't hyphenate the last word on a page or column, or .\" before/after last/first 2 characters of a word. @@ -69,18 +71,18 @@ Unlike is configured with a default set of file names to process. .ig .PP -^?ALLDOCS +\*^?ALLDOCS This facility is optional and may be excluded during NetHack configuration. -^: -^?DLB +\*^: +\*^?DLB This facility is optional but is included in this NetHack configuration. -^: +\*^: This facility is optional and was excluded from this NetHack configuration. -^. -^. +\*^. +\*^. .. .SS Operations .B c diff --git a/doc/makedefs.6 b/doc/makedefs.6 index c9e617db6..9c33ef6e3 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -10,6 +10,8 @@ .. .NB $NHDT-Branch: NetHack-5 $ .NR $NHDT-Revision: 1.22 $ +.ie \n(.g .ds ^ \(ha +.el .ds ^ ^ .\" groff and AT&T-descended troffs use different hyphenation patterns. .\" Don't hyphenate the last word on a page or column, or .\" before/after last/first 2 characters of a word. @@ -220,7 +222,7 @@ The default conditional state is printing enabled. .IP - 4 Any line .I NOT -starting with a caret (^) is either suppressed or passed through unchanged +starting with a caret (\*^) is either suppressed or passed through unchanged depending on the current conditional state. .IP - 4 Any line starting with a caret is a control line; as in C, zero or more spaces @@ -243,21 +245,21 @@ configuration are different from unknown. .P Control lines: .RS -.IP ^^ 4 +.IP \*^\*^ 4 a line starting with a (single) literal caret -.IP ^# +.IP \*^# a comment -.IP ^?\fIID +.IP \*^?\fIID if the .I ID is defined set the conditional state to TRUE -.IP ^!\fIID +.IP \*^!\fIID if the .I ID is not defined set the conditional state to TRUE -.IP ^: +.IP \*^: else; invert the conditional state -.IP ^. +.IP \*^. end the most recent conditional .RE .\".SH EXAMPLES diff --git a/doc/recover.6 b/doc/recover.6 index 1fcdff662..5d78684ee 100644 --- a/doc/recover.6 +++ b/doc/recover.6 @@ -10,7 +10,9 @@ .. .NB $NHDT-Branch: NetHack-5 $ .NR $NHDT-Revision: 1.12 $ -.\" groff and AT&T-descended troffs use different hyphenation patterns. +.ie \n(.g .ds ^ \(ha +.el .ds ^ ^ +.\" groff and AT&T-descended troffs use different hyphenation patterns. .\" Don't hyphenate the last word on a page or column, or .\" before/after last/first 2 characters of a word. .ie \n(.g .hy 12 @@ -49,26 +51,26 @@ specified by the game administrator during compilation (usually /usr/games/lib/nethackdir). .ig .PP -^?ALLDOCS +\*^?ALLDOCS For recovery to be possible, .I nethack must have been compiled with the INSURANCE option, and the run-time option .I checkpoint must also have been on. -^: -^?INSURANCE +\*^: +\*^?INSURANCE For recovery to be possible, .I nethack must have been compiled with the INSURANCE option (this configuration was), and the run-time option .I checkpoint must also have been on. -^: +\*^: This configuration of .I nethack was created without support for recovery. -^. -^. +\*^. +\*^. .. NetHack normally writes out files for levels as the player leaves them, so they will be ready for return visits. From 2d3f9b8c217a63ae0725ac22ff39700d1b83361b Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Tue, 5 May 2026 20:12:58 -0500 Subject: [PATCH 193/702] doc/recover.6: Revise synopsis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tighten formatting: set synopsis syntax characters adjacently to operands. Rename `-d` option argument from "directory" to "playground-directory" for clarity. Set operands more idiomatically. They are not given in pairs; instead "base" can be repeated arbitrarily. See, for example, the POSIX reference page for ls(1). https://pubs.opengroup.org/onlinepubs/9799919799/utilities/ls.html Format ellipsis idiomatically. groff_man_style(7): Notes ... The idiomatic roff ellipsis is three dots (periods) with thin space escape sequences \| internally separating them. Since dots both begin control lines and are candidate endâ€ofâ€sentence characters, however, it is sometimes necessary to prefix and/or suffix an ellipsis with the dummy character escape sequence \&. --- doc/recover.6 | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/doc/recover.6 b/doc/recover.6 index 5d78684ee..922981d00 100644 --- a/doc/recover.6 +++ b/doc/recover.6 @@ -22,11 +22,10 @@ recover \- recover a NetHack game interrupted by disaster .SH SYNOPSIS .B recover -[ -.B \-d -.I directory -] -.I "base1 base2" ... +.RB [ \-d +.IR playground-directory ] +.I base +\&.\|.\|. .SH DESCRIPTION Occasionally, a NetHack game will be interrupted by disaster when the game or the system crashes. From 61a16e69832fd11dd83cbf55ec0cc0ed681a8451 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Tue, 5 May 2026 20:17:52 -0500 Subject: [PATCH 194/702] doc/recover.6: Fix style and markup nits * Identify NETHACKDIR and HACKDIR as environment variables. * ...and set them italics, not roman. * Set default playground directory name in italics, not roman. * Set command names in italics. * Refer to command operands as such, not as "options". * Use man page cross reference on first occurrence of "nethack" when referring to the command executable as opposed to the overall game. Because some text is commented out (`ig`nored), meaning the "first" occurrence appears twice (what's lexically present vs. what's formatted) do this twice as future-proofing. * Set file names in italics, not roman. Set variable parts of file names in roman. * Refer to "single-user systems" instead of "microcomputers"; the latter is becoming antiquated terminology. * Favor present tense over future. * Tighten wording. * Spell "save files" consistently as two words. --- doc/recover.6 | 70 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/doc/recover.6 b/doc/recover.6 index 922981d00..a1c8ad68b 100644 --- a/doc/recover.6 +++ b/doc/recover.6 @@ -27,32 +27,38 @@ recover \- recover a NetHack game interrupted by disaster .I base \&.\|.\|. .SH DESCRIPTION -Occasionally, a NetHack game will be interrupted by disaster -when the game or the system crashes. -Prior to NetHack v3.1, these games were lost because various information +Occasionally, a NetHack game is interrupted by disaster +when the program or the system crashes. +Prior to NetHack v3.1, these games were lost because information like the player's inventory was kept only in memory. Now, all pertinent information can be written out to disk, so such games can be recovered at the point of the last level change. .PP -The -.I base -options tell +.I Base +operands tell .I recover which files to process. -Each base option specifies recovery of a separate game. +Each +.I base +specifies recovery of a separate game. .PP The .B \-d option, which must be the first argument if it appears, -supplies a directory which is the NetHack playground. -It overrides the value from NETHACKDIR, HACKDIR, or the directory +supplies the directory housing the NetHack playground. +It overrides the value of the environment variables +.I NETHACKDIR +and +.IR HACKDIR , +and the directory specified by the game administrator during compilation -(usually /usr/games/lib/nethackdir). +(usually +.IR /usr/games/lib/nethackdir ). .ig .PP \*^?ALLDOCS For recovery to be possible, -.I nethack +.IR nethack (6) must have been compiled with the INSURANCE option, and the run-time option .I checkpoint must also have been on. @@ -71,26 +77,34 @@ was created without support for recovery. \*^. \*^. .. -NetHack normally writes out files for levels as the player leaves them, +.IR nethack (6) +normally writes out files for levels as the player leaves them, so they will be ready for return visits. -When checkpointing, NetHack also writes out the level entered and +When checkpointing, it also writes out the level entered and the current game state on every level change. -This naturally slows level changes down somewhat. +This procedure slows level changes. .PP -The level file names are of the form base.nn, where nn is an internal -bookkeeping number for the level. -The file base.0 is used for game identity, locking, and, when checkpointing, +The level file names are of the form +.IR base. nn, where +.I nn +is an internal bookkeeping number for the level. +The file +.I base.0 +is used for game identity, locking, and, when checkpointing, for the game state. Various OSes use different strategies for constructing the base name. -Microcomputers use the character name, possibly truncated and modified +Single-user systems use the character name, +possibly truncated and modified to be a legal filename on that system. Multi-user systems use the (modified) character name prefixed by a user number to avoid conflicts, -or "xlock" if the number of concurrent players is being limited. +or +.I xlock +if the number of concurrent players is being limited. It may be necessary to look in the playground to find the correct base name of the interrupted game. .I recover -will transform these level files into a save file of the same name as +transforms these level files into a save file of the same name that .I nethack would have used. .PP @@ -105,13 +119,16 @@ through setuid or setgid is tantamount to leaving the playground world-writable, with respect to both cheating and messing up other players. For a single-user system, this of course does not change anything, -so some of the microcomputer ports install +so some of these ports install .I recover by default. .PP For a multi-user system, -the game administrator may want to arrange for all .0 files in the -playground to be fed to recover when the host machine boots, +the game administrator may want to arrange for all +.I .0 +files in the playground to be fed to +.I recover +when the host machine boots, and handle game crashes individually. If the user population is sufficiently trustworthy, .I recover @@ -126,7 +143,7 @@ Like .I nethack itself, .I recover -will overwrite existing savefiles of the same name. +will overwrite existing save files of the same name. Savefiles created by .I recover are uncompressed; @@ -143,8 +160,9 @@ If multiple machines share a playground, this would be impossible to determine. .PP .I recover -should be taught to use the nethack playground locking mechanism to -avoid conflicts. +should be taught to use the +.I nethack +playground locking mechanism to avoid conflicts. .SH COPYRIGHT .\" All troffs and nroffs support `\(co` except Plan 9 nroff, but Plan 9 .\" offers no test for special character availability, and its feature From 74a3dc9d71cf5335f3bcc3c1536a6fba17a67886 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Wed, 6 May 2026 03:56:42 -0500 Subject: [PATCH 195/702] doc/makedefs.6: Fix style and markup nits * Set cross reference to "nethack" man page in lowercase, because that's the name under which it's installed, and POSIX systems are case-sensitive. * Refer to the "nethack" command using a man page cross reference only on its first occurrence. * Favor bullets over hyphens for itemized list. * Drop explicit indentation amounts from lists. The man(7) package's default suffices on all of Solaris 10, DWB 3.3, Plan 9, Heirloom Doctools, and GNU *roffs, and on mandoc(1). * Use tagged paragraphs to set synopses of syntax productions used in the documented file format. * Drop inset (indentation) of itemized and tagged lists; the bullets make the structure clear, and (with the foregoing change) this way the paragraphs align. --- doc/makedefs.6 | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/doc/makedefs.6 b/doc/makedefs.6 index 9c33ef6e3..81193649e 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -42,7 +42,7 @@ makedefs \- NetHack miscellaneous build-time functions .SH DESCRIPTION .B Makedefs is a build-time tool used for a variety of -.BR NetHack (6) +.IR nethack (6) source file creation and modification tasks. For historical reasons, .B makedefs @@ -210,58 +210,61 @@ The command (and certain other commands) filter their input, on a line-by-line basis, according to control lines embedded in the input and on information gleaned from the -.IR NetHack (6) +.I nethack configuration. This allows certain changes such as embedding platform-specific documentation into the master documentation files. .P Rules: -.RS -.IP - 4 +.IP \(bu The default conditional state is printing enabled. -.IP - 4 +.IP \(bu Any line .I NOT starting with a caret (\*^) is either suppressed or passed through unchanged depending on the current conditional state. -.IP - 4 +.IP \(bu Any line starting with a caret is a control line; as in C, zero or more spaces may be embedded in the line almost anywhere (except immediately after the caret); however the caret must be in column 1. -.IP - 4 +.IP \(bu Conditionals may be nested. -.IP - 4 +.IP \(bu .I Makedefs will exit with an error code if any errors are detected; processing will continue (if it can) to allow as many errors as possible to be detected. -.IP - 4 +.IP \(bu Unknown identifiers are treated as both TRUE and as an error. Note that .BR \-\-undef " or " #undef in the -.IR NetHack (6) +.I nethack configuration are different from unknown. -.RE .P Control lines: -.RS -.IP \*^\*^ 4 +.TP +.B +\*^\*^ a line starting with a (single) literal caret -.IP \*^# +.TP +.B \*^# a comment -.IP \*^?\fIID +.TP +.B \*^?\fIID if the .I ID is defined set the conditional state to TRUE -.IP \*^!\fIID +.TP +.B \*^!\fIID if the .I ID is not defined set the conditional state to TRUE -.IP \*^: +.TP +.B \*^: else; invert the conditional state -.IP \*^. +.TP +.B \*^. end the most recent conditional -.RE .\".SH EXAMPLES .SH AUTHOR The NetHack Development Team From 1d13d2ce623260ade844ce6d05093b7fdc9eb8fd Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Wed, 6 May 2026 04:30:52 -0500 Subject: [PATCH 196/702] doc/nethack.6: Fix markup nits Drop unnecessary quotation marks from macro call arguments. --- doc/nethack.6 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index 554b8dd16..f19de5012 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -187,7 +187,7 @@ while .\" on the Macintosh or BeOS, it is \*(lqNetHack Defaults\*(rq, and on VMS|OpenVMS it is nethack.ini in your home directory. The default configuration file may be overridden via the -.BI \-\-nethackrc: "rc-file" +.BI \-\-nethackrc: rc-file command line option or by setting NETHACKOPTIONS in your environment to a string consisting of an @ character followed by the path and filename. .PP @@ -337,7 +337,7 @@ The option will use .I rc-file instead of the default run-time configuration file -.RI "(typically " \*~/.nethackrc ")" +.RI "(typically " \*~/.nethackrc ) and the .B \-\-no\-nethackrc option can be used to skip any run-time configuration file. From 76303faeaba39e7d99ef4f7b5c53dd2ad3da71f3 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Wed, 6 May 2026 04:34:13 -0500 Subject: [PATCH 197/702] doc/*.6: Use typographer's double quotes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ...where available. groff_man_style(7): Notes ... • When and how should I use quotation marks? ... groff, Heirloom Doctools troff, neatroff, and mandoc support all of the special characters \[oq], \[cq], \[lq], \[rq], \[aq], and \[dq] described in subsection “Portability†above. DWB, Plan 9, and Solaris troffs do not. Interpolating the strings \*(lq and \*(rq portably yields directional double quotation marks, if available, in all these formatters (though neatroff does not supply a man macro package), but they cannot reliably be used in macro arguments. --- doc/makedefs.6 | 4 ++-- doc/nethack.6 | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/makedefs.6 b/doc/makedefs.6 index 81193649e..af3919c39 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -192,7 +192,7 @@ is known and defined, otherwise exit shell false (1). .BI \-\-grep\-define " symbol" Force the value of .I symbol -to be "defined." +to be \*(lqdefined.\*(rq .I Symbol must already be known to .BR makedefs . @@ -200,7 +200,7 @@ must already be known to .BI \-\-grep\-undef " symbol" Force the definition of .I symbol -to be "undefined." +to be \*(lqundefined.\*(rq .I Symbol must already be known to .BR makedefs . diff --git a/doc/nethack.6 b/doc/nethack.6 index f19de5012..081bd6c39 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -194,7 +194,7 @@ to a string consisting of an @ character followed by the path and filename. The .B \-u .I player-name -option supplies the answer to the question "Who are you?". +option supplies the answer to the question \*(lqWho are you?\*(rq. It overrides any name from the options or configuration file, USER, LOGNAME, or getlogin(), which will otherwise be tried in order. If none of these provides a useful name, the player will be asked for one. @@ -208,19 +208,19 @@ suffix can be used to specify the profession, race, alignment and/or gender of the character. The full syntax of a .I player-name -including a suffix is "name\-ppp\-rrr\-aaa\-ggg". -"ppp" are at least the first three letters +including a suffix is \*(lqname\-ppp\-rrr\-aaa\-ggg\*(rq. +\*(lqppp\*(rq are at least the first three letters of the profession (this can also be specified using a separate .B \-p .I profession option). -"rrr" are at least the first three letters of the character's +\*(lqrrr\*(rq are at least the first three letters of the character's race (this can also be specified using a separate .B \-r .I race option). -"aaa" are at least the first three letters of the character's -alignment, and "ggg" are at least the first three letters of the +\*(lqaaa\*(rq are at least the first three letters of the character's +alignment, and \*(lqggg\*(rq are at least the first three letters of the character's gender. Any of the parts of the suffix may be left out. .PP From 48ae0eb46e31f83743452580428e9314904784f4 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Wed, 6 May 2026 04:19:40 -0500 Subject: [PATCH 198/702] doc/nethack.6: Rewrite initial description I noticed that the "Dungeons & Dragons" trademark acknowledgement should be using the _registered_ trade mark sign instead of the more general one, as the mark's enjoyed registered status (in the U.S.) since 1978. https://tmsearch.uspto.gov/search/search-results/73123558 It occurred to me that updating the game description for a 2026 audience might be an improvement on one that assumes the reader is familiar with D&D, with Teletype machines ("TTYs"), and with the Rogue game, which NetHack arguably eclipsed in notoriety decades ago. So I rewrote it, and dropped the references to D&D. Besides, as of commit c99da87c700, NetHack is incompatible with "Strength Table I." in the AD&D Player's Handbook (TSR 2010, p. 9), so any grognard who lifts would snatch NetHack's D&D membership card away anyway. ;-) --- doc/nethack.6 | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index 081bd6c39..7decd3bf5 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -123,10 +123,17 @@ can be any of the following. .hw nethackdir .SH DESCRIPTION .I NetHack -is a display oriented Dungeons & Dragons(tm) - like game. -The standard tty display and command structure resemble rogue. +is a fantasy-themed game of surival, +exploration, +and combat +set in the Mazes of Menace, +an elaborate underground complex. .PP -Other, more graphical display options exist for most platforms. +Traditionally, +the game's interface uses a Unix terminal connection, +depicting the interface on a grid of character cells +and responding to keyboard-entered commands. +Other interface options exist for most platforms. .PP To get started you really only need to know two commands. The command @@ -658,5 +665,3 @@ Probably infinite. This file is Copyright \*(co \*(Na, \*(Nd for version \*(Nb:\*(Nr. NetHack may be freely redistributed. See license for details. -.PP -Dungeons & Dragons is a Trademark of Wizards of the Coast, Inc. From cc4c5227af11442d69e735f970dd74b499b6fd99 Mon Sep 17 00:00:00 2001 From: nhkeni Date: Wed, 6 May 2026 16:19:02 -0400 Subject: [PATCH 199/702] use full URL for nethack.org in Guidebook.mn --- doc/Guidebook.mn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 60a993cd5..e74f2f81d 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -6716,7 +6716,7 @@ and had not gone through the process of debugging it as a suitable release, it was decided that the version numbers present on that code snapshot would be retired and never used in an official NetHack release. An announcement was posted on the NetHack Development Team's official -.UR nethack.org +.UR https://www.nethack.org website to that effect, stating that there would never be a 3.4.4, 3.5, or 3.5.0 official release version. From 6ed95bebba1d6fea8c1c327c21476270a9a3bdff Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 6 May 2026 22:58:34 -0400 Subject: [PATCH 200/702] paste error in Guidebook.tex --- doc/Guidebook.tex | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index e0c1e43c5..2302522aa 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -7588,7 +7588,6 @@ and dungeon compilers of past versions, with a new Lua interpreter-based approach to provide those elements. Lua is also used for the quest texts in \textit{NetHack} 5.0.0. The entire development team acknowledges the work done by \textit{Pasi Kallinen} to make that happen. -\textit{Ray Chason} %.pg \medskip From 6204679bfd45ebf5b5a88599681a885afa097a2b Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 6 May 2026 23:02:29 -0400 Subject: [PATCH 201/702] Guidebook type fix --- doc/Guidebook.mn | 2 +- doc/Guidebook.tex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index e74f2f81d..62a7ef492 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -6852,7 +6852,7 @@ work with the msdos port and keep it alive. Cross-compiling the MS-DOS port has helped make that possible and mostly painless. .pg People that contributed to the Windows port of NetHack 5.0 since the -development of NetHack 5.0 begain over eleven years ago, included +development of NetHack 5.0 began over eleven years ago, included \fBMichael Allison\fP, \fBDavid Cohrs\fP, \fBBart House\fP, \fBPasi Kallinen\fP, \fBAlex Kompel\fP, \fBDion Nicolaas\fP, \fBDerek S. Ray\fP and \fBYitzhak Sapir\fP. diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 2302522aa..6f129f090 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -7623,7 +7623,7 @@ port has helped make that possible and mostly painless. %.pg \medskip People that contributed to the Windows port of \textit{NetHack} 5.0 since the -development of \textit{NetHack} 5.0 begain over eleven years ago, included +development of \textit{NetHack} 5.0 began over eleven years ago, included \textit{Michael Allison}, \textit{David Cohrs}, \textit{Bart House}, \textit{Pasi Kallinen}, \textit{Alex Kompel}, \textit{Dion Nicolaas}, \textit{Derek S. Ray} and \textit{Yitzhak Sapir}. From 89c6b49b0c91d49d437b186183b7a2a5d9c16673 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 6 May 2026 23:19:13 -0400 Subject: [PATCH 202/702] spelling correction in nethack.6 --- doc/nethack.6 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/nethack.6 b/doc/nethack.6 index 7decd3bf5..d6c922e00 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -123,7 +123,7 @@ can be any of the following. .hw nethackdir .SH DESCRIPTION .I NetHack -is a fantasy-themed game of surival, +is a fantasy-themed game of survival, exploration, and combat set in the Mazes of Menace, From d52b1daf50bb1400b10e1d2465dd32ee39cdc555 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 7 May 2026 00:23:16 -0400 Subject: [PATCH 203/702] bring fixes5-0-1.txt up to date --- doc/fixes5-0-1.txt | 80 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 doc/fixes5-0-1.txt diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt new file mode 100644 index 000000000..298263c04 --- /dev/null +++ b/doc/fixes5-0-1.txt @@ -0,0 +1,80 @@ +NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.0 $ $NHDT-Date: 1777000050 2026/05/06 11:30:00 $ + +General Fixes and Modified Features +----------------------------------- +fix some cross-compile package filenames that still referenced 370 instead + of 500 +Use NHV macro (NHV=500) for filenames in Makefiles and/or hints files to make + it less likely to overlook or miss them next time +early startup options such as --showpaths could be run non-interactively, so + ensure that getret() doesn't prompt and wait for user input +fix issue where the new game startup message was stating 'Work-in-progress' + even when NH_DEVEL_STATUS was set to NH_STATUS_POSTRELEASE +if 'mention_decor' was set in config file or NETHACKOPTIONS, + starting the game told you that "you are standing on stairs which lead + out of the dungeon", even when the player entered the tutorial where that + wasn't true +doc: use full URL for nethack.org in Guidebook.mn +doc: fix a paste error in Guidebook.tex +doc: fix spelling correction in nethack.6 + +Platform- and/or Interface-Specific Fixes +----------------------------------------- +Amiga: fall back to text mode when tile mode is not viable +Amiga: Detect Workbench depth, display-database MaxDepth, and free chip RAM + if any signals AMIV can't run (e.g. A1000 with 4-colour WB) +Amiga: swap windowprocs to amii_procs before opening any screens +Amiga: disable SYSCF, drop sysconf from package; assure_syscf_file() was + killing the binary when run outside NetHack: was breaking normal + launches +Amiga: honor __stack under libnix; reference __stkinit so the linker pulls + swapstack.o from libnix.a; without it the program runs on the + inherited shell stack and crashes inside Lua / level-gen +Amiga: provide a real v4 UUID via get_nhuuid +Amiga: ship as a NetHack drawer with drawer icon and README +Amiga: ship Workbench icons for the binary and text files +Amiga: fix misleading fallback warning and stale comment +Amiga: stop rendering CLR_BLACK and CLR_WHITE as inverse video +Amiga: default number_pad:1 in shipped nethack.cnf +Amiga: promote AMIGA_INTUITION to supported so it shows up in version info +Amiga: wire altmeta option to sysflags.altmeta +libnh: update get_nhuuid() for libnhmain +libnh: sys/libnh/libnhmain.c: drop `static` on `whoami()` +libnh: rewrote sys/unix/hints/macOS.500: rewrote the libnh.a rule. The + `ar rcs libnh.a $(HOBJ) $(LIBNHSYSOBJ) liblua-$(LUA_VERSION).a` had + four problems: (a) ar archives liblua.a as a single opaque member + that macOS ld can't dereference, (b) date.o (DATE_O, kept separate + from HOBJ) was never archived, so `populate_nomakedefs` and + `nomakedefs` were missing, (c) hacklib.a was likewise omitted, and + (d) HOBJ already contains $(SYSOBJ) (with unixmain.o) and $(WINOBJ) + (the tty windowport), which duplicated symbols from libnhmain.o / + winshim.o. +libnh: sys/libnh/libnhmain.c: gate the emscripten-only code in get_nhuuid + with `#ifdef __EMSCRIPTEN__` instead of `#ifdef NHUUID` +libnh: sys/unix/hints/macOS.500 in the WANT_LIBNH block, add an explicit + `recover: lua_support` dependency (gated by MAKEFILE_TOP). When + $(GAME) is overridden to empty, the regular `recover: $(GAME)` chain + no longer triggers `lua_support`, so include/nhlua.h never gets + generated and recover.c's transitive #include of hack.h fails. +macOS: fix ncurses build with Homebrew +WASM: resolve some build failures in 'make CROSS_TO_WASM=1' +WASM: hints file cross-pre2.500 update to CFLAGS to include -DNHUUID + + + +General New Features +-------------------- + + +Platform- and/or Interface-Specific New Features +------------------------------------------------ + + +NetHack Community Patches (or Variation) Included +------------------------------------------------- + + +Code Cleanup and Reorganization +------------------------------- + + From 1c1f64dc19f41068a90c1c7120effe64d1ec9faa Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 7 May 2026 07:02:26 -0400 Subject: [PATCH 204/702] Issue #1521 asks for Contributing.md file This is expected to improve and fill out over time, with more guidelines for contributing. --- DEVEL/Contributing.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 DEVEL/Contributing.md diff --git a/DEVEL/Contributing.md b/DEVEL/Contributing.md new file mode 100644 index 000000000..5026dde0b --- /dev/null +++ b/DEVEL/Contributing.md @@ -0,0 +1,9 @@ +# NetHack 3.7 Contributing.txt $NHDT-Date: 1596498265 2020/08/03 23:44:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.19 $ +# NetHack may be freely redistributed. See license for details. + +If you are making a GitHub pull request for NetHack, please follow these guidelines: + +1. The 50/72 Rule: Keep the subject line (the first line) under 50 characters +for readability in git log --oneline. If you need a more detailed description +(the body), wrap it at 72 characters. + From 22009c300ad51142306a3572ed66ea500bc3ebe9 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 7 May 2026 07:11:55 -0400 Subject: [PATCH 205/702] update to DEVEL/Contributing.md --- DEVEL/Contributing.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DEVEL/Contributing.md b/DEVEL/Contributing.md index 5026dde0b..99d170922 100644 --- a/DEVEL/Contributing.md +++ b/DEVEL/Contributing.md @@ -7,3 +7,6 @@ If you are making a GitHub pull request for NetHack, please follow these guideli for readability in git log --oneline. If you need a more detailed description (the body), wrap it at 72 characters. +2. Separate Subject from Body: Always include a blank line between the subject +and the body. This helps Git tools correctly parse the message. + From 88bacb00c2b38c30a2fc248ccb2456283b98d112 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 7 May 2026 07:14:56 -0400 Subject: [PATCH 206/702] fixes update --- doc/fixes5-0-1.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 298263c04..09549b72e 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.0 $ $NHDT-Date: 1777000050 2026/05/06 11:30:00 $ +NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.0 $ $NHDT-Date: 1778152494 2026/05/07 11:14:54 $ General Fixes and Modified Features ----------------------------------- @@ -76,5 +76,6 @@ NetHack Community Patches (or Variation) Included Code Cleanup and Reorganization ------------------------------- - +add Contributing.md with some guidelines for making a pull request that + is in an acceptable format From 4a4b4498a8d1eb2cb46ee892388dd8e0a03ce9e2 Mon Sep 17 00:00:00 2001 From: Yoichiro Takahashi Date: Thu, 7 May 2026 21:22:15 +0900 Subject: [PATCH 207/702] Respect ncurses cflags on Linux tty --- sys/unix/hints/linux.500 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index b822b6e50..05cb8c956 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -177,7 +177,7 @@ NHCFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" #NHCFLAGS+=-DLIVELOG #NHCFLAGS+=-DCHANGE_COLOR NHCFLAGS+=-DSELF_RECOVER -ifdef WANT_WIN_CURSES +ifeq "$(USE_CURSESLIB)" "1" NHCFLAGS+=$(NCURSES_CFLAGS) ifeq "$(HAVE_NCURSESW)" "1" NHCFLAGS+=-DCURSES_UNICODE @@ -186,7 +186,7 @@ ifdef MAKEFILE_SRC $(info Attention: CURSES_UNICODE is not being defined without ncursesw) endif #MAKEFILE_SRC endif #HAVE_NCURSESW -endif #WANT_WIN_CURSES +endif #USE_CURSESLIB # #-INCLUDE multisnd1-pre.500 From 39f31a8f065e0301d51f3f9179d98d65440567f4 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 7 May 2026 10:43:24 -0400 Subject: [PATCH 208/702] fix a CROSS_TO_WASM=1 build issue --- sys/unix/hints/include/cross-pre2.500 | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/unix/hints/include/cross-pre2.500 b/sys/unix/hints/include/cross-pre2.500 index 03c35bcc7..6a1331c6a 100644 --- a/sys/unix/hints/include/cross-pre2.500 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -363,6 +363,7 @@ override LUALIB= override TOPLUALIB= override REGEXOBJ = $(TARGETPFX)posixregex.o override WINOBJ= +override UUIDOBJ= # don't bother Making regular NetHack executable override GAME= # the real VARDAT hasn't been defined yet for use in ALLDEP override From 4938a85068980dcc8d6d0003f8b9e732a0c712bf Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 7 May 2026 11:40:14 -0400 Subject: [PATCH 209/702] relocate Contributing.md to the root --- DEVEL/Contributing.md => Contributing.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename DEVEL/Contributing.md => Contributing.md (100%) diff --git a/DEVEL/Contributing.md b/Contributing.md similarity index 100% rename from DEVEL/Contributing.md rename to Contributing.md From 92734c32831098b4002f3a9b2a0413be5dfab87a Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Thu, 7 May 2026 19:43:08 -0400 Subject: [PATCH 210/702] This is cron-daily v1-May-7-2026. 005manpages updated: recover.txt --- doc/recover.txt | 52 ++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/doc/recover.txt b/doc/recover.txt index bfbc9f36a..2631dda0e 100644 --- a/doc/recover.txt +++ b/doc/recover.txt @@ -6,39 +6,39 @@ NAME recover - recover a NetHack game interrupted by disaster SYNOPSIS - recover [ -d directory ] base1 base2 ... + recover [-d playground-directory] base ... DESCRIPTION - Occasionally, a NetHack game will be interrupted by disaster when the - game or the system crashes. Prior to NetHack v3.1, these games were - lost because various information like the player's inventory was kept - only in memory. Now, all pertinent information can be written out to - disk, so such games can be recovered at the point of the last level - change. + Occasionally, a NetHack game is interrupted by disaster when the pro- + gram or the system crashes. Prior to NetHack v3.1, these games were + lost because information like the player's inventory was kept only in + memory. Now, all pertinent information can be written out to disk, so + such games can be recovered at the point of the last level change. - The base options tell recover which files to process. Each base option - specifies recovery of a separate game. + Base operands tell recover which files to process. Each base specifies + recovery of a separate game. The -d option, which must be the first argument if it appears, supplies - a directory which is the NetHack playground. It overrides the value - from NETHACKDIR, HACKDIR, or the directory specified by the game admin- - istrator during compilation (usually /usr/games/lib/nethackdir). - NetHack normally writes out files for levels as the player leaves them, - so they will be ready for return visits. When checkpointing, NetHack - also writes out the level entered and the current game state on every - level change. This naturally slows level changes down somewhat. + the directory housing the NetHack playground. It overrides the value + of the environment variables NETHACKDIR and HACKDIR, and the directory + specified by the game administrator during compilation (usually + /usr/games/lib/nethackdir). nethack(6) normally writes out files for + levels as the player leaves them, so they will be ready for return vis- + its. When checkpointing, it also writes out the level entered and the + current game state on every level change. This procedure slows level + changes. - The level file names are of the form base.nn, where nn is an internal + The level file names are of the form base.nn,where nn is an internal bookkeeping number for the level. The file base.0 is used for game identity, locking, and, when checkpointing, for the game state. Vari- - ous OSes use different strategies for constructing the base name. - Microcomputers use the character name, possibly truncated and modified - to be a legal filename on that system. Multi-user systems use the + ous OSes use different strategies for constructing the base name. Sin- + gle-user systems use the character name, possibly truncated and modi- + fied to be a legal filename on that system. Multi-user systems use the (modified) character name prefixed by a user number to avoid conflicts, - or "xlock" if the number of concurrent players is being limited. It - may be necessary to look in the playground to find the correct base - name of the interrupted game. recover will transform these level files - into a save file of the same name as nethack would have used. + or xlock if the number of concurrent players is being limited. It may + be necessary to look in the playground to find the correct base name of + the interrupted game. recover transforms these level files into a save + file of the same name that nethack would have used. Since recover must be able to read and delete files from the playground and create files in the save directory, it has interesting interactions @@ -46,7 +46,7 @@ DESCRIPTION setuid or setgid is tantamount to leaving the playground world- writable, with respect to both cheating and messing up other players. For a single-user system, this of course does not change anything, so - some of the microcomputer ports install recover by default. + some of these ports install recover by default. For a multi-user system, the game administrator may want to arrange for all .0 files in the playground to be fed to recover when the host @@ -56,7 +56,7 @@ DESCRIPTION is easily compiled from the distribution utility directory. NOTES - Like nethack itself, recover will overwrite existing savefiles of the + Like nethack itself, recover will overwrite existing save files of the same name. Savefiles created by recover are uncompressed; they may be compressed afterwards if desired, but even a compression-using nethack will find them in the uncompressed form. From 3f02b77f2efc43457b3a8578f7e75a6249cd60f0 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Thu, 7 May 2026 19:43:08 -0400 Subject: [PATCH 211/702] This is cron-daily v1-May-7-2026. 005manpages updated: nethack.txt --- doc/nethack.txt | 251 +++++++++++++++++++++++++++++++----------------- 1 file changed, 162 insertions(+), 89 deletions(-) diff --git a/doc/nethack.txt b/doc/nethack.txt index cc9e5dffc..c3e19b0e2 100644 --- a/doc/nethack.txt +++ b/doc/nethack.txt @@ -6,24 +6,44 @@ NAME nethack - Exploring The Mazes of Menace SYNOPSIS - nethack [ -d|--directory directory ] [ -w|--windowtype interface ] - [ --nethackrc:RC-file | --no-nethackrc ] [ -n ] [ -dec | -ibm ] - [ -u playername ] [ -X | -D ] [ -p profession ] [ -r race ] [ -@ ] + nethack [role-option] [-d|--directory directory] [-w|--window- + type interface] [--nethackrc:rc-file|--no-nethackrc] [-n] + [-dec|-ibm] [-u player-name] [-X|-D] [-p profession] [-r race] + [-@] - Also [ -A|-Arc | -B|-Bar | -C|-Cav | -H|-Hea | -K|-Kni | -M|-Mon | - -P|-Pri | -R|-Rog | -Ran | -S|-Sam | -T|-Tou | -V|-Val | -W|-Wiz ] + role-option can be any of the following. - nethack [ -d|--directory directory ] -s|--scores [ -v ] - [ -p profession ] [ -r race ] [ playernames ] + -A|-Arc + -B|-Bar + -C|-Cav + -H|-Hea + -K|-Kni + -M|-Mon + -P|-Pri + -R|-Rog + -Ran + -S|-Sam + -T|-Tou + -V|-Val + -W|-Wiz - nethack [ --usage | --help ] [ --showpaths ] - [ --version[:copy|:dump|:show] ] + nethack {-s|--scores} [-d|--directory directory] [-v] [-p profession] + [-r race] [player-name ...] + + nethack {--usage|--help} + + nethack --showpaths + + nethack --version[:copy|:dump|:show] DESCRIPTION - NetHack is a display oriented Dungeons & Dragons(tm) - like game. The - standard tty display and command structure resemble rogue. + NetHack is a fantasy-themed game of survival, exploration, and combat + set in the Mazes of Menace, an elaborate underground complex. - Other, more graphical display options exist for most platforms. + Traditionally, the game's interface uses a Unix terminal connection, + depicting the interface on a grid of character cells and responding to + keyboard-entered commands. Other interface options exist for most + platforms. To get started you really only need to know two commands. The command ? will give you a list of the available commands (as well as other @@ -65,7 +85,7 @@ DESCRIPTION setting NETHACKOPTIONS in your environment to a string consisting of an @ character followed by the path and filename. - The -u playername option supplies the answer to the question "Who are + The -u player-name option supplies the answer to the question "Who are you?". It overrides any name from the options or configuration file, USER, LOGNAME, or getlogin(), which will otherwise be tried in order. If none of these provides a useful name, the player will be asked for @@ -74,9 +94,9 @@ DESCRIPTION versely, you must use the appropriate player name to restore a saved game. - A playername suffix can be used to specify the profession, race, align- - ment and/or gender of the character. The full syntax of the playername - that includes a suffix is "name-ppp-rrr-aaa-ggg". "ppp" are at least + A player-name suffix can be used to specify the profession, race, + alignment and/or gender of the character. The full syntax of a player- + name including a suffix is "name-ppp-rrr-aaa-ggg". "ppp" are at least the first three letters of the profession (this can also be specified using a separate -p profession option). "rrr" are at least the first three letters of the character's race (this can also be specified using @@ -100,7 +120,7 @@ DESCRIPTION must be uppercase. Ranger has no single-letter choice because -R is already used for the Rogue role. - -@ tells nethack to choose any omitted characteristics (profes- + -@ tells NetHack to choose any omitted characteristics (profes- sion/role, race, gender, alignment) randomly without prompting. Other- wise, leaving out any of these characteristics will result in you being prompted during game startup for the information. @@ -113,16 +133,16 @@ DESCRIPTION mode (also known as wizard mode) after changing the character name to "wizard", if the player is allowed. Otherwise it will switch to -X. Control of who is allowed to use debug mode is done via the "WIZARDS=" - line in nethack's sysconf file. + line in NetHack's sysconf file. The -d or --directory option, which must be the first argument if it appears, supplies a directory which is to serve as the playground. It overrides the value from NETHACKDIR, HACKDIR, or the directory speci- - fied by the game administrator during compilation (usually - /usr/games/lib/nethackdir). This option is usually only useful to the - game administrator. The playground must contain several auxiliary - files such as help files, the list of top scorers, and a subdirectory - save where games are saved. + fied by the game administrator during compilation (usually /usr/games/ + lib/nethackdir). This option is usually only useful to the game admin- + istrator. The playground must contain several auxiliary files such as + help files, the list of top scorers, and a subdirectory save where + games are saved. The -w or --windowtype interface option can be used to specify which interface to use if the program has been built with support for more @@ -130,7 +150,7 @@ DESCRIPTION specified in the run-time configuration file. NetHack's #version com- mand shows available interfaces. - The --nethackrc:RC-file option will use RC-file instead of the default + The --nethackrc:rc-file option will use rc-file instead of the default run-time configuration file (typically ~/.nethackrc) and the --no-nethackrc option can be used to skip any run-time configuration file. @@ -194,81 +214,136 @@ AUTHORS FILES Run-time configuration options were discussed above and use a platform specific name for a file in a platform specific location. For Unix, - the name is '.nethackrc' in the user's home directory. + the name is .nethackrc in the user's home directory. - All other files are in the playground directory, normally - /usr/games/lib/nethackdir. If DLB was defined during the compile, the - data files and special levels will be inside a larger file, normally - nhdat, instead of being separate files. + All other files are in the playground directory, normally /usr/games/ + lib/nethackdir. If DLB was defined during the compile, the data files + and special levels will be inside a larger file, normally nhdat, + instead of being separate files. - nethack The program itself. - Guidebook | Guidebook.txt NetHack's user manual. - data, oracles, rumors Data files used by NetHack. - bogusmon Another data file. - engrave, epitaph, tribute Still more data files. - symbols Data file holding sets of specifications - for how to display monsters, objects, and - map features. - options Data file containing a description of the - build-time option settings. - help, hh, cmdhelp Help data files. ('cmdhelp' is obsolete.) - opthelp, optmenu, wizhelp More help data files. - keyhelp, usagehlp Even more help data files. - *.lua Predefined special levels, dungeon control - for special levels, quest texts. - history A short history of NetHack. - license Rules governing redistribution. - record The list of top scorers. - logfile An extended list of games played - (optional). - xlogfile A more detailed version of 'logfile' - (also optional). - paniclog Record of exceptional conditions - discovered during program execution. - xlock.nn Description of dungeon level 'nn' of - active game 'x' if there's a limit on the - number of simultaneously active games. - UUcccccc.nn Alternate form for dungeon level 'nn' - of active game by user 'UU' playing - character named 'cccccc' when there's no - limit on number of active games. - perm Lock file for xlock.0 or UUcccccc.0. - bonD0.nn Descriptions of the ghost and belongings - of a deceased adventurer who met his or - her demise on level 'nn'. A subsequent - character might encounter this old level. + nethack + The program itself. - save/ A subdirectory containing saved games. + Guidebook + Guidebook.txt + NetHack's user manual. - sysconf System-wide options. Required if - program is built with 'SYSCF' option - enabled, ignored if not. + data + oracles + rumors Data files used by NetHack. - The location of 'sysconf' is specified at build time and can't be - changed except by updating source file "config.h" and rebuilding the - program. + bogusmon + Another data file. - NetHack's Guidebook might not be present if whoever packaged or + engrave + epitaph + tribute + Still more data files. + + symbols + Data file holding sets of specifications for how to display mon- + sters, objects, and map features. + + options + Data file containing a description of the build-time option set- + tings. + + help + hh + cmdhelp + Help data files. (cmdhelp is obsolete.) + + opthelp + optmenu + wizhelp + More help data files. + + keyhelp + usagehlp + Even more help data files. + + *.lua Predefined special levels, dungeon control for special levels, + quest texts. + + history + A short history of NetHack. + + license + Rules governing redistribution. + + record The list of top scorers. + + logfile + An extended list of games played (optional). + + xlogfile + A more detailed version of logfile (also optional). + + paniclog + Record of exceptional conditions discovered during program exe- + cution. + + xlock.nn + Description of dungeon level nn of active game x if there's a + limit on the number of simultaneously active games. + + UUcccccc.nn + Alternate form for dungeon level nn of active game by user UU + playing character named cccccc when there's no limit on number + of active games. + + perm Lock file for xlock.0 or UUcccccc.0. + + bonD0.nn + Descriptions of the ghost and belongings of a deceased adven- + turer who met his or her demise on level nn. A subsequent char- + acter might encounter this old level. + + save/ Subdirectory containing saved games. + + sysconf + System-wide options. Required if program is built with 'SYSCF' + option enabled, ignored if not. + + The location of sysconf is specified at build time and can't be changed + except by updating source file "config.h" and rebuilding the program. + + NetHack's Guidebook might not be present if whoever packaged or installed the program distribution neglected to include it. - In a perfect world, 'paniclog' would remain empty. + In a perfect world, paniclog would remain empty. ENVIRONMENT - USER or LOGNAME Your login name. - HOME Your home directory. - SHELL Your shell. - TERM The type of your terminal. - HACKPAGER or PAGER Replacement for default pager. - MAIL Mailbox file. - MAILREADER Replacement for default reader - (probably /bin/mail or /usr/ucb/mail). - NETHACKDIR or HACKDIR Playground. - NETHACKOPTIONS String predefining several NetHack options. + In some cases, NetHack attempts to access multiple environment vari- + ables in sequence (via getenv(3) or similar) to determine information. + + USER + LOGNAME Your login name. + + HOME Your home directory. + + SHELL Your login shell (not necessarily the one running when + you started NetHack). + + TERM Your terminal type. + + HACKPAGER + PAGER Replacement for default pager. + + MAIL Mailbox file. + + MAILREADER Replacement for default reader (probably /bin/mail or + /usr/ucb/mail). + + NETHACKDIR + HACKDIR Playground. + + NETHACKOPTIONS Predefined NetHack options. If the same option is specified in both NETHACKOPTIONS and .nethackrc, the value assigned in NETHACKOPTIONS takes precedence. - SHOPTYPE and SPLEVTYPE can be used in debugging (wizard) mode. + SHOPTYPE and SPLEVTYPE can be used in debugging (wizard) mode. DEBUGFILES can be used if the program was built with 'DEBUG' enabled. SEE ALSO @@ -278,12 +353,10 @@ BUGS Probably infinite. COPYRIGHT - This file is Copyright (C) Robert Patrick Rankin, 2024 for version - NetHack-5:1.31. NetHack may be freely redistributed. See license for + This file is Copyright (C) Robert Patrick Rankin, 2024 for version + NetHack-5:1.31. NetHack may be freely redistributed. See license for details. - Dungeons & Dragons is a Trademark of Wizards of the Coast, Inc. - NETHACK 26 April 2026 NETHACK(6) From fed12887ca535618808f41fefddbe5d2440b3ebc Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Thu, 7 May 2026 19:43:08 -0400 Subject: [PATCH 212/702] This is cron-daily v1-May-7-2026. 005manpages updated: mnh.txt --- doc/mnh.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/mnh.txt b/doc/mnh.txt index 4d78af3d5..729409a99 100644 --- a/doc/mnh.txt +++ b/doc/mnh.txt @@ -58,4 +58,4 @@ UR mac - - URL passthrough for HTML generator - NETHACK MNH(7) +NETHACK 4 November 2018 MNH(7) From 669e44c670a5daa0d38ad18aaf9fc34f307fca54 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Thu, 7 May 2026 19:43:08 -0400 Subject: [PATCH 213/702] This is cron-daily v1-May-7-2026. 005manpages updated: makedefs.txt --- doc/makedefs.txt | 66 +++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/doc/makedefs.txt b/doc/makedefs.txt index 210ec0ca4..7bae10fa1 100644 --- a/doc/makedefs.txt +++ b/doc/makedefs.txt @@ -6,12 +6,12 @@ NAME makedefs - NetHack miscellaneous build-time functions SYNOPSIS - makedefs { -o | -d | -e | -m | -v | -p | -q | -r | -h } + makedefs {-o|-d|-e|-m|-v|-p|-q|-r|-h} makedefs --input file --output file --command DESCRIPTION - Makedefs is a build-time tool used for a variety of NetHack(6) source + Makedefs is a build-time tool used for a variety of nethack(6) source file creation and modification tasks. For historical reasons, makedefs takes two types of command lines. When invoked with a short option, the files operated on are determined when makedefs is compiled. When @@ -30,11 +30,11 @@ SHORT COMMANDS through the same logic as that used by the --grep command; see the MDGREP FUNCTIONS section below for details. - -m Generate date.h and options file. It will read dat/gitinfo.txt, + -m Generate date.h and options file. It will read dat/gitinfo.txt, only if it is present, to obtain githash= and gitbranch= info and include related preprocessor #defines in date.h file. - -p Generate pm.h + -p Generate pm.h. -q Generate the rumors file. @@ -57,12 +57,12 @@ LONG COMMANDS dash. --input file - Specify the input file for the command (if needed). If the file - is - standard input is read. + Specify the input file for the command (if needed). If file is + "-", makedefs reads the standard input stream. --output file - Specify the output file for the command (if needed). If the - file is - standard output is written. + Specify the output file for the command (if needed). If file is + "-", makedefs writes to the standard input stream. --svs [delimiter] Generate a version string to standard output without a trailing @@ -96,48 +96,46 @@ LONG COMMANDS MDGREP FUNCTIONS The --grep command (and certain other commands) filter their input, on a line-by-line basis, according to control lines embedded in the input - and on information gleaned from the NetHack(6) configuration. This - allows certain changes such as embedding platform-specific documenta- - tion into the master documentation files. + and on information gleaned from the nethack configuration. This allows + certain changes such as embedding platform-specific documentation into + the master documentation files. Rules: - - The default conditional state is printing enabled. + o The default conditional state is printing enabled. - - Any line NOT starting with a caret (^) is either suppressed - or passed through unchanged depending on the current condi- - tional state. + o Any line NOT starting with a caret (^) is either suppressed or + passed through unchanged depending on the current conditional + state. - - Any line starting with a caret is a control line; as in C, - zero or more spaces may be embedded in the line almost any- - where (except immediately after the caret); however the - caret must be in column 1. + o Any line starting with a caret is a control line; as in C, zero + or more spaces may be embedded in the line almost anywhere + (except immediately after the caret); however the caret must be + in column 1. - - Conditionals may be nested. + o Conditionals may be nested. - - Makedefs will exit with an error code if any errors are - detected; processing will continue (if it can) to allow as - many errors as possible to be detected. + o Makedefs will exit with an error code if any errors are + detected; processing will continue (if it can) to allow as many + errors as possible to be detected. - - Unknown identifiers are treated as both TRUE and as an - error. Note that --undef or #undef in the NetHack(6) con- - figuration are different from unknown. + o Unknown identifiers are treated as both TRUE and as an error. + Note that --undef or #undef in the nethack configuration are + different from unknown. Control lines: - ^^ a line starting with a (single) literal caret + ^^ a line starting with a (single) literal caret - ^# a comment + ^# a comment - ^?ID - if the ID is defined set the conditional state to TRUE + ^?ID if the ID is defined set the conditional state to TRUE - ^!ID - if the ID is not defined set the conditional state to TRUE + ^!ID if the ID is not defined set the conditional state to TRUE - ^: else; invert the conditional state + ^: else; invert the conditional state - ^. end the most recent conditional + ^. end the most recent conditional AUTHOR The NetHack Development Team From b02f28fec2980e19845eec20dfe251486de5e552 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Thu, 7 May 2026 19:43:06 -0400 Subject: [PATCH 214/702] This is cron-daily v1-May-7-2026. 000files updated: Files --- Files | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/Files b/Files index f27c19b60..50d8ecfba 100644 --- a/Files +++ b/Files @@ -7,8 +7,9 @@ from or not transferred to your system if you wish. .: (files in top directory) -.clang-format Cross-compiling Files -Porting README azure-pipelines.yml +.clang-format Contributing.md Cross-compiling +Files Porting README +azure-pipelines.yml DEVEL: (files for people developing changes to NetHack) @@ -76,11 +77,11 @@ fixes3-2-2.txt fixes3-2-3.txt fixes3-3-0.txt fixes3-3-1.txt fixes3-4-0.txt fixes3-4-1.txt fixes3-4-2.txt fixes3-4-3.txt fixes3-5-0.txt fixes3-6-0.txt fixes3-6-1.txt fixes3-6-2.txt fixes3-6-3.txt fixes3-6-4.txt fixes3-6-5.txt fixes3-6-6.txt -fixes3-6-7.txt fixes5-0-0.txt fixesX-X-X.txt lua.adoc -makedefs.6 makedefs.txt mn.7 mn.txt -mnh.7 mnh.txt nethack.6 nethack.txt -options.txt recover.6 recover.txt sound.txt -tmac.n tmac.nh window.txt +fixes3-6-7.txt fixes5-0-0.txt fixes5-0-1.txt fixesX-X-X.txt +lua.adoc makedefs.6 makedefs.txt mn.7 +mn.txt mnh.7 mnh.txt nethack.6 +nethack.txt options.txt recover.6 recover.txt +sound.txt tmac.n tmac.nh window.txt include: (files for X versions) @@ -308,14 +309,15 @@ CHKSUMS lua pdcurses pdcursesmod sys/amiga: (files for Amiga versions) -README.amiga amidos.c amidos.p amifont.uu -amifont8.uu amigst.c amii.hlp amimenu.c -amirip.c amistack.c amitty.c amiwind.c -amiwind.p bmp2iff_host.c clipwin.c colorwin.c -grave16.xpm nethack.cnf winamenu.c winami.c -winami.p winchar.c windefs.h winext.h -winfuncs.c winkey.c winproto.h winreq.c -winstr.c xpm2iff_host.c +NHinfo.uu README.amiga amidos.c amidos.p +amifont.uu amifont8.uu amigst.c amii.hlp +amimenu.c amirip.c amistack.c amitty.c +amiwind.c amiwind.p bmp2iff_host.c clipwin.c +cnf-info.uu colorwin.c drawer-info.uu grave16.xpm +license-info.uu nethack.cnf readme-info.uu txt-info.uu +winamenu.c winami.c winami.p winchar.c +windefs.h winext.h winfuncs.c winkey.c +winproto.h winreq.c winstr.c xpm2iff_host.c sys/libnh: (files in top directory) From 13bbbf6a13d109f90579ff578ab3526f186f699a Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Thu, 7 May 2026 19:43:08 -0400 Subject: [PATCH 215/702] This is cron-daily v1-May-7-2026. 005guidebook updated: doc/Guidebook.txt --- doc/Guidebook.txt | 258 +++++++++++++++++++++++----------------------- 1 file changed, 129 insertions(+), 129 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 456ff45ae..1d85d895d 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -7417,39 +7417,39 @@ as a suitable release, it was decided that the version numbers present on that code snapshot would be retired and never used in an official NetHack release. An announcement was posted on the NetHack Develop- - ment Team's official nethack.org website to that effect, stating that - there would never be a 3.4.4, 3.5, or 3.5.0 official release version. + ment Team's official https://www.nethack.org website to that effect, + stating that there would never be a 3.4.4, 3.5, or 3.5.0 official + release version. - In January 2015, preparation began for the release of NetHack + In January 2015, preparation began for the release of NetHack 3.6. - At the beginning of development for what would eventually get - released as 3.6.0, the NetHack Development Team consisted of Warwick - Allison, Michael Allison, Ken Arromdee, David Cohrs, Jessie Collet, - Ken Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet Walz, and - Paul Winner. In early 2015, ahead of the release of 3.6.0, new mem- - bers Sean Hunt, Pasi Kallinen, and Derek S. Ray joined the NetHack + At the beginning of development for what would eventually get + released as 3.6.0, the NetHack Development Team consisted of Warwick + Allison, Michael Allison, Ken Arromdee, David Cohrs, Jessie Collet, + Ken Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet Walz, and + Paul Winner. In early 2015, ahead of the release of 3.6.0, new mem- + bers Sean Hunt, Pasi Kallinen, and Derek S. Ray joined the NetHack Development Team. - Near the end of the development of 3.6.0, one of the significant - inspirations for many of the humorous and fun features found in the + Near the end of the development of 3.6.0, one of the significant + inspirations for many of the humorous and fun features found in the game, author Terry Pratchett, passed away. NetHack 3.6.0 introduced a tribute to him. - 3.6.0 was released in December 2015, and merged work done by the - development team since the release of 3.4.3 with some of the beloved - community patches. Many bugs were fixed and some code was restruc- + 3.6.0 was released in December 2015, and merged work done by the + development team since the release of 3.4.3 with some of the beloved + community patches. Many bugs were fixed and some code was restruc- tured. - The NetHack Development Team, as well as Steve VanDevender and - Kevin Smolkowski, ensured that NetHack 3.6 continued to operate on + The NetHack Development Team, as well as Steve VanDevender and + Kevin Smolkowski, ensured that NetHack 3.6 continued to operate on various UNIX flavors and maintained the X11 interface. - Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick maintained + Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick maintained the port of NetHack 3.6 for MacOS. - Michael Allison, David Cohrs, Bart House, Pasi Kallinen, Alex - Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir maintained the + NetHack 5.0.0 May 2, 2026 @@ -7462,60 +7462,60 @@ + Michael Allison, David Cohrs, Bart House, Pasi Kallinen, Alex + Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir maintained the port of NetHack 3.6 for Microsoft Windows. - Pat Rankin attempted to keep the VMS port running for NetHack - 3.6, hindered by limited access. Kevin Smolkowski has updated and - tested it for the most recent version of OpenVMS (V8.4 as of this + Pat Rankin attempted to keep the VMS port running for NetHack + 3.6, hindered by limited access. Kevin Smolkowski has updated and + tested it for the most recent version of OpenVMS (V8.4 as of this writing) on Alpha and Integrity (aka Itanium aka IA64) but not VAX. - Ray Chason resurrected the MS-DOS port for 3.6 and contributed + Ray Chason resurrected the MS-DOS port for 3.6 and contributed the necessary updates to the community at large. - In late April 2018, several hundred bug fixes for 3.6.0 and some - new features were assembled and released as NetHack 3.6.1. The - NetHack Development Team at the time of release of 3.6.1 consisted of - Warwick Allison, Michael Allison, Ken Arromdee, David Cohrs, Jessie - Collet, Pasi Kallinen, Ken Lorber, Dean Luick, Patric Mueller, Pat - Rankin, Derek S. Ray, Alex Smith, Mike Stephenson, Janet Walz, and + In late April 2018, several hundred bug fixes for 3.6.0 and some + new features were assembled and released as NetHack 3.6.1. The + NetHack Development Team at the time of release of 3.6.1 consisted of + Warwick Allison, Michael Allison, Ken Arromdee, David Cohrs, Jessie + Collet, Pasi Kallinen, Ken Lorber, Dean Luick, Patric Mueller, Pat + Rankin, Derek S. Ray, Alex Smith, Mike Stephenson, Janet Walz, and Paul Winner. In early May 2019, another 320 bug fixes along with some enhance- ments and the adopted curses window port, were released as 3.6.2. - Bart House, who had contributed to the game as a porting team - participant for decades, joined the NetHack Development Team in late + Bart House, who had contributed to the game as a porting team + participant for decades, joined the NetHack Development Team in late May 2019. - NetHack 3.6.3 was released on December 5, 2019 containing over + NetHack 3.6.3 was released on December 5, 2019 containing over 190 bug fixes to NetHack 3.6.2. - NetHack 3.6.4 was released on December 18, 2019 containing a + NetHack 3.6.4 was released on December 18, 2019 containing a security fix and a few bug fixes. - NetHack 3.6.5 was released on January 27, 2020 containing some + NetHack 3.6.5 was released on January 27, 2020 containing some security fixes and a small number of bug fixes. NetHack 3.6.6 was released on March 8, 2020 containing a security fix and some bug fixes. - NetHack 3.6.7 was released on February 16, 2023 containing a + NetHack 3.6.7 was released on February 16, 2023 containing a security fix and some bug fixes. - Development work for the major release to follow NetHack 3.6 - began in 2015 around the same time as NetHack 3.6.0 was being - released. That development work continued in parallel to each of the - NetHack 3.6 releases from 2015 through 2023, and continued until the - end of April 2026. For the first time, that development was shared - publicly on GitHub and SourceForge as it occurred. It was done under - the label NetHack-3.7 work-in-progress (WIP), although the version + Development work for the major release to follow NetHack 3.6 + began in 2015 around the same time as NetHack 3.6.0 was being + released. That development work continued in parallel to each of the + NetHack 3.6 releases from 2015 through 2023, and continued until the + end of April 2026. For the first time, that development was shared + publicly on GitHub and SourceForge as it occurred. It was done under + the label NetHack-3.7 work-in-progress (WIP), although the version number for the next release had not yet been solidified. - Exposure of the development to the public brought many good + Exposure of the development to the public brought many good things, and some challenges. People were able to observe and criticize - changes and new features almost immediately, and they often did. The - GitHub pull request system made it straightforward for people to con- - tribute directly to development. Contributions resolved many, many + changes and new features almost immediately, and they often did. The NetHack 5.0.0 May 2, 2026 @@ -7528,60 +7528,60 @@ + GitHub pull request system made it straightforward for people to con- + tribute directly to development. Contributions resolved many, many bugs in the game and we thank all the contributors. In early 2026, with the game development getting stable enough to - consider initiating an official release, the devteam reviewed the - nature and number of changes in the game. It was clear that there was - sufficient depth and breadth to warrant a major release and version - 5.0 was decided on. That's a new major release over 3.x, without - opening up any ambiguity or confusion with existing variants that + consider initiating an official release, the devteam reviewed the + nature and number of changes in the game. It was clear that there was + sufficient depth and breadth to warrant a major release and version + 5.0 was decided on. That's a new major release over 3.x, without + opening up any ambiguity or confusion with existing variants that there might have been had it been released as version 4.0. NetHack 5.0.0 was released on May 2, 2026. - The source code for NetHack 5.0.0 was modified and modernized to - be compliant with the C99 standard. The 5.0.0 release contained over + The source code for NetHack 5.0.0 was modified and modernized to + be compliant with the C99 standard. The 5.0.0 release contained over 3100 fixes, changes, and updated features. - NetHack 5.0 was the first version to replace the lex and yacc - level and dungeon compilers of past versions, with a new Lua inter- - preter-based approach to provide those elements. Lua is also used for + NetHack 5.0 was the first version to replace the lex and yacc + level and dungeon compilers of past versions, with a new Lua inter- + preter-based approach to provide those elements. Lua is also used for the quest texts in NetHack 5.0.0. The entire development team acknowl- edges the work done by Pasi Kallinen to make that happen. - At the time of the NetHack 5.0 release, the core development + At the time of the NetHack 5.0 release, the core development team, active and erstwhile, included Warwick Allison, Michael Allison, Ken Arromdee, David Cohrs, Jessie Collet, Bart House, Kevin Hugo, Pasi - Kallinen, Ken Lorber, Dean Luick, Pat Rankin, Derek S. Ray, Alex + Kallinen, Ken Lorber, Dean Luick, Pat Rankin, Derek S. Ray, Alex Smith, Patric Mueller, Mike Stephenson, Janet Walz, Paul Winner. - Ken Lorber, Pat Rankin, Patrick Mueller and Michael Allison + Ken Lorber, Pat Rankin, Patrick Mueller and Michael Allison helped ensure that NetHack 5.0 would run on macOS. Ingo Paschke somehow managed to revive a NetHack 5.0 port for the - Amiga, using a cross-compiler on a modern platform to do so. His work + Amiga, using a cross-compiler on a modern platform to do so. His work was shared so others can straightforwardly produce NetHack 5.0 for the Amiga thanks to his efforts. - Ray Chason contributed the majority of maintenance work for the + Ray Chason contributed the majority of maintenance work for the NetHack 5.0 MS-DOS port, including porting the curses interface to it. - Michael Allison ensured that NetHack 5.0 core changes continued to - work with the msdos port and keep it alive. Cross-compiling the MS- + Michael Allison ensured that NetHack 5.0 core changes continued to + work with the msdos port and keep it alive. Cross-compiling the MS- DOS port has helped make that possible and mostly painless. - People that contributed to the Windows port of NetHack 5.0 since - the development of NetHack 5.0 begain over eleven years ago, included - Michael Allison, David Cohrs, Bart House, Pasi Kallinen, Alex Kompel, + People that contributed to the Windows port of NetHack 5.0 since + the development of NetHack 5.0 began over eleven years ago, included + Michael Allison, David Cohrs, Bart House, Pasi Kallinen, Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir. - With sadness, the devteam would like to acknowledge and remember - the past contributions from the late Ron Van Iwaarden, who was the + With sadness, the devteam would like to acknowledge and remember + the past contributions from the late Ron Van Iwaarden, who was the sole maintainer of NetHack for OS/2 for several past NetHack releases. Ron will be missed. - The official NetHack web site is maintained by Ken Lorber at - https://www.nethack.org/. NetHack 5.0.0 May 2, 2026 @@ -7591,65 +7591,65 @@ NetHack Guidebook 116 + + + + The official NetHack web site is maintained by Ken Lorber at + https://www.nethack.org/. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12.1. Special Thanks - On behalf of the NetHack community, thank you very much once - again to M. Drew Streib and Pasi Kallinen for providing a public - NetHack server at nethack.alt.org. Thanks to Keith Simpson and Andy - Thomson for hardfought.org. Thanks to all those unnamed dungeoneers - who invest their time and effort into annual NetHack tournaments such - as Junethack, The November NetHack Tournament, and in days past, + On behalf of the NetHack community, thank you very much once + again to M. Drew Streib and Pasi Kallinen for providing a public + NetHack server at nethack.alt.org. Thanks to Keith Simpson and Andy + Thomson for hardfought.org. Thanks to all those unnamed dungeoneers + who invest their time and effort into annual NetHack tournaments such + as Junethack, The November NetHack Tournament, and in days past, devnull.net (gone for now, but not forgotten). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 12.2. Dungeoneers - - From time to time, some depraved individual out there in netland - sends a particularly intriguing modification to help out with the - - NetHack 5.0.0 May 2, 2026 @@ -7660,7 +7660,11 @@ - game. The NetHack Development Team sometimes makes note of the names + 12.2. Dungeoneers + + From time to time, some depraved individual out there in netland + sends a particularly intriguing modification to help out with the + game. The NetHack Development Team sometimes makes note of the names of the worst of these miscreants in this, the list of Dungeoneers: @@ -7709,10 +7713,6 @@ Andy Church Janne Salmijarvi Nathan Eady Andy Swanson Jean-Christophe Collet Norm Meluch Andy Thomson Jeff Bailey Olaf Seibert - Ari Huttunen Jochen Erwied Pasi Kallinen - Bart House John Kallen Pat Rankin - Benson I. Margulies John Rupley Patric Mueller - Bill Dyer John S. Bien Paul Winner @@ -7726,6 +7726,10 @@ + Ari Huttunen Jochen Erwied Pasi Kallinen + Bart House John Kallen Pat Rankin + Benson I. Margulies John Rupley Patric Mueller + Bill Dyer John S. Bien Paul Winner Boudewijn Waijers Johnny Lee Pierre Martineau Bruce Cox Jon W{tte Ralf Brown Bruce Holloway Jonathan Handler Ray Chason @@ -7774,10 +7778,6 @@ - - - - @@ -7792,7 +7792,7 @@ - Brand and product names are trademarks or registered trademarks + Brand and product names are trademarks or registered trademarks of their respective holders. From c1ae9d5d8c65fdb475850ce50b36e3267d536627 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Sat, 9 May 2026 17:07:09 +0200 Subject: [PATCH 216/702] Amiga: restore glyph icons in menus Core changes routed transient inventory away from WIN_INVEN, so the port's win == WIN_INVEN gate stopped matching and glyphs vanished. Track has_glyphs on the menu and key rendering and sizing off that. --- include/winami.h | 1 + sys/amiga/winamenu.c | 109 ++++++++++++++++--------------------------- sys/amiga/winfuncs.c | 17 +++---- 3 files changed, 46 insertions(+), 81 deletions(-) diff --git a/include/winami.h b/include/winami.h index 525f53d6d..686d37f91 100644 --- a/include/winami.h +++ b/include/winami.h @@ -32,6 +32,7 @@ struct amii_menu { const char *query; /* Query string */ int count; /* Number of strings. */ char chr; /* Character to assign for accelerator */ + boolean has_glyphs; /* Any item carries a real glyph (AMIV) */ }; /* descriptor for Amiga Intuition-based windows. If we decide to cope with diff --git a/sys/amiga/winamenu.c b/sys/amiga/winamenu.c index d391bdec4..9cc2a0fb3 100644 --- a/sys/amiga/winamenu.c +++ b/sys/amiga/winamenu.c @@ -47,6 +47,7 @@ amii_start_menu(winid window, unsigned long mbehavior UNUSED) cw->menu.items = 0; cw->menu.count = 0; cw->menu.chr = 'a'; + cw->menu.has_glyphs = FALSE; if (cw->morestr) free(cw->morestr); @@ -85,6 +86,8 @@ amii_add_menu(winid window, const glyph_info *glyphinfo, const anything *id, mip->attr = attr; mip->color = clr; mip->glyph = Is_rogue_level(&u.uz) ? NO_GLYPH : (glyphinfo ? glyphinfo->glyph : NO_GLYPH); + if (mip->glyph != NO_GLYPH) + cw->menu.has_glyphs = TRUE; mip->selector = 0; mip->gselector = gch; mip->count = -1; @@ -255,12 +258,9 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) /* Initial guess at window sizing values */ txwd = txwidth; - if (WINVERS_AMIV) { - if (win == WIN_INVEN) - txh = max(txheight, pictdata.ysize + 3); /* interline space */ - else - txh = txheight; /* interline space */ - } else + if (WINVERS_AMIV && cw->menu.has_glyphs) + txh = max(txheight, pictdata.ysize + 3); /* interline space */ + else txh = txheight; /* interline space */ /* Check to see if we should open the window, should need to for @@ -280,10 +280,8 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) if (!alwaysinvent || win != WIN_INVEN) { xsize = scrn->WBorLeft + scrn->WBorRight + MenuScroll.Width + 1 + (txwd * cw->maxcol); - if (WINVERS_AMIV) { - if (win == WIN_INVEN) - xsize += pictdata.xsize + 4; - } + if (WINVERS_AMIV && cw->menu.has_glyphs) + xsize += pictdata.xsize + 4; if (xsize > amiIDisplay->xpix) xsize = amiIDisplay->xpix; @@ -322,7 +320,7 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) /* Make space for the glyph to appear at the left of the * description */ - if (WINVERS_AMIV) + if (WINVERS_AMIV && cw->menu.has_glyphs) xsize += pictdata.xsize + 4; if (xsize > amiIDisplay->xpix) @@ -394,52 +392,36 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) SetFont(w->RPort, HackFont); #endif txwd = w->RPort->TxWidth; - if (WINVERS_AMIV) { - if (win == WIN_INVEN) - txh = max(w->RPort->TxHeight, - pictdata.ysize + 3); /* interline space */ - else - txh = w->RPort->TxHeight; /* interline space */ - } else + if (WINVERS_AMIV && cw->menu.has_glyphs) + txh = max(w->RPort->TxHeight, + pictdata.ysize + 3); /* interline space */ + else txh = w->RPort->TxHeight; /* interline space */ /* subtract 2 to account for spacing away from border (1 on each side) */ wheight = (w->Height - w->BorderTop - w->BorderBottom - 2) / txh; - if (WINVERS_AMIV) { - if (win == WIN_INVEN) { - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 - - pictdata.xsize - 3) / txwd; - } else { - cw->cols = - (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; - } + if (WINVERS_AMIV && cw->menu.has_glyphs) { + cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 + - pictdata.xsize - 3) / txwd; } else { cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; } totalvis = CountLines(win); } else { txwd = w->RPort->TxWidth; - if (WINVERS_AMIV) { - if (win == WIN_INVEN) - txh = max(w->RPort->TxHeight, - pictdata.ysize + 3); /* interline space */ - else - txh = w->RPort->TxHeight; /* interline space */ - } else { + if (WINVERS_AMIV && cw->menu.has_glyphs) + txh = max(w->RPort->TxHeight, + pictdata.ysize + 3); /* interline space */ + else txh = w->RPort->TxHeight; /* interline space */ - } /* subtract 2 to account for spacing away from border (1 on each side) */ wheight = (w->Height - w->BorderTop - w->BorderBottom - 2) / txh; - if (WINVERS_AMIV) { - if (win == WIN_INVEN) { - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 - - pictdata.xsize - 3) / txwd; - } else - cw->cols = - (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; + if (WINVERS_AMIV && cw->menu.has_glyphs) { + cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 + - pictdata.xsize - 3) / txwd; } else { cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; } @@ -551,13 +533,9 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) totalvis = CountLines(win); wheight = (w->Height - w->BorderTop - w->BorderBottom - 2) / txh; - if (WINVERS_AMIV) { - if (win == WIN_INVEN) { - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - - 4 - pictdata.xsize - 3) / txwd; - } else - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - - 4) / txwd; + if (WINVERS_AMIV && cw->menu.has_glyphs) { + cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 + - pictdata.xsize - 3) / txwd; } else { cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; @@ -1126,12 +1104,9 @@ FindLine(winid win, int line) panic(winpanicstr, win, "No Window in FindLine"); } txwd = w->RPort->TxWidth; - if (WINVERS_AMIV) { - if (win == WIN_INVEN) { - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 - - pictdata.xsize - 3) / txwd; - } else - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; + if (WINVERS_AMIV && cw->menu.has_glyphs) { + cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 + - pictdata.xsize - 3) / txwd; } else { cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; } @@ -1189,12 +1164,9 @@ CountLines(winid win) } txwd = w->RPort->TxWidth; - if (WINVERS_AMIV) { - if (win == WIN_INVEN) { - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 - - pictdata.xsize - 3) / txwd; - } else - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; + if (WINVERS_AMIV && cw->menu.has_glyphs) { + cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 + - pictdata.xsize - 3) / txwd; } else { cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; } @@ -1255,7 +1227,7 @@ DisplayData(winid win, int start) rp = w->RPort; SetDrMd(rp, JAM2); - if (WINVERS_AMIV && win == WIN_INVEN) { + if (WINVERS_AMIV && cw->menu.has_glyphs) { wheight = (w->Height - w->BorderTop - w->BorderBottom - 2) / max(rp->TxHeight, pictdata.ysize + 3); } else { @@ -1265,12 +1237,9 @@ DisplayData(winid win, int start) cw->rows = wheight; txwd = rp->TxWidth; - if (WINVERS_AMIV) { - if (win == WIN_INVEN) { - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 - - pictdata.xsize - 3) / txwd; - } else - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; + if (WINVERS_AMIV && cw->menu.has_glyphs) { + cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 + - pictdata.xsize - 3) / txwd; } else { cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; } @@ -1292,7 +1261,7 @@ DisplayData(winid win, int start) for (disprow = i = start; disprow < wheight + start; i++) { /* Just erase unused lines in the window */ if (i >= cw->maxrow) { - if (WINVERS_AMIV && win == WIN_INVEN) { + if (WINVERS_AMIV && cw->menu.has_glyphs) { amii_curs(win, 0, disprow - start); amiga_print_glyph(win, 0, NO_GLYPH); } @@ -1312,7 +1281,7 @@ DisplayData(winid win, int start) * current line */ if (cw->type != NHW_MESSAGE || cw->data[i][SEL_ITEM] >= 0) { amii_curs(win, 1, disprow - start); - if (WINVERS_AMIV && win == WIN_INVEN) { + if (WINVERS_AMIV && cw->menu.has_glyphs) { if (mip) amiga_print_glyph(win, 0, mip->glyph); amii_curs(win, 1, disprow - start); @@ -1389,7 +1358,7 @@ DisplayData(winid win, int start) while (*t == ' ') ++t; amii_curs(win, 1, disprow - start - 1); - if (mip && win == WIN_INVEN && WINVERS_AMIV) { + if (mip && WINVERS_AMIV && cw->menu.has_glyphs) { /* Erase any previous glyph drawn here. */ amiga_print_glyph(win, 0, NO_GLYPH); amii_curs(win, 1, disprow - start - 1); diff --git a/sys/amiga/winfuncs.c b/sys/amiga/winfuncs.c index ba7835775..db32e2e8b 100644 --- a/sys/amiga/winfuncs.c +++ b/sys/amiga/winfuncs.c @@ -1695,17 +1695,12 @@ amii_curs(winid window, int x, int y) rp = w->RPort; if (cw->type == NHW_MENU) { - if (WINVERS_AMIV) { - if (window == WIN_INVEN) { - Move(rp, (x * rp->TxWidth) + w->BorderLeft + 1 - + pictdata.xsize + 4, - (y * max(rp->TxHeight, pictdata.ysize + 3)) - + rp->TxBaseline + pictdata.ysize - rp->TxHeight - + w->BorderTop + 4); - } else { - Move(rp, (x * rp->TxWidth) + w->BorderLeft + 1, - (y * rp->TxHeight) + rp->TxBaseline + w->BorderTop + 1); - } + if (WINVERS_AMIV && cw->menu.has_glyphs) { + Move(rp, (x * rp->TxWidth) + w->BorderLeft + 1 + + pictdata.xsize + 4, + (y * max(rp->TxHeight, pictdata.ysize + 3)) + + rp->TxBaseline + pictdata.ysize - rp->TxHeight + + w->BorderTop + 4); } else { Move(rp, (x * rp->TxWidth) + w->BorderLeft + 1, (y * rp->TxHeight) + rp->TxBaseline + w->BorderTop + 1); From edafe39f5dce855b58173597bcd302410b71430e Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 10 May 2026 09:07:10 -0400 Subject: [PATCH 217/702] add awareness of possible updated binary with numeric suffix Close #1514 --- sys/amiga/README.amiga | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/amiga/README.amiga b/sys/amiga/README.amiga index 436a4aea4..907dd579b 100644 --- a/sys/amiga/README.amiga +++ b/sys/amiga/README.amiga @@ -13,8 +13,9 @@ tile rendering. Native AGA/OCS/ECS chipsets are supported. Installation ------------ -Extract NH500AMI.ZIP somewhere on your hard drive (e.g. into Work:). -You'll get a NetHack drawer with everything inside. +Extract NH500AMI.ZIP (or NH500AMIn.ZIP if there's a an updated +binary, where 'n' is a digit suffix) somewhere on your hard drive +(e.g. into Work:). You'll get a NetHack drawer with everything inside. To play from Workbench, open the NetHack drawer and double-click the nethack icon. From f64b99689973c43a261b0b38ffeb9b0ba9a59412 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 10 May 2026 10:33:20 -0400 Subject: [PATCH 218/702] optional package sequencer for building binary Add Makefile support for an optional AMIGPKGSEQ to append a suffix to the Amiga binary, without having to rename the zip file manually after the make CROSS_TO_AMIGA=1 package step. --- sys/unix/hints/include/cross-post.500 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/unix/hints/include/cross-post.500 b/sys/unix/hints/include/cross-post.500 index 512906d8f..73ba215d7 100644 --- a/sys/unix/hints/include/cross-post.500 +++ b/sys/unix/hints/include/cross-post.500 @@ -330,8 +330,8 @@ amigapkg: $(AMITILES) ../util/uudecode ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/readme-info.uu ) ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/drawer-info.uu ) touch $(TARGETPFX)pkg/NetHack/record - ( cd $(TARGETPFX)pkg && zip -9r ../NH$(NHV)AMI.ZIP NetHack NetHack.info ) - @echo amiga package zip file $(TARGETPFX)NH$(NHV)AMI.ZIP + ( cd $(TARGETPFX)pkg && zip -9r ../NH$(NHV)AMI$(AMIPKGSEQ).ZIP NetHack NetHack.info ) + @echo amiga package zip file $(TARGETPFX)NH$(NHV)AMI$(AMIPKGSEQ).ZIP endif # CROSS_TO_AMIGA ifdef CROSS_SHARED From aa6361611842198771f84178e141f78f1b284a17 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 10 May 2026 11:36:43 -0400 Subject: [PATCH 219/702] spelling correction --- sys/amiga/amistack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/amiga/amistack.c b/sys/amiga/amistack.c index 84ae496e1..690bea07c 100644 --- a/sys/amiga/amistack.c +++ b/sys/amiga/amistack.c @@ -1,5 +1,5 @@ /* NetHack 3.6 amistack.c $NHDT-Date: 1432512795 2015/05/25 00:13:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ -/* Copyright (c) Janne Salmij�rvi, Tampere, Finland, 2000 */ +/* Copyright (c) Janne Salmijärvi, Tampere, Finland, 2000 */ /* NetHack may be freely redistributed. See license for details. */ /* From 5cf9086c840f97002b83d6030bee10b3d7aa01ae Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 10 May 2026 12:10:26 -0400 Subject: [PATCH 220/702] Windows: don't demand keypress on intentional exit --- sys/windows/windsys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/windows/windsys.c b/sys/windows/windsys.c index 3dad0d330..f7c2e3d55 100644 --- a/sys/windows/windsys.c +++ b/sys/windows/windsys.c @@ -518,7 +518,7 @@ nethack_exit(int code) * GUILaunched is defined and set in consoletty.c. */ - if (getreturn_enabled) { + if (getreturn_enabled && !program_state.exiting) { raw_print("\n"); if (iflags.window_inited) wait_synch(); From 9d5b02d912dfddb61623187329fa1586c55a5d99 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 10 May 2026 14:43:26 -0400 Subject: [PATCH 221/702] NetHack 5.0.0 packaging error from visual studio A remnant hard-coded 370 was in package.nmake. Note: The errant file was not used to construct the official binaries. Those were done using sys/windows/Makefile.nmake. Closes #1525 --- sys/windows/vs/package/package.nmake | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sys/windows/vs/package/package.nmake b/sys/windows/vs/package/package.nmake index 9842b20c1..31855f752 100644 --- a/sys/windows/vs/package/package.nmake +++ b/sys/windows/vs/package/package.nmake @@ -65,12 +65,13 @@ default: packageall # packaging #=============================================================================== +NHDATFILEBASE=nhdat$(NHV) PKGFILES=Guidebook.txt license NetHack.exe NetHack.txt \ - NetHackW.exe opthelp nhdat370 record symbols.template sysconf.template \ - nethackrc.template + NetHackW.exe opthelp $(NHDATFILEBASE) record symbols.template \ + sysconf.template nethackrc.template FILESTOZIP=$(VSBINDIR)\Guidebook.txt $(VSBINDIR)\license \ $(VSBINDIR)\NetHack.exe $(VSBINDIR)\NetHack.txt $(VSBINDIR)\NetHackW.exe \ - $(VSBINDIR)\opthelp $(VSBINDIR)\nhdat370 $(VSBINDIR)\record \ + $(VSBINDIR)\opthelp $(VSBINDIR)\$(NHDATFILEBASE) $(VSBINDIR)\record \ $(VSBINDIR)\symbols.template $(VSBINDIR)\sysconf.template $(VSBINDIR)\nethackrc.template DBGSYMS = NetHack.PDB NetHackW.PDB PDBTOZIP = ..\NetHack\symbols\$(Configuration)\$(Platform)\NetHack.PDB \ From 745c7fb8d88df39e4902fa60aa7add30f2e0bf4e Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 10 May 2026 16:00:33 -0400 Subject: [PATCH 222/702] some windows fixes Resolves #1526 --- include/extern.h | 4 ++ src/cfgfiles.c | 112 ++++++++++++++++++++++++++++------------- sys/windows/windmain.c | 7 ++- win/win32/mhmain.c | 21 ++++++++ win/win32/mswproc.c | 3 +- 5 files changed, 111 insertions(+), 36 deletions(-) diff --git a/include/extern.h b/include/extern.h index accecff22..03e364612 100644 --- a/include/extern.h +++ b/include/extern.h @@ -347,6 +347,10 @@ extern void disregard_this_config_statement(int); extern boolean config_unmatched_ignored(void); extern void clear_ignore_errors_on_unmatched(void); extern void set_ignore_errors_on_unmatched(void); +#ifdef MSWIN_GRAPHICS +extern void disregard_some_mswin_options(void); +extern void rcfile_only_some_mswin_options(void); +#endif /* ### coloratt.c ### */ diff --git a/src/cfgfiles.c b/src/cfgfiles.c index e2ef65937..4fe3f5da3 100644 --- a/src/cfgfiles.c +++ b/src/cfgfiles.c @@ -1956,40 +1956,6 @@ rcfile(void) /*[end of nethackrc handling]*/ } -void -rcfile_interface_options(void) -{ - allopt_array_init(); - disregard_all_options(); - disregard_all_config_statements(); - heed_this_option(opt_windowtype); - heed_this_option(opt_soundlib); - set_ignore_errors_on_unmatched(); - ignore_statement_errors = TRUE; - rcfile(); - heed_all_config_statements(); - heed_all_options(); - disregard_this_option(opt_windowtype); - disregard_this_option(opt_soundlib); - clear_ignore_errors_on_unmatched(); - ignore_statement_errors = FALSE; -} - -void -rcfile_only_this_option(enum opt heeded_option) -{ - allopt_array_init(); - disregard_all_options(); - disregard_all_config_statements(); - heed_this_option(heeded_option); - set_ignore_errors_on_unmatched(); - ignore_statement_errors = TRUE; - rcfile(); - heed_all_config_statements(); - heed_all_options(); - clear_ignore_errors_on_unmatched(); - ignore_statement_errors = FALSE; -} void heed_all_config_statements(void) @@ -2039,6 +2005,84 @@ config_unmatched_ignored(void) return TRUE; return FALSE; } +void +rcfile_interface_options(void) +{ + allopt_array_init(); + disregard_all_options(); + disregard_all_config_statements(); + heed_this_option(opt_windowtype); + heed_this_option(opt_soundlib); + set_ignore_errors_on_unmatched(); + ignore_statement_errors = TRUE; + rcfile(); + heed_all_config_statements(); + heed_all_options(); + disregard_this_option(opt_windowtype); + disregard_this_option(opt_soundlib); + clear_ignore_errors_on_unmatched(); + ignore_statement_errors = FALSE; +} + +void +rcfile_only_this_option(enum opt heeded_option) +{ + allopt_array_init(); + disregard_all_options(); + disregard_all_config_statements(); + heed_this_option(heeded_option); + set_ignore_errors_on_unmatched(); + ignore_statement_errors = TRUE; + rcfile(); + heed_all_config_statements(); + heed_all_options(); + clear_ignore_errors_on_unmatched(); + ignore_statement_errors = FALSE; +} + +#ifdef MSWIN_GRAPHICS +void +disregard_some_mswin_options(void) +{ + /* later for these */ + disregard_this_option(opt_map_mode); + disregard_this_option(opt_font_map); + disregard_this_option(opt_font_menu); + disregard_this_option(opt_font_message); + disregard_this_option(opt_font_status); + + disregard_this_option(opt_font_size_map); + disregard_this_option(opt_font_size_menu); + disregard_this_option(opt_font_size_message); + disregard_this_option(opt_font_size_status); +} + +void +rcfile_only_some_mswin_options(void) +{ + allopt_array_init(); + disregard_all_options(); + disregard_all_config_statements(); + heed_this_option(opt_map_mode); + heed_this_option(opt_font_map); + heed_this_option(opt_font_menu); + heed_this_option(opt_font_message); + heed_this_option(opt_font_status); + + heed_this_option(opt_font_size_map); + heed_this_option(opt_font_size_menu); + heed_this_option(opt_font_size_message); + heed_this_option(opt_font_size_status); + set_ignore_errors_on_unmatched(); + ignore_statement_errors = TRUE; + rcfile(); + heed_all_config_statements(); + heed_all_options(); + clear_ignore_errors_on_unmatched(); + ignore_statement_errors = FALSE; +} +#endif /* MSWIN_GRAPHICS */ + #endif /* SFCTOOL */ #ifdef SYSCF diff --git a/sys/windows/windmain.c b/sys/windows/windmain.c index 2ff0258f3..e384031b1 100644 --- a/sys/windows/windmain.c +++ b/sys/windows/windmain.c @@ -260,6 +260,9 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ early_options(&argc, &argv, &dir); program_state.early_options = 0; +#ifdef MSWIN_GRAPHICS + disregard_some_mswin_options(); +#endif initoptions(); #if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS) chdir(gf.fqn_prefix[HACKPREFIX]); @@ -325,7 +328,9 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ #elif defined(SND_LIB_WINDSOUND) assign_soundlib(soundlib_windsound); #endif - +#ifdef MSWIN_GRAPHICS + rcfile_only_some_mswin_options(); +#endif u.uhp = 1; /* prevent RIP on early quits */ u.ux = 0; /* prevent flush_screen() */ diff --git a/win/win32/mhmain.c b/win/win32/mhmain.c index 94f2249bc..61fde2aac 100644 --- a/win/win32/mhmain.c +++ b/win/win32/mhmain.c @@ -1193,6 +1193,11 @@ mswin_select_map_mode(int mode) data = (PNHMainWindow) GetWindowLongPtr(GetNHApp()->hMainWnd, GWLP_USERDATA); + if (!data) { + impossible("data is null in %s:%d", __func__, __LINE__); + return; + } + /* override for Rogue level */ if (Is_rogue_level(&u.uz) && !IS_MAP_ASCII(mode)) return; @@ -1268,6 +1273,22 @@ mapmode2menuid(int map_mode) return -1; } + +void +only_some_mswin_options(void) +{ + disregard_this_option(opt_map_mode); /* later */ + disregard_this_option(opt_font_map); + disregard_this_option(opt_font_menu); + disregard_this_option(opt_font_message); + disregard_this_option(opt_font_status); + + disregard_this_option(opt_font_size_map); + disregard_this_option(opt_font_size_menu); + disregard_this_option(opt_font_size_message); + disregard_this_option(opt_font_size_status); +} + void nhlock_windows(BOOL lock) { diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index 8a46c375b..de996828d 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -883,7 +883,8 @@ mswin_display_nhwindow(winid wid, boolean block) } else { if ((GetNHApp()->windowlist[wid].type == NHW_MAP) || (GetNHApp()->windowlist[wid].type == NHW_MESSAGE)) { - (void) mswin_nhgetch(); + if (!program_state.savefile_completed) + (void) mswin_nhgetch(); } } } From 2337a2bae53dfc83e713aa6eca735c1d61e79560 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 10 May 2026 16:04:09 -0400 Subject: [PATCH 223/702] Windows follow-up Remove some unused temporary code --- win/win32/mhmain.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/win/win32/mhmain.c b/win/win32/mhmain.c index 61fde2aac..30eccbc31 100644 --- a/win/win32/mhmain.c +++ b/win/win32/mhmain.c @@ -1273,22 +1273,6 @@ mapmode2menuid(int map_mode) return -1; } - -void -only_some_mswin_options(void) -{ - disregard_this_option(opt_map_mode); /* later */ - disregard_this_option(opt_font_map); - disregard_this_option(opt_font_menu); - disregard_this_option(opt_font_message); - disregard_this_option(opt_font_status); - - disregard_this_option(opt_font_size_map); - disregard_this_option(opt_font_size_menu); - disregard_this_option(opt_font_size_message); - disregard_this_option(opt_font_size_status); -} - void nhlock_windows(BOOL lock) { From 610bd839eec680da4c33f037094b12f05523f4c8 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 10 May 2026 21:11:17 -0400 Subject: [PATCH 224/702] update the code for portable Windows configuration Restrict which options in sysconf will be processed when seeking PORTABLE_DEVICE_PATHS. --- include/extern.h | 4 ++ src/cfgfiles.c | 83 +++++++++++++++++++++++++++++++++++++++++- sys/windows/windmain.c | 30 +++++++++------ sys/windows/windsys.c | 61 +++---------------------------- 4 files changed, 110 insertions(+), 68 deletions(-) diff --git a/include/extern.h b/include/extern.h index 03e364612..cf8d85a08 100644 --- a/include/extern.h +++ b/include/extern.h @@ -347,6 +347,10 @@ extern void disregard_this_config_statement(int); extern boolean config_unmatched_ignored(void); extern void clear_ignore_errors_on_unmatched(void); extern void set_ignore_errors_on_unmatched(void); +extern void rcfile_only_this_statement(int); +#ifdef WIN32 +extern boolean check_for_portable_config(void); +#endif #ifdef MSWIN_GRAPHICS extern void disregard_some_mswin_options(void); extern void rcfile_only_some_mswin_options(void); diff --git a/src/cfgfiles.c b/src/cfgfiles.c index 4fe3f5da3..4e410c880 100644 --- a/src/cfgfiles.c +++ b/src/cfgfiles.c @@ -35,6 +35,9 @@ staticfn char *is_config_section(char *); staticfn boolean handle_config_section(char *); boolean parse_config_line(char *); staticfn char *find_optparam(char *); +#ifdef WIN32 +staticfn boolean portable_sysconf_only_this_statement(int); +#endif #ifndef SFCTOOL staticfn boolean cnf_line_OPTIONS(char *); staticfn boolean cnf_line_AUTOPICKUP_EXCEPTION(char *); @@ -108,7 +111,7 @@ staticfn void cnf_parser_init(struct _cnf_parser_state *parser); staticfn void cnf_parser_done(struct _cnf_parser_state *parser); staticfn void parse_conf_buf(struct _cnf_parser_state *parser, boolean (*proc)(char *arg)); -/* next one is in extern.h; why here too? */ + /* next one is in extern.h; why here too? */ boolean parse_conf_str(const char *str, boolean (*proc)(char *arg)); static boolean ignore_errors_on_unmatched = FALSE, ignore_statement_errors = FALSE; @@ -2040,6 +2043,84 @@ rcfile_only_this_option(enum opt heeded_option) ignore_statement_errors = FALSE; } +void +rcfile_only_this_statement(int statementid) +{ + allopt_array_init(); + disregard_all_options(); + disregard_all_config_statements(); + heed_this_config_statement(statementid); + set_ignore_errors_on_unmatched(); + ignore_statement_errors = TRUE; + rcfile(); + heed_all_config_statements(); + heed_all_options(); + clear_ignore_errors_on_unmatched(); + ignore_statement_errors = FALSE; +} + +#ifdef WIN32 +extern char portable_device_path[_MAX_PATH]; /* windsys.c */ +extern boolean portable; + +staticfn boolean +portable_sysconf_only_this_statement(int statementid) +{ + const char *exepath; + char portable_sysconf[_MAX_PATH]; + + exepath = windows_exepath(); + if (exepath) { + Snprintf(portable_sysconf, sizeof portable_sysconf, "%s/sysconf", + exepath); + if (portable_sysconf[0] && file_exists(portable_sysconf)) { +#ifdef SYSCF +#ifdef SYSCF_FILE + allopt_array_init(); + disregard_all_options(); + disregard_all_config_statements(); + heed_this_config_statement(statementid); + set_ignore_errors_on_unmatched(); + ignore_statement_errors = TRUE; + + config_error_init(TRUE, portable_sysconf, FALSE); + go.opt_phase = syscf_opt; + (void) read_config_file(portable_sysconf, set_in_sysconf); + config_error_done(); + heed_all_config_statements(); + heed_all_options(); + clear_ignore_errors_on_unmatched(); + ignore_statement_errors = FALSE; + if (sysopt.portable_device_paths) { + Snprintf(portable_device_path, sizeof portable_device_path, + "%s\\", exepath); + return TRUE; + } +#endif +#endif /* SYSCF */ + } + } + return FALSE; +} + +boolean +check_for_portable_config(void) +{ + int i, target_index = -1; + + for (i = 0; i < SIZE(config_line_stmt); i++) { + if (!strcmp(config_line_stmt[i].name, "PORTABLE_DEVICE_PATHS")) { + target_index = i; + break; + } + } + if (target_index >= 0) { + return portable_sysconf_only_this_statement(target_index); + } + return FALSE; +} +#endif + #ifdef MSWIN_GRAPHICS void disregard_some_mswin_options(void) diff --git a/sys/windows/windmain.c b/sys/windows/windmain.c index e384031b1..6e7a44db7 100644 --- a/sys/windows/windmain.c +++ b/sys/windows/windmain.c @@ -59,6 +59,7 @@ void windows_nhbell(void); int windows_nh_poskey(int *, int *, int *); void windows_raw_print(const char *); char windows_yn_function(const char *, const char *, char); +boolean portable = FALSE; /* static void windows_getlin(const char *, char *); */ #ifdef WIN32CON @@ -206,8 +207,11 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ } gh.hname = "NetHack"; /* used for syntax messages */ set_default_prefix_locations( - argv[0]); /* must be re-done after initoptions_init() - * which clears out gp.fqn_prefix[] */ + argv[0]); /* must be re-done again after initoptions_init() + * because that function clears out gp.fqn_prefix[] */ +#ifdef MSWIN_GRAPHICS + disregard_some_mswin_options(); +#endif copy_sysconf_content(); copy_symbols_content(); /* Now that sysconf has had a chance to set the TROUBLEPREFIX, don't @@ -260,9 +264,7 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ early_options(&argc, &argv, &dir); program_state.early_options = 0; -#ifdef MSWIN_GRAPHICS - disregard_some_mswin_options(); -#endif + initoptions(); #if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS) chdir(gf.fqn_prefix[HACKPREFIX]); @@ -802,15 +804,19 @@ copy_symbols_content(void) void copy_sysconf_content(void) { - /* Using the SYSCONFPREFIX path, lock it so that it does not change */ - fqn_prefix_locked[SYSCONFPREFIX] = TRUE; + if (sysopt.portable_device_paths) { + portable = TRUE; + } else { + /* Using the SYSCONFPREFIX path, lock it so that it does not change */ + fqn_prefix_locked[SYSCONFPREFIX] = TRUE; - update_file(gf.fqn_prefix[SYSCONFPREFIX], SYSCF_TEMPLATE, - gf.fqn_prefix[DATAPREFIX], SYSCF_TEMPLATE, FALSE); + update_file(gf.fqn_prefix[SYSCONFPREFIX], SYSCF_TEMPLATE, + gf.fqn_prefix[DATAPREFIX], SYSCF_TEMPLATE, FALSE); - /* If the required early game file does not exist, copy it */ - copy_file(gf.fqn_prefix[SYSCONFPREFIX], SYSCF_FILE, - gf.fqn_prefix[DATAPREFIX], SYSCF_TEMPLATE, FALSE); + /* If the required early game file does not exist, copy it */ + copy_file(gf.fqn_prefix[SYSCONFPREFIX], SYSCF_FILE, + gf.fqn_prefix[DATAPREFIX], SYSCF_TEMPLATE, FALSE); + } } void diff --git a/sys/windows/windsys.c b/sys/windows/windsys.c index f7c2e3d55..a951ea6fe 100644 --- a/sys/windows/windsys.c +++ b/sys/windows/windsys.c @@ -44,10 +44,11 @@ * */ -static char portable_device_path[MAX_PATH]; +char portable_device_path[_MAX_PATH]; static boolean path_buffer_set = FALSE; static char path_buffer[MAX_PATH]; +extern boolean portable; #ifndef SFCTOOL /* runtime cursor display control switch */ @@ -88,9 +89,7 @@ int build_known_folder_path(const KNOWNFOLDERID *folder_id, char *path, void build_environment_path(const char *env_str, const char *folder, char *path, size_t path_size); boolean folder_file_exists(const char *folder, const char *file_name); -boolean test_portable_config(const char *executable_path, - char *portable_device_path, - size_t portable_device_path_size); + /* The function pointer nt_kbhit contains a kbhit() equivalent * which varies depending on which window port is active. * For the tty port it is tty_kbhit() [from consoletty.c] @@ -1042,9 +1041,8 @@ set_default_prefix_locations(const char *programPath UNUSED) append_slash(executable_path); #ifndef SFCTOOL - if (test_portable_config(executable_path, portable_device_path, - sizeof portable_device_path)) { - gf.fqn_prefix[SYSCONFPREFIX] = executable_path; + if (portable || (portable = check_for_portable_config())) { + gf.fqn_prefix[SYSCONFPREFIX] = portable_device_path; gf.fqn_prefix[CONFIGPREFIX] = portable_device_path; gf.fqn_prefix[HACKPREFIX] = portable_device_path; gf.fqn_prefix[SAVEPREFIX] = portable_device_path; @@ -1053,7 +1051,7 @@ set_default_prefix_locations(const char *programPath UNUSED) gf.fqn_prefix[SCOREPREFIX] = portable_device_path; gf.fqn_prefix[LOCKPREFIX] = portable_device_path; gf.fqn_prefix[TROUBLEPREFIX] = portable_device_path; - gf.fqn_prefix[DATAPREFIX] = executable_path; + gf.fqn_prefix[DATAPREFIX] = portable_device_path; } else { #endif /* SFCTOOL */ if (!build_known_folder_path(&FOLDERID_Profile, profile_path, @@ -1110,53 +1108,6 @@ append_slash(char *name) } void set_default_prefix_locations(const char *programPath); -boolean -test_portable_config(const char *executable_path, char *portable_device_path, - size_t portable_device_path_size) -{ - int lth = 0; - const char *sysconf = "sysconf"; - char tmppath[MAX_PATH]; - boolean retval = FALSE, - save_initoptions_noterminate = iflags.initoptions_noterminate; - - if (portable_device_path - && folder_file_exists(executable_path, "sysconf")) { - /* - There is a sysconf file (not just sysconf.template) present in - the exe path, which is not the way NetHack is initially - distributed, so assume it means that the admin/installer wants to - override something, perhaps set up for a fully-portable - configuration that leaves no traces behind elsewhere on this - computer's hard drive - delve into that... - */ - - *portable_device_path = '\0'; - lth = sizeof tmppath - strlen(sysconf); - (void) strncpy(tmppath, executable_path, lth - 1); - tmppath[lth - 1] = '\0'; - (void) strcat(tmppath, sysconf); - - iflags.initoptions_noterminate = 1; - /* assure_syscf_file(); */ - config_error_init(TRUE, tmppath, FALSE); - /* ... and _must_ parse correctly. */ - if (read_config_file(tmppath, set_in_sysconf) - && sysopt.portable_device_paths) - retval = TRUE; - (void) config_error_done(); - iflags.initoptions_noterminate = save_initoptions_noterminate; - sysopt_release(); /* the real sysconf processing comes later */ - } - if (retval) { - lth = strlen(executable_path); - if (lth <= (int) portable_device_path_size - 1) - Strcpy(portable_device_path, executable_path); - else - retval = FALSE; - } - return retval; -} const char * get_portable_device(void) From f10fe475057621498fa991cce002e9e897e77e4e Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 10 May 2026 22:58:47 -0400 Subject: [PATCH 225/702] dat/history sync with Guidebook --- dat/history | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dat/history b/dat/history index fba67b7c6..dfc073372 100644 --- a/dat/history +++ b/dat/history @@ -330,7 +330,7 @@ with the msdos port and keep it alive. Cross-compiling the MS-DOS port has helped make that possible and mostly painless. People that contributed to the Windows port of NetHack 5.0 since the -development of NetHack 5.0 begain over eleven years ago, included +development of NetHack 5.0 began over eleven years ago, included Michael Allison, David Cohrs, Bart House, Pasi Kallinen, Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir. From 430c84aef70efcc8ac55d166d05a7adc9e9cb11f Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 10 May 2026 23:21:34 -0400 Subject: [PATCH 226/702] catch up fixes5-0-1.txt --- doc/fixes5-0-1.txt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 09549b72e..514c843e3 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -38,6 +38,9 @@ Amiga: stop rendering CLR_BLACK and CLR_WHITE as inverse video Amiga: default number_pad:1 in shipped nethack.cnf Amiga: promote AMIGA_INTUITION to supported so it shows up in version info Amiga: wire altmeta option to sysflags.altmeta +Amiga: restore glyph icons in menus +Amiga: sys/amiga/README.amiga stated "Extract NH50AMI.ZIP" but it could + be named something else; added a note about the potential suffix libnh: update get_nhuuid() for libnhmain libnh: sys/libnh/libnhmain.c: drop `static` on `whoami()` libnh: rewrote sys/unix/hints/macOS.500: rewrote the libnh.a rule. The @@ -55,11 +58,15 @@ libnh: sys/unix/hints/macOS.500 in the WANT_LIBNH block, add an explicit `recover: lua_support` dependency (gated by MAKEFILE_TOP). When $(GAME) is overridden to empty, the regular `recover: $(GAME)` chain no longer triggers `lua_support`, so include/nhlua.h never gets - generated and recover.c's transitive #include of hack.h fails. + generated and recover.c's transitive #include of hack.h fails macOS: fix ncurses build with Homebrew WASM: resolve some build failures in 'make CROSS_TO_WASM=1' WASM: hints file cross-pre2.500 update to CFLAGS to include -DNHUUID - +Windows: don't demand keypress on intentional exit +Windows: correct a NetHack 5.0.0 packaging error if visual studio was + used; a remnant hard-coded 370 was in package.nmake +Windows: setting any map_mode option in the config file could trigger + cause app failure on launch by dereferencing a null pointer General New Features @@ -72,6 +79,8 @@ Platform- and/or Interface-Specific New Features NetHack Community Patches (or Variation) Included ------------------------------------------------- +NCURSES_CFLAGS was being ignored when using hints/linux.500 with only + WANT_WIN_TTY=1 and not WANT_WIN_CURSES=1 (pr #1522 by torakoya) Code Cleanup and Reorganization From 16986710d559197cc56f8ef226cf284197541e95 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 10 May 2026 23:23:17 -0400 Subject: [PATCH 227/702] follow-up grammar --- doc/fixes5-0-1.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 514c843e3..60f5bb335 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -66,7 +66,7 @@ Windows: don't demand keypress on intentional exit Windows: correct a NetHack 5.0.0 packaging error if visual studio was used; a remnant hard-coded 370 was in package.nmake Windows: setting any map_mode option in the config file could trigger - cause app failure on launch by dereferencing a null pointer + an app failure on launch by dereferencing a null pointer General New Features From a583201f15a4d3279f2cd1e47ddd4aea7bf9b6ec Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 May 2026 06:34:20 -0400 Subject: [PATCH 228/702] check malloc() return in bmp2iff_host.c --- sys/amiga/bmp2iff_host.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sys/amiga/bmp2iff_host.c b/sys/amiga/bmp2iff_host.c index 154335297..85bb42088 100644 --- a/sys/amiga/bmp2iff_host.c +++ b/sys/amiga/bmp2iff_host.c @@ -409,6 +409,10 @@ main(int argc, char **argv) /* read pixel data */ rowstride = (img_w + 3) & ~3; bmpdata = malloc(rowstride * img_h); + if (!bmpdata) { + printf("%s\n", "malloc failure on bmpdata"); + return 1; + } fseek(bmpfp, fhdr.bfOffBits, SEEK_SET); if (fread(bmpdata, 1, rowstride * img_h, bmpfp) != (size_t)(rowstride * img_h)) { @@ -419,6 +423,10 @@ main(int argc, char **argv) /* flip bottom-up to top-down */ pixels = malloc(img_w * img_h); + if (!pixels) { + printf("%s\n", "malloc failure on pixels"); + return 1; + } if (ihdr.biHeight > 0) { for (y = 0; y < img_h; y++) memcpy(pixels + y * img_w, @@ -441,6 +449,10 @@ main(int argc, char **argv) maxcol, outpal, remap); remapped = malloc(img_w * img_h); + if (!remapped) { + printf("%s\n", "malloc failure on remapped"); + return 1; + } for (i = 0; i < img_w * img_h; i++) remapped[i] = (uint8_t)remap[pixels[i]]; From a5a4bc6b4a5e382c345cc0be5e056999e3e129cd Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 May 2026 06:38:11 -0400 Subject: [PATCH 229/702] remove an outdated file that brought a complaint All the files in outdated are mostly source as they were prior to the move to the outdated part of the NetHack tree. They are left there in case somone wants to try to resurrect a port. They are not meant to be compiled, or used as-is. --- outdated/sys/amiga/txt2iff.c | 446 ----------------------------------- 1 file changed, 446 deletions(-) delete mode 100644 outdated/sys/amiga/txt2iff.c diff --git a/outdated/sys/amiga/txt2iff.c b/outdated/sys/amiga/txt2iff.c deleted file mode 100644 index 8e1916b9e..000000000 --- a/outdated/sys/amiga/txt2iff.c +++ /dev/null @@ -1,446 +0,0 @@ -/* NetHack 3.6 txt2iff.c $NHDT-Date: 1432512795 2015/05/25 00:13:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */ -/* Copyright (c) 1995 by Gregg Wonderly, Naperville, Illinois */ -/* NetHack may be freely redistributed. See license for details. */ - -#include - -#include "config.h" -#include "tile.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef _DCC -#include -#include -#include -#endif - -void panic(const char *); -void map_colors(void); -int BestMatch(int, int, int); - -extern pixval ColorMap[3][MAXCOLORMAPSIZE]; -extern int colorsinmap; - -/* - * WARNING: - * This program carries forth the assumption that the colormaps in all - * of the .txt files are the same. This is a bug. - */ - -struct { - int Height; - int Width; -} IFFScreen; - -/* - * We are using a hybrid form of our own design which we call a BMAP (for - * bitmap) form. It is an ILBM with the bitmaps already deinterleaved, - * completely uncompressed. - * This speeds the loading of the images from the games point of view because - * it - * does not have to deinterleave and uncompress them. - */ -#define ID_BMAP MAKE_ID('B', 'M', 'A', 'P') /* instead of ILBM */ -#define ID_BMHD MAKE_ID('B', 'M', 'H', 'D') /* Same as ILBM */ -#define ID_CAMG MAKE_ID('C', 'A', 'M', 'G') /* Same as ILBM */ -#define ID_CMAP MAKE_ID('C', 'M', 'A', 'P') /* Same as ILBM */ -#define ID_PDAT \ - MAKE_ID('P', 'D', 'A', 'T') /* Extra data describing plane \ - * size due to graphics.library \ - * rounding requirements. \ - */ -#define ID_PLNE MAKE_ID('P', 'L', 'N', 'E') /* The planes of the image */ - -#ifndef _DCC -extern -#endif - struct Library *IFFParseBase; - -int nplanes; - -/* BMHD from IFF documentation */ -typedef struct { - UWORD w, h; - WORD x, y; - UBYTE nPlanes; - UBYTE masking; - UBYTE compression; - UBYTE reserved1; - UWORD transparentColor; - UBYTE xAspect, yAspect; - WORD pageWidth, pageHeight; -} BitMapHeader; - -typedef struct { - UBYTE r, g, b; -} AmiColorMap; - -pixel pixels[TILE_Y][TILE_X]; -AmiColorMap *cmap; - -int findcolor(register pixel *pix); -void packwritebody(pixel (*tile)[TILE_X], char **planes, int tileno); - -void -error(char *str) -{ - fprintf(stderr, "ERROR: %s\n", str); -} - -/* - * This array maps the image colors to the amiga's first 16 colors. The - * colors - * are reordered to help with maintaining dripen settings. - */ -int colrmap[] = { 0, 6, 9, 15, 4, 10, 2, 3, 5, 11, 7, 13, 8, 1, 14, 12 }; - -/* How many tiles fit across and down. */ - -#define COLS 20 -#define ROWS ((tiles + COLS - 1) / COLS) - -main(int argc, char **argv) -{ - int colors; - struct { - long nplanes; - long pbytes; - long across; - long down; - long npics; - long xsize; - long ysize; - } pdat; - long pbytes; /* Bytes of data in a plane */ - int i, cnt; - BitMapHeader bmhd; - struct IFFHandle *iff; - long camg = HIRES | LACE; - int tiles = 0; - char **planes; - - if (argc != 3) { - fprintf(stderr, "Usage: %s source destination\n", argv[0]); - exit(1); - } - -#if defined(_DCC) || defined(__GNUC__) - IFFParseBase = OpenLibrary("iffparse.library", 0); - if (!IFFParseBase) { - error("unable to open iffparse.library"); - exit(1); - } -#endif - - /* First, count the files in the file */ - if (fopen_text_file(argv[1], "r") != TRUE) { - perror(argv[1]); - return (1); - } - - nplanes = 0; - i = colorsinmap - 1; /*IFFScreen.Colors - 1; */ - while (i != 0) { - nplanes++; - i >>= 1; - } - - planes = malloc(nplanes * sizeof(char *)); - if (planes == 0) { - error("can not allocate planes pointer"); - exit(1); - } - - while (read_text_tile(pixels) == TRUE) - ++tiles; - fclose_text_file(); - - IFFScreen.Width = COLS * TILE_X; - IFFScreen.Height = ROWS * TILE_Y; - - pbytes = (COLS * ROWS * TILE_X + 15) / 16 * 2 * TILE_Y; - - for (i = 0; i < nplanes; ++i) { - planes[i] = calloc(1, pbytes); - if (planes[i] == 0) { - error("can not allocate planes pointer"); - exit(1); - } - } - - /* Now, process it */ - if (fopen_text_file(argv[1], "r") != TRUE) { - perror(argv[1]); - return (1); - } - - iff = AllocIFF(); - if (!iff) { - error("Can not allocate IFFHandle"); - return (1); - } - - iff->iff_Stream = Open(argv[2], MODE_NEWFILE); - if (!iff->iff_Stream) { - error("Can not open output file"); - return (1); - } - - InitIFFasDOS(iff); - OpenIFF(iff, IFFF_WRITE); - - PushChunk(iff, ID_BMAP, ID_FORM, IFFSIZE_UNKNOWN); - - bmhd.w = IFFScreen.Width; - bmhd.h = IFFScreen.Height; - bmhd.x = 0; - bmhd.y = 0; - bmhd.nPlanes = nplanes; - bmhd.masking = 0; - bmhd.compression = 0; - bmhd.reserved1 = 0; - bmhd.transparentColor = 0; - bmhd.xAspect = 100; - bmhd.yAspect = 100; - bmhd.pageWidth = TILE_X; - bmhd.pageHeight = TILE_Y; - - PushChunk(iff, ID_BMAP, ID_BMHD, sizeof(bmhd)); - WriteChunkBytes(iff, &bmhd, sizeof(bmhd)); - PopChunk(iff); - - PushChunk(iff, ID_BMAP, ID_CAMG, sizeof(camg)); - WriteChunkBytes(iff, &camg, sizeof(camg)); - PopChunk(iff); - - /* We need to reorder the colors to get reasonable default pens but - * we also need to know where some of the colors are - so go find out. - */ - map_colors(); - - cmap = malloc((colors = (1L << nplanes)) * sizeof(AmiColorMap)); - for (i = 0; i < colors; ++i) { - cmap[colrmap[i]].r = ColorMap[CM_RED][i]; - cmap[colrmap[i]].g = ColorMap[CM_GREEN][i]; - cmap[colrmap[i]].b = ColorMap[CM_BLUE][i]; - } - - PushChunk(iff, ID_BMAP, ID_CMAP, IFFSIZE_UNKNOWN); - for (i = 0; i < colors; ++i) - WriteChunkBytes(iff, &cmap[i], 3); - PopChunk(iff); - - cnt = 0; - while (read_text_tile(pixels) == TRUE) { - packwritebody(pixels, planes, cnt); - if (cnt % 20 == 0) - printf("%d..", cnt); - ++cnt; - fflush(stdout); - } - - pdat.nplanes = nplanes; - pdat.pbytes = pbytes; - pdat.xsize = TILE_X; - pdat.ysize = TILE_Y; - pdat.across = COLS; - pdat.down = ROWS; - pdat.npics = cnt; - - PushChunk(iff, ID_BMAP, ID_PDAT, IFFSIZE_UNKNOWN); - WriteChunkBytes(iff, &pdat, sizeof(pdat)); - PopChunk(iff); - - PushChunk(iff, ID_BMAP, ID_PLNE, IFFSIZE_UNKNOWN); - for (i = 0; i < nplanes; ++i) - WriteChunkBytes(iff, planes[i], pbytes); - PopChunk(iff); - - CloseIFF(iff); - Close(iff->iff_Stream); - FreeIFF(iff); - - printf("\n%d tiles converted\n", cnt); - -#if defined(_DCC) || defined(__GNUC__) - CloseLibrary(IFFParseBase); -#endif - exit(0); -} - -findcolor(register pixel *pix) -{ - register int i; - - for (i = 0; i < MAXCOLORMAPSIZE; ++i) { - if ((pix->r == ColorMap[CM_RED][i]) - && (pix->g == ColorMap[CM_GREEN][i]) - && (pix->b == ColorMap[CM_BLUE][i])) { - return (i); - } - } - return (-1); -} - -void -packwritebody(pixel (*tile)[TILE_X], char **planes, int tileno) -{ - register int i, j, k, col; - register char *buf; - register int across, rowbytes, xoff, yoff; - - /* how many tiles fit across? */ - across = COLS; - - /* How many bytes per pixel row */ - rowbytes = ((IFFScreen.Width + 15) / 16) * 2; - - /* How many bytes to account for y distance in planes */ - yoff = ((tileno / across) * TILE_Y) * rowbytes; - - /* How many bytes to account for x distance in planes */ - xoff = (tileno % across) * (TILE_X / 8); - - /* For each row... */ - for (i = 0; i < TILE_Y; ++i) { - /* For each bitplane... */ - for (k = 0; k < nplanes; ++k) { - const int mask = 1l << k; - - /* Go across the row */ - for (j = 0; j < TILE_X; j++) { - col = findcolor(&tile[i][j]); - if (col == -1) { - error("can not convert pixel color to colormap index"); - return; - } - /* Shift the colors around to have good complements and to - * know the dripen values. - */ - col = colrmap[col]; - - /* To top left corner of tile */ - buf = planes[k] + yoff + xoff; - - /*To i'th row of tile and the correct byte for the j'th - * pixel*/ - buf += (i * rowbytes) + (j / 8); - - /* Or in the bit for this color */ - *buf |= (((col & mask) != 0) << (7 - (j % 8))); - } - } - } -} - -/* #define DBG */ - -/* map_colors - * The incoming colormap is in arbitrary order and has arbitrary colors in - * it, but we need (some) specific colors in specific places. Find the - * colors we need and fix the mapping table to match. - */ -/* What we are aiming for: */ -/* XXX was 0-7 */ -#define CX_BLACK 0 -#define CX_WHITE 1 -#define CX_BROWN 11 -#define CX_CYAN 2 -#define CX_GREEN 5 -#define CX_MAGENTA 10 -#define CX_BLUE 4 -#define CX_RED 7 -/* we don't care about the rest, at least now */ -/* should get: black white blue red grey greyblue ltgrey */ -void -map_colors() -{ - int x; -#if 1 - int tmpmap[] = { 0, 2, 3, 7, 4, 5, 8, 9, 10, 11, 13, 15, 12, 1, 14, 6 }; -/* still not right: gray green yellow lost somewhere? */ -#else - int tmpmap[16]; - int x, y; - for (x = 0; x < 16; x++) - tmpmap[x] = -1; /* set not assigned yet */ - - tmpmap[BestMatch(0, 0, 0)] = CX_BLACK; - tmpmap[BestMatch(255, 255, 255)] = CX_WHITE; - tmpmap[BestMatch(255, 0, 0)] = CX_RED; - tmpmap[BestMatch(0, 255, 0)] = CX_GREEN; - tmpmap[BestMatch(0, 0, 255)] = CX_BLUE; - - /* clean up the rest */ - for (x = 0; x < 16; x++) { - for (y = 0; y < 16; y++) - if (tmpmap[y] == x) - goto outer_cont; - for (y = 0; y < 16; y++) - if (tmpmap[y] == -1) { - tmpmap[y] = x; - break; - } - if (y == 16) - panic("too many colors?"); - outer_cont: - ; - } - for (x = 0; x < 16; x++) - if (tmpmap[y] == -1) - panic("lost color?"); -#endif - for (x = 0; x < 16; x++) { -#ifdef DBG - printf("final: c[%d]=%d (target: %d)\n", x, tmpmap[x], colrmap[x]); -#endif - colrmap[x] = tmpmap[x]; - } -} -BestMatch(r, g, b) int r, g, b; -{ - int x; - int bestslot; - int bestrate = 99999999L; - for (x = 0; x < 16; x++) { - int rr = r - ColorMap[CM_RED][x]; - int gg = g - ColorMap[CM_GREEN][x]; - int bb = b - ColorMap[CM_BLUE][x]; - int rate = rr * rr + gg * gg + bb * bb; - if (bestrate > rate) { - bestrate = rate; - bestslot = x; - } - } -#ifdef DBG - printf("map (%d,%d,%d) -> %d (error=%d)\n", r, g, b, bestslot, bestrate); -#endif - return bestslot; -} - -long * -alloc(unsigned int n) -{ - long *ret = malloc(n); - if (!ret) { - error("Can't allocate memory"); - exit(1); - } - return (ret); -} - -void -panic(const char *msg) -{ - fprintf(stderr, "PANIC: %s\n", msg); - exit(1); -} From b4f28edfe4392a7c6d22457dfd8079b0faa210de Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 May 2026 11:33:15 -0400 Subject: [PATCH 230/702] some malloc() --- sys/windows/consoletty.c | 4 ++-- sys/windows/windsys.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index 5b5b77070..65462ef47 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -2513,10 +2513,10 @@ void nethack_enter_consoletty(void) /* setup front and back buffers */ int buffer_size_bytes = sizeof(cell_t) * console.buffer_size; - console.front_buffer = (cell_t *)malloc(buffer_size_bytes); + console.front_buffer = (cell_t *)alloc(buffer_size_bytes); buffer_fill_to_end(console.front_buffer, &undefined_cell, 0, 0); - console.back_buffer = (cell_t *)malloc(buffer_size_bytes); + console.back_buffer = (cell_t *)alloc(buffer_size_bytes); buffer_fill_to_end(console.back_buffer, &clear_cell, 0, 0); /* determine whether OS version has unicode support */ diff --git a/sys/windows/windsys.c b/sys/windows/windsys.c index a951ea6fe..bd8a9871f 100644 --- a/sys/windows/windsys.c +++ b/sys/windows/windsys.c @@ -677,7 +677,7 @@ BOOL winos_font_support_cp437(HFONT hFont) DWORD size = (size_t) GetFontUnicodeRanges(hdc, NULL); if (size) { - GLYPHSET *glyphSet = (GLYPHSET *) malloc((size_t) size); + GLYPHSET *glyphSet = (GLYPHSET *) alloc((size_t) size); if (glyphSet != NULL) { #ifdef _MSC_VER #pragma warning( push ) From 7c14ed2723c520ce39f62646225f200b811256ae Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Mon, 11 May 2026 07:16:06 -0400 Subject: [PATCH 231/702] This is cron-daily v1-May-7-2026. 000files updated: Files --- Files | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Files b/Files index 50d8ecfba..6326696a1 100644 --- a/Files +++ b/Files @@ -135,7 +135,7 @@ mactty.h macwin.h mttypriv.h outdated/sys/amiga: (files for Amiga versions - untested for 5.0) Build.ami Install.ami Makefile.agc Makefile.ami NetHack.cnf -ifchange mkdmake txt2iff.c xpm2iff.c +ifchange mkdmake xpm2iff.c outdated/sys/atari: (files for Atari version - untested for 5.0) From e8e8749c25e3956010ff83ad3ee949436b968496 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 May 2026 12:18:17 -0400 Subject: [PATCH 232/702] move header to bottom of the Contributing.md file --- Contributing.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Contributing.md b/Contributing.md index 99d170922..e5490d5c3 100644 --- a/Contributing.md +++ b/Contributing.md @@ -1,6 +1,3 @@ -# NetHack 3.7 Contributing.txt $NHDT-Date: 1596498265 2020/08/03 23:44:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.19 $ -# NetHack may be freely redistributed. See license for details. - If you are making a GitHub pull request for NetHack, please follow these guidelines: 1. The 50/72 Rule: Keep the subject line (the first line) under 50 characters @@ -10,3 +7,9 @@ for readability in git log --oneline. If you need a more detailed description 2. Separate Subject from Body: Always include a blank line between the subject and the body. This helps Git tools correctly parse the message. + + +# NetHack 3.7 Contributing.txt $NHDT-Date: 1596498265 2020/08/03 23:44:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.19 $ +# NetHack may be freely redistributed. See license for details. + + From b2cf7d5a845c8b0a49d6c7802feaa01ad8dec59a Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 May 2026 12:33:35 -0400 Subject: [PATCH 233/702] Guidebook datestamp to most recent commit --- doc/Guidebook.mn | 2 +- doc/Guidebook.tex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 62a7ef492..a5724074d 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -60,7 +60,7 @@ .ds f0 \*(vr .ds f1 \" empty .\"DO NOT REMOVE NH_DATESUB .ds f2 Date(%B %-d, %Y) -.ds f2 May 2, 2026 +.ds f2 May 6, 2026 . .\" A note on some special characters: .\" \(lq = left double quote diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 6f129f090..2698ba802 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -25,7 +25,7 @@ \author{Original version - Eric S. Raymond\\ (Edited and expanded for 5.0.0 by Mike Stephenson and others)} %DO NOT REMOVE NH_DATESUB \date{Date(%B %-d, %Y)} -\date{May 2, 2026} +\date{May 6, 2026} \maketitle From 66c97eaab3c87064fb42eb92309592723f0e5635 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Mon, 11 May 2026 13:16:09 -0400 Subject: [PATCH 234/702] This is cron-daily v1-May-7-2026. 005guidebook updated: doc/Guidebook.txt --- doc/Guidebook.txt | 238 +++++++++++++++++++++++----------------------- 1 file changed, 119 insertions(+), 119 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 1d85d895d..e44a6bc17 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for NetHack 5.0.0 by Mike Stephenson and others) - May 2, 2026 + May 6, 2026 @@ -126,7 +126,7 @@ employ to great advantage. - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -192,7 +192,7 @@ NetHack continues this fine tradition. Unlike text adventure games - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -258,7 +258,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -324,7 +324,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -390,7 +390,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -456,7 +456,7 @@ The number of turns elapsed so far, displayed if you have the - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -522,7 +522,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -588,7 +588,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -654,7 +654,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -720,7 +720,7 @@ instead. Only these one-step movement commands cause you to - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -786,7 +786,7 @@ ing . ^ is used as shorthand elsewhere in the - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -852,7 +852,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -918,7 +918,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -984,7 +984,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -1050,7 +1050,7 @@ at an adjacent "remembered, unseen monster" marker. - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -1116,7 +1116,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -1182,7 +1182,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -1248,7 +1248,7 @@ (R)UNIX is a registered trademark of The Open Group. - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -1314,7 +1314,7 @@ inventory slot. If it has a name assigned, other stacks with the - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -1380,7 +1380,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -1446,7 +1446,7 @@ fight there. Default key is `F', or `-' with number_pad - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -1512,7 +1512,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -1578,7 +1578,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -1644,7 +1644,7 @@ Pick up things at the current location. Default key is `,'. The - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -1710,7 +1710,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -1776,7 +1776,7 @@ worn. - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -1842,7 +1842,7 @@ Suspend the game, switching from NetHack to the terminal it was - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -1908,7 +1908,7 @@ pick one from inventory, except for the special case of - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -1974,7 +1974,7 @@ menu of sorting orders available (provided that the vanquished - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -2040,7 +2040,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -2106,7 +2106,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -2172,7 +2172,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -2238,7 +2238,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -2304,7 +2304,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -2370,7 +2370,7 @@ them). Some monsters who can open doors can also use unlocking tools. - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -2436,7 +2436,7 @@ been nullified, giving access to whatever is beyond them. In the - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -2502,7 +2502,7 @@ play. - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -2568,7 +2568,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -2634,7 +2634,7 @@ attack, when guessing where an unseen monster is or when deliberately - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -2700,7 +2700,7 @@ noid_confirmation:attack option to require a response of "yes" - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -2766,7 +2766,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -2832,7 +2832,7 @@ are encumbered, one of the conditions Burdened, Stressed, Strained, - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -2898,7 +2898,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -2964,7 +2964,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -3030,7 +3030,7 @@ aklys, lucern hammer, and bec-de-corbin) are defined in an appendix to - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -3096,7 +3096,7 @@ shots by using a numeric prefix before the `t' or `f' command. For - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -3162,7 +3162,7 @@ first you need to have a weapon in each hand. (Note that your two - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -3228,7 +3228,7 @@ even further. Most of these provide a one or two point improvement to - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -3294,7 +3294,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -3360,7 +3360,7 @@ yourself (just give a `.' or `s' for the direction). Be warned, how- - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -3426,7 +3426,7 @@ your ken can be harmful to your health! - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -3492,7 +3492,7 @@ play the entire game without being able to see (a self-imposed chal- - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -3558,7 +3558,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -3624,7 +3624,7 @@ set the goldX option if you prefer to have gold pieces be treated as - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -3690,7 +3690,7 @@ eating such items still counts against foodless conduct. - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -3756,7 +3756,7 @@ monster (i.e. if you would get experience for the death). This is a - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -3822,7 +3822,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -3888,7 +3888,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -3954,7 +3954,7 @@ ning NetHack for the first time, you should find a default template - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -4020,7 +4020,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -4086,7 +4086,7 @@ begins; whatever follows will be common to all sections. Otherwise - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -4152,7 +4152,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -4218,7 +4218,7 @@ sign) to let NetHack know that the rest is intended as a file name. - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -4284,7 +4284,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -4350,7 +4350,7 @@ weapon or both. - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -4416,7 +4416,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -4482,7 +4482,7 @@ extended command, it controls whether the menu shows all available - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -4548,7 +4548,7 @@ might miss some interesting and/or important information. Persis- - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -4614,7 +4614,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -4680,7 +4680,7 @@ class(es). Combination starts with a prompt for object class(es) of - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -4746,7 +4746,7 @@ 5 - One-or-other - show symbols on headers, or on entries if no - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -4812,7 +4812,7 @@ port is the same as specifying 0. - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -4878,7 +4878,7 @@ ing 1 and negating number_pad is the same as specifying 0. (Set- - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -4944,7 +4944,7 @@ `y', set Confirm too); - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -5010,7 +5010,7 @@ ing pets on the map. Effectively a superset of the hilite_pet bool- - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -5076,7 +5076,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -5142,7 +5142,7 @@ game). This option exists partly as an acknowledgement that some - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -5208,7 +5208,7 @@ sistent. - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -5274,7 +5274,7 @@ Controls the sorting behavior for the output of the `\' and ``' com- - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -5340,7 +5340,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -5406,7 +5406,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -5472,7 +5472,7 @@ targets. - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -5538,7 +5538,7 @@ currently using by checking to see if it shows up in the Options list. - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -5604,7 +5604,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -5670,7 +5670,7 @@ this option. - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -5736,7 +5736,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -5802,7 +5802,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -5868,7 +5868,7 @@ hang if this is turned on. Cannot be set with the `O' command. - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -5934,7 +5934,7 @@ you can define patterns to be checked when the game is about to - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -6000,7 +6000,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -6066,7 +6066,7 @@ When asked for a location, the key to go to next closest door or - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -6132,7 +6132,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -6198,7 +6198,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -6264,7 +6264,7 @@ ple MENUCOLOR entries in your configuration file, and the last MENU- - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -6330,7 +6330,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -6396,7 +6396,7 @@ depending upon your other option settings. - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -6462,7 +6462,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -6528,7 +6528,7 @@ value, and the ^ prefix causes the following character to be treated - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -6594,7 +6594,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -6660,7 +6660,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -6726,7 +6726,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -6792,7 +6792,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -6858,7 +6858,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -6924,7 +6924,7 @@ seen via the "#attributes" command. - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -6990,7 +6990,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -7056,7 +7056,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -7122,7 +7122,7 @@ connection between "wizard mode" and the Wizard role). Attempting to - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -7188,7 +7188,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -7254,7 +7254,7 @@ were distinct for specific types of monsters and objects rather than - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -7320,7 +7320,7 @@ file layout which prevented score entries from being read back in cor- - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -7386,7 +7386,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -7452,7 +7452,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -7518,7 +7518,7 @@ changes and new features almost immediately, and they often did. The - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -7584,7 +7584,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -7650,7 +7650,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -7716,7 +7716,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -7782,7 +7782,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 @@ -7848,7 +7848,7 @@ - NetHack 5.0.0 May 2, 2026 + NetHack 5.0.0 May 6, 2026 From f8ea34489f15e909e552d83ec6c7b5119dc33c33 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 15:29:32 +0200 Subject: [PATCH 235/702] Amiga: fix three latent bugs found in code review amiv_lprint_glyph used uninitialized 'base'; amii_clear_nhwindow compared cw->type to a winid; amii_sethipens fell through. --- sys/amiga/winchar.c | 2 +- sys/amiga/winfuncs.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/amiga/winchar.c b/sys/amiga/winchar.c index 0c9dbc6b2..1b62c390f 100644 --- a/sys/amiga/winchar.c +++ b/sys/amiga/winchar.c @@ -563,7 +563,7 @@ amiv_flush_glyph_buffer(struct Window *vw) void amiv_lprint_glyph(winid window, int color_index, int glyph) { - int base; + int base = 0; struct amii_WinDesc *cw; struct Window *w; int curx; diff --git a/sys/amiga/winfuncs.c b/sys/amiga/winfuncs.c index db32e2e8b..788964b77 100644 --- a/sys/amiga/winfuncs.c +++ b/sys/amiga/winfuncs.c @@ -1354,6 +1354,7 @@ amii_sethipens(struct Window *w, int type, int attr) case NHW_TEXT: SetAPen(w->RPort, attr ? C_BLACK : amii_textAPen); SetBPen(w->RPort, amii_textBPen); + break; case -2: SetBPen(w->RPort, amii_otherBPen); SetAPen(w->RPort, attr ? C_RED : amii_otherAPen); @@ -1445,7 +1446,7 @@ amii_clear_nhwindow(winid win) /* Clear the overview window too if it is displayed */ if (WINVERS_AMIV - && (cw->type == WIN_MAP && WIN_OVER != WIN_ERR && reclip == 0)) { + && (cw->type == NHW_MAP && WIN_OVER != WIN_ERR && reclip == 0)) { amii_clear_nhwindow(WIN_OVER); } From 22ddba7c1e0f7d95195d1308a6b9e2163c2e20c4 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 15:47:45 +0200 Subject: [PATCH 236/702] Amiga: more review fixes - NHW_BASE / NHW_OVER collided with NHW_PERMINVENT=6; renumber off NHW_LAST_TYPE. - GlyphToIcon used > 10000 instead of >=. - make_menu_items sized array by sizeof(amii_menu_item) instead of menu_item. - DoMenuScroll could deref NULL amip on SELECTUP. - get_nhuuid uses ISAAC64 rn2() instead of hand-rolled LCG. - fopenp's bound check fired one byte too late. - winami.p had stale signatures for amii_end_menu, amii_select_menu, amii_suspend_nhwindows. --- include/winami.h | 4 ++-- sys/amiga/amidos.c | 21 +++++---------------- sys/amiga/winamenu.c | 6 +++--- sys/amiga/winami.c | 5 +++++ sys/amiga/winami.p | 6 +++--- sys/amiga/winchar.c | 2 +- 6 files changed, 19 insertions(+), 25 deletions(-) diff --git a/include/winami.h b/include/winami.h index 686d37f91..913b130c3 100644 --- a/include/winami.h +++ b/include/winami.h @@ -117,8 +117,8 @@ typedef struct WEVENT { /* port specific variable declarations */ extern winid WIN_BASE; extern winid WIN_OVER; -#define NHW_BASE 6 -#define NHW_OVER 7 /* overview window */ +#define NHW_BASE (NHW_LAST_TYPE + 1) +#define NHW_OVER (NHW_LAST_TYPE + 2) /* overview window */ extern struct amii_WinDesc *amii_wins[MAXWIN + 1]; diff --git a/sys/amiga/amidos.c b/sys/amiga/amidos.c index c06fc1b1c..9de6a0810 100644 --- a/sys/amiga/amidos.c +++ b/sys/amiga/amidos.c @@ -47,30 +47,19 @@ amiga_self_assign(void) UnLock(dup); } -/* Generate an RFC 4122 v4 UUID for this game. Entropy comes from - DateStamp + the running task's address mixed through a small LCG. */ +/* Generate an RFC 4122 v4 UUID for this game. Draw bytes from the + core's ISAAC64 RNG, which init_random() seeded before we get here. */ void get_nhuuid(void) { uchar bytes[16]; - struct DateStamp ds; - unsigned long x; int i; if (svn.nhuuid[0]) return; - DateStamp(&ds); - x = (unsigned long) ds.ds_Days - ^ ((unsigned long) ds.ds_Minute << 16) - ^ ((unsigned long) ds.ds_Tick << 8) - ^ (unsigned long) FindTask(NULL); - /* Classic glibc/POSIX rand() LCG (Knuth, C99 7.22.2.1). Full period - 2^32; we read bits 16-23 to skip the LCG's bad low bits. */ - for (i = 0; i < 16; i++) { - x = x * 1103515245u + 12345u; - bytes[i] = (uchar) (x >> 16); - } + for (i = 0; i < 16; i++) + bytes[i] = (uchar) rn2(256); /* RFC 4122: version=4 (random), variant=10. */ bytes[6] = (bytes[6] & 0x0F) | 0x40; bytes[8] = (bytes[8] & 0x3F) | 0x80; @@ -481,7 +470,7 @@ fopenp(const char *name, const char *mode) while (pp && *pp) { bp = buf; while (*pp && *pp != PATHSEP) { - if (bp > buf + BUFSIZ - 1) + if (bp >= buf + BUFSIZ - 1) return (NULL); lastch = *bp++ = *pp++; } diff --git a/sys/amiga/winamenu.c b/sys/amiga/winamenu.c index 9cc2a0fb3..6d2310bc4 100644 --- a/sys/amiga/winamenu.c +++ b/sys/amiga/winamenu.c @@ -215,7 +215,7 @@ make_menu_items(struct amii_WinDesc *cw, menu_item **rmip) } if (idx) { - mmip = *rmip = (menu_item *) alloc(idx * sizeof(*mip)); + mmip = *rmip = (menu_item *) alloc(idx * sizeof(menu_item)); for (mip = cw->menu.items; mip; mip = mip->next) { if (mip->selected) { mmip->item = mip->identifier; @@ -982,8 +982,8 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) amip->str[SOFF + 2] = '-'; } } - if (counting && amip->selected && amip->canselect - && amip->selector) { + if (amip && counting && amip->selected + && amip->canselect && amip->selector) { amip->count = count; reset_counting = TRUE; amip->str[SOFF + 2] = '#'; diff --git a/sys/amiga/winami.c b/sys/amiga/winami.c index 7770a3547..e1276e986 100644 --- a/sys/amiga/winami.c +++ b/sys/amiga/winami.c @@ -340,6 +340,11 @@ struct win_setup new_wins[] = { 22, 78 }, + /* NHW_PERMINVENT — placeholder; port does not implement persistent + inventory yet, but the slot must exist because new_wins[] is + indexed by NHW_* type. */ + { { 0 } }, + /* NHW_BASE */ { { 0, 0, WIDTH, WINDOWHEIGHT, 0xff, 0xff, RAWKEY | MENUPICK | MOUSEBUTTONS, diff --git a/sys/amiga/winami.p b/sys/amiga/winami.p index dfb588177..57b9af93c 100644 --- a/sys/amiga/winami.p +++ b/sys/amiga/winami.p @@ -6,8 +6,8 @@ void amii_raw_print(const char *); void amii_raw_print_bold(const char *); void amii_start_menu(winid , unsigned long ); void amii_add_menu(winid, const glyph_info *, const anything *, char, char, int, int, const char *, unsigned int); -void amii_end_menu(winid , char , const char * , const char *); -char amii_select_menu(winid ); +void amii_end_menu(winid, const char *); +int amii_select_menu(winid, int, menu_item **); void amii_update_inventory(int); void amii_mark_synch (void); void amii_wait_synch (void); @@ -46,7 +46,7 @@ void cursor_on(winid ); void amii_getret (void); void amii_getlin(const char * , char *); void getlind(const char * , char * , const char *); -void amii_suspend_nhwindows(char * ); +void amii_suspend_nhwindows(const char *); void amii_resume_nhwindows(void); void amii_bell(void); void EditColor(void); diff --git a/sys/amiga/winchar.c b/sys/amiga/winchar.c index 1b62c390f..7e17ea574 100644 --- a/sys/amiga/winchar.c +++ b/sys/amiga/winchar.c @@ -805,7 +805,7 @@ GlyphToIcon(int glyph) glyph_info gi; map_glyphinfo(0, 0, glyph, 0, &gi); - if (glyph > 10000) + if (glyph >= 10000) return glyph; return (gi.gm.tileidx); } From f0b6ddc6f8680eb1f4150276ee7c381230be2760 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 15:55:03 +0200 Subject: [PATCH 237/702] Amiga: drop legacy non-gcc compiler guards Remove AZTEC_C, _DCC, SASC, LATTICE, MANX arms. The port targets bebbo gcc. --- sys/amiga/amidos.c | 9 --------- sys/amiga/amigst.c | 15 --------------- sys/amiga/amirip.c | 16 ---------------- sys/amiga/amistack.c | 19 ++----------------- sys/amiga/amitty.c | 7 ------- sys/amiga/amiwind.c | 28 ---------------------------- sys/amiga/winami.c | 12 +----------- sys/amiga/winchar.c | 2 -- sys/amiga/windefs.h | 44 -------------------------------------------- sys/amiga/winfuncs.c | 22 ---------------------- 10 files changed, 3 insertions(+), 171 deletions(-) diff --git a/sys/amiga/amidos.c b/sys/amiga/amidos.c index 9de6a0810..47b793762 100644 --- a/sys/amiga/amidos.c +++ b/sys/amiga/amidos.c @@ -20,10 +20,8 @@ #undef COUNT -#if defined(__SASC_60) || defined(__GNUC__) #include #include -#endif /* POSIX stubs needed by libnix (-noixemul) */ #ifdef __noixemul__ @@ -85,11 +83,6 @@ free_nhuuid(void) } } -#ifdef AZTEC_50 -#include -#undef strcmpi -#endif - /* Prototypes */ #ifndef CROSS_TO_AMIGA #include "NH:sys/amiga/amiwind.p" @@ -107,9 +100,7 @@ extern struct window_procs amii_procs; struct ami_sysflags sysflags = {0}; FILE *fopenp(const char *, const char *); -#ifndef __SASC_60 int Enable_Abort = 0; /* for stdio package */ -#endif /* Initial path, so we can find NetHack.cnf */ char PATH[PATHLEN] = "NetHack:"; diff --git a/sys/amiga/amigst.c b/sys/amiga/amigst.c index 8f6a74f64..6e6697111 100644 --- a/sys/amiga/amigst.c +++ b/sys/amiga/amigst.c @@ -17,25 +17,10 @@ #include #include -#ifdef __SASC -#include /* for __emit */ -#include -#include -#include -#include -#include -#include -#include -#endif - #include "hack.h" #include "winprocs.h" #include "winami.h" -#ifdef AZTEC -#include -#endif - #ifndef CROSS_TO_AMIGA #include "NH:sys/amiga/winami.p" #include "NH:sys/amiga/amiwind.p" diff --git a/sys/amiga/amirip.c b/sys/amiga/amirip.c index 5f4aa52af..6c23a4f6c 100644 --- a/sys/amiga/amirip.c +++ b/sys/amiga/amirip.c @@ -28,20 +28,10 @@ static struct RastPort *rp; #undef NULL #define NULL 0 -#ifdef AZTEC_C -#include -#else -#ifdef _DCC -#include -#include -#include -#include -#else #include #include #include #include -#endif static BitMapHeader tomb_bmhd; static struct BitMap *tombimg = NULL; @@ -58,14 +48,8 @@ static int xoff, yoff; /* image centering */ #undef red #undef green #undef blue -#ifdef _DCC -#include -#include -#else #include #include -#endif -#endif /* AZTEC_C */ static struct Window *ripwin = 0; static void tomb_text(char *); diff --git a/sys/amiga/amistack.c b/sys/amiga/amistack.c index 690bea07c..50abff355 100644 --- a/sys/amiga/amistack.c +++ b/sys/amiga/amistack.c @@ -2,30 +2,15 @@ /* Copyright (c) Janne Salmijärvi, Tampere, Finland, 2000 */ /* NetHack may be freely redistributed. See license for details. */ -/* - * Increase stack size to allow deep recursions. - * - * Note: This is SAS/C specific, using other compiler probably - * requires another method for increasing stack. - * - */ - -#ifdef __SASC_60 -#include -#endif - /* * Increase stack size to allow deep recursions. * NetHack 5.0 with Lua needs significantly more stack than 3.6. + * + * libnix needs __stkinit referenced to pull swapstack.o from libnix.a. */ -#ifdef __SASC_60 -long __stack = 256 * 1024; -#else -/* libnix needs __stkinit referenced to pull swapstack.o from libnix.a */ unsigned long __stack = 256 * 1024; #ifdef CROSS_TO_AMIGA extern void __stkinit(void); void *__nh_force_stkinit = __stkinit; #endif -#endif diff --git a/sys/amiga/amitty.c b/sys/amiga/amitty.c index 22036c8f5..e47f3b693 100644 --- a/sys/amiga/amitty.c +++ b/sys/amiga/amitty.c @@ -13,13 +13,6 @@ #include #include -#ifdef _DCC -#define getch() getchar() -#endif -#ifdef __SASC_60 -#include -#endif - void tty_change_color(void); char *tty_get_color_string(void); diff --git a/sys/amiga/amiwind.c b/sys/amiga/amiwind.c index d931697b7..beaf3cb89 100644 --- a/sys/amiga/amiwind.c +++ b/sys/amiga/amiwind.c @@ -711,7 +711,6 @@ amii_cleanup(void) void Abort(long rc) { - int fault = 1; #ifdef CHDIR extern char orgdir[]; chdir(orgdir); @@ -724,38 +723,11 @@ Abort(long rc) } else #endif printf("\n\nAbort with alert code %08lx...\n", rc); -/* Alert(rc); this is too severe */ -#ifdef __SASC -#ifdef INTUI_NEW_LOOK - if (IntuitionBase->LibNode.lib_Version >= 37) { - struct EasyStruct es = { - sizeof(struct EasyStruct), 0, "NetHack Panic Request", - "NetHack is Aborting with code == 0x%08lx", - "Continue Abort|Return to Program|Clean up and exit", - }; - fault = EasyRequest(NULL, &es, NULL, (long) rc); - if (fault == 2) - return; - } -#endif - if (fault == 1) { - /* __emit(0x4afc); */ /* illegal instruction */ - __emit(0x40fc); /* divide by */ - __emit(0x0000); /* #0 */ - /* NOTE: don't move amii_cleanup() above here - */ - /* it is too likely to kill the system */ - /* before it can get the SnapShot out, if */ - /* there is something really wrong. */ - } -#endif #ifdef AMII_GRAPHICS if (windowprocs.win_init_nhwindows == amii_procs.win_init_nhwindows) amii_cleanup(); #endif #undef exit -#ifdef AZTEC_C - _abort(); -#endif exit((int) rc); } diff --git a/sys/amiga/winami.c b/sys/amiga/winami.c index e1276e986..c190a7c39 100644 --- a/sys/amiga/winami.c +++ b/sys/amiga/winami.c @@ -1161,17 +1161,7 @@ amii_display_file(const char *fn, boolean complain) if ((fp = dlb_fopen(fn, RDTMODE)) == (dlb *) NULL) { if (complain) { - sprintf(buf, "Can't display %s: %s", fn, -#if defined(_DCC) || defined(__GNUC__) - strerror(errno) -#else -#ifdef __SASC_60 - __sys_errlist[errno] -#else - sys_errlist[errno] -#endif -#endif - ); + sprintf(buf, "Can't display %s: %s", fn, strerror(errno)); amii_addtopl(buf); } return; diff --git a/sys/amiga/winchar.c b/sys/amiga/winchar.c index 7e17ea574..c2281c914 100644 --- a/sys/amiga/winchar.c +++ b/sys/amiga/winchar.c @@ -7,9 +7,7 @@ #include #include #include -#ifndef _DCC #include -#endif #ifdef TESTING #include "hack.h" diff --git a/sys/amiga/windefs.h b/sys/amiga/windefs.h index cb6cbd3db..617c095f1 100644 --- a/sys/amiga/windefs.h +++ b/sys/amiga/windefs.h @@ -5,9 +5,6 @@ #include #include #include -#if !defined(_DCC) && !defined(__GNUC__) -#include -#endif #include #include #include @@ -19,25 +16,10 @@ #include #include #include -/* stddef.h is included in the precompiled version of hack.h . If we include - * it here normally (through string.h) we'll get an "illegal typedef" later - * on. This is the easiest way I can think of to fix it without messing - * around with the rest of the #includes. --AMC - */ -#if defined(_DCC) && !defined(HACK_H) -#define ptrdiff_t ptrdiff_t_ -#define size_t size_t_ -#define wchar_t wchar_t_ -#endif #include #undef strcmpi #include #include -#if defined(_DCC) && !defined(HACK_H) -#undef ptrdiff_t -#undef size_t -#undef wchar_T -#endif #ifdef IDCMP_CLOSEWINDOW #ifndef INTUI_NEW_LOOK @@ -62,17 +44,6 @@ CLIPPING must be defined for the AMIGA version /*#define TOPL_GETLINE /* Don't use a window for getlin() */ /*#define WINDOW_YN /* Use a window for y/n questions */ -#ifdef AZTEC_C -#include -#else -#ifdef _DCC -#include -#include -#include -#include -#include -#include -#else #include #include #include @@ -80,28 +51,13 @@ CLIPPING must be defined for the AMIGA version #include #include #include -#endif /* kludge - see amirip for why */ #undef red #undef green #undef blue -#ifdef _DCC -#include -#else #include -#endif - -#ifdef _DCC -#define __asm /* DICE doesn't like __asm */ -#endif - -#ifdef _DCC -#include -#else #include -#endif -#endif #ifdef SHAREDLIB #include "NH:sys/amiga/lib/libmacs.h" diff --git a/sys/amiga/winfuncs.c b/sys/amiga/winfuncs.c index 788964b77..aec3939c7 100644 --- a/sys/amiga/winfuncs.c +++ b/sys/amiga/winfuncs.c @@ -252,7 +252,6 @@ struct FillParams { WORD offsety; }; -#ifdef __GNUC__ #ifdef __PPC__ void PPC_LayerFillHook(void); struct EmulLibEntry LayerFillHook = { TRAP_LIB, 0, @@ -281,16 +280,6 @@ void LayerFillHook_impl(struct Hook *hk, struct RastPort *rp, struct FillParams *fp) { -#endif -#else -void -#ifndef _DCC - __interrupt -#endif - __saveds __asm LayerFillHook(__a0 struct Hook *hk, - __a2 struct RastPort *rp, - __a1 struct FillParams *fp) -{ #endif long x, y, xmax, ymax; @@ -828,7 +817,6 @@ amii_create_nhwindow(int type) return (newid); } -#ifdef __GNUC__ #ifdef __PPC__ int PPC_SM_Filter(void); struct EmulLibEntry SM_Filter = { TRAP_LIB, 0, @@ -857,16 +845,6 @@ int SM_Filter_impl(struct Hook *hk, ULONG modeID, struct ScreenModeRequester *smr) { -#endif -#else -int -#ifndef _DCC - __interrupt -#endif - __saveds __asm SM_Filter( - __a0 struct Hook *hk, __a1 ULONG modeID, - __a2 struct ScreenModeRequester *smr) -{ #endif struct DimensionInfo dims; struct DisplayInfo disp; From 7b67da20b7105b80c71bb3ce6301f07669f9e58e Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 16:01:00 +0200 Subject: [PATCH 238/702] Amiga: make INTUI_NEW_LOOK unconditional OS 2.0+ Intuition is required; the pre-2.0 fallback paths are unreachable. --- include/winami.h | 10 +------ sys/amiga/amiwind.c | 5 +--- sys/amiga/winamenu.c | 4 --- sys/amiga/winami.c | 66 ++------------------------------------------ sys/amiga/windefs.h | 12 +------- sys/amiga/winfuncs.c | 16 ----------- sys/amiga/winreq.c | 31 +++------------------ 7 files changed, 9 insertions(+), 135 deletions(-) diff --git a/include/winami.h b/include/winami.h index 913b130c3..2b084a68c 100644 --- a/include/winami.h +++ b/include/winami.h @@ -59,16 +59,8 @@ struct amii_WinDesc { char *morestr; /* string to display instead of default */ /* amiga stuff */ struct Window *win; /* Intuition window pointer */ -#ifdef INTUI_NEW_LOOK - struct ExtNewWindow *newwin; /* NewWindow alloc'd */ -#else - struct NewWindow *newwin; /* ExtNewWindow alloc'd */ -#endif -#ifdef INTUI_NEW_LOOK + struct ExtNewWindow *newwin; /* NewWindow alloc'd */ struct TagItem wintags[MAXWINTAGS]; /* Tag items for this window */ -#else - long wintags[MAXWINTAGS * 2]; -#endif void *hook; /* Hook structure pointer for tiles version */ #define FLMAP_INGLYPH 1 /* An NHW_MAP window is in glyph mode */ #define FLMAP_CURSUP 2 /* An NHW_MAP window has the cursor displayed */ diff --git a/sys/amiga/amiwind.c b/sys/amiga/amiwind.c index beaf3cb89..fc33d9e29 100644 --- a/sys/amiga/amiwind.c +++ b/sys/amiga/amiwind.c @@ -630,7 +630,6 @@ amii_cleanup(void) * be visitors, so check close status and wait till everyone is gone. */ if (HackScreen) { -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { if (MenuStrip) FreeMenus(MenuStrip); @@ -643,9 +642,7 @@ amii_cleanup(void) }; EasyRequest(NULL, &easy, NULL, NULL); } - } else -#endif - { + } else { CloseScreen(HackScreen); } HackScreen = NULL; diff --git a/sys/amiga/winamenu.c b/sys/amiga/winamenu.c index 6d2310bc4..a6d203e65 100644 --- a/sys/amiga/winamenu.c +++ b/sys/amiga/winamenu.c @@ -271,11 +271,9 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) topidx = 0; if (w == NULL) { -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { PropScroll.Flags |= PROPNEWLOOK; } -#endif nw = (void *) DupNewWindow((void *) (&new_wins[cw->type].newwin)); if (!alwaysinvent || win != WIN_INVEN) { xsize = scrn->WBorLeft + scrn->WBorRight + MenuScroll.Width + 1 @@ -1415,11 +1413,9 @@ SetPropInfo(struct Window *win, struct Gadget *gad, long vis, long total, long t pot = 0; mflags = AUTOKNOB | FREEVERT; -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { mflags |= PROPNEWLOOK; } -#endif NewModifyProp(gad, win, NULL, mflags, 0, pot, MAXBODY, body, 1); } diff --git a/sys/amiga/winami.c b/sys/amiga/winami.c index c190a7c39..ec7548242 100644 --- a/sys/amiga/winami.c +++ b/sys/amiga/winami.c @@ -207,14 +207,12 @@ int wincnt = 0; /* # of nh windows opened */ * while they are playing... like compiling... */ -#ifdef INTUI_NEW_LOOK extern struct Hook fillhook; struct TagItem tags[] = { { WA_BackFill, (ULONG) &fillhook }, { WA_PubScreenName, (ULONG) "NetHack" }, { TAG_DONE, 0 }, }; -#endif /* * The default dimensions and status values for each window type. The @@ -230,16 +228,10 @@ struct win_setup new_wins[] = { { { 0, 1, 640, 11, 0xff, 0xff, NEWSIZE | GADGETUP | GADGETDOWN | MOUSEMOVE | MOUSEBUTTONS | RAWKEY, BORDERLESS | ACTIVATE | SMART_REFRESH -#ifdef INTUI_NEW_LOOK | WFLG_NW_EXTENDED -#endif , NULL, NULL, (UBYTE *) "Messages", NULL, NULL, 320, 40, 0xffff, 0xffff, -#ifdef INTUI_NEW_LOOK PUBLICSCREEN, tags -#else - CUSTOMSCREEN -#endif }, 0, 0, @@ -251,16 +243,10 @@ struct win_setup new_wins[] = { /* NHW_STATUS */ { { 0, 181, 640, 24, 0xff, 0xff, RAWKEY | MENUPICK | DISKINSERTED, BORDERLESS | ACTIVATE | SMART_REFRESH | BACKDROP -#ifdef INTUI_NEW_LOOK | WFLG_NW_EXTENDED -#endif , NULL, NULL, (UBYTE *) "Game Status", NULL, NULL, 0, 0, 0xffff, 0xffff, -#ifdef INTUI_NEW_LOOK PUBLICSCREEN, tags -#else - CUSTOMSCREEN -#endif }, 0, 0, @@ -273,17 +259,11 @@ struct win_setup new_wins[] = { { { 0, 0, WIDTH, WINDOWHEIGHT, 0xff, 0xff, RAWKEY | MENUPICK | MOUSEBUTTONS | ACTIVEWINDOW | MOUSEMOVE, BORDERLESS | ACTIVATE | SMART_REFRESH | BACKDROP -#ifdef INTUI_NEW_LOOK | WFLG_NW_EXTENDED -#endif , NULL, NULL, (UBYTE *) "Dungeon Map", NULL, NULL, 64, 64, 0xffff, 0xffff, -#ifdef INTUI_NEW_LOOK PUBLICSCREEN, tags -#else - CUSTOMSCREEN -#endif }, 0, 0, @@ -298,16 +278,10 @@ struct win_setup new_wins[] = { | GADGETDOWN | CLOSEWINDOW | VANILLAKEY | NEWSIZE | INACTIVEWINDOW, WINDOWSIZING | WINDOWCLOSE | WINDOWDRAG | ACTIVATE | SMART_REFRESH -#ifdef INTUI_NEW_LOOK | WFLG_NW_EXTENDED -#endif , &MenuScroll, NULL, NULL, NULL, NULL, 64, 32, 0xffff, 0xffff, -#ifdef INTUI_NEW_LOOK PUBLICSCREEN, tags -#else - CUSTOMSCREEN -#endif }, 0, 0, @@ -321,17 +295,11 @@ struct win_setup new_wins[] = { RAWKEY | MENUPICK | DISKINSERTED | MOUSEMOVE | GADGETUP | CLOSEWINDOW | VANILLAKEY | NEWSIZE, WINDOWSIZING | WINDOWCLOSE | WINDOWDRAG | ACTIVATE | SMART_REFRESH -#ifdef INTUI_NEW_LOOK | WFLG_NW_EXTENDED -#endif , &MenuScroll, NULL, (UBYTE *) NULL, NULL, NULL, 100, 32, 0xffff, 0xffff, -#ifdef INTUI_NEW_LOOK PUBLICSCREEN, tags -#else - CUSTOMSCREEN -#endif }, 0, 0, @@ -349,16 +317,10 @@ struct win_setup new_wins[] = { { { 0, 0, WIDTH, WINDOWHEIGHT, 0xff, 0xff, RAWKEY | MENUPICK | MOUSEBUTTONS, BORDERLESS | ACTIVATE | SMART_REFRESH | BACKDROP -#ifdef INTUI_NEW_LOOK | WFLG_NW_EXTENDED -#endif , NULL, NULL, (UBYTE *) NULL, NULL, NULL, -1, -1, 0xffff, 0xffff, -#ifdef INTUI_NEW_LOOK PUBLICSCREEN, tags -#else - CUSTOMSCREEN -#endif }, 0, 0, @@ -370,16 +332,10 @@ struct win_setup new_wins[] = { /* NHW_OVER */ { { 320, 20, 319, 179, 0xff, 0xff, RAWKEY | MENUPICK | MOUSEBUTTONS, BORDERLESS | ACTIVATE | SMART_REFRESH | BACKDROP -#ifdef INTUI_NEW_LOOK | WFLG_NW_EXTENDED -#endif , NULL, NULL, (UBYTE *) NULL, NULL, NULL, 64, 32, 0xffff, 0xffff, -#ifdef INTUI_NEW_LOOK PUBLICSCREEN, tags -#else - CUSTOMSCREEN -#endif }, 0, 0, @@ -394,7 +350,6 @@ const char winpanicstr[] = "Bad winid %d in %s()"; /* The opened windows information */ struct amii_WinDesc *amii_wins[MAXWIN + 1]; -#ifdef INTUI_NEW_LOOK /* * NUMDRIPENS varies based on headers, so don't use it * here, its value is used elsewhere. @@ -413,23 +368,14 @@ struct TagItem scrntags[] = { { TAG_DONE, 0 }, }; -#endif - struct NewScreen NewHackScreen = { 0, 0, WIDTH, SCREENHEIGHT, 3, 0, 1, /* DetailPen, BlockPen */ - HIRES, CUSTOMSCREEN -#ifdef INTUI_NEW_LOOK - | NS_EXTENDED -#endif - , + HIRES, CUSTOMSCREEN | NS_EXTENDED, &Hack80, /* Font */ NULL, /*(UBYTE *)" NetHack X.Y.Z" */ NULL, /* Gadgets */ NULL, /* CustomBitmap */ -#ifdef INTUI_NEW_LOOK - scrntags -#endif -}; + scrntags }; /* * plname is filled either by an option (-u Player or -uPlayer) or @@ -507,13 +453,11 @@ amii_player_selection(void) if( WINVERS_AMIV ) { -#ifdef INTUI_NEW_LOOK Type_NewWindowStructure1.Extension = wintags; Type_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED; fillhook.h_Entry = (void *) &LayerFillHook; fillhook.h_Data = (void *)-2; fillhook.h_SubEntry = 0; -#endif } Type_NewWindowStructure1.Screen = HackScreen; @@ -679,13 +623,11 @@ allocerr: if( WINVERS_AMIV ) { -#ifdef INTUI_NEW_LOOK Rnd_NewWindowStructure1.Extension = wintags; Rnd_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED; fillhook.h_Entry = (void *) &LayerFillHook; fillhook.h_Data = (void *)-2; fillhook.h_SubEntry = 0; -#endif } Rnd_NewWindowStructure1.Screen = HackScreen; @@ -1200,11 +1142,8 @@ SetBorder(struct Gadget *gd) int borders = 6; int hipen = sysflags.amii_dripens[SHINEPEN], shadowpen = sysflags.amii_dripens[SHADOWPEN]; -#ifdef INTUI_NEW_LOOK struct DrawInfo *dip; -#endif -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { if ((dip = GetScreenDrawInfo(HackScreen)) != 0) { hipen = dip->dri_Pens[SHINEPEN]; @@ -1212,7 +1151,6 @@ SetBorder(struct Gadget *gd) FreeScreenDrawInfo(HackScreen, dip); } } -#endif /* Allocate two border structures one for up image and one for down * image, plus vector arrays for the border lines. */ diff --git a/sys/amiga/windefs.h b/sys/amiga/windefs.h index 617c095f1..010b933ea 100644 --- a/sys/amiga/windefs.h +++ b/sys/amiga/windefs.h @@ -21,12 +21,6 @@ #include #include -#ifdef IDCMP_CLOSEWINDOW -#ifndef INTUI_NEW_LOOK -#define INTUI_NEW_LOOK -#endif -#endif - #ifndef HACK_H #include "hack.h" #endif @@ -63,9 +57,7 @@ CLIPPING must be defined for the AMIGA version #include "NH:sys/amiga/lib/libmacs.h" #endif -#ifdef INTUI_NEW_LOOK #include -#endif #define WINVERS_AMII (strcmp("amii", windowprocs.name) == 0) #define WINVERS_AMIV (strcmp("amiv", windowprocs.name) == 0) @@ -109,11 +101,9 @@ CLIPPING must be defined for the AMIGA version #define MAPFTHEIGHT 8 #define MAPFTBASELN 6 -/* If Compiling with the "New Look", redefine these now */ -#ifdef INTUI_NEW_LOOK +/* Use the OS 2.0+ "new look" Intuition structs unconditionally. */ #define NewWindow ExtNewWindow #define NewScreen ExtNewScreen -#endif #define SIZEOF_DISKNAME 8 diff --git a/sys/amiga/winfuncs.c b/sys/amiga/winfuncs.c index aec3939c7..26d7a0e6d 100644 --- a/sys/amiga/winfuncs.c +++ b/sys/amiga/winfuncs.c @@ -143,7 +143,6 @@ ami_wininit_data(int dir) sizeof(sysflags.amii_dripens)); } -#ifdef INTUI_NEW_LOOK struct Hook SM_FilterHook; struct Hook fillhook; struct TagItem wintags[] = { @@ -151,7 +150,6 @@ struct TagItem wintags[] = { { WA_PubScreenName, (ULONG) "NetHack" }, { TAG_END, 0 }, }; -#endif void amii_destroy_nhwindow(winid win) /* just hide */ @@ -244,7 +242,6 @@ amii_destroy_nhwindow(winid win) /* just hide */ WIN_INVEN = WIN_ERR; } -#ifdef INTUI_NEW_LOOK struct FillParams { struct Layer *layer; struct Rectangle bounds; @@ -323,7 +320,6 @@ LayerFillHook_impl(struct Hook *hk, struct RastPort *rp, SetDrMd(&rptmp, JAM2); RectFill(&rptmp, x, y, xmax, ymax); } -#endif winid amii_create_nhwindow(int type) @@ -508,12 +504,10 @@ amii_create_nhwindow(int type) if (nw->Height + stath + maph < HackScreen->Height - nw->TopEdge) nw->Height = HackScreen->Height - nw->TopEdge - 1 - maph - stath; -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { MsgPropScroll.Flags |= PROPNEWLOOK; PropScroll.Flags |= PROPNEWLOOK; } -#endif } nw->IDCMPFlags |= MENUPICK; @@ -980,7 +974,6 @@ amii_init_nhwindows(int *argcp, char **argv) /* Use Intuition sizes for overscan screens... */ amiIDisplay->xpix = 0; -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { if (wbscr = LockPubScreen("Workbench")) { amiIDisplay->xpix = wbscr->Width; @@ -988,7 +981,6 @@ amii_init_nhwindows(int *argcp, char **argv) UnlockPubScreen(NULL, wbscr); } } -#endif if (amiIDisplay->xpix == 0) { amiIDisplay->ypix = GfxBase->NormalDisplayRows; amiIDisplay->xpix = GfxBase->NormalDisplayColumns; @@ -1118,7 +1110,6 @@ amii_init_nhwindows(int *argcp, char **argv) NewHackScreen.BlockPen = C_BLACK; NewHackScreen.DetailPen = C_WHITE; #endif -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { int i; struct DimensionInfo dims; @@ -1137,11 +1128,7 @@ amii_init_nhwindows(int *argcp, char **argv) if (amii_scrnmode == 0xffffffff) { struct ScreenModeRequester *SMR; -#ifdef __GNUC__ SM_FilterHook.h_Entry = (void *) &SM_Filter; -#else - SM_FilterHook.h_Entry = (ULONG (*) ()) SM_Filter; -#endif SM_FilterHook.h_Data = 0; SM_FilterHook.h_SubEntry = 0; SMR = AllocAslRequest(ASL_ScreenModeRequest, NULL); @@ -1231,7 +1218,6 @@ amii_init_nhwindows(int *argcp, char **argv) } } } -#endif if (WINVERS_AMIV) { extern char *tilefile; @@ -1278,10 +1264,8 @@ amii_init_nhwindows(int *argcp, char **argv) else bigscreen = 0; -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) PubScreenStatus(HackScreen, 0); -#endif amiIDisplay->ypix = HackScreen->Height; amiIDisplay->xpix = HackScreen->Width; diff --git a/sys/amiga/winreq.c b/sys/amiga/winreq.c index 910adeb86..f25806f22 100644 --- a/sys/amiga/winreq.c +++ b/sys/amiga/winreq.c @@ -117,21 +117,17 @@ EditColor(void) svcolors[i] = colors[i] = GetRGB4(scrn->ViewPort.ColorMap, i); Col_NewWindowStructure1.Screen = scrn; -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { ((struct PropInfo *) Col_BluePen.SpecialInfo)->Flags |= PROPNEWLOOK; ((struct PropInfo *) Col_RedPen.SpecialInfo)->Flags |= PROPNEWLOOK; ((struct PropInfo *) Col_GreenPen.SpecialInfo)->Flags |= PROPNEWLOOK; } -#endif if (WINVERS_AMIV || WINVERS_AMII) { -#ifdef INTUI_NEW_LOOK Col_NewWindowStructure1.Extension = wintags; Col_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED; fillhook.h_Entry = (void *) &LayerFillHook; fillhook.h_Data = (void *) -2; fillhook.h_SubEntry = 0; -#endif } nw = OpenWindow((void *) &Col_NewWindowStructure1); @@ -372,22 +368,18 @@ EditClipping(void) once = 1; } ClipNewWindowStructure1.Screen = scrn; -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { ((struct PropInfo *) ClipXSIZE.SpecialInfo)->Flags |= PROPNEWLOOK; ((struct PropInfo *) ClipYSIZE.SpecialInfo)->Flags |= PROPNEWLOOK; ((struct PropInfo *) ClipXCLIP.SpecialInfo)->Flags |= PROPNEWLOOK; ((struct PropInfo *) ClipYCLIP.SpecialInfo)->Flags |= PROPNEWLOOK; } -#endif if (WINVERS_AMIV || WINVERS_AMII) { -#ifdef INTUI_NEW_LOOK ClipNewWindowStructure1.Extension = wintags; ClipNewWindowStructure1.Flags |= WFLG_NW_EXTENDED; fillhook.h_Entry = (void *) &LayerFillHook; fillhook.h_Data = (void *) -2; fillhook.h_SubEntry = 0; -#endif } nw = OpenWindow((void *) &ClipNewWindowStructure1); @@ -399,11 +391,9 @@ EditClipping(void) ShowClipValues(nw); mflags = AUTOKNOB | FREEHORIZ; -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { mflags |= PROPNEWLOOK; } -#endif for (i = 0; i < 7; ++i) { if (mxsize <= sizes[i]) @@ -582,12 +572,9 @@ filecopy(char *from, char *to) if (buf) { sprintf(buf, "c:copy \"%s\" \"%s\" clone", from, to); -/* Check SysBase instead? Shouldn't matter */ -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) i = System(buf, NULL); else -#endif Execute(buf, NULL, NULL); free(buf); } else { @@ -716,11 +703,9 @@ DrawCol(struct Window *w, int idx, UWORD *colors) b = colors[idx] & 0x00f; mflags = AUTOKNOB | FREEHORIZ; -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { mflags |= PROPNEWLOOK; } -#endif NewModifyProp(&Col_RedPen, w, NULL, mflags, (r * MAXPOT) / 15, 0, MAXPOT / 15, 0, 1); NewModifyProp(&Col_GreenPen, w, NULL, mflags, (g * MAXPOT) / 15, 0, @@ -759,7 +744,6 @@ DispCol(struct Window *w, int idx, UWORD *colors) void amii_setpens(int count) { -#ifdef INTUI_NEW_LOOK struct EasyStruct ea = { sizeof(struct EasyStruct), 0l, "NetHack Request", "Number of pens requested(%ld) not correct", "Use default pens|Use requested pens" }; @@ -768,12 +752,9 @@ amii_setpens(int count) "Number of pens requested(%ld) not\ncompatible " "with game configuration(%ld)", "Use default pens|Use requested pens" }; -#endif -/* If the pens in amii_curmap are - * more pens than in amii_numcolors, then we choose to ignore - * those pens. - */ -#ifdef INTUI_NEW_LOOK + + /* If the pens in amii_curmap are more than in amii_numcolors, ignore + * the extras. */ if (IntuitionBase && IntuitionBase->LibNode.lib_Version >= 39) { if (count != amii_numcolors) { long args[2]; @@ -791,9 +772,7 @@ amii_setpens(int count) amii_numcolors * sizeof(amii_initmap[0])); } } - } else -#endif - if (count != amii_numcolors) { + } else if (count != amii_numcolors) { memcpy(sysflags.amii_curmap, amii_initmap, amii_numcolors * sizeof(amii_initmap[0])); } @@ -849,13 +828,11 @@ getlind(const char *prompt, char *bufp, const char *dflt) } if (WINVERS_AMIV || WINVERS_AMII) { -#ifdef INTUI_NEW_LOOK StrWindow.Extension = wintags; StrWindow.Flags |= WFLG_NW_EXTENDED; fillhook.h_Entry = (void *) &LayerFillHook; fillhook.h_Data = (void *) -2; fillhook.h_SubEntry = 0; -#endif } if ((cwin = OpenWindow((void *) &StrWindow)) == NULL) { From a8e54185ebb92165b53b738c3c8e60368d55b89a Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 16:03:33 +0200 Subject: [PATCH 239/702] Amiga: drop SHAREDLIB dead build flavor --- sys/amiga/amiwind.c | 11 ----------- sys/amiga/winami.c | 3 +-- sys/amiga/windefs.h | 4 ---- sys/amiga/winext.h | 27 --------------------------- sys/amiga/winproto.h | 16 ---------------- 5 files changed, 1 insertion(+), 60 deletions(-) diff --git a/sys/amiga/amiwind.c b/sys/amiga/amiwind.c index fc33d9e29..80032deb1 100644 --- a/sys/amiga/amiwind.c +++ b/sys/amiga/amiwind.c @@ -690,13 +690,6 @@ amii_cleanup(void) IntuitionBase = NULL; } -#ifdef SHAREDLIB - if (DOSBase) { - CloseLibrary((struct Library *) DOSBase); - DOSBase = NULL; - } -#endif - ((struct Process *) FindTask(NULL))->pr_WindowPtr = (APTR) pr_WindowPtr; Initialized = 0; @@ -704,7 +697,6 @@ amii_cleanup(void) #endif /* AMII_GRAPHICS */ -#ifndef SHAREDLIB void Abort(long rc) { @@ -733,7 +725,6 @@ CleanUp(void) { amii_cleanup(); } -#endif #ifdef AMII_GRAPHICS @@ -849,7 +840,6 @@ amii_number_pad(int state) } #endif /* AMII_GRAPHICS */ -#ifndef SHAREDLIB void amiv_loadlib(void) { @@ -879,4 +869,3 @@ VA_DECL(const char *, s) VA_END(); Abort(0L); } -#endif diff --git a/sys/amiga/winami.c b/sys/amiga/winami.c index ec7548242..8e448fed5 100644 --- a/sys/amiga/winami.c +++ b/sys/amiga/winami.c @@ -159,8 +159,7 @@ unsigned short amiv_init_map[AMII_MAXCOLORS] = { 0x0fff, /* color #31 */ }; -#if !defined(TTY_GRAPHICS) \ - || defined(SHAREDLIB) /* this should be shared better */ +#ifndef TTY_GRAPHICS char morc; /* the character typed in response to a --more-- prompt */ #endif char spaces[76] = " " diff --git a/sys/amiga/windefs.h b/sys/amiga/windefs.h index 010b933ea..85a800633 100644 --- a/sys/amiga/windefs.h +++ b/sys/amiga/windefs.h @@ -53,10 +53,6 @@ CLIPPING must be defined for the AMIGA version #include #include -#ifdef SHAREDLIB -#include "NH:sys/amiga/lib/libmacs.h" -#endif - #include #define WINVERS_AMII (strcmp("amii", windowprocs.name) == 0) diff --git a/sys/amiga/winext.h b/sys/amiga/winext.h index 068593337..e3ef8ef86 100644 --- a/sys/amiga/winext.h +++ b/sys/amiga/winext.h @@ -18,7 +18,6 @@ extern int LI; extern int scrollmsg; extern int alwaysinvent; -#ifndef SHAREDLIB extern unsigned short amii_defpens[20]; extern struct amii_DisplayDesc *amiIDisplay; /* the Amiga Intuition descriptor */ @@ -33,21 +32,6 @@ extern long amii_scrnmode; extern winid amii_rawprwin; extern struct Screen *HackScreen; extern char Initialized; -/* These have already been defined elsewhere (and some are conflicting) - * ... going ... going once ... going twice .... - * extern const char *roles[]; - * extern struct Library *ConsoleDevice; - * extern char toplines[ TBUFSZ ]; - * extern NEARDATA winid WIN_MESSAGE; - * extern NEARDATA winid WIN_MAP; - * extern NEARDATA winid WIN_STATUS; - * extern NEARDATA winid WIN_INVEN; - * extern winid WIN_OVER; - * extern struct GfxBase *GfxBase; - * extern struct Library *DiskfontBase; - * extern struct IntuitionBase *IntuitionBase; - * extern struct Library *LayersBase; - */ extern int amii_msgAPen; extern int amii_msgBPen; extern int amii_statAPen; @@ -58,9 +42,6 @@ extern int amii_textAPen; extern int amii_textBPen; extern int amii_otherAPen; extern int amii_otherBPen; -#else -extern WinamiBASE *WinamiBase; -#endif /* All kinds of shared stuff */ extern struct TextAttr Hack160; extern struct TextAttr Hack40; @@ -132,17 +113,9 @@ typedef enum { extern struct PDAT pictdata; extern struct Hook fillhook; extern struct TagItem wintags[]; -#ifndef SHAREDLIB -#ifndef __GNUC__ -void __asm LayerFillHook(register __a0 struct Hook *hk, - register __a2 struct RastPort *rp, - register __a1 struct FillParams *fp); -#else #ifdef __PPC__ struct EmulLibEntry LayerFillHook; #else void LayerFillHook(void); #endif -#endif -#endif extern int mxsize, mysize; diff --git a/sys/amiga/winproto.h b/sys/amiga/winproto.h index d855e50fe..6bd486dfb 100644 --- a/sys/amiga/winproto.h +++ b/sys/amiga/winproto.h @@ -58,9 +58,7 @@ int amikbhit(void); int WindowGetchar(void); WETYPE WindowGetevent(void); void amii_cleanup(void); -#ifndef SHAREDLIB void Abort(long rc); -#endif void CleanUp(void); void flush_glyph_buffer(struct Window *w); void amiga_print_glyph(winid window, int color_index, int glyph); @@ -71,10 +69,8 @@ void FreeNewWindow(struct NewWindow *win); void bell(void); void amii_delay_output(void); void amii_number_pad(int state); -#ifndef SHAREDLIB void amiv_loadlib(void); void amii_loadlib(void); -#endif void preserve_icon(void); void clear_icon(void); @@ -114,10 +110,6 @@ BitMapHeader ReadTileImageFiles(void); void FreeTileImageFiles(void); /* winami.c */ -#ifdef SHAREDLIB -int __UserLibInit(void); -void __UserLibCleanup(void); -#endif void amii_askname(void); void amii_player_selection(void); void RandomWindow(char *name); @@ -127,15 +119,7 @@ void amii_display_file(const char *fn, boolean complain); void SetBorder(struct Gadget *gd); /* malloc/free provided by stdlib.h */ -#ifdef SHAREDLIB -/* amilib.c */ -void amii_loadlib(void); -void amiv_loadlib(void); -void CleanUp(void); -void setup_librefs(WinamiBASE *base); -#else void Abort(long rc); -#endif win_request_info *amii_ctrl_nhwindow(winid, int, win_request_info *); From 00433c799859c6e14b8a4c8d3b821bdf7e9f8b16 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 16:07:21 +0200 Subject: [PATCH 240/702] Amiga: drop TESTING dev toggle in winchar.c --- sys/amiga/winchar.c | 124 +------------------------------------------- 1 file changed, 2 insertions(+), 122 deletions(-) diff --git a/sys/amiga/winchar.c b/sys/amiga/winchar.c index c2281c914..154b559b2 100644 --- a/sys/amiga/winchar.c +++ b/sys/amiga/winchar.c @@ -9,15 +9,11 @@ #include #include -#ifdef TESTING -#include "hack.h" -#else #ifndef CROSS_TO_AMIGA #include "NH:src/tile.c" #else #include "../src/tile.c" #endif -#endif #ifndef CROSS_TO_AMIGA #include "NH:win/share/tile.h" @@ -94,85 +90,6 @@ struct PDAT pictdata; char *tilefile; struct BitMap *tileimg, *tile; -#ifdef TESTING -short pens[NUMDRIPENS] = { 8, 3, 15, 0, 15, 7, 7, 8, 0 }; -main(int argc, char **argv) -{ - BitMapHeader bmhd; - struct IntuiMessage *imsg; - long code, class; - char buf[100]; - int i, x, y, tbl, done = 0, num; - struct Window *w; - struct Screen *scr; - - bmhd = ReadTileImageFiles(); - - scr = OpenScreenTags( - NULL, SA_Depth, pictdata.nplanes + amii_extraplanes, SA_DisplayID, - DBLNTSC_MONITOR_ID | HIRESLACE_KEY, SA_Overscan, OSCAN_TEXT, SA_Top, - 0, SA_Left, 0, SA_Width, STDSCREENWIDTH, SA_Height, STDSCREENHEIGHT, - SA_Type, CUSTOMSCREEN, SA_DetailPen, 0, SA_BlockPen, 1, SA_Title, - "NetHack Chars", SA_Pens, pens, TAG_DONE); - if (scr == NULL) { - printf("no screen\n"); -#undef exit - exit(1); - } - - w = OpenWindowTags( - 0, WA_CustomScreen, scr, WA_Flags, - WFLG_DRAGBAR | WFLG_SIZEGADGET | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET, - WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS, - WA_Left, 0, WA_Top, scr->WBorTop + 1 + 13, WA_MinWidth, 100, - WA_MinHeight, 100, WA_MaxWidth, 700, WA_MaxHeight, 1000, WA_Width, - 640, WA_Height, 340, WA_SmartRefresh, TRUE, TAG_DONE); - if (w) { - while (!done) { - for (i = 0; i < NUMTILEIMAGES * IMGPAGESIZE; ++i) { - int dx, dy; - tbl = i / IMGPAGESIZE; - x = i % IMGPAGESIZE; - y = x / IMGCOLUMNS; - x = x % IMGCOLUMNS; - dx = i % (IMGCOLUMNS * 2); - dy = i / (IMGCOLUMNS * 2); - BltBitMapRastPort(tileimg, x * pictdata.xsize, - y * pictdata.ysize, w->RPort, - w->BorderLeft + 1 + dx * pictdata.xsize, - w->BorderTop + 1 + dy * pictdata.ysize, - pictdata.xsize, pictdata.ysize, 0xc0); - } - WaitPort(w->UserPort); - while (imsg = (struct IntuiMessage *) GetMsg(w->UserPort)) { - class = imsg->Class; - code = imsg->Code; - ReplyMsg((struct Message *) imsg); - switch (class) { - case IDCMP_MOUSEBUTTONS: { - x = imsg->MouseX - w->BorderLeft; - y = imsg->MouseY - w->BorderTop; - num = ((y / pictdata.ysize) * IMGCOLUMNS * 2) - + (x / pictdata.xsize); - sprintf(buf, "Char #%d", num); - SetWindowTitles(w, buf, buf); - } break; - case IDCMP_CLOSEWINDOW: - done = 1; - break; - } - } - } - CloseWindow(w); - CloseScreen(scr); - } - - FreeTileImageFiles(); - - return (0); -} -#endif - /* * Read a single BMAP IFF file into a BitMap. * Returns the BitMapHeader; *bmp receives the bitmap. @@ -327,25 +244,6 @@ MyFreeBitMap(struct BitMap *bmp) free(bm); } -#ifdef TESTING -void -panic(char *s, long a1, long a2, long a3, long a4) -{ - printf(s, a1, a2, a3, a4); - putchar('\n'); -} -long * -alloc(unsigned int x) -{ - long *p = (long *) malloc(x); - if (!p) { - panic("malloc failed"); - exit(1); - } - return p; -} -#endif - void FreeTileImageFiles(void) { @@ -353,7 +251,6 @@ FreeTileImageFiles(void) FreeImageFile(&tile); } -#ifndef TESTING /* * Define some stuff for our special glyph drawing routines */ @@ -807,17 +704,8 @@ GlyphToIcon(int glyph) return glyph; return (gi.gm.tileidx); } -#endif #ifdef AMII_GRAPHICS -#ifdef TESTING -/* - * Define some stuff for our special glyph drawing routines - */ -static unsigned short glyph_node_index, glyph_buffer_index; -#define NUMBER_GLYPH_NODES 80 -#define GLYPH_BUFFER_SIZE 512 -#endif /* TESTING */ struct amii_glyph_node { short x; @@ -864,7 +752,6 @@ int backg[AMII_MAXCOLORS] = { #define CLR_MAX 16 #endif -#ifndef TESTING /* * Begin Revamped Text display routines * @@ -1002,18 +889,14 @@ amii_lprint_glyph(winid window, int color_index, int glyph) ++glyph_node_index; } } -#endif /* !TESTING */ -#ifdef TESTING /* - * Define some variables which will be used to save context when toggling - * back and forth between low level text and console I/O. + * Variables used to save context when toggling between low level text + * and console I/O. */ static long xsave, ysave, modesave, apensave, bpensave; static int usecolor; -#endif /* TESTING */ -#ifndef TESTING /* * The function is called before any glyphs are driven to the screen. It * removes the cursor, saves internal state of the window, then returns. @@ -1050,7 +933,6 @@ amii_start_glyphout(winid window) iflags.use_color = FALSE; cw->wflags |= FLMAP_INGLYPH; } -#endif /* !TESTING */ #if 0 /* @@ -1090,7 +972,6 @@ amii_end_glyphout(window) #endif #endif -#ifndef TESTING #ifdef OPT_DISPMAP /* don't use dispmap unless x & y are 8,16,24,32,48 and equal */ void @@ -1108,4 +989,3 @@ dispmap_sanity1(int x) return !strchr((char *)valid, x); } #endif /* OPT_DISPMAP */ -#endif /* TESTING */ From e90a297021f6617b16103390065aa3607bb4013f Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 16:13:31 +0200 Subject: [PATCH 241/702] Amiga: drop #if 0 dead-code blocks Includes a dead amii_player_selection / RandomWindow pair (~280 lines), eraseall / CopyFile in amidos.c, and smaller fragments. --- sys/amiga/amidos.c | 68 ---------- sys/amiga/winamenu.c | 7 - sys/amiga/winami.c | 301 ------------------------------------------- sys/amiga/winchar.c | 56 -------- sys/amiga/winfuncs.c | 18 --- sys/amiga/winstr.c | 6 - 6 files changed, 456 deletions(-) diff --git a/sys/amiga/amidos.c b/sys/amiga/amidos.c index 47b793762..43c276dbc 100644 --- a/sys/amiga/amidos.c +++ b/sys/amiga/amidos.c @@ -256,74 +256,6 @@ filesize(char *file) return size; } -#if 0 -void -void -eraseall(const char *path, const char *files) -{ - BPTR dirLock, dirLock2; - struct FileInfoBlock *fibp; - int chklen; -#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) - if(files != g.alllevels)panic("eraseall"); -#endif - chklen=(int)index(files,'*')-(int)files; - - if (dirLock = Lock( (char *)path ,SHARED_LOCK)) { - dirLock2=DupLock(dirLock); - dirLock2= CurrentDir(dirLock2); - fibp=AllocMem(sizeof(struct FileInfoBlock),0); - if(fibp){ - if(Examine(dirLock,fibp)){ - while(ExNext(dirLock,fibp)){ - if(!strncmp(fibp->fib_FileName,files,chklen)){ - DeleteFile(fibp->fib_FileName); - } - } - } - FreeMem(fibp,sizeof(struct FileInfoBlock)); - } - UnLock(dirLock); - UnLock(CurrentDir(dirLock2)); - } -} -#endif - -/* This size makes that most files can be copied with two Read()/Write()s */ - -#if 0 /* Unused */ -#define COPYSIZE 4096 - -char *CopyFile(const char *from, const char *to) -{ - BPTR fromFile, toFile; - char *buffer; - long size; - char *error = NULL; - - buffer = (char *) alloc(COPYSIZE); - if (fromFile = Open( (char *)from, MODE_OLDFILE)) { - if (toFile = Open( (char *)to, MODE_NEWFILE)) { - while (size = Read(fromFile, buffer, (long)COPYSIZE)) { - if (size == -1){ - error = "Read error"; - break; - } - if (size != Write(toFile, buffer, size)) { - error = "Write error"; - break; - } - } - Close(toFile); - } else - error = "Cannot open destination"; - Close(fromFile); - } else - error = "Cannot open source (this should not occur)"; - free(buffer); - return error; -} -#endif #ifdef MFLOPPY /* this should be replaced */ diff --git a/sys/amiga/winamenu.c b/sys/amiga/winamenu.c index a6d203e65..5ab2d7af8 100644 --- a/sys/amiga/winamenu.c +++ b/sys/amiga/winamenu.c @@ -445,13 +445,6 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) morc = 0; oidx = -1; -#if 0 - /* Make sure there are no selections left over from last time. */ -/* XXX potential problem for preselection if this is really needed */ - for( amip = cw->menu.items; amip; amip = amip->next ) - amip->selected = 0; -#endif - DisplayData(win, topidx); /* Make the prop gadget the right size and place */ diff --git a/sys/amiga/winami.c b/sys/amiga/winami.c index 8e448fed5..97782356b 100644 --- a/sys/amiga/winami.c +++ b/sys/amiga/winami.c @@ -408,290 +408,6 @@ amii_askname(void) /* Get the player selection character */ -#if 0 /* New function at the bottom */ -void -amii_player_selection(void) -{ - struct Window *cwin; - struct IntuiMessage *imsg; - int aredone = 0; - struct Gadget *gd; - static int once = 0; - long class, code; - - amii_clear_nhwindow( WIN_BASE ); - if (validrole(flags.initrole)) - return; - else { - flags.initrole = randrole(FALSE); - return; - } -#if 0 /* Don't query the user ... instead give random character -jhsa */ - -#if 0 /* OBSOLETE */ - if( *svp.pl_character ){ - svp.pl_character[ 0 ] = toupper( svp.pl_character[ 0 ] ); - if( strchr( pl_classes, svp.pl_character[ 0 ] ) ) - return; - } -#endif - - if( !once ){ - if( bigscreen ){ - Type_NewWindowStructure1.TopEdge = - (HackScreen->Height/2) - (Type_NewWindowStructure1.Height/2); - } - for( gd = Type_NewWindowStructure1.FirstGadget; gd; - gd = gd->NextGadget ) - { - if( gd->GadgetID != 0 ) - SetBorder( gd ); - } - once = 1; - } - - if( WINVERS_AMIV ) - { - Type_NewWindowStructure1.Extension = wintags; - Type_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED; - fillhook.h_Entry = (void *) &LayerFillHook; - fillhook.h_Data = (void *)-2; - fillhook.h_SubEntry = 0; - } - - Type_NewWindowStructure1.Screen = HackScreen; - if( ( cwin = OpenShWindow( (void *)&Type_NewWindowStructure1 ) ) == NULL ) - { - return; - } -#if 0 - WindowToFront( cwin ); -#endif - - while( !aredone ) - { - WaitPort( cwin->UserPort ); - while( ( imsg = (void *) GetMsg( cwin->UserPort ) ) != NULL ) - { - class = imsg->Class; - code = imsg->Code; - gd = (struct Gadget *)imsg->IAddress; - ReplyMsg( (struct Message *)imsg ); - - switch( class ) - { - case VANILLAKEY: - if( strchr( pl_classes, toupper( code ) ) ) - { - svp.pl_character[0] = toupper( code ); - aredone = 1; - } - else if( code == ' ' || code == '\n' || code == '\r' ) - { - flags.initrole = randrole(FALSE); -#if 0 /* OBSOLETE */ - strcpy( svp.pl_character, roles[ rnd( 11 ) ] ); -#endif - aredone = 1; - amii_clear_nhwindow( WIN_BASE ); - CloseShWindow( cwin ); - RandomWindow( svp.pl_character ); - return; - } - else if( code == 'q' || code == 'Q' ) - { - CloseShWindow( cwin ); - clearlocks(); - exit_nhwindows(NULL); - nh_terminate(0); - } - else - DisplayBeep( NULL ); - break; - - case GADGETUP: - switch( gd->GadgetID ) - { - case 1: /* Random Character */ - flags.initrole = randrole(FALSE); -#if 0 /* OBSOLETE */ - strcpy( svp.pl_character, roles[ rnd( 11 ) ] ); -#endif - amii_clear_nhwindow( WIN_BASE ); - CloseShWindow( cwin ); - RandomWindow( svp.pl_character ); - return; - - default: - svp.pl_character[0] = gd->GadgetID; - break; - } - aredone = 1; - break; - - case CLOSEWINDOW: - CloseShWindow( cwin ); - clearlocks(); - exit_nhwindows(NULL); - nh_terminate(0); - break; - } - } - } - amii_clear_nhwindow( WIN_BASE ); - CloseShWindow( cwin ); -#endif /* Do not query user ... -jhsa */ -} -#endif /* Function elsewhere */ - -#if 0 /* Unused ... -jhsa */ - -#include "NH:sys/amiga/randwin.c" - -void -RandomWindow(char *name) -{ - struct MsgPort *tport; - struct timerequest *trq; - static int once = 0; - struct Gadget *gd; - struct Window *w; - struct IntuiMessage *imsg; - int ticks = 0, aredone = 0, timerdone = 0; - long mask, got; - - tport = CreateMsgPort(); - trq = (struct timerequest *)CreateIORequest( tport, sizeof( *trq ) ); - if( tport == NULL || trq == NULL ) - { -allocerr: - if( tport ) DeleteMsgPort( tport ); - if( trq ) DeleteIORequest( (struct IORequest *)trq ); - Delay( 8 * 50 ); - return; - } - - if( OpenDevice( TIMERNAME, UNIT_VBLANK, (struct IORequest *)trq, 0L ) != 0 ) - goto allocerr; - - trq->tr_node.io_Command = TR_ADDREQUEST; - trq->tr_time.tv_secs = 8; - trq->tr_time.tv_micro = 0; - - SendIO( (struct IORequest *)trq ); - - /* Place the name in the center of the screen */ - Rnd_IText5.IText = name; - Rnd_IText6.LeftEdge = Rnd_IText4.LeftEdge + - (strlen(Rnd_IText4.IText)+1)*8; - Rnd_NewWindowStructure1.Width = ( - (strlen( Rnd_IText2.IText )+1) * 8 ) + - HackScreen->WBorLeft + HackScreen->WBorRight; - Rnd_IText5.LeftEdge = (Rnd_NewWindowStructure1.Width - - (strlen(name)*8))/2; - - gd = Rnd_NewWindowStructure1.FirstGadget; - gd->LeftEdge = (Rnd_NewWindowStructure1.Width - gd->Width)/2; - /* Chose correct modifier */ - Rnd_IText6.IText = "a"; - switch( *name ) - { - case 'a': case 'e': case 'i': case 'o': - case 'u': case 'A': case 'E': case 'I': - case 'O': case 'U': - Rnd_IText6.IText = "an"; - break; - } - - if( !once ) - { - if( bigscreen ) - { - Rnd_NewWindowStructure1.TopEdge = - (HackScreen->Height/2) - (Rnd_NewWindowStructure1.Height/2); - } - for( gd = Rnd_NewWindowStructure1.FirstGadget; gd; gd = gd->NextGadget ) - { - if( gd->GadgetID != 0 ) - SetBorder( gd ); - } - Rnd_NewWindowStructure1.IDCMPFlags |= VANILLAKEY; - - once = 1; - } - - if( WINVERS_AMIV ) - { - Rnd_NewWindowStructure1.Extension = wintags; - Rnd_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED; - fillhook.h_Entry = (void *) &LayerFillHook; - fillhook.h_Data = (void *)-2; - fillhook.h_SubEntry = 0; - } - - Rnd_NewWindowStructure1.Screen = HackScreen; - if( ( w = OpenShWindow( (void *)&Rnd_NewWindowStructure1 ) ) == NULL ) - { - AbortIO( (struct IORequest *)trq ); - WaitIO( (struct IORequest *)trq ); - CloseDevice( (struct IORequest *)trq ); - DeleteIORequest( (struct IORequest *) trq ); - DeleteMsgPort( tport ); - Delay( 50 * 8 ); - return; - } - - PrintIText( w->RPort, &Rnd_IntuiTextList1, 0, 0 ); - - mask = (1L << tport->mp_SigBit)|(1L << w->UserPort->mp_SigBit); - while( !aredone ) - { - got = Wait( mask ); - if( got & (1L << tport->mp_SigBit ) ) - { - aredone = 1; - timerdone = 1; - GetMsg( tport ); - } - while( w && ( imsg = (struct IntuiMessage *) GetMsg( w->UserPort ) ) ) - { - switch( (long)imsg->Class ) - { - /* Must be up for a little while... */ - case INACTIVEWINDOW: - if( ticks >= 40 ) - aredone = 1; - break; - - case INTUITICKS: - ++ticks; - break; - - case GADGETUP: - aredone = 1; - break; - - case VANILLAKEY: - if(imsg->Code=='\n' || imsg->Code==' ' || imsg->Code=='\r') - aredone = 1; - break; - } - ReplyMsg( (struct Message *)imsg ); - } - } - - if( !timerdone ) - { - AbortIO( (struct IORequest *)trq ); - WaitIO( (struct IORequest *)trq ); - } - - CloseDevice( (struct IORequest *)trq ); - DeleteIORequest( (struct IORequest *) trq ); - DeleteMsgPort( tport ); - if(w) CloseShWindow( w ); -} -#endif /* Discarded randwin ... -jhsa */ /* this should probably not be needed (or be renamed) void @@ -992,23 +708,6 @@ amii_yn_function(const char *query, const char *resp, char def) cursor_on(WIN_MESSAGE); q = lowc(WindowGetchar()); cursor_off(WIN_MESSAGE); -#if 0 -/* fix for PL2 */ - if (q == '\020') { /* ctrl-P */ - if(!doprev) - (void) tty_doprev_message(); /* need two initially */ - (void) tty_doprev_message(); - q = (char)0; - doprev = 1; - continue; - } else if (doprev) { - tty_clear_nhwindow(WIN_MESSAGE); - cw->maxcol = cw->maxrow; - doprev = 0; - amii_addtopl(prompt); - continue; - } -#endif /*0*/ digit_ok = allow_num && isdigit(q); if (q == '\033') { if (strchr(resp, 'q')) diff --git a/sys/amiga/winchar.c b/sys/amiga/winchar.c index 154b559b2..5872e706f 100644 --- a/sys/amiga/winchar.c +++ b/sys/amiga/winchar.c @@ -732,26 +732,6 @@ int foreg[AMII_MAXCOLORS] = { int backg[AMII_MAXCOLORS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 1, 6, 5, 3, 0 }; -#if 0 -#define CLR_BLACK 0 -#define CLR_RED 1 -#define CLR_GREEN 2 -#define CLR_BROWN 3 /* on IBM, low-intensity yellow is brown */ -#define CLR_BLUE 4 -#define CLR_MAGENTA 5 -#define CLR_CYAN 6 -#define CLR_GRAY 7 /* low-intensity white */ -#define NO_COLOR 8 -#define CLR_ORANGE 9 -#define CLR_BRIGHT_GREEN 10 -#define CLR_YELLOW 11 -#define CLR_BRIGHT_BLUE 12 -#define CLR_BRIGHT_MAGENTA 13 -#define CLR_BRIGHT_CYAN 14 -#define CLR_WHITE 15 -#define CLR_MAX 16 -#endif - /* * Begin Revamped Text display routines * @@ -934,42 +914,6 @@ amii_start_glyphout(winid window) cw->wflags |= FLMAP_INGLYPH; } -#if 0 -/* - * General cleanup routine -- flushes and restores cursor - */ -void -amii_end_glyphout(window) - winid window; -{ - struct amii_WinDesc *cw; - struct Window *w; - - if( ( cw = amii_wins[ window ] ) == (struct amii_WinDesc *)NULL ) - panic("bad window id %d in amii_end_glyphout()", window ); - - if( ( cw->wflags & FLMAP_INGLYPH ) == 0 ) - return; - cw->wflags &= ~(FLMAP_INGLYPH); - - if( !(w = cw->win ) ) - panic( "bad winid %d, no window ptr set", window ); - - /* - * Clean up whatever is left in the buffer - */ - iflags.use_color = usecolor; - - /* - * Reset internal data structs - */ - SetAPen(w->RPort, apensave); - SetBPen(w->RPort, bpensave); - SetDrMd(w->RPort, modesave); - - Move(w->RPort, xsave, ysave); -} -#endif #endif #ifdef OPT_DISPMAP diff --git a/sys/amiga/winfuncs.c b/sys/amiga/winfuncs.c index 26d7a0e6d..919c63830 100644 --- a/sys/amiga/winfuncs.c +++ b/sys/amiga/winfuncs.c @@ -1106,10 +1106,6 @@ amii_init_nhwindows(int *argcp, char **argv) PATCHLEVEL); NewHackScreen.DefaultTitle = fname; } -#if 0 - NewHackScreen.BlockPen = C_BLACK; - NewHackScreen.DetailPen = C_WHITE; -#endif if (IntuitionBase->LibNode.lib_Version >= 37) { int i; struct DimensionInfo dims; @@ -1687,11 +1683,6 @@ amii_curs(winid window, int x, int y) if (WINVERS_AMIV) { if (cw->type == NHW_MAP) { if (Is_rogue_level(&u.uz)) { -#if 0 -int qqx= (x * w->RPort->TxWidth) + w->BorderLeft; -int qqy= w->BorderTop + ( (y+1) * w->RPort->TxHeight ) + 1; -printf("pos: (%d,%d)->(%d,%d)\n",x,y,qqx,qqy); -#endif SetAPen(w->RPort, C_WHITE); /* XXX should be elsewhere (was 4)*/ Move(rp, (x * w->RPort->TxWidth) + w->BorderLeft, @@ -2038,15 +2029,6 @@ amii_print_glyph(winid win, coordxy x, coordxy y, panic(winpanicstr, win, "amii_print_glyph"); } -#if 0 -{ -static int x=-1; -if(u.uz.dlevel != x){ - fprintf(stderr,"lvlchg: %d (%d)\n",u.uz.dlevel,Is_rogue_level(&u.uz)); - x = u.uz.dlevel; -} -} -#endif if (WINVERS_AMIV && !Is_rogue_level(&u.uz)) { amii_curs(win, x, y); amiga_print_glyph(win, 0, glyph); diff --git a/sys/amiga/winstr.c b/sys/amiga/winstr.c index a3801fff1..e6cfd4f45 100644 --- a/sys/amiga/winstr.c +++ b/sys/amiga/winstr.c @@ -144,12 +144,6 @@ amii_putstr(winid window, int attr, const char *str) p++; str = p; -#if 0 - if( str != ostr ) { - outsubstr( cw, "+", 1, fudge ); - cw->curx+=2; - } -#endif if (*str) amii_scrollmsg(w, cw); amii_cl_end(cw, cw->curx); From beaed3aa08a53ceb9e725b0197e86bd8ea4bde13 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 16:15:49 +0200 Subject: [PATCH 242/702] Amiga: delete the .p prototype headers amidos.p, amiwind.p, winami.p duplicated and partly contradicted winproto.h. Switch amidos.c and amigst.c to winproto.h. --- sys/amiga/amidos.c | 12 ++-------- sys/amiga/amidos.p | 43 ---------------------------------- sys/amiga/amigst.c | 12 +++------- sys/amiga/amiwind.p | 40 ------------------------------- sys/amiga/winami.p | 57 --------------------------------------------- 5 files changed, 5 insertions(+), 159 deletions(-) delete mode 100644 sys/amiga/amidos.p delete mode 100644 sys/amiga/amiwind.p delete mode 100644 sys/amiga/winami.p diff --git a/sys/amiga/amidos.c b/sys/amiga/amidos.c index 43c276dbc..475fb4824 100644 --- a/sys/amiga/amidos.c +++ b/sys/amiga/amidos.c @@ -83,16 +83,8 @@ free_nhuuid(void) } } -/* Prototypes */ -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/amiwind.p" -#include "NH:sys/amiga/winami.p" -#include "NH:sys/amiga/amidos.p" -#else -#include "amiwind.p" -#include "winami.p" -#include "amidos.p" -#endif +#include "winext.h" +#include "winproto.h" extern char Initialized; diff --git a/sys/amiga/amidos.p b/sys/amiga/amidos.p deleted file mode 100644 index 83decbc17..000000000 --- a/sys/amiga/amidos.p +++ /dev/null @@ -1,43 +0,0 @@ -/* NetHack 3.6 amidos.p $NHDT-Date: 1432512796 2015/05/25 00:13:16 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */ -/* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1992, 1993. */ -/* NetHack may be freely redistributed. See license for details. */ - -/* amidos.c */ -void flushout (void); -#ifndef getuid -int getuid (void); -#endif -#ifndef getpid -int getpid (void); -#endif -#ifndef getlogin -char *getlogin (void); -#endif -#ifndef abs -int abs(int ); -#endif -int tgetch (void); -int dosh (void); -void amiga_self_assign (void); -long freediskspace(char *); -long filesize(char *); -void eraseall(const char * , const char *); -char *CopyFile(const char * , const char *); -void copybones(int ); -void playwoRAMdisk (void); -int saveDiskPrompt(int ); -void gameDiskPrompt (void); -void append_slash(char *); -void getreturn(const char *); -#ifndef msmsg -void msmsg( const char *, ... ); -#endif -#if !defined(__SASC_60) && !defined(_DCC) && !defined(CROSS_TO_AMIGA) -int chdir(char *); -#endif -#ifndef strcmpi -int strcmpi(char * , char *); -#endif -#if !defined(memcmp) && !defined(AZTEC_C) && !defined(_DCC) && !defined(__GNUC__) -int memcmp(unsigned char * , unsigned char * , int ); -#endif diff --git a/sys/amiga/amigst.c b/sys/amiga/amigst.c index 6e6697111..c0ace8cdf 100644 --- a/sys/amiga/amigst.c +++ b/sys/amiga/amigst.c @@ -21,14 +21,8 @@ #include "winprocs.h" #include "winami.h" -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/winami.p" -#include "NH:sys/amiga/amiwind.p" -#include "NH:sys/amiga/amidos.p" -#else -#include "winami.p" -#include "amiwind.p" -#include "amidos.p" -#endif +#include "windefs.h" +#include "winext.h" +#include "winproto.h" /* end amigst.c */ diff --git a/sys/amiga/amiwind.p b/sys/amiga/amiwind.p deleted file mode 100644 index 762646dc2..000000000 --- a/sys/amiga/amiwind.p +++ /dev/null @@ -1,40 +0,0 @@ -/* NetHack 3.6 amiwind.p $NHDT-Date: 1432512795 2015/05/25 00:13:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.6 $ */ -/* Copyright (c) Gregg Wonderly, Naperville, IL, 1992, 1993 */ -/* NetHack may be freely redistributed. See license for details. */ - -/* amiwind.c */ -#ifdef INTUI_NEW_LOOK -struct Window * OpenShWindow(struct ExtNewWindow *) ; -#else -struct Window * OpenShWindow(struct NewWindow *) ; -#endif -void CloseShWindow(struct Window *); -int kbhit (void); -int amikbhit (void); -int WindowGetchar (void); -WETYPE WindowGetevent (void); -void WindowFlush (void); -void WindowPutchar(char ); -void WindowFPuts(const char *); -void WindowPuts(const char *); -void WindowPrintf( char *,... ); -void CleanUp (void); -int ConvertKey( struct IntuiMessage * ); -#ifndef SHAREDLIB -void Abort(long ); -#endif -void flush_glyph_buffer(struct Window *); -void amiga_print_glyph(winid , int , int ); -void start_glyphout(winid ); -void amii_end_glyphout(winid ); -#ifdef INTUI_NEW_LOOK -struct ExtNewWindow * DupNewWindow(struct ExtNewWindow *); -void FreeNewWindow(struct ExtNewWindow *); -#else -struct NewWindow * DupNewWindow(struct NewWindow *); -void FreeNewWindow(struct NewWindow *); -#endif -void bell (void); -void amii_delay_output (void); -void amii_number_pad(int ); -void amii_cleanup( void ); diff --git a/sys/amiga/winami.p b/sys/amiga/winami.p deleted file mode 100644 index 57b9af93c..000000000 --- a/sys/amiga/winami.p +++ /dev/null @@ -1,57 +0,0 @@ -/* NetHack 3.6 winami.p $NHDT-Date: 1433806595 2015/06/08 23:36:35 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */ -/* Copyright (c) Gregg Wonderly, Naperville, IL, 1992, 1993 */ -/* NetHack may be freely redistributed. See license for details. */ -/* winami.c */ -void amii_raw_print(const char *); -void amii_raw_print_bold(const char *); -void amii_start_menu(winid , unsigned long ); -void amii_add_menu(winid, const glyph_info *, const anything *, char, char, int, int, const char *, unsigned int); -void amii_end_menu(winid, const char *); -int amii_select_menu(winid, int, menu_item **); -void amii_update_inventory(int); -void amii_mark_synch (void); -void amii_wait_synch (void); -void amii_setclipped (void); -void amii_cliparound(int , int ); -void amii_askname (void); -void amii_player_selection (void); -void flush_output (void); -void amii_destroy_nhwindow(winid ); -int amii_create_nhwindow(int ); -void amii_init_nhwindows (void); -int amii_get_ext_cmd(void); -char amii_yn_function(const char * , const char * , char ); -void amii_addtopl(const char *); -void TextSpaces(struct RastPort * , int ); -void amii_putstr(winid , int , const char *); -void amii_putsym(winid , int , int , CHAR_P ); -void amii_clear_nhwindow(winid ); -void amii_exit_nhwindows(const char *); -int amii_nh_poskey(coordxy *, coordxy *, int *); -int amii_nhgetch (void); -void amii_get_nh_event (void); -void amii_remember_topl (void); -int amii_doprev_message (void); -void amii_display_nhwindow(winid , boolean ); -void amii_display_file(const char * , boolean ); -void amii_curs(winid , int , int ); -void amii_print_glyph(winid, coordxy, coordxy, const glyph_info *, const glyph_info *); -void DoMenuScroll(int , int ); -void DisplayData(int , int , int ); -void SetPropInfo(struct Window * , struct Gadget * , long , long , long ); -void kill_nhwindows(int ); -void amii_cl_end(struct amii_WinDesc * , int ); -void cursor_off(winid ); -void cursor_on(winid ); -void amii_getret (void); -void amii_getlin(const char * , char *); -void getlind(const char * , char * , const char *); -void amii_suspend_nhwindows(const char *); -void amii_resume_nhwindows(void); -void amii_bell(void); -void EditColor(void); -void DrawCol( struct Window *, int, UWORD * ) ; -void DispCol( struct Window *w, int idx, UWORD * ) ; -void SetBorder(struct Gadget *) ; -void port_help (void); -void dismiss_nhwindow(winid) ; From 7b559f4d02e896ca00ae14df19e70b8e51062985 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 16:40:00 +0200 Subject: [PATCH 243/702] Amiga: delete dead files and dead-macro code Delete amigst.c (empty) and amitty.c (TTY/BBS stub). Drop WINVERS_AMIT, SUPERBITMAP_MAP, EXTMENU, SHELL/dosh(), and the bbs_id reference in src/files.c. --- include/amiconf.h | 2 - src/files.c | 9 ---- sys/amiga/amidos.c | 21 -------- sys/amiga/amigst.c | 28 ---------- sys/amiga/amitty.c | 78 --------------------------- sys/amiga/winami.c | 46 ---------------- sys/amiga/windefs.h | 1 - sys/amiga/winext.h | 3 -- sys/unix/hints/include/cross-post.500 | 2 - sys/unix/hints/include/cross-pre2.500 | 8 +-- 10 files changed, 4 insertions(+), 194 deletions(-) delete mode 100644 sys/amiga/amigst.c delete mode 100644 sys/amiga/amitty.c diff --git a/include/amiconf.h b/include/amiconf.h index a362c94f8..6ce9cbae5 100644 --- a/include/amiconf.h +++ b/include/amiconf.h @@ -180,8 +180,6 @@ typedef unsigned short AMII_COLOR_TYPE; #define ANSI_DEFAULT #endif -extern int amibbs; /* BBS mode? */ - #ifdef AMII_GRAPHICS extern int amii_numcolors; void amii_setpens(int); diff --git a/src/files.c b/src/files.c index 1891ba604..16c0f32c8 100644 --- a/src/files.c +++ b/src/files.c @@ -110,10 +110,6 @@ static char fqn_filename_buffer[FQN_NUMBUF][FQN_MAX_FILENAME]; #ifdef AMIGA extern char PATH[]; /* see sys/amiga/amidos.c */ -extern char bbs_id[]; -#ifdef __SASC_60 -#include -#endif #include extern void amii_set_text_font(char *, int); @@ -1065,11 +1061,6 @@ set_savefile_name(boolean regularize_it) #if defined(MICRO) && !defined(WIN32) && !defined(MSDOS) if (strlen(gs.SAVEP) < (SAVESIZE - 1)) Strcpy(gs.SAVEF, gs.SAVEP); - else -#ifdef AMIGA - if (strlen(gs.SAVEP) + strlen(bbs_id) < (SAVESIZE - 1)) - strncat(gs.SAVEF, bbs_id, PATHLEN); -#endif { int i = strlen(gs.SAVEP); #ifdef AMIGA diff --git a/sys/amiga/amidos.c b/sys/amiga/amidos.c index 475fb4824..e7b22259a 100644 --- a/sys/amiga/amidos.c +++ b/sys/amiga/amidos.c @@ -123,27 +123,6 @@ getlogin(void) /* abs() provided by libnix/stdlib */ -#ifdef SHELL -int -dosh(void) -{ - int i = 0; - char buf[BUFSZ]; - extern struct ExecBase *SysBase; - - /* Only under 2.0 and later ROMs do we have System() */ - if (SysBase->LibNode.lib_Version >= 37 && !amibbs) { - getlin("Enter CLI Command...", buf); - if (buf[0] != '\033') - i = System(buf, NULL); - } else { - i = 0; - pline("No mysterious force prevented you from using multitasking."); - } - return i; -} -#endif /* SHELL */ - #ifdef MFLOPPY #include diff --git a/sys/amiga/amigst.c b/sys/amiga/amigst.c deleted file mode 100644 index c0ace8cdf..000000000 --- a/sys/amiga/amigst.c +++ /dev/null @@ -1,28 +0,0 @@ -/* NetHack 3.6 amigst.c $NHDT-Date: 1432512794 2015/05/25 00:13:14 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */ -/* Copyright (c) Gregg Wonderly, Naperville, IL, 1992, 1993 */ -/* NetHack may be freely redistributed. See license for details. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#undef strcmpi -#include -#include - -#include "hack.h" -#include "winprocs.h" -#include "winami.h" - -#include "windefs.h" -#include "winext.h" -#include "winproto.h" - -/* end amigst.c */ diff --git a/sys/amiga/amitty.c b/sys/amiga/amitty.c deleted file mode 100644 index e47f3b693..000000000 --- a/sys/amiga/amitty.c +++ /dev/null @@ -1,78 +0,0 @@ -/* NetHack 3.6 amitty.c $NHDT-Date: 1432512795 2015/05/25 00:13:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */ -/* Copyright (c) Kenneth Lorber, Bethesda, Maryland 1993,1996 */ -/* NetHack may be freely redistributed. See license for details. */ - -/* TTY-specific code for the Amiga - * This is still experimental. - * Still to do: - * add real termcap handling - currently requires ANSI_DEFAULT - */ - -#include "hack.h" -#include "tcap.h" -#include -#include - -void tty_change_color(void); -char *tty_get_color_string(void); - -int amibbs = 0; /* BBS mode */ -char bbs_id[80] = ""; /* BBS uid equivalent */ -long afh_in, afh_out; /* BBS mode Amiga filehandles */ - -#ifdef TTY_GRAPHICS - -void -settty(const char *s) -{ - end_screen(); - if (s) - raw_print(s); - iflags.cbreak = ON; /* this is too easy: probably wrong */ -#if 1 /* should be version>=36 */ - /* if(IsInteractive(afh_in)){ */ - SetMode(afh_in, 0); /* con mode */ -/* } */ -#endif -} -void -gettty() -{ -#if 1 /* should be VERSION >=36 */ - /* if(IsInteractive(afh_in)){ */ - SetMode(afh_in, 1); /* raw mode */ -/* } */ -#endif -} -void -setftty() -{ - iflags.cbreak = ON; /* ditto */ -} -char kill_char = 'X' - '@'; -char erase_char = '\b'; -int -tgetch(void) -{ - unsigned char x; - Read(afh_in, &x, 1); - return (x == '\r') ? '\n' : x; -} -void -get_scr_size() -{ - CO = 80; - LI = 24; -} - -#endif - -void -tty_change_color() -{ -} -char * -tty_get_color_string() -{ - return (""); -} diff --git a/sys/amiga/winami.c b/sys/amiga/winami.c index 97782356b..28f041884 100644 --- a/sys/amiga/winami.c +++ b/sys/amiga/winami.c @@ -422,11 +422,6 @@ amii_get_ext_cmd(void) menu_item *mip; anything id; struct amii_WinDesc *cw; -#ifdef EXTMENU - winid win; - int i; - char buf[256]; -#endif int colx; int bottom = 0; @@ -444,47 +439,6 @@ amii_get_ext_cmd(void) bottom = amii_msgborder(w); colx = 3; -#ifdef EXTMENU - if (iflags.extmenu) { - win = amii_create_nhwindow(NHW_MENU); - amii_start_menu(win, MENU_BEHAVE_STANDARD); - pline("#"); - amii_putstr(WIN_MESSAGE, -1, " "); - - for (i = 0; extcmdlist[i].ef_txt != NULL; ++i) { - id.a_char = *extcmdlist[i].ef_txt; - sprintf(buf, "%-10s - %s ", extcmdlist[i].ef_txt, - extcmdlist[i].ef_desc); - amii_add_menu(win, (const glyph_info *) 0, &id, - extcmdlist[i].ef_txt[0], 0, 0, NO_COLOR, - buf, MENU_ITEMFLAGS_NONE); - } - - amii_end_menu(win, (char *) 0); - sel = amii_select_menu(win, PICK_ONE, &mip); - amii_destroy_nhwindow(win); - - if (sel == 1) { - sel = mip->item.a_char; - for (i = 0; extcmdlist[i].ef_txt != NULL; ++i) { - if (sel == extcmdlist[i].ef_txt[0]) - break; - } - - /* copy in the text */ - if (extcmdlist[i].ef_txt != NULL) { - amii_clear_nhwindow(WIN_MESSAGE); - (void) put_ext_cmd((char *) extcmdlist[i].ef_txt, 0, cw, - bottom); - return (i); - } else - DisplayBeep(NULL); - } - - return (-1); - } -#endif - amii_clear_nhwindow(WIN_MESSAGE); /* Was NHW_MESSAGE */ if (scrollmsg) { pline("#"); diff --git a/sys/amiga/windefs.h b/sys/amiga/windefs.h index 85a800633..07f6da180 100644 --- a/sys/amiga/windefs.h +++ b/sys/amiga/windefs.h @@ -57,7 +57,6 @@ CLIPPING must be defined for the AMIGA version #define WINVERS_AMII (strcmp("amii", windowprocs.name) == 0) #define WINVERS_AMIV (strcmp("amiv", windowprocs.name) == 0) -#define WINVERS_AMIT (strcmp("amitty", windowprocs.name) == 0) /* cw->data[x] contains 2 characters worth of special information. These * characters are stored at the offsets as described here. diff --git a/sys/amiga/winext.h b/sys/amiga/winext.h index e3ef8ef86..02d1436a6 100644 --- a/sys/amiga/winext.h +++ b/sys/amiga/winext.h @@ -59,9 +59,6 @@ extern struct IOStdReq ConsoleIO; extern struct MsgPort *HackPort; extern int txwidth, txheight, txbaseline; -#ifdef SUPERBITMAP_MAP -extern struct BitMap amii_vbm; -#endif /* This gadget data is replicated for menu/text windows... */ extern struct PropInfo PropScroll; diff --git a/sys/unix/hints/include/cross-post.500 b/sys/unix/hints/include/cross-post.500 index 73ba215d7..51357dafb 100644 --- a/sys/unix/hints/include/cross-post.500 +++ b/sys/unix/hints/include/cross-post.500 @@ -232,10 +232,8 @@ endif # CROSS_TO_MIPS ifdef CROSS_TO_AMIGA $(TARGETPFX)amidos.o : ../sys/amiga/amidos.c $(HACK_H) -$(TARGETPFX)amigst.o : ../sys/amiga/amigst.c $(HACK_H) $(TARGETPFX)amirip.o : ../sys/amiga/amirip.c $(HACK_H) $(TARGETPFX)amistack.o : ../sys/amiga/amistack.c $(HACK_H) -$(TARGETPFX)amitty.o : ../sys/amiga/amitty.c $(HACK_H) $(TARGETPFX)amiwind.o : ../sys/amiga/amiwind.c \ ../sys/amiga/amimenu.c $(HACK_H) $(TARGETPFX)winami.o : ../sys/amiga/winami.c $(HACK_H) diff --git a/sys/unix/hints/include/cross-pre2.500 b/sys/unix/hints/include/cross-pre2.500 index 6a1331c6a..44dafac51 100644 --- a/sys/unix/hints/include/cross-pre2.500 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -511,9 +511,9 @@ endif override TARGET_LFLAGS= $(TOOLARCH) -noixemul -Wl,--allow-multiple-definition override TARGET_LIBS += $(LIBLM) VARDATND += nhtiles.bmp -override SYSSRC = ../sys/amiga/amidos.c ../sys/amiga/amigst.c \ +override SYSSRC = ../sys/amiga/amidos.c \ ../sys/amiga/amimenu.c ../sys/amiga/amirip.c \ - ../sys/amiga/amistack.c ../sys/amiga/amitty.c \ + ../sys/amiga/amistack.c \ ../sys/amiga/amiwind.c ../sys/amiga/clipwin.c \ ../sys/amiga/colorwin.c \ ../sys/amiga/winami.c ../sys/amiga/winchar.c \ @@ -522,9 +522,9 @@ override SYSSRC = ../sys/amiga/amidos.c ../sys/amiga/amigst.c \ ../sys/amiga/winstr.c ../sys/share/pcmain.c \ ../win/share/bmptiles.c ../win/share/giftiles.c \ ../win/share/tileset.c -override SYSOBJ = $(TARGETPFX)amidos.o $(TARGETPFX)amigst.o \ +override SYSOBJ = $(TARGETPFX)amidos.o \ $(TARGETPFX)amirip.o $(TARGETPFX)amistack.o \ - $(TARGETPFX)amitty.o $(TARGETPFX)amiwind.o \ + $(TARGETPFX)amiwind.o \ $(TARGETPFX)winami.o $(TARGETPFX)winchar.o \ $(TARGETPFX)winfuncs.o $(TARGETPFX)winkey.o \ $(TARGETPFX)winamenu.o $(TARGETPFX)winreq.o \ From 94a74b84d8674fad44bd32113bb1aeff7d7291ee Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 16:44:06 +0200 Subject: [PATCH 244/702] Amiga: drop OPT_DISPMAP / display_map / fast_map machinery display_map() was never integrated; no .c defines it. All OPT_DISPMAP / DISPMAP / sysflags.fast_map conditionals were unreachable. --- include/amiconf.h | 4 --- sys/amiga/amiwind.c | 3 -- sys/amiga/winchar.c | 82 +++----------------------------------------- sys/amiga/winfuncs.c | 10 +----- sys/amiga/winproto.h | 4 --- sys/amiga/winreq.c | 6 ---- 6 files changed, 5 insertions(+), 104 deletions(-) diff --git a/include/amiconf.h b/include/amiconf.h index 6ce9cbae5..4d1cb8089 100644 --- a/include/amiconf.h +++ b/include/amiconf.h @@ -154,7 +154,6 @@ extern char *gets(char *); #define MAIL /* Get mail at unexpected occasions */ #define DEFAULT_ICON "NetHack:default.icon" /* private icon */ #define AMIFLUSH /* toss typeahead (select flush in .cnf) */ -/* #define OPT_DISPMAP /* enable fast_map option */ /* new window system options */ /* WRONG - AMIGA_INTUITION should go away */ @@ -201,9 +200,6 @@ struct ami_sysflags { unsigned short amii_dripens[20]; /* DrawInfo Pens currently there are 13 in v39 */ AMII_COLOR_TYPE amii_curmap[AMII_MAXCOLORS]; /* colormap */ #endif -#ifdef OPT_DISPMAP - boolean fast_map; /* use optimized, less flexible map display */ -#endif #ifdef MFLOPPY boolean asksavedisk; #endif diff --git a/sys/amiga/amiwind.c b/sys/amiga/amiwind.c index 80032deb1..705cb88e9 100644 --- a/sys/amiga/amiwind.c +++ b/sys/amiga/amiwind.c @@ -328,9 +328,6 @@ ConvertKey(struct IntuiMessage *message) got = 0; break; } -#ifdef OPT_DISPMAP - dispmap_sanity(); -#endif if (got) { CO = (w->Width - w->BorderLeft - w->BorderRight) / mxsize; diff --git a/sys/amiga/winchar.c b/sys/amiga/winchar.c index 5872e706f..a13a378b3 100644 --- a/sys/amiga/winchar.c +++ b/sys/amiga/winchar.c @@ -27,10 +27,6 @@ #include "winproto.h" #endif -#ifdef OPT_DISPMAP -#define DISPMAP /* use display_map() from dispmap.s */ -#endif - /* NH:sys/amiga/winvchar.c */ int main(int, char **); struct BitMap *MyAllocBitMap(int, int, int, long); @@ -54,10 +50,6 @@ extern int reclip; struct BitMap *MyAllocBitMap(int xsize, int ysize, int depth, long mflags); void MyFreeBitMap(struct BitMap *bmp); -#ifdef DISPMAP -extern void display_map(struct Window *); -#endif - #ifdef TILES_IN_GLYPHMAP extern int maxmontile, maxobjtile, maxothtile; /* from tile.c */ #define MAXMONTILE maxmontile @@ -280,7 +272,6 @@ flush_glyph_buffer(struct Window *vw) void amiv_flush_glyph_buffer(struct Window *vw) { -#if !defined(DISPMAP) || defined(OPT_DISPMAP) int xsize, ysize, x, y; struct BitScaleArgs bsa; struct BitScaleArgs bsm; @@ -290,7 +281,6 @@ amiv_flush_glyph_buffer(struct Window *vw) int i, k; int scaling_needed; struct RastPort *rp = vw->RPort; -#endif /* If nothing is buffered, return before we do anything */ if (glyph_node_index == 0) @@ -299,20 +289,8 @@ amiv_flush_glyph_buffer(struct Window *vw) cursor_off(WIN_MAP); amiv_start_glyphout(WIN_MAP); -#ifdef OPT_DISPMAP - if (sysflags.fast_map) { -#endif -#ifdef DISPMAP - display_map(vw); -#endif -#ifdef OPT_DISPMAP - } else { -#endif -#if !defined(DISPMAP) || defined(OPT_DISPMAP) - /* XXX fix indent */ - /* This is a dynamic value based on this relationship. */ - scaling_needed = - (pictdata.xsize != mxsize || pictdata.ysize != mysize); + /* This is a dynamic value based on this relationship. */ + scaling_needed = (pictdata.xsize != mxsize || pictdata.ysize != mysize); /* If overview window is up, set up to render the correct scale there */ @@ -441,10 +419,6 @@ amiv_flush_glyph_buffer(struct Window *vw) MyFreeBitMap(imgbm); if (bm) MyFreeBitMap(bm); -#endif /* DISPMAP */ -#ifdef OPT_DISPMAP - } -#endif amii_end_glyphout(WIN_MAP); @@ -520,27 +494,8 @@ amiv_lprint_glyph(winid window, int color_index, int glyph) amiv_g_nodes[glyph_node_index].dsty = min(w->BorderTop + (cury * mysize), w->Height - 1); -#ifdef OPT_DISPMAP - if (sysflags.fast_map) { -#endif /* keni */ -#ifdef DISPMAP - /* display_map() needs byte-aligned destinations, and we don't - * want to - * overwrite the window border. - */ - amiv_g_nodes[glyph_node_index].dstx = - (w->BorderLeft + 8 + (curx * mxsize)) & -8; -#endif -#ifdef OPT_DISPMAP - } else { -#endif -#if !defined(DISPMAP) || defined(OPT_DISPMAP) - amiv_g_nodes[glyph_node_index].dstx = - min(w->BorderLeft + (curx * mxsize), w->Width - 1); -#endif -#ifdef OPT_DISPMAP - } -#endif + amiv_g_nodes[glyph_node_index].dstx = + min(w->BorderLeft + (curx * mxsize), w->Width - 1); amiv_g_nodes[glyph_node_index].odsty = cw->cury; amiv_g_nodes[glyph_node_index].odstx = cw->curx; amiv_g_nodes[glyph_node_index].srcx = xoff; @@ -552,17 +507,6 @@ amiv_lprint_glyph(winid window, int color_index, int glyph) int j, k, x, y, apen; struct RastPort *rp = w->RPort; x = rp->cp_x - pictdata.xsize - 3; -#ifdef OPT_DISPMAP - if (sysflags.fast_map) { -#endif -#ifdef DISPMAP - x &= -8; - if (x == 0) - x = 8; -#endif -#ifdef OPT_DISPMAP - } -#endif y = rp->cp_y - pictdata.ysize + 1; @@ -915,21 +859,3 @@ amii_start_glyphout(winid window) } #endif - -#ifdef OPT_DISPMAP -/* don't use dispmap unless x & y are 8,16,24,32,48 and equal */ -void -dispmap_sanity(void) -{ - if (mxsize != mysize || dispmap_sanity1(mxsize) - || dispmap_sanity1(mysize)) { - sysflags.fast_map = 0; - } -} -int -dispmap_sanity1(int x) -{ - static unsigned char valid[] = { 8, 16, 24, 32, 48, 0 }; - return !strchr((char *)valid, x); -} -#endif /* OPT_DISPMAP */ diff --git a/sys/amiga/winfuncs.c b/sys/amiga/winfuncs.c index 919c63830..86fed632f 100644 --- a/sys/amiga/winfuncs.c +++ b/sys/amiga/winfuncs.c @@ -136,9 +136,6 @@ ami_wininit_data(int dir) memcpy(amii_initmap, amiv_init_map, sizeof(amii_initmap)); } -#ifdef OPT_DISPMAP - dispmap_sanity(); -#endif memcpy(sysflags.amii_dripens, amii_defpens, sizeof(sysflags.amii_dripens)); } @@ -1886,12 +1883,7 @@ cursor_on(winid window) /* Save the current information */ -#ifdef DISPMAP - if (WINVERS_AMIV && cw->type == NHW_MAP && !Is_rogue_level(&u.uz)) - x = cw->cursx = (rp->cp_x & -8) + 8; - else -#endif - x = cw->cursx = rp->cp_x; + x = cw->cursx = rp->cp_x; y = cw->cursy = rp->cp_y; apen = rp->FgPen; bpen = rp->BgPen; diff --git a/sys/amiga/winproto.h b/sys/amiga/winproto.h index 6bd486dfb..51e4f26b8 100644 --- a/sys/amiga/winproto.h +++ b/sys/amiga/winproto.h @@ -129,7 +129,3 @@ void amii_outrip(winid tmpwin, int how, time_t when); /* winchar.c */ void SetMazeType(MazeType); int GlyphToIcon(int glyph); -#ifdef OPT_DISPMAP -void dispmap_sanity(void); -int dispmap_sanity1(int); -#endif diff --git a/sys/amiga/winreq.c b/sys/amiga/winreq.c index f25806f22..bf6f21974 100644 --- a/sys/amiga/winreq.c +++ b/sys/amiga/winreq.c @@ -460,9 +460,6 @@ EditClipping(void) yclipbord = aidx + 2; } ShowClipValues(nw); -#ifdef OPT_DISPMAP - dispmap_sanity(); -#endif } else if (gd->GadgetID == GADOKAY) { done = 1; okay = 1; @@ -508,9 +505,6 @@ EditClipping(void) SetBPen(nw->RPort, amii_otherBPen); SetDrMd(nw->RPort, JAM2); Text(nw->RPort, buf, strlen(buf)); -#ifdef OPT_DISPMAP - dispmap_sanity(); -#endif break; } } From 010c068861161c06eed1bcf406dea3fd64606fd2 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 16:46:28 +0200 Subject: [PATCH 245/702] Amiga: clean up amiconf.h Remove legacy compiler guards and stale extern declarations (the ami_wbench_* family, CopyFile, ami_argset, ami_mkargline, FromWBench). Drop unused AMII_*_VOLUME / DEFAULT_ICON macros and the IDCMP_CLOSEWINDOW auto-define. --- include/amiconf.h | 98 +---------------------------------------------- 1 file changed, 2 insertions(+), 96 deletions(-) diff --git a/include/amiconf.h b/include/amiconf.h index 4d1cb8089..eda8b3022 100644 --- a/include/amiconf.h +++ b/include/amiconf.h @@ -7,41 +7,17 @@ #define AMICONF_H #undef abs /* avoid using macro form of abs */ -#ifndef __SASC_60 #undef min /* this gets redefined */ #undef max /* this gets redefined */ -#endif #include /* get time_t defined before use! */ -#ifdef CROSS_TO_AMIGA #include #include #include #include #include #include -#endif - -#ifdef __SASC_60 /* since SAS can prevent re-inclusion */ -#include /* general things, including builtins */ -#include -#endif - -#ifdef AZTEC_50 -#include -#define AZTEC_C_WORKAROUND /* Bug which turns up in sounds.c. Bummer... */ -#define NO_SIGNAL /* 5.0 signal handling doesn't like SIGINT... */ -#endif - -#ifdef _DCC -#include -#define _SIZE_T -#endif - -#ifndef __GNUC__ -typedef long off_t; -#endif #define MICRO /* must be defined to allow some inclusions */ @@ -56,66 +32,30 @@ typedef long off_t; /* nhsdat sound library not used in 5.0 */ #undef DLBFILE2 -#ifndef CROSS_TO_AMIGA -#define FILENAME_CMP stricmp /* case insensitive */ -#else #define FILENAME_CMP strcmpi /* case insensitive */ -#endif - -#ifndef __SASC_60 #define O_BINARY 0 -#endif - -/* Compile in New Intuition look for 2.0 */ -#ifdef IDCMP_CLOSEWINDOW -#ifndef INTUI_NEW_LOOK -#define INTUI_NEW_LOOK 1 -#endif -#endif #define MFLOPPY /* You'll probably want this; provides assistance \ * for typical personal computer configurations \ */ -#ifndef CROSS_TO_AMIGA -#define RANDOM -#endif /* ### amidos.c ### */ extern void nethack_exit(int); -/* ### amiwbench.c ### */ - -extern void ami_wbench_init(void); -extern void ami_wbench_args(void); -extern int ami_wbench_getsave(int); -extern void ami_wbench_unlink(char *); -extern int ami_wbench_iconsize(char *); -extern void ami_wbench_iconwrite(char *); -extern int ami_wbench_badopt(const char *); -extern void ami_wbench_cleanup(void); -extern void getlind(const char *, char *, const char *); - /* ### winreq.c ### */ extern void amii_setpens(int); +extern void getlind(const char *, char *, const char *); extern void exit(int); extern void CleanUp(void); extern void Abort(long); extern int getpid(void); -extern char *CopyFile(const char *, const char *); extern int kbhit(void); extern int WindowGetchar(void); -extern void ami_argset(int *, char *[]); -extern void ami_mkargline(int *, char **[]); extern void ami_wininit_data(int); -#define FromWBench 0 /* A hint for compiler ... */ -/* extern boolean FromWBench; /* how were we run? */ -extern int ami_argc; -extern char **ami_argv; - #ifndef MICRO_H #include "micro.h" #endif @@ -125,34 +65,14 @@ extern char **ami_argv; #endif #define remove(x) unlink(x) - -/* DICE wants rewind() to return void. We want it to return int. */ -#if defined(_DCC) || defined(__GNUC__) #define rewind(f) fseek(f, 0, 0) -#endif - -#ifdef AZTEC_C -extern FILE *freopen(const char *, const char *, FILE *); -extern char *gets(char *); -#endif - -/* - * If AZTEC_C we can't use the long cpath in vision.c.... - */ -#ifdef AZTEC_C -#undef MACRO_CPATH -#endif /* * (Possibly) configurable Amiga options: */ #define HACKFONT /* Use special hack.font */ -#ifndef CROSS_TO_AMIGA /* issues with prototype and spawnl */ -#define SHELL /* Have a shell escape command (!) */ -#endif #define MAIL /* Get mail at unexpected occasions */ -#define DEFAULT_ICON "NetHack:default.icon" /* private icon */ #define AMIFLUSH /* toss typeahead (select flush in .cnf) */ /* new window system options */ @@ -170,32 +90,18 @@ typedef unsigned short AMII_COLOR_TYPE; #undef TERMLIB -#define AMII_MUFFLED_VOLUME 40 -#define AMII_SOFT_VOLUME 50 -#define AMII_OKAY_VOLUME 60 -#define AMII_LOUDER_VOLUME 80 - -#ifdef TTY_GRAPHICS -#define ANSI_DEFAULT -#endif - #ifdef AMII_GRAPHICS extern int amii_numcolors; void amii_setpens(int); #endif -/* for cmd.c: override version in micro.h */ -#ifdef __SASC_60 -#undef M -#define M(c) ((c) -128) -#endif struct ami_sysflags { char sysflagsid[10]; #ifdef AMIFLUSH boolean altmeta; /* use ALT keys as META */ boolean amiflush; /* kill typeahead */ #endif -#ifdef AMII_GRAPHICS +#ifdef AMII_GRAPHICS int numcols; unsigned short amii_dripens[20]; /* DrawInfo Pens currently there are 13 in v39 */ AMII_COLOR_TYPE amii_curmap[AMII_MAXCOLORS]; /* colormap */ From c5d8ab1985b6c9e1e3184f353ccbd196506ca5f8 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 16:49:11 +0200 Subject: [PATCH 246/702] Amiga: collapse #ifndef CROSS_TO_AMIGA include forks Every #include block had a paired NH: assign path for native builds. Only the cross-compile path is built now. --- sys/amiga/amiwind.c | 10 ---------- sys/amiga/winamenu.c | 6 ------ sys/amiga/winami.c | 10 ---------- sys/amiga/winchar.c | 11 ----------- sys/amiga/winfuncs.c | 10 ---------- sys/amiga/winkey.c | 6 ------ sys/amiga/winreq.c | 14 -------------- sys/amiga/winstr.c | 6 ------ 8 files changed, 73 deletions(-) diff --git a/sys/amiga/amiwind.c b/sys/amiga/amiwind.c index 705cb88e9..5ad6cb503 100644 --- a/sys/amiga/amiwind.c +++ b/sys/amiga/amiwind.c @@ -3,15 +3,9 @@ /* Copyright (c) Kenneth Lorber, Bethesda, Maryland 1993,1996 */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/windefs.h" -#include "NH:sys/amiga/winext.h" -#include "NH:sys/amiga/winproto.h" -#else #include "windefs.h" #include "winext.h" #include "winproto.h" -#endif /* Have to undef CLOSE as display.h and intuition.h both use it */ #undef CLOSE @@ -38,11 +32,7 @@ struct Library *GadToolsBase = NULL; struct Library *LayersBase = NULL; struct Library *AslBase = NULL; -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/amimenu.c" -#else #include "amimenu.c" -#endif /* Now our own variables */ diff --git a/sys/amiga/winamenu.c b/sys/amiga/winamenu.c index 5ab2d7af8..2c53563b8 100644 --- a/sys/amiga/winamenu.c +++ b/sys/amiga/winamenu.c @@ -3,15 +3,9 @@ */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/windefs.h" -#include "NH:sys/amiga/winext.h" -#include "NH:sys/amiga/winproto.h" -#else #include "windefs.h" #include "winext.h" #include "winproto.h" -#endif /* Start building the text for a menu */ void diff --git a/sys/amiga/winami.c b/sys/amiga/winami.c index 28f041884..f2788fbcb 100644 --- a/sys/amiga/winami.c +++ b/sys/amiga/winami.c @@ -3,15 +3,9 @@ */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/windefs.h" -#include "NH:sys/amiga/winext.h" -#include "NH:sys/amiga/winproto.h" -#else #include "windefs.h" #include "winext.h" #include "winproto.h" -#endif #include "dlb.h" @@ -402,10 +396,6 @@ amii_askname(void) } } -/* Discarded ... -jhsa -#include "NH:sys/amiga/char.c" -*/ - /* Get the player selection character */ diff --git a/sys/amiga/winchar.c b/sys/amiga/winchar.c index a13a378b3..9b29152a7 100644 --- a/sys/amiga/winchar.c +++ b/sys/amiga/winchar.c @@ -9,23 +9,12 @@ #include #include -#ifndef CROSS_TO_AMIGA -#include "NH:src/tile.c" -#else #include "../src/tile.c" -#endif -#ifndef CROSS_TO_AMIGA -#include "NH:win/share/tile.h" -#include "NH:sys/amiga/windefs.h" -#include "NH:sys/amiga/winext.h" -#include "NH:sys/amiga/winproto.h" -#else #include "tile.h" #include "windefs.h" #include "winext.h" #include "winproto.h" -#endif /* NH:sys/amiga/winvchar.c */ int main(int, char **); diff --git a/sys/amiga/winfuncs.c b/sys/amiga/winfuncs.c index 86fed632f..46abfd165 100644 --- a/sys/amiga/winfuncs.c +++ b/sys/amiga/winfuncs.c @@ -3,28 +3,18 @@ */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/windefs.h" -#include "NH:sys/amiga/winext.h" -#include "NH:sys/amiga/winproto.h" -#else #include "windefs.h" #include "winext.h" #include "winproto.h" -#endif #include "patchlevel.h" extern struct TagItem scrntags[]; -#ifndef CROSS_TO_AMIGA -extern struct Library *ConsoleDevice; -#else extern struct Device * # ifdef __CONSTLIBBASEDECL__ __CONSTLIBBASEDECL__ # endif /* __CONSTLIBBASEDECL__ */ ConsoleDevice; -#endif static BitMapHeader amii_bmhd; static void cursor_common(struct RastPort *, int, int); diff --git a/sys/amiga/winkey.c b/sys/amiga/winkey.c index f2686bfde..57e47165c 100644 --- a/sys/amiga/winkey.c +++ b/sys/amiga/winkey.c @@ -2,15 +2,9 @@ /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993. */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/windefs.h" -#include "NH:sys/amiga/winext.h" -#include "NH:sys/amiga/winproto.h" -#else #include "windefs.h" #include "winext.h" #include "winproto.h" -#endif int amii_nh_poskey(coordxy *x, coordxy *y, int *mod) diff --git a/sys/amiga/winreq.c b/sys/amiga/winreq.c index bf6f21974..76f6c1ec2 100644 --- a/sys/amiga/winreq.c +++ b/sys/amiga/winreq.c @@ -2,15 +2,9 @@ /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993. */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/windefs.h" -#include "NH:sys/amiga/winext.h" -#include "NH:sys/amiga/winproto.h" -#else #include "windefs.h" #include "winext.h" #include "winproto.h" -#endif #define GADBLUEPEN 2 #define GADREDPEN 3 @@ -45,11 +39,7 @@ struct NewWindow StrWindow = { &String, NULL, NULL, NULL, NULL, 5, 5, 0xffff, 0xffff, CUSTOMSCREEN }; -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/colorwin.c" -#else #include "colorwin.c" -#endif #define XSIZE 2 #define YSIZE 3 @@ -58,11 +48,7 @@ struct NewWindow StrWindow = { #define GADOKAY 6 #define GADCANCEL 7 -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/clipwin.c" -#else #include "clipwin.c" -#endif void ClearCol(struct Window *w); diff --git a/sys/amiga/winstr.c b/sys/amiga/winstr.c index e6cfd4f45..2f7329467 100644 --- a/sys/amiga/winstr.c +++ b/sys/amiga/winstr.c @@ -2,15 +2,9 @@ /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993. */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/windefs.h" -#include "NH:sys/amiga/winext.h" -#include "NH:sys/amiga/winproto.h" -#else #include "windefs.h" #include "winext.h" #include "winproto.h" -#endif /* Put a string into the indicated window using the indicated attribute */ void From df9673c96e444773449b1424a13229368734d385 Mon Sep 17 00:00:00 2001 From: nhkeni Date: Mon, 11 May 2026 14:46:06 -0400 Subject: [PATCH 247/702] Make all top-level .md files subject to nhsub substitutions. --- .gitattributes | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitattributes b/.gitattributes index 4abc1c90b..7ea33e5c1 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,6 +2,7 @@ *.cpp NHSUBST *.sh NHSUBST *.pl NHSUBST +*.md NHSUBST Porting NHSUBST README NHSUBST * text=auto From 688f9344cd1254cccf132ccfb1d73b95164989f3 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 17:00:47 +0200 Subject: [PATCH 248/702] Amiga: route port paths through fqname() Tile loading hard-coded "NetHack:tiles/tiles{16,32}.iff" and PORT_HELP hard-coded "nethack:amii.hlp". Route through fqname(DATAPREFIX) so DATADIR= overrides apply. Refresh amii.hlp to 5.0 content, ship it via amigapkg, and document HACKDIR / SAVEDIR / BONESDIR examples in nethack.cnf. --- include/amiconf.h | 2 +- sys/amiga/amii.hlp | 82 +++++++++++++++++++-------- sys/amiga/amiwind.c | 10 ++-- sys/amiga/nethack.cnf | 14 +++++ sys/amiga/windefs.h | 1 - sys/amiga/winfuncs.c | 16 +++--- sys/unix/hints/include/cross-post.500 | 1 + 7 files changed, 88 insertions(+), 38 deletions(-) diff --git a/include/amiconf.h b/include/amiconf.h index eda8b3022..47306f9d2 100644 --- a/include/amiconf.h +++ b/include/amiconf.h @@ -86,7 +86,7 @@ extern void ami_wininit_data(int); #define AMII_MAXCOLORS (1L << DEPTH) typedef unsigned short AMII_COLOR_TYPE; -#define PORT_HELP "nethack:amii.hlp" +#define PORT_HELP "amii.hlp" #undef TERMLIB diff --git a/sys/amiga/amii.hlp b/sys/amiga/amii.hlp index 88716f05e..13d59ffc6 100644 --- a/sys/amiga/amii.hlp +++ b/sys/amiga/amii.hlp @@ -1,31 +1,63 @@ - Amiga-specific help file for NetHack 3.6 + Amiga-specific help for NetHack 5.0 -The Amiga port of NetHack supports a number of additional commands -and facilities specific to the Amiga. Listed below are the things -which are either specific to the Amiga port or might not appear -in other ports. -While playing NetHack you can press: +Special key combinations +------------------------ + ALT-HELP Edit the screen colour palette. + CTL-HELP Set tile scaling and clipping (amiv only). + SHIFT-HELP Toggle the dungeon overview window (amiv only). - ALT-HELP Color requestor. - CTL-HELP Scale display (amitile only). - SHIFT-HELP Overview window (amitile only). -Amiga-specific run-time options: - altmeta use the alt keys as meta keys - flush throw away keyboard type-ahead +Command-line flags +------------------ + -L Force interlaced (tall) screen. + -l Force non-interlaced screen. -Command line options recognized are +The usual core flags (-D, -X, -u, -p, -r, -@) apply too. - -n No News at game startup. - -X Play in discovery mode. - -D Play in debug mode. - -L Interlaced screen. - -l Never Interlaced screen. - -u Play as player given as - an argument. - -r Pick a race given as an - argument. - -p Pick a profession given - as an argument - -? Gives command line usage. + +Configuration (nethack.cnf in the NetHack: drawer) +-------------------------------------------------- +Window backend selection: + + OPTIONS=windowtype:amiv tile graphics (default) + OPTIONS=windowtype:amii text/character mode + +Amiga-specific runtime options: + + OPTIONS=altmeta ALT+letter sends META+letter (default on). + Disable with !altmeta if your keymap needs + ALT for typing accented characters. + OPTIONS=flush drop any keys queued during long operations + OPTIONS=asksavedisk prompt for a save-disk before saving + (MFLOPPY only) + + +File-location overrides +----------------------- +NetHack: is automatically assigned to the directory the executable was +launched from. All game files default to that volume. Override any of +these in nethack.cnf to relocate parts of the game state: + + HACKDIR=NetHack: program / shared data + LEVELDIR=NetHack: per-level files during play + SAVEDIR=NetHack:save/ save files + BONESDIR=NetHack:bones/ bones files (shared between games) + DATADIR=NetHack: nhdat and other data files + SCOREDIR=NetHack: record / logfile + LOCKDIR=NetHack: lock files + CONFIGDIR=NetHack: per-user config + +You can also override the install path entirely without editing the cnf +by setting the NETHACKDIR or HACKDIR shell environment variable before +launching: + + setenv NETHACKDIR Work:games/nethack-dev/ + Work:games/nethack-dev/nethack + + +Display fallback +---------------- +Tile mode (amiv) requires at least 16 colours and ~384 KB free chip +RAM. If neither is available the game falls back to text mode (amii) +at startup with a one-line note. diff --git a/sys/amiga/amiwind.c b/sys/amiga/amiwind.c index 5ad6cb503..7cb1dcc88 100644 --- a/sys/amiga/amiwind.c +++ b/sys/amiga/amiwind.c @@ -59,15 +59,17 @@ struct TextFont *TextsFont = NULL; struct TextFont *HackFont = NULL; struct TextFont *RogueFont = NULL; -UBYTE FontName[] = "NetHack:hack.font"; -/* # chars in "NetHack:": */ -#define SIZEOF_DISKNAME 8 +/* hack.font is registered via NetHack:hack.font (which references + * NetHack:hack/8). OpenFont()/SetFont() take the bare name; only + * OpenDiskFont() needs the full path. */ +UBYTE HackFontName[] = "hack.font"; +UBYTE HackFontPath[] = "NetHack:hack.font"; #endif struct TextAttr Hack80 = { #ifdef HACKFONT - &FontName[SIZEOF_DISKNAME], + HackFontName, #else (UBYTE *) "topaz.font", #endif diff --git a/sys/amiga/nethack.cnf b/sys/amiga/nethack.cnf index 95952d6a6..b9083d935 100644 --- a/sys/amiga/nethack.cnf +++ b/sys/amiga/nethack.cnf @@ -47,3 +47,17 @@ MENUCOLOR="gray dragon scale"=cyan MENUCOLOR="speed boots"=magenta MENUCOLOR="luckstone"=green MENUCOLOR="unicorn horn"=green + +# *** FILE LOCATIONS *** +# NetHack: is auto-assigned to the directory the binary was launched +# from, so all game files default there. Uncomment any of these to +# relocate part of the game state to a different volume or subdir. +# +#HACKDIR=NetHack: +#LEVELDIR=NetHack: +#SAVEDIR=NetHack:save/ +#BONESDIR=NetHack:bones/ +#DATADIR=NetHack: +#SCOREDIR=NetHack: +#LOCKDIR=NetHack: +#CONFIGDIR=NetHack: diff --git a/sys/amiga/windefs.h b/sys/amiga/windefs.h index 07f6da180..3cd04ee5d 100644 --- a/sys/amiga/windefs.h +++ b/sys/amiga/windefs.h @@ -100,7 +100,6 @@ CLIPPING must be defined for the AMIGA version #define NewWindow ExtNewWindow #define NewScreen ExtNewScreen -#define SIZEOF_DISKNAME 8 #define CSI '\x9b' #define NO_CHAR -1 diff --git a/sys/amiga/winfuncs.c b/sys/amiga/winfuncs.c index 46abfd165..5ccb16313 100644 --- a/sys/amiga/winfuncs.c +++ b/sys/amiga/winfuncs.c @@ -1012,9 +1012,11 @@ amii_init_nhwindows(int *argcp, char **argv) */ if (DiskfontBase = OpenLibrary("diskfont.library", amii_libvers)) { - Hack80.ta_Name -= SIZEOF_DISKNAME; + extern UBYTE HackFontName[], HackFontPath[]; + + Hack80.ta_Name = HackFontPath; HackFont = OpenDiskFont(&Hack80); - Hack80.ta_Name += SIZEOF_DISKNAME; + Hack80.ta_Name = HackFontName; /* Textsfont13 is filled in with "FONT=" settings. The default is * courier/13. @@ -1025,9 +1027,9 @@ amii_init_nhwindows(int *argcp, char **argv) /* Try hack/8 for texts if no user specified font */ if (TextsFont == NULL) { - Hack80.ta_Name -= SIZEOF_DISKNAME; + Hack80.ta_Name = HackFontPath; TextsFont = OpenDiskFont(&Hack80); - Hack80.ta_Name += SIZEOF_DISKNAME; + Hack80.ta_Name = HackFontName; } /* If no fonts, make everything topaz 8 for non-view windows. @@ -1205,10 +1207,10 @@ amii_init_nhwindows(int *argcp, char **argv) if (WINVERS_AMIV) { extern char *tilefile; if (amii_numcolors >= 32) { - tilefile = "NetHack:tiles/tiles32.iff"; + tilefile = (char *) fqname("tiles/tiles32.iff", DATAPREFIX, 0); amii_numcolors = 32; } else { - tilefile = "NetHack:tiles/tiles16.iff"; + tilefile = (char *) fqname("tiles/tiles16.iff", DATAPREFIX, 0); } amii_bmhd = ReadTileImageFiles(); } else @@ -1967,7 +1969,7 @@ removetopl(int cnt) void port_help(void) { - display_file(PORT_HELP, 1); + display_file(fqname(PORT_HELP, DATAPREFIX, 0), 1); } #endif diff --git a/sys/unix/hints/include/cross-post.500 b/sys/unix/hints/include/cross-post.500 index 51357dafb..42e562690 100644 --- a/sys/unix/hints/include/cross-post.500 +++ b/sys/unix/hints/include/cross-post.500 @@ -321,6 +321,7 @@ amigapkg: $(AMITILES) ../util/uudecode ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/amifont.uu ) cp $(AMISRC)/nethack.cnf $(TARGETPFX)pkg/NetHack/nethack.cnf cp $(AMISRC)/README.amiga $(TARGETPFX)pkg/NetHack/README.amiga + cp $(AMISRC)/amii.hlp $(TARGETPFX)pkg/NetHack/amii.hlp ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/NHinfo.uu ) ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/cnf-info.uu ) ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/license-info.uu ) From 5d86dfccb5b23ecea299515728ecf5d831ac82ef Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 17:05:13 +0200 Subject: [PATCH 249/702] Amiga: replace WINVERS_AMI* strcmp with WINDOWPORT() id compare The macros were strcmp("amiv", windowprocs.name)==0 at every reference -- 72 sites including inner loops. Use the 5.0 core's WINDOWPORT(wn) which compares wp_id. --- sys/amiga/windefs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/amiga/windefs.h b/sys/amiga/windefs.h index 3cd04ee5d..234d213a8 100644 --- a/sys/amiga/windefs.h +++ b/sys/amiga/windefs.h @@ -55,8 +55,8 @@ CLIPPING must be defined for the AMIGA version #include -#define WINVERS_AMII (strcmp("amii", windowprocs.name) == 0) -#define WINVERS_AMIV (strcmp("amiv", windowprocs.name) == 0) +#define WINVERS_AMII WINDOWPORT(amii) +#define WINVERS_AMIV WINDOWPORT(amiv) /* cw->data[x] contains 2 characters worth of special information. These * characters are stored at the offsets as described here. From c85a8cf60731b0e45b4a6a17a5a00b80ae195e38 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 17:07:28 +0200 Subject: [PATCH 250/702] Amiga: drop redundant 'either windowtype' guards Six if(WINVERS_AMIV || WINVERS_AMII) sites are always true with amitty.c gone. --- sys/amiga/winamenu.c | 32 ++++++++++++++------------------ sys/amiga/winfuncs.c | 41 +++++++++++++++++++---------------------- sys/amiga/winreq.c | 36 +++++++++++++++--------------------- 3 files changed, 48 insertions(+), 61 deletions(-) diff --git a/sys/amiga/winamenu.c b/sys/amiga/winamenu.c index 2c53563b8..828ccb4b7 100644 --- a/sys/amiga/winamenu.c +++ b/sys/amiga/winamenu.c @@ -360,10 +360,8 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) } nw->Height = min(ysize, amiIDisplay->ypix - nw->TopEdge); - if (WINVERS_AMIV || WINVERS_AMII) { - /* Make sure we are using the correct hook structure */ - nw->Extension = cw->wintags; - } + /* Make sure we are using the correct hook structure */ + nw->Extension = cw->wintags; /* Now, open the window */ w = cw->win = OpenShWindow((void *) nw); @@ -535,21 +533,19 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) * amii_cl_end if window shrinks and columns decrease. */ - if (WINVERS_AMII || WINVERS_AMIV) { - amii_setfillpens(w, cw->type); - SetDrMd(w->RPort, JAM2); - x2 = w->Width - w->BorderRight; - y2 = w->Height - w->BorderBottom; - x1 = x2 - w->IFont->tf_XSize - w->IFont->tf_XSize; - y1 = w->BorderTop; - if (x1 < w->BorderLeft) - x1 = w->BorderLeft; - RectFill(w->RPort, x1, y1, x2, y2); + amii_setfillpens(w, cw->type); + SetDrMd(w->RPort, JAM2); + x2 = w->Width - w->BorderRight; + y2 = w->Height - w->BorderBottom; + x1 = x2 - w->IFont->tf_XSize - w->IFont->tf_XSize; + y1 = w->BorderTop; + if (x1 < w->BorderLeft) x1 = w->BorderLeft; - y1 = y1 - w->IFont->tf_YSize; - RectFill(w->RPort, x1, y1, x2, y2); - RefreshWindowFrame(w); - } + RectFill(w->RPort, x1, y1, x2, y2); + x1 = w->BorderLeft; + y1 = y1 - w->IFont->tf_YSize; + RectFill(w->RPort, x1, y1, x2, y2); + RefreshWindowFrame(w); /* Make the prop gadget the right size and place */ diff --git a/sys/amiga/winfuncs.c b/sys/amiga/winfuncs.c index 5ccb16313..d22b95c53 100644 --- a/sys/amiga/winfuncs.c +++ b/sys/amiga/winfuncs.c @@ -538,29 +538,26 @@ amii_create_nhwindow(int type) wd = (struct amii_WinDesc *) alloc(sizeof(struct amii_WinDesc)); memset(wd, 0, sizeof(struct amii_WinDesc)); - /* Both, since user may have changed the pen settings so respect those */ - if (WINVERS_AMII || WINVERS_AMIV) { - /* Special backfill for these types of layers */ - switch (type) { - case NHW_MESSAGE: - case NHW_STATUS: - case NHW_TEXT: - case NHW_MENU: - case NHW_BASE: - case NHW_OVER: - case NHW_MAP: - if (wd) { - fillhook.h_Entry = (void *) &LayerFillHook; - fillhook.h_Data = (void *) type; - fillhook.h_SubEntry = 0; - wd->hook = alloc(sizeof(fillhook)); - memcpy(wd->hook, &fillhook, sizeof(fillhook)); - memcpy(wd->wintags, wintags, sizeof(wd->wintags)); - wd->wintags[0].ti_Data = (long) wd->hook; - nw->Extension = (void *) wd->wintags; - } - break; + /* Special backfill for these types of layers */ + switch (type) { + case NHW_MESSAGE: + case NHW_STATUS: + case NHW_TEXT: + case NHW_MENU: + case NHW_BASE: + case NHW_OVER: + case NHW_MAP: + if (wd) { + fillhook.h_Entry = (void *) &LayerFillHook; + fillhook.h_Data = (void *) type; + fillhook.h_SubEntry = 0; + wd->hook = alloc(sizeof(fillhook)); + memcpy(wd->hook, &fillhook, sizeof(fillhook)); + memcpy(wd->wintags, wintags, sizeof(wd->wintags)); + wd->wintags[0].ti_Data = (long) wd->hook; + nw->Extension = (void *) wd->wintags; } + break; } /* Don't open MENU or TEXT windows yet */ diff --git a/sys/amiga/winreq.c b/sys/amiga/winreq.c index 76f6c1ec2..d4a1bc362 100644 --- a/sys/amiga/winreq.c +++ b/sys/amiga/winreq.c @@ -108,13 +108,11 @@ EditColor(void) ((struct PropInfo *) Col_RedPen.SpecialInfo)->Flags |= PROPNEWLOOK; ((struct PropInfo *) Col_GreenPen.SpecialInfo)->Flags |= PROPNEWLOOK; } - if (WINVERS_AMIV || WINVERS_AMII) { - Col_NewWindowStructure1.Extension = wintags; - Col_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED; - fillhook.h_Entry = (void *) &LayerFillHook; - fillhook.h_Data = (void *) -2; - fillhook.h_SubEntry = 0; - } + Col_NewWindowStructure1.Extension = wintags; + Col_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED; + fillhook.h_Entry = (void *) &LayerFillHook; + fillhook.h_Data = (void *) -2; + fillhook.h_SubEntry = 0; nw = OpenWindow((void *) &Col_NewWindowStructure1); @@ -360,13 +358,11 @@ EditClipping(void) ((struct PropInfo *) ClipXCLIP.SpecialInfo)->Flags |= PROPNEWLOOK; ((struct PropInfo *) ClipYCLIP.SpecialInfo)->Flags |= PROPNEWLOOK; } - if (WINVERS_AMIV || WINVERS_AMII) { - ClipNewWindowStructure1.Extension = wintags; - ClipNewWindowStructure1.Flags |= WFLG_NW_EXTENDED; - fillhook.h_Entry = (void *) &LayerFillHook; - fillhook.h_Data = (void *) -2; - fillhook.h_SubEntry = 0; - } + ClipNewWindowStructure1.Extension = wintags; + ClipNewWindowStructure1.Flags |= WFLG_NW_EXTENDED; + fillhook.h_Entry = (void *) &LayerFillHook; + fillhook.h_Data = (void *) -2; + fillhook.h_SubEntry = 0; nw = OpenWindow((void *) &ClipNewWindowStructure1); @@ -807,13 +803,11 @@ getlind(const char *prompt, char *bufp, const char *dflt) once = 1; } - if (WINVERS_AMIV || WINVERS_AMII) { - StrWindow.Extension = wintags; - StrWindow.Flags |= WFLG_NW_EXTENDED; - fillhook.h_Entry = (void *) &LayerFillHook; - fillhook.h_Data = (void *) -2; - fillhook.h_SubEntry = 0; - } + StrWindow.Extension = wintags; + StrWindow.Flags |= WFLG_NW_EXTENDED; + fillhook.h_Entry = (void *) &LayerFillHook; + fillhook.h_Data = (void *) -2; + fillhook.h_SubEntry = 0; if ((cwin = OpenWindow((void *) &StrWindow)) == NULL) { return; From 8dbbbc2fefeffa7a4bfa44d9b98c686ba6225aa5 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 17:09:18 +0200 Subject: [PATCH 251/702] Amiga: deduplicate amii_procs and amiv_procs Factor common body into AMI_WIN_PROCS_BODY. The POSITIONBAR / CLIPPING / CHANGE_COLOR guards in the original were dead. --- sys/amiga/winami.c | 97 +++++++++++++--------------------------------- 1 file changed, 28 insertions(+), 69 deletions(-) diff --git a/sys/amiga/winami.c b/sys/amiga/winami.c index f2788fbcb..19a660e42 100644 --- a/sys/amiga/winami.c +++ b/sys/amiga/winami.c @@ -32,76 +32,35 @@ long amii_scrnmode; /* Interface definition, for use by windows.c and winprocs.h to provide * the intuition interface for the amiga... */ -struct window_procs amii_procs = { - WPID(amii), - WC_COLOR | WC_HILITE_PET | WC_INVERSE, - 0L, - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */ - amii_init_nhwindows, - amii_player_selection, amii_askname, amii_get_nh_event, - amii_exit_nhwindows, amii_suspend_nhwindows, amii_resume_nhwindows, - amii_create_nhwindow, amii_clear_nhwindow, amii_display_nhwindow, - amii_destroy_nhwindow, amii_curs, amii_putstr, genl_putmixed, - amii_display_file, amii_start_menu, amii_add_menu, amii_end_menu, - amii_select_menu, genl_message_menu, - amii_mark_synch, amii_wait_synch, -#ifdef CLIPPING - amii_cliparound, -#endif -#ifdef POSITIONBAR - donull, -#endif - amii_print_glyph, amii_raw_print, amii_raw_print_bold, amii_nhgetch, - amii_nh_poskey, amii_bell, amii_doprev_message, amii_yn_function, - amii_getlin, amii_get_ext_cmd, amii_number_pad, amii_delay_output, -#ifdef CHANGE_COLOR /* only a Mac option currently */ - amii_change_color, amii_get_color_string, -#endif - amii_outrip, genl_preference_update, - genl_getmsghistory, genl_putmsghistory, - genl_status_init, genl_status_finish, genl_status_enablefield, - genl_status_update, - genl_can_suspend_yes, - amii_update_inventory, - amii_ctrl_nhwindow, -}; +/* Both windowports share the same function table -- the AMII (text) / + * AMIV (tile) split happens at runtime based on WINVERS_AMIV checks. */ +#define AMI_WIN_PROCS_BODY \ + WC_COLOR | WC_HILITE_PET | WC_INVERSE, \ + 0L, \ + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* has_color */ \ + amii_init_nhwindows, \ + amii_player_selection, amii_askname, amii_get_nh_event, \ + amii_exit_nhwindows, amii_suspend_nhwindows, amii_resume_nhwindows, \ + amii_create_nhwindow, amii_clear_nhwindow, amii_display_nhwindow, \ + amii_destroy_nhwindow, amii_curs, amii_putstr, genl_putmixed, \ + amii_display_file, amii_start_menu, amii_add_menu, amii_end_menu, \ + amii_select_menu, genl_message_menu, \ + amii_mark_synch, amii_wait_synch, \ + amii_cliparound, \ + amii_print_glyph, amii_raw_print, amii_raw_print_bold, amii_nhgetch,\ + amii_nh_poskey, amii_bell, amii_doprev_message, amii_yn_function, \ + amii_getlin, amii_get_ext_cmd, amii_number_pad, amii_delay_output, \ + amii_change_color, amii_get_color_string, \ + amii_outrip, genl_preference_update, \ + genl_getmsghistory, genl_putmsghistory, \ + genl_status_init, genl_status_finish, genl_status_enablefield, \ + genl_status_update, \ + genl_can_suspend_yes, \ + amii_update_inventory, \ + amii_ctrl_nhwindow -/* The view window layout uses the same function names so we can use - * a shared library to allow the executable to be smaller. - */ -struct window_procs amiv_procs = { - WPID(amiv), - WC_COLOR | WC_HILITE_PET | WC_INVERSE, - 0L, - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */ - amii_init_nhwindows, - amii_player_selection, amii_askname, amii_get_nh_event, - amii_exit_nhwindows, amii_suspend_nhwindows, amii_resume_nhwindows, - amii_create_nhwindow, amii_clear_nhwindow, amii_display_nhwindow, - amii_destroy_nhwindow, amii_curs, amii_putstr, genl_putmixed, - amii_display_file, amii_start_menu, amii_add_menu, amii_end_menu, - amii_select_menu, genl_message_menu, - amii_mark_synch, amii_wait_synch, -#ifdef CLIPPING - amii_cliparound, -#endif -#ifdef POSITIONBAR - donull, -#endif - amii_print_glyph, amii_raw_print, amii_raw_print_bold, amii_nhgetch, - amii_nh_poskey, amii_bell, amii_doprev_message, amii_yn_function, - amii_getlin, amii_get_ext_cmd, amii_number_pad, amii_delay_output, -#ifdef CHANGE_COLOR /* only a Mac option currently */ - amii_change_color, amii_get_color_string, -#endif - amii_outrip, genl_preference_update, - genl_getmsghistory, genl_putmsghistory, - genl_status_init, genl_status_finish, genl_status_enablefield, - genl_status_update, - genl_can_suspend_yes, - amii_update_inventory, - amii_ctrl_nhwindow, -}; +struct window_procs amii_procs = { WPID(amii), AMI_WIN_PROCS_BODY }; +struct window_procs amiv_procs = { WPID(amiv), AMI_WIN_PROCS_BODY }; unsigned short amii_initmap[AMII_MAXCOLORS]; /* Default pens used unless user overides in nethack.cnf. */ From 344063afb6a0ce09d777b7b8f688fe16c0942179 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 17:14:10 +0200 Subject: [PATCH 252/702] Amiga: route non-menu messages from DoMenuScroll to ProcessMessage DoMenuScroll dropped IDCMP messages for non-owner windows -- so a resize of WIN_INVEN or close-gadget on WIN_OVER during a menu never reached the game state. Forward those to ProcessMessage; VANILLAKEY/RAWKEY stay with the menu. --- sys/amiga/amiwind.c | 4 ++-- sys/amiga/winamenu.c | 8 +++++--- sys/amiga/winproto.h | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/sys/amiga/amiwind.c b/sys/amiga/amiwind.c index 7cb1dcc88..d259d5128 100644 --- a/sys/amiga/amiwind.c +++ b/sys/amiga/amiwind.c @@ -17,7 +17,7 @@ static struct Message *GetFMsg(struct MsgPort *); #endif static int BufferGetchar(void); -static void ProcessMessage(struct IntuiMessage *message); +void ProcessMessage(struct IntuiMessage *message); #define BufferQueueChar(ch) (KbdBuffer[KbdBuffered++] = (ch)) @@ -354,7 +354,7 @@ ConvertKey(struct IntuiMessage *message) * ahead of input demands, when the user types ahead. */ -static void +void ProcessMessage(struct IntuiMessage *message) { int c; diff --git a/sys/amiga/winamenu.c b/sys/amiga/winamenu.c index 828ccb4b7..19d439563 100644 --- a/sys/amiga/winamenu.c +++ b/sys/amiga/winamenu.c @@ -463,11 +463,13 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) mx = imsg->MouseX; my = imsg->MouseY; - /* Only do our window or VANILLAKEY from other windows */ - + /* Only do our window or VANILLAKEY from other windows. + * Background events (NEWSIZE on inventory, CLOSEWINDOW + * on overview, etc.) get routed to the main dispatcher + * so the game stays in sync. ProcessMessage ReplyMsgs. */ if (imsg->IDCMPWindow != w && class != VANILLAKEY && class != RAWKEY) { - ReplyMsg((struct Message *) imsg); + ProcessMessage(imsg); continue; } diff --git a/sys/amiga/winproto.h b/sys/amiga/winproto.h index 51e4f26b8..831db69a3 100644 --- a/sys/amiga/winproto.h +++ b/sys/amiga/winproto.h @@ -53,6 +53,7 @@ void SetPropInfo(struct Window *win, struct Gadget *gad, long vis, long total, struct Window *OpenShWindow(struct NewWindow *nw); void CloseShWindow(struct Window *win); int ConvertKey(struct IntuiMessage *message); +void ProcessMessage(struct IntuiMessage *message); int kbhit(void); int amikbhit(void); int WindowGetchar(void); From 2e61bf768f05316cf70c7e9e91883c08734aad66 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 17:34:03 +0200 Subject: [PATCH 253/702] Amiga: fix port_help double-prefix path display_file -> dlb_fopen -> fopen_datafile already prepends DATAPREFIX; wrapping PORT_HELP in fqname() too produced "NetHack:NetHack:amii.hlp". --- sys/amiga/winfuncs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/amiga/winfuncs.c b/sys/amiga/winfuncs.c index d22b95c53..b964d9ffc 100644 --- a/sys/amiga/winfuncs.c +++ b/sys/amiga/winfuncs.c @@ -1966,7 +1966,9 @@ removetopl(int cnt) void port_help(void) { - display_file(fqname(PORT_HELP, DATAPREFIX, 0), 1); + /* display_file -> dlb_fopen -> fopen_datafile already routes through + DATAPREFIX; pass the bare filename. */ + display_file(PORT_HELP, 1); } #endif From d1a84de8fc03d532300988c6d52ad7ca1d944e37 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 18:01:24 +0200 Subject: [PATCH 254/702] Amiga: delete outdated/sys/amiga/ These 3.4.1-era files are superseded: Build/Install.ami -> README.amiga; Makefile.ami/.agc -> sys/unix/hints/include/cross-*.500; NetHack.cnf -> sys/amiga/nethack.cnf; txt2iff/xpm2iff.c -> sys/amiga/*_host.c. --- Files | 5 - outdated/sys/amiga/.gitattributes | 2 - outdated/sys/amiga/Build.ami | 140 --- outdated/sys/amiga/Install.ami | 200 ---- outdated/sys/amiga/Makefile.agc | 1241 ----------------------- outdated/sys/amiga/Makefile.ami | 1578 ----------------------------- outdated/sys/amiga/NetHack.cnf | 213 ---- outdated/sys/amiga/ifchange | 55 - outdated/sys/amiga/mkdmake | 13 - outdated/sys/amiga/txt2iff.c | 446 -------- outdated/sys/amiga/xpm2iff.c | 363 ------- 11 files changed, 4256 deletions(-) delete mode 100644 outdated/sys/amiga/.gitattributes delete mode 100644 outdated/sys/amiga/Build.ami delete mode 100644 outdated/sys/amiga/Install.ami delete mode 100644 outdated/sys/amiga/Makefile.agc delete mode 100644 outdated/sys/amiga/Makefile.ami delete mode 100644 outdated/sys/amiga/NetHack.cnf delete mode 100644 outdated/sys/amiga/ifchange delete mode 100644 outdated/sys/amiga/mkdmake delete mode 100644 outdated/sys/amiga/txt2iff.c delete mode 100644 outdated/sys/amiga/xpm2iff.c diff --git a/Files b/Files index 50d8ecfba..be2f6d514 100644 --- a/Files +++ b/Files @@ -132,11 +132,6 @@ wceconf.h mac-carbon.h mac-qt.h mac-term.h macconf.h macpopup.h mactty.h macwin.h mttypriv.h -outdated/sys/amiga: -(files for Amiga versions - untested for 5.0) -Build.ami Install.ami Makefile.agc Makefile.ami NetHack.cnf -ifchange mkdmake txt2iff.c xpm2iff.c - outdated/sys/atari: (files for Atari version - untested for 5.0) Install.tos atarifnt.uue nethack.mnu setup.g tos.c diff --git a/outdated/sys/amiga/.gitattributes b/outdated/sys/amiga/.gitattributes deleted file mode 100644 index 483f30202..000000000 --- a/outdated/sys/amiga/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -*.p NHSUBST -* NH_filestag=(file%s_for_Amiga_versions_-_untested_for_5.0) diff --git a/outdated/sys/amiga/Build.ami b/outdated/sys/amiga/Build.ami deleted file mode 100644 index 2b435d827..000000000 --- a/outdated/sys/amiga/Build.ami +++ /dev/null @@ -1,140 +0,0 @@ - - Compiling Amiga NetHack 3.4 - Last Revision: 21 February 2002 for NetHack 3.4.1 - - - We would like to thank each and every one of the people who took - the time and effort to report bugs to us. THANK YOU! (And keep - up the good work!) - -I. Introduction - - The Amiga-specific documentation has been split since the 3.1.3 release - - please read the file Install.ami for information specific to the - Amiga port before continuing. - - If you have problems with compilation, installation, or think you have - found a bug in the game, please report it by electronic mail to the - development group at nethack-bugs@nethack.org, where it will be routed - to the appropriate person. Include your configuration, the version of - NetHack you are playing (use the 'v' command or see - include/patchlevel.h), and as much specific information as possible. - As NetHack runs on many different machines, be sure to mention that you - are playing the Amiga version and also mention if you are using the - version for mc68k or ppc. - - If you want to find out about distributing NetHack, read the license - (in NetHack:license or type ?i during the game). - -II. Compiling Amiga NetHack 3.4 - -II.A. Compilation Overview - Compiling NetHack is not very hard - basically you do a little - configuration and start make. It does, however, require a good amount - of disk space and time. It also needs a good bit of memory, especially - for linking. - -II.B. Basic Compilation - - NetHack can be built with SAS/C version 6.5x. The commercial version - of DICE might work, but NetHack version 3.2.2 or later haven't been - compiled with it. The "official" compiler for NetHack 3.6 is SAS/C 6.58 - - we have dropped support for SAS/C 5.x. - - The Manx/Aztec port has not been tested recently and is certainly - broken. Anyone managing to compile NetHack with this compiler is - encouraged to submit context diffs of the required changes. When last - tested, NetHack required version 5.0B of that compiler. - - Compiling with gcc should also work. - -II.B.1. Introduction to Compiling NetHack - Before doing any compilation, read the README files distributed with - the source. These should familiarize you with the source tree layout - and what files are shared with what computers; everything in the - sys/amiga directory is used exclusively by the Amiga. - - The makefile (sys/amiga/Makefile.ami) depends on certain assignments, - providing the developer with a fairly flexible environment. See - sys/amiga/Makefile.ami for assignment assumptions. DICE users should - see section II.B.3 for information on creating a DMakefile usable with - DMake. - - Edit config.h to your liking and system configuration. The defaults - should be satisfactory for most systems. - - Read VERY CAREFULLY through the Makefile to familiarize yourself - with which assignments are assumed. Otherwise, you're going to get - something like "Insert NH: in any drive." You will need uudecode, - and, if you need to modify dgn_comp or lev_comp, flex, and bison. - The first thing Makefile.ami does is build makedefs, which handles - a variety of data file generation, and then lev_comp and dgn_comp - which compile the special levels. Makedefs will then be run to create - a few files, followed by a roughly alphabetically sorted compilation - of the entire source tree. This process will compile selected files - from the sys/amiga, sys/share, win/tty, and src directories, eventually - creating sbin/nethack. After building the main binary, a make install - will build the auxiliary files including help files, special levels, - icons, and the font files and will put these files into their final - positions - most will be in dlb archives (if DLB was defined in config.h). - The first make run should be done in NH:obj and the make install should be - done in NetHack:; for both runs, the makefile is NH:sys/amiga/Makefile.ami - (or NH:sys/amiga/DMakefile for DMake and NH:sys/amiga/Makefile.agc for - gcc). - - Note that not all the source is simple C code. If you are modifying - lev_comp or dgn_comp you may need bison and/or flex (depending on what - modifications you are making). You do not need any of these tools to - simply build NetHack - all the C output files are provided in the source - distribution. Also, the ifchange script requires a version of diff that - produces standard Unix format context diffs for proper operation - the - version shipped with SAS/C is not sufficient. - - If you do not have bison and flex, copy the files from sys/share. The - include files go in include/ and the C files go in util/. If the compile - fails due to prototype errors for malloc and realloc, try deleting - the first line of lev_comp.c and dgn_comp.c. - -II.B.2. Compiling NetHack with SAS/C version 6.58 - - NOTE WELL - Amiga NetHack has dropped support for SAS/C version 5. - This version of NetHack was developed with SAS/C 6.58. Earlier versions - than version of the compiler are known to cause problems - don't use them. - - A couple of notes and warnings from the SAS/C users on the team: - - * Included in the SAS/C port is code for generating a SnapShot.tb - file upon catching various internal disasters. That is why the - debug=l flag is in the makefile. This adds about 270K to the disk - image, but it does not increase the run time memory requirements. - - * The 5.10b optimizer did not produce correct code for NetHack. The - current optimizer has not been tested. - -II.B.3. Compiling NetHack with the commercial version of DICE - - IMPORTANT NOTE: If you are using DMake, you need to create DMakefile - from Makefile.ami. Do the following: - - cd NH:sys/amiga - edit from Makefile.ami to DMakefile with mkdmake opt w255 - - Some versions of DMake have been known to crash horribly on the - makefile - if this happens, you'll need to download another make - utility, such as AMake (ftp://ftp.dragonfire.net/amiga/utils/amake), - which will run in DMake-compatibility mode if invoked with the -C switch - (e.g. "amake -C -f NH:sys/amiga/DMakefile", or just - "alias dmake amake -C"). - - SECOND IMPORTANT NOTE: The score list is currently disabled when - compiling under DICE, due to an as-yet-unknown problem which causes - system crashes when displaying the score list. - - NetHack can be compiled using the commercial version of DICE only. The - registered shareware version had a bug in it which resulted in odd- - aligned procedures. (It is possible to patch DC1 to fix this problem; - however, this is not recommended, and you should upgrade to the - commercial version.) - - During compilation, DICE will output a lot of warnings; they can be - safely ignored. diff --git a/outdated/sys/amiga/Install.ami b/outdated/sys/amiga/Install.ami deleted file mode 100644 index 58ad2409b..000000000 --- a/outdated/sys/amiga/Install.ami +++ /dev/null @@ -1,200 +0,0 @@ - - Using and Installing Amiga NetHack 3.4 - (or Everything You Never Wanted to Know Before NetHacking) - (or Not Everything That Happens Always Comes Knocking) - - Last Revision: 28 March 2000 for NetHack 3.4.1 - - -0. Pre-intro for NetHack 3.4.1: - Amiga-specific changes for 3.4.1: - Most (around 99%) known bugs fixed (volunteers welcome). - HackWB and HackCli are no longer supported. Use the main binary. - - We would like to thank each and every one of the people who took - the time and effort to report bugs to us. THANK YOU! - -I. Introduction - -I.A. Overview - Welcome to Amiga NetHack! If this is your first visit to our fair - city, you are in for an amazing but dangerous journey; if you have - visited us before, beware! the city has changed in many strange and - subtle ways; it has also grown quite a bit. This missive brings to - light those mundane tasks which must be dealt with before beginning - your journey; for those of you who are faced with the task of - installing the pre-fabricated version of our town, section III - (Installing Amiga NetHack 3.6) will guide you through the task at - hand. If you are ready to visit, the local visitors guide is in - section II (Using Amiga NetHack 3.6); please also see the general - guide packaged separately (the file "GuideBook"). - - To all our visitors, a hearty Welcome! - and please be careful. - - [Those responsible for the previous paragraphs have been sacked. The - documentation has been completed at great expense in a more traditional - style. -- The Management] - -I.B. Getting Help - If you have questions about strategy, weapons, or monsters, the best - place to go for help is the Usenet newsgroup rec.games.roguelike.nethack. - - If you have problems with installation or think you have found a bug - in the game, please report it by electronic mail to the development - team at nethack-bugs@nethack.org, where it will be routed to the - appropriate person. Include your configuration, the version of - NetHack you are playing (use the 'v' command), whether or not you are - using an official binary release (and if so which one) and as much - specific information as possible. As NetHack runs on many different - machines, be sure to mention that you are playing the Amiga version. - -I.C. Credits - Olaf Seibert first ported NetHack 2.3 and 3.0 to the Amiga. Richard - Addison, Andrew Church, Jochen Erwied, Mark Gooderum, Ken Lorber, - Greg Olson, Mike Passaretti, and Gregg Wonderly polished and extended - the 3.0 and 3.1 ports. Andrew Church, Ken Lorber, and Gregg Wonderly - are responsible for the 3.2 port. Janne Salmijärvi resurrected the - amigaport for 3.3 and Teemu Suikki joined before 3.4.0. - -II. Using Amiga NetHack 3.4 - Run NetHack from the shell or from some tool that allows that, - ie. ToolManager. See the NetHack.txt file for command line options - and other usage. - -II.A. Sources of Information - Where to go depends on what you want to find out. If you want to find - out about distributing NetHack, read the license (in NetHack:license - or type ?i during the game). For an introduction to NetHack, read - the GuideBook file. To find out what options are compiled into your - copy of NetHack, type #v during the game. Finally, for information - during the game on all kinds of things, type ? and select from the - menu or by pressing Help key. - -II.B. The Amiga NetHack WorkBench Front End - Starting from 3.3.0 HackWB is not supported. - -II.C. The Amiga NetHack CLI Front End - Starting from 3.3.0 CLI Front end is not supported either. - - Instead, use the main binary. See NetHack.txt file for the standard Unix - flags for NetHack. In addition to those flags, Amiga NetHack accepts - the flags -l to force non-interlaced mode and -L to force interlaced mode. - -II.D. Amiga-Specific Information for NetHack - - There are several options that are unique to the Amiga version of - NetHack that may be specified in the NetHack.cnf file or on an - OPTIONS line: - - altmeta allows the ALT keys to function as META keys. The default - is altmeta. - flush flush discards all characters in the queue except the first, - which limits typeahead accidents. The default is !flush. - silent turn off the audio output. The default is silent. - - The current version of Amiga NetHack also supports menu accelerators. - See Guidebook.txt for a detailed description. Also supported is - selecting the number of stacked objects to drop, used with the (D)rop - command. Type the number and then select an item (or items with - accelerators). Items with a count associated with them are denoted - with # in place of -. I.e. 'd - 3 blessed daggers' becomes - 'd # 3 blessed daggers'. You can clear the count by hitting esc - while counting or deselect and reselect the item. The default - is to drop all selected items (as before). - - For other options how to configure the screen setting and colors refer - to Nethack.cnf. - -III. Installing Amiga NetHack 3.4 - -III.A. General Installation - Installation should be easy - basically it consists of putting files - where they belong and adding an assign to your startup. If you are - installing from the official binary distribution, simply unpacking - the archive in the appropriate directory will put the files in the - places they belong. - - IF YOU ALREADY HAVE A PREVIOUS VERSION INSTALLED YOU MUST DELETE THE - OLD SAVE AND BONES FILES - THEY WILL NOT WORK! This includes save - and bones files from all previous versions of NetHack (yes, even 3.3.1). - If you have a game in progress and want to finish it, use your - current version and then update. - -Will NetHack fit on your machine? - NetHack 3.6 is large. NetHack 3.4 is very large. You will need: - > Any standard series Amiga: 500, 600, 1000, 1200, 2000, 2500, 3000, 4000. - > WorkBench 2.04 or later. - > At least 3 meg of RAM. NetHack will NOT run in 1 meg (probably even 2). - > Mass storage: A hard drive with over 3 meg of free space is highly - recommended. - -Hard Disk Installation: - Unpack the archive to your place of choice. Since you are reading this - you've probably done that already. Now just assign NetHack: to - NetHack directory containing the executable and datafiles and other needed - directories. - - Use the table in the next section to see where things should end up. - Be sure that the file 8 ends up in NetHack:hack/8. - -Configuration - Using your favorite text editor, edit NetHack:NetHack.cnf to match - your system. - - Create the save file directory (makedir NetHack:save) and the levels file - directory (makedir NetHack:levels), if they don't already exist. - - Create the score file (echo to NetHack:record) and, if desired, the log - file (echo to NetHack:logfile), if they don't already exist. You may - leave out logfile, but record is needed. - -III.B. File Location Table -NetHack: - amii.hlp Guidebook.txt hack.font - license NetHack NetHack.cnf - NetHack.txt nhdat nhsdat - record Recover Recover.txt - logfile (optional, but useful) -NetHack:hack - 8 -NetHack:tiles - monsters.iff objects.iff other.iff - -IV. BBS Interface - - [Since HackCli and split binary is no longer supported the following - probably doesn't apply anymore. Due to lack of a suitable environment - it is also untested.] - - The BBS mode is based on the standard NetHack tty port and is designed - for use in a BBS setting - it is specifically not recommended for use - on the console. The current TTY mode has changed significantly since - the preliminary version released with 3.1.2. In particular, BBS mode - now works with split binaries (only), and now supports multiple games - in progress at the same time for multi-line boards (note however that - any individual user should not be allowed to run two instances of - NetHack at the same time). - - To set up NetHack for use with a BBS, set OPTIONS=windowtype:tty - and unset DUNGEONS, TRAPS, and EFFECTS in NetHack.cnf. Configure - the BBS to expect I/O through stdin and stdout, and have NetHack - invoked as: - HackCLI :uid -u uname options... - where uid is any string (without embedded spaces, colons, or slashes) - that is unique for each BBS user and uname is some corresponding human- - readable name for that user. Uid is used in constructing file names - to prevent collisions between simultaneous games and to prevent - people from using other people's save files. Uname is the name the - character will have in the game and the name that will appear in the - record file. - - The terminal is assumed to be a 24x80 ANSI-compatible terminal. - The present version does not deal with situations such as low - memory gracefully - as NetHack uses a considerable amount of - memory this is particularly painful with multiple games in - progress. Sysops are reminded to be familiar with the recover - utility, which may be needed from time to time and which should - probably not be available directly to users. Bug reports and - suggestions for improvements are requested from the user community - - this is still considered alpha software. - diff --git a/outdated/sys/amiga/Makefile.agc b/outdated/sys/amiga/Makefile.agc deleted file mode 100644 index 5f36d0049..000000000 --- a/outdated/sys/amiga/Makefile.agc +++ /dev/null @@ -1,1241 +0,0 @@ -# NetHack Makefile. -# Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1991,1992,1993,1996. -# NetHack may be freely redistributed. See license for details. - -### -### modified for gcc by Teemu Suikki (zu@iki.fi) -### -### note: you need to use smake.. sorry -### - -### -### DIRECTORY STRUCTURE -### - -NH = nh: - -SBIN = $(NH)sbin/ -SLIB = $(NH)slib/ -NETHACK = $(NH)NetHack/ -HACKEXE = $(NH)HackExe/ -AMI = $(NH)sys/amiga/ -DAT = $(NH)dat/ -DOC = $(NH)doc/ -I = $(NH)include/ -SHARE = $(NH)sys/share/ -NHS = $(NH)src/ -TTY = $(NH)win/tty/ -WSHARE = $(NH)win/share/ -UTIL = $(NH)util/ -O = $(NH)obj/ -OO = $(NH)objo/ -# NB: O and OO MUST be different directories - -### -### INVOCATION -### - -MAKE = smake - -# Startup makefile with: -# -# $(MAKE) -f $(AMI)Makefile.amigcc -# $(MAKE) -f $(AMI)Makefile.amigcc install -# -# You may use following targets on $(MAKE) command lines: -# all do it all (default) -# link just create binary from object files -# obj just create common object files -# obja just create amiga object files -# objs just create shared object files -# clean deletes the object files -# spotless deletes the object files, main binary, and more -# -# Note: We do not build the Guidebook here since it needs tbl -# (See the file sys/unix/Makefile.doc for more information) - -#[SAS5] [and gcc?] -# If we were to use the precompiled header file feature in a newer version -# of SAS/C, we would comment out these following two lines. -# If we don't use precompiled header files, we uncomment it as well. - -HDEP = $(I)hack.h -CSYM = - -#Pathname for uudecode program: -UUDEC = uudecode - -# Flex/Bison command assignments -- Useful only if you have flex/bison -FLEX = flex -BISON = bison -# FBFIL and FBLIB may be used, if required by your version of flex or bison, -# to specify additional files or libraries to be linked with -FBFIL = -FBLIB = #lib lib:compat.lib - -# If you're compiling this on a 1.3 system, you'll have to uncomment the -# following (for use with the ifchange script below). Also useful instead of -# "protect ifchange +s" -EXECUTE = execute - -# Headers we depend on -AMDEP = $(AMI)winproto.h $(AMI)winext.h $(AMI)windefs.h $(I)winami.h - -# Pathname for the C compiler being used. - -CC = gcc -c -ASM = as - -# Compilation flags for selected C Compiler: -# $(CFLAGS) should appear before filename arguments of $(CC) command line. - -CFLAGS = -O3 -I $(I) - -# Components of various link command lines: -# $(LINK) should be the pathname of the linker being used (with any options -# that should appear at the beginning of the command line). The name of the -# output file should appear immediately after $(LNSPEC). $(LIN) should -# appear before the list of object files in each link command. $(LLINK) -# should appear as the list of object files in the link command line that -# creates the NetHack executable. $(LLIB) should appear at the end of each -# link command line. - -LINK = gcc -noixemul -O3 -LIN = -LLINK = -LLIB = -FLLIB = -OBJSPEC = -o -PNSPEC = -o -LNSPEC = -o -CCLINK = gcc -noixemul -CLFLAGS = -O3 -INCLSPEC = -I -DEFSPEC = -D -IGNSPEC = -j - -### -### FILE LISTS -### - -# A more reasonable random number generator (recommended for the Amiga): - -RANDOBJ = $(O)random.o - -.PRECIOUS: $(I)config.h $(I)decl.h $(I)hack.h $(I)permonst.h $(I)you.h - -# Almost nothing below this line should have to be changed. -# (Exceptions are marked by [SAS6], [MANX], etc.) -# -# Other things that have to be reconfigured are in config.h, -# (amiconf.h, pcconf.h), and possibly system.h, tradstdc.h. - -# Object files for makedefs: - -MAKEOBJS = \ - $(OO)makedefs.o $(O)monst.o $(O)objects.o - -# Object files for special levels compiler: - -SPLEVOBJS = \ - $(OO)lev_yacc.o $(OO)lev_lex.o $(OO)lev_main.o \ - $(O)decl.o $(O)drawing.o $(O)monst.o \ - $(O)objects.o $(OO)panic.o - -# Object files for dungeon compiler - -DGNCOMPOBJS = \ - $(OO)dgn_yacc.o $(OO)dgn_lex.o $(OO)dgn_main.o $(O)alloc.o $(OO)panic.o - -# Object files for NetHack: - -COMMOBJ = \ - $(O)allmain.o $(O)alloc.o $(O)apply.o $(O)artifact.o \ - $(O)attrib.o $(O)ball.o $(O)bones.o $(O)botl.o \ - $(O)cmd.o $(O)dbridge.o $(O)decl.o $(O)detect.o \ - $(O)dig.o $(O)display.o $(O)dlb.o $(O)do.o \ - $(O)do_name.o $(O)do_wear.o $(O)dog.o $(O)dogmove.o \ - $(O)dokick.o $(O)dothrow.o $(O)drawing.o $(O)dungeon.o \ - $(O)eat.o $(O)end.o $(O)engrave.o $(O)exper.o \ - $(O)explode.o $(O)extralev.o $(O)files.o $(O)fountain.o \ - $(O)hack.o $(O)hacklib.o $(O)invent.o $(O)light.o \ - $(O)lock.o $(O)mail.o $(O)makemon.o $(O)mapglyph.o \ - $(O)mcastu.o $(O)mhitm.o $(O)mhitu.o $(O)minion.o \ - $(O)mklev.o $(O)mkmap.o $(O)mkmaze.o $(O)mkobj.o \ - $(O)mkroom.o $(O)mon.o $(O)mondata.o $(O)monmove.o \ - $(O)monst.o $(O)mplayer.o $(O)mthrowu.o $(O)muse.o \ - $(O)music.o $(O)o_init.o $(O)objects.o $(O)objnam.o \ - $(O)options.o $(O)pager.o $(O)pickup.o $(O)pline.o \ - $(O)polyself.o $(O)potion.o $(O)pray.o $(O)priest.o \ - $(O)quest.o $(O)questpgr.o $(O)read.o $(O)rect.o \ - $(O)region.o $(O)restore.o $(O)rnd.o $(O)role.o \ - $(O)rumors.o $(O)save.o $(O)shk.o $(O)shknam.o \ - $(O)sit.o $(O)sounds.o $(O)sp_lev.o $(O)spell.o \ - $(O)steal.o $(O)steed.o $(O)sys.o $(O)teleport.o \ - $(O)timeout.o $(O)topten.o $(O)track.o $(O)trap.o \ - $(O)u_init.o $(O)uhitm.o $(O)vault.o $(O)version.o \ - $(O)vision.o $(O)weapon.o $(O)were.o $(O)wield.o \ - $(O)windows.o $(O)wizard.o $(O)worm.o $(O)worn.o \ - $(O)write.o $(O)zap.o - -MAKEDEFOBJ = \ - $(O)monstr.o - -AMIGAOBJ = \ - $(O)amidos.o $(O)amirip.o $(O)amistack.o \ - $(O)amiwind.o $(O)winami.o $(O)winchar.o $(O)winfuncs.o \ - $(O)winkey.o $(O)winamenu.o $(O)winreq.o $(O)winstr.o - -# Objects from assembly sources (because DMake can't handle default rules) -AMIGAOBJ2 = \ -# $(O)dispmap.o - -SHAREOBJ = \ - $(O)pcmain.o $(RANDOBJ) - -TTYOBJ = \ - $(O)getline.o $(O)termcap.o $(O)topl.o $(O)wintty.o $(O)amitty.o \ - $(O)rip.o - -# Yuck yuck yuck. Have to tell DMake where these are, since they're not -# all in the same place. -TTYSRC = \ - $(TTY)getline.c $(TTY)termcap.c $(TTY)topl.c $(TTY)wintty.c \ - $(AMI)amitty.c $(NHS)rip.c - -# All the object files for NetHack: - -HOBJ = $(COMMOBJ) $(AMIGAOBJ) $(AMIGAOBJ2) $(SHAREOBJ) $(MAKEDEFOBJ) $(TTYOBJ) - -### -### DATA FILES -### - -# quest files -ADFILES1= $(SLIB)Arc-fila.lev $(SLIB)Arc-filb.lev $(SLIB)Arc-loca.lev \ - $(SLIB)Arc-strt.lev -ADFILES= $(SLIB)Arc-goal.lev $(ADFILES1) - -BDFILES1= $(SLIB)Bar-fila.lev $(SLIB)Bar-filb.lev $(SLIB)Bar-loca.lev \ - $(SLIB)Bar-strt.lev -BDFILES= $(SLIB)Bar-goal.lev $(BDFILES1) - -CDFILES1= $(SLIB)Cav-fila.lev $(SLIB)Cav-filb.lev $(SLIB)Cav-loca.lev \ - $(SLIB)Cav-strt.lev -CDFILES= $(SLIB)Cav-goal.lev $(CDFILES1) - -HDFILES1= $(SLIB)Hea-fila.lev $(SLIB)Hea-filb.lev $(SLIB)Hea-loca.lev \ - $(SLIB)Hea-strt.lev -HDFILES= $(SLIB)Hea-goal.lev $(HDFILES1) - -KDFILES1= $(SLIB)Kni-fila.lev $(SLIB)Kni-filb.lev $(SLIB)Kni-loca.lev \ - $(SLIB)Kni-strt.lev -KDFILES= $(SLIB)Kni-goal.lev $(KDFILES1) - -MDFILES1= $(SLIB)Mon-fila.lev $(SLIB)Mon-filb.lev $(SLIB)Mon-loca.lev \ - $(SLIB)Mon-strt.lev -MDFILES= $(SLIB)Mon-goal.lev $(MDFILES1) - -PDFILES1= $(SLIB)Pri-fila.lev $(SLIB)Pri-filb.lev $(SLIB)Pri-loca.lev \ - $(SLIB)Pri-strt.lev -PDFILES= $(SLIB)Pri-goal.lev $(PDFILES1) - -RDFILES1= $(SLIB)Rog-fila.lev $(SLIB)Rog-filb.lev $(SLIB)Rog-loca.lev \ - $(SLIB)Rog-strt.lev -RDFILES= $(SLIB)Rog-goal.lev $(RDFILES1) - -RANFILES1= $(SLIB)Ran-fila.lev $(SLIB)Ran-filb.lev $(SLIB)Ran-loca.lev \ - $(SLIB)Ran-strt.lev -RANFILES= $(SLIB)Ran-goal.lev $(RANFILES1) - -SDFILES1= $(SLIB)Sam-fila.lev $(SLIB)Sam-filb.lev $(SLIB)Sam-loca.lev \ - $(SLIB)Sam-strt.lev -SDFILES= $(SLIB)Sam-goal.lev $(SDFILES1) - -TDFILES1= $(SLIB)Tou-fila.lev $(SLIB)Tou-filb.lev $(SLIB)Tou-loca.lev \ - $(SLIB)Tou-strt.lev -TDFILES= $(SLIB)Tou-goal.lev $(TDFILES1) - -VDFILES1= $(SLIB)Val-fila.lev $(SLIB)Val-filb.lev $(SLIB)Val-loca.lev \ - $(SLIB)Val-strt.lev -VDFILES= $(SLIB)Val-goal.lev $(VDFILES1) - -WDFILES1= $(SLIB)Wiz-fila.lev $(SLIB)Wiz-filb.lev $(SLIB)Wiz-loca.lev \ - $(SLIB)Wiz-strt.lev -WDFILES= $(SLIB)Wiz-goal.lev $(WDFILES1) - -XDFILES= $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(KDFILES) \ - $(MDFILES) $(PDFILES) $(RDFILES) $(RANFILES) $(SDFILES) $(TDFILES) \ - $(VDFILES) $(WDFILES) - -TILEFILES= \ - $(SBIN)txt2iff \ - $(NETHACK)tiles \ - $(NETHACK)tiles/objects.iff \ - $(NETHACK)tiles/monsters.iff \ - $(NETHACK)tiles/other.iff - -INSTDUNGEONFILES1= \ - $(SLIB)air.lev $(SLIB)asmodeus.lev $(SLIB)astral.lev \ - $(SLIB)baalz.lev $(SLIB)bigrm-1.lev $(SLIB)bigrm-2.lev \ - $(SLIB)bigrm-3.lev $(SLIB)bigrm-4.lev $(SLIB)bigrm-5.lev \ - $(SLIB)castle.lev $(SLIB)dungeon $(SLIB)earth.lev \ - $(SLIB)fakewiz1.lev $(SLIB)fakewiz2.lev $(SLIB)fire.lev \ - $(SLIB)juiblex.lev $(SLIB)knox.lev $(SLIB)medusa-1.lev \ - $(SLIB)medusa-2.lev $(SLIB)minend-1.lev $(SLIB)minend-2.lev \ - $(SLIB)minetn-1.lev $(SLIB)minetn-2.lev $(SLIB)minefill.lev \ - $(SLIB)options $(SLIB)oracle.lev $(SLIB)orcus.lev \ - $(SLIB)sanctum.lev $(SLIB)soko1-1.lev $(SLIB)soko1-2.lev \ - $(SLIB)soko2-1.lev $(SLIB)soko2-2.lev $(SLIB)soko3-1.lev \ - $(SLIB)soko3-2.lev $(SLIB)soko4-1.lev $(SLIB)soko4-2.lev \ - $(SLIB)tower1.lev $(SLIB)tower2.lev $(SLIB)tower3.lev \ - $(SLIB)valley.lev $(SLIB)water.lev $(SLIB)wizard1.lev \ - $(SLIB)wizard2.lev $(SLIB)wizard3.lev \ - $(XDFILES) - -INSTDUNGEONFILES= $(NETHACK)NetHack.cnf $(INSTDUNGEONFILES1) - - -INSTDATAFILES= \ - $(NETHACK)license $(NETHACK)logfile $(NETHACK)record \ - $(NETHACK)tomb.iff $(NETHACK)amii.hlp $(NETHACK)Recover.txt \ - $(NETHACK)GuideBook.txt $(NETHACK)NetHack.txt $(NETHACK)Install.ami \ -# $(NETHACK)HackWB.hlp $(NETHACK)WBDefaults.def - -LIBFILES= \ - $(INSTDUNGEONFILES1) \ - $(SLIB)cmdhelp $(SLIB)data $(SLIB)dungeon \ - $(SLIB)help $(SLIB)hh $(SLIB)history \ - $(SLIB)opthelp $(SLIB)oracles $(SLIB)rumors \ - $(SLIB)quest.dat $(SLIB)wizhelp - -### -### Getting down to business: -### - -all: $(COMPACT_HEADERS) $(SBIN)lev_comp $(SBIN)dgn_comp $(SBIN)NetHack \ - $(SBIN)dlb $(NETHACK)recover #$(NETHACK)HackCli $(SBIN)splitter \ -# $(NETHACK)HackWB - -install: inst-data inst-dungeon inst-fonts inst-tiles \ - $(NETHACK)recover $(NETHACK)NetHack $(NETHACK)nhdat - #$(NETHACK)NetHack.dir inst-icons - -$(SBIN)NetHack: link - -$(NETHACK)NetHack: $(SBIN)NetHack - copy $(SBIN)NetHack $(NETHACK)NetHack - -## uuh this is messy.. smake has weird command line length limit -link: $(HOBJ) - list to t:link lformat="$(O)%s" $(O)\#?.o QUICK NOHEAD - echo "\#sh" to t:cc - echo "$(LINK) $(LNSPEC) $(SBIN)NetHack $(LIN) $(LLIB) $(LLINK) " >>t:cc noline - fmt -u -w 2500 t:link >>t:cc - sh t:cc - delete t:cc t:link - - -## dlb support -$(OO)dlb_main.o: $(UTIL)dlb_main.c $(HDEP) $(I)dlb.h $(I)date.h - $(CC) $(CFLAGS) $(OBJSPEC)$(OO)dlb_main.o $(UTIL)dlb_main.c - -$(SBIN)dlb: $(OO)dlb_main.o $(O)dlb.o $(O)alloc.o $(OO)panic.o - $(LINK) $(PNSPEC) $(SBIN)dlb $(LIN) $(OO)dlb_main.o $(O)dlb.o \ - $(O)alloc.o $(OO)panic.o $(LLIB) - -obj: $(HOBJ) - -obja: $(AMIGAOBJ) - -objs: $(SHAREOBJ) - - -SUFFIXES = .lev .des -.des.lev: - $(SBIN)lev_comp $< - -# The default method for creating object files: - -#$(O)%.o: $(NHS)%.c -.c.o: - $(CC) $(CFLAGS) $(CSYM) $(OBJSPEC)$@ $< - -clean: - -delete $(O)\#?.o $(OO)\#?.o - -spotless: clean - -delete $(SBIN)NetHack $(SBIN)lev_comp $(SBIN)makedefs $(SBIN)dgn_comp - -delete $(SBIN)dlb $(SBIN)txt2iff $(SBIN)splitter - -delete $(SBIN)tilemap - -delete $(SLIB)data $(SLIB)rumors - -delete $(SLIB)\#?.lev - -delete $(SLIB)dungeon - -delete $(SLIB)cmdhelp $(SLIB)help $(SLIB)hh $(SLIB)history - -delete $(SLIB)opthelp $(SLIB)options $(SLIB)oracles - -delete $(SLIB)quest.dat $(SLIB)wizhelp -# -delete $(SLIB)earth.lev $(SLIB)air.lev $(SLIB)fire.lev -# -delete $(SLIB)water.lev $(SLIB)astral.lev -# -delete $(SLIB)tower1.lev $(SLIB)tower2.lev $(SLIB)tower3.lev -# -delete $(SLIB)fakewiz1.lev $(SLIB)fakewiz2.lev -# -delete $(SLIB)medusa-1.lev $(SLIB)medusa-2.lev -# -delete $(SLIB)oracle.lev $(SLIB)wizard1.lev $(SLIB)wizard2.lev -# -delete $(SLIB)wizard3.lev $(DAT)dungeon.pdf $(SLIB)valley.lev -# -delete $(SLIB)minefill.lev -# -delete $(SLIB)minetn-1 $(SLIB)minetn-2 $(SLIB)minend-1 $(SLIB)minend-2 -# -delete $(SLIB)soko1-1.lev $(SLIB)soko1-2.lev $(SLIB)soko2-1.lev -# -delete $(SLIB)soko2-2.lev $(SLIB)soko3-1.lev $(SLIB)soko3-2.lev -# -delete $(SLIB)soko4-1.lev $(SLIB)soko4-2.lev -# -delete $(ADFILES) -# -delete $(BDFILES) -# -delete $(CDFILES) -# -delete $(HDFILES) -# -delete $(KDFILES) -# -delete $(MDFILES) -# -delete $(PDFILES) -# -delete $(RDFILES) -# -delete $(RANFILES) -# -delete $(SDFILES) -# -delete $(TDFILES) -# -delete $(VDFILES) -# -delete $(WDFILES) - -delete $(I)onames.h $(I)pm.h $(I)date.h - -delete $(NHS)tile.c $(NHS)monstr.c - -delete $(I)tile.h -# -echo to $(I)onames.h "" noline -# -c:wait 2 -# -echo to $(I)pm.h "" noline -# -c:wait 2 -# -setdate $(UTIL)makedefs.c -# -c:wait 2 - -# Creating precompiled version of $(I)hack.h to save disk I/O. - -# -# Please note: The dependency lines for the modules here are -# deliberately incorrect. Including "hack.h" in -# the dependency list would cause a dependency -# loop. -# - -$(SBIN)makedefs: $(MAKEOBJS) - $(LINK) $(LNSPEC) $(SBIN)makedefs $(LIN) $(MAKEOBJS) $(LLIB) - -$(OO)makedefs.o: $(UTIL)makedefs.c $(I)config.h $(I)permonst.h $(I)monsym.h \ - $(I)objclass.h $(I)patchlevel.h $(I)artilist.h - $(CC) $(DEFSPEC)MAKEDEFS_C $(CFLAGS) $(OBJSPEC)$@ $(UTIL)makedefs.c - -$(SBIN)lev_comp: $(SPLEVOBJS) - $(LINK) $(LNSPEC) $(SBIN)lev_comp $(LIN) $(SPLEVOBJS) $(FBFIL) $(FLLIB) - -$(SBIN)dgn_comp: $(DGNCOMPOBJS) - $(LINK) $(LNSPEC) $(SBIN)dgn_comp $(LIN) $(DGNCOMPOBJS) $(FBFIL) $(FLLIB) - -$(OO)lev_yacc.o: $(UTIL)lev_yacc.c $(HDEP) $(I)sp_lev.h $(I)pm.h $(I)onames.h -# setdate $(UTIL)lev_yacc.c - $(CC) $(DEFSPEC)LEV_LEX_C $(DEFSPEC)PREFIX="NH:slib/" $(CFLAGS) \ - $(DEFSPEC)alloca=malloc $(OBJSPEC)$@ $(UTIL)lev_yacc.c - -$(OO)lev_lex.o: $(UTIL)lev_lex.c $(HDEP) $(I)lev_comp.h $(I)sp_lev.h - $(CC) $(DEFSPEC)LEV_LEX_C $(CFLAGS) $(OBJSPEC)$@ $(UTIL)lev_lex.c - -$(OO)lev_main.o: $(UTIL)lev_main.c $(HDEP) $(I)pm.h $(I)onames.h $(I)date.h - $(CC) $(DEFSPEC)LEV_LEX_C $(DEFSPEC)AMIGA $(CFLAGS) $(OBJSPEC)$@ \ - $(UTIL)lev_main.c - -$(OO)dgn_yacc.o: $(UTIL)dgn_yacc.c $(HDEP) $(I)dgn_file.h $(I)patchlevel.h - $(CC) $(DEFSPEC)LEV_LEX_C $(CFLAGS) $(DEFSPEC)alloca=malloc \ - $(OBJSPEC)$@ $(UTIL)dgn_yacc.c - -$(OO)dgn_lex.o: $(UTIL)dgn_lex.c $(I)config.h $(I)dgn_comp.h $(I)dgn_file.h - $(CC) $(DEFSPEC)LEV_LEX_C $(CFLAGS) $(OBJSPEC)$@ $(UTIL)dgn_lex.c - -$(OO)dgn_main.o: $(UTIL)dgn_main.c $(I)config.h $(I)date.h - $(CC) $(DEFSPEC)LEV_LEX_C $(DEFSPEC)AMIGA $(CFLAGS) $(OBJSPEC)$@ \ - $(UTIL)dgn_main.c - -$(OO)panic.o: $(UTIL)panic.c $(HDEP) - -$(OO)recover.o: $(UTIL)recover.c $(I)config.h $(I)date.h - $(CC) $(DEFSPEC)LEV_LEX_C $(DEFSPEC)AMIGA $(CFLAGS) $(OBJSPEC)$@ \ - $(UTIL)recover.c - -$(NETHACK)recover: $(OO)recover.o - $(LINK) $(LNSPEC) $(NETHACK)recover $(LIN) $(OO)recover.o $(LLIB) - -# [OPTION] -- If you have flex/bison, leave these uncommented. Otherwise, -# comment them out and be careful! (You're not guaranteed to have the most -# up to date *_comp.c, *_comp.h and *_lex.c) - -$(I)lev_comp.h: $(UTIL)lev_yacc.c $(I)patchlevel.h - -$(UTIL)lev_yacc.c: $(UTIL)lev_comp.y $(I)patchlevel.h - $(BISON) -d $(UTIL)lev_comp.y -# copy y.tab.c $(UTIL)lev_yacc.c -# copy y.tab.h $(I)lev_comp.h - copy $(UTIL)lev_comp.tab.c $(UTIL)lev_yacc.c - copy $(UTIL)lev_comp.tab.h $(I)lev_comp.h -# delete y.tab.c -# delete y.tab.h - delete $(UTIL)lev_comp.tab.c - delete $(UTIL)lev_comp.tab.h - -$(UTIL)lev_lex.c: $(UTIL)lev_comp.l $(I)patchlevel.h - $(FLEX) $(UTIL)lev_comp.l - copy lex.yy.c $(UTIL)lev_lex.c - delete lex.yy.c - -$(I)dgn_comp.h: $(UTIL)dgn_yacc.c $(I)patchlevel.h - -$(UTIL)dgn_yacc.c: $(UTIL)dgn_comp.y $(I)patchlevel.h - $(BISON) -d $(UTIL)dgn_comp.y -# copy y.tab.c $(UTIL)dgn_yacc.c -# copy y.tab.h $(I)dgn_comp.h - copy $(UTIL)dgn_comp.tab.c $(UTIL)dgn_yacc.c - copy $(UTIL)dgn_comp.tab.h $(I)dgn_comp.h -# delete y.tab.c -# delete y.tab.h - delete $(UTIL)dgn_comp.tab.c - delete $(UTIL)dgn_comp.tab.h - -$(UTIL)dgn_lex.c: $(UTIL)dgn_comp.l $(I)patchlevel.h - $(FLEX) $(UTIL)dgn_comp.l - copy lex.yy.c $(UTIL)dgn_lex.c - delete lex.yy.c - -# -# The following include files depend on makedefs to be created. -# As a result, they are not defined in HACKINCL, instead, their -# dependencies are explicitly outlined here. -# - -# -# date.h should be remade any time any of the source or include code -# is modified. Unfortunately, this would make the contents of this -# file far more complex. Since "hack.h" depends on most of the include -# files, we kludge around this by making date.h dependent on hack.h, -# even though it doesn't include this file. -# - -$(I)date.h $(DAT)options: $(HDEP) $(SBIN)makedefs $(AMIGAOBJ) $(I)patchlevel.h - $(SBIN)makedefs -v - $(EXECUTE) ifchange MOVE $(I)t.date.h $(I)date.h - -c:wait 2 - -$(I)onames.h: $(SBIN)makedefs - $(SBIN)makedefs -o - $(EXECUTE) ifchange TOUCH $(I)t.onames.h $(I)onames.h $(I)decl.h - $(EXECUTE) ifchange MOVE $(I)t.onames.h $(I)onames.h - -c:wait 2 - -$(I)pm.h: $(SBIN)makedefs - $(SBIN)makedefs -p - $(EXECUTE) ifchange TOUCH $(I)t.pm.h $(I)pm.h $(I)decl.h $(I)youprop.h - $(EXECUTE) ifchange MOVE $(I)t.pm.h $(I)pm.h - -c:wait 2 - -$(SLIB)quest.dat: $(DAT)quest.txt $(SBIN)makedefs - $(SBIN)makedefs -q - -$(NHS)monstr.c: $(HDEP) $(SBIN)makedefs - $(SBIN)makedefs -m - -c:wait 2 - -$(SLIB)oracles: $(DAT)oracles.txt $(SBIN)makedefs - $(SBIN)makedefs -h - -c:wait 2 - -# -# The following programs vary depending on what OS you are using. -# As a result, they are not defined in HACKSRC and their dependencies -# are explicitly outlined here. -# - -$(O)amidos.o: $(AMI)amidos.c $(HDEP) - -$(O)amirip.o: $(AMI)amirip.c $(HDEP) - -$(O)aglue.o: $(AMI)aglue.a - $(ASM) $(AFLAGS) $(AOBJSPEC)$(O)aglue.o $(AMI)aglue.a - -$(O)winchar.o: $(AMI)winchar.c $(NHS)tile.c $(HDEP) - -$(NHS)tile.c: $(WSHARE)tilemap.c - $(CCLINK) $(CFLAGS) $(PNSPEC) $(SBIN)tilemap $(WSHARE)tilemap.c - $(SBIN)tilemap - -$(O)winstr.o: $(AMI)winstr.c $(HDEP) $(AMDEP) - -$(O)winreq.o: $(AMI)winreq.c $(HDEP) $(AMDEP) $(AMI)colorwin.c $(AMI)clipwin.c - -$(O)winfuncs.o: $(AMI)winfuncs.c $(HDEP) $(AMDEP) $(I)patchlevel.h - -$(O)winkey.o: $(AMI)winkey.c $(HDEP) $(AMDEP) - -$(O)winamenu.o: $(AMI)winamenu.c $(HDEP) $(AMDEP) - -$(O)winami.o: $(AMI)winami.c $(HDEP) $(AMDEP) #$(AMI)char.c $(AMI)randwin.c - -#$(O)amilib.o: $(AMI)amilib.c $(HDEP) $(AMDEP) - -$(O)amiwind.o: $(AMI)amiwind.c $(AMI)amimenu.c $(HDEP) $(AMDEP) - -$(O)amiwbench.o: $(AMI)amiwbench.c $(HDEP) - -$(O)random.o: $(SHARE)random.c - -$(O)pcmain.o: $(SHARE)pcmain.c $(HDEP) $(I)dlb.h - -$(O)dispmap.o: $(AMI)dispmap.s - $(ASM) $(AFLAGS) $(AOBJSPEC)$@ $< - -# Stuff to build the front ends -$(NETHACK)HackWB: $(OO)wb.o $(OO)wbx.o $(OO)loader.o $(OO)multi.o - $(LINK) $(LNSPEC) $(NETHACK)HackWB $(LIN) $(OO)wb.o $(OO)wbx.o \ - $(OO)loader.o $(OO)multi.o $(LLIB) - -$(NETHACK)HackCli: $(OO)cli.o $(OO)loader.o $(OO)multi.o - $(LINK) $(LNSPEC) $(NETHACK)HackCli $(LIN) $(OO)cli.o $(OO)loader.o \ - $(OO)multi.o $(LLIB) - -# This needs to exist to eliminate the HackWB startup message -$(NETHACK)WBDefaults.def: - echo to $(NETHACK)WBDefaults.def - -WBH = $(AMI)wbdefs.h $(AMI)wbstruct.h $(AMI)wbprotos.h -ASP = $(AMI)splitter -$(OO)wb.o: $(WBH) $(AMI)wb.c $(AMI)wbwin.c $(AMI)wbdata.c $(AMI)wbgads.c \ - $(I)patchlevel.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)wb.o $(AMI)wb.c - -$(OO)wbx.o: $(WBH) $(AMI)wbcli.c $(AMI)wbwin.c $(AMI)wbdata.c \ - $(I)patchlevel.h $(I)date.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)wbx.o $(AMI)wbcli.c - -$(OO)loader.o: $(ASP)/loader.c $(ASP)/split.h $(ASP)/amiout.h $(ASP)/multi.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)loader.o $(ASP)/loader.c - -$(OO)multi.o: $(ASP)/multi.c $(ASP)/multi.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)multi.o $(ASP)/multi.c - -$(OO)cli.o: $(WBH) $(AMI)wbcli.c $(I)patchlevel.h $(I)date.h - $(CC) $(WBCFLAGS) $(WBC2FLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)cli.o \ - $(AMI)wbcli.c - -#### -# splitter support -$(SBIN)splitter: $(OO)splitter.o $(OO)arg.o - $(LINK) $(LNSPEC) $(SBIN)splitter $(LIN) $(OO)splitter.o $(OO)arg.o \ - $(LLIB) - -$(NETHACK)NetHack.dir: $(SBIN)splitter $(SBIN)NetHack - $(SBIN)splitter $(SBIN)NetHack - -$(OO)splitter.o: $(ASP)/splitter.c $(ASP)/split.h $(ASP)/amiout.h $(ASP)/arg.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)splitter.o \ - $(ASP)/splitter.c - -$(OO)arg.o: $(ASP)/arg.c $(ASP)/arg.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)arg.o $(ASP)/arg.c - -# Create/copy other stuff into NetHack: directory: - -$(NETHACK)tomb.iff: $(SBIN)xpm2iff $(AMI)grave16.xpm - $(SBIN)xpm2iff $(AMI)grave16.xpm $(NETHACK)tomb.iff - -$(OO)xpm2iff.o: $(AMI)xpm2iff.c - $(CC) $(CFLAGS) $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ $(AMI)xpm2iff.c - -$(SBIN)xpm2iff: $(OO)xpm2iff.o - $(LINK) $(LNSPEC) $@ $(LIN) $(OO)xpm2iff.o $(FLLIB) - -# Tile installation for the tile version of the game -inst-tiles: $(TILEFILES) - -$(NETHACK)tiles: - -makedir $(NETHACK)tiles - -$(OO)txt2iff.o: $(AMI)txt2iff.c - $(CC) $(CFLAGS) $(CSYM) $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ \ - $(AMI)txt2iff.c - -$(OO)ppmwrite.o: $(WSHARE)ppmwrite.c - $(CC) $(CFLAGS) $(CSYM) $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ $(WSHARE)ppmwrite.c - -$(OO)tiletext.o: $(WSHARE)tiletext.c $(I)config.h $(WSHARE)tile.h - $(CC) $(CFLAGS) $(CSYM) $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ $(WSHARE)tiletext.c - -$(OO)tiletxt.o: $(WSHARE)tilemap.c $(I)hack.h - $(CC) $(CFLAGS) $(CSYM) $(DEFSPEC)TILETEXT $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ $(WSHARE)tilemap.c - -NAMEOBJS = $(O)drawing.o $(O)decl.o $(O)monst.o $(O)objects.o - -$(SBIN)txt2ppm: $(OO)ppmwrite.o $(NAMEOBJS) $(O)alloc.o $(OO)panic.o $(OO)tiletext.o $(OO)tiletxt.o - $(LINK) $(LNSPEC) $@ $(LIN) $(OO)ppmwrite.o $(NAMEOBJS) $(OO)tiletext.o $(OO)tiletxt.o $(O)alloc.o $(OO)panic.o $(FLLIB) - -$(SBIN)txt2iff: $(OO)txt2iff.o $(NAMEOBJS) $(OO)tiletext.o $(OO)tiletxt.o - $(LINK) $(LNSPEC) $@ $(LIN) $(OO)txt2iff.o $(NAMEOBJS) $(OO)tiletext.o \ - $(OO)tiletxt.o $(FLLIB) - -$(NETHACK)tiles/objects.iff: $(WSHARE)objects.txt $(SBIN)txt2iff - $(SBIN)txt2iff $(WSHARE)objects.txt $(NETHACK)tiles/objects.iff - -$(NETHACK)tiles/monsters.iff: $(WSHARE)monsters.txt $(SBIN)txt2iff - $(SBIN)txt2iff $(WSHARE)monsters.txt $(NETHACK)tiles/monsters.iff - -$(NETHACK)tiles/other.iff: $(WSHARE)other.txt $(SBIN)txt2iff - $(SBIN)txt2iff $(WSHARE)other.txt $(NETHACK)tiles/other.iff - -inst-dungeon: $(INSTDUNGEONFILES) - -$(NETHACK)options : $(DAT)options - copy $(DAT)options $@ - -# Create compiled dungeon files -BGM= $(SLIB)bigrm-2.lev $(SLIB)bigrm-3.lev $(SLIB)bigrm-4.lev $(SLIB)bigrm-5.lev -$(BGM): $(SLIB)bigrm-1.lev - -$(SLIB)bigrm-1.lev: $(DAT)bigroom.des $(SBIN)lev_comp - -$(SLIB)castle.lev: $(DAT)castle.des $(SBIN)lev_comp - -ENDGAME1= $(SLIB)air.lev $(SLIB)earth.lev $(SLIB)fire.lev $(SLIB)water.lev -$(ENDGAME1): $(SLIB)astral.lev - -$(SLIB)astral.lev: $(DAT)endgame.des $(SBIN)lev_comp - -GEHENNOM1= $(SLIB)asmodeus.lev $(SLIB)baalz.lev $(SLIB)juiblex.lev \ - $(SLIB)orcus.lev $(SLIB)sanctum.lev -$(GEHENNOM1): $(SLIB)valley.lev - -$(SLIB)valley.lev: $(DAT)gehennom.des $(SBIN)lev_comp - -$(SLIB)knox.lev: $(DAT)knox.des $(SBIN)lev_comp - -MINES1= $(SLIB)minend-1.lev $(SLIB)minend-2.lev $(SLIB)minetn-1.lev $(SLIB)minetn-2.lev -$(MINES1): $(SLIB)minefill.lev - -$(SLIB)minefill.lev: $(DAT)mines.des $(SBIN)lev_comp - -$(SLIB)oracle.lev: $(DAT)oracle.des $(SBIN)lev_comp - -TOWER1= $(SLIB)tower1.lev $(SLIB)tower2.lev -$(TOWER1): $(SLIB)tower3.lev - -$(SLIB)tower3.lev: $(DAT)tower.des $(SBIN)lev_comp - -WIZARD1= $(SLIB)wizard1.lev $(SLIB)wizard2.lev $(SLIB)wizard3.lev \ - $(SLIB)fakewiz1.lev -$(WIZARD1): $(SLIB)fakewiz2.lev - -$(SLIB)fakewiz2.lev: $(DAT)yendor.des $(SBIN)lev_comp - -MEDUSA1= $(SLIB)medusa-1.lev -$(MEDUSA1): $(SLIB)medusa-2.lev - -$(SLIB)medusa-2.lev: $(DAT)medusa.des $(SBIN)lev_comp - -SOKOBAN1= $(SLIB)soko1-1.lev $(SLIB)soko1-2.lev $(SLIB)soko2-1.lev \ - $(SLIB)soko2-2.lev $(SLIB)soko3-1.lev $(SLIB)soko3-2.lev \ - $(SLIB)soko4-1.lev -$(SOKOBAN1): $(SLIB)soko4-2.lev - -$(SLIB)soko4-2.lev: $(DAT)sokoban.des $(SBIN)lev_comp - -$(ADFILES1): $(SLIB)Arc-goal.lev - -$(SLIB)Arc-goal.lev: $(DAT)Arch.des $(SBIN)lev_comp - -$(BDFILES1): $(SLIB)Bar-goal.lev - -$(SLIB)Bar-goal.lev: $(DAT)Barb.des $(SBIN)lev_comp - -$(CDFILES1): $(SLIB)Cav-goal.lev - -$(SLIB)Cav-goal.lev: $(DAT)Caveman.des $(SBIN)lev_comp - -$(HDFILES1): $(SLIB)Hea-goal.lev - -$(SLIB)Hea-goal.lev: $(DAT)Healer.des $(SBIN)lev_comp - -$(KDFILES1): $(SLIB)Kni-goal.lev - -$(SLIB)Kni-goal.lev: $(DAT)Knight.des $(SBIN)lev_comp - -$(MDFILES1): $(SLIB)Mon-goal.lev - -$(SLIB)Mon-goal.lev: $(DAT)Monk.des $(SBIN)lev_comp - -$(PDFILES1): $(SLIB)Pri-goal.lev - -$(SLIB)Pri-goal.lev: $(DAT)Priest.des $(SBIN)lev_comp - -$(RDFILES1): $(SLIB)Rog-goal.lev - -$(SLIB)Rog-goal.lev: $(DAT)Rogue.des $(SBIN)lev_comp - -$(RANFILES1): $(SLIB)Ran-goal.lev - -$(SLIB)Ran-goal.lev: $(DAT)Ranger.des $(SBIN)lev_comp - -$(SDFILES1): $(SLIB)Sam-goal.lev - -$(SLIB)Sam-goal.lev: $(DAT)Samurai.des $(SBIN)lev_comp - -$(TDFILES1): $(SLIB)Tou-goal.lev - -$(SLIB)Tou-goal.lev: $(DAT)Tourist.des $(SBIN)lev_comp - -$(VDFILES1): $(SLIB)Val-goal.lev - -$(SLIB)Val-goal.lev: $(DAT)Valkyrie.des $(SBIN)lev_comp - -$(WDFILES1): $(SLIB)Wiz-goal.lev - -$(SLIB)Wiz-goal.lev: $(DAT)Wizard.des $(SBIN)lev_comp - -$(SLIB)dungeon: $(DAT)dungeon.def $(SBIN)makedefs $(SBIN)dgn_comp - $(SBIN)makedefs -e - $(SBIN)dgn_comp $(DAT)dungeon.pdf - copy $(DAT)dungeon $(SLIB)dungeon - delete $(DAT)dungeon - -inst-data: $(INSTDATAFILES) - -$(NETHACK)amii.hlp: $(AMI)amii.hlp - copy $(AMI)amii.hlp $@ - -#$(NETHACK)data: $(DAT)data -# copy $(DAT)data $@ - -$(SLIB)data: $(DAT)data.base $(I)config.h $(SBIN)makedefs - $(SBIN)makedefs -d - -#$(NETHACK)rumors: $(DAT)rumors -# copy $(DAT)rumors $@ - -$(SLIB)rumors: $(DAT)rumors.tru $(DAT)rumors.fal $(SBIN)makedefs - $(SBIN)makedefs -r - -$(SLIB)cmdhelp: $(DAT)cmdhelp - copy $(DAT)cmdhelp $@ - -$(SLIB)help: $(DAT)help - copy $(DAT)help $@ - -$(SLIB)hh: $(DAT)hh - copy $(DAT)hh $@ - -$(NETHACK)HackWB.hlp: $(AMI)HackWB.hlp - copy $(AMI)HackWB.hlp $@ - -$(SLIB)history: $(DAT)history - copy $(DAT)history $@ - -$(NETHACK)license: $(DAT)license - copy $(DAT)license $@ - -$(SLIB)opthelp: $(DAT)opthelp - copy $(DAT)opthelp $@ - -$(NETHACK)Recover.txt: $(DOC)Recover.txt - copy $(DOC)Recover.txt $@ - -$(NETHACK)GuideBook.txt: $(DOC)GuideBook.txt - copy $(DOC)GuideBook.txt $@ - -$(NETHACK)NetHack.txt: $(DOC)NetHack.txt - copy $(DOC)NetHack.txt $@ - -$(NETHACK)Install.ami: $(AMI)Install.ami - copy $(AMI)Install.ami $@ - -$(NETHACK)logfile: - echo to $@ - -$(NETHACK)record: - echo to $@ - -$(SLIB)wizhelp: $(DAT)wizhelp - copy $(DAT)wizhelp $@ - -# Create the directories here because NetHack.cnf puts them there by default -$(NETHACK)NetHack.cnf: $(AMI)NetHack.cnf - copy $(AMI)NetHack.cnf $@ - -makedir $(NETHACK)save - -makedir $(NETHACK)levels - -# Unpack and install fonts - -INSTFONTFILES= $(NETHACK)hack.font $(NETHACK)hack $(NETHACK)hack/8 - -inst-fonts: $(INSTFONTFILES) - -$(NETHACK)hack/8: $(AMI)amifont8.uu $(NETHACK)hack - $(UUDEC) $(AMI)amifont8.uu - copy 8 $(NETHACK)hack/8 - delete 8 - -$(NETHACK)hack.font: $(AMI)amifont.uu - $(UUDEC) $(AMI)amifont.uu - copy hack.font $(NETHACK)hack.font - delete hack.font - -$(NETHACK)hack: - -makedir $@ - -INSTICONFILES= \ - $(NETHACK)default.icon $(NETHACK)NetHack.info $(NETHACK)NewGame.info \ - $(NETHACK)HackWB.info - -inst-icons: $(INSTICONFILES) - -# Unpack the icons into place - -$(NETHACK)default.icon: $(AMI)dflticon.uu - $(UUDEC) $(AMI)dflticon.uu -# copy default.icon $(NETHACK)default.icon -# delete default.icon - -$(NETHACK)NetHack.info: $(AMI)NHinfo.uu - $(UUDEC) $(AMI)NHinfo.uu -# copy NetHack.info $(NETHACK)NetHack.info -# delete NetHack.info - -$(NETHACK)NewGame.info: $(AMI)NewGame.uu - $(UUDEC) $(AMI)NewGame.uu -# copy NewGame.info $(NETHACK)NewGame.info -# delete NewGame.info - -$(NETHACK)HackWB.info: $(AMI)HackWB.uu - $(UUDEC) $(AMI)HackWB.uu -# copy HackWB.info $(NETHACK)HackWB.info -# delete HackWB.info - -# If DLB is defined, create the nhdat library file in the playground -# directory. If not, move all the data files there. -$(NETHACK)nhdat: $(LIBFILES) - list to T:nhdat.lst $(SLIB) QUICK NOHEAD FILES - echo >T:make-nhdat $(SBIN)dlb cCfI $(SLIB) $(NETHACK)nhdat T:nhdat.lst - echo >>T:make-nhdat if not exists $(NETHACK)nhdat - echo >>T:make-nhdat copy $(SLIB)\#? $(NETHACK) - echo >>T:make-nhdat endif - execute T:make-nhdat - -delete T:make-nhdat - -# DO NOT DELETE THIS LINE - -$(O)allmain.o: $(NHS)allmain.c $(HDEP) - -$(O)alloc.o: $(NHS)alloc.c $(I)config.h - -$(O)apply.o: $(NHS)apply.c $(HDEP) - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)apply.c - -$(O)artifact.o: $(NHS)artifact.c $(HDEP) $(I)artifact.h $(I)artilist.h - -$(O)attrib.o: $(NHS)attrib.c $(HDEP) $(I)artifact.h - -$(O)ball.o: $(NHS)ball.c $(HDEP) - -$(O)bones.o: $(NHS)bones.c $(HDEP) - -$(O)botl.o: $(NHS)botl.c $(HDEP) - -$(O)cmd.o: $(NHS)cmd.c $(HDEP) $(I)func_tab.h - -$(O)dbridge.o: $(NHS)dbridge.c $(HDEP) - -$(O)decl.o: $(NHS)decl.c $(HDEP) $(I)quest.h - -$(O)detect.o: $(NHS)detect.c $(HDEP) $(I)artifact.h - -$(O)dig.o: $(NHS)dig.c $(HDEP) - -$(O)display.o: $(NHS)display.c $(HDEP) - -$(O)dlb.o: $(NHS)dlb.c $(HDEP) $(I)dlb.h - -$(O)do.o: $(NHS)do.c $(HDEP) - -$(O)do_name.o: $(NHS)do_name.c $(HDEP) - -$(O)do_wear.o: $(NHS)do_wear.c $(HDEP) - -$(O)dog.o: $(NHS)dog.c $(HDEP) - -$(O)dogmove.o: $(NHS)dogmove.c $(HDEP) $(I)mfndpos.h - -$(O)dokick.o: $(NHS)dokick.c $(HDEP) - -$(O)dothrow.o: $(NHS)dothrow.c $(HDEP) - -$(O)drawing.o: $(NHS)drawing.c $(HDEP) $(I)tcap.h - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)drawing.c - -$(O)dungeon.o: $(NHS)dungeon.c $(HDEP) $(I)dgn_file.h $(I)dlb.h - -$(O)eat.o: $(NHS)eat.c $(HDEP) - -$(O)end.o: $(NHS)end.c $(HDEP) $(I)dlb.h - -$(O)engrave.o: $(NHS)engrave.c $(HDEP) - -$(O)exper.o: $(NHS)exper.c $(HDEP) - -$(O)explode.o: $(NHS)explode.c $(HDEP) - -$(O)extralev.o: $(NHS)extralev.c $(HDEP) - -$(O)files.o: $(NHS)files.c $(HDEP) $(I)dlb.h $(I)date.h - -$(O)fountain.o: $(NHS)fountain.c $(HDEP) - -$(O)hack.o: $(NHS)hack.c $(HDEP) - -$(O)hacklib.o: $(NHS)hacklib.c $(HDEP) - -$(O)invent.o: $(NHS)invent.c $(HDEP) $(I)artifact.h - -$(O)light.o: $(NHS)light.c $(HDEP) - -$(O)lock.o: $(NHS)lock.c $(HDEP) - -$(O)mail.o: $(NHS)mail.c $(HDEP) $(I)mail.h - -$(O)makemon.o: $(NHS)makemon.c $(HDEP) - -$(O)mapglyph.o: $(NHS)mapglyph.c $(HDEP) - -$(O)mcastu.o: $(NHS)mcastu.c $(HDEP) - -$(O)mhitm.o: $(NHS)mhitm.c $(HDEP) $(I)artifact.h - -$(O)mhitu.o: $(NHS)mhitu.c $(HDEP) $(I)artifact.h - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)mhitu.c - -$(O)minion.o: $(NHS)minion.c $(HDEP) - -$(O)mklev.o: $(NHS)mklev.c $(HDEP) - -$(O)mkmap.o: $(NHS)mkmap.c $(HDEP) $(I)sp_lev.h - -$(O)mkmaze.o: $(NHS)mkmaze.c $(HDEP) $(I)sp_lev.h - -$(O)mkobj.o: $(NHS)mkobj.c $(HDEP) $(I)artifact.h $(I)prop.h - -$(O)mkroom.o: $(NHS)mkroom.c $(HDEP) - -$(O)mon.o: $(NHS)mon.c $(HDEP) $(I)mfndpos.h - -$(O)mondata.o: $(NHS)mondata.c $(HDEP) - -$(O)monmove.o: $(NHS)monmove.c $(HDEP) $(I)mfndpos.h $(I)artifact.h - -$(O)monst.o: $(NHS)monst.c $(I)config.h $(I)permonst.h $(I)monsym.h \ - $(I)color.h - -$(O)monstr.o: $(NHS)monstr.c $(HDEP) - -$(O)mplayer.o: $(NHS)mplayer.c $(HDEP) - -$(O)mthrowu.o: $(NHS)mthrowu.c $(HDEP) - -$(O)muse.o: $(NHS)muse.c $(HDEP) - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)muse.c - -$(O)music.o: $(NHS)music.c $(HDEP) #interp.c - -$(O)o_init.o: $(NHS)o_init.c $(HDEP) - -$(O)objects.o: $(NHS)objects.c $(I)config.h $(I)obj.h $(I)objclass.h \ - $(I)prop.h $(I)skills.h $(I)color.h - $(CC) $(CFLAGS) $(INCLSPEC)$(NHS) $(OBJSPEC)$@ $(NHS)objects.c - -$(O)objnam.o: $(NHS)objnam.c $(HDEP) - -$(O)options.o: $(NHS)options.c $(HDEP) $(I)tcap.h $(I)config.h \ - $(I)objclass.h $(I)flag.h - -$(O)pager.o: $(NHS)pager.c $(HDEP) $(I)dlb.h - -$(O)pickup.o: $(NHS)pickup.c $(HDEP) - -$(O)pline.o: $(NHS)pline.c $(HDEP) - -$(O)polyself.o: $(NHS)polyself.c $(HDEP) - -$(O)potion.o: $(NHS)potion.c $(HDEP) - -$(O)pray.o: $(NHS)pray.c $(HDEP) - -$(O)priest.o: $(NHS)priest.c $(HDEP) $(I)mfndpos.h - -$(O)quest.o: $(NHS)quest.c $(HDEP) $(I)quest.h - -$(O)questpgr.o: $(NHS)questpgr.c $(HDEP) $(I)dlb.h - -$(O)read.o: $(NHS)read.c $(HDEP) - -$(O)rect.o: $(NHS)rect.c $(HDEP) - -$(O)region.o: $(NHS)region.c $(HDEP) - -$(O)restore.o: $(NHS)restore.c $(HDEP) $(I)tcap.h $(I)quest.h - -$(O)rnd.o: $(NHS)rnd.c $(HDEP) - -$(O)role.o: $(NHS)role.c $(HDEP) - -$(O)rumors.o: $(NHS)rumors.c $(HDEP) $(I)dlb.h - -$(O)save.o: $(NHS)save.c $(HDEP) $(I)quest.h - -$(O)shk.o: $(NHS)shk.c $(HDEP) - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)shk.c - -$(O)shknam.o: $(NHS)shknam.c $(HDEP) - -$(O)sit.o: $(NHS)sit.c $(HDEP) $(I)artifact.h - -$(O)sounds.o: $(NHS)sounds.c $(HDEP) - -$(O)sp_lev.o: $(NHS)sp_lev.c $(HDEP) $(I)sp_lev.h $(I)rect.h $(I)dlb.h - -$(O)spell.o: $(NHS)spell.c $(HDEP) - -$(O)steal.o: $(NHS)steal.c $(HDEP) - -$(O)steed.o: $(NHS)steed.c $(HDEP) - -$(O)sys.o: $(NHS)sys.c $(HDEP) - -$(O)teleport.o: $(NHS)teleport.c $(HDEP) - -$(O)timeout.o: $(NHS)timeout.c $(HDEP) - -$(O)topten.o: $(NHS)topten.c $(HDEP) $(I)dlb.h - -$(O)track.o: $(NHS)track.c $(HDEP) - -$(O)trap.o: $(NHS)trap.c $(HDEP) - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)trap.c - -$(O)u_init.o: $(NHS)u_init.c $(HDEP) - -$(O)uhitm.o: $(NHS)uhitm.c $(HDEP) - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)uhitm.c - -$(O)vault.o: $(NHS)vault.c $(HDEP) - -$(O)version.o: $(NHS)version.c $(HDEP) $(I)date.h $(I)patchlevel.h - -$(O)vision.o: $(NHS)vision.c $(HDEP) #$(I)vis_tab.h - -$(O)weapon.o: $(NHS)weapon.c $(HDEP) - -$(O)were.o: $(NHS)were.c $(HDEP) - -$(O)wield.o: $(NHS)wield.c $(HDEP) - -$(O)windows.o: $(NHS)windows.c $(HDEP) $(I)wintty.h - -$(O)wizard.o: $(NHS)wizard.c $(HDEP) - -$(O)worm.o: $(NHS)worm.c $(HDEP) - -$(O)worn.o: $(NHS)worn.c $(HDEP) - -$(O)write.o: $(NHS)write.c $(HDEP) - -$(O)zap.o: $(NHS)zap.c $(HDEP) - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)zap.c - -$(O)getline.o: $(TTY)getline.c $(HDEP) $(I)wintty.h - -$(O)termcap.o: $(TTY)termcap.c $(HDEP) $(I)wintty.h $(I)tcap.h - -$(O)topl.o: $(TTY)topl.c $(HDEP) $(I)wintty.h $(I)tcap.h - -$(O)wintty.o: $(TTY)wintty.c $(HDEP) $(I)wintty.h $(I)tcap.h \ - $(I)date.h $(I)patchlevel.h - -$(O)amitty.o: $(AMI)amitty.c $(HDEP) - -$(O)amistack.o: $(AMI)amistack.c - $(CC) $(CFLAGS3) $(CSYM) $(OBJSPEC)$@ $(AMI)amistack.c - -$(O)rip.o: $(NHS)rip.c $(HDEP) - - -$(I)config.h: $(I)config1.h $(I)tradstdc.h $(I)global.h - -setdate $(I)config.h - -c:wait 2 - -# onames.h handled at onames.h target, pm.h - -$(I)decl.h: $(I)quest.h $(I)spell.h $(I)color.h $(I)obj.h $(I)you.h - -setdate $(I)decl.h - -c:wait 2 - -$(I)global.h: $(I)coord.h $(I)pcconf.h $(I)amiconf.h - -setdate $(I)global.h - -c:wait 2 - -$(I)hack.h: $(I)config.h $(I)context.h $(I)trap.h $(I)decl.h $(I)dungeon.h - $(I)monsym.h $(I)mkroom.h $(I)objclass.h $(I)flag.h $(I)rm.h - $(I)vision.h $(I)display.h $(I)wintype.h $(I)engrave.h - $(I)rect.h $(I)region.h $(I)sys.h - -setdate $(I)hack.h - -c:wait 2 - -$(I)permonst.h: $(I)monattk.h $(I)monflag.h $(I)align.h - -setdate $(I)permonst.h - -c:wait 2 - -$(I)you.h: $(I)align.h $(I)attrib.h $(I)monst.h $(I)mextra.h $(I)youprop.h $(I)skills.h - -setdate $(I)you.h - -c:wait 2 - -# pm.h handled at target - -$(I)youprop.h: $(I)prop.h $(I)permonst.h $(I)mondata.h - -setdate $(I)youprop.h - -c:wait 2 - -$(I)display.h: $(I)vision.h $(I)mondata.h - -setdate $(I)display.h - -c:wait 2 - -$(I)dungeon.h: $(I)align.h - -setdate $(I)dungeon.h - -c:wait 2 - -$(I)engrave.h: $(I)rect.h - -setdate $(I)engrave.h - -c:wait 2 - -$(I)mextra.h: $(I)align.h - -setdate $(I)mextra.h - -c:wait 2 - -$(I)mondata.h: $(I)align.h - -setdate $(I)mondata.h - -c:wait 2 - -$(I)monst.h: $(I)align.h $(I)mextra.h - -setdate $(I)monst.h - -c:wait 2 - -$(I)pcconf.h: $(I)micro.h $(I)system.h - -setdate $(I)pcconf.h - -c:wait 2 - -$(I)rm.h: $(I)align.h - -setdate $(I)rm.h - -c:wait 2 - - -#notes -# install keeps doing re-install because it keeps rebuilding lev_comp??? -# fixed(?) - deleted setdate diff --git a/outdated/sys/amiga/Makefile.ami b/outdated/sys/amiga/Makefile.ami deleted file mode 100644 index d07a6633b..000000000 --- a/outdated/sys/amiga/Makefile.ami +++ /dev/null @@ -1,1578 +0,0 @@ -# NetHack Makefile. -# Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1991,1992,1993,1996. -# NetHack may be freely redistributed. See license for details. - -### -### INTRODUCTION -### - -# This makefile is arranged for compiling for the Amiga with SAS/C 6.51 but -# can be configured for compiling with Manx C 5 or commercial DICE with -# simple changes. The appropriate changes are identified by #[compiler] -# where compiler is one of: SAS6, MANX, or DICE; the options in this -# makefile as should be set according to the compiler being used. (But see -# note 3 below.) - -# Note: When using the Manx compiler, an alternate make utility is -# required. The bundled Aztec make is just too damaged. - -# Note 2: The #SFD_xxx lines are used with mkdmake to generate a DMake- -# compatible makefile (DMakefile) from this file. Any line beginning with -# #SFD_INSTEAD replaces, in DMakefile, the following line from Makefile.ami. -# #SFD_BEGIN, #SFD_ELSE, and #SFD_END bracket multi-line sections for the two -# makefile formats. -# When changing this file, #SFD_INSTEAD lines will need to be inserted for -# the following cases: -# - Dependencies with different numbers of filenames (both > 1) on -# either side. The #SFD_INSTEAD line should immediately precede -# the line with the colon, and should contain a double colon "::" -# instead of a single colon. -# - Special command lists that override the default. A line containing -# "#SFD_INSTEAD #none" should precede such a rule. If the rule is -# more than one line long, precede it with "#SFD_BEGIN" and -# "#SFD_ELSE", and follow it with "#SFD_END". -# - Files not in the src, sys/amiga, sys/share, or win/tty directories -# that rely on the default ".c.o" rule. Following the dependency -# should be "#SFD_INSTEAD " with the filename inserted -# into the default rule where appropriate, then a line contianing -# "#none". -# In any SFD_BEGIN/ELSE/END block added, put a '##' before every line -# between the BEGIN and ELSE. Any line that's really a comment needs three -# '#'s, e.g. "### DICE comment". - -# Note 2A: Whenever an SFD line/block is added, the appropriate repeat count -# in mkdmake must be changed. (The repeat count "0" meaning "repeat -# until end of file" doesn't work as advertised.) - -# Note 3: mkdmake will automatically substitute DICE flags, etc. for SAS -# where appropriate. Since the makefile is already set up for SAS, -# the only people who end up having to make changes here are Manx -# users (or people who want to change the defaults). - -### -### DIRECTORY STRUCTURE -### - -NH = NH: -SBIN = $(NH)sbin/ -SLIB = $(NH)slib/ -NETHACK = $(NH)NetHack/ -HACKEXE = $(NH)HackExe/ -AMI = $(NH)sys/amiga/ -DAT = $(NH)dat/ -DOC = $(NH)doc/ -I = $(NH)include/ -SHARE = $(NH)sys/share/ -NHS = $(NH)src/ -TTY = $(NH)win/tty/ -WSHARE = $(NH)win/share/ -UTIL = $(NH)util/ -O = $(NH)obj/ -OO = $(NH)objo/ -# NB: O and OO MUST be different directories - -### -### INVOCATION -### - -#[SAS6] -#MAKE = smake -#[MANX] -#MAKE = make -#[DICE] -#MAKE = dmake - -# Startup makefile with: -# -#[SAS6] -#[MANX] -# $(MAKE) -f $(AMI)Makefile.ami -# $(MAKE) -f $(AMI)Makefile.ami install -# -#[DICE] -# $(MAKE) -f $(AMI)DMakefile -# $(MAKE) -f $(AMI)DMakefile install -# -# -# You may use following targets on $(MAKE) command lines: -# all do it all (default) -# link just create binary from object files -# obj just create common object files -# obja just create amiga object files -# objs just create shared object files -# clean deletes the object files -# spotless deletes the object files, main binary, and more -# -# Note: We do not build the Guidebook here since it needs tbl -# (See the file sys/unix/Makefile.doc for more information) - -#X# Precompiled header files: -#X# $(HDEP) should appear in any dependency list for an object file where -#X# we would want to make use of the precompiled version of $(I)hack.h, -#X# while $(CSYM) should appear in the C compiler command line that creates -#X# any such object file. (Changes made here should agree with the $(HDEP): -#X# target that appears later in this makefile.) -#X# - -#SFD_BEGIN -## -###[DICE] -### If we were compiling with DICE and wanted to use the symbol table -### pre-loading feature, we would uncomment these following two lines. -## -##HDEP = $(I)hack.sym -##CSYM = -H$(I)hack.sym=hack.h -## -#SFD_ELSE - -#[SAS5] -# If we were to use the precompiled header file feature in a newer version -# of SAS/C, we would comment out these following two lines. -# If we don't use precompiled header files, we uncomment it as well. - -HDEP = $(I)hack.h $(I)pm.h $(I)onames.h -CSYM = - -#[MANX] -# If we were compiling with Aztec, and wanted to use the symbol table -# pre-loading feature, we would uncomment these following two lines. - -#HDEP = Ram:hack.sym -#CSYM = +IRam:hack.sym - -#SFD_END - -#Pathname for uudecode program: -UUDEC = uudecode - -# Flex/Bison command assignments -- Useful only if you have flex/bison -FLEX = flex -BISON = bison -# FBFIL and FBLIB may be used, if required by your version of flex or bison, -# to specify additional files or libraries to be linked with -FBFIL = -FBLIB = #lib lib:compat.lib - -# If you're compiling this on a 1.3 system, you'll have to uncomment the -# following (for use with the ifchange script below). Also useful instead of -# "protect ifchange +s" -EXECUTE = execute - -# Headers we depend on -AMDEP = $(AMI)winproto.h $(AMI)winext.h $(AMI)windefs.h $(I)winami.h - -# Pathname for the C compiler being used. - -#SFD_BEGIN -## -###[DICE] -##CC = dcc -##ASM = das -## -#SFD_ELSE - -#[SAS6] -CC = sc -ASM = asm - -#[MANX] -#CC = cc - -#SFD_END - -# Compilation flags for selected C Compiler: -# $(CFLAGS) should appear before filename arguments of $(CC) command line. - -#SFD_BEGIN -## -###[DICE] -##CFLAGS = -c -I$(I) -mC -mD -ms -// -##CFLAGS2 = -##WBCFLAGS = -c -I$(I) -mC -mD -ms -// -##WBC2FLAGS = -DCLI -##SPLFLAGS = -DSPLIT -## -#SFD_ELSE - -#[SAS6] -# Note: make sure your CLI stack size is large (at least 50K) or lev_comp -# and makedefs may fail terribly - stack checking is disabled. -# -# **** WARNING **** GST support is not fool proof. You must make makedefs -# without a GST first so that the generated headers -# that are part of the GST can be made. -# -#GSTSRC=$(AMI)gst.c -# -#GSTHEAD=$(I)hack.h $(I)pm.h $(I)trap.h $(I)onames.h \ -# $(AMI)winami.p $(AMI)amidos.p $(AMI)amiwind.p -# -#GSTFILE=$(O)NetHack.gst -# undefine this to not compile with GSTs -#GST=gst=$(GSTFILE) -# -DEBUG=debug=symbol -CPU=cpu=68000 -#OPTFLAGS=opt opttime optpeep optgo optinl optsched optcomp=10 optdep=5 optrdep=5 #optalias +OPTTIME -OPTSIZE -CFLAGS = data=far nominc $(DEBUG) idir=$(I) $(CPU) nostkchk nover \ - codename=nhcode dataname=nhdata strmerge $(OPTFLAGS) $(TILES) $(SAVEDS) \ - afp $(ERRREXX) $(GST) -# for files that are too large for the standard flags: -CFLAGS2 = code=far strmerge $(SAVEDS) -WBCFLAGS = ignore=217,62 data=far ansi nminc code=far idir=$(I) $(CPU) afp \ - $(DEBUG) $(ERRREXX) define=AMIGA $(GST) -XXX = data=far ansi nminc idir=$(I) $(CPU) afp opt optinline optinlocal \ - optloop opttime -WBC2FLAGS = define=CLI -SPLFLAGS = define=SPLIT #dollarok -#for amistack.c -CFLAGS3 = data=near dataname=__MERGED nominc $(DEBUG) idir=$(I) $(CPU) nover nostkchk \ - codename=nhcode strmerge $(OPTFLAGS) $(TILES) $(SAVEDS) \ - afp $(ERRREXX) $(GST) - -#[MANX] -#CFLAGS = -i$(I) -mc -md -ms -pa -ps -bs -wo -qq -#WBCFLAGS = -mc -md -ms -pa -ps -bs -wo -qq -pp - -#SFD_END - -# Assembly flags: - -#SFD_BEGIN -## -###[DICE] -##AFLAGS = -##AOBJSPEC = -o -## -#SFD_ELSE - -#[SAS6] -AFLAGS = #what to put here? -AOBJSPEC = -o - -#SFD_END - -# Components of various link command lines: -# $(LINK) should be the pathname of the linker being used (with any options -# that should appear at the beginning of the command line). The name of the -# output file should appear immediately after $(LNSPEC). $(LIN) should -# appear before the list of object files in each link command. $(LLINK) -# should appear as the list of object files in the link command line that -# creates the NetHack executable. $(LLIB) should appear at the end of each -# link command line. - -# Note: amiga.lib added due to missing prototypes/pragmas. -# Should be deleted when this is resolved. - -#SFD_BEGIN -## -###[DICE] -### If you have flex/bison libraries, use the second definition of FLLIB -### instead of the first. -## -##LINK = dcc -mD -##LIN = -##LLINK = @$(AMI)ami.lnk -##LLIB = -##FLLIB = -###FLLIB = -l$(FBLIB) -##OBJSPEC = -o -##PNSPEC = -o -##LNSPEC = -o -##CCLINK = dcc -##CLFLAGS = -I$(I) -mC -mD -ms -// -##INCLSPEC = -I -##DEFSPEC = -D -##IGNSPEC = -j -## -#SFD_ELSE - -#[SAS6] - -LINK = slink noicons verbose maxhunk 262144 stripdebug -LIN = from lib:catch.o -LLINK = with $(AMI)ami.lnk -LLIB = lib lib:scnb.lib BATCH #lib lib:amiga.lib BATCH #scnb.lib or sc.lib -FLLIB = $(FBLIB) lib Lib:sc.lib BATCH -OBJSPEC = objname= -PNSPEC = noicons to #pname= -LNSPEC = to -CCLINK = sc link -INCLSPEC = idir= -DEFSPEC = define= -IGNSPEC = ignore= -COMPACT_HEADERS=$(GSTFILE) - -#[MANX] - -#LINK = ln -g +q +ss -o -#LIN = -#LLINK = -f $(AMI)ami.lnk -#LLIB = -lcl16 -#FLLIB = -lcl16 -#OBJSPEC = -o -#PNSPEC = -o -#LNSPEC = -o -#CCLINK = cc -#INCLSPEC = -i -#DEFSPEC = -d -#IGNSPEC = -j - -#SFD_END - -### -### FILE LISTS -### - -# A more reasonable random number generator (recommended for the Amiga): - -RANDOBJ = $(O)random.o - -#SFD_INSTEAD #none -.PRECIOUS: $(I)config.h $(I)decl.h $(I)hack.h $(I)permonst.h $(I)you.h - -# Almost nothing below this line should have to be changed. -# (Exceptions are marked by [SAS6], [MANX], etc.) -# -# Other things that have to be reconfigured are in config.h, -# (amiconf.h, pcconf.h), and possibly system.h, tradstdc.h. - -# Object files for makedefs: - -MAKEOBJS = \ - $(OO)makedefs.o $(O)monst.o $(O)objects.o - -# Object files for special levels compiler: - -SPLEVOBJS = \ - $(OO)lev_yacc.o $(OO)lev_lex.o $(OO)lev_main.o \ - $(O)decl.o $(O)drawing.o $(O)monst.o \ - $(O)objects.o $(OO)panic.o - -# Object files for dungeon compiler - -DGNCOMPOBJS = \ - $(OO)dgn_yacc.o $(OO)dgn_lex.o $(OO)dgn_main.o $(O)alloc.o $(OO)panic.o - -# Object files for NetHack: - -COMMOBJ = \ - $(O)allmain.o $(O)alloc.o $(O)apply.o $(O)artifact.o \ - $(O)attrib.o $(O)ball.o $(O)bones.o $(O)botl.o \ - $(O)cmd.o $(O)dbridge.o $(O)decl.o $(O)detect.o \ - $(O)dig.o $(O)display.o $(O)dlb.o $(O)do.o \ - $(O)do_name.o $(O)do_wear.o $(O)dog.o $(O)dogmove.o \ - $(O)dokick.o $(O)dothrow.o $(O)drawing.o $(O)dungeon.o \ - $(O)eat.o $(O)end.o $(O)engrave.o $(O)exper.o \ - $(O)explode.o $(O)extralev.o $(O)files.o $(O)fountain.o \ - $(O)hack.o $(O)hacklib.o $(O)invent.o $(O)light.o \ - $(O)lock.o $(O)mail.o $(O)makemon.o $(O)mapglyph.o \ - $(O)mcastu.o $(O)mhitm.o $(O)mhitu.o $(O)minion.o \ - $(O)mklev.o $(O)mkmap.o $(O)mkmaze.o $(O)mkobj.o \ - $(O)mkroom.o $(O)mon.o $(O)mondata.o $(O)monmove.o \ - $(O)monst.o $(O)mplayer.o $(O)mthrowu.o $(O)muse.o \ - $(O)music.o $(O)o_init.o $(O)objects.o $(O)objnam.o \ - $(O)options.o $(O)pager.o $(O)pickup.o $(O)pline.o \ - $(O)polyself.o $(O)potion.o $(O)pray.o $(O)priest.o \ - $(O)quest.o $(O)questpgr.o $(O)read.o $(O)rect.o \ - $(O)region.o $(O)restore.o $(O)rnd.o $(O)role.o \ - $(O)rumors.o $(O)save.o $(O)shk.o $(O)shknam.o \ - $(O)sit.o $(O)sounds.o $(O)sp_lev.o $(O)spell.o \ - $(O)steal.o $(O)steed.o $(O)sys.o $(O)teleport.o \ - $(O)timeout.o $(O)topten.o $(O)track.o $(O)trap.o \ - $(O)u_init.o $(O)uhitm.o $(O)vault.o $(O)version.o \ - (O)vision.o $(O)weapon.o $(O)were.o $(O)wield.o \ - $(O)windows.o $(O)wizard.o $(O)worm.o $(O)worn.o \ - $(O)write.o $(O)zap.o - -MAKEDEFOBJ = \ - $(O)monstr.o - -AMIGAOBJ = \ - $(O)amidos.o $(O)amirip.o $(O)amistack.o \ - $(O)amiwind.o $(O)winami.o $(O)winchar.o $(O)winfuncs.o \ - $(O)winkey.o $(O)winamenu.o $(O)winreq.o $(O)winstr.o - -# Objects from assembly sources (because DMake can't handle default rules) -AMIGAOBJ2 = \ -# $(O)dispmap.o - -SHAREOBJ = \ - $(O)pcmain.o $(RANDOBJ) - -TTYOBJ = \ - $(O)getline.o $(O)termcap.o $(O)topl.o $(O)wintty.o $(O)amitty.o \ - $(O)rip.o - -# Yuck yuck yuck. Have to tell DMake where these are, since they're not -# all in the same place. -TTYSRC = \ - $(TTY)getline.c $(TTY)termcap.c $(TTY)topl.c $(TTY)wintty.c \ - $(AMI)amitty.c $(NHS)rip.c - -# All the object files for NetHack: - -HOBJ = $(COMMOBJ) $(AMIGAOBJ) $(AMIGAOBJ2) $(SHAREOBJ) $(MAKEDEFOBJ) $(TTYOBJ) - -### -### DATA FILES -### - -# quest files -ADFILES1= $(SLIB)Arc-fila.lev $(SLIB)Arc-filb.lev $(SLIB)Arc-loca.lev \ - $(SLIB)Arc-strt.lev -ADFILES= $(SLIB)Arc-goal.lev $(ADFILES1) - -BDFILES1= $(SLIB)Bar-fila.lev $(SLIB)Bar-filb.lev $(SLIB)Bar-loca.lev \ - $(SLIB)Bar-strt.lev -BDFILES= $(SLIB)Bar-goal.lev $(BDFILES1) - -CDFILES1= $(SLIB)Cav-fila.lev $(SLIB)Cav-filb.lev $(SLIB)Cav-loca.lev \ - $(SLIB)Cav-strt.lev -CDFILES= $(SLIB)Cav-goal.lev $(CDFILES1) - -HDFILES1= $(SLIB)Hea-fila.lev $(SLIB)Hea-filb.lev $(SLIB)Hea-loca.lev \ - $(SLIB)Hea-strt.lev -HDFILES= $(SLIB)Hea-goal.lev $(HDFILES1) - -KDFILES1= $(SLIB)Kni-fila.lev $(SLIB)Kni-filb.lev $(SLIB)Kni-loca.lev \ - $(SLIB)Kni-strt.lev -KDFILES= $(SLIB)Kni-goal.lev $(KDFILES1) - -MDFILES1= $(SLIB)Mon-fila.lev $(SLIB)Mon-filb.lev $(SLIB)Mon-loca.lev \ - $(SLIB)Mon-strt.lev -MDFILES= $(SLIB)Mon-goal.lev $(MDFILES1) - -PDFILES1= $(SLIB)Pri-fila.lev $(SLIB)Pri-filb.lev $(SLIB)Pri-loca.lev \ - $(SLIB)Pri-strt.lev -PDFILES= $(SLIB)Pri-goal.lev $(PDFILES1) - -RDFILES1= $(SLIB)Rog-fila.lev $(SLIB)Rog-filb.lev $(SLIB)Rog-loca.lev \ - $(SLIB)Rog-strt.lev -RDFILES= $(SLIB)Rog-goal.lev $(RDFILES1) - -RANFILES1= $(SLIB)Ran-fila.lev $(SLIB)Ran-filb.lev $(SLIB)Ran-loca.lev \ - $(SLIB)Ran-strt.lev -RANFILES= $(SLIB)Ran-goal.lev $(RANFILES1) - -SDFILES1= $(SLIB)Sam-fila.lev $(SLIB)Sam-filb.lev $(SLIB)Sam-loca.lev \ - $(SLIB)Sam-strt.lev -SDFILES= $(SLIB)Sam-goal.lev $(SDFILES1) - -TDFILES1= $(SLIB)Tou-fila.lev $(SLIB)Tou-filb.lev $(SLIB)Tou-loca.lev \ - $(SLIB)Tou-strt.lev -TDFILES= $(SLIB)Tou-goal.lev $(TDFILES1) - -VDFILES1= $(SLIB)Val-fila.lev $(SLIB)Val-filb.lev $(SLIB)Val-loca.lev \ - $(SLIB)Val-strt.lev -VDFILES= $(SLIB)Val-goal.lev $(VDFILES1) - -WDFILES1= $(SLIB)Wiz-fila.lev $(SLIB)Wiz-filb.lev $(SLIB)Wiz-loca.lev \ - $(SLIB)Wiz-strt.lev -WDFILES= $(SLIB)Wiz-goal.lev $(WDFILES1) - -XDFILES= $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(KDFILES) \ - $(MDFILES) $(PDFILES) $(RDFILES) $(RANFILES) $(SDFILES) $(TDFILES) \ - $(VDFILES) $(WDFILES) - -TILEFILES= \ - $(SBIN)txt2iff \ - $(NETHACK)tiles \ - $(NETHACK)tiles/objects.iff \ - $(NETHACK)tiles/monsters.iff \ - $(NETHACK)tiles/other.iff - -INSTDUNGEONFILES1= \ - $(SLIB)air.lev $(SLIB)asmodeus.lev $(SLIB)astral.lev \ - $(SLIB)baalz.lev $(SLIB)bigrm-1.lev $(SLIB)bigrm-2.lev \ - $(SLIB)bigrm-3.lev $(SLIB)bigrm-4.lev $(SLIB)bigrm-5.lev \ - $(SLIB)castle.lev $(SLIB)dungeon $(SLIB)earth.lev \ - $(SLIB)fakewiz1.lev $(SLIB)fakewiz2.lev $(SLIB)fire.lev \ - $(SLIB)juiblex.lev $(SLIB)knox.lev $(SLIB)medusa-1.lev \ - $(SLIB)medusa-2.lev $(SLIB)minend-1.lev $(SLIB)minend-2.lev \ - $(SLIB)minetn-1.lev $(SLIB)minetn-2.lev $(SLIB)minefill.lev \ - $(SLIB)options $(SLIB)oracle.lev $(SLIB)orcus.lev \ - $(SLIB)sanctum.lev $(SLIB)soko1-1.lev $(SLIB)soko1-2.lev \ - $(SLIB)soko2-1.lev $(SLIB)soko2-2.lev $(SLIB)soko3-1.lev \ - $(SLIB)soko3-2.lev $(SLIB)soko4-1.lev $(SLIB)soko4-2.lev \ - $(SLIB)tower1.lev $(SLIB)tower2.lev $(SLIB)tower3.lev \ - $(SLIB)valley.lev $(SLIB)water.lev $(SLIB)wizard1.lev \ - $(SLIB)wizard2.lev $(SLIB)wizard3.lev \ - $(XDFILES) - -INSTDUNGEONFILES= $(NETHACK)NetHack.cnf $(INSTDUNGEONFILES1) - - -INSTDATAFILES= \ - $(NETHACK)license $(NETHACK)logfile $(NETHACK)record \ - $(NETHACK)tomb.iff $(NETHACK)amii.hlp $(NETHACK)Recover.txt \ - $(NETHACK)GuideBook.txt $(NETHACK)NetHack.txt $(NETHACK)Install.ami - -LIBFILES= \ - $(INSTDUNGEONFILES1) \ - $(SLIB)cmdhelp $(SLIB)data $(SLIB)dungeon \ - $(SLIB)help $(SLIB)hh $(SLIB)history \ - $(SLIB)opthelp $(SLIB)oracles $(SLIB)rumors \ - $(SLIB)quest.dat $(SLIB)wizhelp - -### -### Getting down to business: -### - -#SFD_INSTEAD all: $(SBIN)lev_comp $(SBIN)dgn_comp $(SBIN)NetHack \ -all: $(COMPACT_HEADERS) $(SBIN)lev_comp $(SBIN)dgn_comp $(SBIN)NetHack \ - $(SBIN)dlb $(NETHACK)recover - -install: all inst-data inst-dungeon inst-fonts inst-tiles \ - $(NETHACK)nhdat $(NETHACK)NetHack - -$(SBIN)NetHack: $(HOBJ) $(AMI)ami.lnk - $(LINK) $(LNSPEC) $(SBIN)NetHack $(LIN) $(LLINK) $(LLIB) - -$(NETHACK)NetHack: $(SBIN)NetHack - copy $(SBIN)NetHack $(NETHACK)NetHack - -link: - $(LINK) $(LNSPEC) $(SBIN)NetHack $(LIN) $(LLINK) $(LLIB) - -$(AMI)ami.lnk: $(AMI)Makefile.ami - list to $(AMI)ami.lnk lformat="$(O)%s" $(O)\#?.o QUICK NOHEAD - -## dlb support -$(OO)dlb_main.o: $(UTIL)dlb_main.c $(HDEP) $(I)dlb.h $(I)date.h - $(CC) $(CFLAGS) $(OBJSPEC)$(OO)dlb_main.o $(UTIL)dlb_main.c - -$(SBIN)dlb: $(OO)dlb_main.o $(O)dlb.o $(O)alloc.o $(OO)panic.o - $(LINK) $(PNSPEC) $(SBIN)dlb $(LIN) $(OO)dlb_main.o $(O)dlb.o \ - $(O)alloc.o $(OO)panic.o $(LLIB) - -obj: $(HOBJ) - -obja: $(AMIGAOBJ) - -objs: $(SHAREOBJ) - - -#SFD_BEGIN -#SFD_ELSE -SUFFIXES = .lev .des -.des.lev: - $(SBIN)lev_comp $< -#SFD_END - - -# The default method for creating object files: - -#SFD_BEGIN -## -###[DICE] -## -##$(COMMOBJ): $(COMMOBJ:"$(O)*.o":"$(NHS)%1.c") -## $(CC) $(CFLAGS) $(CSYM) $(OBJSPEC)%(left) %(right) -## -##$(AMIGAOBJ): $(AMIGAOBJ:"$(O)*.o":"$(AMI)%1.c") -## $(CC) $(CFLAGS) $(CSYM) $(OBJSPEC)%(left) %(right) -## -##$(SHAREOBJ): $(SHAREOBJ:"$(O)*.o":"$(SHARE)%1.c") -## $(CC) $(CFLAGS) $(CSYM) $(OBJSPEC)%(left) %(right) -## -##$(TTYOBJ): $(TTYSRC) -## $(CC) $(CFLAGS) $(CSYM) $(OBJSPEC)%(left) %(right) -## -#SFD_ELSE - -#[SAS6] - -.c.o: - $(CC) $(CFLAGS) $(CSYM) $(OBJSPEC)$@ $< - -#SFD_END - - -clean: - -delete $(O)\#?.o $(OO)\#?.o - -spotless: clean - -delete $(SBIN)NetHack $(SBIN)lev_comp $(SBIN)makedefs $(SBIN)dgn_comp - -delete $(SBIN)dlb $(SBIN)txt2iff $(SBIN)splitter - -delete $(SBIN)tilemap - -delete $(SLIB)data $(SLIB)rumors - -delete $(SLIB)\#?.lev - -delete $(SLIB)dungeon - -delete $(SLIB)cmdhelp $(SLIB)help $(SLIB)hh $(SLIB)history - -delete $(SLIB)opthelp $(SLIB)options $(SLIB)oracles - -delete $(SLIB)quest.dat $(SLIB)wizhelp -# -delete $(SLIB)earth.lev $(SLIB)air.lev $(SLIB)fire.lev -# -delete $(SLIB)water.lev $(SLIB)astral.lev -# -delete $(SLIB)tower1.lev $(SLIB)tower2.lev $(SLIB)tower3.lev -# -delete $(SLIB)fakewiz1.lev $(SLIB)fakewiz2.lev -# -delete $(SLIB)medusa-1.lev $(SLIB)medusa-2.lev -# -delete $(SLIB)oracle.lev $(SLIB)wizard1.lev $(SLIB)wizard2.lev -# -delete $(SLIB)wizard3.lev $(DAT)dungeon.pdf $(SLIB)valley.lev -# -delete $(SLIB)minefill.lev -# -delete $(SLIB)minetn-1 $(SLIB)minetn-2 $(SLIB)minend-1 $(SLIB)minend-2 -# -delete $(SLIB)soko1-1.lev $(SLIB)soko1-2.lev $(SLIB)soko2-1.lev -# -delete $(SLIB)soko2-2.lev $(SLIB)soko3-1.lev $(SLIB)soko3-2.lev -# -delete $(SLIB)soko4-1.lev $(SLIB)soko4-2.lev -# -delete $(ADFILES) -# -delete $(BDFILES) -# -delete $(CDFILES) -# -delete $(HDFILES) -# -delete $(KDFILES) -# -delete $(MDFILES) -# -delete $(PDFILES) -# -delete $(RDFILES) -# -delete $(RANFILES) -# -delete $(SDFILES) -# -delete $(TDFILES) -# -delete $(VDFILES) -# -delete $(WDFILES) - -delete $(I)onames.h $(I)pm.h $(I)date.h - -delete $(NHS)tile.c $(NHS)monstr.c - -delete $(I)tile.h -# -echo to $(I)onames.h "" noline -# -wait 2 -# -echo to $(I)pm.h "" noline -# -wait 2 -# -setdate $(UTIL)makedefs.c -# -wait 2 - -# Creating precompiled version of $(I)hack.h to save disk I/O. - -#SFD_BEGIN -## -###[DICE] -### If we were compiling with DICE and wanted to use the symbol table -### pre-loading feature, we would technically not need a rule to make the -### precompiled header file, because DCC handles this automatically; -### however, we must delete the precompiled header file if any of the -### includes change, and we need to create it manually because the -### sys/amiga sources, compiled first, define things differently than the -### main sources want them. -## -##$(HDEP): $(I)hack.h $(I)pm.h $(I)onames.h -## -delete $(I)hack.sym -## echo to Ram:hackincl.c "#include " -## $(CC) $(CFLAGS) $(CSYM) $(OBJSPEC)Ram:hackincl.o Ram:hackincl.c -## -delete Ram:hackincl.c Ram:hackincl.o -## -#SFD_ELSE - -#X#[SAS5] -#X# If we were to use the precompiled header file feature of SAS/C, we -#X# would uncomment the following lines. (Also see defines for HDEP and -#X# CSYM near the beginning of this file, as these should be appropriately -#X# defined.) - -#X#$(HDEP): $(I)hack.h $(SBIN)makedefs -#X# echo to Ram:hackincl.c "#include <$(I)hack.h>" -#X# $(CC) $(CFLAGS) -ph $(OBJSPEC)$@ Ram:hackincl.c -#X# -delete Ram:hackincl.c - -#[MANX] -# If we were compiling with Aztec, and wanted to use the symbol table -# pre-loading feature, we would uncomment these following two lines. - -#$(HDEP): $(I)hack.h $(SBIN)makedefs -# $(CC) $(CFLAGS) -a $(OBJSPEC)Ram:hack.asm +h$@ $(I)hack.h -# -delete Ram:hack.asm - -#SFD_END - -# -# Please note: The dependency lines for the modules here are -# deliberately incorrect. Including "hack.h" in -# the dependency list would cause a dependency -# loop. -# - -$(SBIN)makedefs: $(MAKEOBJS) - $(LINK) $(LNSPEC) $(SBIN)makedefs $(LIN) $(MAKEOBJS) $(LLIB) - -$(OO)makedefs.o: $(UTIL)makedefs.c $(I)config.h $(I)permonst.h $(I)monsym.h \ - $(I)objclass.h $(I)patchlevel.h $(I)artilist.h - $(CC) $(DEFSPEC)MAKEDEFS_C $(CFLAGS) $(OBJSPEC)$@ $(UTIL)makedefs.c - -$(SBIN)lev_comp: $(SPLEVOBJS) - $(LINK) $(LNSPEC) $(SBIN)lev_comp $(LIN) $(SPLEVOBJS) $(FBFIL) $(FLLIB) - -$(SBIN)dgn_comp: $(DGNCOMPOBJS) - $(LINK) $(LNSPEC) $(SBIN)dgn_comp $(LIN) $(DGNCOMPOBJS) $(FBFIL) $(FLLIB) - -$(OO)lev_yacc.o: $(UTIL)lev_yacc.c $(HDEP) $(I)sp_lev.h $(I)pm.h $(I)onames.h -# setdate $(UTIL)lev_yacc.c - $(CC) $(DEFSPEC)LEV_LEX_C $(DEFSPEC)PREFIX="NH:slib/" $(CFLAGS) \ - $(DEFSPEC)alloca=malloc $(OBJSPEC)$@ $(UTIL)lev_yacc.c - -$(OO)lev_lex.o: $(UTIL)lev_lex.c $(HDEP) $(I)lev_comp.h $(I)sp_lev.h - $(CC) $(DEFSPEC)LEV_LEX_C $(CFLAGS) $(OBJSPEC)$@ $(UTIL)lev_lex.c - -$(OO)lev_main.o: $(UTIL)lev_main.c $(HDEP) $(I)pm.h $(I)onames.h $(I)date.h - $(CC) $(DEFSPEC)LEV_LEX_C $(DEFSPEC)AMIGA $(CFLAGS) $(OBJSPEC)$@ \ - $(UTIL)lev_main.c - -$(OO)dgn_yacc.o: $(UTIL)dgn_yacc.c $(HDEP) $(I)dgn_file.h $(I)patchlevel.h - $(CC) $(DEFSPEC)LEV_LEX_C $(CFLAGS) $(DEFSPEC)alloca=malloc \ - $(OBJSPEC)$@ $(UTIL)dgn_yacc.c - -$(OO)dgn_lex.o: $(UTIL)dgn_lex.c $(I)config.h $(I)dgn_comp.h $(I)dgn_file.h - $(CC) $(DEFSPEC)LEV_LEX_C $(CFLAGS) $(OBJSPEC)$@ $(UTIL)dgn_lex.c - -$(OO)dgn_main.o: $(UTIL)dgn_main.c $(I)config.h $(I)date.h - $(CC) $(DEFSPEC)LEV_LEX_C $(DEFSPEC)AMIGA $(CFLAGS) $(OBJSPEC)$@ \ - $(UTIL)dgn_main.c - -$(OO)panic.o: $(UTIL)panic.c $(HDEP) -#SFD_INSTEAD $(CC) $(CFLAGS) $(OBJSPEC)%(left) $(UTIL)panic.c -#none - -$(OO)recover.o: $(UTIL)recover.c $(I)config.h $(I)date.h - $(CC) $(DEFSPEC)LEV_LEX_C $(DEFSPEC)AMIGA $(CFLAGS) $(OBJSPEC)$@ \ - $(UTIL)recover.c - -$(NETHACK)recover: $(OO)recover.o - $(LINK) $(LNSPEC) $(NETHACK)recover $(LIN) $(OO)recover.o $(LLIB) - -# [OPTION] -- If you have flex/bison, leave these uncommented. Otherwise, -# comment them out and be careful! (You're not guaranteed to have the most -# up to date *_comp.c, *_comp.h and *_lex.c) - -$(I)lev_comp.h: $(UTIL)lev_yacc.c $(I)patchlevel.h - -$(UTIL)lev_yacc.c: $(UTIL)lev_comp.y $(I)patchlevel.h - $(BISON) -d $(UTIL)lev_comp.y -# copy y.tab.c $(UTIL)lev_yacc.c -# copy y.tab.h $(I)lev_comp.h - copy $(UTIL)lev_comp.tab.c $(UTIL)lev_yacc.c - copy $(UTIL)lev_comp.tab.h $(I)lev_comp.h -# delete y.tab.c -# delete y.tab.h - delete $(UTIL)lev_comp.tab.c - delete $(UTIL)lev_comp.tab.h - -$(UTIL)lev_lex.c: $(UTIL)lev_comp.l $(I)patchlevel.h - $(FLEX) $(UTIL)lev_comp.l - copy lex.yy.c $(UTIL)lev_lex.c - delete lex.yy.c - -$(I)dgn_comp.h: $(UTIL)dgn_yacc.c $(I)patchlevel.h - -$(UTIL)dgn_yacc.c: $(UTIL)dgn_comp.y $(I)patchlevel.h - $(BISON) -d $(UTIL)dgn_comp.y -# copy y.tab.c $(UTIL)dgn_yacc.c -# copy y.tab.h $(I)dgn_comp.h - copy $(UTIL)dgn_comp.tab.c $(UTIL)dgn_yacc.c - copy $(UTIL)dgn_comp.tab.h $(I)dgn_comp.h -# delete y.tab.c -# delete y.tab.h - delete $(UTIL)dgn_comp.tab.c - delete $(UTIL)dgn_comp.tab.h - -$(UTIL)dgn_lex.c: $(UTIL)dgn_comp.l $(I)patchlevel.h - $(FLEX) $(UTIL)dgn_comp.l - copy lex.yy.c $(UTIL)dgn_lex.c - delete lex.yy.c - -# -# The following include files depend on makedefs to be created. -# As a result, they are not defined in HACKINCL, instead, their -# dependencies are explicitly outlined here. -# - -# -# date.h should be remade any time any of the source or include code -# is modified. Unfortunately, this would make the contents of this -# file far more complex. Since "hack.h" depends on most of the include -# files, we kludge around this by making date.h dependent on hack.h, -# even though it doesn't include this file. -# - -#SFD_INSTEAD $(I)date.h $(DAT)options:: $(HDEP) $(SBIN)makedefs $(AMIGAOBJ) -$(I)date.h $(DAT)options: $(HDEP) $(SBIN)makedefs $(AMIGAOBJ) $(I)patchlevel.h - $(SBIN)makedefs -v - $(EXECUTE) $(AMI)ifchange MOVE $(I)t.date.h $(I)date.h - -wait 2 - -$(I)onames.h: $(SBIN)makedefs - $(SBIN)makedefs -o - $(EXECUTE) $(AMI)ifchange TOUCH $(I)t.onames.h $(I)onames.h $(I)decl.h - $(EXECUTE) $(AMI)ifchange MOVE $(I)t.onames.h $(I)onames.h - -wait 2 - -$(I)pm.h: $(SBIN)makedefs - $(SBIN)makedefs -p - $(EXECUTE) $(AMI)ifchange TOUCH $(I)t.pm.h $(I)pm.h $(I)decl.h $(I)youprop.h - $(EXECUTE) $(AMI)ifchange MOVE $(I)t.pm.h $(I)pm.h - -wait 2 - -$(SLIB)quest.dat: $(DAT)quest.txt $(SBIN)makedefs - $(SBIN)makedefs -q - -$(NHS)monstr.c: $(HDEP) $(SBIN)makedefs - $(SBIN)makedefs -m - -wait 2 - -$(SLIB)oracles: $(DAT)oracles.txt $(SBIN)makedefs - $(SBIN)makedefs -h - -wait 2 - -# -# The following programs vary depending on what OS you are using. -# As a result, they are not defined in HACKSRC and their dependencies -# are explicitly outlined here. -# - -$(O)amidos.o: $(AMI)amidos.c $(HDEP) - -$(O)amirip.o: $(AMI)amirip.c $(HDEP) - -$(O)aglue.o: $(AMI)aglue.a - $(ASM) $(AFLAGS) $(AOBJSPEC)$(O)aglue.o $(AMI)aglue.a - -$(O)winchar.o: $(AMI)winchar.c $(NHS)tile.c $(HDEP) - -$(NHS)tile.c: $(WSHARE)tilemap.c -#SFD_INSTEAD $(CCLINK) $(CLFLAGS) $(PNSPEC) $(SBIN)tilemap $(WSHARE)tilemap.c - $(CCLINK) $(CFLAGS) $(PNSPEC) $(SBIN)tilemap $(WSHARE)tilemap.c - $(SBIN)tilemap - -$(O)winstr.o: $(AMI)winstr.c $(HDEP) $(AMDEP) - -$(O)winreq.o: $(AMI)winreq.c $(HDEP) $(AMDEP) $(AMI)colorwin.c $(AMI)clipwin.c - -$(O)winfuncs.o: $(AMI)winfuncs.c $(HDEP) $(AMDEP) $(I)patchlevel.h - -$(O)winkey.o: $(AMI)winkey.c $(HDEP) $(AMDEP) - -$(O)winamenu.o: $(AMI)winamenu.c $(HDEP) $(AMDEP) - -$(O)winami.o: $(AMI)winami.c $(HDEP) $(AMDEP) #$(AMI)char.c $(AMI)randwin.c - -#$(O)amilib.o: $(AMI)amilib.c $(HDEP) $(AMDEP) - -$(O)amiwind.o: $(AMI)amiwind.c $(AMI)amimenu.c $(HDEP) $(AMDEP) - -$(O)amiwbench.o: $(AMI)amiwbench.c $(HDEP) - -$(O)random.o: $(SHARE)random.c - -$(O)pcmain.o: $(SHARE)pcmain.c $(HDEP) $(I)dlb.h - -$(O)dispmap.o: $(AMI)dispmap.s - $(ASM) $(AFLAGS) $(AOBJSPEC)$@ $< - -# Stuff to build the front ends -$(NETHACK)HackWB: $(OO)wb.o $(OO)wbx.o $(OO)loader.o $(OO)multi.o - $(LINK) $(LNSPEC) $(NETHACK)HackWB $(LIN) $(OO)wb.o $(OO)wbx.o \ - $(OO)loader.o $(OO)multi.o $(LLIB) - -$(NETHACK)HackCli: $(OO)cli.o $(OO)loader.o $(OO)multi.o - $(LINK) $(LNSPEC) $(NETHACK)HackCli $(LIN) $(OO)cli.o $(OO)loader.o \ - $(OO)multi.o $(LLIB) - -# This needs to exist to eliminate the HackWB startup message -#SFD_INSTEAD $(NETHACK)WBDefaults.def: $(NETHACK)WBDefaults.def -$(NETHACK)WBDefaults.def: - echo to $(NETHACK)WBDefaults.def - -WBH = $(AMI)wbdefs.h $(AMI)wbstruct.h $(AMI)wbprotos.h -ASP = $(AMI)splitter -$(OO)wb.o: $(WBH) $(AMI)wb.c $(AMI)wbwin.c $(AMI)wbdata.c $(AMI)wbgads.c \ - $(I)patchlevel.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)wb.o $(AMI)wb.c - -$(OO)wbx.o: $(WBH) $(AMI)wbcli.c $(AMI)wbwin.c $(AMI)wbdata.c \ - $(I)patchlevel.h $(I)date.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)wbx.o $(AMI)wbcli.c - -$(OO)loader.o: $(ASP)/loader.c $(ASP)/split.h $(ASP)/amiout.h $(ASP)/multi.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)loader.o $(ASP)/loader.c - -$(OO)multi.o: $(ASP)/multi.c $(ASP)/multi.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)multi.o $(ASP)/multi.c - -$(OO)cli.o: $(WBH) $(AMI)wbcli.c $(I)patchlevel.h $(I)date.h - $(CC) $(WBCFLAGS) $(WBC2FLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)cli.o \ - $(AMI)wbcli.c - -#### -# splitter support -$(SBIN)splitter: $(OO)splitter.o $(OO)arg.o - $(LINK) $(LNSPEC) $(SBIN)splitter $(LIN) $(OO)splitter.o $(OO)arg.o \ - $(LLIB) - -$(NETHACK)NetHack.dir: $(SBIN)splitter $(SBIN)NetHack - $(SBIN)splitter $(SBIN)NetHack - -$(OO)splitter.o: $(ASP)/splitter.c $(ASP)/split.h $(ASP)/amiout.h $(ASP)/arg.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)splitter.o \ - $(ASP)/splitter.c - -$(OO)arg.o: $(ASP)/arg.c $(ASP)/arg.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)arg.o $(ASP)/arg.c - -# Create/copy other stuff into NetHack: directory: - -$(NETHACK)tomb.iff: $(SBIN)xpm2iff $(AMI)grave16.xpm - $(SBIN)xpm2iff $(AMI)grave16.xpm $(NETHACK)tomb.iff - -$(OO)xpm2iff.o: $(AMI)xpm2iff.c - $(CC) $(CFLAGS) $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ $(AMI)xpm2iff.c - -$(SBIN)xpm2iff: $(OO)xpm2iff.o - $(LINK) $(LNSPEC) $@ $(LIN) $(OO)xpm2iff.o $(FLLIB) - -# Tile installation for the tile version of the game -inst-tiles: $(TILEFILES) - -#SFD_INSTEAD $(NETHACK)tiles: $(NETHACK)tiles -$(NETHACK)tiles: - -makedir $(NETHACK)tiles - -$(OO)txt2iff.o: $(AMI)txt2iff.c - $(CC) $(CFLAGS) $(CSYM) $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ \ - $(AMI)txt2iff.c - -$(OO)ppmwrite.o: $(WSHARE)ppmwrite.c - $(CC) $(CFLAGS) $(CSYM) $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ $(WSHARE)ppmwrite.c - -$(OO)tiletext.o: $(WSHARE)tiletext.c $(I)config.h $(WSHARE)tile.h - $(CC) $(CFLAGS) $(CSYM) $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ $(WSHARE)tiletext.c - -$(OO)tiletxt.o: $(WSHARE)tilemap.c $(I)hack.h - $(CC) $(CFLAGS) $(CSYM) $(DEFSPEC)TILETEXT $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ $(WSHARE)tilemap.c - -NAMEOBJS = $(O)drawing.o $(O)decl.o $(O)monst.o $(O)objects.o - -$(SBIN)txt2ppm: $(OO)ppmwrite.o $(NAMEOBJS) $(O)alloc.o $(OO)panic.o $(OO)tiletext.o $(OO)tiletxt.o - $(LINK) $(LNSPEC) $@ $(LIN) $(OO)ppmwrite.o $(NAMEOBJS) $(OO)tiletext.o $(OO)tiletxt.o $(O)alloc.o $(OO)panic.o $(FLLIB) - -$(SBIN)txt2iff: $(OO)txt2iff.o $(NAMEOBJS) $(OO)tiletext.o $(OO)tiletxt.o - $(LINK) $(LNSPEC) $@ $(LIN) $(OO)txt2iff.o $(NAMEOBJS) $(OO)tiletext.o \ - $(OO)tiletxt.o $(FLLIB) - -$(NETHACK)tiles/objects.iff: $(WSHARE)objects.txt $(SBIN)txt2iff - $(SBIN)txt2iff $(WSHARE)objects.txt $(NETHACK)tiles/objects.iff - -$(NETHACK)tiles/monsters.iff: $(WSHARE)monsters.txt $(SBIN)txt2iff - $(SBIN)txt2iff $(WSHARE)monsters.txt $(NETHACK)tiles/monsters.iff - -$(NETHACK)tiles/other.iff: $(WSHARE)other.txt $(SBIN)txt2iff - $(SBIN)txt2iff $(WSHARE)other.txt $(NETHACK)tiles/other.iff - -inst-dungeon: $(INSTDUNGEONFILES) - -$(NETHACK)options : $(DAT)options - copy $(DAT)options $@ - -# Create compiled dungeon files -BGM= $(SLIB)bigrm-2.lev $(SLIB)bigrm-3.lev $(SLIB)bigrm-4.lev $(SLIB)bigrm-5.lev -$(BGM): $(SLIB)bigrm-1.lev - -$(SLIB)bigrm-1.lev: $(DAT)bigroom.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)bigroom.des -#none - -$(SLIB)castle.lev: $(DAT)castle.des $(SBIN)lev_comp - -ENDGAME1= $(SLIB)air.lev $(SLIB)earth.lev $(SLIB)fire.lev $(SLIB)water.lev -$(ENDGAME1): $(SLIB)astral.lev - -$(SLIB)astral.lev: $(DAT)endgame.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)endgame.des -#none - -GEHENNOM1= $(SLIB)asmodeus.lev $(SLIB)baalz.lev $(SLIB)juiblex.lev \ - $(SLIB)orcus.lev $(SLIB)sanctum.lev -$(GEHENNOM1): $(SLIB)valley.lev - -$(SLIB)valley.lev: $(DAT)gehennom.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)gehennom.des -#none - -$(SLIB)knox.lev: $(DAT)knox.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)knox.des -#none - -MINES1= $(SLIB)minend-1.lev $(SLIB)minend-2.lev $(SLIB)minetn-1.lev $(SLIB)minetn-2.lev -$(MINES1): $(SLIB)minefill.lev - -$(SLIB)minefill.lev: $(DAT)mines.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)mines.des -#none - -$(SLIB)oracle.lev: $(DAT)oracle.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)oracle.des -#none - -TOWER1= $(SLIB)tower1.lev $(SLIB)tower2.lev -$(TOWER1): $(SLIB)tower3.lev - -$(SLIB)tower3.lev: $(DAT)tower.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)tower.des -#none - -WIZARD1= $(SLIB)wizard1.lev $(SLIB)wizard2.lev $(SLIB)wizard3.lev \ - $(SLIB)fakewiz1.lev -$(WIZARD1): $(SLIB)fakewiz2.lev - -$(SLIB)fakewiz2.lev: $(DAT)yendor.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)yendor.des -#none - -MEDUSA1= $(SLIB)medusa-1.lev -$(MEDUSA1): $(SLIB)medusa-2.lev - -$(SLIB)medusa-2.lev: $(DAT)medusa.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)medusa.des -#none - -SOKOBAN1= $(SLIB)soko1-1.lev $(SLIB)soko1-2.lev $(SLIB)soko2-1.lev \ - $(SLIB)soko2-2.lev $(SLIB)soko3-1.lev $(SLIB)soko3-2.lev \ - $(SLIB)soko4-1.lev -$(SOKOBAN1): $(SLIB)soko4-2.lev - -$(SLIB)soko4-2.lev: $(DAT)sokoban.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)sokoban.des -#none - -$(ADFILES1): $(SLIB)Arc-goal.lev - -$(SLIB)Arc-goal.lev: $(DAT)Arch.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Arch.des -#none - -$(BDFILES1): $(SLIB)Bar-goal.lev - -$(SLIB)Bar-goal.lev: $(DAT)Barb.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Barb.des -#none - -$(CDFILES1): $(SLIB)Cav-goal.lev - -$(SLIB)Cav-goal.lev: $(DAT)Caveman.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Caveman.des -#none - -$(HDFILES1): $(SLIB)Hea-goal.lev - -$(SLIB)Hea-goal.lev: $(DAT)Healer.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Healer.des -#none - -$(KDFILES1): $(SLIB)Kni-goal.lev - -$(SLIB)Kni-goal.lev: $(DAT)Knight.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Knight.des -#none - -$(MDFILES1): $(SLIB)Mon-goal.lev - -$(SLIB)Mon-goal.lev: $(DAT)Monk.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Monk.des -#none - -$(PDFILES1): $(SLIB)Pri-goal.lev - -$(SLIB)Pri-goal.lev: $(DAT)Priest.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Priest.des -#none - -$(RDFILES1): $(SLIB)Rog-goal.lev - -$(SLIB)Rog-goal.lev: $(DAT)Rogue.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Rogue.des -#none - -$(RANFILES1): $(SLIB)Ran-goal.lev - -$(SLIB)Ran-goal.lev: $(DAT)Ranger.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Ranger.des -#none - -$(SDFILES1): $(SLIB)Sam-goal.lev - -$(SLIB)Sam-goal.lev: $(DAT)Samurai.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Samurai.des -#none - -$(TDFILES1): $(SLIB)Tou-goal.lev - -$(SLIB)Tou-goal.lev: $(DAT)Tourist.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Tourist.des -#none - -$(VDFILES1): $(SLIB)Val-goal.lev - -$(SLIB)Val-goal.lev: $(DAT)Valkyrie.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Valkyrie.des -#none - -$(WDFILES1): $(SLIB)Wiz-goal.lev - -$(SLIB)Wiz-goal.lev: $(DAT)Wizard.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Wizard.des -#none - -$(SLIB)dungeon: $(DAT)dungeon.def $(SBIN)makedefs $(SBIN)dgn_comp - $(SBIN)makedefs -e - $(SBIN)dgn_comp $(DAT)dungeon.pdf - copy $(DAT)dungeon $(SLIB)dungeon - delete $(DAT)dungeon - -inst-data: $(INSTDATAFILES) - -$(NETHACK)amii.hlp: $(AMI)amii.hlp - copy $(AMI)amii.hlp $@ - -#$(NETHACK)data: $(DAT)data -# copy $(DAT)data $@ - -$(SLIB)data: $(DAT)data.base $(I)config.h $(SBIN)makedefs - $(SBIN)makedefs -d - -#$(NETHACK)rumors: $(DAT)rumors -# copy $(DAT)rumors $@ - -$(SLIB)rumors: $(DAT)rumors.tru $(DAT)rumors.fal $(SBIN)makedefs - $(SBIN)makedefs -r - -$(SLIB)cmdhelp: $(DAT)cmdhelp - copy $(DAT)cmdhelp $@ - -$(SLIB)help: $(DAT)help - copy $(DAT)help $@ - -$(SLIB)hh: $(DAT)hh - copy $(DAT)hh $@ - -$(NETHACK)HackWB.hlp: $(AMI)HackWB.hlp - copy $(AMI)HackWB.hlp $@ - -$(SLIB)history: $(DAT)history - copy $(DAT)history $@ - -$(NETHACK)license: $(DAT)license - copy $(DAT)license $@ - -$(SLIB)opthelp: $(DAT)opthelp - copy $(DAT)opthelp $@ - -$(NETHACK)Recover.txt: $(DOC)Recover.txt - copy $(DOC)Recover.txt $@ - -$(NETHACK)GuideBook.txt: $(DOC)GuideBook.txt - copy $(DOC)GuideBook.txt $@ - -$(NETHACK)NetHack.txt: $(DOC)NetHack.txt - copy $(DOC)NetHack.txt $@ - -$(NETHACK)Install.ami: $(AMI)Install.ami - copy $(AMI)Install.ami $@ - -#SFD_INSTEAD $(NETHACK)logfile: $(NETHACK)logfile -$(NETHACK)logfile: - echo to $@ - -#SFD_INSTEAD $(NETHACK)record: $(NETHACK)record -$(NETHACK)record: - echo to $@ - -$(SLIB)wizhelp: $(DAT)wizhelp - copy $(DAT)wizhelp $@ - -# Create the directories here because NetHack.cnf puts them there by default -$(NETHACK)NetHack.cnf: $(AMI)NetHack.cnf - copy $(AMI)NetHack.cnf $@ - -makedir $(NETHACK)save - -makedir $(NETHACK)levels - -#SFD_BEGIN -#SFD_ELSE -$(O)NetHack.gst: $(GSTSRC) $(I)hack.h - sc makegst=$(GSTFILE) $(CFLAGS) $(GSTSRC) -#SFD_END - -# Unpack and install fonts - -INSTFONTFILES= $(NETHACK)hack.font $(NETHACK)hack $(NETHACK)hack/8 - -inst-fonts: $(INSTFONTFILES) - -$(NETHACK)hack/8: $(AMI)amifont8.uu $(NETHACK)hack - $(UUDEC) $(AMI)amifont8.uu - copy 8 $(NETHACK)hack/8 - delete 8 - -$(NETHACK)hack.font: $(AMI)amifont.uu - $(UUDEC) $(AMI)amifont.uu - copy hack.font $(NETHACK)hack.font - delete hack.font - -#SFD_INSTEAD $(NETHACK)hack: $(NETHACK)hack -$(NETHACK)hack: - -makedir $@ - -INSTICONFILES= \ - $(NETHACK)default.icon $(NETHACK)NetHack.info $(NETHACK)NewGame.info \ - $(NETHACK)HackWB.info - -inst-icons: $(INSTICONFILES) - -# Unpack the icons into place - -$(NETHACK)default.icon: $(AMI)dflticon.uu - $(UUDEC) $(AMI)dflticon.uu -# copy default.icon $(NETHACK)default.icon -# delete default.icon - -$(NETHACK)NetHack.info: $(AMI)NHinfo.uu - $(UUDEC) $(AMI)NHinfo.uu -# copy NetHack.info $(NETHACK)NetHack.info -# delete NetHack.info - -$(NETHACK)NewGame.info: $(AMI)NewGame.uu - $(UUDEC) $(AMI)NewGame.uu -# copy NewGame.info $(NETHACK)NewGame.info -# delete NewGame.info - -$(NETHACK)HackWB.info: $(AMI)HackWB.uu - $(UUDEC) $(AMI)HackWB.uu -# copy HackWB.info $(NETHACK)HackWB.info -# delete HackWB.info - -# If DLB is defined, create the nhdat library file in the playground -# directory. If not, move all the data files there. -$(NETHACK)nhdat: $(LIBFILES) $(SBIN)dlb - list to T:nhdat.lst $(SLIB) QUICK NOHEAD FILES - echo >T:make-nhdat $(SBIN)dlb cCfI $(SLIB) $(NETHACK)nhdat T:nhdat.lst - echo >>T:make-nhdat if not exists $(NETHACK)nhdat - echo >>T:make-nhdat copy $(SLIB)\#? $(NETHACK) - echo >>T:make-nhdat endif - execute T:make-nhdat - -delete T:make-nhdat - -# DO NOT DELETE THIS LINE - -$(O)allmain.o: $(NHS)allmain.c $(HDEP) - -$(O)alloc.o: $(NHS)alloc.c $(I)config.h - -$(O)apply.o: $(NHS)apply.c $(HDEP) -#SFD_INSTEAD #none - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)apply.c - -$(O)artifact.o: $(NHS)artifact.c $(HDEP) $(I)artifact.h $(I)artilist.h - -$(O)attrib.o: $(NHS)attrib.c $(HDEP) $(I)artifact.h - -$(O)ball.o: $(NHS)ball.c $(HDEP) - -$(O)bones.o: $(NHS)bones.c $(HDEP) - -$(O)botl.o: $(NHS)botl.c $(HDEP) - -$(O)cmd.o: $(NHS)cmd.c $(HDEP) $(I)func_tab.h - -$(O)dbridge.o: $(NHS)dbridge.c $(HDEP) - -$(O)decl.o: $(NHS)decl.c $(HDEP) $(I)quest.h - -$(O)detect.o: $(NHS)detect.c $(HDEP) $(I)artifact.h - -$(O)dig.o: $(NHS)dig.c $(HDEP) - -$(O)display.o: $(NHS)display.c $(HDEP) - -$(O)dlb.o: $(NHS)dlb.c $(HDEP) $(I)dlb.h - -$(O)do.o: $(NHS)do.c $(HDEP) - -$(O)do_name.o: $(NHS)do_name.c $(HDEP) - -$(O)do_wear.o: $(NHS)do_wear.c $(HDEP) - -$(O)dog.o: $(NHS)dog.c $(HDEP) - -$(O)dogmove.o: $(NHS)dogmove.c $(HDEP) $(I)mfndpos.h - -$(O)dokick.o: $(NHS)dokick.c $(HDEP) - -$(O)dothrow.o: $(NHS)dothrow.c $(HDEP) - -$(O)drawing.o: $(NHS)drawing.c $(HDEP) $(I)tcap.h - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)drawing.c - -$(O)dungeon.o: $(NHS)dungeon.c $(HDEP) $(I)dgn_file.h $(I)dlb.h - -$(O)eat.o: $(NHS)eat.c $(HDEP) - -$(O)end.o: $(NHS)end.c $(HDEP) $(I)dlb.h - -$(O)engrave.o: $(NHS)engrave.c $(HDEP) - -$(O)exper.o: $(NHS)exper.c $(HDEP) - -$(O)explode.o: $(NHS)explode.c $(HDEP) - -$(O)extralev.o: $(NHS)extralev.c $(HDEP) - -$(O)files.o: $(NHS)files.c $(HDEP) $(I)dlb.h $(I)date.h - -$(O)fountain.o: $(NHS)fountain.c $(HDEP) - -$(O)hack.o: $(NHS)hack.c $(HDEP) - -$(O)hacklib.o: $(NHS)hacklib.c $(HDEP) - -$(O)invent.o: $(NHS)invent.c $(HDEP) $(I)artifact.h - -$(O)light.o: $(NHS)light.c $(HDEP) - -$(O)lock.o: $(NHS)lock.c $(HDEP) - -$(O)mail.o: $(NHS)mail.c $(HDEP) $(I)mail.h - -$(O)makemon.o: $(NHS)makemon.c $(HDEP) - -$(O)mapglyph.o: $(NHS)mapglyph.c $(HDEP) - -$(O)mcastu.o: $(NHS)mcastu.c $(HDEP) - -$(O)mhitm.o: $(NHS)mhitm.c $(HDEP) $(I)artifact.h - -$(O)mhitu.o: $(NHS)mhitu.c $(HDEP) $(I)artifact.h - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)mhitu.c - -$(O)minion.o: $(NHS)minion.c $(HDEP) - -$(O)mklev.o: $(NHS)mklev.c $(HDEP) - -$(O)mkmap.o: $(NHS)mkmap.c $(HDEP) $(I)sp_lev.h - -$(O)mkmaze.o: $(NHS)mkmaze.c $(HDEP) $(I)sp_lev.h - -$(O)mkobj.o: $(NHS)mkobj.c $(HDEP) $(I)artifact.h $(I)prop.h - -$(O)mkroom.o: $(NHS)mkroom.c $(HDEP) - -$(O)mon.o: $(NHS)mon.c $(HDEP) $(I)mfndpos.h - -$(O)mondata.o: $(NHS)mondata.c $(HDEP) - -$(O)monmove.o: $(NHS)monmove.c $(HDEP) $(I)mfndpos.h $(I)artifact.h - -$(O)monst.o: $(NHS)monst.c $(I)config.h $(I)permonst.h $(I)monsym.h $(I)color.h - -$(O)monstr.o: $(NHS)monstr.c $(HDEP) -#SFD_INSTEAD $(CC) $(CFLAGS) $(OBJSPEC)%(left) $(NHS)monstr.c -#none - -$(O)mplayer.o: $(NHS)mplayer.c $(HDEP) - -$(O)mthrowu.o: $(NHS)mthrowu.c $(HDEP) - -$(O)muse.o: $(NHS)muse.c $(HDEP) - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)muse.c - -$(O)music.o: $(NHS)music.c $(HDEP) #interp.c - -$(O)o_init.o: $(NHS)o_init.c $(HDEP) - -$(O)objects.o: $(NHS)objects.c $(I)config.h $(I)obj.h $(I)objclass.h \ - $(I)prop.h $(I)skills.h $(I)color.h -#SFD_INSTEAD #none - $(CC) $(CFLAGS) $(INCLSPEC)$(NHS) $(OBJSPEC)$@ $(NHS)objects.c - -$(O)objnam.o: $(NHS)objnam.c $(HDEP) - -$(O)options.o: $(NHS)options.c $(HDEP) $(I)tcap.h $(I)config.h \ - $(I)objclass.h $(I)flag.h - -$(O)pager.o: $(NHS)pager.c $(HDEP) $(I)dlb.h - -$(O)pickup.o: $(NHS)pickup.c $(HDEP) - -$(O)pline.o: $(NHS)pline.c $(HDEP) - -$(O)polyself.o: $(NHS)polyself.c $(HDEP) - -$(O)potion.o: $(NHS)potion.c $(HDEP) - -$(O)pray.o: $(NHS)pray.c $(HDEP) - -$(O)priest.o: $(NHS)priest.c $(HDEP) $(I)mfndpos.h - -$(O)quest.o: $(NHS)quest.c $(HDEP) $(I)quest.h - -$(O)questpgr.o: $(NHS)questpgr.c $(HDEP) $(I)dlb.h - -$(O)read.o: $(NHS)read.c $(HDEP) - -$(O)rect.o: $(NHS)rect.c $(HDEP) - -$(O)region.o: $(NHS)region.c $(HDEP) - -$(O)restore.o: $(NHS)restore.c $(HDEP) $(I)tcap.h $(I)quest.h - -$(O)rnd.o: $(NHS)rnd.c $(HDEP) - -$(O)role.o: $(NHS)role.c $(HDEP) - -$(O)rumors.o: $(NHS)rumors.c $(HDEP) $(I)dlb.h - -$(O)save.o: $(NHS)save.c $(HDEP) $(I)quest.h - -$(O)shk.o: $(NHS)shk.c $(HDEP) -#SFD_INSTEAD #none - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)shk.c - -$(O)shknam.o: $(NHS)shknam.c $(HDEP) - -$(O)sit.o: $(NHS)sit.c $(HDEP) $(I)artifact.h - -$(O)sounds.o: $(NHS)sounds.c $(HDEP) - -$(O)sp_lev.o: $(NHS)sp_lev.c $(HDEP) $(I)sp_lev.h $(I)rect.h $(I)dlb.h - -$(O)spell.o: $(NHS)spell.c $(HDEP) - -$(O)steal.o: $(NHS)steal.c $(HDEP) - -$(O)steed.o: $(NHS)steed.c $(HDEP) - -$(O)sys.o: $(NHS)sys.c $(HDEP) - -$(O)teleport.o: $(NHS)teleport.c $(HDEP) - -$(O)timeout.o: $(NHS)timeout.c $(HDEP) - -$(O)topten.o: $(NHS)topten.c $(HDEP) $(I)dlb.h - -$(O)track.o: $(NHS)track.c $(HDEP) - -$(O)trap.o: $(NHS)trap.c $(HDEP) -#SFD_INSTEAD #none - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)trap.c - -$(O)u_init.o: $(NHS)u_init.c $(HDEP) - -$(O)uhitm.o: $(NHS)uhitm.c $(HDEP) - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)uhitm.c - -$(O)vault.o: $(NHS)vault.c $(HDEP) - -$(O)version.o: $(NHS)version.c $(HDEP) $(I)date.h $(I)patchlevel.h - -# DMake doesn't grok mid-line comments -#SFD_INSTEAD $(O)vision.o: $(NHS)vision.c $(HDEP) -$(O)vision.o: $(NHS)vision.c $(HDEP) #$(I)vis_tab.h - -$(O)weapon.o: $(NHS)weapon.c $(HDEP) - -$(O)were.o: $(NHS)were.c $(HDEP) - -$(O)wield.o: $(NHS)wield.c $(HDEP) - -$(O)windows.o: $(NHS)windows.c $(HDEP) $(I)wintty.h - -$(O)wizard.o: $(NHS)wizard.c $(HDEP) - -$(O)worm.o: $(NHS)worm.c $(HDEP) - -$(O)worn.o: $(NHS)worn.c $(HDEP) - -$(O)write.o: $(NHS)write.c $(HDEP) - -$(O)zap.o: $(NHS)zap.c $(HDEP) - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)zap.c - -$(O)getline.o: $(TTY)getline.c $(HDEP) $(I)wintty.h - -$(O)termcap.o: $(TTY)termcap.c $(HDEP) $(I)wintty.h $(I)tcap.h - -$(O)topl.o: $(TTY)topl.c $(HDEP) $(I)wintty.h $(I)tcap.h - -$(O)wintty.o: $(TTY)wintty.c $(HDEP) $(I)wintty.h $(I)tcap.h \ - $(I)date.h $(I)patchlevel.h - -$(O)amitty.o: $(AMI)amitty.c $(HDEP) - -$(O)amistack.o: $(AMI)amistack.c - $(CC) $(CFLAGS3) $(CSYM) $(OBJSPEC)$@ $(AMI)amistack.c - -$(O)rip.o: $(NHS)rip.c $(HDEP) - - -$(I)config.h: $(I)config1.h $(I)tradstdc.h $(I)global.h - -setdate $(I)config.h - -wait 2 - -# onames.h handled at onames.h target, pm.h - -$(I)decl.h: $(I)quest.h $(I)spell.h $(I)color.h $(I)obj.h $(I)you.h - -setdate $(I)decl.h - -wait 2 - -$(I)global.h: $(I)coord.h $(I)pcconf.h $(I)amiconf.h - -setdate $(I)global.h - -wait 2 - -$(I)hack.h: $(I)config.h $(I)context.h $(I)trap.h $(I)decl.h $(I)dungeon.h \ - $(I)monsym.h $(I)mkroom.h $(I)objclass.h $(I)flag.h $(I)rm.h \ - $(I)vision.h $(I)display.h $(I)wintype.h $(I)engrave.h \ - $(I)rect.h $(I)region.h $(I)sys.h - -setdate $(I)hack.h - -wait 2 - -$(I)permonst.h: $(I)monattk.h $(I)monflag.h $(I)align.h - -setdate $(I)permonst.h - -wait 2 - -$(I)you.h: $(I)align.h $(I)attrib.h $(I)monst.h $(I)mextra.h $(I)youprop.h $(I)skills.h - -setdate $(I)you.h - -wait 2 - -# pm.h handled at target - -$(I)youprop.h: $(I)prop.h $(I)permonst.h $(I)mondata.h - -setdate $(I)youprop.h - -wait 2 - -$(I)display.h: $(I)vision.h $(I)mondata.h - -setdate $(I)display.h - -wait 2 - -$(I)dungeon.h: $(I)align.h - -setdate $(I)dungeon.h - -wait 2 - -$(I)engrave.h: $(I)rect.h - -setdate $(I)engrave.h - -wait 2 - -$(I)mextra.h: $(I)align.h - -setdate $(I)mextra.h - -wait 2 - -$(I)mondata.h: $(I)align.h - -setdate $(I)mondata.h - -wait 2 - -$(I)monst.h: $(I)align.h $(I)mextra.h - -setdate $(I)monst.h - -wait 2 - -$(I)pcconf.h: $(I)micro.h $(I)system.h - -setdate $(I)pcconf.h - -wait 2 - -$(I)rm.h: $(I)align.h - -setdate $(I)rm.h - -wait 2 - - -#notes -# install keeps doing re-install because it keeps rebuilding lev_comp??? -# fixed(?) - deleted setdate -# make nhdat rebuils sys/amiga objects diff --git a/outdated/sys/amiga/NetHack.cnf b/outdated/sys/amiga/NetHack.cnf deleted file mode 100644 index 89794c094..000000000 --- a/outdated/sys/amiga/NetHack.cnf +++ /dev/null @@ -1,213 +0,0 @@ -# A '#' at the beginning of a line means the rest of the line is a comment. - -# This is an example configuration file. -# If several people are to use it, don't specify "name" or personal -# prefences like "dogname" or "packorder" in OPTIONS. - -# To change configuration, comment out the unwanted configurations, and -# remove the comment from the configuration you want. - -# Some options to set personal preferences. If several people are to -# use it, options like these should not be set here - use the command line -#OPTIONS=name:Janet-V,female,dogname:Fido,fruit:apricot -#OPTIONS=packorder:")[%?+/=!(*0_`,scores:10t/2a,noverbose -#OPTIONS=gender:male -#OPTIONS=role:random -#OPTIONS=race:random -#OPTIONS=align:chaotic -# Other general options -#OPTIONS=time,rest_on_space,noautopickup - -# The search path for files like record, help, opthelp, etc. -PATH=NetHack: - -# My own setup -#OPTIONS=nolegacy,fruit:lemon,time,autopickup,checkpoint,showexp,showscore,standout,nonews -#OPTIONS=nomail,flush,eight_bit_tty,scores:10t/2a,pickup_types:$,suppress_alert:3.3.0,autoquiver - -# The windowtype option must be set before any options regarding colors and palette -# are set otherwise previously set values will be overridden by the defaults -# -# The font version of the game -OPTIONS=windowtype:amii -# -# New tile version of the game -#OPTIONS=windowtype:amitile -# -# A hard disk configuration. -# -HACKDIR=NetHack: -LEVELS=Nethack:Levels -SAVE=Nethack:Save -BONESDIR=Nethack:Levels -SCOREDIR=Nethack: -LOCKDIR=Nethack: -CONFIGDIR=Nethack: -DATADIR=Nethack: -TROUBLEDIR=Nethack: - -# *** CHARACTER GRAPHICS *** -# -# See the on-line help or the Guidebook for which symbols are in which -# positions. -# -# Note that the hack.font has special graphics characters from 192 on. - -# An example using the hack.font graphics character set: -DUNGEON = 032 192 193 194 195 196 197 198 216 214 \ - 215 213 217 145 146 147 148 035 035 217 \ - 218 229 060 062 060 062 095 124 092 035 \ - 123 125 042 125 042 042 035 035 046 035 \ - 125 - -TRAPS = 094 094 094 094 094 094 094 094 094 094 \ - 094 094 094 094 094 094 094 034 094 094 \ - 094 094 - -EFFECTS = 241 240 242 243 042 033 123 125 \ - 064 038 042 035 \ - 244 245 246 247 239 248 249 250 \ - 230 234 231 236 212 237 232 235 233 - -WARNINGS = 048 049 050 051 052 053 - -# Monitors vary greatly in their color response. If the default colors -# are not good on your monitor, here are some other alternatives for the -# font version of the game: -# -# Last color of the palette is always used for the cursor. -# -#CBM 1960, set color/contrast for good pure red, green, and blue. True colors. -#PENS=000,fff,a61,7bb,0f0,e0c,00f,f00 -#CBM 1960, set color/contrast as above, better colors for NetHack. -#PENS=667,fff,da1,7bb,2f0,e0d,0af,f42 -#and other suggestions: -#PENS=888,ffc,840,0b8,4e4,e8b,7be,a04 -#PENS=000,fff,830,7ae,181,c06,23e,c00 -# -# For an "interlaced"+ line screen, the default font is courier:13. If you want -# a different font, set it here. The format is "fontname.font:size"; i.e. the -# .font extension is required. -#FONT=courier.font:13 -#FONT=topaz.font:8 -# -# Proportional fonts such as CGTimes are probably not a good idea because they -# result in many things not being spaced out correctly. -#FONT=CGTimes.font:15 -# -# This sized proportional font is readable, but still has spacing problems -#FONT=CGTimes.font:21 -# -# FOR AGA OR OTHER DISPLAYS CAPABLE OF 5 OR MORE PLANES... -# -# For a screen of depth 5 the following dripens provide a brown border -# using pens 16-31. -# -# Pens 16-31 can be redefined with PENS= if you want different colors, -# using the PENS= values below for a 4 plane screen as the first 16 colors. -# -#DEPTH=5 -#DRIPENS=0,0,0,17,27,23,1,23,15,0,23,27 -# -# The APEN and BPEN values in the various types of windows can be set in -# the manner shown below. These values are for the 16 color version of -# the tile game. -# -# These values are specified as APEN,BPEN (foreground,background) -# -#MSGPENS=1,12 -#STATUSPENS=1,12 -#MENUPENS=1,23 -#TEXTPENS=1,23 -#OTHERPENS=1,23 -# -# FOR ECS OR OTHERS ONLY CAPABLE OF 4 PLANES... -# -# These values work good for the TILE version of the game on ECS machines -# These are the default values for reference purposes. -# -#DEPTH=4 -#defaults for tilemode: -#PENS=000,fff,0bf,f60,00f,090,69b,f00,6f0,ff0,f0f,940,466,c40,ddb,fb9 -#DRIPENS=0,1,0,2,4,12,14,12,7,1,12,4 -#defaults for fontmode: -#PENS=000,fff,830,7ac,181,c06,23e,c00 -#DRIPENS=0,6,2,1,6,3,1,3,7,1,3,6 -# -# The APEN and BPEN values in the various types of windows can be set in -# the manner shown below. These values are for a 32 color version of -# the tile game. -# -# These values are specified as APEN,BPEN (foreground,background) -# -#MSGPENS=1,12 -#STATUSPENS=1,12 -#MENUPENS=0,14 -#TEXTPENS=0,14 -#OTHERPENS=1,12 -# -# New alternative color scheme for 16 color font mode. -# This changes the colors of monsters, objects etc. -# -# FGPENS and BGPENS define APEN and BPEN for objects and monsters on the map. -# The colors are in the following order: -# black, red, green, brown, blue, magenta, cyan, gray, no color, orange, -# bright green, yellow, bright blue, bright magenta, bright cyan, white -# -DEPTH=4 -PENS=000,fff,830,7ac,181,c06,23e,c00,888,f60,4f4,ff0,4af,f8f,8ff,f00 -FGPENS= 0, 7, 4, 2, 6, 5, 3, 8, 1, 9,10,11,12,13,14, 1 -BGPENS= 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -# -# Screen mode selections below should all work for either the font or tile -# version of the game. Other modes can be tried and as long as they are at -# least 640x200, the game should adapt to them... -# -# Select screenmode with a requester -#SCREENMODE=Req -# NTSC_MONITOR_ID -#SCREENMODE=0x00019000 -# PAL_MONITOR_ID -#SCREENMODE=0x00029000 -# NTSC_MONITOR_ID+LACE -#SCREENMODE=0x00019004 -# PAL_MONITOR_ID+LACE -#SCREENMODE=0x00029004 -# NTSC_MONITOR_ID+HIRES+LACE -#SCREENMODE=0x00019024 -# PAL_MONITOR_ID+HIRES+LACE -#SCREENMODE=0x00029024 -# VGA_MONITOR_ID -#SCREENMODE=0x00031000 -# VGAPRODUCT_KEY -#SCREENMODE=0x00039024 -# A2024TENHERTZ_KEY -#SCREENMODE=0x00041000 -# A2024FIFTEENHERTZ_KEY -#SCREENMODE=0x00049000 -# EURO72_MONITOR_ID -#SCREENMODE=0x00061000 -# EURO72PRODUCT_KEY -#SCREENMODE=0x00069024 -# EURO72PRODUCTLACE_KEY -#SCREENMODE=0x00069025 -# EURO72PRODUCTDBL_KEY -#SCREENMODE=0x00069020 -# EURO36_MONITOR_ID -#SCREENMODE=0x00071000 -# SUPER72HIRESDBL_KEY -#SCREENMODE=0x00089008 -# SUPER72SUPERDBL_KEY -#SCREENMODE=0x00089028 -# DBLNTSCHIRES_KEY -#SCREENMODE=0x00099000 -# DBLNTSCHIRESFF_KEY -#SCREENMODE=0x00099004 -# DBLNTSCHIRESLACE_KEY -#SCREENMODE=0x00099005 -# DBLPALHIRES_KEY -#SCREENMODE=0x000a9000 -# DBLPALHIRESFF_KEY -#SCREENMODE=0x000a9004 -# DBLPALHIRESLACE_KEY -#SCREENMODE=0x000a9005 diff --git a/outdated/sys/amiga/ifchange b/outdated/sys/amiga/ifchange deleted file mode 100644 index d06450c08..000000000 --- a/outdated/sys/amiga/ifchange +++ /dev/null @@ -1,55 +0,0 @@ -.KEY oper/a,tmp/a,real/a,f1,f2,f3,f4,f5 - -. ; miscellaneous script functions for the Amiga -. ; Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1992, 1993, 1996. -. ; NetHack may be freely redistributed. See license for details. - -FAILAT 6 -IF EQ "MOVE" - IF EXISTS - diff >T:mic -c - search from T:mic SEARCH "---" QUIET - IF WARN - echo "MOVE: no change" - delete - ELSE - echo "MOVE: copy" - copy clone - delete - ENDIF - ELSE - echo "MOVE: copy2" - copy clone - delete - ENDIF - QUIT -ENDIF - -IF EQ "TOUCH" - IF EXISTS - diff >T:mic -c - search from T:mic SEARCH "---" QUIET - IF NOT WARN - echo "TOUCH: touch" - IF NOT EQ "@" - setdate - ENDIF - IF NOT EQ "@" - setdate - ENDIF - IF NOT EQ "@" - setdate - ENDIF - IF NOT EQ "@" - setdate - ENDIF - IF NOT EQ "@" - setdate - ENDIF - ENDIF - ENDIF - QUIT -ENDIF - -echo "ifchange: '' not recognized" -quit 10 diff --git a/outdated/sys/amiga/mkdmake b/outdated/sys/amiga/mkdmake deleted file mode 100644 index fc002ef10..000000000 --- a/outdated/sys/amiga/mkdmake +++ /dev/null @@ -1,13 +0,0 @@ -GE/$@/%(left)/ -GE/$ - -#include "config.h" -#include "tile.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef _DCC -#include -#include -#include -#endif - -void panic(const char *); -void map_colors(void); -int BestMatch(int, int, int); - -extern pixval ColorMap[3][MAXCOLORMAPSIZE]; -extern int colorsinmap; - -/* - * WARNING: - * This program carries forth the assumption that the colormaps in all - * of the .txt files are the same. This is a bug. - */ - -struct { - int Height; - int Width; -} IFFScreen; - -/* - * We are using a hybrid form of our own design which we call a BMAP (for - * bitmap) form. It is an ILBM with the bitmaps already deinterleaved, - * completely uncompressed. - * This speeds the loading of the images from the games point of view because - * it - * does not have to deinterleave and uncompress them. - */ -#define ID_BMAP MAKE_ID('B', 'M', 'A', 'P') /* instead of ILBM */ -#define ID_BMHD MAKE_ID('B', 'M', 'H', 'D') /* Same as ILBM */ -#define ID_CAMG MAKE_ID('C', 'A', 'M', 'G') /* Same as ILBM */ -#define ID_CMAP MAKE_ID('C', 'M', 'A', 'P') /* Same as ILBM */ -#define ID_PDAT \ - MAKE_ID('P', 'D', 'A', 'T') /* Extra data describing plane \ - * size due to graphics.library \ - * rounding requirements. \ - */ -#define ID_PLNE MAKE_ID('P', 'L', 'N', 'E') /* The planes of the image */ - -#ifndef _DCC -extern -#endif - struct Library *IFFParseBase; - -int nplanes; - -/* BMHD from IFF documentation */ -typedef struct { - UWORD w, h; - WORD x, y; - UBYTE nPlanes; - UBYTE masking; - UBYTE compression; - UBYTE reserved1; - UWORD transparentColor; - UBYTE xAspect, yAspect; - WORD pageWidth, pageHeight; -} BitMapHeader; - -typedef struct { - UBYTE r, g, b; -} AmiColorMap; - -pixel pixels[TILE_Y][TILE_X]; -AmiColorMap *cmap; - -int findcolor(register pixel *pix); -void packwritebody(pixel (*tile)[TILE_X], char **planes, int tileno); - -void -error(char *str) -{ - fprintf(stderr, "ERROR: %s\n", str); -} - -/* - * This array maps the image colors to the amiga's first 16 colors. The - * colors - * are reordered to help with maintaining dripen settings. - */ -int colrmap[] = { 0, 6, 9, 15, 4, 10, 2, 3, 5, 11, 7, 13, 8, 1, 14, 12 }; - -/* How many tiles fit across and down. */ - -#define COLS 20 -#define ROWS ((tiles + COLS - 1) / COLS) - -main(int argc, char **argv) -{ - int colors; - struct { - long nplanes; - long pbytes; - long across; - long down; - long npics; - long xsize; - long ysize; - } pdat; - long pbytes; /* Bytes of data in a plane */ - int i, cnt; - BitMapHeader bmhd; - struct IFFHandle *iff; - long camg = HIRES | LACE; - int tiles = 0; - char **planes; - - if (argc != 3) { - fprintf(stderr, "Usage: %s source destination\n", argv[0]); - exit(1); - } - -#if defined(_DCC) || defined(__GNUC__) - IFFParseBase = OpenLibrary("iffparse.library", 0); - if (!IFFParseBase) { - error("unable to open iffparse.library"); - exit(1); - } -#endif - - /* First, count the files in the file */ - if (fopen_text_file(argv[1], "r") != TRUE) { - perror(argv[1]); - return (1); - } - - nplanes = 0; - i = colorsinmap - 1; /*IFFScreen.Colors - 1; */ - while (i != 0) { - nplanes++; - i >>= 1; - } - - planes = malloc(nplanes * sizeof(char *)); - if (planes == 0) { - error("can not allocate planes pointer"); - exit(1); - } - - while (read_text_tile(pixels) == TRUE) - ++tiles; - fclose_text_file(); - - IFFScreen.Width = COLS * TILE_X; - IFFScreen.Height = ROWS * TILE_Y; - - pbytes = (COLS * ROWS * TILE_X + 15) / 16 * 2 * TILE_Y; - - for (i = 0; i < nplanes; ++i) { - planes[i] = calloc(1, pbytes); - if (planes[i] == 0) { - error("can not allocate planes pointer"); - exit(1); - } - } - - /* Now, process it */ - if (fopen_text_file(argv[1], "r") != TRUE) { - perror(argv[1]); - return (1); - } - - iff = AllocIFF(); - if (!iff) { - error("Can not allocate IFFHandle"); - return (1); - } - - iff->iff_Stream = Open(argv[2], MODE_NEWFILE); - if (!iff->iff_Stream) { - error("Can not open output file"); - return (1); - } - - InitIFFasDOS(iff); - OpenIFF(iff, IFFF_WRITE); - - PushChunk(iff, ID_BMAP, ID_FORM, IFFSIZE_UNKNOWN); - - bmhd.w = IFFScreen.Width; - bmhd.h = IFFScreen.Height; - bmhd.x = 0; - bmhd.y = 0; - bmhd.nPlanes = nplanes; - bmhd.masking = 0; - bmhd.compression = 0; - bmhd.reserved1 = 0; - bmhd.transparentColor = 0; - bmhd.xAspect = 100; - bmhd.yAspect = 100; - bmhd.pageWidth = TILE_X; - bmhd.pageHeight = TILE_Y; - - PushChunk(iff, ID_BMAP, ID_BMHD, sizeof(bmhd)); - WriteChunkBytes(iff, &bmhd, sizeof(bmhd)); - PopChunk(iff); - - PushChunk(iff, ID_BMAP, ID_CAMG, sizeof(camg)); - WriteChunkBytes(iff, &camg, sizeof(camg)); - PopChunk(iff); - - /* We need to reorder the colors to get reasonable default pens but - * we also need to know where some of the colors are - so go find out. - */ - map_colors(); - - cmap = malloc((colors = (1L << nplanes)) * sizeof(AmiColorMap)); - for (i = 0; i < colors; ++i) { - cmap[colrmap[i]].r = ColorMap[CM_RED][i]; - cmap[colrmap[i]].g = ColorMap[CM_GREEN][i]; - cmap[colrmap[i]].b = ColorMap[CM_BLUE][i]; - } - - PushChunk(iff, ID_BMAP, ID_CMAP, IFFSIZE_UNKNOWN); - for (i = 0; i < colors; ++i) - WriteChunkBytes(iff, &cmap[i], 3); - PopChunk(iff); - - cnt = 0; - while (read_text_tile(pixels) == TRUE) { - packwritebody(pixels, planes, cnt); - if (cnt % 20 == 0) - printf("%d..", cnt); - ++cnt; - fflush(stdout); - } - - pdat.nplanes = nplanes; - pdat.pbytes = pbytes; - pdat.xsize = TILE_X; - pdat.ysize = TILE_Y; - pdat.across = COLS; - pdat.down = ROWS; - pdat.npics = cnt; - - PushChunk(iff, ID_BMAP, ID_PDAT, IFFSIZE_UNKNOWN); - WriteChunkBytes(iff, &pdat, sizeof(pdat)); - PopChunk(iff); - - PushChunk(iff, ID_BMAP, ID_PLNE, IFFSIZE_UNKNOWN); - for (i = 0; i < nplanes; ++i) - WriteChunkBytes(iff, planes[i], pbytes); - PopChunk(iff); - - CloseIFF(iff); - Close(iff->iff_Stream); - FreeIFF(iff); - - printf("\n%d tiles converted\n", cnt); - -#if defined(_DCC) || defined(__GNUC__) - CloseLibrary(IFFParseBase); -#endif - exit(0); -} - -findcolor(register pixel *pix) -{ - register int i; - - for (i = 0; i < MAXCOLORMAPSIZE; ++i) { - if ((pix->r == ColorMap[CM_RED][i]) - && (pix->g == ColorMap[CM_GREEN][i]) - && (pix->b == ColorMap[CM_BLUE][i])) { - return (i); - } - } - return (-1); -} - -void -packwritebody(pixel (*tile)[TILE_X], char **planes, int tileno) -{ - register int i, j, k, col; - register char *buf; - register int across, rowbytes, xoff, yoff; - - /* how many tiles fit across? */ - across = COLS; - - /* How many bytes per pixel row */ - rowbytes = ((IFFScreen.Width + 15) / 16) * 2; - - /* How many bytes to account for y distance in planes */ - yoff = ((tileno / across) * TILE_Y) * rowbytes; - - /* How many bytes to account for x distance in planes */ - xoff = (tileno % across) * (TILE_X / 8); - - /* For each row... */ - for (i = 0; i < TILE_Y; ++i) { - /* For each bitplane... */ - for (k = 0; k < nplanes; ++k) { - const int mask = 1l << k; - - /* Go across the row */ - for (j = 0; j < TILE_X; j++) { - col = findcolor(&tile[i][j]); - if (col == -1) { - error("can not convert pixel color to colormap index"); - return; - } - /* Shift the colors around to have good complements and to - * know the dripen values. - */ - col = colrmap[col]; - - /* To top left corner of tile */ - buf = planes[k] + yoff + xoff; - - /*To i'th row of tile and the correct byte for the j'th - * pixel*/ - buf += (i * rowbytes) + (j / 8); - - /* Or in the bit for this color */ - *buf |= (((col & mask) != 0) << (7 - (j % 8))); - } - } - } -} - -/* #define DBG */ - -/* map_colors - * The incoming colormap is in arbitrary order and has arbitrary colors in - * it, but we need (some) specific colors in specific places. Find the - * colors we need and fix the mapping table to match. - */ -/* What we are aiming for: */ -/* XXX was 0-7 */ -#define CX_BLACK 0 -#define CX_WHITE 1 -#define CX_BROWN 11 -#define CX_CYAN 2 -#define CX_GREEN 5 -#define CX_MAGENTA 10 -#define CX_BLUE 4 -#define CX_RED 7 -/* we don't care about the rest, at least now */ -/* should get: black white blue red grey greyblue ltgrey */ -void -map_colors() -{ - int x; -#if 1 - int tmpmap[] = { 0, 2, 3, 7, 4, 5, 8, 9, 10, 11, 13, 15, 12, 1, 14, 6 }; -/* still not right: gray green yellow lost somewhere? */ -#else - int tmpmap[16]; - int x, y; - for (x = 0; x < 16; x++) - tmpmap[x] = -1; /* set not assigned yet */ - - tmpmap[BestMatch(0, 0, 0)] = CX_BLACK; - tmpmap[BestMatch(255, 255, 255)] = CX_WHITE; - tmpmap[BestMatch(255, 0, 0)] = CX_RED; - tmpmap[BestMatch(0, 255, 0)] = CX_GREEN; - tmpmap[BestMatch(0, 0, 255)] = CX_BLUE; - - /* clean up the rest */ - for (x = 0; x < 16; x++) { - for (y = 0; y < 16; y++) - if (tmpmap[y] == x) - goto outer_cont; - for (y = 0; y < 16; y++) - if (tmpmap[y] == -1) { - tmpmap[y] = x; - break; - } - if (y == 16) - panic("too many colors?"); - outer_cont: - ; - } - for (x = 0; x < 16; x++) - if (tmpmap[y] == -1) - panic("lost color?"); -#endif - for (x = 0; x < 16; x++) { -#ifdef DBG - printf("final: c[%d]=%d (target: %d)\n", x, tmpmap[x], colrmap[x]); -#endif - colrmap[x] = tmpmap[x]; - } -} -BestMatch(r, g, b) int r, g, b; -{ - int x; - int bestslot; - int bestrate = 99999999L; - for (x = 0; x < 16; x++) { - int rr = r - ColorMap[CM_RED][x]; - int gg = g - ColorMap[CM_GREEN][x]; - int bb = b - ColorMap[CM_BLUE][x]; - int rate = rr * rr + gg * gg + bb * bb; - if (bestrate > rate) { - bestrate = rate; - bestslot = x; - } - } -#ifdef DBG - printf("map (%d,%d,%d) -> %d (error=%d)\n", r, g, b, bestslot, bestrate); -#endif - return bestslot; -} - -long * -alloc(unsigned int n) -{ - long *ret = malloc(n); - if (!ret) { - error("Can't allocate memory"); - exit(1); - } - return (ret); -} - -void -panic(const char *msg) -{ - fprintf(stderr, "PANIC: %s\n", msg); - exit(1); -} diff --git a/outdated/sys/amiga/xpm2iff.c b/outdated/sys/amiga/xpm2iff.c deleted file mode 100644 index 0ffbc8c47..000000000 --- a/outdated/sys/amiga/xpm2iff.c +++ /dev/null @@ -1,363 +0,0 @@ -/* NetHack 3.6 xpm2iff.c $NHDT-Date: 1432512795 2015/05/25 00:13:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */ -/* Copyright (c) 1995 by Gregg Wonderly, Naperville, Illinois */ -/* NetHack may be freely redistributed. See license for details. */ - -#include - -#include "config.h" -#include "tile.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef _DCC -#include -#include -#include -#endif - -struct xpmscreen { - int Width; - int Height; - int Colors; - int ColorResolution; - int Background; - int AspectRatio; - int Interlace; - int BytesPerRow; -} XpmScreen; - -/* translation table from xpm characters to RGB and colormap slots */ -struct Ttable { - char flag; - char r, g, b; - int slot; /* output colortable index */ -} ttable[256]; - -pixval ColorMap[3][MAXCOLORMAPSIZE]; -int colorsinmap; - -/* - * We are using a hybrid form of our own design which we call a BMAP (for - * bitmap) form. It is an ILBM with the bitmaps already deinterleaved, - * completely uncompressed. - * This speeds the loading of the images from the games point of view because - * it - * does not have to deinterleave and uncompress them. - */ -#define ID_BMAP MAKE_ID('B', 'M', 'A', 'P') /* instead of ILBM */ -#define ID_BMHD MAKE_ID('B', 'M', 'H', 'D') /* Same as ILBM */ -#define ID_CAMG MAKE_ID('C', 'A', 'M', 'G') /* Same as ILBM */ -#define ID_CMAP MAKE_ID('C', 'M', 'A', 'P') /* Same as ILBM */ -#define ID_PDAT \ - MAKE_ID('P', 'D', 'A', 'T') /* Extra data describing plane \ - * size due to graphics.library \ - * rounding requirements. \ - */ -#define ID_PLNE MAKE_ID('P', 'L', 'N', 'E') /* The planes of the image */ - -int nplanes; - -/* BMHD from IFF documentation */ -typedef struct { - UWORD w, h; - WORD x, y; - UBYTE nPlanes; - UBYTE masking; - UBYTE compression; - UBYTE reserved1; - UWORD transparentColor; - UBYTE xAspect, yAspect; - WORD pageWidth, pageHeight; -} BitMapHeader; - -typedef struct { - UBYTE r, g, b; -} AmiColorMap; - -pixel pixels[TILE_Y][TILE_X]; -AmiColorMap *cmap; - -void -error(char *str) -{ - fprintf(stderr, "ERROR: %s\n", str); -} - -char **planes; - -main(int argc, char **argv) -{ - int colors; - struct { - long nplanes; - long pbytes; - long across; - long down; - long npics; - long xsize; - long ysize; - } pdat; - long pbytes; /* Bytes of data in a plane */ - int i, cnt; - BitMapHeader bmhd; - struct IFFHandle *iff; - long camg = HIRES | LACE; - int tiles = 0; - int index; - -#if defined(_DCC) || defined(__GNUC__) - IFFParseBase = OpenLibrary("iffparse.library", 0); - if (!IFFParseBase) { - error("unable to open iffparse.library"); - exit(1); - } -#endif - - if (fopen_xpm_file(argv[1], "r") != TRUE) { - perror(argv[1]); - return (1); - } - - nplanes = 0; - i = XpmScreen.Colors - 1; - while (i != 0) { - nplanes++; - i >>= 1; - } - - planes = malloc(nplanes * sizeof(char *)); - if (planes == 0) { - error("can not allocate planes pointer"); - exit(1); - } - - XpmScreen.BytesPerRow = ((XpmScreen.Width + 15) / 16) * 2; - pbytes = XpmScreen.BytesPerRow * XpmScreen.Height; - for (i = 0; i < nplanes; ++i) { - planes[i] = malloc(pbytes); - if (planes[i] == 0) { - error("can not allocate planes pointer"); - exit(1); - } - memset(planes[i], 0, pbytes); - } - - iff = AllocIFF(); - if (!iff) { - error("Can not allocate IFFHandle"); - return (1); - } - - iff->iff_Stream = Open(argv[2], MODE_NEWFILE); - if (!iff->iff_Stream) { - error("Can not open output file"); - return (1); - } - - InitIFFasDOS(iff); - OpenIFF(iff, IFFF_WRITE); - - PushChunk(iff, ID_BMAP, ID_FORM, IFFSIZE_UNKNOWN); - - bmhd.w = XpmScreen.Width; - bmhd.h = XpmScreen.Height; - bmhd.x = 0; - bmhd.y = 0; - bmhd.nPlanes = nplanes; - bmhd.masking = 0; - bmhd.compression = 0; - bmhd.reserved1 = 0; - bmhd.transparentColor = 0; - bmhd.xAspect = 100; - bmhd.yAspect = 100; - bmhd.pageWidth = 0; /* not needed for this program */ - bmhd.pageHeight = 0; /* not needed for this program */ - - PushChunk(iff, ID_BMAP, ID_BMHD, sizeof(bmhd)); - WriteChunkBytes(iff, &bmhd, sizeof(bmhd)); - PopChunk(iff); - - PushChunk(iff, ID_BMAP, ID_CAMG, sizeof(camg)); - WriteChunkBytes(iff, &camg, sizeof(camg)); - PopChunk(iff); - -#define SCALE(x) (x) - cmap = malloc((colors = (1L << nplanes)) * sizeof(AmiColorMap)); - if (cmap == 0) { - error("Can't allocate color map"); - exit(1); - } - for (index = 0; index < 256; index++) { - if (ttable[index].flag) { - cmap[ttable[index].slot].r = SCALE(ttable[index].r); - cmap[ttable[index].slot].g = SCALE(ttable[index].g); - cmap[ttable[index].slot].b = SCALE(ttable[index].b); - } - } -#undef SCALE - - PushChunk(iff, ID_BMAP, ID_CMAP, IFFSIZE_UNKNOWN); - WriteChunkBytes(iff, cmap, colors * sizeof(*cmap)); - PopChunk(iff); - - conv_image(); - - pdat.nplanes = nplanes; - pdat.pbytes = pbytes; - pdat.xsize = XpmScreen.Width; - pdat.ysize = XpmScreen.Height; - pdat.across = 0; - pdat.down = 0; - pdat.npics = 1; - - PushChunk(iff, ID_BMAP, ID_PDAT, IFFSIZE_UNKNOWN); - WriteChunkBytes(iff, &pdat, sizeof(pdat)); - PopChunk(iff); - - PushChunk(iff, ID_BMAP, ID_PLNE, IFFSIZE_UNKNOWN); - for (i = 0; i < nplanes; ++i) - WriteChunkBytes(iff, planes[i], pbytes); - PopChunk(iff); - - CloseIFF(iff); - Close(iff->iff_Stream); - FreeIFF(iff); - -#if defined(_DCC) || defined(__GNUC__) - CloseLibrary(IFFParseBase); -#endif - exit(0); -} - -#define SETBIT(Plane, Plane_offset, Col, Value) \ - if (Value) { \ - planes[Plane][Plane_offset + (Col / 8)] |= 1 << (7 - (Col & 7)); \ - } - -conv_image() -{ - int row, col, planeno; - - for (row = 0; row < XpmScreen.Height; row++) { - char *xb = xpmgetline(); - int plane_offset; - if (xb == 0) - return; - plane_offset = row * XpmScreen.BytesPerRow; - for (col = 0; col < XpmScreen.Width; col++) { - int slot; - int color = xb[col]; - if (!ttable[color].flag) { - fprintf(stderr, "Bad image data\n"); - } - slot = ttable[color].slot; - for (planeno = 0; planeno < nplanes; planeno++) { - SETBIT(planeno, plane_offset, col, slot & (1 << planeno)); - } - } - } -} - -long * -alloc(unsigned int n) -{ - long *ret = malloc(n); - if (!ret) { - error("Can't allocate memory"); - exit(1); - } - return (ret); -} - -FILE *xpmfh = 0; -char initbuf[200]; -char *xpmbuf = initbuf; - -/* version 1. Reads the raw xpm file, NOT the compiled version. This is - * not a particularly good idea but I don't have time to do the right thing - * at this point, even if I was absolutely sure what that was. */ -fopen_xpm_file(const char *fn, const char *mode) -{ - int temp; - char *xb; - if (strcmp(mode, "r")) - return FALSE; /* no choice now */ - if (xpmfh) - return FALSE; /* one file at a time */ - xpmfh = fopen(fn, mode); - if (!xpmfh) - return FALSE; /* I'm hard to please */ - - /* read the header */ - xb = xpmgetline(); - if (xb == 0) - return FALSE; - if (4 != sscanf(xb, "%d %d %d %d", &XpmScreen.Width, &XpmScreen.Height, - &XpmScreen.Colors, &temp)) - return FALSE; /* bad header */ - /* replace the original buffer with one big enough for - * the real data - */ - /* XXX */ - xpmbuf = malloc(XpmScreen.Width * 2); - if (!xpmbuf) { - error("Can't allocate line buffer"); - exit(1); - } - if (temp != 1) - return FALSE; /* limitation of this code */ - - { - /* read the colormap and translation table */ - int ccount = -1; - while (ccount++ < (XpmScreen.Colors - 1)) { - char index; - int r, g, b; - xb = xpmgetline(); - if (xb == 0) - return FALSE; - if (4 != sscanf(xb, "%c c #%2x%2x%2x", &index, &r, &g, &b)) { - fprintf(stderr, "Bad color entry: %s\n", xb); - return FALSE; - } - ttable[index].flag = 1; /* this color is valid */ - ttable[index].r = r; - ttable[index].g = g; - ttable[index].b = b; - ttable[index].slot = ccount; - } - } - return TRUE; -} - -/* This deserves better. Don't read it too closely - you'll get ill. */ -#define bufsz 2048 -char buf[bufsz]; -xpmgetline() -{ - char *bp; - do { - if (fgets(buf, bufsz, xpmfh) == 0) - return 0; - } while (buf[0] != '"'); - /* strip off the trailing <",> if any */ - for (bp = buf; *bp; bp++) - ; - bp--; - while (isspace(*bp)) - bp--; - if (*bp == ',') - bp--; - if (*bp == '"') - bp--; - bp++; - *bp = '\0'; - - return &buf[1]; -} From 1cfff0f002837cd5fa4bd760906271137ad829ae Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 11 May 2026 20:27:16 +0200 Subject: [PATCH 255/702] Amiga: correct command-line flag doc in amii.hlp Wizard mode is gated on player name == WIZARD_NAME, not on -D or -debug. Document -uwizard as the working entry point. --- sys/amiga/amii.hlp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/amiga/amii.hlp b/sys/amiga/amii.hlp index 13d59ffc6..6139b29ff 100644 --- a/sys/amiga/amii.hlp +++ b/sys/amiga/amii.hlp @@ -12,8 +12,12 @@ Command-line flags ------------------ -L Force interlaced (tall) screen. -l Force non-interlaced screen. + -uNAME Play as NAME (e.g. -uwizard for wizard mode). + -pCLASS Pick a profession (e.g. -pvalkyrie). + -rRACE Pick a race. -The usual core flags (-D, -X, -u, -p, -r, -@) apply too. +Wizard/debug mode is gated on the player name matching WIZARD_NAME +("wizard" by default), so the simplest way in is -uwizard. Configuration (nethack.cnf in the NetHack: drawer) From 3973944a936005a13909dc6d92c1b57ffcf36301 Mon Sep 17 00:00:00 2001 From: nhkeni Date: Mon, 11 May 2026 15:22:06 -0400 Subject: [PATCH 256/702] Fix subst for luahelper. --- dat/.gitattributes | 1 + dat/luahelper | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dat/.gitattributes b/dat/.gitattributes index cf71f9633..a15ea206f 100644 --- a/dat/.gitattributes +++ b/dat/.gitattributes @@ -2,6 +2,7 @@ *.des NHSUBST *.txt NHSUBST *.lua NHSUBST +luahelper NHSUBST data.base NHSUBST symbols NHSUBST tribute NHSUBST diff --git a/dat/luahelper b/dat/luahelper index f06c9c367..5db4f831b 100644 --- a/dat/luahelper +++ b/dat/luahelper @@ -1,4 +1,4 @@ -# NetHack 5.0 luahelper $NHDT-Date: $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 luahelper $NHDT-Date: 1777237994 2026/04/26 16:13:14 $ $NHDT-Branch: NetHack-5.0 $ # # Makefile to assist developers in adding lines to various build # Makefiles, or project files, as lua files are added or removed. From 0991b0e770780569f09489ee7e957fb481103862 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 May 2026 15:30:53 -0400 Subject: [PATCH 257/702] tiletext.c warning suppression --- sys/unix/Makefile.utl | 2 +- sys/unix/hints/include/compiler.500 | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/unix/Makefile.utl b/sys/unix/Makefile.utl index ff064a5d7..4e6091550 100644 --- a/sys/unix/Makefile.utl +++ b/sys/unix/Makefile.utl @@ -521,7 +521,7 @@ tilemap: tilemap.o $(OBJDIR)/objects.o $(OBJDIR)/monst.o $(OBJDIR)/drawing.o \ ./tilemap tiletext.o: ../win/share/tiletext.c $(CONFIG_H) ../win/share/tile.h - $(CC) $(CFLAGS) $(CSTD) -I../win/share -c ../win/share/tiletext.c -o $@ + $(CC) $(CFLAGS) $(NO_WARN_DISCARDED_QUALIFIERS) $(CSTD) -I../win/share -c ../win/share/tiletext.c -o $@ tiletxt.o: ../win/share/tiletxt.c ../win/share/tilemap.c $(HACK_H) $(CC) $(CFLAGS) $(CSTD) -I../win/share -c ../win/share/tiletxt.c -o $@ tilemap.o: ../win/share/tilemap.c $(HACK_H) diff --git a/sys/unix/hints/include/compiler.500 b/sys/unix/hints/include/compiler.500 index d04b06381..0284a9caf 100755 --- a/sys/unix/hints/include/compiler.500 +++ b/sys/unix/hints/include/compiler.500 @@ -94,6 +94,7 @@ ifeq "$(GCCGTEQ9)" "1" # flags present in gcc version greater than or equal to 9 can go here CFLAGS+=-Wformat-overflow CFLAGS+=-Wmissing-parameter-type +NO_WARN_DISCARDED_QUALIFIERS=-Wno-discarded-qualifiers endif # GCC greater than or equal to 9 #ifeq "$(GCCGTEQ11)" "1" CFLAGS+=-Wimplicit-fallthrough From 3ca18c8e443f10020debac8f91d009659c160356 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 May 2026 15:40:29 -0400 Subject: [PATCH 258/702] be more cautious on gcc version for warning --- sys/unix/hints/include/compiler.500 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/unix/hints/include/compiler.500 b/sys/unix/hints/include/compiler.500 index 0284a9caf..069b9c995 100755 --- a/sys/unix/hints/include/compiler.500 +++ b/sys/unix/hints/include/compiler.500 @@ -89,19 +89,19 @@ CXX=g++ -std=gnu++11 GCCGTEQ9 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 9) GCCGTEQ11 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 11) GCCGTEQ12 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 12) -GCCGTEQ14 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 14) +GCCGTEQ16 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 16) ifeq "$(GCCGTEQ9)" "1" # flags present in gcc version greater than or equal to 9 can go here CFLAGS+=-Wformat-overflow CFLAGS+=-Wmissing-parameter-type -NO_WARN_DISCARDED_QUALIFIERS=-Wno-discarded-qualifiers endif # GCC greater than or equal to 9 #ifeq "$(GCCGTEQ11)" "1" CFLAGS+=-Wimplicit-fallthrough #endif #ifeq "$(GCCGTEQ12)" "1" #endif -#ifeq "$(GCCGTEQ14)" "1" +#ifeq "$(GCCGTEQ16)" "1" +NO_WARN_DISCARDED_QUALIFIERS=-Wno-discarded-qualifiers #endif # end of gcc-specific else # gcc or clang? From 48fa545cf5f460d537d97e35a9d5c62c280d1301 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 May 2026 16:25:14 -0400 Subject: [PATCH 259/702] update Contributing.md --- Contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Contributing.md b/Contributing.md index e5490d5c3..754f3ee9e 100644 --- a/Contributing.md +++ b/Contributing.md @@ -9,7 +9,7 @@ and the body. This helps Git tools correctly parse the message. -# NetHack 3.7 Contributing.txt $NHDT-Date: 1596498265 2020/08/03 23:44:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.19 $ +# NetHack 5.0 Contributing.txt $NHDT-Date: 1778531111 2026/05/11 20:25:11 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ # NetHack may be freely redistributed. See license for details. From 34204d08749e32c176640f4183edd5b6b07e2b5d Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Mon, 11 May 2026 16:16:07 -0400 Subject: [PATCH 260/702] This is cron-daily v1-May-7-2026. 000files updated: Files --- Files | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Files b/Files index be2f6d514..45991d090 100644 --- a/Files +++ b/Files @@ -304,15 +304,14 @@ CHKSUMS lua pdcurses pdcursesmod sys/amiga: (files for Amiga versions) -NHinfo.uu README.amiga amidos.c amidos.p -amifont.uu amifont8.uu amigst.c amii.hlp -amimenu.c amirip.c amistack.c amitty.c -amiwind.c amiwind.p bmp2iff_host.c clipwin.c +NHinfo.uu README.amiga amidos.c amifont.uu +amifont8.uu amii.hlp amimenu.c amirip.c +amistack.c amiwind.c bmp2iff_host.c clipwin.c cnf-info.uu colorwin.c drawer-info.uu grave16.xpm license-info.uu nethack.cnf readme-info.uu txt-info.uu -winamenu.c winami.c winami.p winchar.c -windefs.h winext.h winfuncs.c winkey.c -winproto.h winreq.c winstr.c xpm2iff_host.c +winamenu.c winami.c winchar.c windefs.h +winext.h winfuncs.c winkey.c winproto.h +winreq.c winstr.c xpm2iff_host.c sys/libnh: (files in top directory) From 3b5e784c69d1bc93c335076e197a6dcbcdba95b1 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 May 2026 17:07:17 -0400 Subject: [PATCH 261/702] fixes5-0-1.txt catch-up --- doc/fixes5-0-1.txt | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 60f5bb335..b2ced97a8 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.0 $ $NHDT-Date: 1778152494 2026/05/07 11:14:54 $ +NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ $NHDT-Date: 1778533634 2026/05/11 21:07:14 $ General Fixes and Modified Features ----------------------------------- @@ -41,6 +41,12 @@ Amiga: wire altmeta option to sysflags.altmeta Amiga: restore glyph icons in menus Amiga: sys/amiga/README.amiga stated "Extract NH50AMI.ZIP" but it could be named something else; added a note about the potential suffix +Amiga: fix port_help double-prefix path +Amiga: route non-menu messages from DoMenuScroll to ProcessMessage +Amiga: deduplicate amii_procs and amiv_procs +Amiga: replace WINVERS_AMI* strcmp with WINDOWPORT() id compare +Amiga: route port paths through fqname() +gcc-16: tiletext.c [-Wdiscarded-qualifiers] warning suppression libnh: update get_nhuuid() for libnhmain libnh: sys/libnh/libnhmain.c: drop `static` on `whoami()` libnh: rewrote sys/unix/hints/macOS.500: rewrote the libnh.a rule. The @@ -87,4 +93,16 @@ Code Cleanup and Reorganization ------------------------------- add Contributing.md with some guidelines for making a pull request that is in an acceptable format +Make all top-level .md files subject to nhsub substitutions +Fix subst for luahelper +Amiga: delete dead files and dead-macro code +Amiga: delete the .p prototype headers +Amiga: drop #if 0 dead-code blocks +Amiga: drop TESTING dev toggle in winchar.c +Amiga: collapse #ifndef CROSS_TO_AMIGA include forks +Amiga: clean up amiconf.h +Amiga: drop OPT_DISPMAP / display_map / fast_map machinery +Amiga: correct command-line flag doc in amii.hlp +Amiga: delete outdated/sys/amiga/ source folder tree +Amiga: drop redundant 'either windowtype' guards From f06e2389b67ef0673ef8e8bff8be58cd92065258 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 May 2026 17:36:21 -0400 Subject: [PATCH 262/702] more fixes5-0-1.txt updates --- doc/fixes5-0-1.txt | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index b2ced97a8..3d765fc94 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ $NHDT-Date: 1778533634 2026/05/11 21:07:14 $ +NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ $NHDT-Date: 1778535379 2026/05/11 21:36:19 $ General Fixes and Modified Features ----------------------------------- @@ -41,11 +41,24 @@ Amiga: wire altmeta option to sysflags.altmeta Amiga: restore glyph icons in menus Amiga: sys/amiga/README.amiga stated "Extract NH50AMI.ZIP" but it could be named something else; added a note about the potential suffix +Amiga: `amiv_lprint_glyph` used an uninitialized `base` in tile-offset math +Amiga: `amii_clear_nhwindow` overview window never got cleared with the map +Amiga: `amii_sethipens` fell through from `NHW_TEXT` into `case -2`, clobbering + text-window pens +Amiga: `NHW_BASE`/`NHW_OVER` collided with `NHW_PERMINVENT=6`; renumbered + off `NHW_LAST_TYPE`, matching the `wintty.h` convention +Amiga: `make_menu_items` sized its output array by + `sizeof(amii_menu_item)` instead of `sizeof(menu_item)` +Amiga: `DoMenuScroll` could deref a NULL `amip` on the `SELECTUP` path +Amiga: `GlyphToIcon`'s ASCII passthrough used `> 10000` instead of `>=` +Amiga: `fopenp`'s buffer-bound check fired one byte too late Amiga: fix port_help double-prefix path -Amiga: route non-menu messages from DoMenuScroll to ProcessMessage -Amiga: deduplicate amii_procs and amiv_procs Amiga: replace WINVERS_AMI* strcmp with WINDOWPORT() id compare Amiga: route port paths through fqname() +Amiga: drop redundant 'either windowtype' guards +Amiga: deduplicate amii_procs and amiv_procs +Amiga: route non-menu messages from DoMenuScroll to ProcessMessage +Amiga: delete outdated/sys/amiga/ gcc-16: tiletext.c [-Wdiscarded-qualifiers] warning suppression libnh: update get_nhuuid() for libnhmain libnh: sys/libnh/libnhmain.c: drop `static` on `whoami()` @@ -104,5 +117,13 @@ Amiga: clean up amiconf.h Amiga: drop OPT_DISPMAP / display_map / fast_map machinery Amiga: correct command-line flag doc in amii.hlp Amiga: delete outdated/sys/amiga/ source folder tree -Amiga: drop redundant 'either windowtype' guards +Amiga: drop legacy non-gcc compiler guards +Amiga: remove remnants of support for compiling on Amiga (the old + compilers couldn't cope with such a large codebase anymore) +Amiga: remove old conditionals for running on OS 1.3 +Amiga: remove miscellaneous unused code like TTY/BBS support, commented + out test code etc +Amiga: make INTUI_NEW_LOOK unconditional +Amiga: drop SHAREDLIB dead build flavor + From 45ab4eb1aa31777be78d9ab1f23031a94df71589 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 May 2026 17:40:50 -0400 Subject: [PATCH 263/702] follow-up: paste error snuck in --- doc/fixes5-0-1.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 3d765fc94..5477d1f83 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ $NHDT-Date: 1778535379 2026/05/11 21:36:19 $ +NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ $NHDT-Date: 1778535648 2026/05/11 21:40:48 $ General Fixes and Modified Features ----------------------------------- @@ -50,7 +50,7 @@ Amiga: `NHW_BASE`/`NHW_OVER` collided with `NHW_PERMINVENT=6`; renumbered Amiga: `make_menu_items` sized its output array by `sizeof(amii_menu_item)` instead of `sizeof(menu_item)` Amiga: `DoMenuScroll` could deref a NULL `amip` on the `SELECTUP` path -Amiga: `GlyphToIcon`'s ASCII passthrough used `> 10000` instead of `>=` +Amiga: `GlyphToIcon`'s ASCII passthrough used `> 10000` instead of `>=` Amiga: `fopenp`'s buffer-bound check fired one byte too late Amiga: fix port_help double-prefix path Amiga: replace WINVERS_AMI* strcmp with WINDOWPORT() id compare From c42d35eac0b3aa87a45ad102b4c2945b602a5897 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 11 May 2026 15:06:13 -0700 Subject: [PATCH 264/702] avoid newsym(0,0) for vault guard When a vault guard is being moving off the map to <0,0> to wait until his temporary corridor gets removed, don't try to update the map for that off-the-screen location in order to avoid triggering impossible() from newsym(). Plus a trivial tweak to NH_abort(). Its argument is never modified so declare it as such. --- doc/fixes5-0-1.txt | 6 ++++-- include/extern.h | 2 +- src/end.c | 4 ++-- src/monmove.c | 4 +++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 5477d1f83..0333cc5f7 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -12,8 +12,10 @@ fix issue where the new game startup message was stating 'Work-in-progress' even when NH_DEVEL_STATUS was set to NH_STATUS_POSTRELEASE if 'mention_decor' was set in config file or NETHACKOPTIONS, starting the game told you that "you are standing on stairs which lead - out of the dungeon", even when the player entered the tutorial where that - wasn't true + out of the dungeon", even when the player entered the tutorial where + that wasn't true +when a vault guard was moved off the map, an impossible about trying to update + map location <0,0> was issued doc: use full URL for nethack.org in Guidebook.mn doc: fix a paste error in Guidebook.tex doc: fix spelling correction in nethack.6 diff --git a/include/extern.h b/include/extern.h index cf8d85a08..af726885b 100644 --- a/include/extern.h +++ b/include/extern.h @@ -995,7 +995,7 @@ extern void done1(int); extern int done2(void); extern void done_in_by(struct monst *, int) NONNULLARG1; extern void done_object_cleanup(void); -extern void NH_abort(char *); +extern void NH_abort(const char *); #endif /* !MAKEDEFS_C && MDLIB_C && !CPPREGEX_C */ #if !defined(CPPREGEX_C) ATTRNORETURN extern void panic(const char *, ...) PRINTF_F(1, 2) NORETURN; diff --git a/src/end.c b/src/end.c index 8a366d434..27040abe7 100644 --- a/src/end.c +++ b/src/end.c @@ -1896,7 +1896,7 @@ build_english_list(char *in) # endif void -NH_abort(char *why USED_FOR_CRASHREPORT) +NH_abort(const char *why USED_FOR_CRASHREPORT) { #ifdef PANICTRACE int gdb_prio = SYSOPT_PANICTRACE_GDB; @@ -1912,7 +1912,7 @@ NH_abort(char *why USED_FOR_CRASHREPORT) #ifdef PANICTRACE #ifdef CRASHREPORT - if(!submit_web_report(1, "Panic", why)) + if (!submit_web_report(1, "Panic", why)) #endif { #ifndef VMS diff --git a/src/monmove.c b/src/monmove.c index f1a294d55..340c2f628 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1653,7 +1653,9 @@ postmov( u_on_newpos(mtmp->mx, mtmp->my); swallowed(0); } else { - newsym(mtmp->mx, mtmp->my); + /* only call newsym() when not a vault guard moving to <0,0> */ + if (mtmp->mx) + newsym(mtmp->mx, mtmp->my); } } /* mmoved==MMOVE_MOVED */ From ef600a41f66eb69d4c7d5c91b6f34e7c46b19405 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 May 2026 19:16:03 -0400 Subject: [PATCH 265/702] allow a hints file to be able to specify GUIDECMD define GUIDECMD in sys/unix/Makefile.doc using '?=' notation --- sys/unix/Makefile.doc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/unix/Makefile.doc b/sys/unix/Makefile.doc index f2f42502a..dfb812700 100644 --- a/sys/unix/Makefile.doc +++ b/sys/unix/Makefile.doc @@ -29,7 +29,7 @@ COLCMD ?= col -bx # The command to use to generate a PostScript file # PSCMD = ditroff | psdit -PSCMD = groff +PSCMD ?= groff # Use the "cat" GUIDECMD if nroff and/or tbl and/or col are not installed # Not appropriate for creating Guidebook.txt. @@ -38,8 +38,8 @@ PSCMD = groff # Single page. Might need adjustment to .pl value # GUIDECMD= $(GUIDE_PREFORMAT) | perl -pe 's/^(.mt)$$/.pl 4720v\n.in 0\n.po 8\n.ll 64m\n$$1/' | nroff -c -Tascii | $(COLCMD) # -GUIDECMD = $(GUIDE_PREFORMAT) | nroff -c -Tascii $(NROFF_FLAGS) | $(COLCMD) -ONEPAGECMD = $(ONEPAGE_PREFORMAT) | nroff -c -Tascii $(NROFF_FLAGS) | $(COLCMD) +GUIDECMD ?= $(GUIDE_PREFORMAT) | nroff -c -Tascii $(NROFF_FLAGS) | $(COLCMD) +ONEPAGECMD ?= $(ONEPAGE_PREFORMAT) | nroff -c -Tascii $(NROFF_FLAGS) | $(COLCMD) # Only generate output for the current configuration: NHGREP = $(MAKEDEFS) --grep --input - --output - From ccb3db39d7f110dce925dcf391411274e599a307 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 May 2026 19:59:53 -0400 Subject: [PATCH 266/702] more hints file prep --- sys/unix/Makefile.doc | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/sys/unix/Makefile.doc b/sys/unix/Makefile.doc index dfb812700..5dbe117f0 100644 --- a/sys/unix/Makefile.doc +++ b/sys/unix/Makefile.doc @@ -12,6 +12,7 @@ NHSROOT=.. MAKEDEFS = ../util/makedefs #STRIPBS ?= ../util/stripbs +NROFF ?= nroff # Which version do we want to build? (XXX These are not used anywhere.) GUIDEBOOK = Guidebook # regular ASCII file @@ -33,13 +34,13 @@ PSCMD ?= groff # Use the "cat" GUIDECMD if nroff and/or tbl and/or col are not installed # Not appropriate for creating Guidebook.txt. -# GUIDECMD = cat Guidebook.txt +# GUIDECMD ?= cat Guidebook.txt # # Single page. Might need adjustment to .pl value -# GUIDECMD= $(GUIDE_PREFORMAT) | perl -pe 's/^(.mt)$$/.pl 4720v\n.in 0\n.po 8\n.ll 64m\n$$1/' | nroff -c -Tascii | $(COLCMD) +# GUIDECMD= $(GUIDE_PREFORMAT) | perl -pe 's/^(.mt)$$/.pl 4720v\n.in 0\n.po 8\n.ll 64m\n$$1/' | $(NROFF) -c -Tascii | $(COLCMD) # -GUIDECMD ?= $(GUIDE_PREFORMAT) | nroff -c -Tascii $(NROFF_FLAGS) | $(COLCMD) -ONEPAGECMD ?= $(ONEPAGE_PREFORMAT) | nroff -c -Tascii $(NROFF_FLAGS) | $(COLCMD) +GUIDECMD ?= $(GUIDE_PREFORMAT) | $(NROFF) -c -Tascii $(NROFF_FLAGS) | $(COLCMD) +ONEPAGECMD ?= $(ONEPAGE_PREFORMAT) | $(NROFF) -c -Tascii $(NROFF_FLAGS) | $(COLCMD) # Only generate output for the current configuration: NHGREP = $(MAKEDEFS) --grep --input - --output - @@ -51,14 +52,14 @@ NEEDMAKEDEFS = $(MAKEDEFS) #NHGREP = cat #NEEDMAKEDEFS = -GUIDEBOOK_MN_SRC = Guidebook.mn -GUIDEBOOK_MN = $(GUIDEBOOK_MN_SRC) -GUIDEBOOK_TEX_SRC = Guidebook.tex -GUIDEBOOK_TEX = $(GUIDEBOOK_TEX_SRC) +GUIDEBOOK_MN_SRC ?= Guidebook.mn +GUIDEBOOK_MN ?= $(GUIDEBOOK_MN_SRC) +GUIDEBOOK_TEX_SRC ?= Guidebook.tex +GUIDEBOOK_TEX ?= $(GUIDEBOOK_TEX_SRC) -GUIDE_PREFORMAT = cat $(GUIDEBOOK_MN) | $(NHGREP) | tbl tmac.n - +GUIDE_PREFORMAT ?= cat $(GUIDEBOOK_MN) | $(NHGREP) | tbl tmac.n - # for Guidebook.dat, unpaginated version of Guidebook.txt -ONEPAGE_PREFORMAT = cat Gbk-1pg-pfx.mn $(GUIDEBOOK_MN) Gbk-1pg-sfx.mn \ +ONEPAGE_PREFORMAT ?= cat Gbk-1pg-pfx.mn $(GUIDEBOOK_MN) Gbk-1pg-sfx.mn \ | $(NHGREP) | tbl tmac.n - # the basic guidebook @@ -91,7 +92,6 @@ $(MAKEDEFS) : ../util/makedefs.c ../include/config.h ../src/mdlib.c \ GAME = nethack MANDIR ?= /usr/man/man6 MANEXT = 6 -NROFF ?= nroff # manual installation for most BSD-style systems GAMEMANCREATE = cat nethack.6 | $(NHGREP) > @@ -99,10 +99,10 @@ RCVRMANCREATE = cat recover.6 | $(NHGREP) > DLBMANCREATE = cat dlb.6 | $(NHGREP) > MDMANCREATE = cat makedefs.6 | $(NHGREP) > # manual installation for most SYSV-style systems -# GAMEMANCREATE = cat nethack.6 | $(NHGREP) | nroff -man - > -# RCVRMANCREATE = cat recover.6 | $(NHGREP) | nroff -man - > -# DLBMANCREATE = cat dlb.6 | $(NHGREP) | nroff -man - > -# MDMANCREATE = cat makedefs.6 | $(NHGREP) | nroff -man - > +# GAMEMANCREATE = cat nethack.6 | $(NHGREP) | $(NROFF) -man - > +# RCVRMANCREATE = cat recover.6 | $(NHGREP) | $(NROFF) -man - > +# DLBMANCREATE = cat dlb.6 | $(NHGREP) | $(NROFF) -man - > +# MDMANCREATE = cat makedefs.6 | $(NHGREP) | $(NROFF) -man - > manpages: $(PREMANPAGES) -$(GAMEMANCREATE) $(MANDIR)/$(GAME).$(MANEXT) From d62b56e0f2b9bb86d96759528b0df580e78459a9 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 May 2026 20:45:49 -0400 Subject: [PATCH 267/702] yet more hints file prep --- sys/unix/Makefile.doc | 67 ++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/sys/unix/Makefile.doc b/sys/unix/Makefile.doc index 5dbe117f0..044632a2d 100644 --- a/sys/unix/Makefile.doc +++ b/sys/unix/Makefile.doc @@ -9,15 +9,24 @@ NHSROOT=.. # for Atari # SHELL=E:/GEMINI2/MUPFEL.TTP -MAKEDEFS = ../util/makedefs +MAKEDEFS ?= ../util/makedefs +# Only generate output for the current configuration: +NHGREP ?= $(MAKEDEFS) --grep --input - --output - +NEEDMAKEDEFS ?= $(MAKEDEFS) +# Generate output for all configurations: +#NHGREP ?= $(MAKEDEFS) --grep --input - --output - --grep-define ALLDOCS +#NEEDMAKEDEFS ?= $(MAKEDEFS) +# Fallback: +#NHGREP ?= cat +#NEEDMAKEDEFS ?= -#STRIPBS ?= ../util/stripbs NROFF ?= nroff +# NROFF_FLAGS comes from a hints file, or is empty # Which version do we want to build? (XXX These are not used anywhere.) -GUIDEBOOK = Guidebook # regular ASCII file -#GUIDEBOOK = Guidebook.ps # PostScript file -#GUIDEBOOK = Guidebook.dvi # TeX device-independent file +GUIDEBOOK ?= Guidebook # regular ASCII file +#GUIDEBOOK ?= Guidebook.ps # PostScript file +#GUIDEBOOK ?= Guidebook.dvi # TeX device-independent file # Some versions of col need -x to keep them from converting spaces to tabs; # some versions of col don't do the conversion by default and don't @@ -29,39 +38,33 @@ COLCMD ?= col -bx #COLCMD ?= $(STRIPBS) # The command to use to generate a PostScript file -# PSCMD = ditroff | psdit +# PSCMD ?= ditroff | psdit PSCMD ?= groff -# Use the "cat" GUIDECMD if nroff and/or tbl and/or col are not installed -# Not appropriate for creating Guidebook.txt. -# GUIDECMD ?= cat Guidebook.txt -# -# Single page. Might need adjustment to .pl value -# GUIDECMD= $(GUIDE_PREFORMAT) | perl -pe 's/^(.mt)$$/.pl 4720v\n.in 0\n.po 8\n.ll 64m\n$$1/' | $(NROFF) -c -Tascii | $(COLCMD) -# -GUIDECMD ?= $(GUIDE_PREFORMAT) | $(NROFF) -c -Tascii $(NROFF_FLAGS) | $(COLCMD) -ONEPAGECMD ?= $(ONEPAGE_PREFORMAT) | $(NROFF) -c -Tascii $(NROFF_FLAGS) | $(COLCMD) - -# Only generate output for the current configuration: -NHGREP = $(MAKEDEFS) --grep --input - --output - -NEEDMAKEDEFS = $(MAKEDEFS) -# Generate output for all configurations: -#NHGREP = $(MAKEDEFS) --grep --input - --output - --grep-define ALLDOCS -#NEEDMAKEDEFS = $(MAKEDEFS) -# Fallback: -#NHGREP = cat -#NEEDMAKEDEFS = - GUIDEBOOK_MN_SRC ?= Guidebook.mn GUIDEBOOK_MN ?= $(GUIDEBOOK_MN_SRC) -GUIDEBOOK_TEX_SRC ?= Guidebook.tex -GUIDEBOOK_TEX ?= $(GUIDEBOOK_TEX_SRC) GUIDE_PREFORMAT ?= cat $(GUIDEBOOK_MN) | $(NHGREP) | tbl tmac.n - # for Guidebook.dat, unpaginated version of Guidebook.txt ONEPAGE_PREFORMAT ?= cat Gbk-1pg-pfx.mn $(GUIDEBOOK_MN) Gbk-1pg-sfx.mn \ | $(NHGREP) | tbl tmac.n - +ONEPAGECMD ?= $(ONEPAGE_PREFORMAT) | nroff -c -Tascii $(NROFF_FLAGS) | $(COLCMD) +# Use the "cat" GUIDECMD if nroff and/or tbl and/or col are not installed +# Not appropriate for creating Guidebook.txt. +# GUIDECMD ?= cat Guidebook.txt +# +# Single page. Might need adjustment to .pl value +# GUIDECMD ?= $(GUIDE_PREFORMAT) | perl -pe 's/^(.mt)$$/.pl 4720v\n.in 0\n.po 8\n.ll 64m\n$$1/' | nroff -c -Tascii | $(COLCMD) +# +GUIDECMD ?= $(GUIDE_PREFORMAT) | nroff -c -Tascii $(NROFF_FLAGS) | $(COLCMD) +GUIDEBOOK_TEX_SRC ?= Guidebook.tex +GUIDEBOOK_TEX ?= $(GUIDEBOOK_TEX_SRC) +#STRIPBS ?= ../util/stripbs +# STRIPBS often comes from a hints file, or is empty + +# targets +# # the basic guidebook Guidebook : $(GUIDEBOOK_MN) tmac.n tmac.nh $(NEEDMAKEDEFS) $(STRIPBS) -$(GUIDECMD) > Guidebook @@ -99,10 +102,10 @@ RCVRMANCREATE = cat recover.6 | $(NHGREP) > DLBMANCREATE = cat dlb.6 | $(NHGREP) > MDMANCREATE = cat makedefs.6 | $(NHGREP) > # manual installation for most SYSV-style systems -# GAMEMANCREATE = cat nethack.6 | $(NHGREP) | $(NROFF) -man - > -# RCVRMANCREATE = cat recover.6 | $(NHGREP) | $(NROFF) -man - > -# DLBMANCREATE = cat dlb.6 | $(NHGREP) | $(NROFF) -man - > -# MDMANCREATE = cat makedefs.6 | $(NHGREP) | $(NROFF) -man - > +# GAMEMANCREATE = cat nethack.6 | $(NHGREP) | nroff -man - > +# RCVRMANCREATE = cat recover.6 | $(NHGREP) | nroff -man - > +# DLBMANCREATE = cat dlb.6 | $(NHGREP) | nroff -man - > +# MDMANCREATE = cat makedefs.6 | $(NHGREP) | nroff -man - > manpages: $(PREMANPAGES) -$(GAMEMANCREATE) $(MANDIR)/$(GAME).$(MANEXT) From f5456fa92c649e4a5a3f60019e94ea768da450c0 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 11 May 2026 22:59:42 -0400 Subject: [PATCH 268/702] another Windows issue causing startup grief --- win/win32/mhmain.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/win/win32/mhmain.c b/win/win32/mhmain.c index 30eccbc31..bd3ffda5a 100644 --- a/win/win32/mhmain.c +++ b/win/win32/mhmain.c @@ -1194,7 +1194,9 @@ mswin_select_map_mode(int mode) (PNHMainWindow) GetWindowLongPtr(GetNHApp()->hMainWnd, GWLP_USERDATA); if (!data) { +#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED && NH_DEVEL_STATUS != NH_STATUS_POSTRELEASE) impossible("data is null in %s:%d", __func__, __LINE__); +#endif return; } From 80a99d1ed100e5eb70e822bcfdf5debc88b4c07b Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 12 May 2026 00:10:38 -0400 Subject: [PATCH 269/702] stop init of allopt[] from wiping out disregards --- sys/windows/windmain.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sys/windows/windmain.c b/sys/windows/windmain.c index 6e7a44db7..3cb87f4f5 100644 --- a/sys/windows/windmain.c +++ b/sys/windows/windmain.c @@ -209,9 +209,9 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ set_default_prefix_locations( argv[0]); /* must be re-done again after initoptions_init() * because that function clears out gp.fqn_prefix[] */ -#ifdef MSWIN_GRAPHICS - disregard_some_mswin_options(); -#endif + allopt_array_init(); /* we do this here, so allopt doesn't get cleared + after we disregard some */ + copy_sysconf_content(); copy_symbols_content(); /* Now that sysconf has had a chance to set the TROUBLEPREFIX, don't @@ -254,6 +254,9 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ error("NetHack: current directory path too long"); #endif getreturn_enabled = TRUE; +#ifdef MSWIN_GRAPHICS + disregard_some_mswin_options(); +#endif initoptions_init(); // This allows OPTIONS in syscf on Windows. set_default_prefix_locations( argv[0]); /* must be re-done after initoptions_init() From 7d802883bc020dea4924c21ad6e853df33d468a4 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 12 May 2026 09:07:06 -0400 Subject: [PATCH 270/702] replace hard-coded nroff with $(NROFF) --- sys/unix/Makefile.doc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/sys/unix/Makefile.doc b/sys/unix/Makefile.doc index 044632a2d..41a620794 100644 --- a/sys/unix/Makefile.doc +++ b/sys/unix/Makefile.doc @@ -48,15 +48,16 @@ GUIDE_PREFORMAT ?= cat $(GUIDEBOOK_MN) | $(NHGREP) | tbl tmac.n - # for Guidebook.dat, unpaginated version of Guidebook.txt ONEPAGE_PREFORMAT ?= cat Gbk-1pg-pfx.mn $(GUIDEBOOK_MN) Gbk-1pg-sfx.mn \ | $(NHGREP) | tbl tmac.n - -ONEPAGECMD ?= $(ONEPAGE_PREFORMAT) | nroff -c -Tascii $(NROFF_FLAGS) | $(COLCMD) +ONEPAGECMD ?= $(ONEPAGE_PREFORMAT) | $(NROFF) -c -Tascii $(NROFF_FLAGS) | $(COLCMD) # Use the "cat" GUIDECMD if nroff and/or tbl and/or col are not installed # Not appropriate for creating Guidebook.txt. # GUIDECMD ?= cat Guidebook.txt # # Single page. Might need adjustment to .pl value -# GUIDECMD ?= $(GUIDE_PREFORMAT) | perl -pe 's/^(.mt)$$/.pl 4720v\n.in 0\n.po 8\n.ll 64m\n$$1/' | nroff -c -Tascii | $(COLCMD) +# PLVALUE='s/^(.mt)$$/.pl 4720v\n.in 0\n.po 8\n.ll 64m\n$$1/' +# GUIDECMD ?= $(GUIDE_PREFORMAT) | perl -pe $(PLVALUE) | $(NROFF) -c -Tascii | $(COLCMD) # -GUIDECMD ?= $(GUIDE_PREFORMAT) | nroff -c -Tascii $(NROFF_FLAGS) | $(COLCMD) +GUIDECMD ?= $(GUIDE_PREFORMAT) | $(NROFF) -c -Tascii $(NROFF_FLAGS) | $(COLCMD) GUIDEBOOK_TEX_SRC ?= Guidebook.tex GUIDEBOOK_TEX ?= $(GUIDEBOOK_TEX_SRC) @@ -102,10 +103,10 @@ RCVRMANCREATE = cat recover.6 | $(NHGREP) > DLBMANCREATE = cat dlb.6 | $(NHGREP) > MDMANCREATE = cat makedefs.6 | $(NHGREP) > # manual installation for most SYSV-style systems -# GAMEMANCREATE = cat nethack.6 | $(NHGREP) | nroff -man - > -# RCVRMANCREATE = cat recover.6 | $(NHGREP) | nroff -man - > -# DLBMANCREATE = cat dlb.6 | $(NHGREP) | nroff -man - > -# MDMANCREATE = cat makedefs.6 | $(NHGREP) | nroff -man - > +# GAMEMANCREATE = cat nethack.6 | $(NHGREP) | $(NROFF) -man - > +# RCVRMANCREATE = cat recover.6 | $(NHGREP) | $(NROFF) -man - > +# DLBMANCREATE = cat dlb.6 | $(NHGREP) | $(NROFF) -man - > +# MDMANCREATE = cat makedefs.6 | $(NHGREP) | $(NROFF) -man - > manpages: $(PREMANPAGES) -$(GAMEMANCREATE) $(MANDIR)/$(GAME).$(MANEXT) From 657f6eaad96624cb164bd8fea1513c6ef43fe8a5 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Tue, 12 May 2026 11:04:04 +0200 Subject: [PATCH 271/702] Amiga: fix latent issues found in code review - fname[18]/sprintf risks overflow for >=10 in any version field; switch to snprintf into a wider static buffer. - (1L << i) for i==31 (or shifting into the depth-loop terminator) is undefined for signed long; use 1UL. - Drop unused cnt= from amii_display_nhwindow's DoMenuScroll call; the menu return value is consumed elsewhere, not here. --- sys/amiga/winchar.c | 2 +- sys/amiga/winfuncs.c | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/sys/amiga/winchar.c b/sys/amiga/winchar.c index 9b29152a7..8980bdf55 100644 --- a/sys/amiga/winchar.c +++ b/sys/amiga/winchar.c @@ -116,7 +116,7 @@ ReadImageFile(const char *filename, struct BitMap **bmp) prop = FindProp(iff, ID_BMAP, ID_CMAP); if (prop) { unsigned char *cmap = prop->sp_Data; - for (j = 0; j < (1L << np) * 3; j += 3) { + for (j = 0; j < (1UL << np) * 3; j += 3) { amii_initmap[j / 3] = amiv_init_map[j / 3] = ((cmap[j+0] >> 4) << 8) diff --git a/sys/amiga/winfuncs.c b/sys/amiga/winfuncs.c index b964d9ffc..3af760edb 100644 --- a/sys/amiga/winfuncs.c +++ b/sys/amiga/winfuncs.c @@ -1087,9 +1087,9 @@ amii_init_nhwindows(int *argcp, char **argv) NewHackScreen.Width = max(WIDTH, amiIDisplay->xpix); NewHackScreen.Height = max(SCREENHEIGHT, amiIDisplay->ypix); { - static char fname[18]; - sprintf(fname, "NetHack %d.%d.%d", VERSION_MAJOR, VERSION_MINOR, - PATCHLEVEL); + static char fname[32]; + snprintf(fname, sizeof fname, "NetHack %d.%d.%d", + VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL); NewHackScreen.DefaultTitle = fname; } if (IntuitionBase->LibNode.lib_Version >= 37) { @@ -1216,7 +1216,7 @@ amii_init_nhwindows(int *argcp, char **argv) /* Find out how deep the screen needs to be, 32 planes is enough! */ for (i = 0; i < 32; ++i) { - if ((1L << i) >= amii_numcolors) + if ((1UL << i) >= (unsigned long) amii_numcolors) break; } @@ -1240,7 +1240,7 @@ amii_init_nhwindows(int *argcp, char **argv) if (--NewHackScreen.Depth < 3) Abort(AN_OpenScreen & ~AT_DeadEnd); } - amii_numcolors = 1L << NewHackScreen.Depth; + amii_numcolors = 1UL << NewHackScreen.Depth; if (HackScreen->Height > 300 && forcenobig == 0) bigscreen = 1; else @@ -1526,7 +1526,6 @@ void amii_display_nhwindow(winid win, boolean blocking) { menu_item *mip; - int cnt; static int lastwin = -1; struct amii_WinDesc *cw; @@ -1549,7 +1548,7 @@ amii_display_nhwindow(winid win, boolean blocking) } if (cw->type == NHW_MENU || cw->type == NHW_TEXT) { - cnt = DoMenuScroll(win, blocking, PICK_ONE, &mip); + (void) DoMenuScroll(win, blocking, PICK_ONE, &mip); } else if (cw->type == NHW_MAP) { amii_end_glyphout(win); /* Do more if it is time... */ From 7c8524ae37a62679e3a29bbdfc4e30855153c141 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Tue, 12 May 2026 11:04:10 +0200 Subject: [PATCH 272/702] Amiga: make amigapkg depend on $(GAMEBIN) Without the dependency, 'make amigapkg' would copy whatever was already in targets/amiga/ without ever rebuilding when sources changed -- silently shipping a stale binary. --- sys/unix/hints/include/cross-post.500 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/unix/hints/include/cross-post.500 b/sys/unix/hints/include/cross-post.500 index 42e562690..e01623002 100644 --- a/sys/unix/hints/include/cross-post.500 +++ b/sys/unix/hints/include/cross-post.500 @@ -307,7 +307,7 @@ UUDECODE = ../util/uudecode ../util/uudecode: ../sys/share/uudecode.c $(CC) $(CFLAGS) -o $@ $< -amigapkg: $(AMITILES) ../util/uudecode +amigapkg: $(GAMEBIN) $(AMITILES) ../util/uudecode mkdir -p $(TARGETPFX)pkg/NetHack/tiles $(TARGETPFX)pkg/NetHack/hack cp $(GAMEBIN) $(TARGETPFX)pkg/NetHack/nethack cp ../dat/nhdat $(TARGETPFX)pkg/NetHack/nhdat From f5837878259bb43960c247b4fc5604e65705b7a8 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Tue, 12 May 2026 11:12:40 +0200 Subject: [PATCH 273/702] Amiga: fix overview-window crashes - MyAllocBitMap left bm->mflags uninitialized, so MyFreeBitMap took the wrong path between FreeRaster and FreeMem and intermittently corrupted exec's free list (Software Failure 0x81000005, DEADEND in FreeMem). - The NHW_OVER window is BORDERLESS, so attaching WINDOWSIZING | WINDOWDRAG | WINDOWCLOSE created phantom gadgets that hit-test against unrelated input. Pressing ESC while the overview was selected fired CLOSEWINDOW and destroyed the window underneath the running code, leading to wild-PC crashes. Drop the gadget flags; SHIFT-HELP already toggles the overview cleanly via delayed_key_action. - amii_destroy_nhwindow only reset WIN_MAP / WIN_STATUS / WIN_MESSAGE / WIN_INVEN; WIN_OVER and WIN_BASE kept pointing at freed slots, so any later 'WIN_X != WIN_ERR && amii_wins[WIN_X]->win' check dereferenced NULL. Reset them too. --- sys/amiga/winchar.c | 1 + sys/amiga/winfuncs.c | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/sys/amiga/winchar.c b/sys/amiga/winchar.c index 8980bdf55..b84561311 100644 --- a/sys/amiga/winchar.c +++ b/sys/amiga/winchar.c @@ -189,6 +189,7 @@ MyAllocBitMap(int xsize, int ysize, int depth, long mflags) if (!bm) return (NULL); + bm->mflags = mflags; bm->xsize = xsize; bm->ysize = ysize; InitBitMap(&bm->bm, depth, xsize, ysize); diff --git a/sys/amiga/winfuncs.c b/sys/amiga/winfuncs.c index 3af760edb..9b172201d 100644 --- a/sys/amiga/winfuncs.c +++ b/sys/amiga/winfuncs.c @@ -227,6 +227,10 @@ amii_destroy_nhwindow(winid win) /* just hide */ WIN_MESSAGE = WIN_ERR; else if (win == WIN_INVEN) WIN_INVEN = WIN_ERR; + else if (win == WIN_OVER) + WIN_OVER = WIN_ERR; + else if (win == WIN_BASE) + WIN_BASE = WIN_ERR; } struct FillParams { @@ -416,8 +420,13 @@ amii_create_nhwindow(int type) if (nw->Width >= amiIDisplay->xpix - nw->LeftEdge) nw->Width = amiIDisplay->xpix - nw->LeftEdge; } else if (WINVERS_AMIV && type == NHW_OVER) { - nw->Flags |= WINDOWSIZING | WINDOWDRAG | WINDOWCLOSE; - nw->IDCMPFlags |= CLOSEWINDOW; + /* No window-system gadgets: BORDERLESS means there is no border + * to attach close/size/drag gadgets to. On some Kickstarts the + * phantom gadgets hit-test against unrelated input (selecting + * the overview and pressing ESC has been observed to destroy + * the window and crash the game). SHIFT-HELP toggles the + * overview cleanly via delayed_key_action; that is the + * supported close path. */ /* Bring up window as half the width of the message window, and make * the message window change to one half the width... */ From 74c87caac37e7cd1855a18fa646f3071915cff05 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Tue, 12 May 2026 11:35:27 +0200 Subject: [PATCH 274/702] Amiga: fix bitmap/IFF resource handling in winchar.c - MyAllocBitMap left bm->bm.Planes[] uninitialized; InitBitMap only fills BytesPerRow/Rows/Flags/Depth, not Planes[]. If AllocRaster fails mid-loop, MyFreeBitMap was iterating up to Depth and would pass uninitialized stack-garbage pointers to FreeRaster. Zero Planes[] before the alloc loop. - ReadImageFile leaked iffparse.library, the IFFHandle, the DOS file handle, and any open-IFF state on every panic path. On AmigaOS those handles are not auto-reclaimed when the process dies, so each failure stranded resources until reboot. Restructure to a single cleanup label and free in reverse-acquisition order before panicking. - OpenIFF returns an error code that was being thrown away, so a failed open would feed corrupt state to ParseIFF. Check and bail. --- sys/amiga/winchar.c | 68 +++++++++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 17 deletions(-) diff --git a/sys/amiga/winchar.c b/sys/amiga/winchar.c index b84561311..9636ba3e7 100644 --- a/sys/amiga/winchar.c +++ b/sys/amiga/winchar.c @@ -79,36 +79,54 @@ struct BitMap *tileimg, *tile; BitMapHeader ReadImageFile(const char *filename, struct BitMap **bmp) { - BitMapHeader *bmhd, bmhds; + BitMapHeader *bmhd, bmhds = { 0 }; int j, np; - struct IFFHandle *iff; + long err; + struct IFFHandle *iff = NULL; struct StoredProperty *prop; + int iff_opened = 0; + const char *errfmt = NULL; + long errcode = 0; IFFParseBase = OpenLibrary("iffparse.library", 0L); if (!IFFParseBase) panic("No iffparse.library"); iff = AllocIFF(); - if (!iff) - panic("can't start IFF processing"); + if (!iff) { + errfmt = "can't start IFF processing"; + goto cleanup; + } iff->iff_Stream = Open(filename, MODE_OLDFILE); - if (iff->iff_Stream == 0) - panic("Can't open %s", filename); + if (iff->iff_Stream == 0) { + errfmt = "Can't open %s"; + goto cleanup; + } InitIFFasDOS(iff); - OpenIFF(iff, IFFF_READ); + if ((err = OpenIFF(iff, IFFF_READ)) != 0) { + errfmt = "OpenIFF failed on %s, code %ld"; + errcode = err; + goto cleanup; + } + iff_opened = 1; + PropChunk(iff, ID_BMAP, ID_BMHD); PropChunk(iff, ID_BMAP, ID_CMAP); PropChunk(iff, ID_BMAP, ID_PDAT); StopChunk(iff, ID_BMAP, ID_PLNE); - if ((j = ParseIFF(iff, IFFPARSE_SCAN)) != 0) - panic("ParseIFF failed on %s, code %d", - filename, j); + if ((err = ParseIFF(iff, IFFPARSE_SCAN)) != 0) { + errfmt = "ParseIFF failed on %s, code %ld"; + errcode = err; + goto cleanup; + } prop = FindProp(iff, ID_BMAP, ID_BMHD); - if (!prop) - panic("No BMHD chunk in %s", filename); + if (!prop) { + errfmt = "No BMHD chunk in %s"; + goto cleanup; + } bmhd = (BitMapHeader *) prop->sp_Data; np = bmhd->nPlanes; @@ -132,18 +150,29 @@ ReadImageFile(const char *filename, struct BitMap **bmp) *bmp = MyAllocBitMap(bmhd->w, bmhd->h, np, MEMF_CHIP | MEMF_CLEAR); - if (!*bmp) - panic("Can't allocate bitmap for %s", filename); + if (!*bmp) { + errfmt = "Can't allocate bitmap for %s"; + goto cleanup; + } for (j = 0; j < np; j++) ReadChunkBytes(iff, (*bmp)->Planes[j], RASSIZE(bmhd->w, bmhd->h)); bmhds = *bmhd; - CloseIFF(iff); - Close(iff->iff_Stream); - FreeIFF(iff); + +cleanup: + if (iff_opened) + CloseIFF(iff); + if (iff && iff->iff_Stream) + Close(iff->iff_Stream); + if (iff) + FreeIFF(iff); CloseLibrary(IFFParseBase); + IFFParseBase = NULL; + + if (errfmt) + panic(errfmt, filename, errcode); return bmhds; } @@ -193,6 +222,11 @@ MyAllocBitMap(int xsize, int ysize, int depth, long mflags) bm->xsize = xsize; bm->ysize = ysize; InitBitMap(&bm->bm, depth, xsize, ysize); + /* InitBitMap does not zero Planes[]; if a later AllocRaster fails + * and MyFreeBitMap unwinds, the uninitialized entries above the + * failure would be passed to FreeRaster as garbage pointers. */ + for (j = 0; j < (int) (sizeof bm->bm.Planes / sizeof bm->bm.Planes[0]); ++j) + bm->bm.Planes[j] = NULL; for (j = 0; j < depth; ++j) { if (mflags & MEMF_CHIP) bm->bm.Planes[j] = AllocRaster(xsize, ysize); From cb46d9effda8c01618c0dbfb05b20ca64d76a4f8 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Tue, 12 May 2026 11:35:41 +0200 Subject: [PATCH 275/702] Amiga: tighten two minor issues from review - amii_set_text_font called CloseLibrary(DiskfontBase) outside the OpenLibrary guard; on Kickstart V36+ that is a no-op for a NULL handle, but on V33/V34 it is undefined. Move the close inside the if-block where DiskfontBase is known non-NULL. - amii_get_ext_cmd's bounds check used BUFSZ for an obufp[100] buffer; the tighter COLNO check actually bounded it but the expression was misleading. Use sizeof obufp. --- sys/amiga/winami.c | 3 ++- sys/amiga/winfuncs.c | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/sys/amiga/winami.c b/sys/amiga/winami.c index 19a660e42..edd1b5d15 100644 --- a/sys/amiga/winami.c +++ b/sys/amiga/winami.c @@ -499,7 +499,8 @@ amii_get_ext_cmd(void) sel = com_index; } else { colx = put_ext_cmd(obufp, colx, cw, bottom); - if (bufp - obufp < BUFSZ - 1 && bufp - obufp < COLNO) + if (bufp - obufp < (int) sizeof obufp - 1 + && bufp - obufp < COLNO) bufp++; } } else if (c == ('X' - 64) || c == '\177') { diff --git a/sys/amiga/winfuncs.c b/sys/amiga/winfuncs.c index 9b172201d..f2ffdb641 100644 --- a/sys/amiga/winfuncs.c +++ b/sys/amiga/winfuncs.c @@ -1732,7 +1732,7 @@ amii_set_text_font(char *name, int size) /* Look for windows to set, and change them */ - if (DiskfontBase = OpenLibrary("diskfont.library", amii_libvers)) { + if ((DiskfontBase = OpenLibrary("diskfont.library", amii_libvers))) { TextsFont = OpenDiskFont(&TextsFont13); for (i = 0; TextsFont && i < MAXWIN; ++i) { if ((cw = amii_wins[i]) && cw->win != NULL) { @@ -1751,9 +1751,9 @@ amii_set_text_font(char *name, int size) } } } + CloseLibrary(DiskfontBase); + DiskfontBase = NULL; } - CloseLibrary(DiskfontBase); - DiskfontBase = NULL; } void From 157c005f02deadd3251003f43513b84926f69f59 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Tue, 12 May 2026 15:18:44 +0200 Subject: [PATCH 276/702] Amiga: harden host-side bmp/xpm to iff converters Replace #pragma-pack BMP header reads with little-endian byte readers so the tool works on any host endianness. Add dimension and color-count range checks, zero-init pixel remap table, check calloc, free bmpdata on early returns, send malloc errors to stderr. Add bp>xbuf guards to xpmgetline's strip loop. --- sys/amiga/bmp2iff_host.c | 76 ++++++++++++++++++++++++++++++++++++---- sys/amiga/xpm2iff_host.c | 18 +++++++--- 2 files changed, 83 insertions(+), 11 deletions(-) diff --git a/sys/amiga/bmp2iff_host.c b/sys/amiga/bmp2iff_host.c index 85bb42088..1182aa732 100644 --- a/sys/amiga/bmp2iff_host.c +++ b/sys/amiga/bmp2iff_host.c @@ -65,6 +65,41 @@ static const RGB amiv_pal[16] = { {0xFF,0xBB,0x99}, /* 15 peach */ }; +/* --------------------------------------------------------- */ +/* Little-endian readers (BMP is LE regardless of host) */ +/* --------------------------------------------------------- */ + +static int +read_u16le(FILE *fp, uint16_t *out) +{ + int lo = fgetc(fp), hi = fgetc(fp); + if (hi == EOF) return 0; + *out = (uint16_t)(((unsigned) hi << 8) | (unsigned) lo); + return 1; +} + +static int +read_u32le(FILE *fp, uint32_t *out) +{ + int b0 = fgetc(fp), b1 = fgetc(fp); + int b2 = fgetc(fp), b3 = fgetc(fp); + if (b3 == EOF) return 0; + *out = ((uint32_t)(unsigned) b3 << 24) + | ((uint32_t)(unsigned) b2 << 16) + | ((uint32_t)(unsigned) b1 << 8) + | (uint32_t)(unsigned) b0; + return 1; +} + +static int +read_i32le(FILE *fp, int32_t *out) +{ + uint32_t v; + if (!read_u32le(fp, &v)) return 0; + *out = (int32_t) v; + return 1; +} + /* --------------------------------------------------------- */ /* Colour helpers */ /* --------------------------------------------------------- */ @@ -345,7 +380,7 @@ main(int argc, char **argv) int nplanes, maxcol; int i, y; RGB outpal[256]; - int remap[256]; + int remap[256] = {0}; uint8_t *remapped; uint8_t *plane_data[8]; uint8_t cmap_rgb[256 * 3]; @@ -370,8 +405,22 @@ main(int argc, char **argv) bmpfp = fopen(argv[3], "rb"); if (!bmpfp) { perror(argv[3]); return 1; } - if (fread(&fhdr, sizeof(fhdr), 1, bmpfp) != 1 - || fread(&ihdr, sizeof(ihdr), 1, bmpfp) != 1) { + if (!read_u16le(bmpfp, &fhdr.bfType) + || !read_u32le(bmpfp, &fhdr.bfSize) + || !read_u16le(bmpfp, &fhdr.bfReserved1) + || !read_u16le(bmpfp, &fhdr.bfReserved2) + || !read_u32le(bmpfp, &fhdr.bfOffBits) + || !read_u32le(bmpfp, &ihdr.biSize) + || !read_i32le(bmpfp, &ihdr.biWidth) + || !read_i32le(bmpfp, &ihdr.biHeight) + || !read_u16le(bmpfp, &ihdr.biPlanes) + || !read_u16le(bmpfp, &ihdr.biBitCount) + || !read_u32le(bmpfp, &ihdr.biCompression) + || !read_u32le(bmpfp, &ihdr.biSizeImage) + || !read_i32le(bmpfp, &ihdr.biXPelsPerMeter) + || !read_i32le(bmpfp, &ihdr.biYPelsPerMeter) + || !read_u32le(bmpfp, &ihdr.biClrUsed) + || !read_u32le(bmpfp, &ihdr.biClrImportant)) { fprintf(stderr, "Failed to read BMP header\n"); return 1; } @@ -388,6 +437,11 @@ main(int argc, char **argv) img_w = ihdr.biWidth; img_h = abs(ihdr.biHeight); + if (img_w <= 0 || img_w > 16384 || img_h <= 0 || img_h > 16384) { + fprintf(stderr, "BMP dimensions out of range: %dx%d\n", + img_w, img_h); + return 1; + } ncolors = ihdr.biClrUsed ? ihdr.biClrUsed : 256; if (ncolors > 256) ncolors = 256; @@ -410,13 +464,15 @@ main(int argc, char **argv) rowstride = (img_w + 3) & ~3; bmpdata = malloc(rowstride * img_h); if (!bmpdata) { - printf("%s\n", "malloc failure on bmpdata"); + fprintf(stderr, "malloc failure on bmpdata\n"); return 1; } fseek(bmpfp, fhdr.bfOffBits, SEEK_SET); if (fread(bmpdata, 1, rowstride * img_h, bmpfp) != (size_t)(rowstride * img_h)) { fprintf(stderr, "Failed to read pixel data\n"); + free(bmpdata); + fclose(bmpfp); return 1; } fclose(bmpfp); @@ -424,7 +480,8 @@ main(int argc, char **argv) /* flip bottom-up to top-down */ pixels = malloc(img_w * img_h); if (!pixels) { - printf("%s\n", "malloc failure on pixels"); + fprintf(stderr, "malloc failure on pixels\n"); + free(bmpdata); return 1; } if (ihdr.biHeight > 0) { @@ -450,7 +507,7 @@ main(int argc, char **argv) remapped = malloc(img_w * img_h); if (!remapped) { - printf("%s\n", "malloc failure on remapped"); + fprintf(stderr, "malloc failure on remapped\n"); return 1; } for (i = 0; i < img_w * img_h; i++) @@ -458,8 +515,13 @@ main(int argc, char **argv) /* convert to bitplanes */ planesize = (img_w / 8) * img_h; - for (i = 0; i < nplanes; i++) + for (i = 0; i < nplanes; i++) { plane_data[i] = calloc(1, planesize); + if (!plane_data[i]) { + fprintf(stderr, "calloc failure for plane %d\n", i); + return 1; + } + } to_planes(remapped, img_w, img_h, nplanes, plane_data); diff --git a/sys/amiga/xpm2iff_host.c b/sys/amiga/xpm2iff_host.c index 589d4f56f..5a968979e 100644 --- a/sys/amiga/xpm2iff_host.c +++ b/sys/amiga/xpm2iff_host.c @@ -62,12 +62,13 @@ xpmgetline(void) /* strip trailing <",> and whitespace */ for (bp = xbuf; *bp; bp++) ; - bp--; - while (isspace((unsigned char)*bp)) + if (bp > xbuf) bp--; - if (*bp == ',') + while (bp > xbuf && isspace((unsigned char)*bp)) bp--; - if (*bp == '"') + if (bp > xbuf && *bp == ',') + bp--; + if (bp > xbuf && *bp == '"') bp--; bp++; *bp = '\0'; @@ -209,10 +210,19 @@ main(int argc, char **argv) return 1; } + if (XpmScreen.Colors < 1 || XpmScreen.Colors > 256) { + fprintf(stderr, + "xpm2iff_host: unsupported color count %d\n", + XpmScreen.Colors); + return 1; + } + /* nplanes = ceil(log2(Colors)) */ nplanes = 0; i = XpmScreen.Colors - 1; while (i > 0) { nplanes++; i >>= 1; } + if (nplanes == 0) + nplanes = 1; colors = 1 << nplanes; From ebcf31a4dae5575d87014f7d81b9274a49142ccf Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Tue, 12 May 2026 15:19:28 +0200 Subject: [PATCH 277/702] Amiga: drop UNTESTED AROS path; tighten fopenp separator write The UNTESTED #ifdef in freediskspace was never gated by any hints file, so the unsigned-long-long path could only be enabled by a stray manual #define -- in which case the return type is still long and silently truncates. Remove the branches. In fopenp the separator '/' write was unchecked: when the path segment exactly filled the buffer to BUFSIZ-2 it would land at buf[BUFSIZ-1] and the follow-on NUL would write past the end. Guard the write. --- sys/amiga/amidos.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/sys/amiga/amidos.c b/sys/amiga/amidos.c index e7b22259a..097e57905 100644 --- a/sys/amiga/amidos.c +++ b/sys/amiga/amidos.c @@ -142,15 +142,7 @@ getlogin(void) long freediskspace(char *path) { -#ifdef UNTESTED - /* these changes from Patric Mueller for AROS to - * handle larger disks. Also needs limits.h and aros/oldprograms.h - * for AROS. (keni) - */ - unsigned long long freeBytes = 0; -#else long freeBytes = 0; -#endif struct InfoData *infoData; /* Remember... longword aligned */ char fileName[32]; @@ -192,11 +184,6 @@ freediskspace(char *path) infoData->id_NumBlocks - infoData->id_NumBlocksUsed; freeBytes -= (freeBytes + EXTENSION) / (EXTENSION + 1); freeBytes *= infoData->id_BytesPerBlock; -#ifdef UNTESTED - if (freeBytes > LONG_MAX) { - freeBytes = LONG_MAX; - } -#endif } if (freeBytes < 0) freeBytes = 0; @@ -368,8 +355,11 @@ fopenp(const char *name, const char *mode) return (NULL); lastch = *bp++ = *pp++; } - if (lastch != ':' && lastch != '/' && bp != buf) + if (lastch != ':' && lastch != '/' && bp != buf) { + if (bp >= buf + BUFSIZ - 2) + return (NULL); *bp++ = '/'; + } if (bp + strlen(name) > buf + BUFSIZ - 1) return (NULL); strcpy(bp, name); From d99eeb17c2c5acbcac1f519909348de116af27a1 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Tue, 12 May 2026 15:21:23 +0200 Subject: [PATCH 278/702] Amiga: header hygiene and palette-size constants Add AMII_PALETTE_SIZE / AMIV_PALETTE_SIZE in amiconf.h to make the actual populated portion of the init-map arrays explicit. Drop the redundant extern void exit() declaration. Annotate Abort with NORETURN in both amiconf.h and winproto.h; drop the duplicate Abort declaration further down winproto.h. Convert the bare-token "CLIPPING must be defined" assertion in windefs.h into a real #error directive. Comment in winext.h to disambiguate the three similarly named amii*_init*map palette arrays. --- include/amiconf.h | 7 +++++-- sys/amiga/windefs.h | 2 +- sys/amiga/winext.h | 11 +++++++++++ sys/amiga/winproto.h | 4 +--- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/include/amiconf.h b/include/amiconf.h index 47306f9d2..593f3e470 100644 --- a/include/amiconf.h +++ b/include/amiconf.h @@ -48,9 +48,8 @@ extern void nethack_exit(int); extern void amii_setpens(int); extern void getlind(const char *, char *, const char *); -extern void exit(int); extern void CleanUp(void); -extern void Abort(long); +extern void Abort(long) NORETURN; extern int getpid(void); extern int kbhit(void); extern int WindowGetchar(void); @@ -84,6 +83,10 @@ extern void ami_wininit_data(int); #define CHANGE_COLOR 1 #define DEPTH 6 /* Maximum depth of the screen allowed */ #define AMII_MAXCOLORS (1L << DEPTH) +/* Number of palette entries actually populated in amii_init_map[] (AMII text + * mode) and amiv_init_map[] (AMIV tile mode). Indices beyond these read 0. */ +#define AMII_PALETTE_SIZE 8 +#define AMIV_PALETTE_SIZE 32 typedef unsigned short AMII_COLOR_TYPE; #define PORT_HELP "amii.hlp" diff --git a/sys/amiga/windefs.h b/sys/amiga/windefs.h index 234d213a8..84faf98ff 100644 --- a/sys/amiga/windefs.h +++ b/sys/amiga/windefs.h @@ -29,7 +29,7 @@ #include "func_tab.h" #ifndef CLIPPING -CLIPPING must be defined for the AMIGA version +#error "CLIPPING must be defined for the AMIGA version" #endif #undef LI diff --git a/sys/amiga/winext.h b/sys/amiga/winext.h index 02d1436a6..0ceff1d6b 100644 --- a/sys/amiga/winext.h +++ b/sys/amiga/winext.h @@ -23,6 +23,17 @@ extern struct amii_DisplayDesc *amiIDisplay; /* the Amiga Intuition descriptor */ extern struct window_procs amii_procs; extern struct window_procs amiv_procs; +/* Three similarly-named palette arrays. Note the position of the + * second underscore distinguishes them: + * amii_initmap = working/runtime palette (mutated by tile/tomb load + * and the in-game color editor). + * amii_init_map = AMII (text-mode) compile-time defaults, 8 entries. + * amiv_init_map = AMIV (tile-mode) compile-time defaults, 32 entries + * (mutated by ReadImageFile when a tile/tomb IFF + * carries its own CMAP). + * The naming is historical; sysflags.amii_curmap is yet another related + * array holding the user's saved color choices. + */ extern unsigned short amii_initmap[AMII_MAXCOLORS]; extern unsigned short amiv_init_map[AMII_MAXCOLORS]; extern unsigned short amii_init_map[AMII_MAXCOLORS]; diff --git a/sys/amiga/winproto.h b/sys/amiga/winproto.h index 831db69a3..60bb1adf9 100644 --- a/sys/amiga/winproto.h +++ b/sys/amiga/winproto.h @@ -59,7 +59,7 @@ int amikbhit(void); int WindowGetchar(void); WETYPE WindowGetevent(void); void amii_cleanup(void); -void Abort(long rc); +void Abort(long rc) NORETURN; void CleanUp(void); void flush_glyph_buffer(struct Window *w); void amiga_print_glyph(winid window, int color_index, int glyph); @@ -120,8 +120,6 @@ void amii_display_file(const char *fn, boolean complain); void SetBorder(struct Gadget *gd); /* malloc/free provided by stdlib.h */ -void Abort(long rc); - win_request_info *amii_ctrl_nhwindow(winid, int, win_request_info *); /* amirip.c */ From 15e3973ac2c5eb639b85277912eddfcc3245df59 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Tue, 12 May 2026 15:24:15 +0200 Subject: [PATCH 279/702] Amiga: tighten input/dialog buffer bounds Right-size the Intuition string-gadget buffer to BUFSZ so a caller with a BUFSZ-sized buffer cannot be overflowed. Enlarge the amii_yn_function prompt buffer to fit the worst-case query + resp + def + trailing space and switch the appends to Snprintf with remaining-space tracking. Replace sprintf in amii_display_file's "Can't display X: Y" path with Snprintf. In EditColor's Save path drop the strcpy/strcat chain that could trail off the end of oname/nname when dirname returned a near-full path; use Snprintf instead. Rewrite dirname() to copy first and truncate the copy, so it no longer briefly NULs the caller's string. --- sys/amiga/winami.c | 15 +++++++++------ sys/amiga/winreq.c | 48 +++++++++++++++++++++++++++------------------- 2 files changed, 37 insertions(+), 26 deletions(-) diff --git a/sys/amiga/winami.c b/sys/amiga/winami.c index edd1b5d15..6fdd95b55 100644 --- a/sys/amiga/winami.c +++ b/sys/amiga/winami.c @@ -339,7 +339,7 @@ struct NewScreen NewHackScreen = { 0, 0, WIDTH, SCREENHEIGHT, 3, 0, void amii_askname(void) { - char plnametmp[300]; /* From winreq.c: sizeof(StrStringSIBuff) */ + char plnametmp[BUFSZ]; /* matches StrStringSIBuff in winreq.c */ *plnametmp = 0; do { amii_getlin("Who are you?", plnametmp); @@ -577,7 +577,7 @@ amii_yn_function(const char *query, const char *resp, char def) char q; char rtmp[40]; boolean digit_ok, allow_num; - char prompt[BUFSZ]; + char prompt[BUFSZ + QBUFSZ + 16]; struct amii_WinDesc *cw; if (cw = amii_wins[WIN_MESSAGE]) @@ -592,10 +592,12 @@ amii_yn_function(const char *query, const char *resp, char def) *rb = '\0'; (void) strncpy(prompt, query, QBUFSZ - 1); prompt[QBUFSZ - 1] = '\0'; - Sprintf(eos(prompt), " [%s]", respbuf); + Snprintf(eos(prompt), sizeof prompt - strlen(prompt), + " [%s]", respbuf); if (def) - Sprintf(eos(prompt), " (%c)", def); - Strcat(prompt, " "); + Snprintf(eos(prompt), sizeof prompt - strlen(prompt), + " (%c)", def); + Snprintf(eos(prompt), sizeof prompt - strlen(prompt), " "); pline("%s", prompt); } else { amii_putstr(WIN_MESSAGE, 0, query); @@ -705,7 +707,8 @@ amii_display_file(const char *fn, boolean complain) if ((fp = dlb_fopen(fn, RDTMODE)) == (dlb *) NULL) { if (complain) { - sprintf(buf, "Can't display %s: %s", fn, strerror(errno)); + Snprintf(buf, sizeof buf, + "Can't display %s: %s", fn, strerror(errno)); amii_addtopl(buf); } return; diff --git a/sys/amiga/winreq.c b/sys/amiga/winreq.c index d4a1bc362..fb87db8bc 100644 --- a/sys/amiga/winreq.c +++ b/sys/amiga/winreq.c @@ -21,8 +21,8 @@ struct IntuiText IText1 = { 3, 0, JAM1, 4, 1, NULL, (UBYTE *) "Cancel", struct Gadget Gadget2 = { NULL, 9, 15, 56, 10, NULL, RELVERIFY, BOOLGADGET, (APTR) &Border1, NULL, &IText1, NULL, NULL, 1, NULL }; -UBYTE StrStringSIBuff[300]; -struct StringInfo StrStringSInfo = { StrStringSIBuff, UNDOBUFFER, 0, 300, 0, +UBYTE StrStringSIBuff[BUFSZ]; +struct StringInfo StrStringSInfo = { StrStringSIBuff, UNDOBUFFER, 0, BUFSZ, 0, 0, 0, 0, 0, 0, 0, 0, NULL }; SHORT BorderVectors2[] = { 0, 0, 439, 0, 439, 11, 0, 11, 0, 0 }; struct Border Border2 = { -1, -1, 3, 0, JAM1, 5, BorderVectors2, NULL }; @@ -187,14 +187,23 @@ EditColor(void) break; } - strcpy(oname, dirname((char *) configfile)); - if (oname[strlen(oname) - 1] != ':') { - sprintf(nname, "%s/New_NetHack.cnf", oname); - strcat(oname, "/"); - strcat(oname, "Old_NetHack.cnf"); - } else { - sprintf(nname, "%sNew_NetHack.cnf", oname); - strcat(oname, "Old_NetHack.cnf"); + { + size_t olen; + strncpy(oname, dirname((char *) configfile), + sizeof(oname) - 1); + oname[sizeof(oname) - 1] = '\0'; + olen = strlen(oname); + if (olen > 0 && oname[olen - 1] != ':') { + Snprintf(nname, sizeof nname, + "%s/New_NetHack.cnf", oname); + Snprintf(oname + olen, sizeof(oname) - olen, + "/Old_NetHack.cnf"); + } else { + Snprintf(nname, sizeof nname, + "%sNew_NetHack.cnf", oname); + Snprintf(oname + olen, sizeof(oname) - olen, + "Old_NetHack.cnf"); + } } nfp = fopen(nname, "w"); @@ -506,20 +515,19 @@ EditClipping(void) char * dirname(char *str) { - char *t, c; static char dir[300]; + char *t; - t = strrchr(str, '/'); + strncpy(dir, str, sizeof(dir) - 1); + dir[sizeof(dir) - 1] = '\0'; + + t = strrchr(dir, '/'); + if (!t) + t = strrchr(dir, ':'); if (!t) - t = strrchr(str, ':'); - if (!t) { dir[0] = '\0'; - } else { - c = *t; - *t = 0; - strcpy(dir, str); - *t = c; - } + else + *t = '\0'; return (dir); } From 252ca5bef7ad1cca25693d40e5e8b0df3594b608 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Tue, 12 May 2026 15:27:13 +0200 Subject: [PATCH 280/702] Amiga: defensive NULL/bounds guards in menus and window creation Guard the gd lookup in DoMenuScroll's GADGETUP/MOUSEMOVE branches so a window with no GadgetID==1 does not deref NULL; match the existing guards in the keyboard-scroll branches. In the keyboard selector and MENU_UNSELECT_ALL paths, only mutate items with canselect set so a non-selectable header cannot have its str stomped. Clamp MENU_LAST_PAGE topidx to >= 0. Make find_menu_item return NULL on negative idx instead of the head item. Guard the PROMPTFIRST data[] shuffle behind cury > 0. In amii_destroy_nhwindow's NHW_OVER branch use cw->win with a NULL guard instead of dereferencing amii_wins[WIN_OVER]->win blindly. Range-check the type argument to amii_create_nhwindow. Fix the *argv_in[1] precedence bug so the -L/-l flag does not deref NULL when it is the last argument. Wrap AllocAslRequest result in a NULL check before AslRequestTags/FreeAslRequest. Defensively bounds-check the idx argument to DispCol. Replace the -25937 signed-int literal in clipwin's PropInfo with the equivalent UWORD value 39599. Simplify amii_start_menu's free loop; switch DoMenuScroll's inventory title and Count display to Snprintf, and stop passing countString to pline as a format. --- sys/amiga/clipwin.c | 2 +- sys/amiga/winamenu.c | 34 +++++++++++++++++++---------- sys/amiga/winfuncs.c | 51 +++++++++++++++++++++++++------------------- sys/amiga/winreq.c | 3 +++ 4 files changed, 56 insertions(+), 34 deletions(-) diff --git a/sys/amiga/clipwin.c b/sys/amiga/clipwin.c index f2d38ce64..6277b6b60 100644 --- a/sys/amiga/clipwin.c +++ b/sys/amiga/clipwin.c @@ -197,7 +197,7 @@ static struct Gadget ClipXSIZE = { static struct PropInfo ClipClipYSIZESInfo = { AUTOKNOB + FREEHORIZ, /* PropInfo flags */ - -25937, -1, /* horizontal and vertical pot values */ + 39599, -1, /* horizontal and vertical pot values */ 10922, -1, /* horizontal and vertical body values */ }; diff --git a/sys/amiga/winamenu.c b/sys/amiga/winamenu.c index 19d439563..7a9e404ed 100644 --- a/sys/amiga/winamenu.c +++ b/sys/amiga/winamenu.c @@ -32,8 +32,7 @@ amii_start_menu(winid window, unsigned long mbehavior UNUSED) cw->data = NULL; } - for (mip = cw->menu.items, i = 0; - (mip = cw->menu.items) && i < cw->menu.count; ++i) { + while ((mip = cw->menu.items) != NULL) { cw->menu.items = mip->next; free(mip); } @@ -149,11 +148,13 @@ amii_end_menu(winid window, const char *morestr) cw->menu.last->next = cw->menu.items; cw->menu.items = cw->menu.last; cw->menu.last = mip; - t = cw->data[cw->cury - 1]; - for (i = cw->cury - 1; i > 0; i--) { - cw->data[i] = cw->data[i - 1]; + if (cw->cury > 0) { + t = cw->data[cw->cury - 1]; + for (i = cw->cury - 1; i > 0; i--) { + cw->data[i] = cw->data[i - 1]; + } + cw->data[0] = t; } - cw->data[0] = t; #endif } @@ -190,6 +191,8 @@ amii_menu_item * find_menu_item(struct amii_WinDesc *cw, int idx) { amii_menu_item *mip; + if (idx < 0) + return NULL; for (mip = cw->menu.items; idx > 0 && mip; mip = mip->next) --idx; @@ -336,7 +339,8 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) nw->Screen = HackScreen; if (win == WIN_INVEN) { - sprintf(title, "%s the %s's Inventory", svp.plname, svp.pl_character); + Snprintf(title, sizeof title, "%s the %s's Inventory", + svp.plname, svp.pl_character); nw->Title = title; if (lastinvent.MaxX != 0) { nw->LeftEdge = lastinvent.MinX; @@ -606,7 +610,8 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) if (how == PICK_ANY) { amip = cw->menu.items; while (amip) { - if (amip->selected) { + if (amip->canselect && amip->selector + && amip->selected) { amip->selected = FALSE; amip->count = -1; amip->str[SOFF + 2] = '-'; @@ -738,8 +743,9 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) } else { reset_counting = TRUE; } - sprintf(countString, "Count: %d", count); - pline(countString); + Snprintf(countString, sizeof countString, + "Count: %ld", count); + pline("%s", countString); } } else if (code == CTRL('D') || code == CTRL('U') || code == MENU_NEXT_PAGE @@ -761,7 +767,7 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) if (code == MENU_FIRST_PAGE) { topidx = 0; } else if (code == MENU_LAST_PAGE) { - topidx = cw->maxrow - wheight; + topidx = max(0, cw->maxrow - wheight); } else for (i = 0; i < endcnt; ++i) { if (code == CTRL('D') || code == MENU_NEXT_PAGE) { @@ -851,6 +857,8 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) } else { int selected = FALSE; for (amip = cw->menu.items; amip; amip = amip->next) { + if (!amip->canselect) + continue; if (amip->selector == code) { if (how == PICK_ONE) aredone = 1; @@ -905,6 +913,8 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) aredone = 1; for (gd = w->FirstGadget; gd && gd->GadgetID != 1;) gd = gd->NextGadget; + if (!gd) + break; pip = (struct PropInfo *) gd->SpecialInfo; totalvis = CountLines(win); @@ -917,6 +927,8 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) case MOUSEMOVE: for (gd = w->FirstGadget; gd && gd->GadgetID != 1;) gd = gd->NextGadget; + if (!gd) + break; pip = (struct PropInfo *) gd->SpecialInfo; totalvis = CountLines(win); diff --git a/sys/amiga/winfuncs.c b/sys/amiga/winfuncs.c index f2ffdb641..e318f3dfa 100644 --- a/sys/amiga/winfuncs.c +++ b/sys/amiga/winfuncs.c @@ -164,23 +164,23 @@ amii_destroy_nhwindow(winid win) /* just hide */ WIN_OVER = WIN_ERR; } } else if (cw->type == NHW_OVER) { - struct Window *w = amii_wins[WIN_OVER]->win; - amii_oldover.MinX = w->LeftEdge; - amii_oldover.MinY = w->TopEdge; - amii_oldover.MaxX = w->Width; - amii_oldover.MaxY = w->Height; + struct Window *w = cw->win; + if (w) { + amii_oldover.MinX = w->LeftEdge; + amii_oldover.MinY = w->TopEdge; + amii_oldover.MaxX = w->Width; + amii_oldover.MaxY = w->Height; - if (WIN_MESSAGE != WIN_ERR && amii_wins[WIN_MESSAGE]) { - w = amii_wins[WIN_MESSAGE]->win; - amii_oldmsg.MinX = w->LeftEdge; - amii_oldmsg.MinY = w->TopEdge; - amii_oldmsg.MaxX = w->Width; - amii_oldmsg.MaxY = w->Height; - SizeWindow(amii_wins[WIN_MESSAGE]->win, - (amiIDisplay->xpix - - amii_wins[WIN_MESSAGE]->win->LeftEdge) - - amii_wins[WIN_MESSAGE]->win->Width, - 0); + if (WIN_MESSAGE != WIN_ERR && amii_wins[WIN_MESSAGE] + && (w = amii_wins[WIN_MESSAGE]->win) != NULL) { + amii_oldmsg.MinX = w->LeftEdge; + amii_oldmsg.MinY = w->TopEdge; + amii_oldmsg.MaxX = w->Width; + amii_oldmsg.MaxY = w->Height; + SizeWindow(w, + (amiIDisplay->xpix - w->LeftEdge) - w->Width, + 0); + } } } } @@ -359,6 +359,9 @@ amii_create_nhwindow(int type) panic("no memory for msg port"); } + if (type < 0 || type > NHW_OVER) + panic("bad type %d in create_nhwindow", type); + nw = &new_wins[type].newwin; nw->Width = amiIDisplay->xpix; nw->Screen = HackScreen; @@ -915,7 +918,7 @@ amii_init_nhwindows(int *argcp, char **argv) for (t = 1; t <= lclargc; t++) { if (!strcmp("-L", *argv_in) || !strcmp("-l", *argv_in)) { - bigscreen = (*argv_in[1] == 'l') ? -1 : 1; + bigscreen = ((*argv_in)[1] == 'l') ? -1 : 1; /* and eat the flag */ (*argcp)--; } else { @@ -1123,12 +1126,16 @@ amii_init_nhwindows(int *argcp, char **argv) SM_FilterHook.h_Data = 0; SM_FilterHook.h_SubEntry = 0; SMR = AllocAslRequest(ASL_ScreenModeRequest, NULL); - if (AslRequestTags(SMR, ASLSM_FilterFunc, (ULONG) &SM_FilterHook, - TAG_END)) - amii_scrnmode = SMR->sm_DisplayID; - else + if (SMR) { + if (AslRequestTags(SMR, ASLSM_FilterFunc, + (ULONG) &SM_FilterHook, TAG_END)) + amii_scrnmode = SMR->sm_DisplayID; + else + amii_scrnmode = 0; + FreeAslRequest(SMR); + } else { amii_scrnmode = 0; - FreeAslRequest(SMR); + } } if (forcenobig == 0) { diff --git a/sys/amiga/winreq.c b/sys/amiga/winreq.c index fb87db8bc..4b3056838 100644 --- a/sys/amiga/winreq.c +++ b/sys/amiga/winreq.c @@ -704,6 +704,9 @@ DispCol(struct Window *w, int idx, UWORD *colors) char buf[50]; char *colname, *defval; + if (idx < 0 || idx >= amii_numcolors) + return; + if (WINVERS_AMIV) { colname = amiv_colnames[idx].name; defval = amiv_colnames[idx].defval; From 4e63ba90ca70d4cbd881af1345acaf591426101b Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Tue, 12 May 2026 15:28:43 +0200 Subject: [PATCH 281/702] Amiga: bound BufferQueueChar; move CloseWindow out of Forbid() Make the BufferQueueChar macro bounds-check KbdBuffered against KBDBUFFER internally so the RAWKEY and NEWSIZE 'R'-64 paths can no longer push past the 10-byte queue; widen KbdBuffered to int so the counter cannot wrap silently in the queue-scan loops. In amii_cleanup move kill_nhwindows()/DeleteMsgPort() outside the Forbid()/Permit() pair: CloseWindow can wait on layers.library semaphores on OS 3.x and that is unsafe under Forbid. Keep only the IDCMP-flush loop inside. --- sys/amiga/amiwind.c | 7 ++++--- sys/amiga/winext.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/sys/amiga/amiwind.c b/sys/amiga/amiwind.c index d259d5128..c3c1b3394 100644 --- a/sys/amiga/amiwind.c +++ b/sys/amiga/amiwind.c @@ -19,7 +19,8 @@ static struct Message *GetFMsg(struct MsgPort *); static int BufferGetchar(void); void ProcessMessage(struct IntuiMessage *message); -#define BufferQueueChar(ch) (KbdBuffer[KbdBuffered++] = (ch)) +#define BufferQueueChar(ch) \ + do { if (KbdBuffered < KBDBUFFER) KbdBuffer[KbdBuffered++] = (ch); } while (0) struct Device *ConsoleDevice = NULL; @@ -51,7 +52,7 @@ struct Library *DiskfontBase; #define KBDBUFFER 10 static unsigned char KbdBuffer[KBDBUFFER]; -unsigned char KbdBuffered; +int KbdBuffered; #ifdef HACKFONT @@ -609,10 +610,10 @@ amii_cleanup(void) Forbid(); while (msg = (struct IntuiMessage *) GetMsg(HackPort)) ReplyMsg((struct Message *) msg); + Permit(); kill_nhwindows(1); DeleteMsgPort(HackPort); HackPort = NULL; - Permit(); } /* Close the screen, under v37 or greater it is a pub screen and there may diff --git a/sys/amiga/winext.h b/sys/amiga/winext.h index 0ceff1d6b..adfd83cd6 100644 --- a/sys/amiga/winext.h +++ b/sys/amiga/winext.h @@ -63,7 +63,7 @@ extern struct Menu HackMenu[]; extern struct Menu *MenuStrip; extern struct NewMenu GTHackMenu[]; extern APTR *VisualInfo; -extern unsigned char KbdBuffered; +extern int KbdBuffered; extern struct TextFont *TextsFont; extern struct TextFont *HackFont; extern struct IOStdReq ConsoleIO; From 459113a48e729df3ad0f1c81698bfa37dea7343d Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Tue, 12 May 2026 15:29:37 +0200 Subject: [PATCH 282/702] Amiga: fix --more-- infinite loop on overlong words When a single word exceeds the visible message-window width the wrap loop found no whitespace, called outmore(cw), and continued without advancing str -- and on the next iteration curx==0 took it straight back to the same spot. Force-break the word at the column boundary when we are already at the start of a line. Also reset the wrapping static flag to 0 after the NHW_BASE wrap cleanup runs, so the cleanup fires once after a wrap instead of on every subsequent putstr. --- sys/amiga/winstr.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/sys/amiga/winstr.c b/sys/amiga/winstr.c index 2f7329467..9d3e207f4 100644 --- a/sys/amiga/winstr.c +++ b/sys/amiga/winstr.c @@ -125,8 +125,25 @@ amii_putstr(winid window, int attr, const char *str) p = (char *) str; if (p == str) { - /* p = (char *)&str[ cw->cols ]; */ - outmore(cw); + /* No whitespace within visible width. */ + if (cw->curx > 0) { + /* Mid-line: clear it and retry at column 0. */ + outmore(cw); + continue; + } + /* Already at line start: word is longer than one + * line, so force-break it at the column boundary. */ + i = cw->cols - 1 - fudge; + if (i <= 0) + i = 1; + if ((size_t) i > strlen(str)) + i = strlen(str); + outsubstr(cw, (char *) str, i, fudge); + cw->curx += i; + str += i; + if (*str) + amii_scrollmsg(w, cw); + amii_cl_end(cw, cw->curx); continue; } @@ -205,6 +222,7 @@ amii_putstr(winid window, int attr, const char *str) TextSpaces(w->RPort, cw->cols); cw->cury--; } + wrapping = 0; } amii_curs(window, cw->curx + 1, cw->cury); Text(w->RPort, (char *) str, strlen((char *) str)); From 146fbf20d8aa4cda608365628694bd152e118126 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Tue, 12 May 2026 15:30:48 +0200 Subject: [PATCH 283/702] Amiga: clamp amii_numcolors and guard tile CMAP loop Reject tile/tomb IFF files whose nPlanes field exceeds DEPTH: the CMAP loop writes 1<= 7 would corrupt adjacent BSS. After OpenScreen succeeds, clamp amii_numcolors to the actually populated portion of the init-map arrays (AMII_PALETTE_SIZE for text mode, AMIV_PALETTE_SIZE for tile mode). On a 64-color screen this stops LoadRGB4 from loading the zero-initialized tail entries as black. Replace the matching magic 32 in the tilefile selection with AMIV_PALETTE_SIZE. While there, add the (char) cast on amii_glyph_buffer's truncating assignment to make the contract explicit. --- sys/amiga/winchar.c | 8 +++++++- sys/amiga/winfuncs.c | 9 +++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/sys/amiga/winchar.c b/sys/amiga/winchar.c index 9636ba3e7..ed486c70e 100644 --- a/sys/amiga/winchar.c +++ b/sys/amiga/winchar.c @@ -130,6 +130,12 @@ ReadImageFile(const char *filename, struct BitMap **bmp) bmhd = (BitMapHeader *) prop->sp_Data; np = bmhd->nPlanes; + if (np > DEPTH) { + errfmt = "%s: too many bitplanes (code %ld)"; + errcode = np; + goto cleanup; + } + /* Load CMAP into palette arrays if present */ prop = FindProp(iff, ID_BMAP, ID_CMAP); if (prop) { @@ -819,7 +825,7 @@ amii_lprint_glyph(winid window, int color_index, int glyph) /* * Add it to the end of the buffer */ - amii_glyph_buffer[glyph_buffer_index++] = glyph; + amii_glyph_buffer[glyph_buffer_index++] = (char) glyph; amii_g_nodes[glyph_node_index - 1].len++; } else { /* See if we're out of glyph nodes */ diff --git a/sys/amiga/winfuncs.c b/sys/amiga/winfuncs.c index e318f3dfa..c5d997ef6 100644 --- a/sys/amiga/winfuncs.c +++ b/sys/amiga/winfuncs.c @@ -1219,9 +1219,9 @@ amii_init_nhwindows(int *argcp, char **argv) if (WINVERS_AMIV) { extern char *tilefile; - if (amii_numcolors >= 32) { + if (amii_numcolors >= AMIV_PALETTE_SIZE) { tilefile = (char *) fqname("tiles/tiles32.iff", DATAPREFIX, 0); - amii_numcolors = 32; + amii_numcolors = AMIV_PALETTE_SIZE; } else { tilefile = (char *) fqname("tiles/tiles16.iff", DATAPREFIX, 0); } @@ -1257,6 +1257,11 @@ amii_init_nhwindows(int *argcp, char **argv) Abort(AN_OpenScreen & ~AT_DeadEnd); } amii_numcolors = 1UL << NewHackScreen.Depth; + { + int palmax = WINVERS_AMIV ? AMIV_PALETTE_SIZE : AMII_PALETTE_SIZE; + if (amii_numcolors > palmax) + amii_numcolors = palmax; + } if (HackScreen->Height > 300 && forcenobig == 0) bigscreen = 1; else From 89971a5fc97b0ecf688e30b42ee794b80ac873a1 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Tue, 12 May 2026 15:31:44 +0200 Subject: [PATCH 284/702] Amiga: fix extended-command menu mouse-pick The amii_get_ext_cmd menu used the first character of each command as the item identity (id.a_char) and then linearly searched extcmdlist for the first command starting with that character. Many commands share a first letter, so picking #airlevel returned #adjust, #wipe returned #wear, etc. Store the actual index in id.a_int and read it back directly. While in that function, size obufp at BUFSZ (was 100) and replace the unbounded strcpy from extcmdlist[i].ef_txt with strncpy + explicit NUL. --- sys/amiga/winami.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/sys/amiga/winami.c b/sys/amiga/winami.c index 6fdd95b55..631af1771 100644 --- a/sys/amiga/winami.c +++ b/sys/amiga/winami.c @@ -375,7 +375,7 @@ amii_get_ext_cmd(void) int bottom = 0; struct Window *w; - char obufp[100]; + char obufp[BUFSZ]; char *bufp = obufp; int c; int com_index, oindex; @@ -417,7 +417,7 @@ amii_get_ext_cmd(void) amii_start_menu(win, MENU_BEHAVE_STANDARD); for (i = 0; extcmdlist[i].ef_txt != NULL; ++i) { - id.a_char = extcmdlist[i].ef_txt[0]; + id.a_int = i; sprintf(buf, "%-10s - %s ", extcmdlist[i].ef_txt, extcmdlist[i].ef_desc); amii_add_menu(win, (const glyph_info *) 0, &id, @@ -432,16 +432,14 @@ amii_get_ext_cmd(void) if (sel == 0) { return (-1); } else { - sel = mip->item.a_char; - for (i = 0; extcmdlist[i].ef_txt != NULL; ++i) { - if (sel == extcmdlist[i].ef_txt[0]) - break; - } + i = mip->item.a_int; /* copy in the text */ if (extcmdlist[i].ef_txt != NULL) { amii_clear_nhwindow(WIN_MESSAGE); - strcpy(bufp = obufp, extcmdlist[i].ef_txt); + strncpy(obufp, extcmdlist[i].ef_txt, sizeof(obufp) - 1); + obufp[sizeof(obufp) - 1] = '\0'; + bufp = obufp; (void) put_ext_cmd(obufp, colx, cw, bottom); return (i); } else From 6736f878aafee238a7c17250a345a3bccb504a67 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Tue, 12 May 2026 15:33:29 +0200 Subject: [PATCH 285/702] Amiga: graphical tombstone RTG-screen fallback amii_outrip relies on LoadRGB4/transpalette fade and raw BltBitMap to a SMART_REFRESH window -- chipset-era idioms that do not reach the visible display on Picasso96 or CyberGraphX screens. On RTG the screen stayed black and the user saw nothing between the death messages and the high-score list. Detect RTG by screen size > 800x600 and fall through to genl_outrip so RTG users get the ASCII tombstone instead. Switch the still-graphical path to BltBitMapRastPort so the blit goes through the layer system, and move CloseWindow(ripwin) outside the Forbid()/Permit() pair (same fix as amii_cleanup). Rename cmap_white/cmap_black to cmap_outline/cmap_fill -- those variables actually hold the indices of the darkest and lightest palette entries, used for the four offset outline strokes and the centered fill stroke respectively; the old names were backwards. --- sys/amiga/amirip.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/sys/amiga/amirip.c b/sys/amiga/amirip.c index 6c23a4f6c..5ccb9aac1 100644 --- a/sys/amiga/amirip.c +++ b/sys/amiga/amirip.c @@ -81,7 +81,7 @@ static struct NewWindow newwin = { 0, 0, 640, 200, 1, 0, int wh; /* was local in outrip, but needed for SCALE macro */ -int cmap_white, cmap_black; +int cmap_outline, cmap_fill; void amii_outrip(winid tmpwin, int how, time_t when) @@ -99,6 +99,16 @@ amii_outrip(winid tmpwin, int how, time_t when) if (!WINVERS_AMIV || HackScreen->RastPort.BitMap->Depth < 4) goto cleanup; + /* The graphical tombstone uses raw chipset-style palette twiddling + * (LoadRGB4, transpalette fade) and BltBitMap to a SMART_REFRESH + * window. That works on the native chipset and AGA, but on RTG + * setups (Picasso96, CyberGraphX) the visible display is decoupled + * from the chipset registers and the tombstone never appears. + * Detect RTG by screen size beyond what chipset modes can reach + * and fall through to the plain ASCII tombstone instead. */ + if (HackScreen->Width > 800 || HackScreen->Height > 600) + goto cleanup; + /* Use the users display size */ newwin.Height = amiIDisplay->ypix - newwin.TopEdge; newwin.Width = amiIDisplay->xpix; @@ -132,11 +142,11 @@ amii_outrip(winid tmpwin, int how, time_t when) for (i = 0; i < SIZE(cols); i++) cols[i] = cols_base[i] + xoff; - cmap_white = search_cmap(0, 0, 0); - cmap_black = search_cmap(15, 15, 15); + cmap_outline = search_cmap(0, 0, 0); + cmap_fill = search_cmap(15, 15, 15); - BltBitMap(tombimg, 0, 0, rp->BitMap, xoff, yoff, tomb_bmhd.w, tomb_bmhd.h, - 0xc0, 0xff, NULL); + BltBitMapRastPort(tombimg, 0, 0, rp, xoff, yoff, + tomb_bmhd.w, tomb_bmhd.h, 0xc0); /* Put together death description */ formatkiller(buf, sizeof buf, how, FALSE); @@ -254,8 +264,8 @@ cleanup: Forbid(); while (imsg = (struct IntuiMessage *) GetMsg(ripwin->UserPort)) ReplyMsg((struct Message *) imsg); - CloseWindow(ripwin); Permit(); + CloseWindow(ripwin); } LoadRGB4(&HackScreen->ViewPort, sysflags.amii_curmap, amii_numcolors); @@ -279,23 +289,23 @@ tomb_text(char *p) sprintf(buf, " %s ", p); l = TextLength(rp, buf, strlen(buf)); - SetAPen(rp, cmap_white); + SetAPen(rp, cmap_outline); Move(rp, cols[cno] - (l / 2) - 1, tomb_line); Text(rp, buf, strlen(buf)); - SetAPen(rp, cmap_white); + SetAPen(rp, cmap_outline); Move(rp, cols[cno] - (l / 2) + 1, tomb_line); Text(rp, buf, strlen(buf)); - SetAPen(rp, cmap_white); + SetAPen(rp, cmap_outline); Move(rp, cols[cno] - (l / 2), tomb_line - 1); Text(rp, buf, strlen(buf)); - SetAPen(rp, cmap_white); + SetAPen(rp, cmap_outline); Move(rp, cols[cno] - (l / 2), tomb_line + 1); Text(rp, buf, strlen(buf)); - SetAPen(rp, cmap_black); + SetAPen(rp, cmap_fill); Move(rp, cols[cno] - (l / 2), tomb_line); Text(rp, buf, strlen(buf)); } From e0ccf22d844601039453740c1ee957f63e8b2763 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 12 May 2026 12:44:26 -0400 Subject: [PATCH 286/702] One of our TeX tools leaves .out files behind --- doc/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/.gitignore b/doc/.gitignore index 2cb6f5896..801e06728 100644 --- a/doc/.gitignore +++ b/doc/.gitignore @@ -10,6 +10,7 @@ Guidebook.dat Guidebook.aux Guidebook.dvi Guidebook.log +Guidebook.out Guidebook.pdf Guidebook.ps Guidebook.dated.* From 1b1beaa5bb7c5440500e2d45a9fe48641fa769e9 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 12 May 2026 18:00:39 -0400 Subject: [PATCH 287/702] spelling correction --- src/invent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invent.c b/src/invent.c index 446859540..078c3c5d5 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1526,7 +1526,7 @@ static const char *const currencies[] = { "cirbozoid", /* Starslip */ "credit chit", /* Deus Ex */ "cubit", /* Battlestar Galactica */ - "Flanian Pobble Bead", /* The Hitchhiker's Guide to the Galaxy */ + "Flainian Pobble Bead", /* The Hitchhiker's Guide to the Galaxy */ "fretzer", /* Jules Verne */ "imperial credit", /* Star Wars */ "Hong Kong Luna Dollar", /* The Moon is a Harsh Mistress */ From 17ae93100327d81c39a1d3a1a36fe7385bb61a02 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 12 May 2026 19:08:44 -0400 Subject: [PATCH 288/702] fixes5-0-1.txt catch-up --- doc/fixes5-0-1.txt | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 0333cc5f7..259399e64 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -19,6 +19,8 @@ when a vault guard was moved off the map, an impossible about trying to update doc: use full URL for nethack.org in Guidebook.mn doc: fix a paste error in Guidebook.tex doc: fix spelling correction in nethack.6 +spelling: "Flanian Pobble Bead" to "Flainian Pobble Bead" + Platform- and/or Interface-Specific Fixes ----------------------------------------- @@ -61,6 +63,28 @@ Amiga: drop redundant 'either windowtype' guards Amiga: deduplicate amii_procs and amiv_procs Amiga: route non-menu messages from DoMenuScroll to ProcessMessage Amiga: delete outdated/sys/amiga/ +Amiga: graphical tombstone RTG-screen fallback +Amiga: fix extended-command menu mouse-pick +Amiga: clamp amii_numcolors and guard tile CMAP loop +Amiga: fix --more-- infinite loop on overlong words +Amiga: bound BufferQueueChar; move CloseWindow out of Forbid() +Amiga: defensive NULL/bounds guards in menus and window creation +Amiga: tighten input/dialog buffer bounds +Amiga: header hygiene and palette-size constants +Amiga: drop UNTESTED AROS path; tighten fopenp separator write +Amiga: harden host-side bmp/xpm to iff converters +Amiga: tighten two minor issues from review +Amiga: fix bitmap/IFF resource handling in winchar.c +Amiga: fix overview-window crashes +Amiga: fix latent issue found in code review: fname[18]/sprintf risks + overflow for >=10 in any version field; switch to snprintf into + a wider static buffer +Amiga: fix latent issue found in code review: (1L << i) for i==31 (or + shifting into the depth-loop terminator) is undefined for signed + long;use 1UL +Amiga: fix latent issue found in code review: Drop unused cnt= from + amii_display_nhwindow's DoMenuScroll call; the menu return value + is consumed elsewhere, not here gcc-16: tiletext.c [-Wdiscarded-qualifiers] warning suppression libnh: update get_nhuuid() for libnhmain libnh: sys/libnh/libnhmain.c: drop `static` on `whoami()` @@ -127,5 +151,6 @@ Amiga: remove miscellaneous unused code like TTY/BBS support, commented out test code etc Amiga: make INTUI_NEW_LOOK unconditional Amiga: drop SHAREDLIB dead build flavor +Amiga: make amigapkg depend on $(GAMEBIN) From b17392a985623489138dff5a646401555ec8027f Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 13 May 2026 11:39:40 -0400 Subject: [PATCH 289/702] innocuous commit --- include/unixconf.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/unixconf.h b/include/unixconf.h index e7ee91565..e493a95b0 100644 --- a/include/unixconf.h +++ b/include/unixconf.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 unixconf.h $NHDT-Date: 1711213886 2024/03/23 17:11:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.57 $ */ +/* NetHack 5.0 unixconf.h $NHDT-Date: 1778686773 2026/05/13 15:39:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.60 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -331,6 +331,7 @@ #include #endif + #if defined(BSD) || defined(ULTRIX) #if !defined(DGUX) && !defined(SUNOS4) #define memcpy(d, s, n) bcopy(s, d, n) From b9da5b7ced9e27fe20c77f20d89f49656843c966 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 13 May 2026 12:40:12 -0400 Subject: [PATCH 290/702] update tested versions of Visual Studio 2026-05-13 --- sys/windows/Makefile.nmake | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index 080e530be..075b82cd2 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -8,8 +8,8 @@ # MS Visual Studio Visual C++ compiler # # Visual Studio Compilers Tested: -# - Microsoft Visual Studio Community 2022 v 17.14.31 -# - Microsoft Visual Studio Community 2026 v 18.5.2 +# - Microsoft Visual Studio Community 2022 v 17.14.32 +# - Microsoft Visual Studio Community 2026 v 18.6.0 # #============================================================================== # This is used for building two distinct executables of NetHack: @@ -1189,6 +1189,7 @@ rc=Rc.exe # Recently tested versions: TESTEDVS2022 = 14.44.35225.0 TESTEDVS2026 = 14.50.35730.0 +TESTEDVS2026 = 14.51.36243.0 VS20261ST = 1450000000 VS2026CUR = $(TESTEDVS2026:.=) From 46ab1ae213299d36bca0744063a44e4eab54c3d1 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 13 May 2026 12:43:15 -0400 Subject: [PATCH 291/702] follow-up: remove previous line --- sys/windows/Makefile.nmake | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index 075b82cd2..578547b32 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -1188,7 +1188,6 @@ rc=Rc.exe # # Recently tested versions: TESTEDVS2022 = 14.44.35225.0 -TESTEDVS2026 = 14.50.35730.0 TESTEDVS2026 = 14.51.36243.0 VS20261ST = 1450000000 From afeb2f55c901483de020390b85be36611c47d05d Mon Sep 17 00:00:00 2001 From: Anthony C Howe Date: Wed, 13 May 2026 12:49:45 -0400 Subject: [PATCH 292/702] bsd build support Originating from https://github.com/NetHack/NetHack/pull/1519, there was an issue with the pull request's back-end fork or with the pull request itself. The code changes were applied manually instead, with credit to the pull request's author, instead of being directly merged in via the pull request. Contributed by @SirWumpus on GitHub. Also, - fixed a bit of conditional code in include/unixconf.h, where the #else clause remained out of reach for non-bsd systems, but was needed.. - added a disclaimer to the contributed sys/unix/hints/netbsd.500. --- include/unixconf.h | 9 ++++- sys/unix/hints/netbsd.500 | 78 +++++++++++++++++++++++++++++++++++++++ win/tty/termcap.c | 22 ++++++----- 3 files changed, 98 insertions(+), 11 deletions(-) create mode 100644 sys/unix/hints/netbsd.500 diff --git a/include/unixconf.h b/include/unixconf.h index e493a95b0..1fe51c128 100644 --- a/include/unixconf.h +++ b/include/unixconf.h @@ -170,7 +170,7 @@ #ifdef AMS #define AMS_MAILBOX "/Mailbox" #else -#if defined(__FreeBSD__) || defined(__OpenBSD__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) #define DEF_MAILREADER "/usr/bin/mail" #else #define DEF_MAILREADER "/usr/ucb/Mail" @@ -331,9 +331,14 @@ #include #endif +#if defined(__NetBSD__) +#define tparm2(s, x) tparm(s,x,0,0,0,0,0,0,0,0) +#else +#define tparm2(s, x) tparm(s,x) +#endif #if defined(BSD) || defined(ULTRIX) -#if !defined(DGUX) && !defined(SUNOS4) +#if !defined(DGUX) && !defined(SUNOS4) && !defined(__NetBSD__) #define memcpy(d, s, n) bcopy(s, d, n) #define memcmp(s1, s2, n) bcmp(s2, s1, n) #endif diff --git a/sys/unix/hints/netbsd.500 b/sys/unix/hints/netbsd.500 new file mode 100644 index 000000000..b62dfbb95 --- /dev/null +++ b/sys/unix/hints/netbsd.500 @@ -0,0 +1,78 @@ +# +# NetHack 5.0 unix $NHDT-Date: 1596498428 2020/08/03 23:47:08 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ +# Copyright 2026 by Anthony C Howe. +# NetHack may be freely redistributed. See license for details. +# +# This is a contributed file. The NetHack Development Team makes this +# file available so that others may benefit, but may not be able to +# support or maintain it. Use at your own risk. +# +#-PRE +# unix hints file +# This hints file provides the legacy configuration that NetHack has shipped +# with historically - this means you will most likely need to hand edit .h +# and Makefiles. + + +PREFIX=/usr/local + +# Binaries and supporting data. +HACKDIR=$(PREFIX)/libexec/nethackdir + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# Careful, this directory is deleted on install. +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +INSTDIR=$(HACKDIR) + +# Save games +VARDIR=/var/games/nethackdir + +# Home for nethask.sh wrapper. If undefined, no wrapper installed. +# Suggest leaving /usr/games as-is from bsdgames.tgz. +SHELLDIR=$(PREFIX)/bin + +CFLAGS=-O -I../include -USYSV -DBSD -DHACKDIR='"$(HACKDIR)"' -DVAR_PLAYGROUND='"$(VARDIR)"' +LINK=$(CC) + +WINSRC = $(WINTTYSRC) +WINOBJ = $(WINTTYOBJ) +WINLIB = $(WINTTYLIB) + +WINTTYLIB=-ltermcap + +CHOWN=chown +CHGRP=chgrp + +GAMEUID = games +GAMEGRP = games + +GAMEPERM = 04755 +VARFILEPERM = 0644 +VARDIRPERM = 0755 + +.ifdef MAKEFILE_DOC +MAKEDEFS = ../util/makedefs +NEEDMAKEDEFS = $(MAKEDEFS) +.if exists (/usr/pkg/bin/groff) +NROFF = /usr/pkg/bin/groff +.else +NROFF = groff +.endif +# NROFF_FLAGS comes from a hints file +GUIDEBOOK = Guidebook # regular ASCII file +COLCMD = col -bx +PSCMD = $(NROFF) +NHGREP = $(MAKEDEFS) --grep --input - --output - +GUIDEBOOK_MN_SRC = Guidebook.mn +GUIDEBOOK_MN = $(GUIDEBOOK_MN_SRC) +GUIDE_PREFORMAT = cat $(GUIDEBOOK_MN) | $(NHGREP) | tbl tmac.n - +ONEPAGE_PREFORMAT = cat Gbk-1pg-pfx.mn $(GUIDEBOOK_MN) Gbk-1pg-sfx.mn \ + | $(NHGREP) | tbl tmac.n - +ONEPAGECMD = $(ONEPAGE_PREFORMAT) | $(NROFF) -c -Tascii $(NROFF_FLAGS) \ + | $(COLCMD) +GUIDECMD = export GROFF_NO_SGR=1; \ + $(GUIDE_PREFORMAT) | $(NROFF) -c -Tascii $(NROFF_FLAGS) \ + | $(COLCMD) +GUIDEBOOK_TEX_SRC = Guidebook.tex +GUIDEBOOK_TEX = $(GUIDEBOOK_TEX_SRC) +.endif # MAKEFILE_DOC diff --git a/win/tty/termcap.c b/win/tty/termcap.c index b5ffcef4e..35c4696ab 100644 --- a/win/tty/termcap.c +++ b/win/tty/termcap.c @@ -41,7 +41,12 @@ static char *nh_VE = (char *) 0; /* cursor_normal */ /*static char *nh_VS = (char *) 0;*/ /* cursor_visible (highlighted cursor) */ static char *nh_Ic = (char *) 0; /* initialize_color */ -static char *HO, *CL, *CE, *UP, *XD, *BC, *SO, *SE, *TI, *TE; +#if !defined(__NetBSD__) +static char *UP, *BC; +static char PC = '\0'; +#endif + +static char *HO, *CL, *CE, *XD, *SO, *SE, *TI, *TE; static char *VS, *VE; static char *ME, *MR, *MB, *MH, *MD; static char *ZH, *ZR; @@ -49,7 +54,6 @@ static char *ZH, *ZR; #ifdef TERMLIB boolean dynamic_HIHE = FALSE; static int SG; -static char PC = '\0'; static char tbuf[512]; #endif /*TERMLIB*/ @@ -973,10 +977,10 @@ init_hilite(void) if (colors >= 16) { for (c = 0; c < SIZE(ti_map); c++) { /* system colors */ - scratch = tparm(setf, ti_map[c].nh_color); + scratch = tparm2(setf, ti_map[c].nh_color); hilites[ti_map[c].nh_color] = dupstr(scratch); /* bright colors */ - scratch = tparm(setf, ti_map[c].nh_bright_color); + scratch = tparm2(setf, ti_map[c].nh_bright_color); hilites[ti_map[c].nh_bright_color] = dupstr(scratch); } } else { @@ -987,7 +991,7 @@ init_hilite(void) while (c--) { char *work; - scratch = tparm(setf, ti_map[c].ti_color); + scratch = tparm2(setf, ti_map[c].ti_color); work = (char *) alloc(strlen(scratch) + md_len + 1); Strcpy(work, MD); hilites[ti_map[c].nh_bright_color] = work; @@ -998,10 +1002,10 @@ init_hilite(void) } if (colors >= 16) { - scratch = tparm(setf, COLOR_WHITE | BRIGHT); + scratch = tparm2(setf, COLOR_WHITE | BRIGHT); hilites[CLR_WHITE] = dupstr(scratch); } else { - scratch = tparm(setf, COLOR_WHITE); + scratch = tparm2(setf, COLOR_WHITE); hilites[CLR_WHITE] = (char *) alloc(strlen(scratch) + md_len + 1); Strcpy(hilites[CLR_WHITE], MD); Strcat(hilites[CLR_WHITE], scratch); @@ -1012,7 +1016,7 @@ init_hilite(void) if (iflags.wc2_darkgray) { if (colors >= 16) { - scratch = tparm(setf, COLOR_BLACK|BRIGHT); + scratch = tparm2(setf, COLOR_BLACK|BRIGHT); hilites[CLR_BLACK] = dupstr(scratch); } else { /* On many terminals, esp. those using classic PC CGA/EGA/VGA @@ -1020,7 +1024,7 @@ init_hilite(void) * produces a dark shade of gray that is visible against a * black background. We can use it to represent black objects. */ - scratch = tparm(setf, COLOR_BLACK); + scratch = tparm2(setf, COLOR_BLACK); hilites[CLR_BLACK] = (char *) alloc(strlen(scratch) + md_len + 1); Strcpy(hilites[CLR_BLACK], MD); Strcat(hilites[CLR_BLACK], scratch); From 17f5642faf45669a6bf2cc7ab6d191ba62328a6e Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 13 May 2026 23:05:44 +0300 Subject: [PATCH 293/702] Obey statue type gender The gnome king statue in minetn-5 was generated as a gnome leader, obey the gender of the statue name, so generating a statue of for example "gnome king" and "gnome queen" works correctly. --- doc/fixes5-0-1.txt | 1 + src/sp_lev.c | 17 +++++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 259399e64..f5c5f25f1 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -20,6 +20,7 @@ doc: use full URL for nethack.org in Guidebook.mn doc: fix a paste error in Guidebook.tex doc: fix spelling correction in nethack.6 spelling: "Flanian Pobble Bead" to "Flainian Pobble Bead" +obey statue type gender (gnome king statue in minetn-5) Platform- and/or Interface-Specific Fixes diff --git a/src/sp_lev.c b/src/sp_lev.c index ab86cd3a5..a894c5e46 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -3671,6 +3671,7 @@ lspo_object(lua_State *L) boolean nonpmobj = FALSE; int i; char *montype = get_table_str_opt(L, "montype", NULL); + int lflags = 0; if (montype) { if ((tmpobj.id == TIN && (!strcmpi(montype, "spinach") @@ -3688,11 +3689,16 @@ lspo_object(lua_State *L) G_NOGEN | G_IGNORE); } else { for (i = LOW_PM; i < NUMMONS; i++) - if (!strcmpi(mons[i].pmnames[NEUTRAL], montype) - || (mons[i].pmnames[MALE] != 0 - && !strcmpi(mons[i].pmnames[MALE], montype)) - || (mons[i].pmnames[FEMALE] != 0 - && !strcmpi(mons[i].pmnames[FEMALE], montype))) { + if (!strcmpi(mons[i].pmnames[NEUTRAL], montype)) { + pm = &mons[i]; + break; + } else if (mons[i].pmnames[MALE] != 0 + && !strcmpi(mons[i].pmnames[MALE], montype)) { + lflags |= CORPSTAT_MALE; + pm = &mons[i]; + } else if (mons[i].pmnames[FEMALE] != 0 + && !strcmpi(mons[i].pmnames[FEMALE], montype)) { + lflags |= CORPSTAT_FEMALE; pm = &mons[i]; break; } @@ -3704,7 +3710,6 @@ lspo_object(lua_State *L) nhl_error(L, "Unknown montype"); } if (tmpobj.id == STATUE || tmpobj.id == CORPSE) { - int lflags = 0; if (get_table_boolean_opt(L, "historic", 0)) lflags |= CORPSTAT_HISTORIC; From 11cd02106380f5a6e1d6e9d9c8c1ba7587299692 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 13 May 2026 17:34:46 -0400 Subject: [PATCH 294/702] update header info on netbsd.500 --- sys/unix/hints/netbsd.500 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/unix/hints/netbsd.500 b/sys/unix/hints/netbsd.500 index b62dfbb95..8a688a630 100644 --- a/sys/unix/hints/netbsd.500 +++ b/sys/unix/hints/netbsd.500 @@ -1,5 +1,5 @@ # -# NetHack 5.0 unix $NHDT-Date: 1596498428 2020/08/03 23:47:08 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ +# NetHack 5.0 unix $NHDT-Date: 1778708083 2026/05/13 21:34:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.0 $ # Copyright 2026 by Anthony C Howe. # NetHack may be freely redistributed. See license for details. # @@ -13,7 +13,6 @@ # with historically - this means you will most likely need to hand edit .h # and Makefiles. - PREFIX=/usr/local # Binaries and supporting data. From bc20ccd6599ede2952fcf64f647337e3b29a04aa Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 13 May 2026 20:38:52 -0400 Subject: [PATCH 295/702] README wording bit --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 46ddd8464..4603e1033 100644 --- a/README +++ b/README @@ -88,8 +88,8 @@ Please read items (1), (2) and (3) BEFORE doing anything with your new code. Intel Pentium or better running Windows 10 or 11 [compiles, runs] Intel-based, or Apple M1, M2, M3, M4, M5 Macs running + macOS 10.11 (El Capitan) to macOS 26 (Tahoe) [compiles, runs] - macOS 10.11 (El Capitan) to macOS 26 (Tahoe) [compile, run] (follow the instructions in sys/unix/NewInstall.unx) Intel 80386 or greater running MS-DOS with DPMI [cross-compiles on Linux, runs on MS-DOS, emulator/dosbox] From 7e50882ffbd438feb37e0069eeead5b60fe24ad0 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 14 May 2026 07:29:02 -0400 Subject: [PATCH 296/702] Files updated from cron daily --- Files | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Files b/Files index 45991d090..4d2b3f1e5 100644 --- a/Files +++ b/Files @@ -402,8 +402,8 @@ NetHack.xcscheme makedefs.xcscheme recover.xcscheme sys/unix/hints: (files for configuring UNIX NetHack versions) linux-minimal linux.500 macOS.500 -macosx.sh solaris solaris-playground -unix +macosx.sh netbsd.500 solaris +solaris-playground unix sys/unix/hints/include: (files for configuring UNIX NetHack versions) From 342bbc85c440103366c6f5c13de6adae2b4677b9 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 14 May 2026 08:31:33 -0400 Subject: [PATCH 297/702] warning bit for clang-22 and tiletext.c --- sys/unix/hints/include/compiler.500 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/unix/hints/include/compiler.500 b/sys/unix/hints/include/compiler.500 index 069b9c995..acc5662d1 100755 --- a/sys/unix/hints/include/compiler.500 +++ b/sys/unix/hints/include/compiler.500 @@ -110,6 +110,7 @@ CXX=clang++ -std=gnu++11 CLANGGTEQ12 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 12) CLANGGTEQ14 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 14) CLANGGTEQ21 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 21) +CLANGGTEQ22 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 22) ifeq "$(CLANGGTEQ12)" "1" CFLAGS+=-Wimplicit-fallthrough endif @@ -124,6 +125,9 @@ endif ifeq "$(CLANGGTEQ21)" "1" CFLAGS+=-Wno-deprecated-octal-literals endif +ifeq "$(CLANGGTEQ22)" "1" +NO_WARN_DISCARDED_QUALIFIERS=-Wno-incompatible-pointer-types-discards-qualifiers +endif # none endif # clang-specific ends here From f000fed16d85e0b48a4ae6a79f50f5fa4acc084a Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 14 May 2026 17:22:53 +0300 Subject: [PATCH 298/702] Fix statue and figurine genders in special levels When a random statue or a figurine was generated in special levels, the gender was not initialized correctly, so you ended up getting eg. "dwarf ruler" It now works correctly, and you can still specifically request a non-gendered version with the montype-parameter. For example des.object({ id = "statue" }); des.object({ id = "statue", montype = "dwarf ruler" }); --- doc/fixes5-0-1.txt | 1 + src/sp_lev.c | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index f5c5f25f1..3cacb63c0 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -21,6 +21,7 @@ doc: fix a paste error in Guidebook.tex doc: fix spelling correction in nethack.6 spelling: "Flanian Pobble Bead" to "Flainian Pobble Bead" obey statue type gender (gnome king statue in minetn-5) +fix statue and figurine genders in special levels in general Platform- and/or Interface-Specific Fixes diff --git a/src/sp_lev.c b/src/sp_lev.c index a894c5e46..eaefe3808 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -3691,11 +3691,13 @@ lspo_object(lua_State *L) for (i = LOW_PM; i < NUMMONS; i++) if (!strcmpi(mons[i].pmnames[NEUTRAL], montype)) { pm = &mons[i]; + tmpobj.spe = 0; break; } else if (mons[i].pmnames[MALE] != 0 && !strcmpi(mons[i].pmnames[MALE], montype)) { lflags |= CORPSTAT_MALE; pm = &mons[i]; + break; } else if (mons[i].pmnames[FEMALE] != 0 && !strcmpi(mons[i].pmnames[FEMALE], montype)) { lflags |= CORPSTAT_FEMALE; @@ -3709,7 +3711,7 @@ lspo_object(lua_State *L) else if (!nonpmobj) nhl_error(L, "Unknown montype"); } - if (tmpobj.id == STATUE || tmpobj.id == CORPSE) { + if (tmpobj.id == STATUE || tmpobj.id == CORPSE || tmpobj.id == FIGURINE) { if (get_table_boolean_opt(L, "historic", 0)) lflags |= CORPSTAT_HISTORIC; @@ -3717,7 +3719,8 @@ lspo_object(lua_State *L) lflags |= CORPSTAT_MALE; if (get_table_boolean_opt(L, "female", 0)) lflags |= CORPSTAT_FEMALE; - tmpobj.spe = lflags; + if (lflags |= 0) + tmpobj.spe = lflags; } else if (tmpobj.id == EGG) { tmpobj.spe = get_table_boolean_opt(L, "laid_by_you", 0) ? 1 : 0; } else if (!nonpmobj) { /* tmpobj.spe is already set for nonpmobj */ From c6a58c5c5a5051021f9f931ab6bf6648384c4fc9 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 14 May 2026 08:48:19 -0700 Subject: [PATCH 299/702] warning fix --- src/sp_lev.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sp_lev.c b/src/sp_lev.c index eaefe3808..ae4757bc4 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -3698,8 +3698,8 @@ lspo_object(lua_State *L) lflags |= CORPSTAT_MALE; pm = &mons[i]; break; - } else if (mons[i].pmnames[FEMALE] != 0 - && !strcmpi(mons[i].pmnames[FEMALE], montype)) { + } else if (mons[i].pmnames[FEMALE] != 0 + && !strcmpi(mons[i].pmnames[FEMALE], montype)) { lflags |= CORPSTAT_FEMALE; pm = &mons[i]; break; @@ -3711,7 +3711,8 @@ lspo_object(lua_State *L) else if (!nonpmobj) nhl_error(L, "Unknown montype"); } - if (tmpobj.id == STATUE || tmpobj.id == CORPSE || tmpobj.id == FIGURINE) { + if (tmpobj.id == STATUE || tmpobj.id == FIGURINE + || tmpobj.id == CORPSE) { if (get_table_boolean_opt(L, "historic", 0)) lflags |= CORPSTAT_HISTORIC; @@ -3719,7 +3720,7 @@ lspo_object(lua_State *L) lflags |= CORPSTAT_MALE; if (get_table_boolean_opt(L, "female", 0)) lflags |= CORPSTAT_FEMALE; - if (lflags |= 0) + if (lflags != 0) tmpobj.spe = lflags; } else if (tmpobj.id == EGG) { tmpobj.spe = get_table_boolean_opt(L, "laid_by_you", 0) ? 1 : 0; From 2eb817af070906553ee360d75f2633519728885e Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 14 May 2026 13:03:48 -0400 Subject: [PATCH 300/702] OS bit in sp_lev.c --- src/sp_lev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sp_lev.c b/src/sp_lev.c index ae4757bc4..496962ae2 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 sp_lev.c $NHDT-Date: 1737610109 2025/01/22 21:28:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.373 $ */ +/* NetHack 5.0 sp_lev.c $NHDT-Date: 1778778225 2026/05/14 17:03:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.387 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -70,7 +70,7 @@ staticfn boolean good_stair_loc(coordxy, coordxy); staticfn void ensure_way_out(void); #if 0 -/* macosx complains that these are unused */ +/* macOS complains that these are unused */ staticfn long sp_code_jmpaddr(long, long); staticfn void spo_room(struct sp_coder *); staticfn void spo_trap(struct sp_coder *); From 5edb093e140af05f57d3305881a6cad13a2c4296 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 14 May 2026 22:40:48 -0400 Subject: [PATCH 301/702] pdcurses: don't truncate curses window width The curses windows were being capped at 110 columns inappropriately. Use the full width of the console. --- include/extern.h | 2 ++ sys/windows/consoletty.c | 12 ++++++++++++ win/curses/cursinit.c | 23 +++++++++++++++++++---- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/include/extern.h b/include/extern.h index af726885b..bac993d62 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2180,6 +2180,8 @@ void console_g_putch(int in_ch); extern void set_output_mode(int); extern void synch_cursor(void); extern void nethack_enter_consoletty(void); +extern int get_console_width(void); +extern int get_console_height(void); extern void consoletty_exit(void); extern int set_keyhandling_via_option(void); #ifdef ENHANCED_SYMBOLS diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index 65462ef47..1e5cb7cd4 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -2638,6 +2638,18 @@ void nethack_enter_consoletty(void) nhUse(apisuccess); } +int +get_console_width(void) +{ + return console.width; +} + +int +get_console_height(void) +{ + return console.height; +} + RESTORE_WARNING_CONDEXPR_IS_CONSTANT #endif /* TTY_GRAPHICS */ diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 5ab7ea198..5fcd726b9 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -761,11 +761,26 @@ curses_init_options(void) terminal size programmatically. If the user does not specify a size in the config file, we will set it to a nice big 32x110 to take advantage of some of the nice features of this windowport. */ - if (iflags.wc2_term_cols == 0) - iflags.wc2_term_cols = 110; - if (iflags.wc2_term_rows == 0) - iflags.wc2_term_rows = 32; + if (iflags.wc2_term_cols == 0) { +#ifndef MSWIN_GRAPHICS + int console_width = get_console_width(); + if (console_width != 0) + iflags.wc2_term_cols = console_width; + else +#endif + iflags.wc2_term_cols = 110; + } + if (iflags.wc2_term_rows == 0) { +#ifndef MSWIN_GRAPHICS + int console_height = get_console_height(); + + if (console_height != 0) + iflags.wc2_term_rows = console_height; + else +#endif + iflags.wc2_term_rows = 32; + } resize_term(iflags.wc2_term_rows, iflags.wc2_term_cols); getmaxyx(base_term, term_rows, term_cols); From accb14b797e24874dc312b1e6e7a51cfeadae93f Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 14 May 2026 23:57:25 -0400 Subject: [PATCH 302/702] free up some console alloc()'d memory under curses tty takes care of this, but it wasn't being done under curses --- include/extern.h | 2 +- sys/windows/consoletty.c | 17 +++++++++++------ sys/windows/windsys.c | 7 +++++++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/include/extern.h b/include/extern.h index bac993d62..8f113ba2d 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2182,7 +2182,7 @@ extern void synch_cursor(void); extern void nethack_enter_consoletty(void); extern int get_console_width(void); extern int get_console_height(void); -extern void consoletty_exit(void); +extern void console_exit(void); extern int set_keyhandling_via_option(void); #ifdef ENHANCED_SYMBOLS extern void tty_utf8graphics_fixup(void); diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index 1e5cb7cd4..2fac8b212 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -954,7 +954,7 @@ tty_number_pad(int state UNUSED) void term_shutdown(void) { - consoletty_exit(); + console_exit(); } #ifdef ASCIIGRAPH @@ -1044,14 +1044,19 @@ consoletty_open(int mode UNUSED) extern void set_emergency_io(void); void -consoletty_exit(void) +console_exit(void) { free_custom_colors(); - free((genericptr_t) console.front_buffer); - free((genericptr_t) console.back_buffer); + if (console.front_buffer) + free((genericptr_t) console.front_buffer); + if (console.back_buffer) + free((genericptr_t) console.back_buffer); console.front_buffer = console.back_buffer = 0; - free((genericptr_t) console.localestr); - free((genericptr_t) console.orig_localestr); + if (console.localestr) + free((genericptr_t) console.localestr), console.localestr = 0; + if (console.orig_localestr) + free((genericptr_t) console.orig_localestr), + console.orig_localestr = 0; set_emergency_io(); } diff --git a/sys/windows/windsys.c b/sys/windows/windsys.c index bd8a9871f..91dc8eb40 100644 --- a/sys/windows/windsys.c +++ b/sys/windows/windsys.c @@ -526,6 +526,13 @@ nethack_exit(int code) genl_status_finish(); #ifdef MSWIN_GRAPHICS free_winmain_stuff(); +#endif +#ifdef WIN32CON +#ifdef CURSES_GRAPHICS + if (WINDOWPORT(curses)) { + console_exit(); + } +#endif #endif exit(code); } From 99f559fe18ecca1cf1d7c4322944ace0129c9ea3 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 15 May 2026 01:21:45 -0400 Subject: [PATCH 303/702] utilize more real estate on Windows GUI curses Some inventory items were being hidden in a lengthy list. --- include/extern.h | 4 ++++ sys/windows/windsys.c | 12 ++++++++++++ win/curses/cursinit.c | 20 ++++++++++++++++++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/include/extern.h b/include/extern.h index 8f113ba2d..eafc34c92 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2031,6 +2031,10 @@ extern int win32_cr_helper(char, struct CRctxt *, void *, int); extern int win32_cr_gettrace(int, char *, int); extern int *win32_cr_shellexecute(const char *); # endif +#ifdef MSWIN_GRAPHICS +extern int get_approx_window_column_width(void); +extern int get_approx_window_rows(void); +#endif #endif /* WIN32 */ #endif /* MICRO || WIN32 */ diff --git a/sys/windows/windsys.c b/sys/windows/windsys.c index 91dc8eb40..40c788a0d 100644 --- a/sys/windows/windsys.c +++ b/sys/windows/windsys.c @@ -1252,6 +1252,18 @@ error: } #undef win32err +#ifdef MSWIN_GRAPHICS +int +get_approx_window_column_width(void) +{ + return GetSystemMetrics(SM_CXSCREEN) / 8; +} +int +get_approx_window_rows(void) +{ + return GetSystemMetrics(SM_CYSCREEN) / 12; +} +#endif #include #define MAX_SYM_SIZE 100 diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 5fcd726b9..dd733a156 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -768,8 +768,18 @@ curses_init_options(void) if (console_width != 0) iflags.wc2_term_cols = console_width; else -#endif iflags.wc2_term_cols = 110; +#else + int width = get_approx_window_column_width(); + + if (width > 220) + width = 220; + + if (width != 0) + iflags.wc2_term_cols = width; + else + iflags.wc2_term_cols = 110; +#endif } if (iflags.wc2_term_rows == 0) { #ifndef MSWIN_GRAPHICS @@ -778,8 +788,14 @@ curses_init_options(void) if (console_height != 0) iflags.wc2_term_rows = console_height; else -#endif iflags.wc2_term_rows = 32; +#else + int scrows = get_approx_window_rows(); + + if (scrows > 54) + scrows = 54; + iflags.wc2_term_rows = scrows ? scrows : 32; +#endif } resize_term(iflags.wc2_term_rows, iflags.wc2_term_cols); getmaxyx(base_term, term_rows, term_cols); From 9ec26da4ff7bef33efae86c6544df8c7e4709924 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 15 May 2026 08:11:56 -0700 Subject: [PATCH 304/702] static analysis fix attempt These three changes compile but I don't know whether thay succeed in suppressing the new static analyzer complaints. --- include/extern.h | 5 +++-- src/options.c | 3 ++- sys/unix/unixunix.c | 8 ++++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/extern.h b/include/extern.h index eafc34c92..64026008e 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 extern.h $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1523 $ */ +/* NetHack 5.0 extern.h $NHDT-Date: 1778886716 2026/05/15 15:11:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.1558 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -693,7 +693,8 @@ extern void free_mgivenname(struct monst *) NONNULLARG1; extern void new_oname(struct obj *, int) NONNULLARG1; extern void free_oname(struct obj *) NONNULLARG1; extern const char *safe_oname(struct obj *) NONNULLARG1; -extern struct monst *christen_monst(struct monst *, const char *) NONNULLARG1; +extern struct monst *christen_monst(struct monst *, const char *) NONNULL + NONNULLARG1; extern struct obj *oname(struct obj *, const char *, unsigned) NONNULLPTRS; extern boolean objtyp_is_callable(int); extern int name_ok(struct obj *); diff --git a/src/options.c b/src/options.c index f5d24b1b1..0bb1b4b29 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 options.c $NHDT-Date: 1737556914 2025/01/22 06:41:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.753 $ */ +/* NetHack 5.0 options.c $NHDT-Date: 1778886716 2026/05/15 15:11:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.782 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -558,6 +558,7 @@ parseoptions( got_match = FALSE; if (allopt[i].pfx) { + assert(allopt[i].name != NULL); if (str_start_is(opts, allopt[i].name, TRUE)) { matchidx = i; got_match = pfx_match = TRUE; diff --git a/sys/unix/unixunix.c b/sys/unix/unixunix.c index d614f3278..55c173004 100644 --- a/sys/unix/unixunix.c +++ b/sys/unix/unixunix.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 unixunix.c $NHDT-Date: 1711213894 2024/03/23 17:11:34 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.43 $ */ +/* NetHack 5.0 unixunix.c $NHDT-Date: 1778886716 2026/05/15 15:11:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.48 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -370,6 +370,9 @@ int child(int wt) { int f; +#ifdef CHDIR + const char *home = getenv("HOME"); +#endif suspend_nhwindows((char *) 0); /* also calls end_screen() */ #ifdef _M_UNIX @@ -382,7 +385,8 @@ child(int wt) (void) setgid(getgid()); (void) setuid(getuid()); #ifdef CHDIR - (void) chdir(getenv("HOME")); + if (home) + (void) chdir(home); #endif return 1; } From 8d0cfb05fa34254a9279e7585f43816557a676c8 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 15 May 2026 12:11:34 -0400 Subject: [PATCH 305/702] rename netbsd.500 to bsd.500 In past releases of NetHack, there was a myriad of different hints files for different operating systems, and even different versions of operating systems. It made maintenance a chore, because all the variable hints files had to be updated for a wanted change, or (as typically was the case), some lesser-used hints files were left behind and became outdated. Instead of going down that road again, this renames sys/unix/hints/netbsd.500 to sys/unix/hints/bsd.500 Where things need to differ for a different bsd flavour, the differences can be shrouded in things like .if ${WHICHBSD} == "NETBSD" .else .endif This change is being done to make maintenance easier, at the cost of making the resulting Makefiles a little more complex, but there won't be as many separate Makefile hints to maintain. This commit is being done instead of merging pull request #1531 which would add a new sys/unix/hints/openbsd.500 file. Only tested on NetBSD so far. Please let us know if there's an issue on other bsd's, and we will attempt to fix thos issues. Closes #1531 Close --- include/unixconf.h | 2 +- sys/unix/hints/{netbsd.500 => bsd.500} | 12 +++++++++++- sys/unix/hints/include/whichbsd.500 | 22 ++++++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) rename sys/unix/hints/{netbsd.500 => bsd.500} (88%) create mode 100644 sys/unix/hints/include/whichbsd.500 diff --git a/include/unixconf.h b/include/unixconf.h index 1fe51c128..f4856055c 100644 --- a/include/unixconf.h +++ b/include/unixconf.h @@ -338,7 +338,7 @@ #endif #if defined(BSD) || defined(ULTRIX) -#if !defined(DGUX) && !defined(SUNOS4) && !defined(__NetBSD__) +#if !defined(DGUX) && !defined(SUNOS4) && !defined(__NetBSD__) && !defined(__FreeBSD__) #define memcpy(d, s, n) bcopy(s, d, n) #define memcmp(s1, s2, n) bcmp(s2, s1, n) #endif diff --git a/sys/unix/hints/netbsd.500 b/sys/unix/hints/bsd.500 similarity index 88% rename from sys/unix/hints/netbsd.500 rename to sys/unix/hints/bsd.500 index 8a688a630..14187680a 100644 --- a/sys/unix/hints/netbsd.500 +++ b/sys/unix/hints/bsd.500 @@ -12,6 +12,10 @@ # This hints file provides the legacy configuration that NetHack has shipped # with historically - this means you will most likely need to hand edit .h # and Makefiles. +# +# note: '#-INCLUDE' is not just a comment. setup.sh inserts the contents of +# a file found in sys/unix/hints/include +#-INCLUDE whichbsd.500 PREFIX=/usr/local @@ -52,11 +56,17 @@ VARDIRPERM = 0755 .ifdef MAKEFILE_DOC MAKEDEFS = ../util/makedefs NEEDMAKEDEFS = $(MAKEDEFS) + +.if ${WHICHBSD} == "NETBSD" .if exists (/usr/pkg/bin/groff) NROFF = /usr/pkg/bin/groff .else NROFF = groff -.endif +.endif # ? Is NROFF groff or /usr/pkg/bin/groff +.else # WHICHBSD is not NETBSD +NROFF = groff +.endif # WHICHBSD + # NROFF_FLAGS comes from a hints file GUIDEBOOK = Guidebook # regular ASCII file COLCMD = col -bx diff --git a/sys/unix/hints/include/whichbsd.500 b/sys/unix/hints/include/whichbsd.500 new file mode 100644 index 000000000..c2bd28795 --- /dev/null +++ b/sys/unix/hints/include/whichbsd.500 @@ -0,0 +1,22 @@ +#================================================================= +# NetHack 5.0 include/whichbsd.500 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-5.0 $ +# +# +# +.ifdef WHICHBSD +.undef WHICHBSD +.endif + +.if ${.MAKE.OS} == "FreeBSD" +WHICHBSD=FREEBSD +.elif ${.MAKE.OS} == "OpenBSD" +WHICHBSD=OPENBSD +.elif ${.MAKE.OS} == "NetBSD" +WHICHBSD=NETBSD +.else +WHICHBSD=OTHERBSD +.endif + +# End of whichbsd.500 -PRE section +#================================================================= + From d81d47b81e516d4dc06c38620b2203ce18afac38 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 15 May 2026 12:18:29 -0400 Subject: [PATCH 306/702] new file header info --- sys/unix/hints/include/whichbsd.500 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/unix/hints/include/whichbsd.500 b/sys/unix/hints/include/whichbsd.500 index c2bd28795..32be90b5d 100644 --- a/sys/unix/hints/include/whichbsd.500 +++ b/sys/unix/hints/include/whichbsd.500 @@ -1,6 +1,5 @@ #================================================================= -# NetHack 5.0 include/whichbsd.500 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-5.0 $ -# +# NetHack 5.0 include/whichbsd.500 $NHDT-Date: 1778861905 2026/05/15 16:18:25 $ $NHDT-Branch: NetHack-5.0 $ # # .ifdef WHICHBSD From e05864544cc54067717ab273dc45751bd560db2c Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Fri, 15 May 2026 12:16:06 -0400 Subject: [PATCH 307/702] This is cron-daily v1-May-7-2026. 000files updated: Files --- Files | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Files b/Files index 4d2b3f1e5..e6d4e707f 100644 --- a/Files +++ b/Files @@ -401,8 +401,8 @@ NetHack.xcscheme makedefs.xcscheme recover.xcscheme sys/unix/hints: (files for configuring UNIX NetHack versions) -linux-minimal linux.500 macOS.500 -macosx.sh netbsd.500 solaris +bsd.500 linux-minimal linux.500 +macOS.500 macosx.sh solaris solaris-playground unix sys/unix/hints/include: @@ -410,7 +410,7 @@ sys/unix/hints/include: compiler.500 cross-post.500 cross-pre1.500 cross-pre2.500 gbdates-post.500 gbdates-pre.500 misc.500 multisnd-post.500 multisnd1-pre.500 multisnd2-pre.500 multiw-1.500 multiw-2.500 -response.500 +response.500 whichbsd.500 sys/vms: (files for VMS version) From a533350537e1bb355622014c88ecfebd09d58350 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 15 May 2026 20:21:48 +0300 Subject: [PATCH 308/702] TTY: allow custom glyph colors on more limited terminals Previously changing glyph colors required a terminal with more than 256 colors, even if the color was one of the basic 16 colors used by NetHack. --- doc/fixes5-0-1.txt | 2 ++ win/tty/wintty.c | 13 ++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 3cacb63c0..6cd737192 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -114,6 +114,8 @@ Windows: correct a NetHack 5.0.0 packaging error if visual studio was used; a remnant hard-coded 370 was in package.nmake Windows: setting any map_mode option in the config file could trigger an app failure on launch by dereferencing a null pointer +tty: allow custom glyph colors if they're basic 16 nethack colors + on terminals with less than 256 colors General New Features diff --git a/win/tty/wintty.c b/win/tty/wintty.c index c9bdd4b06..68cce5c6a 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -3897,18 +3897,17 @@ tty_print_glyph( if (ttyDisplay->color != NO_COLOR) term_end_color(); } - /* we don't link with termcap.o if NO_TERMS is defined */ - if ((tty_procs.wincap2 & WC2_EXTRACOLORS) - && glyphinfo->gm.customcolor != 0 - && iflags.colorcount >= 256 + if (glyphinfo->gm.customcolor != 0 && !calling_from_update_inventory) { - if ((glyphinfo->gm.customcolor & NH_BASIC_COLOR) == 0) { + if ((glyphinfo->gm.customcolor & NH_BASIC_COLOR) != 0) { + /* NH_BASIC_COLOR */ + color = COLORVAL(glyphinfo->gm.customcolor); + } else if ((tty_procs.wincap2 & WC2_EXTRACOLORS) + && iflags.colorcount >= 256) { term_start_extracolor(glyphinfo->gm.customcolor, glyphinfo->gm.color256idx); ttyDisplay->colorflags = 0; colordone = TRUE; - } else { - color = COLORVAL(glyphinfo->gm.customcolor); } } if (!colordone) { From c558ef0b33220bb262750ddbc1d15bbcdacd54ad Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 15 May 2026 15:29:25 -0400 Subject: [PATCH 309/702] Makefile syntax did not work on OpenBSD Trying another approach for whichbsd.500 --- sys/unix/hints/include/whichbsd.500 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sys/unix/hints/include/whichbsd.500 b/sys/unix/hints/include/whichbsd.500 index 32be90b5d..86fa74ea0 100644 --- a/sys/unix/hints/include/whichbsd.500 +++ b/sys/unix/hints/include/whichbsd.500 @@ -6,11 +6,13 @@ .undef WHICHBSD .endif -.if ${.MAKE.OS} == "FreeBSD" +OS!=uname -s + +.if ${OS} == "FreeBSD" WHICHBSD=FREEBSD -.elif ${.MAKE.OS} == "OpenBSD" +.elif ${OS} == "OpenBSD" WHICHBSD=OPENBSD -.elif ${.MAKE.OS} == "NetBSD" +.elif ${OS} == "NetBSD" WHICHBSD=NETBSD .else WHICHBSD=OTHERBSD From e11ff5f703642f15141c5818f1ba075fd79ace38 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 15 May 2026 13:40:34 -0700 Subject: [PATCH 310/702] another try at removing static analyzer complaints The one in options hasn't been addressed this time. --- src/bones.c | 1 + sys/unix/unixunix.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/bones.c b/src/bones.c index d7837536a..092ed203a 100644 --- a/src/bones.c +++ b/src/bones.c @@ -471,6 +471,7 @@ savebones(int how, time_t when, struct obj *corpse) to be given here, but it has been moved to done() so that it gets delivered even when savebones() isn't called] */ drop_upon_death(mtmp, (struct obj *) 0, u.ux, u.uy); + assert(mtmp != NULL && mtmp->data != NULL); /* static analysis hack */ /* 'mtmp' now has hero's inventory; if 'mtmp' is a mummy, give it a wrapping unless already carrying one */ if (mtmp->data->mlet == S_MUMMY && !m_carrying(mtmp, MUMMY_WRAPPING)) diff --git a/sys/unix/unixunix.c b/sys/unix/unixunix.c index 55c173004..a7fb3f92e 100644 --- a/sys/unix/unixunix.c +++ b/sys/unix/unixunix.c @@ -370,9 +370,6 @@ int child(int wt) { int f; -#ifdef CHDIR - const char *home = getenv("HOME"); -#endif suspend_nhwindows((char *) 0); /* also calls end_screen() */ #ifdef _M_UNIX @@ -382,6 +379,9 @@ child(int wt) linux_mapon(); #endif if ((f = fork()) == 0) { /* child */ +#ifdef CHDIR + const char *home = getenv("HOME"); +#endif (void) setgid(getgid()); (void) setuid(getuid()); #ifdef CHDIR From 3a0c6f17c72bdead48f38fd52080aee55013b266 Mon Sep 17 00:00:00 2001 From: Patric Mueller Date: Fri, 15 May 2026 23:30:29 +0200 Subject: [PATCH 311/702] fix buffer overflow in update_topl Buffer overflows could occur when interacting with containers while inputting or outputting many items. This commit ensures topline updates do not exceed buffer limits by checking against TBUFSZ. Issue reported by k21971 on IRC. --- doc/fixes5-0-1.txt | 2 ++ win/tty/topl.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 6cd737192..175061880 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -22,6 +22,8 @@ doc: fix spelling correction in nethack.6 spelling: "Flanian Pobble Bead" to "Flainian Pobble Bead" obey statue type gender (gnome king statue in minetn-5) fix statue and figurine genders in special levels in general +fix buffer overflow in update_topl when handling multiple items in a + container Platform- and/or Interface-Specific Fixes diff --git a/win/tty/topl.c b/win/tty/topl.c index a216b3435..b9f9936a8 100644 --- a/win/tty/topl.c +++ b/win/tty/topl.c @@ -261,7 +261,8 @@ update_topl(const char *bp) n0 = strlen(bp); if ((ttyDisplay->toplin == TOPLINE_NEED_MORE || skip) && cw->cury == 0 - && n0 + (int) strlen(gt.toplines) + 3 < CO - 8 /* room for --More-- */ + /* room for --More-- */ + && n0 + (int) strlen(gt.toplines) + 3 < min(CO - 8, TBUFSZ) && (notdied = strncmp(bp, "You die", 7)) != 0) { Strcat(gt.toplines, " "); Strcat(gt.toplines, bp); From a8f97a39263b99eba3a87ba34ccda02dd3df0bf1 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 15 May 2026 21:58:51 -0400 Subject: [PATCH 312/702] OpenBSD build bits An issue still remains with fetch-Lua in the top Makefile. --- include/unixconf.h | 6 ++++-- win/tty/termcap.c | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/unixconf.h b/include/unixconf.h index f4856055c..0bae0ddf0 100644 --- a/include/unixconf.h +++ b/include/unixconf.h @@ -331,14 +331,16 @@ #include #endif -#if defined(__NetBSD__) +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) #define tparm2(s, x) tparm(s,x,0,0,0,0,0,0,0,0) #else #define tparm2(s, x) tparm(s,x) #endif #if defined(BSD) || defined(ULTRIX) -#if !defined(DGUX) && !defined(SUNOS4) && !defined(__NetBSD__) && !defined(__FreeBSD__) +#if !defined(DGUX) && !defined(SUNOS4) \ + && !defined(__NetBSD__) && !defined(__FreeBSD__) \ + && !defined(__OpenBSD__) #define memcpy(d, s, n) bcopy(s, d, n) #define memcmp(s1, s2, n) bcmp(s2, s1, n) #endif diff --git a/win/tty/termcap.c b/win/tty/termcap.c index 35c4696ab..d5fb0f755 100644 --- a/win/tty/termcap.c +++ b/win/tty/termcap.c @@ -894,7 +894,8 @@ cl_eos(void) /* free after Robert Viduya */ #include -#if !defined(LINUX) && !defined(__FreeBSD__) && !defined(NOTPARMDECL) +#if !defined(LINUX) && !defined(__FreeBSD__) && !defined(__OpenBSD__) \ + && !defined(NOTPARMDECL) extern char *tparm(); #endif From 0f0e7c99bf4010bff0533a80df300b8fda00ce0e Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 16 May 2026 14:57:12 +0300 Subject: [PATCH 313/702] Fix random attended shrines in irregular rooms --- doc/fixes5-0-1.txt | 1 + src/mkroom.c | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 175061880..fa287d1ee 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -24,6 +24,7 @@ obey statue type gender (gnome king statue in minetn-5) fix statue and figurine genders in special levels in general fix buffer overflow in update_topl when handling multiple items in a container +fix random attended shrines in irregular rooms Platform- and/or Interface-Specific Fixes diff --git a/src/mkroom.c b/src/mkroom.c index dd9fa8468..f1a0cfb35 100644 --- a/src/mkroom.c +++ b/src/mkroom.c @@ -573,6 +573,8 @@ mkswamp(void) /* Michiel Huisjes & Fred de Wilde */ } } +/* return center of room, or a random free location + if center is blocked */ staticfn coord * shrine_pos(int roomno) { @@ -591,6 +593,14 @@ shrine_pos(int roomno) buf.y = troom->ly + delta / 2; if ((delta % 2) && rn2(2)) buf.y++; + + /* irregular room or the location is blocked */ + if (roomno != levl[buf.x][buf.y].roomno + || (levl[buf.x][buf.y].typ != ROOM + && levl[buf.x][buf.y].typ != ICE + && levl[buf.x][buf.y].typ != CLOUD)) + (void) somexyspace(troom, &buf); + return &buf; } From 2445b97a10b0c250375242b2d6e695d30da3214c Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 16 May 2026 08:57:54 -0400 Subject: [PATCH 314/702] build fix with hints file linux.500 and musl=1 This fix was suggested by @PPN-SD in the comments on GitHub issue https://github.com/NetHack/NetHack/issues/1530#issuecomment-4466027729 Resolves #1530 --- sys/unix/hints/linux.500 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index 05cb8c956..d4b095e25 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -197,7 +197,10 @@ ifeq "$(CCISCLANG)" "1" # clang-specific ends else # gcc-specific starts +ifndef MUSL +# __sighandler_t does not exist in musl LIBCFLAGS+=-DSIG_RET_TYPE=__sighandler_t +endif # gcc-specific ends endif From e1ee404ecc46708919ec3eb428359966ba777f59 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 16 May 2026 09:05:29 -0400 Subject: [PATCH 315/702] warning workaround led to a build error on some platforms & compilers Use another method for the warning workaround. allmain.c:33:56: error: 'maybe_unused' attribute cannot be applied to types 33 | early_init(int argc USED_FOR_CRASHREPORT, char *argv[] USED_FOR_CRASHREPORT) | ^ allmain.c:28:30: note: expanded from macro 'USED_FOR_CRASHREPORT' 28 | #define USED_FOR_CRASHREPORT UNUSED | ^ ../include/tradstdc.h:510:16: note: expanded from macro 'UNUSED' 510 | #define UNUSED ATTRUNUSED | ^ ../include/tradstdc.h:397:22: note: expanded from macro 'ATTRUNUSED' 397 | #define ATTRUNUSED [[maybe_unused]] | ^ allmain.c:33:49: warning: unused parameter 'argv' [-Wunused-parameter] 33 | early_init(int argc USED_FOR_CRASHREPORT, char *argv[] USED_FOR_CRASHREPORT) | ^ 1 warning and 1 error generated. --- src/allmain.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/allmain.c b/src/allmain.c index f7ee742ad..5c573da4b 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -22,15 +22,9 @@ staticfn void regen_pw(int); staticfn void regen_hp(int); staticfn void interrupt_multi(const char *); -#ifdef CRASHREPORT -#define USED_FOR_CRASHREPORT -#else -#define USED_FOR_CRASHREPORT UNUSED -#endif - /*ARGSUSED*/ void -early_init(int argc USED_FOR_CRASHREPORT, char *argv[] USED_FOR_CRASHREPORT) +early_init(int argc, char *argv[]) { program_state_init(); #ifdef CRASHREPORT @@ -42,6 +36,8 @@ early_init(int argc USED_FOR_CRASHREPORT, char *argv[] USED_FOR_CRASHREPORT) monst_globals_init(); sys_early_init(); runtime_info_init(); + nhUse(argc); + nhUse(argv[0]); } staticfn void From 5199921c05dbb38acbc45a1195ce38efc722155f Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 16 May 2026 16:51:30 +0300 Subject: [PATCH 316/702] Fix experience-level up/down hilighting The highlighting worked correctly for #levelchange in wizard mode, but not for gaining experience levels by killing monsters. --- doc/fixes5-0-1.txt | 1 + src/botl.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index fa287d1ee..9742f9b0f 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -25,6 +25,7 @@ fix statue and figurine genders in special levels in general fix buffer overflow in update_topl when handling multiple items in a container fix random attended shrines in irregular rooms +fix experience-level up/down hilighting Platform- and/or Interface-Specific Fixes diff --git a/src/botl.c b/src/botl.c index 22f447ea4..dea5c2e42 100644 --- a/src/botl.c +++ b/src/botl.c @@ -714,7 +714,7 @@ static struct istat_s initblstats[MAXBLSTATS] = { INIT_BLSTAT("gold", " %s", ANY_LONG, 40, BL_GOLD), INIT_BLSTATP("power", " Pw:%s", ANY_INT, 10, BL_ENEMAX, BL_ENE), INIT_BLSTAT("power-max", "(%s)", ANY_INT, 10, BL_ENEMAX), - INIT_BLSTATP("experience-level", " Xp:%s", ANY_INT, 10, BL_EXP, BL_XP), + INIT_BLSTATP("experience-level", " Xp:%s", ANY_INT, 10, BL_XP, BL_XP), INIT_BLSTAT("armor-class", " AC:%s", ANY_INT, 10, BL_AC), INIT_BLSTAT("HD", " HD:%s", ANY_INT, 10, BL_HD), INIT_BLSTAT("time", " T:%s", ANY_LONG, 30, BL_TIME), From 4434b14884caa74ffd8d28f6e52509f0c9b89f2d Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 16 May 2026 10:59:48 -0400 Subject: [PATCH 317/702] more hints file readiness in Makefiles --- include/config.h | 2 ++ sys/unix/Makefile.doc | 3 +++ sys/unix/Makefile.src | 13 ++++++++----- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/include/config.h b/include/config.h index e266ad092..4fcc892e0 100644 --- a/include/config.h +++ b/include/config.h @@ -677,9 +677,11 @@ typedef unsigned char uchar; #ifdef NHL_SANDBOX #ifdef CHRONICLE /* LIVELOG (and therefore CHRONICLE) is needed for --loglua */ +#ifndef LIVELOG #define LIVELOG #endif #endif +#endif /* experimential; if the platform/window-port supports it; when the game has * started to wait for player input, and the wait lasts longer than diff --git a/sys/unix/Makefile.doc b/sys/unix/Makefile.doc index 41a620794..dadbdf295 100644 --- a/sys/unix/Makefile.doc +++ b/sys/unix/Makefile.doc @@ -96,12 +96,14 @@ $(MAKEDEFS) : ../util/makedefs.c ../include/config.h ../src/mdlib.c \ GAME = nethack MANDIR ?= /usr/man/man6 MANEXT = 6 +MANDIRPREP ?= true # manual installation for most BSD-style systems GAMEMANCREATE = cat nethack.6 | $(NHGREP) > RCVRMANCREATE = cat recover.6 | $(NHGREP) > DLBMANCREATE = cat dlb.6 | $(NHGREP) > MDMANCREATE = cat makedefs.6 | $(NHGREP) > + # manual installation for most SYSV-style systems # GAMEMANCREATE = cat nethack.6 | $(NHGREP) | $(NROFF) -man - > # RCVRMANCREATE = cat recover.6 | $(NHGREP) | $(NROFF) -man - > @@ -109,6 +111,7 @@ MDMANCREATE = cat makedefs.6 | $(NHGREP) > # MDMANCREATE = cat makedefs.6 | $(NHGREP) | $(NROFF) -man - > manpages: $(PREMANPAGES) + -$(MANDIRPREP) -$(GAMEMANCREATE) $(MANDIR)/$(GAME).$(MANEXT) -$(RCVRMANCREATE) $(MANDIR)/recover.$(MANEXT) -$(DLBMANCREATE) $(MANDIR)/dlb.$(MANEXT) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 863fa096c..519894b13 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -230,6 +230,9 @@ REGEXOBJ ?= $(TARGETPFX)posixregex.o #REGEXOBJ = $(TARGETPFX)pmatchregex.o #REGEXOBJ = $(TARGETPFX)cppregex.o +TILECFILE ?= tile.c +TILEOFILE ?= + # Set the WINSRC, WINOBJ, and WINLIB lines to correspond to your desired # combination of windowing systems. Also set matching USE_x_GRAPHICS in # config.h. Note that if you are building for any window system which @@ -260,10 +263,10 @@ WINX11SRC = ../win/X11/Window.c ../win/X11/dialogs.c ../win/X11/winX.c \ ../win/X11/winmap.c ../win/X11/winmenu.c ../win/X11/winmesg.c \ ../win/X11/winmisc.c ../win/X11/winstat.c ../win/X11/wintext.c \ ../win/X11/winval.c tile.c -WINX11OBJ = $(TARGETPFX)Window.o $(TARGETPFX)dialogs.o $(TARGETPFX)winX.o \ +WINX11OBJ ?= $(TARGETPFX)Window.o $(TARGETPFX)dialogs.o $(TARGETPFX)winX.o \ $(TARGETPFX)winmap.o $(TARGETPFX)winmenu.o $(TARGETPFX)winmesg.o \ $(TARGETPFX)winmisc.o $(TARGETPFX)winstat.o $(TARGETPFX)wintext.o \ - $(TARGETPFX)winval.o #$(TARGETPFX)tile.o + $(TARGETPFX)winval.o $(TILEOFILE) # # Files for a Qt 3 interface (renamed since nethack 3.6.x) # @@ -291,7 +294,7 @@ WINQTSRC = ../win/Qt/qt_bind.cpp ../win/Qt/qt_click.cpp \ ../win/Qt/qt_stat.cpp ../win/Qt/qt_str.cpp ../win/Qt/qt_streq.cpp \ ../win/Qt/qt_svsel.cpp ../win/Qt/qt_win.cpp ../win/Qt/qt_xcmd.cpp \ ../win/Qt/qt_yndlg.cpp $(WINQTMOC) tile.c -WINQTOBJ = $(TARGETPFX)qt_bind.o $(TARGETPFX)qt_click.o \ +WINQTOBJ ?= $(TARGETPFX)qt_bind.o $(TARGETPFX)qt_click.o \ $(TARGETPFX)qt_clust.o $(TARGETPFX)qt_delay.o \ $(TARGETPFX)qt_glyph.o $(TARGETPFX)qt_icon.o \ $(TARGETPFX)qt_inv.o $(TARGETPFX)qt_key.o $(TARGETPFX)qt_line.o \ @@ -366,7 +369,7 @@ WINBELIB = -lbe # # libraries for curses port # link with ncurses -WINCURSESLIB = -lncurses +WINCURSESLIB ?= -lncurses # link with pdcurses for SDL, installed in a separate directory #WINCURSESLIB = -L/usr/local/lib/pdcurses -lpdcurses -lSDL # same as above, for XCurses @@ -426,7 +429,7 @@ RANDOBJ = # used by `make depend' to reconstruct this Makefile; you shouldn't need this # at all but can override with 'make AWK=nawk' or 'make AWK=gawk' if necessary -AWK = awk +AWK ?= awk # when using 'makedefs -v', also force dat/gitinfo.txt to be up to date; # changing this to 0 will change the behavior to only make that file if From b2458e679a7eb8a0d867b9d09187e92a0a6eceab Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 16 May 2026 11:37:51 -0400 Subject: [PATCH 318/702] recently-appeared warning bit mkroom.c(598): warning C4389: '!=': signed/unsigned mismatch --- src/mkroom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mkroom.c b/src/mkroom.c index f1a0cfb35..68ce1e1d6 100644 --- a/src/mkroom.c +++ b/src/mkroom.c @@ -595,7 +595,7 @@ shrine_pos(int roomno) buf.y++; /* irregular room or the location is blocked */ - if (roomno != levl[buf.x][buf.y].roomno + if (roomno != (int) levl[buf.x][buf.y].roomno || (levl[buf.x][buf.y].typ != ROOM && levl[buf.x][buf.y].typ != ICE && levl[buf.x][buf.y].typ != CLOUD)) From d78a87511095b1636754788fbe0a46ec43eb19a5 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 16 May 2026 12:15:20 -0400 Subject: [PATCH 319/702] more Windows curses size tinkering --- include/extern.h | 8 ++++---- sys/windows/consoletty.c | 4 ++-- sys/windows/windsys.c | 12 ------------ win/curses/cursinit.c | 38 ++++++++++++-------------------------- win/win32/mhmain.c | 13 +++++++++++++ 5 files changed, 31 insertions(+), 44 deletions(-) diff --git a/include/extern.h b/include/extern.h index 64026008e..92a38c0ff 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2033,8 +2033,8 @@ extern int win32_cr_gettrace(int, char *, int); extern int *win32_cr_shellexecute(const char *); # endif #ifdef MSWIN_GRAPHICS -extern int get_approx_window_column_width(void); -extern int get_approx_window_rows(void); +extern int get_approx_display_width(void); +extern int get_approx_display_rows(void); #endif #endif /* WIN32 */ @@ -2185,8 +2185,8 @@ void console_g_putch(int in_ch); extern void set_output_mode(int); extern void synch_cursor(void); extern void nethack_enter_consoletty(void); -extern int get_console_width(void); -extern int get_console_height(void); +extern int get_approx_display_cols(void); +extern int get_approx_display_rows(void); extern void console_exit(void); extern int set_keyhandling_via_option(void); #ifdef ENHANCED_SYMBOLS diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index 2fac8b212..c44c95232 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -2644,13 +2644,13 @@ void nethack_enter_consoletty(void) } int -get_console_width(void) +get_approx_display_cols(void) { return console.width; } int -get_console_height(void) +get_approx_display_rows(void) { return console.height; } diff --git a/sys/windows/windsys.c b/sys/windows/windsys.c index 40c788a0d..91dc8eb40 100644 --- a/sys/windows/windsys.c +++ b/sys/windows/windsys.c @@ -1252,18 +1252,6 @@ error: } #undef win32err -#ifdef MSWIN_GRAPHICS -int -get_approx_window_column_width(void) -{ - return GetSystemMetrics(SM_CXSCREEN) / 8; -} -int -get_approx_window_rows(void) -{ - return GetSystemMetrics(SM_CYSCREEN) / 12; -} -#endif #include #define MAX_SYM_SIZE 100 diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index dd733a156..c53edd981 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -762,40 +762,26 @@ curses_init_options(void) size in the config file, we will set it to a nice big 32x110 to take advantage of some of the nice features of this windowport. */ if (iflags.wc2_term_cols == 0) { -#ifndef MSWIN_GRAPHICS - int console_width = get_console_width(); + int display_width = get_approx_display_cols(); - if (console_width != 0) - iflags.wc2_term_cols = console_width; + if (display_width > 220) + display_width = 220; + + if (display_width != 0) + iflags.wc2_term_cols = display_width; else iflags.wc2_term_cols = 110; -#else - int width = get_approx_window_column_width(); - - if (width > 220) - width = 220; - - if (width != 0) - iflags.wc2_term_cols = width; - else - iflags.wc2_term_cols = 110; -#endif } if (iflags.wc2_term_rows == 0) { -#ifndef MSWIN_GRAPHICS - int console_height = get_console_height(); + int display_height = get_approx_display_rows(); - if (console_height != 0) - iflags.wc2_term_rows = console_height; + if (display_height > 64) + display_height = 64; + + if (display_height != 0) + iflags.wc2_term_rows = display_height; else iflags.wc2_term_rows = 32; -#else - int scrows = get_approx_window_rows(); - - if (scrows > 54) - scrows = 54; - iflags.wc2_term_rows = scrows ? scrows : 32; -#endif } resize_term(iflags.wc2_term_rows, iflags.wc2_term_cols); getmaxyx(base_term, term_rows, term_cols); diff --git a/win/win32/mhmain.c b/win/win32/mhmain.c index bd3ffda5a..d543def7b 100644 --- a/win/win32/mhmain.c +++ b/win/win32/mhmain.c @@ -1361,6 +1361,19 @@ nh_compose_ascii_screenshot(void) return retval; } +int +get_approx_display_cols(void) +{ + return GetSystemMetrics(SM_CXSCREEN) / 8; +} + +int +get_approx_display_rows(void) +{ + return GetSystemMetrics(SM_CYSCREEN) / 12; +} + + #ifdef ENHANCED_SYMBOLS // returns malloc() created pointer - callee assumes the ownership static WCHAR * From 083e55e905699d8a73aa2b77b22b4030b6e8bd01 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 16 May 2026 12:22:03 -0400 Subject: [PATCH 320/702] Windows curses-related follow-up --- include/extern.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/include/extern.h b/include/extern.h index 92a38c0ff..f633348ed 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2032,10 +2032,6 @@ extern int win32_cr_helper(char, struct CRctxt *, void *, int); extern int win32_cr_gettrace(int, char *, int); extern int *win32_cr_shellexecute(const char *); # endif -#ifdef MSWIN_GRAPHICS -extern int get_approx_display_width(void); -extern int get_approx_display_rows(void); -#endif #endif /* WIN32 */ #endif /* MICRO || WIN32 */ @@ -2172,7 +2168,7 @@ extern void tutorial(boolean); #if !defined(MAKEDEFS_C) && !defined(MDLIB_C) && !defined(CPPREGEX_C) -/* ### consoletty.c ### */ +/* ### consoletty.c ### */ #ifdef WIN32 extern void get_scr_size(void); @@ -2185,6 +2181,7 @@ void console_g_putch(int in_ch); extern void set_output_mode(int); extern void synch_cursor(void); extern void nethack_enter_consoletty(void); +/* body in consoletty.c and mhmain.c */ extern int get_approx_display_cols(void); extern int get_approx_display_rows(void); extern void console_exit(void); From 476d0717a7d2bf3b1889228bd7893a312927d87f Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 16 May 2026 21:02:38 -0400 Subject: [PATCH 321/702] CI NetHack version --- azure-pipelines.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7c7eea340..c2ac01944 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -100,7 +100,7 @@ steps: echo "CXX: $CXX" displayName: 'Echoing variables' -- checkout: git://NetHack/NetHack@NetHack-3.7 +- checkout: git://NetHack/NetHack@NetHack-5.0 submodules: true path: $(netHackPath) # $(Agent.BuildDirectory)/$(netHackPath) @@ -179,7 +179,7 @@ steps: - bash: | cd sys/unix - sh setup.sh hints/linux.370 + sh setup.sh hints/linux.500 cd ../.. make fetch-lua make WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc all @@ -221,7 +221,7 @@ steps: - bash: | brew install groff cd sys/unix - sh setup.sh hints/macos.370 + sh setup.sh hints/macos.500 cd ../.. make fetch-lua make WANT_MACSOUND=1 all @@ -234,7 +234,7 @@ steps: export GCCVER=gcc1220 export IN_CI=SKIP_FONTS_IN_CI=1 cd sys/unix - sh setup.sh hints/linux.370 + sh setup.sh hints/linux.500 cd ../.. make fetch-lua sys/msdos/fetch-cross-compiler.sh From 51011e234d7036b70aa0ed0752756c91f7dc41b1 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 16 May 2026 21:41:05 -0400 Subject: [PATCH 322/702] build fix attempt for msdos cross-compile Recent change was #ifdef PDCURSES, but that is also used on msdos and other platforms --- win/curses/cursinit.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index c53edd981..efbc93950 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -761,6 +761,7 @@ curses_init_options(void) terminal size programmatically. If the user does not specify a size in the config file, we will set it to a nice big 32x110 to take advantage of some of the nice features of this windowport. */ +#if defined(WIN32) if (iflags.wc2_term_cols == 0) { int display_width = get_approx_display_cols(); @@ -783,6 +784,13 @@ curses_init_options(void) else iflags.wc2_term_rows = 32; } +#else + /* FIXME: should these be higher; is there a way to detect max there? */ + if (iflags.wc2_term_cols == 0) + iflags.wc2_term_cols = 80; + if (iflags.wc2_term_rows == 0) + iflags.wc2_term_rows = 25; +#endif resize_term(iflags.wc2_term_rows, iflags.wc2_term_cols); getmaxyx(base_term, term_rows, term_cols); From 125800404b129a07532828ad0bec0859fed22957 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 16 May 2026 21:45:30 -0400 Subject: [PATCH 323/702] fixes5-0-1.txt catch-up --- doc/fixes5-0-1.txt | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 9742f9b0f..dbbae2adc 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -91,6 +91,14 @@ Amiga: fix latent issue found in code review: (1L << i) for i==31 (or Amiga: fix latent issue found in code review: Drop unused cnt= from amii_display_nhwindow's DoMenuScroll call; the menu return value is consumed elsewhere, not here +curses on Windows: the number of columns was being capped by default + at 110 in cursinit.c; try to use the console width if no explicit + setting was specified in the config file; impacted both wincon + and wingui curses +curses on Windows: some early data is alloc'd for the windows console + settings in both tty and curses (pdcursesmod) prior to the + window port initialization, but only tty was freeing it; call + console_exit() in nethack_exit if window port is curses gcc-16: tiletext.c [-Wdiscarded-qualifiers] warning suppression libnh: update get_nhuuid() for libnhmain libnh: sys/libnh/libnhmain.c: drop `static` on `whoami()` @@ -111,6 +119,8 @@ libnh: sys/unix/hints/macOS.500 in the WANT_LIBNH block, add an explicit no longer triggers `lua_support`, so include/nhlua.h never gets generated and recover.c's transitive #include of hack.h fails macOS: fix ncurses build with Homebrew +musl: musl libc does not have __sighandler_t so don't use it in the + macro definition for SIG_RET_TYPE with musl WASM: resolve some build failures in 'make CROSS_TO_WASM=1' WASM: hints file cross-pre2.500 update to CFLAGS to include -DNHUUID Windows: don't demand keypress on intentional exit @@ -134,6 +144,7 @@ NetHack Community Patches (or Variation) Included ------------------------------------------------- NCURSES_CFLAGS was being ignored when using hints/linux.500 with only WANT_WIN_TTY=1 and not WANT_WIN_CURSES=1 (pr #1522 by torakoya) +added a hints file netbsd.500 for NetBSD (pr #1519 by SirWumpus) Code Cleanup and Reorganization @@ -160,5 +171,7 @@ Amiga: remove miscellaneous unused code like TTY/BBS support, commented Amiga: make INTUI_NEW_LOOK unconditional Amiga: drop SHAREDLIB dead build flavor Amiga: make amigapkg depend on $(GAMEBIN) - - +unix hints: consolidate all the bsd flavours into a single sys/unix/bsd.500 + hints file to ease maintenance going forward; use bsd make + conditional logic to carry out steps unique to NetBSD, OpenBSD, + FreeBSD, GhostBSD From 8ce430bd89bdd44dd065e9b56cd85d20affea4ef Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 16 May 2026 22:13:40 -0400 Subject: [PATCH 324/702] put the values on other pdcurses platforms back They were set this way on other pdcurses platforms prior to this recent change, so leave them at those values. --- win/curses/cursinit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index efbc93950..9fcc1d962 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -787,9 +787,9 @@ curses_init_options(void) #else /* FIXME: should these be higher; is there a way to detect max there? */ if (iflags.wc2_term_cols == 0) - iflags.wc2_term_cols = 80; + iflags.wc2_term_cols = 110; if (iflags.wc2_term_rows == 0) - iflags.wc2_term_rows = 25; + iflags.wc2_term_rows = 32; #endif resize_term(iflags.wc2_term_rows, iflags.wc2_term_cols); getmaxyx(base_term, term_rows, term_cols); From 85ca1cce7469fc315ec095da6f2b0ed0c38faca7 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 17 May 2026 20:38:10 -0400 Subject: [PATCH 325/702] add #-EARLY section --- sys/unix/hints/linux.500 | 16 ++++++++++------ sys/unix/hints/macOS.500 | 26 +++++++++++++++++++------- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index d4b095e25..ea2517248 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -5,22 +5,26 @@ #--------------------------------------------------------------------- # Linux hints file with support for multiple window ports (interfaces) # Tested on: -# - Ubuntu focal +# - Ubuntu resolute raccoon # # If this doesn't work for your distribution, consider making a new # hints file for it, rather than changing this one. # And let us know about it. # +#-EARLY -#-PRE -# linux.500 hints file provides a single-user build for Linux (such -# as Ubuntu focal). +TARGETPFX= +HINTSVERSION := 500 -# note: '#-INCLUDE' is not just a comment +# note: '#-INCLUDE' is not just a comment, it inserts a +# file from sys/unix/hints/include. # multiw-1.500 contains sections 1 to 2 #-INCLUDE multiw-1.500 -HINTSVERSION := 500 +# sys/unix/Makefile.header will get inserted right here, +# ahead of the PRE section. + +#-PRE ifdef MAKEFILE_TOP ifeq ($(MAKELEVEL),0) diff --git a/sys/unix/hints/macOS.500 b/sys/unix/hints/macOS.500 index 93af6954d..fdefb69d5 100755 --- a/sys/unix/hints/macOS.500 +++ b/sys/unix/hints/macOS.500 @@ -5,23 +5,35 @@ #--------------------------------------------------------------------- # MacOS hints file with support for multiple window ports (interfaces) # Tested on: -# - MacOS Catalina 10.15 -# - MacOS Ventura 13 (Intel processor) +# - MacOS Catalina 10.15 (Intel processor) +# - MacOS Tahoe 26.5 (Intel processor) +# - MacOS Tahoe 26.5 (M ARM64 processor) # # If this doesn't work for some other version of macOS, consider # making a new hints file it, rather than changing this one. # And let us know about it. # Useful info: http://www.opensource.apple.com/darwinsource/index.html +# +#-EARLY + +TARGETPFX= +HINTSVERSION := 500 + +# note: '#-INCLUDE' is not just a comment, it inserts a +# file from sys/unix/hints/include. +# multiw-1.500 contains sections 1 to 2 +#-INCLUDE multiw-1.500 + +# sys/unix/Makefile.header will get inserted right here, +# ahead of the PRE section. + +#-PRE + #-PRE xxxx # macOS hints file # -# note: '#-INCLUDE' is not just a comment; multiw-1 contains sections 1 to 2 -#-INCLUDE multiw-1.500 - -HINTSVERSION := 500 - ifdef MAKEFILE_TOP ifeq ($(MAKELEVEL),0) PRECHECK+=checkmakefiles From d9bc6d7b8a44d6474943699df5a421df336cac4f Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 17 May 2026 20:54:08 -0400 Subject: [PATCH 326/702] Revert "add #-EARLY section" This reverts commit 85ca1cce7469fc315ec095da6f2b0ed0c38faca7. --- sys/unix/hints/linux.500 | 16 ++++++---------- sys/unix/hints/macOS.500 | 26 +++++++------------------- 2 files changed, 13 insertions(+), 29 deletions(-) diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index ea2517248..d4b095e25 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -5,26 +5,22 @@ #--------------------------------------------------------------------- # Linux hints file with support for multiple window ports (interfaces) # Tested on: -# - Ubuntu resolute raccoon +# - Ubuntu focal # # If this doesn't work for your distribution, consider making a new # hints file for it, rather than changing this one. # And let us know about it. # -#-EARLY -TARGETPFX= -HINTSVERSION := 500 +#-PRE +# linux.500 hints file provides a single-user build for Linux (such +# as Ubuntu focal). -# note: '#-INCLUDE' is not just a comment, it inserts a -# file from sys/unix/hints/include. +# note: '#-INCLUDE' is not just a comment # multiw-1.500 contains sections 1 to 2 #-INCLUDE multiw-1.500 -# sys/unix/Makefile.header will get inserted right here, -# ahead of the PRE section. - -#-PRE +HINTSVERSION := 500 ifdef MAKEFILE_TOP ifeq ($(MAKELEVEL),0) diff --git a/sys/unix/hints/macOS.500 b/sys/unix/hints/macOS.500 index fdefb69d5..93af6954d 100755 --- a/sys/unix/hints/macOS.500 +++ b/sys/unix/hints/macOS.500 @@ -5,35 +5,23 @@ #--------------------------------------------------------------------- # MacOS hints file with support for multiple window ports (interfaces) # Tested on: -# - MacOS Catalina 10.15 (Intel processor) -# - MacOS Tahoe 26.5 (Intel processor) -# - MacOS Tahoe 26.5 (M ARM64 processor) +# - MacOS Catalina 10.15 +# - MacOS Ventura 13 (Intel processor) # # If this doesn't work for some other version of macOS, consider # making a new hints file it, rather than changing this one. # And let us know about it. # Useful info: http://www.opensource.apple.com/darwinsource/index.html -# -#-EARLY - -TARGETPFX= -HINTSVERSION := 500 - -# note: '#-INCLUDE' is not just a comment, it inserts a -# file from sys/unix/hints/include. -# multiw-1.500 contains sections 1 to 2 -#-INCLUDE multiw-1.500 - -# sys/unix/Makefile.header will get inserted right here, -# ahead of the PRE section. - -#-PRE - #-PRE xxxx # macOS hints file # +# note: '#-INCLUDE' is not just a comment; multiw-1 contains sections 1 to 2 +#-INCLUDE multiw-1.500 + +HINTSVERSION := 500 + ifdef MAKEFILE_TOP ifeq ($(MAKELEVEL),0) PRECHECK+=checkmakefiles From 29951cccd12d9139685ade7a9a1163d9f44d1a03 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 18 May 2026 13:03:31 -0400 Subject: [PATCH 327/702] add support for optional builder-created make.prefs Set things up so that the Makefile build will look for 'make.prefs' at the top of the NetHack source tree. If 'make.prefs' is present, the Makefile build will include it just ahead of the PRE section of a hints file specified to sys/unix/setup.sh, or practically the first thing during a Makefile build if no hints file was specified. The advantage of using a 'make.prefs' is that instead of putting a series of Makefile variable value assignments on the command line each time, like this: make WANT_WIN_X11=1 WANT_WIN_TTY=1 WANT_WIN_CURSES=1 c2x=1 resp=1 update you can, instead, put those preferences into make.prefs, like this: # start of make.prefs WANT_WIN_X11=1 WANT_WIN_TTY=1 WANT_WIN_CURSES=1 c2x=1 resp=1 # end of make.prefs Now, my make command just needs to specify a target: make update The syntax for checking whether make.prefs exists, and for including it, is GNU make, or bsd make, specific, so sys/unix/mkmkfile.sh will insert the correct syntax for the make that is in-use when sys/unix/setup.sh is executed. The 'make.prefs' file isn't limited to Makefile variable assignments, and can contain any valid make syntax for the version of make on your system, but adding make syntax beyond Makefile variable assignment will cause your make.prefs file to become specific to that version of make. There are syntactical differences between GNU make and bsd make, particularly for directives and conditional tests. The 'make.prefs' file can potentially eliminate much/all of the manual editing of distributed repository Makefiles or hints files that you, as a NetHack developer or builder, might routinely carry out. You have the option of placing your preference changes in 'make.prefs' instead. Related reference for .500 hints file variables: In the NetHack source tree: sys/unix/README.hints On GitHub: https://github.com/NetHack/NetHack/blob/NetHack-5.0/sys/unix/README-hints For example, on macOS, where GNU make is being used, and I typically set things up using the macOS.500 hints file: sys/unix/setup.sh sys/unix/hints/macOS.500 I might have the following make.prefs in the root of my NetHack source tree: #---- snip ------- $(info Attention - Using make.prefs) WANT_MACSOUND=1 resp=1 #---- end-snip --- For another example, on Linux, where GNU make is being used, and I typically set things up using the linux.500 hints file: sys/unix/setup.sh sys/unix/hints/linux.500 I might have the following make.prefs file in the root of my NetHack source tree: #---- snip ------- $(info Using make.prefs) WANT_WIN_X11=1 WANT_WIN_TTY=1 WANT_WIN_CURSES=1 c2x=1 resp=1 #---- end-snip --- --- .gitignore | 1 + sys/unix/Makefile.src | 188 ++++++++++++++-------------- sys/unix/Makefile.utl | 3 +- sys/unix/hints/include/multiw-2.500 | 3 - sys/unix/hints/linux.500 | 3 +- sys/unix/hints/macOS.500 | 2 +- sys/unix/mkmkfile.sh | 32 +++++ sys/unix/setup.sh | 17 ++- 8 files changed, 145 insertions(+), 104 deletions(-) diff --git a/.gitignore b/.gitignore index 5615fe332..ab0e33e93 100644 --- a/.gitignore +++ b/.gitignore @@ -49,6 +49,7 @@ Makefile.gcc Makefile-orig Makefile.bcc-orig Makefile.gcc-orig +make.prefs *.suo *.pdb *.ilk diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 519894b13..9d7a82e29 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -4,7 +4,8 @@ # NetHack may be freely redistributed. See license for details. # Root of source tree: -NHSROOT=.. +NHSROOT ?=.. +SRCDIR = $(NHSROOT)/src # newer makes predefine $(MAKE) to 'make' and do smarter processing of # recursive make calls if $(MAKE) is used @@ -41,37 +42,37 @@ SHELL=/bin/sh # SHELL=E:/GEMINI2/MUPFEL.TTP # Usually, the C compiler driver is used for linking: -#LINK=$(CC) +#LINK ?=$(CC) # If we're cross-compiling, a hints file will override this # to a unique target directory, but otherwise it just goes in # ../src -TARGETPFX= +TARGETPFX ?= # Pick the SYSSRC and SYSOBJ lines corresponding to your desired operating # system. # # for UNIX systems -SYSSRC = ../sys/share/ioctl.c ../sys/share/unixtty.c ../sys/unix/unixmain.c \ +SYSSRC ?= ../sys/share/ioctl.c ../sys/share/unixtty.c ../sys/unix/unixmain.c \ ../sys/unix/unixunix.c ../sys/unix/unixres.c -SYSOBJ = $(TARGETPFX)ioctl.o $(TARGETPFX)unixmain.o $(TARGETPFX)unixtty.o \ +SYSOBJ ?= $(TARGETPFX)ioctl.o $(TARGETPFX)unixmain.o $(TARGETPFX)unixtty.o \ $(TARGETPFX)unixunix.o $(TARGETPFX)unixres.o # # for Systos -# SYSSRC = ../sys/atari/tos.c ../sys/share/pcmain.c ../sys/share/pcsys.c \ +# SYSSRC ?= ../sys/atari/tos.c ../sys/share/pcmain.c ../sys/share/pcsys.c \ # ../sys/share/pctty.c ../sys/share/pcunix.c -# SYSOBJ = $(TARGETPFX)tos.o $(TARGETPFX)pcmain.o $(TARGETPFX)pcsys.o \ +# SYSOBJ ?= $(TARGETPFX)tos.o $(TARGETPFX)pcmain.o $(TARGETPFX)pcsys.o \ # $(TARGETPFX)pctty.o $(TARGETPFX)pcunix.o # # for BeOS -#SYSSRC = ../sys/be/bemain.c ../sys/share/unixtty.c ../sys/share/ioctl.c -#SYSOBJ = $(TARGETPFX)bemain.o $(TARGETPFX)unixtty.o $(TARGETPFX)ioctl.o +#SYSSRC ?= ../sys/be/bemain.c ../sys/share/unixtty.c ../sys/share/ioctl.c +#SYSOBJ ?= $(TARGETPFX)bemain.o $(TARGETPFX)unixtty.o $(TARGETPFX)ioctl.o # NetHack 5.0 began introducing C99 code. # # If your compiler needs an appropriate switch to accept C99 code. -# CSTD = -std=c99 +# CSTD ?= -std=c99 # if you are using gcc as your compiler: # uncomment the CC definition below if it's not in your environment @@ -192,8 +193,8 @@ SYSOBJ = $(TARGETPFX)ioctl.o $(TARGETPFX)unixmain.o $(TARGETPFX)unixtty.o \ CFLAGS ?= -I../include LINK ?= $(CC) -AR = ar -ARFLAGS = rcs +AR ?= ar +ARFLAGS ?= rcs # The Qt and Be window systems are written in C++, while the rest of # NetHack is standard C. If using Qt, uncomment the LINK line here to get @@ -210,15 +211,15 @@ MOCPATH ?= $(QTDIR)/bin/$(MOC) # The default is for the TARGET_* variables to match the defaults. # If we're cross-compiling these will get overridden elsewhere, likely via # a hints file. TARGETPFX was set above earlier. -TARGET_CC = $(CC) -TARGET_CFLAGS = $(CFLAGS) $(CSTD) -TARGET_LINK = $(LINK) -TARGET_LFLAGS = $(LFLAGS) -TARGET_CXX = $(CXX) -TARGET_CXXFLAGS = $(CXXFLAGS) -TARGET_LIBS = $(LIBS) -TARGET_AR = $(AR) -TARGET_ARFLAGS = $(ARFLAGS) +TARGET_CC ?= $(CC) +TARGET_CFLAGS ?= $(CFLAGS) $(CSTD) +TARGET_LINK ?= $(LINK) +TARGET_LFLAGS ?= $(LFLAGS) +TARGET_CXX ?= $(CXX) +TARGET_CXXFLAGS ?= $(CXXFLAGS) +TARGET_LIBS ?= $(LIBS) +TARGET_AR ?= $(AR) +TARGET_ARFLAGS ?= $(ARFLAGS) # we specify C preprocessor flags via CFLAGS; files built with default rules # might include $(CPPFLAGS) which could get a value from user's environment; @@ -227,42 +228,38 @@ CPPFLAGS = # file for regular expression matching REGEXOBJ ?= $(TARGETPFX)posixregex.o -#REGEXOBJ = $(TARGETPFX)pmatchregex.o -#REGEXOBJ = $(TARGETPFX)cppregex.o +#REGEXOBJ ?= $(TARGETPFX)pmatchregex.o +#REGEXOBJ ?= $(TARGETPFX)cppregex.o -TILECFILE ?= tile.c -TILEOFILE ?= +GENTILECFILE = tile.c +GENTILEOFILE = $(TARGETPFX)tile.o # Set the WINSRC, WINOBJ, and WINLIB lines to correspond to your desired # combination of windowing systems. Also set matching USE_x_GRAPHICS in -# config.h. Note that if you are building for any window system which -# uses tiles, uncomment '#$(TARGETPFX)tile.o' (by removing the '#') in that -# system's WINxOBJ (WINX11OBJ or WINQTOBJ or WINQT3OBJ). If you are building -# nethack with support for multiple window systems, only uncomment that for -# one of them to avoid duplicate tile.o. +# config.h. # # files for a straight tty port using no native windowing system -WINTTYSRC = ../win/tty/getline.c ../win/tty/termcap.c ../win/tty/topl.c \ +WINTTYSRC ?= ../win/tty/getline.c ../win/tty/termcap.c ../win/tty/topl.c \ ../win/tty/wintty.c -WINTTYOBJ = $(TARGETPFX)getline.o $(TARGETPFX)termcap.o $(TARGETPFX)topl.o \ +WINTTYOBJ ?= $(TARGETPFX)getline.o $(TARGETPFX)termcap.o $(TARGETPFX)topl.o \ $(TARGETPFX)wintty.o # # Files for curses interface -WINCURSESSRC = ../win/curses/cursmain.c ../win/curses/curswins.c \ +WINCURSESSRC ?= ../win/curses/cursmain.c ../win/curses/curswins.c \ ../win/curses/cursmisc.c ../win/curses/cursdial.c \ ../win/curses/cursstat.c ../win/curses/cursinit.c \ ../win/curses/cursmesg.c ../win/curses/cursinvt.c -WINCURSESOBJ = $(TARGETPFX)cursmain.o $(TARGETPFX)curswins.o \ +WINCURSESOBJ ?= $(TARGETPFX)cursmain.o $(TARGETPFX)curswins.o \ $(TARGETPFX)cursmisc.o $(TARGETPFX)cursdial.o \ $(TARGETPFX)cursstat.o $(TARGETPFX)cursinit.o \ $(TARGETPFX)cursmesg.o $(TARGETPFX)cursinvt.o # # files for an X11 port # (tile.c is a generated source file) -WINX11SRC = ../win/X11/Window.c ../win/X11/dialogs.c ../win/X11/winX.c \ +WINX11SRC ?= ../win/X11/Window.c ../win/X11/dialogs.c ../win/X11/winX.c \ ../win/X11/winmap.c ../win/X11/winmenu.c ../win/X11/winmesg.c \ ../win/X11/winmisc.c ../win/X11/winstat.c ../win/X11/wintext.c \ - ../win/X11/winval.c tile.c + ../win/X11/winval.c $(GENTILECFILE) WINX11OBJ ?= $(TARGETPFX)Window.o $(TARGETPFX)dialogs.o $(TARGETPFX)winX.o \ $(TARGETPFX)winmap.o $(TARGETPFX)winmenu.o $(TARGETPFX)winmesg.o \ $(TARGETPFX)winmisc.o $(TARGETPFX)winstat.o $(TARGETPFX)wintext.o \ @@ -273,7 +270,7 @@ WINX11OBJ ?= $(TARGETPFX)Window.o $(TARGETPFX)dialogs.o $(TARGETPFX)winX.o \ #WINQT3SRC = ../win/Qt3/qt3_win.cpp ../win/Qt3/qt3_clust.cpp \ # ../win/Qt3/qt3tableview.cpp #WINQT3OBJ = $(TARGETPFX)qt3_win.o $(TARGETPFX)qt3_clust.o \ -# $(TARGETPFX)qt3tableview.o #$(TARGETPFX)tile.o +# $(TARGETPFX)qt3tableview.o $(GENTILEOFILE) # empty values for 'make depend' WINQT3SRC = WINQT3OBJ = @@ -283,9 +280,9 @@ WINQT3OBJ = # # generated source files made by Qt's 'moc' program from ../win/Qt/qt_*.h; # appended to WINQTSRC for use by 'make depend' -WINQTMOC = qt_kde0.moc qt_main.moc qt_map.moc qt_menu.moc qt_msg.moc \ +WINQTMOC ?= qt_kde0.moc qt_main.moc qt_map.moc qt_menu.moc qt_msg.moc \ qt_plsel.moc qt_set.moc qt_stat.moc qt_xcmd.moc qt_yndlg.moc -WINQTSRC = ../win/Qt/qt_bind.cpp ../win/Qt/qt_click.cpp \ +WINQTSRC ?= ../win/Qt/qt_bind.cpp ../win/Qt/qt_click.cpp \ ../win/Qt/qt_clust.cpp ../win/Qt/qt_delay.cpp \ ../win/Qt/qt_glyph.cpp ../win/Qt/qt_icon.cpp ../win/Qt/qt_inv.cpp \ ../win/Qt/qt_key.cpp ../win/Qt/qt_line.cpp ../win/Qt/qt_main.cpp \ @@ -293,7 +290,7 @@ WINQTSRC = ../win/Qt/qt_bind.cpp ../win/Qt/qt_click.cpp \ ../win/Qt/qt_plsel.cpp ../win/Qt/qt_rip.cpp ../win/Qt/qt_set.cpp \ ../win/Qt/qt_stat.cpp ../win/Qt/qt_str.cpp ../win/Qt/qt_streq.cpp \ ../win/Qt/qt_svsel.cpp ../win/Qt/qt_win.cpp ../win/Qt/qt_xcmd.cpp \ - ../win/Qt/qt_yndlg.cpp $(WINQTMOC) tile.c + ../win/Qt/qt_yndlg.cpp $(WINQTMOC) $(GENTILECFILE) WINQTOBJ ?= $(TARGETPFX)qt_bind.o $(TARGETPFX)qt_click.o \ $(TARGETPFX)qt_clust.o $(TARGETPFX)qt_delay.o \ $(TARGETPFX)qt_glyph.o $(TARGETPFX)qt_icon.o \ @@ -302,23 +299,22 @@ WINQTOBJ ?= $(TARGETPFX)qt_bind.o $(TARGETPFX)qt_click.o \ $(TARGETPFX)qt_msg.o $(TARGETPFX)qt_plsel.o $(TARGETPFX)qt_rip.o \ $(TARGETPFX)qt_set.o $(TARGETPFX)qt_stat.o $(TARGETPFX)qt_str.o \ $(TARGETPFX)qt_streq.o $(TARGETPFX)qt_svsel.o $(TARGETPFX)qt_win.o \ - $(TARGETPFX)qt_xcmd.o $(TARGETPFX)qt_yndlg.o #$(TARGETPFX)tile.o + $(TARGETPFX)qt_xcmd.o $(TARGETPFX)qt_yndlg.o $(GENTILEOFILE) # Files for Shim windowing interface for libnh -- doesn't do anything, # just passes along the API calls to the library # -WINSHIMSRC = ../win/shim/winshim.c -WINSHIMOBJ = winshim.o +WINSHIMSRC ?= ../win/shim/winshim.c +WINSHIMOBJ ?= winshim.o # # Files for a BeOS InterfaceKit port -- not ready for prime time -WINBESRC = -WINBEOBJ = +WINBESRC ?= +WINBEOBJ ?= #WINBESRC = ../win/BeOS/winbe.cpp ../win/BeOS/NHWindow.cpp \ -# ../win/BeOS/NHMenuWindow.cpp ../win/BeOS/NHMapWindow.cpp tile.c +# ../win/BeOS/NHMenuWindow.cpp ../win/BeOS/NHMapWindow.cpp $(GENTILECFILE) #WINBEOBJ = $(TARGETPFX)winbe.o $(TARGETPFX)NHWindow.o \ -# $(TARGETPFX)NHMenuWindow.o $(TARGETPFX)NHMapWindow.o \ -# $(TARGETPFX)tile.o +# $(TARGETPFX)NHMenuWindow.o $(TARGETPFX)NHMapWindow.o $(GENTILEOFILE) # # #WINSRC = $(WINTTYSRC) @@ -356,16 +352,16 @@ WINBEOBJ = WINQT3LIB = -L$(QTDIR)/lib -lqt # # libraries for Qt 4 -WINQT4LIB = `pkg-config QtGui --libs` +WINQT4LIB ?= `pkg-config QtGui --libs` # # libraries for Qt 5 (use with WINQTSRC and WINQTOBJ) -WINQT5LIB = `pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --libs` +WINQT5LIB ?= `pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --libs` # # libraries for KDE (with Qt) -WINKDELIB = -lkdecore -lkdeui -lXext +WINKDELIB ?= -lkdecore -lkdeui -lXext # # libraries for BeOS -WINBELIB = -lbe +WINBELIB ?= -lbe # # libraries for curses port # link with ncurses @@ -418,14 +414,14 @@ WINOBJ ?= $(WINTTYOBJ) WINLIB ?= $(WINTTYLIB) -lncurses # make NetHack -GAME = nethack +GAME ?= nethack # GAME = nethack.prg -GAMEBIN = $(GAME) +GAMEBIN ?= $(GAME) # if you defined RANDOM in unixconf.h since your system did not come # with a reasonable random number generator # RANDOBJ = $(TARGETPFX)random.o -RANDOBJ = +RANDOBJ ?= # used by `make depend' to reconstruct this Makefile; you shouldn't need this # at all but can override with 'make AWK=nawk' or 'make AWK=gawk' if necessary @@ -494,22 +490,22 @@ AT = $(AT_V$(QUIETCC)) # verbosity-adjacent; these will already have 'real' values if hints have # set up cross-compiling, in which case these assignments will be no-ops -PREGAME=@true -PACKAGE=@true +PREGAME ?=@true +PACKAGE ?=@true -HACKLIBSRC = hacklib.c -HACKLIBOBJS = hacklib.o -HACKLIB = hacklib.a -TARGET_HACKLIB = $(TARGETPFX)hacklib.a +HACKLIBSRC ?= hacklib.c +HACKLIBOBJS ?= hacklib.o +HACKLIB ?= hacklib.a +TARGET_HACKLIB ?= $(TARGETPFX)hacklib.a -MAKEDEFS = ../util/makedefs +MAKEDEFS ?= ../util/makedefs # -lm required by lua LUA_VERSION ?=5.4.8 -LUABASE = liblua-$(LUA_VERSION).a -LUALIB = ../lib/lua/$(LUABASE) -LUALIBS = $(LUALIB) -lm $(DLLIB) -LUAHEADERS = lib/lua-$(LUA_VERSION)/src +LUABASE ?= liblua-$(LUA_VERSION).a +LUALIB ?= ../lib/lua/$(LUABASE) +LUALIBS ?= $(LUALIB) -lm $(DLLIB) +LUAHEADERS ?= lib/lua-$(LUA_VERSION)/src # timestamp files to reduce `make' overhead and shorten .o dependency lists CONFIG_H = ../src/config.h-t @@ -517,7 +513,7 @@ HACK_H = ../src/hack.h-t # all .c that are part of the main NetHack program and are not operating- or # windowing-system specific. Do not include date.c in this list. -HACKCSRC = allmain.c alloc.c apply.c artifact.c attrib.c ball.c bones.c \ +HACKCSRC ?= allmain.c alloc.c apply.c artifact.c attrib.c ball.c bones.c \ botl.c calendar.c cmd.c coloratt.c dbridge.c decl.c detect.c dig.c display.c \ dlb.c do.c do_name.c do_wear.c dog.c dogmove.c dokick.c dothrow.c \ drawing.c dungeon.c earlyarg.c eat.c end.c engrave.c exper.c explode.c \ @@ -537,40 +533,40 @@ HACKCSRC = allmain.c alloc.c apply.c artifact.c attrib.c ball.c bones.c \ windows.c wizard.c wizcmds.c worm.c worn.c write.c zap.c # all operating-system-dependent .c (for dependencies and such) -SYSCSRC = ../sys/share/pcmain.c ../sys/share/pcsys.c \ +SYSCSRC ?= ../sys/share/pcmain.c ../sys/share/pcsys.c \ ../sys/share/pctty.c ../sys/share/pcunix.c \ ../sys/share/pmatchregex.c ../sys/share/posixregex.c \ ../sys/share/random.c \ ../sys/share/ioctl.c ../sys/share/unixtty.c ../sys/unix/unixmain.c \ ../sys/unix/unixunix.c ../sys/unix/unixres.c -SYSCXXSRC = ../sys/share/cppregex.cpp +SYSCXXSRC ?= ../sys/share/cppregex.cpp # generated source files (tile.c is handled separately via WINxxxSRC) -GENCSRC = #tile.c +GENCSRC ?= #tile.c # all windowing-system-dependent .c (for dependencies and such) -WINCSRC = $(WINTTYSRC) $(WINCURSESSRC) $(WINX11SRC) $(WINSHIMSRC) +WINCSRC ?= $(WINTTYSRC) $(WINCURSESSRC) $(WINX11SRC) $(WINSHIMSRC) # all windowing-system-dependent .cpp (for dependencies and such) -WINCXXSRC = $(WINQTSRC) $(WINQT3SRC) $(WINBESRC) +WINCXXSRC ?= $(WINQTSRC) $(WINQT3SRC) $(WINBESRC) # Files for window system chaining. Requires SYSCF; include via HINTSRC/HINTOBJ -CHAINSRC = ../win/chain/wc_chainin.c ../win/chain/wc_chainout.c \ +CHAINSRC ?= ../win/chain/wc_chainin.c ../win/chain/wc_chainout.c \ ../win/chain/wc_trace.c -CHAINOBJ = $(TARGETPFX)wc_chainin.o $(TARGETPFX)wc_chainout.o \ +CHAINOBJ ?= $(TARGETPFX)wc_chainin.o $(TARGETPFX)wc_chainout.o \ $(TARGETPFX)wc_trace.o # .c files for this version (for date.h) -VERSOURCES = $(HACKCSRC) $(HACKLIBSRC) $(SYSSRC) $(WINSRC) $(CHAINSRC) $(GENCSRC) +VERSOURCES ?= $(HACKCSRC) $(HACKLIBSRC) $(SYSSRC) $(WINSRC) $(CHAINSRC) $(GENCSRC) # .c files for all versions using this Makefile (for lint and tags) -CSOURCES = $(HACKCSRC) $(HACKLIBSRC) $(SYSCSRC) $(WINCSRC) $(CHAINSRC) $(GENCSRC) +CSOURCES ?= $(HACKCSRC) $(HACKLIBSRC) $(SYSCSRC) $(WINCSRC) $(CHAINSRC) $(GENCSRC) # all .h files except date.h, which would # cause dependency loops if run through "make depend" # and dgn_file.h, special level & dungeon files. # -HACKINCL = align.h artifact.h artilist.h attrib.h botl.h \ +HACKINCL ?= align.h artifact.h artilist.h attrib.h botl.h \ color.h config.h config1.h context.h coord.h cstd.h decl.h \ defsym.h display.h dlb.h dungeon.h engrave.h extern.h flag.h \ fnamesiz.h func_tab.h global.h warnings.h hack.h lint.h mextra.h \ @@ -583,16 +579,16 @@ HACKINCL = align.h artifact.h artilist.h attrib.h botl.h \ wintty.h wincurs.h winX.h winprocs.h wintype.h you.h youprop.h \ weight.h -HSOURCES = $(HACKINCL) dgn_file.h +HSOURCES ?= $(HACKINCL) dgn_file.h # the following .o's _must_ be made before any others (for makedefs) -FIRSTOBJ = monst.o objects.o -HOSTOBJ = $(FIRSTOBJ) alloc.o drawing.o +FIRSTOBJ ?= monst.o objects.o +HOSTOBJ ?= $(FIRSTOBJ) alloc.o drawing.o # # $(TARGETPFX)date.o is not included in this list # -HOBJ = $(TARGETPFX)allmain.o $(TARGETPFX)alloc.o \ +HOBJ ?= $(TARGETPFX)allmain.o $(TARGETPFX)alloc.o \ $(TARGETPFX)apply.o $(TARGETPFX)artifact.o $(TARGETPFX)attrib.o \ $(TARGETPFX)ball.o $(TARGETPFX)bones.o $(TARGETPFX)botl.o \ $(TARGETPFX)calendar.o $(TARGETPFX)cfgfiles.o $(TARGETPFX)cmd.o \ @@ -636,10 +632,10 @@ HOBJ = $(TARGETPFX)allmain.o $(TARGETPFX)alloc.o \ $(TARGETPFX)wizcmds.o $(TARGETPFX)worm.o $(TARGETPFX)worn.o \ $(TARGETPFX)write.o $(TARGETPFX)zap.o \ $(REGEXOBJ) $(RANDOBJ) $(SYSOBJ) $(WINOBJ) \ - $(HINTOBJ) $(SNDLIBOBJ) $(UUIDOBJ) \ + $(HINTOBJ) $(SNDLIBOBJ) $(UUIDOBJ) $(GENTILEOFILE) \ $(TARGETPFX)version.o -DATE_O = $(TARGETPFX)date.o +DATE_O ?= $(TARGETPFX)date.o # the .o files from the HACKCSRC, SYSSRC, and WINSRC lists @@ -657,42 +653,48 @@ pregame: $(RESPONSEFILES) $(GAME): pregame $(MAKEDEFS) $(LUALIB) $(WAVS) $(SYSTEM) @echo "$(GAME) is up to date." -Sysunix: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(DATE_O) $(BUILDMORE) Makefile +Sysunix: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(GENTILEOFILE) \ + $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ $(HOBJ) $(DATE_O) $(TARGET_HACKLIB) $(WINLIB) \ $(TARGET_LIBS) $(LUALIBS) $(AUTOLIBS) @touch Sysunix -Sys3B2: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(DATE_O) $(BUILDMORE) Makefile +Sys3B2: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(GENTILEOFILE) \ + $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ $(HOBJ) $(DATE_O) $(TARGET_HACKLIB) $(WINLIB) \ $(LUALIBS) -lmalloc @touch Sys3B2 -Sysatt: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(DATE_O) $(BUILDMORE) Makefile +Sysatt: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(GENTILEOFILE) \ + $(DATE_O) $(BUILDMORE) Makefile @echo "Loading $(GAME)." $(AT)$(LD) $(TARGET_LFLAGS) /lib/crt0s.o /lib/shlib.ifile \ -o $(GAMEBIN) $(HOSTOBJ) $(HOBJ) $(DATE_O) $(TARGET_HACKLIB) \ $(LUALIBS) @touch Sysatt -Systos: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(DATE_O) $(BUILDMORE) Makefile +Systos: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(GENTILEOFILE) \ + $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ $(HOBJ) $(DATE_O) $(TARGET_HACKLIB) \ $(WINLIB) $(LUALIBS) @touch Systos -SysV-AT: DUMB.Setup $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(DATE_O) $(BUILDMORE) Makefile +SysV-AT: DUMB.Setup $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(GENTILEOFILE) \ + $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ $(HOBJ) $(DATE_O) $(TARGET_HACKLIB) \ $(WINLIB) $(LUALIBS) @touch SysV-AT -SysBe: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(DATE_O) $(BUILDMORE) Makefile +SysBe: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(GENTILEOFILE) \ + $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAME) \ $(HOBJ) $(DATE_O) $(TARGET_HACKLIB) \ @@ -766,7 +768,7 @@ $(MAKEDEFS): $(FIRSTOBJ) \ # Created at build time for configurations which support tiles, # but not by makedefs so not connected to the others. tile.c: ../win/share/tilemap.c $(HACK_H) - @( cd ../util ; $(MAKE) ../src/tile.c ) + @( cd ../util ; $(MAKE) $(SRCDIR)/tile.c ) # # hacklib (a library of utility routines) @@ -824,7 +826,7 @@ spotless: clean -rm -f ../include/nhlua.h -rm -f ../include/date.h #created but no longer used, at least by core -rm -f ../include/onames.h ../include/pm.h #obsolete generated files - -rm -f tile.c *.moc Qt*.h-t + -rm -f $(GENTILECFILE) *.moc Qt*.h-t -rm -f ../win/gnome/gn_rip.h package: @@ -856,7 +858,7 @@ updatedepend-setup: echo '#include "../$(LUAHEADERS)/lualib.h"' >> $$HFILE && \ echo '#include "../$(LUAHEADERS)/lauxlib.h"' >> $$HFILE && \ echo '/*nhlua.h*/' >> $$HFILE ) - @echo "Generating bogus src/tile.c" + @echo "Generating bogus $(GENTILECFILE)" @echo '#error bogus include/nhlua.h' > ../../src/tile.c @echo "#include \"hack.h\"" >> ../../src/tile.c @@ -881,7 +883,7 @@ depend2: $(WINQTMOC) @echo '# see make depend above' >> $(MAKEFILE_NAME) - diff Makefile.bak $(MAKEFILE_NAME) @rm -f Makefile.bak - @rm -f ../include/nhlua.h tile.c + @rm -f ../include/nhlua.h $(GENTILECFILE) # DO NOT DELETE THIS LINE OR CHANGE ANYTHING BEYOND IT diff --git a/sys/unix/Makefile.utl b/sys/unix/Makefile.utl index 4e6091550..d169fa5aa 100644 --- a/sys/unix/Makefile.utl +++ b/sys/unix/Makefile.utl @@ -10,6 +10,7 @@ # Root of source tree: NHSROOT=.. +SRCDIR = $(NHSROOT)/src # newer makes predefine $(MAKE) to 'make' and do smarter processing of # recursive make calls if $(MAKE) is used @@ -517,7 +518,7 @@ tilemap: tilemap.o $(OBJDIR)/objects.o $(OBJDIR)/monst.o $(OBJDIR)/drawing.o \ $(CLINK) $(LFLAGS) -o tilemap tilemap.o $(OBJDIR)/objects.o \ $(OBJDIR)/monst.o $(OBJDIR)/drawing.o $(HACKLIB) \ $(LIBS) -../src/tile.c: tilemap +$(SRCDIR)/tile.c: tilemap ./tilemap tiletext.o: ../win/share/tiletext.c $(CONFIG_H) ../win/share/tile.h diff --git a/sys/unix/hints/include/multiw-2.500 b/sys/unix/hints/include/multiw-2.500 index 01f1fb6c1..b25225a66 100644 --- a/sys/unix/hints/include/multiw-2.500 +++ b/sys/unix/hints/include/multiw-2.500 @@ -80,7 +80,6 @@ WINSRC = WINOBJ0 = SND_CFLAGS= XTRASRC = -XTRAOBJ = ifdef WANT_WIN_TTY WINSRC += $(WINTTYSRC) @@ -105,7 +104,6 @@ WINCFLAGS += -DX11_GRAPHICS WINSRC += $(WIINX11SRC) WINOBJ0 += $(WINX11OBJ) XTRASRC += tile.c -XTRAOBJ += $(TARGETPFX)tile.o endif ifndef WANT_WIN_QT @@ -157,7 +155,6 @@ HAVE_SNDLIB = 1 NEEDS_SND_USERSOUNDS = 1 NEEDS_SND_SEAUTOMAP = 1 XTRASRC += tile.c -XTRAOBJ += $(TARGETPFX)tile.o # ifndef CPLUSPLUS_NEEDED CPLUSPLUS_NEEDED = 1 diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index d4b095e25..4fb8b453f 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -275,6 +275,7 @@ ifdef WANT_WIN_X11 USE_XPM=1 WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm +GENTILEOFILE = $(SRCDIR)/tile.o # -x: if built without dlb, some versions of mkfontdir think *.lev are fonts POSTINSTALL += bdftopcf win/X11/nh10.bdf > $(HACKDIR)/nh10.pcf; ( cd $(HACKDIR); mkfontdir -x .lev ); # separate from CFLAGS so that we don't pass it to every file @@ -365,7 +366,7 @@ LINK = $(CC) endif # !WANT_WIN_QT # prevent duplicate tile.o in WINOBJ -WINOBJ = $(WINOBJ0) $(sort $(XTRAOBJ)) +WINOBJ = $(WINOBJ0) # prevent duplicates in VARDATND if both X11 and Qt are being supported VARDATND += $(sort $(VARDATND0)) diff --git a/sys/unix/hints/macOS.500 b/sys/unix/hints/macOS.500 index 93af6954d..ebf78788a 100755 --- a/sys/unix/hints/macOS.500 +++ b/sys/unix/hints/macOS.500 @@ -314,7 +314,7 @@ LINK=$(CC) endif # !WANT_WIN_QT # prevent duplicate tile.o in WINOBJ -WINOBJ = $(WINOBJ0) $(sort $(XTRAOBJ)) +WINOBJ = $(WINOBJ0) # prevent duplicates in VARDATND if both X11 and Qt are being supported VARDATND += $(sort $(VARDATND0)) diff --git a/sys/unix/mkmkfile.sh b/sys/unix/mkmkfile.sh index 01cdb9b72..82e8b91d0 100755 --- a/sys/unix/mkmkfile.sh +++ b/sys/unix/mkmkfile.sh @@ -10,6 +10,7 @@ # $3 install path # $4 hints file (path) # $5 hints file (as given by user) +# $6 gnu or bsd echo "#" > $3 echo "# This file is generated automatically. Do not edit." >> $3 @@ -20,6 +21,37 @@ echo "" >> $3 echo "HINTSFILE=$5" >> $3 echo "" >> $3 +echo "###" >> $3 +echo "### add check for builder include file $6-style" >> $3 +echo "###" >> $3 +echo "" >> $3 +BUILDERINCL=make.prefs +echo "" >> $3 +case "$6" in + "gnu") + echo "ifdef MAKEFILE_TOP" >> $3 + echo "NHSROOT=." >> $3 + echo "else" >> $3 + echo "NHSROOT=.." >> $3 + echo "endif" >> $3 + echo "ifneq (\"\$(wildcard \$(NHSROOT)/$BUILDERINCL))\",\"\")" >> $3 + echo "-include \$(NHSROOT)/$BUILDERINCL" >> $3 + echo "endif" >> $3 + ;; + "bsd") + echo ".ifdef MAKEFILE_TOP" >> $3 + echo "NHSROOT=." >> $3 + echo ".else" >> $3 + echo "NHSROOT=.." >> $3 + echo ".endif" >> $3 + echo ".if exists(\$(NHSROOT)/$BUILDERINCL)" >> $3 + echo ".include \"\$(NHSROOT)/$BUILDERINCL\"" >> $3 + echo ".endif" >> $3 + ;; + *) +esac +echo "" >> $3 + echo "###" >> $3 echo "### Start $5 PRE" >> $3 echo "###" >> $3 diff --git a/sys/unix/setup.sh b/sys/unix/setup.sh index 7f5b504e1..6731a12d2 100755 --- a/sys/unix/setup.sh +++ b/sys/unix/setup.sh @@ -31,8 +31,15 @@ x) hints=/dev/null ;; esac -/bin/sh ./mkmkfile.sh Makefile.top TOP ../../Makefile $hints $hfile -/bin/sh ./mkmkfile.sh Makefile.dat DAT ../../dat/Makefile $hints $hfile -/bin/sh ./mkmkfile.sh Makefile.doc DOC ../../doc/Makefile $hints $hfile -/bin/sh ./mkmkfile.sh Makefile.src SRC ../../src/Makefile $hints $hfile -/bin/sh ./mkmkfile.sh Makefile.utl UTL ../../util/Makefile $hints $hfile +# is make gnu or bsd? +if make --version 2>/dev/null | grep -q "GNU"; then + whichmake=gnu +else + whichmake=bsd +fi + +/bin/sh ./mkmkfile.sh Makefile.top TOP ../../Makefile $hints $hfile $whichmake +/bin/sh ./mkmkfile.sh Makefile.dat DAT ../../dat/Makefile $hints $hfile $whichmake +/bin/sh ./mkmkfile.sh Makefile.doc DOC ../../doc/Makefile $hints $hfile $whichmake +/bin/sh ./mkmkfile.sh Makefile.src SRC ../../src/Makefile $hints $hfile $whichmake +/bin/sh ./mkmkfile.sh Makefile.utl UTL ../../util/Makefile $hints $hfile $whichmake From 3a892160df634648430e72ef6e033abd0c5be1d0 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 18 May 2026 13:07:13 -0400 Subject: [PATCH 328/702] macOS follow-up --- sys/unix/hints/macOS.500 | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/unix/hints/macOS.500 b/sys/unix/hints/macOS.500 index ebf78788a..a5cc6e82e 100755 --- a/sys/unix/hints/macOS.500 +++ b/sys/unix/hints/macOS.500 @@ -271,6 +271,7 @@ ifdef WANT_WIN_X11 USE_XPM=1 WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm +GENTILEOFILE = $(SRCDIR)/tile.o # -x: if built without dodlb, some versions of mkfontdir think *.lev are fonts POSTINSTALL += bdftopcf win/X11/nh10.bdf > $(HACKDIR)/nh10.pcf; ( cd $(HACKDIR); mkfontdir -x .lev ); # separate from CFLAGS so that we don't pass it to every file From 0607d6426cf80be100a934bfd2dd86ded32ae181 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 18 May 2026 13:53:02 -0400 Subject: [PATCH 329/702] follow-up --- sys/unix/hints/include/multiw-2.500 | 5 ++--- sys/unix/hints/linux.500 | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/sys/unix/hints/include/multiw-2.500 b/sys/unix/hints/include/multiw-2.500 index b25225a66..75657d5e9 100644 --- a/sys/unix/hints/include/multiw-2.500 +++ b/sys/unix/hints/include/multiw-2.500 @@ -79,7 +79,6 @@ WINCFLAGS= WINSRC = WINOBJ0 = SND_CFLAGS= -XTRASRC = ifdef WANT_WIN_TTY WINSRC += $(WINTTYSRC) @@ -103,7 +102,7 @@ ifdef WANT_WIN_X11 WINCFLAGS += -DX11_GRAPHICS WINSRC += $(WIINX11SRC) WINOBJ0 += $(WINX11OBJ) -XTRASRC += tile.c +GENTILECFILE = $(SRCDIR)/tile.c endif ifndef WANT_WIN_QT @@ -154,7 +153,7 @@ endif #! WANT_WIN_QT4 HAVE_SNDLIB = 1 NEEDS_SND_USERSOUNDS = 1 NEEDS_SND_SEAUTOMAP = 1 -XTRASRC += tile.c +GENTILECFILE = $(SRCDIR)/tile.c # ifndef CPLUSPLUS_NEEDED CPLUSPLUS_NEEDED = 1 diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index 4fb8b453f..8a309bfe3 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -473,7 +473,7 @@ LFLAGS+=-rdynamic # if TTY_TILES_ESCCODES #WINSRC += tile.c -#WINOBJ += tile.o +#GENTILEOFILE = $(SRCDIR)/tile.o # endif CHOWN=true From 95151d99fcb5f5493ee9d6c300d66f8f9cd9f289 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 18 May 2026 14:18:24 -0400 Subject: [PATCH 330/702] more follow-up CI still had a duplicate tile.o --- sys/unix/Makefile.src | 22 +++++++++++----------- sys/unix/Makefile.utl | 2 +- sys/unix/hints/include/cross-pre2.500 | 2 +- sys/unix/hints/macOS.500 | 1 - 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 9d7a82e29..c72ca9e71 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -231,8 +231,8 @@ REGEXOBJ ?= $(TARGETPFX)posixregex.o #REGEXOBJ ?= $(TARGETPFX)pmatchregex.o #REGEXOBJ ?= $(TARGETPFX)cppregex.o -GENTILECFILE = tile.c -GENTILEOFILE = $(TARGETPFX)tile.o +GENTILECFILE = $(SRCDIR)/tile.c +GENTILEOFILE ?= # Set the WINSRC, WINOBJ, and WINLIB lines to correspond to your desired # combination of windowing systems. Also set matching USE_x_GRAPHICS in @@ -270,7 +270,7 @@ WINX11OBJ ?= $(TARGETPFX)Window.o $(TARGETPFX)dialogs.o $(TARGETPFX)winX.o \ #WINQT3SRC = ../win/Qt3/qt3_win.cpp ../win/Qt3/qt3_clust.cpp \ # ../win/Qt3/qt3tableview.cpp #WINQT3OBJ = $(TARGETPFX)qt3_win.o $(TARGETPFX)qt3_clust.o \ -# $(TARGETPFX)qt3tableview.o $(GENTILEOFILE) +# $(TARGETPFX)qt3tableview.o # empty values for 'make depend' WINQT3SRC = WINQT3OBJ = @@ -299,7 +299,7 @@ WINQTOBJ ?= $(TARGETPFX)qt_bind.o $(TARGETPFX)qt_click.o \ $(TARGETPFX)qt_msg.o $(TARGETPFX)qt_plsel.o $(TARGETPFX)qt_rip.o \ $(TARGETPFX)qt_set.o $(TARGETPFX)qt_stat.o $(TARGETPFX)qt_str.o \ $(TARGETPFX)qt_streq.o $(TARGETPFX)qt_svsel.o $(TARGETPFX)qt_win.o \ - $(TARGETPFX)qt_xcmd.o $(TARGETPFX)qt_yndlg.o $(GENTILEOFILE) + $(TARGETPFX)qt_xcmd.o $(TARGETPFX)qt_yndlg.o # Files for Shim windowing interface for libnh -- doesn't do anything, # just passes along the API calls to the library @@ -314,7 +314,7 @@ WINBEOBJ ?= #WINBESRC = ../win/BeOS/winbe.cpp ../win/BeOS/NHWindow.cpp \ # ../win/BeOS/NHMenuWindow.cpp ../win/BeOS/NHMapWindow.cpp $(GENTILECFILE) #WINBEOBJ = $(TARGETPFX)winbe.o $(TARGETPFX)NHWindow.o \ -# $(TARGETPFX)NHMenuWindow.o $(TARGETPFX)NHMapWindow.o $(GENTILEOFILE) +# $(TARGETPFX)NHMenuWindow.o $(TARGETPFX)NHMapWindow.o # # #WINSRC = $(WINTTYSRC) @@ -541,9 +541,6 @@ SYSCSRC ?= ../sys/share/pcmain.c ../sys/share/pcsys.c \ ../sys/unix/unixunix.c ../sys/unix/unixres.c SYSCXXSRC ?= ../sys/share/cppregex.cpp -# generated source files (tile.c is handled separately via WINxxxSRC) -GENCSRC ?= #tile.c - # all windowing-system-dependent .c (for dependencies and such) WINCSRC ?= $(WINTTYSRC) $(WINCURSESSRC) $(WINX11SRC) $(WINSHIMSRC) # all windowing-system-dependent .cpp (for dependencies and such) @@ -585,6 +582,9 @@ HSOURCES ?= $(HACKINCL) dgn_file.h FIRSTOBJ ?= monst.o objects.o HOSTOBJ ?= $(FIRSTOBJ) alloc.o drawing.o +$(info WINOBJ=$(WINOBJ)) +$(info GENTILEOFILE=$(GENTILEOFILE)) + # # $(TARGETPFX)date.o is not included in this list # @@ -767,8 +767,8 @@ $(MAKEDEFS): $(FIRSTOBJ) \ @( cd ../util ; $(MAKE) ../include/pm.h ) # Created at build time for configurations which support tiles, # but not by makedefs so not connected to the others. -tile.c: ../win/share/tilemap.c $(HACK_H) - @( cd ../util ; $(MAKE) $(SRCDIR)/tile.c ) +../src/tile.c: ../win/share/tilemap.c $(HACK_H) + @( cd ../util ; $(MAKE) ../src/tile.c ) # # hacklib (a library of utility routines) @@ -1272,7 +1272,7 @@ $(TARGETPFX)strutil.o: strutil.c $(HACK_H) $(TARGETPFX)symbols.o: symbols.c $(HACK_H) ../include/tcap.h $(TARGETPFX)sys.o: sys.c $(HACK_H) $(TARGETPFX)teleport.o: teleport.c $(HACK_H) -$(TARGETPFX)tile.o: tile.c $(HACK_H) +$(TARGETPFX)tile.o: $(SRCDIR)/tile.c $(HACK_H) $(TARGETPFX)timeout.o: timeout.c $(HACK_H) $(TARGETPFX)topten.o: topten.c $(HACK_H) ../include/dlb.h $(TARGETPFX)track.o: track.c $(HACK_H) diff --git a/sys/unix/Makefile.utl b/sys/unix/Makefile.utl index d169fa5aa..89fc4899b 100644 --- a/sys/unix/Makefile.utl +++ b/sys/unix/Makefile.utl @@ -518,7 +518,7 @@ tilemap: tilemap.o $(OBJDIR)/objects.o $(OBJDIR)/monst.o $(OBJDIR)/drawing.o \ $(CLINK) $(LFLAGS) -o tilemap tilemap.o $(OBJDIR)/objects.o \ $(OBJDIR)/monst.o $(OBJDIR)/drawing.o $(HACKLIB) \ $(LIBS) -$(SRCDIR)/tile.c: tilemap +../src/tile.c: tilemap ./tilemap tiletext.o: ../win/share/tiletext.c $(CONFIG_H) ../win/share/tile.h diff --git a/sys/unix/hints/include/cross-pre2.500 b/sys/unix/hints/include/cross-pre2.500 index 44dafac51..297b17175 100644 --- a/sys/unix/hints/include/cross-pre2.500 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -225,7 +225,7 @@ override SYSOBJ= $(TARGETPFX)pcmain.o $(TARGETPFX)msdos.o \ $(TARGETPFX)vidvga.o $(TARGETPFX)vidvesa.o \ $(TARGETPFX)font.o \ $(TARGETPFX)bmptiles.o $(TARGETPFX)giftiles.o \ - $(TARGETPFX)tileset.o $(TARGETPFX)tile.o + $(TARGETPFX)tileset.o $(GENTILEOFILE) override WINLIB= override LUALIB= override LUALIBS= diff --git a/sys/unix/hints/macOS.500 b/sys/unix/hints/macOS.500 index a5cc6e82e..5ac7e171c 100755 --- a/sys/unix/hints/macOS.500 +++ b/sys/unix/hints/macOS.500 @@ -314,7 +314,6 @@ else # !WANT_WIN_QT LINK=$(CC) endif # !WANT_WIN_QT -# prevent duplicate tile.o in WINOBJ WINOBJ = $(WINOBJ0) # prevent duplicates in VARDATND if both X11 and Qt are being supported VARDATND += $(sort $(VARDATND0)) From 9841830460a4bd8ae6f390e65cd858b5a232dc9f Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 18 May 2026 15:46:54 -0400 Subject: [PATCH 331/702] some more follow-up CROSS_TO_MSDOS build --- sys/unix/Makefile.src | 6 +++--- sys/unix/hints/include/cross-post.500 | 8 +++++++- sys/unix/hints/include/cross-pre2.500 | 11 +++++++++-- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index c72ca9e71..74d3307f6 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -263,7 +263,7 @@ WINX11SRC ?= ../win/X11/Window.c ../win/X11/dialogs.c ../win/X11/winX.c \ WINX11OBJ ?= $(TARGETPFX)Window.o $(TARGETPFX)dialogs.o $(TARGETPFX)winX.o \ $(TARGETPFX)winmap.o $(TARGETPFX)winmenu.o $(TARGETPFX)winmesg.o \ $(TARGETPFX)winmisc.o $(TARGETPFX)winstat.o $(TARGETPFX)wintext.o \ - $(TARGETPFX)winval.o $(TILEOFILE) + $(TARGETPFX)winval.o # # Files for a Qt 3 interface (renamed since nethack 3.6.x) # @@ -553,10 +553,10 @@ CHAINOBJ ?= $(TARGETPFX)wc_chainin.o $(TARGETPFX)wc_chainout.o \ $(TARGETPFX)wc_trace.o # .c files for this version (for date.h) -VERSOURCES ?= $(HACKCSRC) $(HACKLIBSRC) $(SYSSRC) $(WINSRC) $(CHAINSRC) $(GENCSRC) +VERSOURCES ?= $(HACKCSRC) $(HACKLIBSRC) $(SYSSRC) $(WINSRC) $(CHAINSRC) $(GENTILECFILE) # .c files for all versions using this Makefile (for lint and tags) -CSOURCES ?= $(HACKCSRC) $(HACKLIBSRC) $(SYSCSRC) $(WINCSRC) $(CHAINSRC) $(GENCSRC) +CSOURCES ?= $(HACKCSRC) $(HACKLIBSRC) $(SYSCSRC) $(WINCSRC) $(CHAINSRC) $(GENTILECFILE) # all .h files except date.h, which would diff --git a/sys/unix/hints/include/cross-post.500 b/sys/unix/hints/include/cross-post.500 index e01623002..d07d14f18 100644 --- a/sys/unix/hints/include/cross-post.500 +++ b/sys/unix/hints/include/cross-post.500 @@ -18,7 +18,9 @@ $(TARGETPFX)vidvesa.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ ../win/share/tile.h ../include/tileset.h ../sys/msdos/font.h $(HACK_H) $(TARGETPFX)vidstub.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ $(HACK_H) -$(TARGETPFX)tile.o : tile.c +$(TARGETPFX)tile.o : $(SRCDIR)/tile.c + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $(SRCDIR)/tile.c +$(SRCDIR)tile.c : tiletext $(TARGETPFX)exceptn.o : ../lib/djgpp/djgpp-patch/src/libc/go32/exceptn.S $(TARGET_CC) -c -o $@ ../lib/djgpp/djgpp-patch/src/libc/go32/exceptn.S $(TARGET_AR) ru ../lib/djgpp/i586-pc-msdosdjgpp/lib/libc.a $(TARGETPFX)exceptn.o @@ -475,7 +477,11 @@ $(TARGETPFX)slk.o : $(PDCTOP)/pdcurses/slk.c $(TARGETPFX)termattr.o : $(PDCTOP)/pdcurses/termattr.c $(TARGETPFX)touch.o : $(PDCTOP)/pdcurses/touch.c $(TARGETPFX)util.o : $(PDCTOP)/pdcurses/util.c +# We need an explicit recipe for the creation of $(TARGETPFX)window.o +# because it will try and use the X11 version of window.c otherwise $(TARGETPFX)window.o : $(PDCTOP)/pdcurses/window.c + $(TARGET_CC) $(PDCINCL) $(PDC_TARGET_CFLAGS) \ + -Wno-sign-compare -o$@ $(PDCTOP)/pdcurses/window.c $(TARGETPFX)debug.o : $(PDCTOP)/pdcurses/debug.c $(TARGETPFX)pdcclip.o : $(PDCPORT)/pdcclip.c $(TARGETPFX)pdcdisp.o : $(PDCPORT)/pdcdisp.c diff --git a/sys/unix/hints/include/cross-pre2.500 b/sys/unix/hints/include/cross-pre2.500 index 297b17175..a7958855a 100644 --- a/sys/unix/hints/include/cross-pre2.500 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -134,6 +134,7 @@ override TARGET_CC = $(TOOLTOP1)/i586-pc-msdosdjgpp-gcc override TARGET_CXX = $(TOOLTOP1)/i586-pc-msdosdjgpp-g++ override TARGET_AR = $(TOOLTOP1)/i586-pc-msdosdjgpp-gcc-ar override TARGET_STUBEDIT = ../lib/djgpp/i586-pc-msdosdjgpp/bin/stubedit +override GENTILEOFILE = $(TARGETPFX)tile.o ifdef MAKEFILE_SRC FLDR=../ endif @@ -176,7 +177,7 @@ MSDOS_GPP_CFLAGS = -Wall -Wextra -Wno-missing-field-initializers -Wreturn-type \ -Wmissing-declarations -Wformat-nonliteral -Wunreachable-code \ -Wno-maybe-uninitialized MSDOS_TARGET_CFLAGS = -c -O $(DBGFLAGS) -I../include -I../sys/msdos -I../win/share \ - $(LUAINCL) -DDLB $(PDCURSESDEF) -DTILES_IN_GLYPHMAP \ + $(LUAINCL) -DDLB $(PDCURSESDEF) -DTILES_IN_GLYPHMAP -DUSE_TILES \ -DCROSSCOMPILE -DCROSSCOMPILE_TARGET -DCROSS_TO_MSDOS \ -D_NAIVE_DOS_REGS \ $(MSDOS_GCC_CFLAGS) $(SNDCFLAGS) @@ -225,11 +226,12 @@ override SYSOBJ= $(TARGETPFX)pcmain.o $(TARGETPFX)msdos.o \ $(TARGETPFX)vidvga.o $(TARGETPFX)vidvesa.o \ $(TARGETPFX)font.o \ $(TARGETPFX)bmptiles.o $(TARGETPFX)giftiles.o \ - $(TARGETPFX)tileset.o $(GENTILEOFILE) + $(TARGETPFX)tileset.o override WINLIB= override LUALIB= override LUALIBS= override TOPLUALIB= +override WINX11OBJ= override GAMEBIN = $(TARGETPFX)nethack.exe override RECOVERBIN = $(TARGETPFX)recover.exe override SFCTOOLBIN = $(TARGETPFX)sfctool.exe @@ -258,6 +260,11 @@ endif # WANT_WIN_CURSES # Rule for files in sys/msdos $(TARGETPFX)%.o : ../sys/msdos/%.c $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< +# +# Rule for files in util +$(TARGETPFX)%.o : ../util/%.c + $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< + endif # CROSS_TO_MSDOS #================================================================= From 68e36aff74c9ceb024ef0d8d5671f92f91050656 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 18 May 2026 16:06:15 -0400 Subject: [PATCH 332/702] CROSS_TO_AMIGA fix --- sys/unix/hints/include/cross-pre2.500 | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/unix/hints/include/cross-pre2.500 b/sys/unix/hints/include/cross-pre2.500 index a7958855a..7dc4d746b 100644 --- a/sys/unix/hints/include/cross-pre2.500 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -509,6 +509,7 @@ override TARGET_CFLAGS = -c -O2 -noixemul $(TOOLARCH) \ -DCROSSCOMPILE -DCROSSCOMPILE_TARGET -DCROSS_TO_AMIGA \ -DAMIGA_VERSION_STRING=\""VER: NetHack 5.0.0"\" override TARGET_CXXFLAGS = $(TARGET_CFLAGS) +override GENTILEOFILE = $(TARGETPFX)tile.o LUA_TARGET_CFLAGS = $(TARGET_CFLAGS) ifeq "$(REGEXOBJ)" "$(TARGETPFX)cppregex.o" override TARGET_LINK = $(TARGET_CXX) From 721dc27f2624121a9df735791c6fc244b9e5c84e Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 18 May 2026 16:09:36 -0400 Subject: [PATCH 333/702] remove an unneeded change from earlier CROSS_TO_MSDOS --- sys/unix/hints/include/cross-pre2.500 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/unix/hints/include/cross-pre2.500 b/sys/unix/hints/include/cross-pre2.500 index 7dc4d746b..a8648aca9 100644 --- a/sys/unix/hints/include/cross-pre2.500 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -177,7 +177,7 @@ MSDOS_GPP_CFLAGS = -Wall -Wextra -Wno-missing-field-initializers -Wreturn-type \ -Wmissing-declarations -Wformat-nonliteral -Wunreachable-code \ -Wno-maybe-uninitialized MSDOS_TARGET_CFLAGS = -c -O $(DBGFLAGS) -I../include -I../sys/msdos -I../win/share \ - $(LUAINCL) -DDLB $(PDCURSESDEF) -DTILES_IN_GLYPHMAP -DUSE_TILES \ + $(LUAINCL) -DDLB $(PDCURSESDEF) -DTILES_IN_GLYPHMAP \ -DCROSSCOMPILE -DCROSSCOMPILE_TARGET -DCROSS_TO_MSDOS \ -D_NAIVE_DOS_REGS \ $(MSDOS_GCC_CFLAGS) $(SNDCFLAGS) From 5333747f02ea125c689f347b4c584b5624ef4b23 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 19 May 2026 00:49:30 -0400 Subject: [PATCH 334/702] Add some support for Alpine Linux system Lua package Requires apk add lua5.4-dev (for the C Lua headers) --- sys/unix/Makefile.src | 4 ++-- sys/unix/Makefile.top | 21 +++++++++++---------- sys/unix/README-hints | 2 ++ sys/unix/hints/linux.500 | 35 +++++++++++++++++++++++++++++++++-- 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 74d3307f6..10e833f61 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -673,8 +673,8 @@ Sysatt: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(GENTILEOFILE) \ $(DATE_O) $(BUILDMORE) Makefile @echo "Loading $(GAME)." $(AT)$(LD) $(TARGET_LFLAGS) /lib/crt0s.o /lib/shlib.ifile \ - -o $(GAMEBIN) $(HOSTOBJ) $(HOBJ) $(DATE_O) $(TARGET_HACKLIB) \ - $(LUALIBS) + -o $(GAMEBIN) $(HOSTOBJ) $(HOBJ) $(DATE_O) \ + $(TARGET_HACKLIB) $(LUALIBS) @touch Sysatt Systos: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(GENTILEOFILE) \ diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 5ecca3232..6641bc116 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -121,13 +121,14 @@ DAT = $(DATNODLB) $(DATDLB) RECOVERBIN = recover # Lua -LUAHEADERS = lib/lua-$(LUA_VERSION)/src -LUATESTTARGET = $(LUAHEADERS)/lua.h -LUATOP = $(LUAHEADERS) -LUAMAKEFLAGS = CC='$(CC)' SYSCFLAGS='$(SYSCFLAGS)' -LUA2NHTOP = ../../.. -LUABASELIB = liblua-$(LUA_VERSION).a -TOPLUALIB = lib/lua/$(LUABASELIB) +LUAHEADERS ?= lib/lua-$(LUA_VERSION)/src +LUATESTTARGET ?= $(LUAHEADERS)/lua.h +LUATOP ?= $(LUAHEADERS) +LUAMAKEFLAGS ?= CC='$(CC)' SYSCFLAGS='$(SYSCFLAGS)' +LUA2NHTOP ?= ../../.. +LUABASELIB ?= liblua-$(LUA_VERSION).a +TOPLUALIB ?= lib/lua/$(LUABASELIB) +LUAHPREFIX ?= ../ ALLDEP = $(PRECHECK) $(GAME) recover Guidebook $(VARDAT) spec_levs check-dlb @@ -149,12 +150,12 @@ $(TOPLUALIB): $(LUATOP)/liblua.a include/nhlua.h: $(TOPLUALIB) echo '/* nhlua.h - generated by top Makefile */' > $@ - @echo '#include "../$(LUAHEADERS)/lua.h"' >> $@ + @echo '#include "$(LUAHPREFIX)$(LUAHEADERS)/lua.h"' >> $@ @sed -e '/(lua_error)/!d' \ -e '/(lua_error)/s/LUA_API/ATTRNORETURN LUA_API/1' \ -e '/(lua_error)/s/;/ NORETURN;/1' < $(LUAHEADERS)/lua.h >> $@ - @echo '#include "../$(LUAHEADERS)/lualib.h"' >> $@ - @echo '#include "../$(LUAHEADERS)/lauxlib.h"' >> $@ + @echo '#include "$(LUAHPREFIX)$(LUAHEADERS)/lualib.h"' >> $@ + @echo '#include "$(LUAHPREFIX)$(LUAHEADERS)/lauxlib.h"' >> $@ @echo '/*nhlua.h*/' >> $@ # LUATESTTARGET is this by default lib/lua-$(LUA_VERSION)/src/lua.h: diff --git a/sys/unix/README-hints b/sys/unix/README-hints index 283d1cf29..196f32734 100644 --- a/sys/unix/README-hints +++ b/sys/unix/README-hints @@ -49,6 +49,8 @@ make musl=1 Build with settings appropriate for linking with musl libc, instead of glibc. This causes NOCRASHREPORT to be defined, and avoids the use of 'col' during the build. +make WANT_SYSTEM_LUA=1 Attempt to use an existing Lua package already + on the system (initially for Alpine Linux). make resp=1 Place the majority of the compiler switches into a response file to de-clutter the build compiler command lines and eliminate some of the diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index 8a309bfe3..d8aebe39e 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -23,6 +23,7 @@ HINTSVERSION := 500 ifdef MAKEFILE_TOP +LUA_VERSION=5.4.8 ifeq ($(MAKELEVEL),0) PRECHECK+=checkmakefiles # all files included from this hints file get listed @@ -67,6 +68,35 @@ USE_NOSTATICFN = 1 #-INCLUDE compiler.500 +ifdef WANT_SYSTEM_LUA +OS_ID := $(shell grep -E '^ID=' /etc/os-release 2>/dev/null | cut -d= -f2) +ifeq ($(OS_ID),alpine) +USE_SYSTEM_LUA=1 +CURSPKG = ncurses +endif # Alpine Linux + +ifeq "$(USE_SYSTEM_LUA)" "1" +#5.4.8 +ifndef LUA_VERSION +LUA_VERSION := 5.4.8 +endif +LUASUBDELIM := $(subst ., ,$(LUA_VERSION)) +LUASHVER := $(word 1, $(LUASUBDELIM)).$(word 2, $(LUASUBDELIM)) +LUAHEADERS := /usr/include/lua$(LUASHVER) +LUATESTTARGET := $(LUAHEADERS)/lua.h +LUAHPREFIX := +LUAFLAGS := $(shell pkg-config --cflags lua-$(LUASHVER)) +LUALIBS := $(shell pkg-config --libs lua-$(LUASHVER)) +CFLAGS += $(LUAFLAGS) +LUATOP= +LUAMAKEFLAGS= +LUA2NHTOP= +LUABASELIB= +TOPLUALIB= +LUALIB= +endif # USE_SYSTEM_LUA +endif # WANT_SYSTEM_LUA + ifdef WANT_WIN_QT ifdef WANT_WIN_QT5 QTDIR=/usr @@ -96,6 +126,7 @@ LFLAGS+=-fsanitize=undefined endif ifeq "$(USE_CURSESLIB)" "1" +CURSPKG ?= ncursesw # default CURSESLIB = -lncurses -ltinfo # If CURSES_UNICODE is defined, we need ncursesw. @@ -103,8 +134,8 @@ CURSESLIB = -lncurses -ltinfo # CURSESLIB = -lncurses -ltinfo ifdef MAKEFILE_SRC comma:=, -NCURSES_LFLAGS = $(shell pkg-config ncursesw --libs) -NCURSES_CFLAGS = $(shell pkg-config ncursesw --cflags) +NCURSES_LFLAGS = $(shell pkg-config $(CURSPKG) --libs) +NCURSES_CFLAGS = $(shell pkg-config $(CURSPKG) --cflags) ifeq (,$(findstring ncursesw, $(NCURSES_LFLAGS))) ifeq (,$(findstring ncurses, $(NCURSES_LFLAGS))) #this indicates that pkg-config itself was unavailable From 46735de8a6f8758c2d4a38705c7a46884ea0617a Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 19 May 2026 11:38:05 -0400 Subject: [PATCH 335/702] extend WANT_SYSTEM_LUA=1 to other distros Only tested on Ubuntu at this point. feedback on other distros is welcome --- sys/unix/Makefile.src | 4 +- sys/unix/Makefile.top | 7 +- sys/unix/hints/include/cross-pre2.500 | 8 +- sys/unix/hints/include/linuxdistro.500 | 25 ++++++ sys/unix/hints/linux.500 | 103 ++++++++++++++++++++++--- 5 files changed, 126 insertions(+), 21 deletions(-) create mode 100644 sys/unix/hints/include/linuxdistro.500 diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 10e833f61..8d1490db4 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -582,8 +582,8 @@ HSOURCES ?= $(HACKINCL) dgn_file.h FIRSTOBJ ?= monst.o objects.o HOSTOBJ ?= $(FIRSTOBJ) alloc.o drawing.o -$(info WINOBJ=$(WINOBJ)) -$(info GENTILEOFILE=$(GENTILEOFILE)) +#$(info WINOBJ=$(WINOBJ)) +#$(info GENTILEOFILE=$(GENTILEOFILE)) # # $(TARGETPFX)date.o is not included in this list diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 6641bc116..d09dd2db0 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -127,8 +127,9 @@ LUATOP ?= $(LUAHEADERS) LUAMAKEFLAGS ?= CC='$(CC)' SYSCFLAGS='$(SYSCFLAGS)' LUA2NHTOP ?= ../../.. LUABASELIB ?= liblua-$(LUA_VERSION).a -TOPLUALIB ?= lib/lua/$(LUABASELIB) +LUATOPLIB ?= lib/lua/$(LUABASELIB) LUAHPREFIX ?= ../ +LUALIBBUILT ?= $(LUATOP)/liblua.a ALLDEP = $(PRECHECK) $(GAME) recover Guidebook $(VARDAT) spec_levs check-dlb @@ -144,11 +145,11 @@ lua_support: include/nhlua.h @true $(LUATOP)/liblua.a: $(LUAHEADERS)/lua.h ( cd $(LUATOP) && make $(LUAMAKEFLAGS) a ) -$(TOPLUALIB): $(LUATOP)/liblua.a +lib/lua/$(LUABASELIB): $(LUALIBBUILT) @( if test -d lib/lua ; then true ; else mkdir -p lib/lua ; fi ) cp $(LUATOP)/liblua.a $@ -include/nhlua.h: $(TOPLUALIB) +include/nhlua.h: $(LUATOPLIB) echo '/* nhlua.h - generated by top Makefile */' > $@ @echo '#include "$(LUAHPREFIX)$(LUAHEADERS)/lua.h"' >> $@ @sed -e '/(lua_error)/!d' \ diff --git a/sys/unix/hints/include/cross-pre2.500 b/sys/unix/hints/include/cross-pre2.500 index a8648aca9..fead0d4e8 100644 --- a/sys/unix/hints/include/cross-pre2.500 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -230,7 +230,7 @@ override SYSOBJ= $(TARGETPFX)pcmain.o $(TARGETPFX)msdos.o \ override WINLIB= override LUALIB= override LUALIBS= -override TOPLUALIB= +override LUATOPLIB= override WINX11OBJ= override GAMEBIN = $(TARGETPFX)nethack.exe override RECOVERBIN = $(TARGETPFX)recover.exe @@ -367,7 +367,7 @@ override SYSOBJ= $(TARGETPFX)libnhmain.o \ $(TARGETPFX)winshim.o override WINLIB = emranlib override LUALIB= -override TOPLUALIB= +override LUATOPLIB= override REGEXOBJ = $(TARGETPFX)posixregex.o override WINOBJ= override UUIDOBJ= @@ -450,7 +450,7 @@ override SYSOBJ = $(TARGETPFX)ioctl.o $(TARGETPFX)unixmain.o $(TARGETPFX)unixtty override WINLIB = $(NCURSESLIB) override LUALIB= override LUALIBS= -override TOPLUALIB= +override LUATOPLIB= override GAMEBIN=$(MIPS_TARGET) override RECOVERBIN = $(TARGETPFX)recover override PACKAGE = mipspkg @@ -543,7 +543,7 @@ override SYSOBJ = $(TARGETPFX)amidos.o \ override WINLIB= override LUALIB= override LUALIBS= -override TOPLUALIB= +override LUATOPLIB= override DLLIB= override WINOBJ= override GAMEBIN = $(TARGETPFX)nethack diff --git a/sys/unix/hints/include/linuxdistro.500 b/sys/unix/hints/include/linuxdistro.500 new file mode 100644 index 000000000..7ff828f1c --- /dev/null +++ b/sys/unix/hints/include/linuxdistro.500 @@ -0,0 +1,25 @@ +# ----- linuxdistro.500 -------- + +LINUX_DISTRO= +OS_ID := $(shell grep -E '^ID=' /etc/os-release 2>/dev/null | cut -d= -f2) +#$(info OS_ID=$(OS_ID)) + +ifeq ($(OS_ID),alpine) +LINUX_DISTRO=alpine +USE_SYSTEM_LUA=1 +CURSPKG = ncurses +endif +ifeq ($(OS_ID),debian) +LINUX_DISTRO=debian +USE_SYSTEM_LUA=1 +endif +ifeq ($(OS_ID),ubuntu) +LINUX_DISTRO=ubuntu +USE_SYSTEM_LUA=1 +endif +ifeq ($(OS_ID),fedora) +LINUX_DISTRO=fedora +USE_SYSTEM_LUA=1 +endif +#$(info LINUX_DIST=$(LINUX_DISTRO)) +# ----- end of linuxdistro.500 -------- diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index d8aebe39e..7df63d93f 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -36,6 +36,9 @@ HINTSINCLFILES := $(addsuffix .$(HINTSVERSION), $(HINTSINCLNAMES)) endif endif +#-INCLUDE linuxdistro.500 + + ifndef LIBXPM LIBXPM= -L/opt/X11/lib -lXpm endif @@ -69,31 +72,107 @@ USE_NOSTATICFN = 1 #-INCLUDE compiler.500 ifdef WANT_SYSTEM_LUA -OS_ID := $(shell grep -E '^ID=' /etc/os-release 2>/dev/null | cut -d= -f2) -ifeq ($(OS_ID),alpine) -USE_SYSTEM_LUA=1 -CURSPKG = ncurses -endif # Alpine Linux - -ifeq "$(USE_SYSTEM_LUA)" "1" -#5.4.8 ifndef LUA_VERSION LUA_VERSION := 5.4.8 endif LUASUBDELIM := $(subst ., ,$(LUA_VERSION)) LUASHVER := $(word 1, $(LUASUBDELIM)).$(word 2, $(LUASUBDELIM)) + +ifeq ($(LINUX_DISTRO),alpine) +# prereq: doas apk add lua5.4-dev +# doas apk add linux-headers +# doas apk add musl-dev +USE_SYSTEM_LUA=1 +SHELLPKG :=pkg-config +LUAPKGNAME = lua-$(LUASHVER) +CURSPKG = ncurses +# +else ifeq ($(LINUX_DISTRO),debian) +# prereq: sudo apt install lua5.4 liblua5.4-dev +USE_SYSTEM_LUA=1 +SHELLPKG :=pkg-config +LUAPKGNAME = lua-$(LUASHVER) +# +else ifeq ($(LINUX_DISTRO),ubuntu) +# prereq: sudo apt install lua5.4 liblua5.4-dev +USE_SYSTEM_LUA=1 +SHELLPKG :=dpkg +LUAPKGNAME = lua$(LUASHVER) +# +else ifeq ($(LINUX_DISTRO),fedora) +# prereq: sudo dnf install lua lua-devel +USE_SYSTEM_LUA=1 +SHELLPKG :=rpm +LUAPKGNAME = lua-devel +# +else +USE_SYSTEM_LUA=0 +SHELLPKG := +endif # LINUX_DISTRO + +ifeq ($(USE_SYSTEM_LUA),1) +ifneq "$(SHELLPKG)" "" +# +# Two requirements must now pass: +# 1. We need to be able to check if Lua package +# is installed. We do that here. +# 2. The lua.h header file needs to be present +# where expected. We set LUATESTTARGET here, +# but the check is done later on in the top +# Makefile. +# +# Try to confirm package presence +ifeq ($(SHELLPKG),pkg-config) +PKG_EXISTS := $(shell pkg-config --exists $(LUAPKGNAME) \ + && echo yes || echo no) +# +else ifeq ($(SHELLPKG),dpkg) +PKG_EXISTS := $(shell dpkg -s $(LUAPKGNAME) > /dev/null 2>&1 \ + && echo yes || echo no) +# +else ifeq ($(SHELLPKG),rpm) +PKG_EXISTS := $(shell rpm -q $(LUAPKGNAME) > /dev/null 2>&1 \ + && echo yes || echo no) +# +else +$(info Section for DEFAULT) +PKG_EXISTS=no +$(info Existance of package $(LUAPKGNAME) could not be verified) +endif + +ifeq ($(PKG_EXISTS),yes) +$(info Existance of package $(LUAPKGNAME) verified) +# +ifeq ($(LINUX_DISTRO),fedora) +LUACFLAGS := $(shell pkg-config --cflags lua-$(LUASHVER)) +LUALIBS := $(shell pkg-config --libs lua-$(LUASHVER)) LUAHEADERS := /usr/include/lua$(LUASHVER) LUATESTTARGET := $(LUAHEADERS)/lua.h -LUAHPREFIX := -LUAFLAGS := $(shell pkg-config --cflags lua-$(LUASHVER)) +# +else ifeq ($(LINUX_DISTRO),ubuntu) +LUACFLAGS := -I/usr/include/lua$(LUASHVER) +LUALIBS := -llua$(LUASHVER) -lm -ldl +LUAHEADERS := /usr/include/lua$(LUASHVER) +LUATESTTARGET := $(LUAHEADERS)/lua.h +# +else ifeq ($(SHELLPKG),pkg-config) +LUACFLAGS := $(shell pkg-config --cflags lua-$(LUASHVER)) LUALIBS := $(shell pkg-config --libs lua-$(LUASHVER)) -CFLAGS += $(LUAFLAGS) +LUAHEADERS := /usr/include/lua$(LUASHVER) +LUATESTTARGET := $(LUAHEADERS)/lua.h +endif +# +LUAHPREFIX= LUATOP= LUAMAKEFLAGS= LUA2NHTOP= LUABASELIB= -TOPLUALIB= +LUATOPLIB= +LUALIBBUILT= LUALIB= +CFLAGS += $(LUACFLAGS) +endif # PKG_EXISTS? +endif # SHELLPKG has a value endif # USE_SYSTEM_LUA endif # WANT_SYSTEM_LUA From 182dd93a3847d9ad8c22e4b1296eeeac48b52d95 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 19 May 2026 11:53:54 -0400 Subject: [PATCH 336/702] remove a debug line --- sys/unix/hints/linux.500 | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index 7df63d93f..cf3c9dac3 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -135,7 +135,6 @@ PKG_EXISTS := $(shell rpm -q $(LUAPKGNAME) > /dev/null 2>&1 \ && echo yes || echo no) # else -$(info Section for DEFAULT) PKG_EXISTS=no $(info Existance of package $(LUAPKGNAME) could not be verified) endif From b17eafa0abc8edc2f16fda4089eeda95edb5424d Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 19 May 2026 12:18:23 -0400 Subject: [PATCH 337/702] CROSS_TO_AMIGA=1 build fix Fallout from other work this past weekend. --- sys/unix/hints/include/cross-post.500 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/unix/hints/include/cross-post.500 b/sys/unix/hints/include/cross-post.500 index d07d14f18..0d90d2a96 100644 --- a/sys/unix/hints/include/cross-post.500 +++ b/sys/unix/hints/include/cross-post.500 @@ -239,7 +239,7 @@ $(TARGETPFX)amistack.o : ../sys/amiga/amistack.c $(HACK_H) $(TARGETPFX)amiwind.o : ../sys/amiga/amiwind.c \ ../sys/amiga/amimenu.c $(HACK_H) $(TARGETPFX)winami.o : ../sys/amiga/winami.c $(HACK_H) -$(TARGETPFX)winchar.o : ../sys/amiga/winchar.c tile.c $(HACK_H) +$(TARGETPFX)winchar.o : ../sys/amiga/winchar.c $(SRCDIR)/tile.c $(HACK_H) $(TARGETPFX)winfuncs.o : ../sys/amiga/winfuncs.c $(HACK_H) $(TARGETPFX)winkey.o : ../sys/amiga/winkey.c $(HACK_H) $(TARGETPFX)winamenu.o : ../sys/amiga/winamenu.c $(HACK_H) From 4c825ed9a97981f38b8fa346642c6dd0d1a0b83e Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 19 May 2026 15:38:37 -0400 Subject: [PATCH 338/702] typo CROSS_TO_MSDOS=1 --- sys/unix/hints/include/cross-post.500 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/unix/hints/include/cross-post.500 b/sys/unix/hints/include/cross-post.500 index 0d90d2a96..a62193a48 100644 --- a/sys/unix/hints/include/cross-post.500 +++ b/sys/unix/hints/include/cross-post.500 @@ -20,7 +20,7 @@ $(TARGETPFX)vidstub.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ $(HACK_H) $(TARGETPFX)tile.o : $(SRCDIR)/tile.c $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $(SRCDIR)/tile.c -$(SRCDIR)tile.c : tiletext +$(SRCDIR)/tile.c : tiletext $(TARGETPFX)exceptn.o : ../lib/djgpp/djgpp-patch/src/libc/go32/exceptn.S $(TARGET_CC) -c -o $@ ../lib/djgpp/djgpp-patch/src/libc/go32/exceptn.S $(TARGET_AR) ru ../lib/djgpp/i586-pc-msdosdjgpp/lib/libc.a $(TARGETPFX)exceptn.o From 1b7e52973201eeaade656634657d3c61fd8aec54 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 20 May 2026 00:37:02 -0400 Subject: [PATCH 339/702] cross-compile and build adjustments Tested: Ubuntu: make WANT_WIN_TTY=1 WANT_WIN_CURSES=1 resp=1 update Ubuntu: make WANT_SYSTEM_LUA=1 WANT_WIN_TTY=1 WANT_WIN_CURSES=1 resp=1 update make CROSS_TO_MSDOS=1 package make CROSS_TO_AMIGA=1 all make CROSS_TO_AMIGA=1 package --- sys/unix/Makefile.src | 42 +++++++++++++++------------ sys/unix/Makefile.top | 4 +-- sys/unix/hints/include/cross-post.500 | 12 +++++--- sys/unix/hints/include/cross-pre2.500 | 8 +++++ sys/unix/hints/linux.500 | 8 ++--- 5 files changed, 45 insertions(+), 29 deletions(-) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 8d1490db4..71d55b3ce 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -553,10 +553,10 @@ CHAINOBJ ?= $(TARGETPFX)wc_chainin.o $(TARGETPFX)wc_chainout.o \ $(TARGETPFX)wc_trace.o # .c files for this version (for date.h) -VERSOURCES ?= $(HACKCSRC) $(HACKLIBSRC) $(SYSSRC) $(WINSRC) $(CHAINSRC) $(GENTILECFILE) +VERSOURCES ?= $(HACKCSRC) $(HACKLIBSRC) $(SYSSRC) $(WINSRC) $(CHAINSRC) # .c files for all versions using this Makefile (for lint and tags) -CSOURCES ?= $(HACKCSRC) $(HACKLIBSRC) $(SYSCSRC) $(WINCSRC) $(CHAINSRC) $(GENTILECFILE) +CSOURCES ?= $(HACKCSRC) $(HACKLIBSRC) $(SYSCSRC) $(WINCSRC) $(CHAINSRC) # all .h files except date.h, which would @@ -632,10 +632,10 @@ HOBJ ?= $(TARGETPFX)allmain.o $(TARGETPFX)alloc.o \ $(TARGETPFX)wizcmds.o $(TARGETPFX)worm.o $(TARGETPFX)worn.o \ $(TARGETPFX)write.o $(TARGETPFX)zap.o \ $(REGEXOBJ) $(RANDOBJ) $(SYSOBJ) $(WINOBJ) \ - $(HINTOBJ) $(SNDLIBOBJ) $(UUIDOBJ) $(GENTILEOFILE) \ + $(HINTOBJ) $(SNDLIBOBJ) $(UUIDOBJ) \ $(TARGETPFX)version.o -DATE_O ?= $(TARGETPFX)date.o +DATE_O = $(TARGETPFX)date.o # the .o files from the HACKCSRC, SYSSRC, and WINSRC lists @@ -653,51 +653,55 @@ pregame: $(RESPONSEFILES) $(GAME): pregame $(MAKEDEFS) $(LUALIB) $(WAVS) $(SYSTEM) @echo "$(GAME) is up to date." -Sysunix: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(GENTILEOFILE) \ +#$(info DATE_O=$(DATE_O)) +#$(info GENTILEOFILE=$(GENTILEOFILE)) + +Sysunix: $(GENTILEOFILE) $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) \ $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ - $(HOBJ) $(DATE_O) $(TARGET_HACKLIB) $(WINLIB) \ + $(HOBJ) $(DATE_O) $(GENTILEOFILE) \ + $(TARGET_HACKLIB) $(WINLIB) \ $(TARGET_LIBS) $(LUALIBS) $(AUTOLIBS) @touch Sysunix -Sys3B2: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(GENTILEOFILE) \ +Sys3B2: $(GENTILEOFILE) $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) \ $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ - $(HOBJ) $(DATE_O) $(TARGET_HACKLIB) $(WINLIB) \ - $(LUALIBS) -lmalloc + $(HOBJ) $(DATE_O) $(GENTILEOFILE) \ + $(TARGET_HACKLIB) $(WINLIB) $(LUALIBS) -lmalloc @touch Sys3B2 -Sysatt: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(GENTILEOFILE) \ +Sysatt: $(GENTILEOFILE) $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) \ $(DATE_O) $(BUILDMORE) Makefile @echo "Loading $(GAME)." $(AT)$(LD) $(TARGET_LFLAGS) /lib/crt0s.o /lib/shlib.ifile \ - -o $(GAMEBIN) $(HOSTOBJ) $(HOBJ) $(DATE_O) \ - $(TARGET_HACKLIB) $(LUALIBS) + -o $(GAMEBIN) $(HOSTOBJ) $(HOBJ) \ + $(DATE_O) $(GENTILEOFILE) $(TARGET_HACKLIB) $(LUALIBS) @touch Sysatt -Systos: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(GENTILEOFILE) \ +Systos: $(GENTILEOFILE) $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) \ $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ - $(HOBJ) $(DATE_O) $(TARGET_HACKLIB) \ + $(HOBJ) $(DATE_O) $(GENTILEOFILE) $(TARGET_HACKLIB) \ $(WINLIB) $(LUALIBS) @touch Systos -SysV-AT: DUMB.Setup $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(GENTILEOFILE) \ +SysV-AT: DUMB.Setup $(GENTILEOFILE) $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) \ $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ - $(HOBJ) $(DATE_O) $(TARGET_HACKLIB) \ + $(HOBJ) $(DATE_O) $(GENTILEOFILE) $(TARGET_HACKLIB) \ $(WINLIB) $(LUALIBS) @touch SysV-AT -SysBe: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(GENTILEOFILE) \ +SysBe: $(GENTILEOFILE) $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) \ $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAME) \ - $(HOBJ) $(DATE_O) $(TARGET_HACKLIB) \ + $(HOBJ) $(DATE_O) $(GENTILEOFILE) $(TARGET_HACKLIB) \ $(WINLIB) $(TARGET_LIBS) $(LUALIBS) @xres -o $(GAME) ../win/BeOS/nethack.rsrc @mimeset -f $(GAME) @@ -785,7 +789,7 @@ $(TARGETPFX)sfbase.o: sfbase.c $(HACK_H) ../include/sfprocs.h ../include/sfmacro # date.c should be recompiled any time any of the source or include code # is modified. DATECFLAGS = $(TARGET_CFLAGS) $(GITHASH) $(GITBRANCH) $(GITPREFIX) -$(TARGETPFX)date.o: date.c $(HACK_H) $(HACKCSRC) $(HOBJ) $(TARGET_HACKLIB) +$(TARGETPFX)date.o: date.c $(GENTILECFILE) $(HACK_H) $(HACKCSRC) $(HOBJ) $(TARGET_HACKLIB) $(TARGET_CC) $(DATECFLAGS) -c -o $@ date.c # date.h should be remade any time any of the source or include code diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index d09dd2db0..80b89870d 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -123,8 +123,8 @@ RECOVERBIN = recover # Lua LUAHEADERS ?= lib/lua-$(LUA_VERSION)/src LUATESTTARGET ?= $(LUAHEADERS)/lua.h -LUATOP ?= $(LUAHEADERS) -LUAMAKEFLAGS ?= CC='$(CC)' SYSCFLAGS='$(SYSCFLAGS)' +LUATOP = $(LUAHEADERS) +LUAMAKEFLAGS = CC='$(CC)' SYSCFLAGS='$(SYSCFLAGS)' LUA2NHTOP ?= ../../.. LUABASELIB ?= liblua-$(LUA_VERSION).a LUATOPLIB ?= lib/lua/$(LUABASELIB) diff --git a/sys/unix/hints/include/cross-post.500 b/sys/unix/hints/include/cross-post.500 index a62193a48..2d6ef3546 100644 --- a/sys/unix/hints/include/cross-post.500 +++ b/sys/unix/hints/include/cross-post.500 @@ -5,6 +5,10 @@ ifdef CROSS_TO_MSDOS # +.PHONY: tilemap +tilemap: ../util/tilemap.o $(SRCDIR)/objects.o $(SRCDIR)/monst.o $(SRCDIR)/drawing.o $(HACKLIB) +../util/tilemap.o : ../win/share/tilemap.c + (cd ../util ; make tilemap.o ; cd ../src ) $(TARGETPFX)msdos.o : ../sys/msdos/msdos.c $(HACK_H) $(TARGETPFX)font.o : ../sys/msdos/font.c ../sys/msdos/font.h $(HACK_H) $(TARGETPFX)pckeys.o : ../sys/msdos/pckeys.c $(HACK_H) @@ -20,13 +24,13 @@ $(TARGETPFX)vidstub.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ $(HACK_H) $(TARGETPFX)tile.o : $(SRCDIR)/tile.c $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $(SRCDIR)/tile.c -$(SRCDIR)/tile.c : tiletext +$(SRCDIR)/tile.c : tilemap $(TARGETPFX)exceptn.o : ../lib/djgpp/djgpp-patch/src/libc/go32/exceptn.S $(TARGET_CC) -c -o $@ ../lib/djgpp/djgpp-patch/src/libc/go32/exceptn.S $(TARGET_AR) ru ../lib/djgpp/i586-pc-msdosdjgpp/lib/libc.a $(TARGETPFX)exceptn.o $(GAMEBIN) : $(HOBJ) $(TARGETPFX)date.o $(TARGET_HACKLIB) $(LUACROSSLIB) $(TARGET_LINK) $(TARGET_LFLAGS) -o $@ \ - $(HOBJ) $(TARGET_HACKLIB) $(WINLIB) $(TARGET_LIBS) + $(HOBJ) $(DATE_O) $(GENTILEOFILE) $(TARGET_HACKLIB) $(WINLIB) $(TARGET_LIBS) $(DOSFONT)/ter-u16b.psf: $(FONTTOP)/ter-u16b.bdf $(DOSFONT)/nh-u16b.bdf $(DOSFONT)/makefont.lua $(LUABIN) $(LUABIN) $(DOSFONT)/makefont.lua $(FONTTOP)/ter-u16b.bdf $(DOSFONT)/nh-u16b.bdf $@ $(DOSFONT)/ter-u16v.psf: $(FONTTOP)/ter-u16v.bdf $(DOSFONT)/nh-u16v.bdf $(DOSFONT)/makefont.lua $(LUABIN) @@ -351,7 +355,7 @@ $(TARGETPFX)hacklib.a: $(TARGETPFX)hacklib.o $(TARGET_AR) $(TARGET_ARFLAGS) $@ $(TARGETPFX)hacklib.o ifdef MAKEFILE_UTL $(TARGETPFX)recover.o: recover.c $(CONFIG_H) - $(TARGET_CC) $(TARGET_CFLAGS) $(CSTD) -c recover.c -o $@ + $(TARGET_CC) $(TARGET_CFLAGS) -c recover.c -o $@ ifdef CROSS_TO_MSDOS $(TARGETPFX)recover.exe : $(TARGETPFX)recover.o $(TARGETPFX)rversion.o $(TARGETPFX)hacklib.a $(TARGET_LINK) $(TARGET_LFLAGS) \ @@ -362,7 +366,7 @@ $(TARGETPFX)recover : $(TARGETPFX)recover.o $(TARGETPFX)rversion.o $(TARGETPFX)h $(TARGETPFX)recover.o $(TARGETPFX)rversion.o $(TARGETPFX)hacklib.a -o $@ endif $(TARGETPFX)rversion.o: ../src/version.c $(HACK_H) - $(TARGET_CC) $(TARGET_CFLAGS) -DMINIMAL_FOR_RECOVER $(CSTD) -c ../src/version.c -o $@ + $(TARGET_CC) $(TARGET_CFLAGS) -DMINIMAL_FOR_RECOVER -c ../src/version.c -o $@ endif # MAKEFILE_UTL endif # CROSS diff --git a/sys/unix/hints/include/cross-pre2.500 b/sys/unix/hints/include/cross-pre2.500 index fead0d4e8..ea5d31767 100644 --- a/sys/unix/hints/include/cross-pre2.500 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -123,6 +123,8 @@ ifdef CROSS_TO_MSDOS #================================================================= CFLAGS += -DCROSSCOMPILE +#also set a make variable flagging this as a crosscompile +CROSSCOMPILE=1 # # Override the build tools and some obj files to @@ -274,6 +276,8 @@ ifdef CROSS_TO_WASM # WASM # originally from https://github.com/NetHack/NetHack/pull/385 #===============-================================================= +#also set a make variable flagging this as a crosscompile +CROSSCOMPILE=1 # #WASM_DEBUG = 1 WASM_DATA_DIR = $(TARGETPFX)wasm-data @@ -410,6 +414,8 @@ ifdef CROSS_TO_MIPS #================================================================= CFLAGS += -DCROSSCOMPILE +#also set a make variable flagging this as a crosscompile +CROSSCOMPILE=1 # # Override the build tools and some obj files to @@ -486,6 +492,8 @@ ifdef CROSS_TO_AMIGA #================================================================= CFLAGS += -DCROSSCOMPILE +#also set a make variable flagging this as a crosscompile +CROSSCOMPILE=1 # # Override the build tools and some obj files to diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index cf3c9dac3..1bb35460d 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -162,10 +162,10 @@ LUATESTTARGET := $(LUAHEADERS)/lua.h endif # LUAHPREFIX= -LUATOP= -LUAMAKEFLAGS= -LUA2NHTOP= -LUABASELIB= +#LUATOP= +#LUAMAKEFLAGS= +#LUA2NHTOP= +#LUABASELIB= LUATOPLIB= LUALIBBUILT= LUALIB= From 1eb91a61afb2f647f4c257d4d52996948cf0f62d Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Tue, 19 May 2026 12:16:07 -0400 Subject: [PATCH 340/702] This is cron-daily v1-May-7-2026. 000files updated: Files --- Files | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Files b/Files index e6d4e707f..2353e640a 100644 --- a/Files +++ b/Files @@ -408,9 +408,9 @@ solaris-playground unix sys/unix/hints/include: (files for configuring UNIX NetHack versions) compiler.500 cross-post.500 cross-pre1.500 cross-pre2.500 -gbdates-post.500 gbdates-pre.500 misc.500 multisnd-post.500 -multisnd1-pre.500 multisnd2-pre.500 multiw-1.500 multiw-2.500 -response.500 whichbsd.500 +gbdates-post.500 gbdates-pre.500 linuxdistro.500 misc.500 +multisnd-post.500 multisnd1-pre.500 multisnd2-pre.500 multiw-1.500 +multiw-2.500 response.500 whichbsd.500 sys/vms: (files for VMS version) From 93786ddfd9685bdd1239890d32be2da623f4d8a9 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 20 May 2026 08:00:02 -0400 Subject: [PATCH 341/702] add a fixes5-0-1.txt entry for WANT_SYSTEM_LUA=1 --- doc/fixes5-0-1.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index dbbae2adc..daa4ae615 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -118,6 +118,10 @@ libnh: sys/unix/hints/macOS.500 in the WANT_LIBNH block, add an explicit $(GAME) is overridden to empty, the regular `recover: $(GAME)` chain no longer triggers `lua_support`, so include/nhlua.h never gets generated and recover.c's transitive #include of hack.h fails +Linux: add WANT_SYSTEM_LUA=1 support to the linux.500 hints files and + its included files, making it possible to avoid the 'fetch-lua' + step and the subsequent compiling of Lua; it tries to use use + the Lua5.4 package that is already installed on the system macOS: fix ncurses build with Homebrew musl: musl libc does not have __sighandler_t so don't use it in the macro definition for SIG_RET_TYPE with musl From f9165e66fcac8b095bed928a3e99981cd5aab158 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 20 May 2026 08:55:28 -0400 Subject: [PATCH 342/702] curses display sizes on Windows console, GUI --- win/curses/cursinit.c | 44 ++++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 9fcc1d962..1135d0eb8 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -744,6 +744,12 @@ curses_character_dialog(const char **choices, const char *prompt) void curses_init_options(void) { +#ifdef PDCURSES + int display_height = 0, display_width = 0; +#if defined(WIN32) && !defined(WIN32CON) + int alt_display_height = 0, alt_display_width = 0; +#endif +#endif /* change these from set_gameview to set_in_game */ set_wc_option_mod_status(WC_ALIGN_MESSAGE | WC_ALIGN_STATUS, set_in_game); @@ -761,36 +767,18 @@ curses_init_options(void) terminal size programmatically. If the user does not specify a size in the config file, we will set it to a nice big 32x110 to take advantage of some of the nice features of this windowport. */ -#if defined(WIN32) - if (iflags.wc2_term_cols == 0) { - int display_width = get_approx_display_cols(); - if (display_width > 220) - display_width = 220; - - if (display_width != 0) - iflags.wc2_term_cols = display_width; - else - iflags.wc2_term_cols = 110; - } - if (iflags.wc2_term_rows == 0) { - int display_height = get_approx_display_rows(); - - if (display_height > 64) - display_height = 64; - - if (display_height != 0) - iflags.wc2_term_rows = display_height; - else - iflags.wc2_term_rows = 32; - } -#else - /* FIXME: should these be higher; is there a way to detect max there? */ - if (iflags.wc2_term_cols == 0) - iflags.wc2_term_cols = 110; - if (iflags.wc2_term_rows == 0) - iflags.wc2_term_rows = 32; + getmaxyx(base_term, display_height, display_width); +#if defined(WIN32) && !defined(WIN32CON) + alt_display_width = get_approx_display_cols(); + alt_display_height = get_approx_display_rows(); + display_width = min(230, alt_display_width); + display_height = min(66, alt_display_height); #endif + if (iflags.wc2_term_cols == 0) + iflags.wc2_term_cols = display_width; + if (iflags.wc2_term_rows == 0) + iflags.wc2_term_rows = display_height; resize_term(iflags.wc2_term_rows, iflags.wc2_term_cols); getmaxyx(base_term, term_rows, term_cols); From 0f8f8f4892e1605cf640288f9fee2c8aec9a3fe9 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 21 May 2026 01:26:29 -0400 Subject: [PATCH 343/702] Windows console dev debug line --- sys/windows/consoletty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index c44c95232..93dd8a966 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -2438,7 +2438,7 @@ void nethack_enter_consoletty(void) */ width = csbi.srWindow.Right - csbi.srWindow.Left + 1; #ifdef DEBUG - if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) + if (wizard && NH_DEVEL_STATUS != NH_STATUS_RELEASED) fprintf(stdout, "width = %d\n", width); #endif } From 51f486589c2ed9a980ae6f28dfe9ef4698f564d6 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 21 May 2026 09:10:31 +0300 Subject: [PATCH 344/702] Add sysconf MAX_REROLLS option Public servers probably want to set this. --- doc/fixes5-0-1.txt | 1 + include/sys.h | 1 + src/cfgfiles.c | 15 +++++++++++++++ src/invent.c | 27 +++++++++++++++++++++++---- src/sys.c | 1 + sys/unix/sysconf | 4 ++++ 6 files changed, 45 insertions(+), 4 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index daa4ae615..1aa287b92 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -138,6 +138,7 @@ tty: allow custom glyph colors if they're basic 16 nethack colors General New Features -------------------- +sysconf option MAX_REROLLS to limit number of rerolls Platform- and/or Interface-Specific New Features diff --git a/include/sys.h b/include/sys.h index 2ea704cdb..6ad569dce 100644 --- a/include/sys.h +++ b/include/sys.h @@ -25,6 +25,7 @@ struct sysopt_s { * -1: getenv() didn't find a value for DEBUGFILES. */ int maxplayers; + int maxrerolls; int seduce; int check_save_uid; /* restoring savefile checks UID? */ int check_plname; /* use plname for checking wizards/explorers/shellers */ diff --git a/src/cfgfiles.c b/src/cfgfiles.c index 4e410c880..6e870169e 100644 --- a/src/cfgfiles.c +++ b/src/cfgfiles.c @@ -74,6 +74,7 @@ staticfn boolean cnf_line_CHECK_PLNAME(char *); staticfn boolean cnf_line_SEDUCE(char *); staticfn boolean cnf_line_HIDEUSAGE(char *); staticfn boolean cnf_line_MAXPLAYERS(char *); +staticfn boolean cnf_line_MAX_REROLLS(char *); staticfn boolean cnf_line_PERSMAX(char *); staticfn boolean cnf_line_PERS_IS_UID(char *); staticfn boolean cnf_line_ENTRYMAX(char *); @@ -968,6 +969,19 @@ cnf_line_MAXPLAYERS(char *bufp) return TRUE; } +staticfn boolean +cnf_line_MAX_REROLLS(char *bufp) +{ + int n = atoi(bufp); + + if (n < 0 || n > 255) { + config_error_add("Illegal value in MAX_REROLLS (maximum is 255)"); + n = 10; + } + sysopt.maxrerolls = n; + return TRUE; +} + staticfn boolean cnf_line_PERSMAX(char *bufp) { @@ -1349,6 +1363,7 @@ static const struct match_config_line_stmt { CNFL_S(SEDUCE, 6), CNFL_S(HIDEUSAGE, 9), CNFL_S(MAXPLAYERS, 10), + CNFL_S(MAX_REROLLS, 10), CNFL_S(PERSMAX, 7), CNFL_S(PERS_IS_UID, 11), CNFL_S(ENTRYMAX, 8), diff --git a/src/invent.c b/src/invent.c index 078c3c5d5..228eacd12 100644 --- a/src/invent.c +++ b/src/invent.c @@ -26,6 +26,7 @@ staticfn int ckvalidcat(struct obj *); staticfn int ckunpaid(struct obj *); staticfn char *safeq_xprname(struct obj *); staticfn char *safeq_shortxprname(struct obj *); +staticfn boolean hit_reroll_limit(int); staticfn char display_pickinv(const char *, const char *, const char *, boolean, boolean, long *); staticfn char display_used_invlets(char); @@ -2540,6 +2541,15 @@ askchain( return cnt; } +staticfn boolean +hit_reroll_limit(int curr) +{ +#ifdef SYSCF + if (sysopt.maxrerolls && curr >= (sysopt.maxrerolls-1)) + return TRUE; +#endif /*SYSCF*/ + return FALSE; +} /* The menu for rerolling attributes and inventory. @@ -2569,9 +2579,17 @@ reroll_menu(void) ATR_NONE, NO_COLOR, "start the game with this character", MENU_ITEMFLAGS_NONE); any.a_char = 'y'; + Strcat(buf, "reroll another character"); +#ifdef SYSCF + if (sysopt.maxrerolls > 0) { + char *bp = eos(buf); + + Sprintf(bp, " (%li/%i)", + u.uroleplay.numrerolls+1, sysopt.maxrerolls); + } +#endif /*SYSCF*/ add_menu(win, &nul_glyphinfo, &any, flags.lootabc ? 0 : 'r', 0, - ATR_NONE, NO_COLOR, "reroll another character", - MENU_ITEMFLAGS_NONE); + ATR_NONE, NO_COLOR, buf, MENU_ITEMFLAGS_NONE); any.a_char = 0; add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE, NO_COLOR, "", MENU_ITEMFLAGS_NONE); @@ -2600,7 +2618,7 @@ reroll_menu(void) if (select_menu(win, PICK_ONE, &pick_list) > 0) { option = pick_list[0].item.a_char; free((genericptr_t) pick_list); - } else { + } else if (!hit_reroll_limit(u.uroleplay.numrerolls)) { /* user closed the menu without selecting; unclear what their choice is here so ask again; but (e.g. for hangup handling) stop asking if the user cancels out again */ @@ -2610,7 +2628,8 @@ reroll_menu(void) if (option == 'y') { ++u.uroleplay.numrerolls; - return TRUE; + if (!hit_reroll_limit(u.uroleplay.numrerolls)) + return TRUE; } return FALSE; } diff --git a/src/sys.c b/src/sys.c index 758a93667..a5a0e87e0 100644 --- a/src/sys.c +++ b/src/sys.c @@ -59,6 +59,7 @@ sys_early_init(void) sysopt.genericusers = (char *) 0; sysopt.msghandler = (char *) 0; sysopt.maxplayers = 0; /* XXX eventually replace MAX_NR_OF_PLAYERS */ + sysopt.maxrerolls = 0; sysopt.bones_pools = 0; sysopt.livelog = LL_NONE; diff --git a/sys/unix/sysconf b/sys/unix/sysconf index e960bd522..a8b136410 100644 --- a/sys/unix/sysconf +++ b/sys/unix/sysconf @@ -55,6 +55,10 @@ GENERICUSERS=play player game games nethack nethacker ec2-user # letter and "lock" (eg. alock, block, ...) MAXPLAYERS=10 +# Limit the number of rerolls +# Default is 0 (meaning infinite), valid values are 0-255 +MAX_REROLLS=0 + # If not null, added to string "To get local support, " in the support # information help. #SUPPORT=call Izchak at extension 42. From 65646e2a8c8c2d515d47fddea74ccbb592b98866 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 21 May 2026 10:36:22 -0400 Subject: [PATCH 345/702] fix recently appearing warnings in clang-22 and visual studio clang-22: invent.c:2621:16: warning: variable 'option' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized] 2621 | } else if (!hit_reroll_limit(u.uroleplay.numrerolls)) { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ invent.c:2629:9: note: uninitialized use occurs here 2629 | if (option == 'y') { | ^~~~~~ invent.c:2621:12: note: remove the 'if' if its condition is always true 2621 | } else if (!hit_reroll_limit(u.uroleplay.numrerolls)) { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ invent.c:2570:16: note: initialize the variable 'option' to silence this warning 2570 | char option; | ^ | = '\0' 1 warning generated. visual studio: src/invent.c(2629,1): warning C4701: potentially uninitialized local variable 'option' used --- src/invent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invent.c b/src/invent.c index 228eacd12..29a4026ef 100644 --- a/src/invent.c +++ b/src/invent.c @@ -2567,7 +2567,7 @@ reroll_menu(void) struct obj *otmp; int tmpglyph; glyph_info tmpglyphinfo; - char option; + char option = 'n'; char buf[BUFSZ]; win = create_nhwindow(NHW_MENU); From 18845b6f678648ce9214d6dfbb1ba54553b2159c Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 21 May 2026 10:44:29 -0400 Subject: [PATCH 346/702] match magic object tiles with mundane counterparts Fixes #1533 --- win/share/objects.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/win/share/objects.txt b/win/share/objects.txt index 53ebdcf13..f150a9e8b 100644 --- a/win/share/objects.txt +++ b/win/share/objects.txt @@ -4808,7 +4808,7 @@ Z = (195, 195, 195) ...........AJ... ..........KJA... .........KJA.... - ........JJA..... + ........KJA..... .......JJA...... ......KJA....... .....JJA........ @@ -5000,8 +5000,8 @@ Z = (195, 195, 195) ....OOOOOOOO.... ...OOOOOOOOOO... ...LOOOOOOOOLAA. - ...LKOOOOOOJLAA. - ...KKLKKKKLJJAA. + ...LKOOOOOOJLAAA + ...KKLKKKKLJJAAA ...JKLKKKKLJJAA. ....JKKKKKKJAA.. .....JJJJJJAA... From b9d87fea6db547a24465cdc9554df7a215853e2d Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 21 May 2026 12:04:01 -0400 Subject: [PATCH 347/702] fix a buffer overlow introduced in recent commit --- src/invent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invent.c b/src/invent.c index 29a4026ef..a1ea94863 100644 --- a/src/invent.c +++ b/src/invent.c @@ -2579,7 +2579,7 @@ reroll_menu(void) ATR_NONE, NO_COLOR, "start the game with this character", MENU_ITEMFLAGS_NONE); any.a_char = 'y'; - Strcat(buf, "reroll another character"); + Strcpy(buf, "reroll another character"); #ifdef SYSCF if (sysopt.maxrerolls > 0) { char *bp = eos(buf); From e14cb40a6e85dcec26294c4c57c2e44fc92b7762 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Thu, 21 May 2026 20:58:16 +0200 Subject: [PATCH 348/702] pickup: show container glyphs in tip/loot menus doloot_core(), choose_tip_container_menu(), and tipcontainer_gettarget() each iterate carried or floor containers and offer them as menu rows, but passed &nul_glyphinfo so port windowports had nothing to render alongside. Compute proper glyph_info from each container the same way src/invent.c already does for inventory menus. --- src/pickup.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/pickup.c b/src/pickup.c index 65e77fca6..0ca9dca13 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -2236,7 +2236,8 @@ doloot_core(void) if (num_conts > 1) { /* use a menu to loot many containers */ - int n, i; + int n, i, tmpglyph; + glyph_info tmpglyphinfo; winid win; anything any; menu_item *pick_list = (menu_item *) 0; @@ -2249,7 +2250,9 @@ doloot_core(void) cobj = cobj->nexthere) if (Is_container(cobj)) { any.a_obj = cobj; - add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE, clr, + tmpglyph = obj_to_glyph(cobj, rn2_on_display_rng); + map_glyphinfo(0, 0, tmpglyph, 0U, &tmpglyphinfo); + add_menu(win, &tmpglyphinfo, &any, 0, 0, ATR_NONE, clr, doname(cobj), MENU_ITEMFLAGS_NONE); } end_menu(win, "Loot which containers?"); @@ -3504,7 +3507,8 @@ tip_ok(struct obj *obj) staticfn int choose_tip_container_menu(void) { - int n, i; + int n, i, tmpglyph; + glyph_info tmpglyphinfo; winid win; anything any; menu_item *pick_list = (menu_item *) 0; @@ -3520,7 +3524,9 @@ choose_tip_container_menu(void) if (Is_container(otmp)) { ++i; any.a_obj = otmp; - add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE, + tmpglyph = obj_to_glyph(otmp, rn2_on_display_rng); + map_glyphinfo(0, 0, tmpglyph, 0U, &tmpglyphinfo); + add_menu(win, &tmpglyphinfo, &any, 0, 0, ATR_NONE, clr, doname(otmp), MENU_ITEMFLAGS_NONE); } if (gi.invent) { @@ -3872,7 +3878,8 @@ tipcontainer_gettarget( struct obj *box, boolean *cancelled) { - int n, n_conts; + int n, n_conts, tmpglyph; + glyph_info tmpglyphinfo; winid win; anything any; char buf[BUFSZ]; @@ -3923,7 +3930,9 @@ tipcontainer_gettarget( any = cg.zeroany; any.a_obj = !exclude_it ? otmp : 0; Sprintf(buf, "%s%s", !exclude_it ? "" : " ", doname(otmp)); - add_menu(win, &nul_glyphinfo, &any, !exclude_it ? otmp->invlet : 0, 0, + tmpglyph = obj_to_glyph(otmp, rn2_on_display_rng); + map_glyphinfo(0, 0, tmpglyph, 0U, &tmpglyphinfo); + add_menu(win, &tmpglyphinfo, &any, !exclude_it ? otmp->invlet : 0, 0, ATR_NONE, clr, buf, MENU_ITEMFLAGS_NONE); } From 3beaf04c4505fd95b9c409b14762df6135416082 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 21 May 2026 15:54:27 -0400 Subject: [PATCH 349/702] fixes update for menu glyphs: shop bills, tip/loot --- doc/fixes5-0-1.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 1aa287b92..564a6f4bf 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -26,6 +26,9 @@ fix buffer overflow in update_topl when handling multiple items in a container fix random attended shrines in irregular rooms fix experience-level up/down hilighting +cherry-pick a pair of core fixes from the m68k-wip branch to add menu + glyphs to shop bills and container tip/loot menus (pr #1539 + by ingpaschke) Platform- and/or Interface-Specific Fixes From 7d512fd8cec09b50909296c627a0b9ab4d59cca9 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Thu, 21 May 2026 11:31:24 +0200 Subject: [PATCH 350/702] shk: show item glyphs in the pay-bill menu menu_pick_pay_items() passed &nul_glyphinfo to add_menu so port windowports never had a tile/glyph to render alongside each entry on the bill. Compute the proper glyph_info from the bill's obj, matching the pattern src/invent.c already uses for inventory menus. --- src/shk.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/shk.c b/src/shk.c index bd87b8849..cb86dfaa5 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1675,7 +1675,8 @@ menu_pick_pay_items( menu_item *pick_list = (menu_item *) 0; char *p, buf[BUFSZ]; long amt, largest_amt, save_quan; - int i, j, n, amt_width; + int i, j, n, amt_width, tmpglyph; + glyph_info tmpglyphinfo; any = cg.zeroany; win = create_nhwindow(NHW_MENU); @@ -1716,7 +1717,9 @@ menu_pick_pay_items( isn't hallucinating; also, that would mess up the alignment */ Snprintf(buf, sizeof buf, "%*ld Zm, %s", amt_width, amt, p); any.a_int = i + 1; /* +1: avoid 0 */ - add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE, NO_COLOR, buf, + tmpglyph = obj_to_glyph(otmp, rn2_on_display_rng); + map_glyphinfo(0, 0, tmpglyph, 0U, &tmpglyphinfo); + add_menu(win, &tmpglyphinfo, &any, 0, 0, ATR_NONE, NO_COLOR, buf, MENU_ITEMFLAGS_NONE); } From 3f837939bad97ec75d95f08da7e21d5b87501847 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Fri, 22 May 2026 06:02:00 +0100 Subject: [PATCH 351/702] Change the MAX_REROLLS option to be MAX_REROLL_RATE Having a hard cap on the number of rerolls doesn't help save CPU usage from excessive rerolling, because if the cap is set low enough to keep the CPU usage reasonable it isn't high enough for players to actually use the feature. Instead, allow capping the number of rerolls per second. (Sensible values seem to be in the 5-10 range.) If the player attempts more rerolls than this, show a paranoid confirmation prompt: the need to type the answer to the prompt will slow a human user down (and if the prompt is filled in too quickly, it will simply just be shown again, preventing attempts to use automation to skip the prompt). --- doc/fixes5-0-1.txt | 2 +- include/sys.h | 2 +- src/allmain.c | 36 ++++++++++++++++++++++++++++++++++++ src/cfgfiles.c | 10 +++++----- src/invent.c | 28 ++-------------------------- src/sys.c | 2 +- sys/unix/sysconf | 6 +++--- 7 files changed, 49 insertions(+), 37 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 564a6f4bf..5a37e9964 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -141,7 +141,7 @@ tty: allow custom glyph colors if they're basic 16 nethack colors General New Features -------------------- -sysconf option MAX_REROLLS to limit number of rerolls +sysconf option MAX_REROLL_RATE to limit rate at which rerolls are performed Platform- and/or Interface-Specific New Features diff --git a/include/sys.h b/include/sys.h index 6ad569dce..da060cad7 100644 --- a/include/sys.h +++ b/include/sys.h @@ -25,7 +25,7 @@ struct sysopt_s { * -1: getenv() didn't find a value for DEBUGFILES. */ int maxplayers; - int maxrerolls; + int maxrerollrate; int seduce; int check_save_uid; /* restoring savefile checks UID? */ int check_plname; /* use plname for checking wizards/explorers/shellers */ diff --git a/src/allmain.c b/src/allmain.c index 5c573da4b..90c4932ad 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -769,6 +769,17 @@ newgame(void) { int i; +#ifdef SYSCF + time_t last_reroll_time; + time_t cur_reroll_time; + int rerolls_this_second = 0; +# if defined(BSD) && !defined(POSIX_TYPES) +# define GET_REROLL_TIME(t) (void) time((long *) t); +# else +# define GET_REROLL_TIME(t) (void) time(t); +# endif +#endif /* defined(SYSCF) */ + /* make sure welcome messages are given before noticing monsters */ notice_mon_off(); disp.botlx = TRUE; @@ -819,7 +830,32 @@ newgame(void) docrt(); flush_screen(1); bot(); + +#ifdef SYSCF + GET_REROLL_TIME(&last_reroll_time); +#endif + while (u.uroleplay.reroll && reroll_menu()) { +#ifdef SYSCF + if (sysopt.maxrerollrate > 0) { + check_reroll_time: + GET_REROLL_TIME(&cur_reroll_time); + + if (last_reroll_time != cur_reroll_time) { + last_reroll_time = cur_reroll_time; + rerolls_this_second = 1; + } else { + if (rerolls_this_second >= sysopt.maxrerollrate) { + if (!paranoid_query(TRUE, "Continue rerolling?")) + break; + goto check_reroll_time; + } + ++rerolls_this_second; + } + } +#endif + + ++u.uroleplay.numrerolls; u_init_inventory_attrs(); bot(); } diff --git a/src/cfgfiles.c b/src/cfgfiles.c index 6e870169e..438c65478 100644 --- a/src/cfgfiles.c +++ b/src/cfgfiles.c @@ -74,7 +74,7 @@ staticfn boolean cnf_line_CHECK_PLNAME(char *); staticfn boolean cnf_line_SEDUCE(char *); staticfn boolean cnf_line_HIDEUSAGE(char *); staticfn boolean cnf_line_MAXPLAYERS(char *); -staticfn boolean cnf_line_MAX_REROLLS(char *); +staticfn boolean cnf_line_MAX_REROLL_RATE(char *); staticfn boolean cnf_line_PERSMAX(char *); staticfn boolean cnf_line_PERS_IS_UID(char *); staticfn boolean cnf_line_ENTRYMAX(char *); @@ -970,15 +970,15 @@ cnf_line_MAXPLAYERS(char *bufp) } staticfn boolean -cnf_line_MAX_REROLLS(char *bufp) +cnf_line_MAX_REROLL_RATE(char *bufp) { int n = atoi(bufp); if (n < 0 || n > 255) { - config_error_add("Illegal value in MAX_REROLLS (maximum is 255)"); + config_error_add("Illegal value in MAX_REROLL_RATE (maximum is 255)"); n = 10; } - sysopt.maxrerolls = n; + sysopt.maxrerollrate = n; return TRUE; } @@ -1363,7 +1363,7 @@ static const struct match_config_line_stmt { CNFL_S(SEDUCE, 6), CNFL_S(HIDEUSAGE, 9), CNFL_S(MAXPLAYERS, 10), - CNFL_S(MAX_REROLLS, 10), + CNFL_S(MAX_REROLL_RATE, 10), CNFL_S(PERSMAX, 7), CNFL_S(PERS_IS_UID, 11), CNFL_S(ENTRYMAX, 8), diff --git a/src/invent.c b/src/invent.c index a1ea94863..4c7f61bff 100644 --- a/src/invent.c +++ b/src/invent.c @@ -26,7 +26,6 @@ staticfn int ckvalidcat(struct obj *); staticfn int ckunpaid(struct obj *); staticfn char *safeq_xprname(struct obj *); staticfn char *safeq_shortxprname(struct obj *); -staticfn boolean hit_reroll_limit(int); staticfn char display_pickinv(const char *, const char *, const char *, boolean, boolean, long *); staticfn char display_used_invlets(char); @@ -2541,16 +2540,6 @@ askchain( return cnt; } -staticfn boolean -hit_reroll_limit(int curr) -{ -#ifdef SYSCF - if (sysopt.maxrerolls && curr >= (sysopt.maxrerolls-1)) - return TRUE; -#endif /*SYSCF*/ - return FALSE; -} - /* The menu for rerolling attributes and inventory. This is similar to the other inventory menus, but simpler to help it fit on @@ -2580,14 +2569,6 @@ reroll_menu(void) MENU_ITEMFLAGS_NONE); any.a_char = 'y'; Strcpy(buf, "reroll another character"); -#ifdef SYSCF - if (sysopt.maxrerolls > 0) { - char *bp = eos(buf); - - Sprintf(bp, " (%li/%i)", - u.uroleplay.numrerolls+1, sysopt.maxrerolls); - } -#endif /*SYSCF*/ add_menu(win, &nul_glyphinfo, &any, flags.lootabc ? 0 : 'r', 0, ATR_NONE, NO_COLOR, buf, MENU_ITEMFLAGS_NONE); any.a_char = 0; @@ -2618,7 +2599,7 @@ reroll_menu(void) if (select_menu(win, PICK_ONE, &pick_list) > 0) { option = pick_list[0].item.a_char; free((genericptr_t) pick_list); - } else if (!hit_reroll_limit(u.uroleplay.numrerolls)) { + } else { /* user closed the menu without selecting; unclear what their choice is here so ask again; but (e.g. for hangup handling) stop asking if the user cancels out again */ @@ -2626,12 +2607,7 @@ reroll_menu(void) } destroy_nhwindow(win); - if (option == 'y') { - ++u.uroleplay.numrerolls; - if (!hit_reroll_limit(u.uroleplay.numrerolls)) - return TRUE; - } - return FALSE; + return option == 'y'; } /* diff --git a/src/sys.c b/src/sys.c index a5a0e87e0..55e93eb02 100644 --- a/src/sys.c +++ b/src/sys.c @@ -59,7 +59,7 @@ sys_early_init(void) sysopt.genericusers = (char *) 0; sysopt.msghandler = (char *) 0; sysopt.maxplayers = 0; /* XXX eventually replace MAX_NR_OF_PLAYERS */ - sysopt.maxrerolls = 0; + sysopt.maxrerollrate = 0; sysopt.bones_pools = 0; sysopt.livelog = LL_NONE; diff --git a/sys/unix/sysconf b/sys/unix/sysconf index a8b136410..2d9676601 100644 --- a/sys/unix/sysconf +++ b/sys/unix/sysconf @@ -55,9 +55,9 @@ GENERICUSERS=play player game games nethack nethacker ec2-user # letter and "lock" (eg. alock, block, ...) MAXPLAYERS=10 -# Limit the number of rerolls -# Default is 0 (meaning infinite), valid values are 0-255 -MAX_REROLLS=0 +# Limit the number of rerolls per second when using the reroll option. +# 0 means that there is no limit on how quickly the user can reroll. +MAX_REROLL_RATE=0 # If not null, added to string "To get local support, " in the support # information help. From 4c7f2dfaac678f97f43fd13ad0277c0944271e9f Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 22 May 2026 12:21:42 -0400 Subject: [PATCH 352/702] some Windows curses adjustments dialog on startup --- sys/windows/windmain.c | 9 +++++++++ win/curses/cursdial.c | 33 ++++++++++++++++++++++----------- win/curses/cursmain.c | 2 +- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/sys/windows/windmain.c b/sys/windows/windmain.c index 3cb87f4f5..2cc92ac2a 100644 --- a/sys/windows/windmain.c +++ b/sys/windows/windmain.c @@ -303,7 +303,9 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ #ifdef WINCHAIN commit_windowchain(); #endif + init_nhwindows(&argc, argv); + #ifdef TTY_GRAPHICS if WINDOWPORT(tty) { int i; @@ -1265,7 +1267,11 @@ other_self_recover_prompt(void) int c, ci, ct, pl, retval = 0; boolean ismswin = WINDOWPORT(mswin), iscurses = WINDOWPORT(curses); + int save_popupdialog = iflags.wc_popup_dialog; + if (WINDOWPORT(curses)) { + iflags.wc_popup_dialog = TRUE; + } pl = 1; c = 'n'; ct = 0; @@ -1316,6 +1322,9 @@ other_self_recover_prompt(void) else retval = 1; /* yes, do recover the old game */ } + if (WINDOWPORT(curses)) { + iflags.wc_popup_dialog = save_popupdialog; + } return retval; } diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index b317c8543..e2bb44066 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -205,10 +205,8 @@ curses_line_input_dialog( /* Get a single character response from the player, such as a y/n prompt */ int -curses_character_input_dialog( - const char *prompt, - const char *choices, - char def) +curses_character_input_dialog(const char *prompt, const char *choices, + char def) { WINDOW *askwin = NULL; #ifdef PDCURSES @@ -222,12 +220,15 @@ curses_character_input_dialog( int prompt_height = 1; boolean any_choice = FALSE; boolean accept_count = FALSE; +#ifdef PDCURSES + int x, y; +#endif /* if messages were being suppressed for the remainder of the turn, re-activate them now that input is being requested */ curses_got_input(); - if (svm.moves > 0) { + if (svm.moves > 0 || !program_state.beyond_savefile_load) { curses_get_window_size(MAP_WIN, &map_height, &map_width); } else { map_height = term_rows; @@ -260,10 +261,10 @@ curses_character_input_dialog( choicestr[count + 5] = def; choicestr[count + 6] = ')'; choicestr[count + 7] = '\0'; - } else { /* No usable default choice */ + } else { /* No usable default choice */ choicestr[count + 3] = '\0'; - def = '\0'; /* Mark as no default */ + def = '\0'; /* Mark as no default */ } strcpy(askstr, prompt); strcat(askstr, choicestr); @@ -281,7 +282,8 @@ curses_character_input_dialog( } if (iflags.wc_popup_dialog /*|| curses_stupid_hack*/) { - askwin = curses_create_window(TEXT_WIN, prompt_width, prompt_height, UP); + askwin = + curses_create_window(TEXT_WIN, prompt_width, prompt_height, UP); activemenu = askwin; for (count = 0; count < prompt_height; count++) { @@ -291,6 +293,11 @@ curses_character_input_dialog( } curses_set_wid_colors(TEXT_WIN, askwin); +#ifdef PDCURSES + getyx(askwin, y, x); + wmove(askwin, y, x); + curs_set(1); +#endif wrefresh(askwin); } else { /* TODO: add SUPPRESS_HISTORY flag, then after getting a response, @@ -299,11 +306,15 @@ curses_character_input_dialog( } /*curses_stupid_hack = 0; */ - +#ifndef PDCURSES curs_set(1); +#endif while (1) { #ifdef PDCURSES - answer = wgetch(message_window); + if (WIN_MESSAGE != WIN_ERR) + answer = wgetch(message_window); + else + answer = wgetch(askwin); #else answer = curses_read_char(); #endif @@ -321,7 +332,7 @@ curses_character_input_dialog( } answer = def; for (count = 0; choices[count] != '\0'; count++) { - if (choices[count] == 'q') { /* q is preferred over n */ + if (choices[count] == 'q') { /* q is preferred over n */ answer = 'q'; } else if ((choices[count] == 'n') && answer != 'q') { answer = 'n'; diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 23f5e90f2..52b034410 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -1004,7 +1004,7 @@ curses_print_glyph( #ifdef ENHANCED_SYMBOLS (SYMHANDLING(H_UTF8) && glyphinfo->gm.u && glyphinfo->gm.u->utf8str) - ? glyphinfo->gm.u : NULL, + ? glyphinfo->gm.u : NULL, #endif (nhcolor != 0) ? nhcolor : color, bkglyphinfo->framecolor, attr); From a1fad59f2d6a830d8e32c6976a1595cab0e6519c Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 22 May 2026 12:24:32 -0400 Subject: [PATCH 353/702] idlecheckpoint support in curses --- include/config.h | 1 + win/curses/cursmisc.c | 31 ++++++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/include/config.h b/include/config.h index 4fcc892e0..21556bcc4 100644 --- a/include/config.h +++ b/include/config.h @@ -690,6 +690,7 @@ typedef unsigned char uchar; * Currently has support in: * WIN32CON * Qt + * curses */ /* #define IDLECHECKPOINT */ diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 3084d193a..e085d54d3 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -34,16 +34,41 @@ int curses_getch(void) { int ch; + boolean timeoutset = FALSE; - if (iflags.debug_fuzzer) + if (iflags.debug_fuzzer) { ch = randomkey(); - else + } else if (iflags.idlecheckpoint) { + boolean done_a_checkpoint = FALSE; + + done_a_checkpoint = FALSE; + timeout(IDLECHECKPOINT_WAIT_TIME * 1000); + timeoutset = TRUE; + + while (1) { + ch = getch(); + if (ch == ERR && !done_a_checkpoint) { +#ifdef INSURANCE + save_currentstate(); +#endif /* INSURANCE */ + done_a_checkpoint = TRUE; + timeout(-1); + timeoutset = FALSE; + } else { + if (timeoutset) { + timeout(-1); + timeoutset = FALSE; + } + break; + } + } + } else { ch = getch(); + } return ch; } /* Read a character of input from the user */ - int curses_read_char(void) { From e394dc341bb86b1953aabf0feacfeb3e36bb0d2e Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 22 May 2026 12:25:13 -0400 Subject: [PATCH 354/702] prevent a checkpoint from executing too early --- src/do.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/do.c b/src/do.c index a7ad93903..54cfd5960 100644 --- a/src/do.c +++ b/src/do.c @@ -1376,6 +1376,9 @@ save_currentstate(void) { NHFILE *nhfp; + if (!program_state.something_worth_saving) + return; + program_state.in_checkpoint++; if (flags.ins_chkpt) { /* write out just-attained level, with pets and everything */ From be4d613bff524c96053db333ae0315b8a7dff376 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 22 May 2026 14:20:13 -0400 Subject: [PATCH 355/702] follow-up curses idlecheckpoint --- win/curses/cursmisc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index e085d54d3..efa5da83a 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -41,7 +41,6 @@ curses_getch(void) } else if (iflags.idlecheckpoint) { boolean done_a_checkpoint = FALSE; - done_a_checkpoint = FALSE; timeout(IDLECHECKPOINT_WAIT_TIME * 1000); timeoutset = TRUE; From 189a0b8c3f59f9527152a1f6eeed53cb0b368798 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 22 May 2026 14:46:17 -0400 Subject: [PATCH 356/702] update tested versions of Visual Studio 2026-05-22 --- sys/windows/Makefile.nmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index 578547b32..93df07466 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -8,8 +8,8 @@ # MS Visual Studio Visual C++ compiler # # Visual Studio Compilers Tested: -# - Microsoft Visual Studio Community 2022 v 17.14.32 -# - Microsoft Visual Studio Community 2026 v 18.6.0 +# - Microsoft Visual Studio Community 2022 v 17.14.33 +# - Microsoft Visual Studio Community 2026 v 18.6.1 # #============================================================================== # This is used for building two distinct executables of NetHack: @@ -1188,7 +1188,7 @@ rc=Rc.exe # # Recently tested versions: TESTEDVS2022 = 14.44.35225.0 -TESTEDVS2026 = 14.51.36243.0 +TESTEDVS2026 = 14.51.36244.0 VS20261ST = 1450000000 VS2026CUR = $(TESTEDVS2026:.=) From ced5744fe67f398b31a43ff1f9090a5dbc92b23f Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Thu, 21 May 2026 21:14:58 +0200 Subject: [PATCH 357/702] share+amiga: gate pcmain.c nhuuid for CROSS_TO_AMIGA, drop amidos.c copy amidos.c had a byte-identical copy of the RFC 4122 v4 generator already living under CROSS_TO_ATARI in sys/share/pcmain.c. --- sys/amiga/amidos.c | 38 -------------------------- sys/share/pcmain.c | 66 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 56 insertions(+), 48 deletions(-) diff --git a/sys/amiga/amidos.c b/sys/amiga/amidos.c index 097e57905..6aa0577fe 100644 --- a/sys/amiga/amidos.c +++ b/sys/amiga/amidos.c @@ -45,44 +45,6 @@ amiga_self_assign(void) UnLock(dup); } -/* Generate an RFC 4122 v4 UUID for this game. Draw bytes from the - core's ISAAC64 RNG, which init_random() seeded before we get here. */ -void -get_nhuuid(void) -{ - uchar bytes[16]; - int i; - - if (svn.nhuuid[0]) - return; - - for (i = 0; i < 16; i++) - bytes[i] = (uchar) rn2(256); - /* RFC 4122: version=4 (random), variant=10. */ - bytes[6] = (bytes[6] & 0x0F) | 0x40; - bytes[8] = (bytes[8] & 0x3F) | 0x80; - - Snprintf(svn.nhuuid, sizeof svn.nhuuid, - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x", - bytes[0], bytes[1], bytes[2], bytes[3], - bytes[4], bytes[5], - bytes[6], bytes[7], - bytes[8], bytes[9], - bytes[10], bytes[11], bytes[12], bytes[13], - bytes[14], bytes[15]); -} - -void -free_nhuuid(void) -{ - int i; - - for (i = 0; i < SIZE(svn.nhuuid); i++) { - svn.nhuuid[i] = 0; - } -} - #include "winext.h" #include "winproto.h" diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index 24495392b..2eea63724 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -12,7 +12,7 @@ #include #endif -#if !defined(AMIGA) && !defined(__DJGPP__) +#if !defined(AMIGA) && !defined(__DJGPP__) && !defined(__MINT__) #include #else #include @@ -27,9 +27,7 @@ char orgdir[PATHLEN]; /* also used in pcsys.c, amidos.c */ #ifdef TOS boolean run_from_desktop = TRUE; /* should we pause before exiting?? */ -#ifdef __GNUC__ -long _stksize = 16 * 1024; -#endif +/* _stksize is owned by sys/atari/tos.c for the 5.0 GEM build. */ #endif #ifdef AMIGA @@ -119,7 +117,6 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ #endif #ifdef TOS - long clock_time; if (*argv[0]) { /* only a CLI can give us argv[0] */ gh.hname = argv[0]; run_from_desktop = FALSE; @@ -342,10 +339,6 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ /* * It seems you really want to play. */ -#ifdef TOS - if (comp_times((long) time(&clock_time))) - error("Your clock is incorrectly set!"); -#endif if (!dlb_init()) { pline( "%s\n%s\n%s\n%s\n\nNetHack was unable to open the required file " @@ -779,7 +772,48 @@ free_nhuuid(void) } #endif -#if defined(CROSS_TO_AMIGA) +#if defined(CROSS_TO_ATARI) || defined(CROSS_TO_AMIGA) +/* Generate an RFC 4122 v4 UUID for this game. Draw bytes from the + core's ISAAC64 RNG, which init_random() seeded before we get here. */ +void +get_nhuuid(void) +{ + uchar bytes[16]; + int i; + + if (svn.nhuuid[0]) + return; + + for (i = 0; i < 16; i++) + bytes[i] = (uchar) rn2(256); + /* RFC 4122: version=4 (random), variant=10. */ + bytes[6] = (bytes[6] & 0x0F) | 0x40; + bytes[8] = (bytes[8] & 0x3F) | 0x80; + + Snprintf(svn.nhuuid, sizeof svn.nhuuid, + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x%02x%02x%02x%02x", + bytes[0], bytes[1], bytes[2], bytes[3], + bytes[4], bytes[5], + bytes[6], bytes[7], + bytes[8], bytes[9], + bytes[10], bytes[11], bytes[12], bytes[13], + bytes[14], bytes[15]); +} + +void +free_nhuuid(void) +{ + int i; + + for (i = 0; i < SIZE(svn.nhuuid); i++) { + svn.nhuuid[i] = 0; + } +} +#endif + +#if defined(CROSS_TO_AMIGA) || defined(CROSS_TO_ATARI) +#ifdef CROSS_TO_AMIGA void msmsg VA_DECL(const char *, fmt) { @@ -790,6 +824,18 @@ VA_DECL(const char *, fmt) VA_END(); return; } +#endif +#ifdef CROSS_TO_ATARI +void +msmsg(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + fflush(stdout); +} +#endif unsigned long sys_random_seed(void) From 1e34b52648e273c5fb804a533ab25bf788e366de Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Thu, 21 May 2026 21:15:12 +0200 Subject: [PATCH 358/702] share: extend pcmain.c nhuuid to CROSS_TO_MSDOS, drop stub The MSDOS branch carried a zero-filled placeholder with a FIXME; it can use the same RFC 4122 v4 path as Atari and Amiga. --- sys/share/pcmain.c | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index 2eea63724..50e7316ab 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -745,34 +745,8 @@ exepath(char *str) } #endif /* EXEPATH */ -#if defined(CROSS_TO_MSDOS) - -void -get_nhuuid(void) -{ - unsigned char stmp[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - if (svn.nhuuid[0]) - return; - - /* FIXME: fill in a useful valid UUID somehow */ - Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", (char *) stmp); -} - -void -free_nhuuid(void) -{ - int i; - - for (i = 0; i < SIZE(svn.nhuuid); i++) { - svn.nhuuid[i] = 0; - } -} -#endif - -#if defined(CROSS_TO_ATARI) || defined(CROSS_TO_AMIGA) +#if defined(CROSS_TO_ATARI) || defined(CROSS_TO_AMIGA) \ + || defined(CROSS_TO_MSDOS) /* Generate an RFC 4122 v4 UUID for this game. Draw bytes from the core's ISAAC64 RNG, which init_random() seeded before we get here. */ void From 3ea7fd3d67344d9a51f79988db8695381ef0d14b Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 22 May 2026 15:41:18 -0400 Subject: [PATCH 359/702] stamp Guidebook with date of most recent commit to it --- doc/Guidebook.mn | 2 +- doc/Guidebook.tex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index a5724074d..72401328e 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -60,7 +60,7 @@ .ds f0 \*(vr .ds f1 \" empty .\"DO NOT REMOVE NH_DATESUB .ds f2 Date(%B %-d, %Y) -.ds f2 May 6, 2026 +.ds f2 May 11, 2026 . .\" A note on some special characters: .\" \(lq = left double quote diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 2698ba802..3df3d7d71 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -25,7 +25,7 @@ \author{Original version - Eric S. Raymond\\ (Edited and expanded for 5.0.0 by Mike Stephenson and others)} %DO NOT REMOVE NH_DATESUB \date{Date(%B %-d, %Y)} -\date{May 6, 2026} +\date{May 11, 2026} \maketitle From 2808f45c7063b0fbe5e6eefdd8be51091959bc63 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Fri, 22 May 2026 16:16:09 -0400 Subject: [PATCH 360/702] This is cron-daily v1-May-7-2026. 005guidebook updated: doc/Guidebook.txt --- doc/Guidebook.txt | 238 +++++++++++++++++++++++----------------------- 1 file changed, 119 insertions(+), 119 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index e44a6bc17..113272b04 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for NetHack 5.0.0 by Mike Stephenson and others) - May 6, 2026 + May 11, 2026 @@ -126,7 +126,7 @@ employ to great advantage. - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -192,7 +192,7 @@ NetHack continues this fine tradition. Unlike text adventure games - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -258,7 +258,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -324,7 +324,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -390,7 +390,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -456,7 +456,7 @@ The number of turns elapsed so far, displayed if you have the - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -522,7 +522,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -588,7 +588,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -654,7 +654,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -720,7 +720,7 @@ instead. Only these one-step movement commands cause you to - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -786,7 +786,7 @@ ing . ^ is used as shorthand elsewhere in the - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -852,7 +852,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -918,7 +918,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -984,7 +984,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -1050,7 +1050,7 @@ at an adjacent "remembered, unseen monster" marker. - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -1116,7 +1116,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -1182,7 +1182,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -1248,7 +1248,7 @@ (R)UNIX is a registered trademark of The Open Group. - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -1314,7 +1314,7 @@ inventory slot. If it has a name assigned, other stacks with the - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -1380,7 +1380,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -1446,7 +1446,7 @@ fight there. Default key is `F', or `-' with number_pad - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -1512,7 +1512,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -1578,7 +1578,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -1644,7 +1644,7 @@ Pick up things at the current location. Default key is `,'. The - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -1710,7 +1710,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -1776,7 +1776,7 @@ worn. - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -1842,7 +1842,7 @@ Suspend the game, switching from NetHack to the terminal it was - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -1908,7 +1908,7 @@ pick one from inventory, except for the special case of - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -1974,7 +1974,7 @@ menu of sorting orders available (provided that the vanquished - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -2040,7 +2040,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -2106,7 +2106,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -2172,7 +2172,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -2238,7 +2238,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -2304,7 +2304,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -2370,7 +2370,7 @@ them). Some monsters who can open doors can also use unlocking tools. - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -2436,7 +2436,7 @@ been nullified, giving access to whatever is beyond them. In the - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -2502,7 +2502,7 @@ play. - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -2568,7 +2568,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -2634,7 +2634,7 @@ attack, when guessing where an unseen monster is or when deliberately - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -2700,7 +2700,7 @@ noid_confirmation:attack option to require a response of "yes" - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -2766,7 +2766,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -2832,7 +2832,7 @@ are encumbered, one of the conditions Burdened, Stressed, Strained, - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -2898,7 +2898,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -2964,7 +2964,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -3030,7 +3030,7 @@ aklys, lucern hammer, and bec-de-corbin) are defined in an appendix to - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -3096,7 +3096,7 @@ shots by using a numeric prefix before the `t' or `f' command. For - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -3162,7 +3162,7 @@ first you need to have a weapon in each hand. (Note that your two - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -3228,7 +3228,7 @@ even further. Most of these provide a one or two point improvement to - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -3294,7 +3294,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -3360,7 +3360,7 @@ yourself (just give a `.' or `s' for the direction). Be warned, how- - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -3426,7 +3426,7 @@ your ken can be harmful to your health! - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -3492,7 +3492,7 @@ play the entire game without being able to see (a self-imposed chal- - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -3558,7 +3558,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -3624,7 +3624,7 @@ set the goldX option if you prefer to have gold pieces be treated as - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -3690,7 +3690,7 @@ eating such items still counts against foodless conduct. - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -3756,7 +3756,7 @@ monster (i.e. if you would get experience for the death). This is a - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -3822,7 +3822,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -3888,7 +3888,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -3954,7 +3954,7 @@ ning NetHack for the first time, you should find a default template - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -4020,7 +4020,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -4086,7 +4086,7 @@ begins; whatever follows will be common to all sections. Otherwise - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -4152,7 +4152,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -4218,7 +4218,7 @@ sign) to let NetHack know that the rest is intended as a file name. - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -4284,7 +4284,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -4350,7 +4350,7 @@ weapon or both. - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -4416,7 +4416,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -4482,7 +4482,7 @@ extended command, it controls whether the menu shows all available - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -4548,7 +4548,7 @@ might miss some interesting and/or important information. Persis- - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -4614,7 +4614,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -4680,7 +4680,7 @@ class(es). Combination starts with a prompt for object class(es) of - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -4746,7 +4746,7 @@ 5 - One-or-other - show symbols on headers, or on entries if no - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -4812,7 +4812,7 @@ port is the same as specifying 0. - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -4878,7 +4878,7 @@ ing 1 and negating number_pad is the same as specifying 0. (Set- - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -4944,7 +4944,7 @@ `y', set Confirm too); - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -5010,7 +5010,7 @@ ing pets on the map. Effectively a superset of the hilite_pet bool- - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -5076,7 +5076,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -5142,7 +5142,7 @@ game). This option exists partly as an acknowledgement that some - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -5208,7 +5208,7 @@ sistent. - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -5274,7 +5274,7 @@ Controls the sorting behavior for the output of the `\' and ``' com- - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -5340,7 +5340,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -5406,7 +5406,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -5472,7 +5472,7 @@ targets. - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -5538,7 +5538,7 @@ currently using by checking to see if it shows up in the Options list. - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -5604,7 +5604,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -5670,7 +5670,7 @@ this option. - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -5736,7 +5736,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -5802,7 +5802,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -5868,7 +5868,7 @@ hang if this is turned on. Cannot be set with the `O' command. - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -5934,7 +5934,7 @@ you can define patterns to be checked when the game is about to - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -6000,7 +6000,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -6066,7 +6066,7 @@ When asked for a location, the key to go to next closest door or - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -6132,7 +6132,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -6198,7 +6198,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -6264,7 +6264,7 @@ ple MENUCOLOR entries in your configuration file, and the last MENU- - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -6330,7 +6330,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -6396,7 +6396,7 @@ depending upon your other option settings. - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -6462,7 +6462,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -6528,7 +6528,7 @@ value, and the ^ prefix causes the following character to be treated - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -6594,7 +6594,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -6660,7 +6660,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -6726,7 +6726,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -6792,7 +6792,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -6858,7 +6858,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -6924,7 +6924,7 @@ seen via the "#attributes" command. - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -6990,7 +6990,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -7056,7 +7056,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -7122,7 +7122,7 @@ connection between "wizard mode" and the Wizard role). Attempting to - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -7188,7 +7188,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -7254,7 +7254,7 @@ were distinct for specific types of monsters and objects rather than - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -7320,7 +7320,7 @@ file layout which prevented score entries from being read back in cor- - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -7386,7 +7386,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -7452,7 +7452,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -7518,7 +7518,7 @@ changes and new features almost immediately, and they often did. The - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -7584,7 +7584,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -7650,7 +7650,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -7716,7 +7716,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -7782,7 +7782,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 @@ -7848,7 +7848,7 @@ - NetHack 5.0.0 May 6, 2026 + NetHack 5.0.0 May 11, 2026 From 6aed21933d7e87148c8f42341512202994fc2f34 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 23 May 2026 13:33:35 -0400 Subject: [PATCH 361/702] add paragraph about README.hints to NewInstall.unx --- sys/unix/NewInstall.unx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/unix/NewInstall.unx b/sys/unix/NewInstall.unx index fe1ebaf83..9ced987c1 100644 --- a/sys/unix/NewInstall.unx +++ b/sys/unix/NewInstall.unx @@ -155,6 +155,10 @@ additional interfaces. See below. | | | | qt6-multimedia-dev | +----------+-------+-----------------+--------------------------------------+ +There are other hints file options that are meant to impact your NetHack build +in various other ways too. A reference list can be found in +sys/unix/README.hints. + # NetHack 5.0 NewInstall.unx $NHDT-Date: 1652276817 2022/05/11 13:46:57 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ # Copyright (c) 2009 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. From fd4fd6ef86833d4be98ade0ab6b03a596cf7432d Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 23 May 2026 13:43:06 -0400 Subject: [PATCH 362/702] README-hints -> README.hints --- sys/unix/{README-hints => README.hints} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename sys/unix/{README-hints => README.hints} (100%) diff --git a/sys/unix/README-hints b/sys/unix/README.hints similarity index 100% rename from sys/unix/README-hints rename to sys/unix/README.hints From 0536318099b37a2775529776c74ce97cc234797b Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sat, 23 May 2026 14:16:07 -0400 Subject: [PATCH 363/702] This is cron-daily v1-May-7-2026. 000files updated: Files --- Files | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Files b/Files index 2353e640a..a520f9beb 100644 --- a/Files +++ b/Files @@ -378,7 +378,7 @@ sys/unix: (files for UNIX versions) Install.unx Makefile.check Makefile.dat Makefile.doc Makefile.src Makefile.top Makefile.utl NewInstall.unx -README-hints README.xcode XCode.xcconfig depend.awk +README.hints README.xcode XCode.xcconfig depend.awk gitinfo.sh macuuid.m mkmkfile.sh nethack.sh setup.sh sysconf unixmain.c unixres.c unixunix.c From 94e7d0bcf384de7cd6a8d2d200efb0d4b45ccde0 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 23 May 2026 20:01:06 -0400 Subject: [PATCH 364/702] fixes5-0-1.txt catch-up --- doc/fixes5-0-1.txt | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 5a37e9964..d47725199 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -1,5 +1,5 @@ NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ $NHDT-Date: 1778535648 2026/05/11 21:40:48 $ - + General Fixes and Modified Features ----------------------------------- fix some cross-compile package filenames that still referenced 370 instead @@ -29,6 +29,12 @@ fix experience-level up/down hilighting cherry-pick a pair of core fixes from the m68k-wip branch to add menu glyphs to shop bills and container tip/loot menus (pr #1539 by ingpaschke) +tiles: make the tile for magic flute and mundane flute be exactly the + same; do the same thing for drum of earthquake and leather drum +fix a buffer overflow in reroll processing that was introduced in a + post-release 5.0.0 commit +ensure a checkpoint, aka a save_currentstate() call, isn't done before + the game is ready Platform- and/or Interface-Specific Fixes @@ -102,6 +108,9 @@ curses on Windows: some early data is alloc'd for the windows console settings in both tty and curses (pdcursesmod) prior to the window port initialization, but only tty was freeing it; call console_exit() in nethack_exit if window port is curses +curses on Windows: dialogs pertaining to the need for self-recover + were not visible and therefore the player had no idea that + answers were expected or why gcc-16: tiletext.c [-Wdiscarded-qualifiers] warning suppression libnh: update get_nhuuid() for libnhmain libnh: sys/libnh/libnhmain.c: drop `static` on `whoami()` @@ -135,6 +144,9 @@ Windows: correct a NetHack 5.0.0 packaging error if visual studio was used; a remnant hard-coded 370 was in package.nmake Windows: setting any map_mode option in the config file could trigger an app failure on launch by dereferencing a null pointer +Windows: a Windows console debug line began showing up after the sources + switched NH_DEVEL_STATUS from NH_STATUS_RELEASED to + NH_STATUS_POSTRELEASE; make it only show if (wizard) is true tty: allow custom glyph colors if they're basic 16 nethack colors on terminals with less than 256 colors @@ -142,6 +154,11 @@ tty: allow custom glyph colors if they're basic 16 nethack colors General New Features -------------------- sysconf option MAX_REROLL_RATE to limit rate at which rerolls are performed +idlecheckpoint config file option to update checkpoint files whenever an + input request isn't responded to within IDLECHECKPOINT_WAIT_TIME + seconds; helps ensure that a recover operation, if it turns out + to be needed, is much more current than the last level change; + support added for Windows console, Qt, and curses Platform- and/or Interface-Specific New Features @@ -183,3 +200,12 @@ unix hints: consolidate all the bsd flavours into a single sys/unix/bsd.500 hints file to ease maintenance going forward; use bsd make conditional logic to carry out steps unique to NetBSD, OpenBSD, FreeBSD, GhostBSD +unix hints: the Makefiles distributed by sys/unix/setup.sh will now check + for the presence of a make.prefs at the top of the NetHack tree, + and will include it if it exists; make.prefs must contain valid + Makefile syntax and can be used to set preferences instead of + placing them on the make command line; Use GNU make syntax for GNU + make, and use bsd make syntax for bsd make +share a single copy of nhuuid generation code between Amiga, Atari, and msdos + by way of sys/share/pcmain.c (cherry-pick from pr #1541 by ingpaschke) + From d7726e606982b6ffd81ac0245aaa061accc51899 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 23 May 2026 20:03:30 -0400 Subject: [PATCH 365/702] follow-up grammar bit --- doc/fixes5-0-1.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index d47725199..5b1c1f376 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ $NHDT-Date: 1778535648 2026/05/11 21:40:48 $ +NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.20 $ $NHDT-Date: 1779581008 2026/05/24 00:03:28 $ General Fixes and Modified Features ----------------------------------- @@ -145,7 +145,7 @@ Windows: correct a NetHack 5.0.0 packaging error if visual studio was Windows: setting any map_mode option in the config file could trigger an app failure on launch by dereferencing a null pointer Windows: a Windows console debug line began showing up after the sources - switched NH_DEVEL_STATUS from NH_STATUS_RELEASED to + switched from NH_DEVEL_STATUS from NH_STATUS_RELEASED to NH_STATUS_POSTRELEASE; make it only show if (wizard) is true tty: allow custom glyph colors if they're basic 16 nethack colors on terminals with less than 256 colors From ff4abc9b8c4e4427cb992f39a835fef37182f5eb Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 23 May 2026 20:05:54 -0400 Subject: [PATCH 366/702] 3rd time is the charm3rd time is the charm3rd time is the charm --- doc/fixes5-0-1.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 5b1c1f376..b7c02e531 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -145,8 +145,8 @@ Windows: correct a NetHack 5.0.0 packaging error if visual studio was Windows: setting any map_mode option in the config file could trigger an app failure on launch by dereferencing a null pointer Windows: a Windows console debug line began showing up after the sources - switched from NH_DEVEL_STATUS from NH_STATUS_RELEASED to - NH_STATUS_POSTRELEASE; make it only show if (wizard) is true + switched patchlevel.h NH_DEVEL_STATUS from NH_STATUS_RELEASED to + NH_STATUS_POSTRELEASE; make it only ever show if (wizard) is true tty: allow custom glyph colors if they're basic 16 nethack colors on terminals with less than 256 colors From 4470ce348e7c89ff5944c16f3e37a3017d106ece Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Sun, 24 May 2026 02:28:06 +0200 Subject: [PATCH 367/702] lua: read coordxy fields with the right width (big-endian fix) Add ANY_INT16 to any_types and use it for u.ux/uy/tx/ty and uz dlevel/dnum. These are coordxy (int16_t) but the Lua bindings were treating them as 1-byte fields, so on big-endian m68k Lua read the high byte (0) instead of the actual value. Symptom: place_object off map <0,0> in the tutorial. --- include/wintype.h | 1 + src/nhlua.c | 16 ++++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/include/wintype.h b/include/wintype.h index 5d17e4147..08da476f8 100644 --- a/include/wintype.h +++ b/include/wintype.h @@ -58,6 +58,7 @@ enum any_types { ANY_STR, /* pointer to null-terminated char string */ ANY_NFUNC, /* pointer to function taking no args, returning int */ ANY_MASK32, /* 32-bit mask (stored as unsigned long) */ + ANY_INT16, /* xint16 / coordxy (16-bit signed) */ ANY_INVALID /* leave this last */ }; diff --git a/src/nhlua.c b/src/nhlua.c index 314e51f07..d4ec44cd9 100644 --- a/src/nhlua.c +++ b/src/nhlua.c @@ -1954,6 +1954,10 @@ nhl_push_anything(lua_State *L, int anytype, void *src) any.a_schar = *(schar *) src; lua_pushinteger(L, any.a_schar); break; + case ANY_INT16: + any.a_int = *(xint16 *) src; + lua_pushinteger(L, any.a_int); + break; } return 1; } @@ -1968,13 +1972,13 @@ nhl_meta_u_index(lua_State *L) void *ptr; int type; } ustruct[] = { - { "ux", &(u.ux), ANY_UCHAR }, - { "uy", &(u.uy), ANY_UCHAR }, + { "ux", &(u.ux), ANY_INT16 }, + { "uy", &(u.uy), ANY_INT16 }, { "dx", &(u.dx), ANY_SCHAR }, { "dy", &(u.dy), ANY_SCHAR }, { "dz", &(u.dz), ANY_SCHAR }, - { "tx", &(u.tx), ANY_UCHAR }, - { "ty", &(u.ty), ANY_UCHAR }, + { "tx", &(u.tx), ANY_INT16 }, + { "ty", &(u.ty), ANY_INT16 }, { "ulevel", &(u.ulevel), ANY_INT }, { "ulevelmax", &(u.ulevelmax), ANY_INT }, { "uhunger", &(u.uhunger), ANY_INT }, @@ -1985,8 +1989,8 @@ nhl_meta_u_index(lua_State *L) { "mh", &(u.mh), ANY_INT }, { "mhmax", &(u.mhmax), ANY_INT }, { "mtimedone", &(u.mtimedone), ANY_INT }, - { "dlevel", &(u.uz.dlevel), ANY_SCHAR }, /* actually coordxy */ - { "dnum", &(u.uz.dnum), ANY_SCHAR }, /* actually coordxy */ + { "dlevel", &(u.uz.dlevel), ANY_INT16 }, + { "dnum", &(u.uz.dnum), ANY_INT16 }, { "uluck", &(u.uluck), ANY_SCHAR }, { "uhp", &(u.uhp), ANY_INT }, { "uhpmax", &(u.uhpmax), ANY_INT }, From 26804768252b8bed235619a8d8051707f0e4f539 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 23 May 2026 21:37:56 -0400 Subject: [PATCH 368/702] fixes entry for the big-endian fix --- doc/fixes5-0-1.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index b7c02e531..0c3addb87 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -35,6 +35,11 @@ fix a buffer overflow in reroll processing that was introduced in a post-release 5.0.0 commit ensure a checkpoint, aka a save_currentstate() call, isn't done before the game is ready +add ANY_INT16 to any_types and use it for u.ux/uy/tx/ty and uz dlevel/dnum; + those are coordxy (int16_t) but the Lua bindings were treating them + as 1-byte fields, so on big-endian m68k Lua read the high byte (0) + instead of the actual value. Symptom: place_object off map <0,0> + in the tutorial. Platform- and/or Interface-Specific Fixes From 7025945d2a6dc4cae08c1a446ba3c2f474fcea4e Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 23 May 2026 22:50:12 -0400 Subject: [PATCH 369/702] Get CROSSCOMPILE defined earlier in the Makefiles --- sys/unix/hints/include/cross-pre1.500 | 1 + sys/unix/hints/include/cross-pre2.500 | 7 ------- sys/unix/hints/linux.500 | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/sys/unix/hints/include/cross-pre1.500 b/sys/unix/hints/include/cross-pre1.500 index 9c8c0a24c..1730f5af3 100644 --- a/sys/unix/hints/include/cross-pre1.500 +++ b/sys/unix/hints/include/cross-pre1.500 @@ -50,6 +50,7 @@ override TARGET_LIBS= endif ifdef CROSS +CROSSCOMPILE=1 override PREGAME= override BUILDMORE= override CLEANMORE= diff --git a/sys/unix/hints/include/cross-pre2.500 b/sys/unix/hints/include/cross-pre2.500 index ea5d31767..ef6f1c04f 100644 --- a/sys/unix/hints/include/cross-pre2.500 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -123,8 +123,6 @@ ifdef CROSS_TO_MSDOS #================================================================= CFLAGS += -DCROSSCOMPILE -#also set a make variable flagging this as a crosscompile -CROSSCOMPILE=1 # # Override the build tools and some obj files to @@ -277,7 +275,6 @@ ifdef CROSS_TO_WASM # originally from https://github.com/NetHack/NetHack/pull/385 #===============-================================================= #also set a make variable flagging this as a crosscompile -CROSSCOMPILE=1 # #WASM_DEBUG = 1 WASM_DATA_DIR = $(TARGETPFX)wasm-data @@ -414,8 +411,6 @@ ifdef CROSS_TO_MIPS #================================================================= CFLAGS += -DCROSSCOMPILE -#also set a make variable flagging this as a crosscompile -CROSSCOMPILE=1 # # Override the build tools and some obj files to @@ -492,8 +487,6 @@ ifdef CROSS_TO_AMIGA #================================================================= CFLAGS += -DCROSSCOMPILE -#also set a make variable flagging this as a crosscompile -CROSSCOMPILE=1 # # Override the build tools and some obj files to diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index 1bb35460d..776d74529 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -384,7 +384,7 @@ ifdef WANT_WIN_X11 USE_XPM=1 WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm -GENTILEOFILE = $(SRCDIR)/tile.o +GENTILEOFILE = $(TARGETPFX)tile.o # -x: if built without dlb, some versions of mkfontdir think *.lev are fonts POSTINSTALL += bdftopcf win/X11/nh10.bdf > $(HACKDIR)/nh10.pcf; ( cd $(HACKDIR); mkfontdir -x .lev ); # separate from CFLAGS so that we don't pass it to every file From 05371dd481e488d63354ada6b31734043044db64 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 24 May 2026 00:01:50 -0400 Subject: [PATCH 370/702] some tipping fixes - adjust the surface name in prompts (resolves a TODO in the code). - be more player-friendly with the prompting, and don't prompt a second time if the floor/surface is the only tip-destination, as that can be annoyng and viewed as unnecessary. Instead, include that information in the first decision prompt. Resolves #1537 --- src/pickup.c | 158 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 102 insertions(+), 56 deletions(-) diff --git a/src/pickup.c b/src/pickup.c index 0ca9dca13..7424f109e 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -42,7 +42,7 @@ staticfn int traditional_loot(boolean); staticfn int menu_loot(int, boolean); staticfn int tip_ok(struct obj *); staticfn int choose_tip_container_menu(void); -staticfn struct obj *tipcontainer_gettarget(struct obj *, boolean *); +staticfn struct obj *tipcontainer_gettarget(struct obj *, boolean *, int *); staticfn int tipcontainer_checks(struct obj *, struct obj *, boolean); staticfn char in_or_out_menu(const char *, struct obj *, boolean, boolean, boolean, boolean); @@ -3607,10 +3607,25 @@ dotip(void) } else { for (cobj = svl.level.objects[cc.x][cc.y]; cobj; cobj = nobj) { + int target_count = 0; + boolean dum; /* argument placeholder, not actually used */ + char prompt_part2[BUFSZ]; + nobj = cobj->nexthere; if (!Is_container(cobj)) continue; - c = ynq(safe_qbuf(qbuf, "There is ", " here, tip it?", + /* + * Calling tipcontainer_gettarget with a non-zero int ptr + * as the 3rd argument just obtains the count of elligible + * tip targets. No menu is displayed and no tip-target pick + * is carried out. + */ + (void) tipcontainer_gettarget(cobj, &dum, &target_count); + Sprintf(prompt_part2, " here, tip it%s%s?", + (target_count == 0) ? " onto the " : "", + (target_count == 0) ? surface(cobj->ox, cobj->oy) + : ""); + c = ynq(safe_qbuf(qbuf, "There is ", prompt_part2, cobj, doname, ansimpleoname, "container")); if (c == 'q') @@ -3709,7 +3724,7 @@ tipcontainer(struct obj *box) /* or bag */ * if 'box' is known to be empty or known to be locked, give up * before choosing 'targetbox'. */ - targetbox = tipcontainer_gettarget(box, &cancelled); + targetbox = tipcontainer_gettarget(box, &cancelled, (int *) 0); if (cancelled) return; @@ -3876,16 +3891,17 @@ count_target_containers( staticfn struct obj * tipcontainer_gettarget( struct obj *box, - boolean *cancelled) + boolean *cancelled, + int *only_count_targets) { - int n, n_conts, tmpglyph; + int n, n_conts = 0, tmpglyph, looppass, count_tiptargets = 0; glyph_info tmpglyphinfo; - winid win; + winid win = WIN_ERR; anything any; - char buf[BUFSZ]; + char buf[BUFSZ], on_the_surface[BUFSZ]; menu_item *pick_list = (menu_item *) 0; struct obj dummyobj, *otmp; - boolean hands_available = TRUE, exclude_it; + boolean hands_available = TRUE, exclude_it, skip_targetmenu = FALSE; int clr = NO_COLOR; #if 0 /* [skip potential early return so that menu response is needed @@ -3899,58 +3915,88 @@ tipcontainer_gettarget( return (struct obj *) 0; } #endif + /* + * looppass 0 : count the elligible drop targets + * looppass 1 : if there are elligible tip targets, besides the floor, + * then build and present a menu of those targets, including + * the floor. + */ + for (looppass = 0; looppass < 2; looppass++) { + if (looppass == 1) { + if (only_count_targets) { + *only_count_targets = count_tiptargets; + skip_targetmenu = TRUE; + break; + } + if (count_tiptargets == 0) { + /* nothing but the floor */ + skip_targetmenu = TRUE; + break; + } + win = create_nhwindow(NHW_MENU); + start_menu(win, MENU_BEHAVE_STANDARD); - win = create_nhwindow(NHW_MENU); - start_menu(win, MENU_BEHAVE_STANDARD); + dummyobj = cg.zeroobj; /* lint suppression; only its address + matters */ + any = cg.zeroany; + any.a_obj = &dummyobj; + /* tip to floor does not require free hands */ + Sprintf(on_the_surface, "on the %s", surface(u.ux, u.uy)); + add_menu(win, &nul_glyphinfo, &any, '-', 0, ATR_NONE, clr, + on_the_surface, MENU_ITEMFLAGS_SELECTED); + add_menu_str(win, ""); - dummyobj = cg.zeroobj; /* lint suppression; only its address matters */ - any = cg.zeroany; - any.a_obj = &dummyobj; - /* tip to floor does not require free hands */ - add_menu(win, &nul_glyphinfo, &any, '-', 0, ATR_NONE, clr, - /* [TODO? vary destination string depending on surface()] */ - "on the floor", MENU_ITEMFLAGS_SELECTED); - add_menu_str(win, ""); - - n_conts = 0; - for (otmp = gi.invent; otmp; otmp = otmp->nobj) { - if (otmp == box) - continue; - /* skip non-containers; bag of tricks passes Is_container() test, - only include it if it isn't known to be a bag of tricks */ - if (!Is_container(otmp) - || (otmp->otyp == BAG_OF_TRICKS && otmp->dknown - && objects[otmp->otyp].oc_name_known)) - continue; - if (!n_conts++) - hands_available = u_handsy(); /* might issue message */ - /* container-to-container tip requires free hands; - exclude container as possible target when known to be locked */ - exclude_it = !hands_available || (otmp->olocked && otmp->lknown); - any = cg.zeroany; - any.a_obj = !exclude_it ? otmp : 0; - Sprintf(buf, "%s%s", !exclude_it ? "" : " ", doname(otmp)); - tmpglyph = obj_to_glyph(otmp, rn2_on_display_rng); - map_glyphinfo(0, 0, tmpglyph, 0U, &tmpglyphinfo); - add_menu(win, &tmpglyphinfo, &any, !exclude_it ? otmp->invlet : 0, 0, - ATR_NONE, clr, buf, MENU_ITEMFLAGS_NONE); + n_conts = 0; + } + for (otmp = gi.invent; otmp; otmp = otmp->nobj) { + if (otmp == box) + continue; + /* skip non-containers; bag of tricks passes Is_container() test, + only include it if it isn't known to be a bag of tricks */ + if (!Is_container(otmp) + || (otmp->otyp == BAG_OF_TRICKS && otmp->dknown + && objects[otmp->otyp].oc_name_known)) + continue; + if (!n_conts++) + hands_available = u_handsy(); /* might issue message */ + /* container-to-container tip requires free hands; + exclude container as possible target when known to be locked */ + exclude_it = !hands_available || (otmp->olocked && otmp->lknown); + if (looppass == 0) { + if (!exclude_it) + count_tiptargets++; + } else { + any = cg.zeroany; + any.a_obj = !exclude_it ? otmp : 0; + Sprintf(buf, "%s%s", !exclude_it ? "" : " ", doname(otmp)); + tmpglyph = obj_to_glyph(otmp, rn2_on_display_rng); + map_glyphinfo(0, 0, tmpglyph, 0U, &tmpglyphinfo); + add_menu(win, &tmpglyphinfo, &any, + !exclude_it ? otmp->invlet : 0, 0, ATR_NONE, clr, + buf, MENU_ITEMFLAGS_NONE); + } + } } + if (!skip_targetmenu) { + Sprintf(buf, "Where to tip the contents of %s", doname(box)); + end_menu(win, buf); + n = select_menu(win, PICK_ONE, &pick_list); + destroy_nhwindow(win); - Sprintf(buf, "Where to tip the contents of %s", doname(box)); - end_menu(win, buf); - n = select_menu(win, PICK_ONE, &pick_list); - destroy_nhwindow(win); - - otmp = 0; - if (pick_list) { - otmp = pick_list[0].item.a_obj; - /* PICK_ONE with a preselected item might return 2; - if so, choose the one that wasn't preselected */ - if (n > 1 && otmp == &dummyobj) - otmp = pick_list[1].item.a_obj; - if (otmp == &dummyobj) - otmp = 0; - free((genericptr_t) pick_list); + otmp = 0; + if (pick_list) { + otmp = pick_list[0].item.a_obj; + /* PICK_ONE with a preselected item might return 2; + if so, choose the one that wasn't preselected */ + if (n > 1 && otmp == &dummyobj) + otmp = pick_list[1].item.a_obj; + if (otmp == &dummyobj) + otmp = 0; + free((genericptr_t) pick_list); + } + } else { + otmp = 0; + n = 0; /* don't flag as having been cancelled */ } *cancelled = (boolean) (n == -1); return otmp; From c506c73fbeb601ca73a921a7dd0bfbd2046cf563 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 24 May 2026 00:21:40 -0400 Subject: [PATCH 371/702] X11 bit --- sys/unix/hints/linux.500 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index 776d74529..64f2bfed6 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -384,7 +384,9 @@ ifdef WANT_WIN_X11 USE_XPM=1 WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm -GENTILEOFILE = $(TARGETPFX)tile.o +ifndef CROSSCOMPILE +GENTILEOFILE = $(SRCDIR)/tile.o +endif # -x: if built without dlb, some versions of mkfontdir think *.lev are fonts POSTINSTALL += bdftopcf win/X11/nh10.bdf > $(HACKDIR)/nh10.pcf; ( cd $(HACKDIR); mkfontdir -x .lev ); # separate from CFLAGS so that we don't pass it to every file From c22b21e3bd0228e7d69cb03de42fb2d02be35e4c Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 24 May 2026 11:49:12 -0400 Subject: [PATCH 372/702] follow-up: spelling fix in comment --- src/pickup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pickup.c b/src/pickup.c index 7424f109e..5de4c3c98 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -3616,7 +3616,7 @@ dotip(void) continue; /* * Calling tipcontainer_gettarget with a non-zero int ptr - * as the 3rd argument just obtains the count of elligible + * as the 3rd argument just obtains the count of eligible * tip targets. No menu is displayed and no tip-target pick * is carried out. */ From 0a332657f17982f8b410649ecedd4b01ab3c6bc8 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 24 May 2026 12:40:24 -0400 Subject: [PATCH 373/702] methods of disabling glyphid cache prefill Two methods are now provided for slow ports/platforms that need to do this for performance reasons. Hopefully, this will avoid proliferation of more platform-specific conditional code within initoptions_init(). Method (1): #define DISABLE_GLYPHID_CACHE_PREFILL in platform/OS's include/*conf.h. or Method (2): set gd.disable_glyphid_cache_prefill = TRUE in startup code after decl_global_init(), and prior to initoptions_init(). It has to be done after decl_global_init() because decl_global_init() sets the value to its initialization default. --- include/decl.h | 1 + src/decl.c | 4 ++++ src/options.c | 5 +++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/decl.h b/include/decl.h index 70727a2bf..a58ae77d4 100644 --- a/include/decl.h +++ b/include/decl.h @@ -344,6 +344,7 @@ struct instance_globals_d { /* new */ boolean deferred_showpaths; char *deferred_showpaths_dir; + boolean disable_glyphid_cache_prefill; boolean havestate; }; diff --git a/src/decl.c b/src/decl.c index 4fe4585f0..02cfa5f2d 100644 --- a/src/decl.c +++ b/src/decl.c @@ -313,6 +313,7 @@ static const struct instance_globals_d g_init_d = { FALSE, /* decor_levitate_override */ FALSE, /* deferred_showpaths */ NULL, /* deferred_showpaths_dir */ + FALSE, /* disable_glyphid_cache_prefill */ TRUE, /* havestate*/ }; @@ -1184,6 +1185,9 @@ decl_globals_init(void) gu.urole = urole_init_data; gu.urace = urace_init_data; +#ifdef DISABLE_GLYPHID_CACHE_PREFILL + gd.disable_glyphid_cache_prefill = TRUE; +#endif } /* fields in 'hands_obj' don't matter, just its distinct address */ diff --git a/src/options.c b/src/options.c index 0bb1b4b29..80518ea66 100644 --- a/src/options.c +++ b/src/options.c @@ -7151,8 +7151,9 @@ initoptions_init(void) gc.cmdline_windowsys = NULL; } - /* make any symbol parsing quicker */ - if (!glyphid_cache_status()) + /* make any symbol parsing quicker, but only if + * gd.disable_glyphid_cache_prefill is not set to TRUE */ + if (!glyphid_cache_status() && !gd.disable_glyphid_cache_prefill) fill_glyphid_cache(); /* set up the command parsing */ From c1697c0042ebfc96ddc8e139ccb0950736b5a037 Mon Sep 17 00:00:00 2001 From: copperwater Date: Sun, 24 May 2026 15:30:46 -0400 Subject: [PATCH 374/702] Don't print "low buzzing" for bee-less trees when kicked Noticed this when testing a level with some barren trees which were set in the special level to not contain bees; the barren trees are still able to produce a low buzzing. This may convince players that they can get bees from the tree if only they kick it enough times, which will not happen. To avoid that, only print this message when the tree can release bees, augmenting the existing check for killer bees being non-extinct. --- src/dokick.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dokick.c b/src/dokick.c index a399aca03..45cc67798 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -1137,7 +1137,9 @@ kick_nondoor(coordxy x, coordxy y, int avrg_attrib) /* nothing, fruit or trouble? 75:23.5:1.5% */ if (rn2(3)) { - if (!rn2(6) && !(svm.mvitals[PM_KILLER_BEE].mvflags & G_GONE)) + if (!rn2(6) + && !(svm.mvitals[PM_KILLER_BEE].mvflags & G_GONE) + && !(gm.maploc->looted & TREE_SWARM)) You_hear("a low buzzing."); /* a warning */ kick_ouch(x, y, ""); return ECMD_TIME; From 7a38d29363888e1071a2b5eb25b2f13ee52f54f6 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 24 May 2026 18:30:46 -0400 Subject: [PATCH 375/702] nomenclature: glyphids glyphids shall be known as glyphnames henceforth glyphid_cache shall be known as glyphname_hashtable --- doc/Guidebook.mn | 6 +- doc/Guidebook.tex | 6 +- include/decl.h | 2 +- include/extern.h | 12 ++-- src/decl.c | 4 +- src/earlyarg.c | 8 +-- src/glyphs.c | 168 +++++++++++++++++++++++----------------------- src/options.c | 18 ++--- src/save.c | 4 +- src/symbols.c | 8 +-- src/wizcmds.c | 10 +-- 11 files changed, 123 insertions(+), 123 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 72401328e..f6ef0a4be 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -6170,10 +6170,10 @@ U+224B and the color represented by R-G-B value 0-0-160: OPTIONS=glyph:G_pool/U+224B/0-0-160 .ft .ED -The list of acceptable glyphid's can be produced by -\fBnethack \-\-dumpglyphids\fP. +The list of acceptable glyphnames can be produced by +\fBnethack \-\-dumpglyphnames\fP. Individual NetHack glyphs can be specified using the G_ prefix, -or you can use an S_ symbol for a glyphid and store the custom +or you can use an S_ symbol for a glyphname and store the custom representation for all NetHack glyphs that would map to that particular symbol. .pg diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 3df3d7d71..bd38f183d 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -6769,12 +6769,12 @@ U+224B and the color represented by R-G-B value 0-0-160:\\ OPTIONS=glyph:G_pool/U+224B/0-0-160 \end{verbatim} -The list of acceptable glyphid's can be produced by +The list of acceptable glyphnames can be produced by \begin{verbatim} - nethack --glyphids + nethack --dumpglyphnames \end{verbatim} Individual NetHack glyphs can be specified using the G\textunderscore prefix, -or you can use an S\textunderscore symbol for a glyphid and store the custom +or you can use an S\textunderscore symbol for a glyphname and store the custom representation for all NetHack glyphs that would map to that particular symbol. diff --git a/include/decl.h b/include/decl.h index a58ae77d4..4eca88060 100644 --- a/include/decl.h +++ b/include/decl.h @@ -344,7 +344,7 @@ struct instance_globals_d { /* new */ boolean deferred_showpaths; char *deferred_showpaths_dir; - boolean disable_glyphid_cache_prefill; + boolean disable_glyphname_hashtable_prefill; boolean havestate; }; diff --git a/include/extern.h b/include/extern.h index f633348ed..93a4083a2 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1183,16 +1183,16 @@ int set_map_customcolor(glyph_map *gm, uint32 nhcolor) NONNULLARG1; extern int unicode_val(const char *); extern int glyphrep(const char *) NONNULLARG1; extern int match_glyph(char *) NONNULLARG1; -extern void dump_all_glyphids(FILE *fp) NONNULLARG1; -extern void wizcustom_glyphids(winid win); -extern void fill_glyphid_cache(void); -extern void free_glyphid_cache(void); -extern boolean glyphid_cache_status(void); +extern void dump_all_glyphnames(FILE *fp) NONNULLARG1; +extern void wizcustom_glyphnames(winid win); +extern void populate_glyphname_hashtable(void); +extern void empty_glyphname_hashtable(void); +extern boolean glyphname_hashtable_loaded(void); extern void apply_customizations(enum graphics_sets which_set, enum do_customizations docustomize); extern void purge_custom_entries(enum graphics_sets which_set); extern void purge_all_custom_entries(void); -extern void dump_glyphids(void); +extern void dump_glyphnames(void); extern void clear_all_glyphmap_colors(void); extern void reset_customcolors(void); extern int glyph_to_cmap(int); diff --git a/src/decl.c b/src/decl.c index 02cfa5f2d..54110ab72 100644 --- a/src/decl.c +++ b/src/decl.c @@ -313,7 +313,7 @@ static const struct instance_globals_d g_init_d = { FALSE, /* decor_levitate_override */ FALSE, /* deferred_showpaths */ NULL, /* deferred_showpaths_dir */ - FALSE, /* disable_glyphid_cache_prefill */ + FALSE, /* disable_glyphname_hashtable_prefill */ TRUE, /* havestate*/ }; @@ -1186,7 +1186,7 @@ decl_globals_init(void) gu.urole = urole_init_data; gu.urace = urace_init_data; #ifdef DISABLE_GLYPHID_CACHE_PREFILL - gd.disable_glyphid_cache_prefill = TRUE; + gd.disable_glyphname_hashtable_prefill = TRUE; #endif } diff --git a/src/earlyarg.c b/src/earlyarg.c index e8009a57e..efdc9e8c1 100755 --- a/src/earlyarg.c +++ b/src/earlyarg.c @@ -40,7 +40,7 @@ static const struct early_opt earlyopts[] = { #ifndef NODUMPENUMS { ARG_DUMPENUMS, "dumpenums", 9, FALSE }, #endif - { ARG_DUMPGLYPHIDS, "dumpglyphids", 12, FALSE }, + { ARG_DUMPGLYPHIDS, "dumpglyphnames", 12, FALSE }, { ARG_DUMPMONGEN, "dumpmongen", 10, FALSE }, { ARG_DUMPWEIGHTS, "dumpweights", 11, FALSE }, #ifdef WIN32 @@ -530,7 +530,7 @@ argcheck(int argc, char *argv[], enum earlyarg e_arg) return 2; #endif case ARG_DUMPGLYPHIDS: - dump_glyphids(); + dump_glyphnames(); return 2; case ARG_DUMPMONGEN: dump_mongen(); @@ -803,9 +803,9 @@ dump_enums(void) #endif /* NODUMPENUMS */ void -dump_glyphids(void) +dump_glyphnames(void) { - dump_all_glyphids(stdout); + dump_all_glyphnames(stdout); } #endif /* !NODUMPENUMS */ diff --git a/src/glyphs.c b/src/glyphs.c index 53235659d..e38e1baa9 100644 --- a/src/glyphs.c +++ b/src/glyphs.c @@ -11,7 +11,7 @@ extern struct enum_dump objdump[]; #define Fprintf (void) fprintf -enum reserved_activities { res_nothing, res_dump_glyphids, res_fill_cache }; +enum reserved_activities { res_nothing, res_dump_glyphnames, res_fill_hashtable }; enum things_to_find { find_nothing, find_pm, find_oc, find_cmap, find_glyph }; struct find_struct { enum things_to_find findtype; @@ -26,20 +26,20 @@ struct find_struct { genericptr_t reserved; }; static const struct find_struct zero_find = { 0 }; -struct glyphid_cache_t { +struct glyphname_hashtable_entry_t { int glyphnum; char *id; }; -static struct glyphid_cache_t *glyphid_cache; -static unsigned glyphid_cache_lsize; -static size_t glyphid_cache_size; -static struct find_struct glyphcache_find, to_custom_symbol_find; +static struct glyphname_hashtable_entry_t *glyphname_hashtable_ptr; +static unsigned glyphname_hashtable_lsize; +static size_t glyphname_hashtable_size; +static struct find_struct glyphname_hashtable_find, to_custom_symbol_find; static const long nonzero_black = CLR_BLACK | NH_BASIC_COLOR; -staticfn void init_glyph_cache(void); -staticfn void add_glyph_to_cache(int glyphnum, const char *id); +staticfn void init_glyphname_hashtable(void); +staticfn void add_glyph_to_glyphname_hashtable(int glyphnum, const char *id); staticfn int find_glyph_in_cache(const char *id); -staticfn char *find_glyphid_in_cache_by_glyphnum(int glyphnum); +staticfn char *find_glyphname_in_hashtable_by_glyphnum(int glyphnum); staticfn uint32 glyph_hash(const char *id); staticfn void to_custom_symset_entry_callback(int glyph, struct find_struct *findwhat); @@ -114,18 +114,18 @@ glyphrep_to_custom_map_entries( int *glyphptr) { to_custom_symbol_find = zero_find; - char buf[BUFSZ], *c_glyphid, *c_unicode, *c_colorval, *cp; + char buf[BUFSZ], *c_glyphname, *c_unicode, *c_colorval, *cp; int reslt = 0; long rgb = 0L; boolean slash = FALSE, colon = FALSE; - if (!glyphid_cache) + if (!glyphname_hashtable_ptr) reslt = 1; /* for debugger use only; no cache available */ nhUse(reslt); Snprintf(buf, sizeof buf, "%s", op); c_unicode = c_colorval = (char *) 0; - c_glyphid = cp = buf; + c_glyphname = cp = buf; while (*cp) { if (*cp == ':' || *cp == '/') { if (*cp == ':') { @@ -148,8 +148,8 @@ glyphrep_to_custom_map_entries( } } /* some sanity checks */ - if (c_glyphid && *c_glyphid == ' ') - c_glyphid++; + if (c_glyphname && *c_glyphname == ' ') + c_glyphname++; if (c_colorval && *c_colorval == ' ') c_colorval++; if (c_unicode && *c_unicode == ' ') { @@ -176,7 +176,7 @@ glyphrep_to_custom_map_entries( to_custom_symbol_find.unicode_val = c_unicode; to_custom_symbol_find.extraval = glyphptr; to_custom_symbol_find.callback = to_custom_symset_entry_callback; - reslt = glyph_find_core(c_glyphid, &to_custom_symbol_find); + reslt = glyph_find_core(c_glyphname, &to_custom_symbol_find); return reslt; } @@ -300,22 +300,22 @@ glyph_find_core( void -fill_glyphid_cache(void) +populate_glyphname_hashtable(void) { int reslt = 0; - if (!glyphid_cache) { - init_glyph_cache(); + if (!glyphname_hashtable_ptr) { + init_glyphname_hashtable(); } - if (glyphid_cache) { - glyphcache_find = zero_find; - glyphcache_find.findtype = find_nothing; - glyphcache_find.reserved = (genericptr_t) glyphid_cache; - glyphcache_find.restype = res_fill_cache; - reslt = parse_id((char *) 0, &glyphcache_find); + if (glyphname_hashtable_ptr) { + glyphname_hashtable_find = zero_find; + glyphname_hashtable_find.findtype = find_nothing; + glyphname_hashtable_find.reserved = (genericptr_t) glyphname_hashtable_ptr; + glyphname_hashtable_find.restype = res_fill_hashtable; + reslt = parse_id((char *) 0, &glyphname_hashtable_find); if (!reslt) { - free_glyphid_cache(); - glyphid_cache = (struct glyphid_cache_t *) 0; + empty_glyphname_hashtable(); + glyphname_hashtable_ptr = (struct glyphname_hashtable_entry_t *) 0; } } } @@ -331,101 +331,101 @@ fill_glyphid_cache(void) */ staticfn void -init_glyph_cache(void) +init_glyphname_hashtable(void) { size_t glyph; /* Cache size of power of 2 not less than 2*MAX_GLYPH */ - glyphid_cache_lsize = 0; - glyphid_cache_size = 1; - while (glyphid_cache_size < 2*MAX_GLYPH) { - ++glyphid_cache_lsize; - glyphid_cache_size <<= 1; + glyphname_hashtable_lsize = 0; + glyphname_hashtable_size = 1; + while (glyphname_hashtable_size < 2*MAX_GLYPH) { + ++glyphname_hashtable_lsize; + glyphname_hashtable_size <<= 1; } - glyphid_cache = (struct glyphid_cache_t *) alloc( - glyphid_cache_size * sizeof (struct glyphid_cache_t)); - for (glyph = 0; glyph < glyphid_cache_size; ++glyph) { - glyphid_cache[glyph].glyphnum = 0; - glyphid_cache[glyph].id = (char *) 0; + glyphname_hashtable_ptr = (struct glyphname_hashtable_entry_t *) alloc( + glyphname_hashtable_size * sizeof (struct glyphname_hashtable_entry_t)); + for (glyph = 0; glyph < glyphname_hashtable_size; ++glyph) { + glyphname_hashtable_ptr[glyph].glyphnum = 0; + glyphname_hashtable_ptr[glyph].id = (char *) 0; } } void -free_glyphid_cache(void) +empty_glyphname_hashtable(void) { size_t idx; - if (!glyphid_cache) + if (!glyphname_hashtable_ptr) return; - for (idx = 0; idx < glyphid_cache_size; ++idx) { - if (glyphid_cache[idx].id) { - free(glyphid_cache[idx].id); - glyphid_cache[idx].id = (char *) 0; + for (idx = 0; idx < glyphname_hashtable_size; ++idx) { + if (glyphname_hashtable_ptr[idx].id) { + free(glyphname_hashtable_ptr[idx].id); + glyphname_hashtable_ptr[idx].id = (char *) 0; } } - free(glyphid_cache); - glyphid_cache = (struct glyphid_cache_t *) 0; + free(glyphname_hashtable_ptr); + glyphname_hashtable_ptr = (struct glyphname_hashtable_entry_t *) 0; } staticfn void -add_glyph_to_cache(int glyphnum, const char *id) +add_glyph_to_glyphname_hashtable(int glyphnum, const char *id) { uint32 hash = glyph_hash(id); - size_t hash1 = (size_t) (hash & (glyphid_cache_size - 1)); + size_t hash1 = (size_t) (hash & (glyphname_hashtable_size - 1)); size_t hash2 = (size_t) - (((hash >> glyphid_cache_lsize) & (glyphid_cache_size - 1)) | 1); + (((hash >> glyphname_hashtable_lsize) & (glyphname_hashtable_size - 1)) | 1); size_t i = hash1; do { - if (glyphid_cache[i].id == NULL) { + if (glyphname_hashtable_ptr[i].id == NULL) { /* Empty bucket found */ - glyphid_cache[i].id = dupstr(id); - glyphid_cache[i].glyphnum = glyphnum; + glyphname_hashtable_ptr[i].id = dupstr(id); + glyphname_hashtable_ptr[i].glyphnum = glyphnum; return; } /* For speed, assume that no ID occurs twice */ - i = (i + hash2) & (glyphid_cache_size - 1); + i = (i + hash2) & (glyphname_hashtable_size - 1); } while (i != hash1); /* This should never happen */ - panic("glyphid_cache full"); + panic("glyphname_hashtable_ptr full"); } staticfn int find_glyph_in_cache(const char *id) { uint32 hash = glyph_hash(id); - size_t hash1 = (size_t) (hash & (glyphid_cache_size - 1)); + size_t hash1 = (size_t) (hash & (glyphname_hashtable_size - 1)); size_t hash2 = (size_t) - (((hash >> glyphid_cache_lsize) & (glyphid_cache_size - 1)) | 1); + (((hash >> glyphname_hashtable_lsize) & (glyphname_hashtable_size - 1)) | 1); size_t i = hash1; do { - if (glyphid_cache[i].id == NULL) { + if (glyphname_hashtable_ptr[i].id == NULL) { /* Empty bucket found */ return -1; } - if (strcmpi(id, glyphid_cache[i].id) == 0) { + if (strcmpi(id, glyphname_hashtable_ptr[i].id) == 0) { /* Match found */ - return glyphid_cache[i].glyphnum; + return glyphname_hashtable_ptr[i].glyphnum; } - i = (i + hash2) & (glyphid_cache_size - 1); + i = (i + hash2) & (glyphname_hashtable_size - 1); } while (i != hash1); return -1; } staticfn char * -find_glyphid_in_cache_by_glyphnum(int glyphnum) +find_glyphname_in_hashtable_by_glyphnum(int glyphnum) { size_t idx; - if (!glyphid_cache) + if (!glyphname_hashtable_ptr) return (char *) 0; - for (idx = 0; idx < glyphid_cache_size; ++idx) { - if (glyphid_cache[idx].glyphnum == glyphnum - && glyphid_cache[idx].id != 0) { + for (idx = 0; idx < glyphname_hashtable_size; ++idx) { + if (glyphname_hashtable_ptr[idx].glyphnum == glyphnum + && glyphname_hashtable_ptr[idx].id != 0) { /* Match found */ - return glyphid_cache[idx].id; + return glyphname_hashtable_ptr[idx].id; } } return (char *) 0; @@ -449,9 +449,9 @@ glyph_hash(const char *id) } boolean -glyphid_cache_status(void) +glyphname_hashtable_loaded(void) { - return (glyphid_cache != 0); + return (glyphname_hashtable_ptr != 0); } int @@ -471,7 +471,7 @@ glyphrep(const char *op) { int reslt = 0, glyph = NO_GLYPH; - if (!glyphid_cache) + if (!glyphname_hashtable_ptr) reslt = 1; /* for debugger use only; no cache available */ nhUse(reslt); reslt = glyphrep_to_custom_map_entries(op, &glyph); @@ -794,26 +794,26 @@ purge_custom_entries(enum graphics_sets which_set) } void -dump_all_glyphids(FILE *fp) +dump_all_glyphnames(FILE *fp) { - struct find_struct dump_glyphid_find = zero_find; + struct find_struct dump_glyphname_find = zero_find; - dump_glyphid_find.findtype = find_nothing; - dump_glyphid_find.reserved = (genericptr_t) fp; - dump_glyphid_find.restype = res_dump_glyphids; - (void) parse_id((char *) 0, &dump_glyphid_find); + dump_glyphname_find.findtype = find_nothing; + dump_glyphname_find.reserved = (genericptr_t) fp; + dump_glyphname_find.restype = res_dump_glyphnames; + (void) parse_id((char *) 0, &dump_glyphname_find); } void -wizcustom_glyphids(winid win) +wizcustom_glyphnames(winid win) { int glyphnum; char *id; - if (!glyphid_cache) + if (!glyphname_hashtable_ptr) return; for (glyphnum = 0; glyphnum < MAX_GLYPH; ++glyphnum) { - id = find_glyphid_in_cache_by_glyphnum(glyphnum); + id = find_glyphname_in_hashtable_by_glyphnum(glyphnum); if (id) { wizcustom_callback(win, glyphnum, id); } @@ -834,7 +834,7 @@ parse_id( char buf[4][QBUFSZ]; if (findwhat->findtype == find_nothing && findwhat->restype) { - if (findwhat->restype == res_dump_glyphids) { + if (findwhat->restype == res_dump_glyphnames) { if (findwhat->reserved) { fp = (FILE *) findwhat->reserved; dump_ids = TRUE; @@ -842,9 +842,9 @@ parse_id( return 0; } } - if (findwhat->restype == res_fill_cache) { + if (findwhat->restype == res_fill_hashtable) { if (findwhat->reserved - && findwhat->reserved == (genericptr_t) glyphid_cache) { + && findwhat->reserved == (genericptr_t) glyphname_hashtable_ptr) { filling_cache = TRUE; } else { return 0; @@ -855,7 +855,7 @@ parse_id( is_G = (id && id[0] == 'G' && id[1] == '_'); is_S = (id && id[0] == 'S' && id[1] == '_'); - if ((is_G && !glyphid_cache) || filling_cache || dump_ids || is_S) { + if ((is_G && !glyphname_hashtable_ptr) || filling_cache || dump_ids || is_S) { while (loadsyms[i].range) { if (!pm_offset && loadsyms[i].range == SYM_MON) pm_offset = i; @@ -873,7 +873,7 @@ parse_id( } } if (is_G || filling_cache || dump_ids) { - if (!filling_cache && id && glyphid_cache) { + if (!filling_cache && id && glyphname_hashtable_ptr) { int val = find_glyph_in_cache(id); if (val >= 0) { findwhat->findtype = find_glyph; @@ -1112,7 +1112,7 @@ parse_id( if (dump_ids) { Fprintf(fp, "(%04d) %s\n", glyph, buf[0]); } else if (filling_cache) { - add_glyph_to_cache(glyph, buf[0]); + add_glyph_to_glyphname_hashtable(glyph, buf[0]); } else if (id) { if (!strcmpi(id, buf[0])) { findwhat->findtype = find_glyph; @@ -1123,7 +1123,7 @@ parse_id( } } } - } /* not glyphid_cache */ + } /* not glyphname_hashtable_ptr */ } else if (is_S) { /* cmap entries */ for (i = 0; i < cmap_count; ++i) { diff --git a/src/options.c b/src/options.c index 80518ea66..2c8464294 100644 --- a/src/options.c +++ b/src/options.c @@ -4224,11 +4224,11 @@ optfn_symset( if (req == do_handler) { int reslt; - if (!glyphid_cache_status()) - fill_glyphid_cache(); + if (!glyphname_hashtable_loaded()) + populate_glyphname_hashtable(); reslt = handler_symset(optidx); - if (glyphid_cache_status()) - free_glyphid_cache(); + if (glyphname_hashtable_loaded()) + empty_glyphname_hashtable(); /* apply_customizations(gc.currentgraphics, (do_custom_colors | do_custom_symbols)); */ return reslt; @@ -7152,9 +7152,9 @@ initoptions_init(void) } /* make any symbol parsing quicker, but only if - * gd.disable_glyphid_cache_prefill is not set to TRUE */ - if (!glyphid_cache_status() && !gd.disable_glyphid_cache_prefill) - fill_glyphid_cache(); + * gd.disable_glyphname_hashtable_prefill is not set to TRUE */ + if (!glyphname_hashtable_loaded() && !gd.disable_glyphname_hashtable_prefill) + populate_glyphname_hashtable(); /* set up the command parsing */ reset_commands(TRUE); /* init */ @@ -7377,8 +7377,8 @@ initoptions_finish(void) iflags.wc_ascii_map = FALSE, iflags.wc_tiled_map = TRUE; #ifdef ENHANCED_SYMBOLS - if (glyphid_cache_status()) - free_glyphid_cache(); + if (glyphname_hashtable_loaded()) + empty_glyphname_hashtable(); apply_customizations(gc.currentgraphics, do_custom_symbols | do_custom_colors); #endif diff --git a/src/save.c b/src/save.c index 1d61ee751..f9ab60115 100644 --- a/src/save.c +++ b/src/save.c @@ -1175,8 +1175,8 @@ freedynamicdata(void) if (options_set_window_colors_flag) options_free_window_colors(); - if (glyphid_cache_status()) - free_glyphid_cache(); + if (glyphname_hashtable_loaded()) + empty_glyphname_hashtable(); if (tnhfp) { close_nhfile(tnhfp); diff --git a/src/symbols.c b/src/symbols.c index 428c354d4..edc3f26a6 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -1069,12 +1069,12 @@ do_symset(boolean rogueflag) if (gs.symset[which_set].name) { /* non-default symbols */ int ok; - if (!glyphid_cache_status()) { - fill_glyphid_cache(); + if (!glyphname_hashtable_loaded()) { + populate_glyphname_hashtable(); } ok = read_sym_file(which_set); - if (glyphid_cache_status()) { - free_glyphid_cache(); + if (glyphname_hashtable_loaded()) { + empty_glyphname_hashtable(); } if (ok) { ready_to_switch = TRUE; diff --git a/src/wizcmds.c b/src/wizcmds.c index db94384a3..3ff2ec3c7 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -1945,8 +1945,8 @@ wiz_custom(void) #endif menu_item *pick_list = (menu_item *) 0; - if (!glyphid_cache_status()) - fill_glyphid_cache(); + if (!glyphname_hashtable_loaded()) + populate_glyphname_hashtable(); win = create_nhwindow(NHW_MENU); start_menu(win, MENU_BEHAVE_STANDARD); @@ -1964,7 +1964,7 @@ wiz_custom(void) known_handling[gs.symset[PRIMARYSET].handling]); } Sprintf(buf, "%s", bufa); - wizcustom_glyphids(win); + wizcustom_glyphnames(win); end_menu(win, bufa); n = select_menu(win, PICK_NONE, &pick_list); destroy_nhwindow(win); @@ -1975,8 +1975,8 @@ wiz_custom(void) #endif if (n >= 1) free((genericptr_t) pick_list); - if (glyphid_cache_status()) - free_glyphid_cache(); + if (glyphname_hashtable_loaded()) + empty_glyphname_hashtable(); docrt(); } else pline(unavailcmd, ecname_from_fn(wiz_custom)); From 0e39c11be961fd254830741433f132ce47ce1738 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 24 May 2026 22:24:50 -0400 Subject: [PATCH 376/702] update --dumpenums Include the glyph_offsets from display.h --- src/earlyarg.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/src/earlyarg.c b/src/earlyarg.c index efdc9e8c1..3d360129f 100755 --- a/src/earlyarg.c +++ b/src/earlyarg.c @@ -709,6 +709,7 @@ dump_enums(void) monsters_enum, objects_enum, objects_misc_enum, + glyph_offsets_enum, defsym_cmap_enum, defsym_mon_syms_enum, defsym_mon_defchars_enum, @@ -720,6 +721,59 @@ dump_enums(void) NUM_ENUM_DUMPS }; +#define dump_go(go) { GLYPH_##go, #go } +static const struct enum_dump glyph_offsets_dump[] = { + dump_go(MON_OFF), + dump_go(MON_MALE_OFF), + dump_go(MON_FEM_OFF), + dump_go(PET_OFF), + dump_go(PET_MALE_OFF), + dump_go(PET_FEM_OFF), + dump_go(INVIS_OFF), + dump_go(DETECT_OFF), + dump_go(DETECT_MALE_OFF), + dump_go(DETECT_FEM_OFF), + dump_go(BODY_OFF), + dump_go(RIDDEN_OFF), + dump_go(RIDDEN_MALE_OFF), + dump_go(RIDDEN_FEM_OFF), + dump_go(OBJ_OFF), + dump_go(CMAP_OFF), + dump_go(CMAP_STONE_OFF), + dump_go(CMAP_MAIN_OFF), + dump_go(CMAP_MINES_OFF), + dump_go(CMAP_GEH_OFF), + dump_go(CMAP_KNOX_OFF), + dump_go(CMAP_SOKO_OFF), + dump_go(CMAP_A_OFF), + dump_go(ALTAR_OFF), + dump_go(CMAP_B_OFF), + dump_go(ZAP_OFF), + dump_go(CMAP_C_OFF), + dump_go(SWALLOW_OFF), + dump_go(EXPLODE_OFF), + dump_go(EXPLODE_DARK_OFF), + dump_go(EXPLODE_NOXIOUS_OFF), + dump_go(EXPLODE_MUDDY_OFF), + dump_go(EXPLODE_WET_OFF), + dump_go(EXPLODE_MAGICAL_OFF), + dump_go(EXPLODE_FIERY_OFF), + dump_go(EXPLODE_FROSTY_OFF), + dump_go(WARNING_OFF), + dump_go(STATUE_OFF), + dump_go(STATUE_MALE_OFF), + dump_go(STATUE_FEM_OFF), + dump_go(PILETOP_OFF), + dump_go(OBJ_PILETOP_OFF), + dump_go(BODY_PILETOP_OFF), + dump_go(STATUE_MALE_PILETOP_OFF), + dump_go(STATUE_FEM_PILETOP_OFF), + dump_go(UNEXPLORED_OFF), + dump_go(NOTHING_OFF), + { MAX_GLYPH, "MAX_GLYPH" } + }; +#undef dump_go + #define dump_om(om) { om, #om } static const struct enum_dump omdump[] = { dump_om(LAST_GENERIC), @@ -736,12 +790,13 @@ dump_enums(void) dump_om(LAST_GLASS_GEM), dump_om(NUM_REAL_GEMS), dump_om(NUM_GLASS_GEMS), - dump_om(MAX_GLYPH), + dump_om(MAXEXPCHARS), + dump_om(WARNCOUNT), }; #undef dump_om static const struct enum_dump *const ed[NUM_ENUM_DUMPS] = { - monsdump, objdump, omdump, + monsdump, objdump, omdump, glyph_offsets_dump, defsym_cmap_dump, defsym_mon_syms_dump, defsym_mon_defchars_dump, objclass_defchars_dump, @@ -761,6 +816,7 @@ dump_enums(void) { "monnums", "PM_", UNPREFIXED_COUNT, 0, SIZE(monsdump) }, { "objects_nums", "", 1, 0, SIZE(objdump) }, { "misc_object_nums", "", 1, 0, SIZE(omdump) }, + { "glyph_offsets", "GLYPH_", 1, 0, SIZE(glyph_offsets_dump) }, { "cmap_symbols", "", 1, 0, SIZE(defsym_cmap_dump) }, { "mon_syms", "", 1, 0, SIZE(defsym_mon_syms_dump) }, { "mon_defchars", "", 1, 1, SIZE(defsym_mon_defchars_dump) }, From 87a0bdf26c851f5da2a48279c0d647e25dde5e2b Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 25 May 2026 17:06:24 +0200 Subject: [PATCH 377/702] display: fix off-by-one in glyph_is_normal_piletop_obj glyph_is_normal_object includes its boundary slot GLYPH_OBJ_OFF + FIRST_OBJECT - 1 via >=, but its piletop sibling glyph_is_normal_piletop_obj used > and excluded the matching GLYPH_OBJ_PILETOP_OFF + FIRST_OBJECT - 1 slot. That leaves exactly one glyph (the would-be G_piletop_generic_venom) matching neither the piletop-generic nor the piletop-normal predicate, so parse_id never builds a name for it and --dumpglyphnames emits a blank line for the slot. Change > to >= so the two ranges are inclusive on the same side. --dumpglyphnames now produces (8009) G_piletop_generic_venom. --- include/display.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/display.h b/include/display.h index a48883342..0518a6a2b 100644 --- a/include/display.h +++ b/include/display.h @@ -846,7 +846,7 @@ enum glyph_offsets { || glyph_is_piletop_generic_obj(glyph)) #define glyph_is_normal_piletop_obj(glyph) \ ((glyph) == GLYPH_OBJ_PILETOP_OFF \ - || ((glyph) > GLYPH_OBJ_PILETOP_OFF + FIRST_OBJECT - 1 \ + || ((glyph) >= GLYPH_OBJ_PILETOP_OFF + FIRST_OBJECT - 1 \ && (glyph) < (GLYPH_OBJ_PILETOP_OFF + NUM_OBJECTS))) #define glyph_is_normal_object(glyph) \ ((glyph) == GLYPH_OBJ_OFF \ From 752af5b4351bb604518523a55665565e304ec62c Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 25 May 2026 12:19:47 -0400 Subject: [PATCH 378/702] add fixes5-0-1.txt entry for pr #1547 fix off-by-one in glyph_is_normal_piletop_obj --- doc/fixes5-0-1.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 0c3addb87..b2d139880 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -40,6 +40,7 @@ add ANY_INT16 to any_types and use it for u.ux/uy/tx/ty and uz dlevel/dnum; as 1-byte fields, so on big-endian m68k Lua read the high byte (0) instead of the actual value. Symptom: place_object off map <0,0> in the tutorial. +fix an off-by-one in glyph_is_normal_piletop_obj (pr #1547 by ingpaschke) Platform- and/or Interface-Specific Fixes From b7c7f051b4259ba3cd180a32f8880f6073f9bd2c Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 25 May 2026 13:49:44 -0400 Subject: [PATCH 379/702] update Guidebook to refer to glyphname --- doc/Guidebook.mn | 6 +++--- doc/Guidebook.tex | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index f6ef0a4be..d90b4c4fd 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -60,7 +60,7 @@ .ds f0 \*(vr .ds f1 \" empty .\"DO NOT REMOVE NH_DATESUB .ds f2 Date(%B %-d, %Y) -.ds f2 May 11, 2026 +.ds f2 May 25, 2026 . .\" A note on some special characters: .\" \(lq = left double quote @@ -6155,7 +6155,7 @@ individually within your nethack.rc file. The format for defining a glyph representation is: .SD n .ft CR -OPTIONS=glyph:\fIglyphid\fP/\fIU+nnnn\fP/\fIR-G-B\fP +OPTIONS=glyph:\fIglyphname\fP/\fIU+nnnn\fP/\fIR-G-B\fP .ft .ED .pg @@ -6163,7 +6163,7 @@ The window port that is active needs to provide support for displaying UTF-8 character sequences and explicit red-green-blue colors in order for the glyph representation to be visible. For example, the following line in your configuration file will cause -the glyph representation for glyphid G_pool to use Unicode codepoint +the glyph representation for glyphname G_pool to use Unicode codepoint U+224B and the color represented by R-G-B value 0-0-160: .SD n .ft CR diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index bd38f183d..5ce42112e 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -25,7 +25,7 @@ \author{Original version - Eric S. Raymond\\ (Edited and expanded for 5.0.0 by Mike Stephenson and others)} %DO NOT REMOVE NH_DATESUB \date{Date(%B %-d, %Y)} -\date{May 11, 2026} +\date{May 25, 2026} \maketitle @@ -6755,7 +6755,7 @@ individually within your own nethack.rc file. The format for defining a glyph representation is:\\ \begin{verbatim} -OPTIONS=glyph:glyphid/U+nnnn/R-G-B +OPTIONS=glyph:glyphname/U+nnnn/R-G-B \end{verbatim} The window port that is active needs to provide support for displaying UTF-8 @@ -6763,7 +6763,7 @@ character sequences and explicit 24-bit red-green-blue colors in order for the g representation to be visible as specified. For example, the following line in your configuration file will cause -the glyph representation for glyphid G\textunderscore pool to use Unicode codepoint +the glyph representation for glyphname G\textunderscore pool to use Unicode codepoint U+224B and the color represented by R-G-B value 0-0-160:\\ \begin{verbatim} OPTIONS=glyph:G_pool/U+224B/0-0-160 From be9e430ebb936a9d315516eb551abfe5a704c48a Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 25 May 2026 19:23:21 +0200 Subject: [PATCH 380/702] glyphs: replace open-addressed glyphname hashtable with sorted index The open-addressed glyphname_hashtable stored each canonical "G_xxx" name as a dupstr'd string in its bucket: ~9577 small heap allocations and ~290 KB of resident name strings, on top of ~256 KB of 32768-bucket scaffolding kept at <50% load for probe performance. On classic Mac OS the populate cost (quadratic small-allocation in a fragmented Memory Manager heap) dominated startup time -- many seconds on an SE/30 -- and ~800 KB resident is meaningful on the small machines the port targets. Switch to a sorted (hash, glyph) index sized exactly to the number of named glyphs: struct glyphname_hashtable_entry_t { uint32 hash; int glyphnum; }; populate_glyphname_hashtable() allocates one block of MAX_GLYPH entries (no per-name strings), fills it via compose_glyph_name() + glyph_hash(), and qsort()s ascending by hash. Lookup binary-searches the hash column, then walks any equal-hash neighbours verifying each candidate by reconstructing its canonical name and strcmpi'ing it back -- collisions are rare with 9577 uniformly-distributed 32-bit hashes. Other changes that fall out: * Extract compose_glyph_name() from parse_id's bulk-iteration switch so it is the single source of truth for "glyph number -> canonical name". Called by find_glyph_in_hashtable for collision verification, by populate_glyphname_hashtable, by the --dumpglyphnames path, and by wizcustom_glyphnames. * empty_glyphname_hashtable() reduces to free(ptr); no per-entry strings to release. * Drop find_glyphname_in_hashtable_by_glyphnum (no longer used -- wizcustom_glyphnames iterates compose_glyph_name directly). * Drop the res_fill_hashtable parse_id mode; populate iterates directly. Memory drops from ~800 KB to ~75 KB. One allocation instead of ~9578. Lookup goes from O(1) to O(log N) but N ~ 9577 means ~14 comparisons per probe -- well under what the upstream cache ever cost in practice. Function names (populate_glyphname_hashtable, etc.) are kept for extern.h compatibility; the data structure is now a sorted index, "hashtable" in the names is historical. --dumpglyphnames output is byte-identical. --- src/glyphs.c | 734 +++++++++++++++++++++++---------------------------- 1 file changed, 333 insertions(+), 401 deletions(-) diff --git a/src/glyphs.c b/src/glyphs.c index e38e1baa9..6132844e8 100644 --- a/src/glyphs.c +++ b/src/glyphs.c @@ -11,7 +11,7 @@ extern struct enum_dump objdump[]; #define Fprintf (void) fprintf -enum reserved_activities { res_nothing, res_dump_glyphnames, res_fill_hashtable }; +enum reserved_activities { res_nothing, res_dump_glyphnames }; enum things_to_find { find_nothing, find_pm, find_oc, find_cmap, find_glyph }; struct find_struct { enum things_to_find findtype; @@ -27,20 +27,18 @@ struct find_struct { }; static const struct find_struct zero_find = { 0 }; struct glyphname_hashtable_entry_t { - int glyphnum; - char *id; + uint32 hash; + int glyphnum; /* NO_GLYPH (==MAX_GLYPH) marks an empty bucket */ }; static struct glyphname_hashtable_entry_t *glyphname_hashtable_ptr; -static unsigned glyphname_hashtable_lsize; -static size_t glyphname_hashtable_size; -static struct find_struct glyphname_hashtable_find, to_custom_symbol_find; +static size_t glyphname_hashtable_count; +static struct find_struct to_custom_symbol_find; static const long nonzero_black = CLR_BLACK | NH_BASIC_COLOR; -staticfn void init_glyphname_hashtable(void); -staticfn void add_glyph_to_glyphname_hashtable(int glyphnum, const char *id); -staticfn int find_glyph_in_cache(const char *id); -staticfn char *find_glyphname_in_hashtable_by_glyphnum(int glyphnum); +staticfn int find_glyph_in_hashtable(const char *id); +staticfn int cmp_glyphname_entry(const void *a, const void *b); staticfn uint32 glyph_hash(const char *id); +staticfn int compose_glyph_name(int glyph, char *buf, size_t bufsz); staticfn void to_custom_symset_entry_callback(int glyph, struct find_struct *findwhat); staticfn int parse_id(const char *id, struct find_struct *findwhat); @@ -196,6 +194,239 @@ fix_glyphname(char *str) return str; } +/* Build the canonical "G_xxx" identifier for the given glyph into buf. + * Returns 1 if a name was produced, 0 if this glyph has no canonical name + * (a few unused object indices); buf[0] is set to '\0' in that case. + * Used by parse_id's bulk-iteration paths, by find_glyph_in_hashtable to + * verify hash matches, by populate_glyphname_hashtable to fill the table, + * and by wizcustom_glyphnames. */ +staticfn int +compose_glyph_name(int glyph, char *buf, size_t bufsz) +{ + int i, j, mnum, cmap_offset = 0; + boolean skip_base = FALSE; + const char *buf2, *buf3, *buf4; + char tmpbuf[4][QBUFSZ]; + + if (bufsz < 2) + return 0; + buf[0] = '\0'; + tmpbuf[0][0] = tmpbuf[1][0] = tmpbuf[2][0] = tmpbuf[3][0] = '\0'; + + /* compute cmap_offset (the start of SYM_PCHAR entries in loadsyms[]) */ + i = 0; + while (loadsyms[i].range) { + if (!cmap_offset && loadsyms[i].range == SYM_PCHAR) + cmap_offset = i; + i++; + } + + if (glyph_is_monster(glyph)) { + buf2 = ""; + buf3 = monsdump[glyph_to_mon(glyph)].nm; + if (glyph_is_normal_male_monster(glyph)) { + buf2 = "male_"; + } else if (glyph_is_normal_female_monster(glyph)) { + buf2 = "female_"; + } else if (glyph_is_ridden_male_monster(glyph)) { + buf2 = "ridden_male_"; + } else if (glyph_is_ridden_female_monster(glyph)) { + buf2 = "ridden_female_"; + } else if (glyph_is_detected_male_monster(glyph)) { + buf2 = "detected_male_"; + } else if (glyph_is_detected_female_monster(glyph)) { + buf2 = "detected_female_"; + } else if (glyph_is_male_pet(glyph)) { + buf2 = "pet_male_"; + } else if (glyph_is_female_pet(glyph)) { + buf2 = "pet_female_"; + } + Strcpy(buf, "G_"); + Strcat(buf, buf2); + Strcat(buf, buf3); + } else if (glyph_is_body(glyph)) { + buf2 = glyph_is_body_piletop(glyph) ? "piletop_body_" : "body_"; + buf3 = monsdump[glyph_to_body_corpsenm(glyph)].nm; + Strcpy(buf, "G_"); + Strcat(buf, buf2); + Strcat(buf, buf3); + } else if (glyph_is_statue(glyph)) { + buf2 = glyph_is_fem_statue_piletop(glyph) + ? "piletop_statue_of_female_" + : glyph_is_fem_statue(glyph) + ? "statue_of_female_" + : glyph_is_male_statue_piletop(glyph) + ? "piletop_statue_of_male_" + : glyph_is_male_statue(glyph) + ? "statue_of_male_" + : ""; + buf3 = monsdump[glyph_to_statue_corpsenm(glyph)].nm; + Strcpy(buf, "G_"); + Strcat(buf, buf2); + Strcat(buf, buf3); + } else if (glyph_is_object(glyph)) { + i = glyph_to_obj(glyph); + if (((i > SCR_STINKING_CLOUD) && (i < SCR_MAIL)) + || ((i > WAN_LIGHTNING) && (i < GOLD_PIECE))) { + return 0; + } + if ((i >= WAN_LIGHT) && (i <= WAN_LIGHTNING)) + buf2 = "wand of "; + else if ((i >= SPE_DIG) && (i < SPE_BLANK_PAPER)) + buf2 = "spellbook of "; + else if ((i >= SCR_ENCHANT_ARMOR) && (i <= SCR_STINKING_CLOUD)) + buf2 = "scroll of "; + else if ((i >= POT_GAIN_ABILITY) && (i <= POT_WATER)) + buf2 = (i == POT_WATER) ? "flask of n" : "potion of "; + else if ((i >= RIN_ADORNMENT) && (i <= RIN_PROTECTION_FROM_SHAPE_CHAN)) + buf2 = "ring of "; + else if (i == LAND_MINE) + buf2 = "unset "; + else + buf2 = ""; + buf3 = (i == SCR_BLANK_PAPER) ? "blank scroll" + : (i == SPE_BLANK_PAPER) ? "blank spellbook" + : (i == SLIME_MOLD) ? "slime mold" + : obj_descr[i].oc_name + ? obj_descr[i].oc_name + : obj_descr[i].oc_descr; + Strcpy(buf, "G_"); + if (glyph_is_normal_piletop_obj(glyph)) + Strcat(buf, "piletop_"); + Strcat(buf, buf2); + Strcat(buf, buf3); + } else if (glyph_is_cmap(glyph) || glyph_is_cmap_zap(glyph) + || glyph_is_swallow(glyph) || glyph_is_explosion(glyph)) { + int cmap = -1; + + buf2 = ""; + buf3 = ""; + buf4 = ""; + if (glyph == GLYPH_CMAP_OFF) { + cmap = S_stone; + buf3 = "stone substrate"; + skip_base = TRUE; + } else if (glyph_is_cmap_gehennom(glyph)) { + cmap = (glyph - GLYPH_CMAP_GEH_OFF) + S_vwall; + buf4 = "_gehennom"; + } else if (glyph_is_cmap_knox(glyph)) { + cmap = (glyph - GLYPH_CMAP_KNOX_OFF) + S_vwall; + buf4 = "_knox"; + } else if (glyph_is_cmap_main(glyph)) { + cmap = (glyph - GLYPH_CMAP_MAIN_OFF) + S_vwall; + buf4 = "_main"; + } else if (glyph_is_cmap_mines(glyph)) { + cmap = (glyph - GLYPH_CMAP_MINES_OFF) + S_vwall; + buf4 = "_mines"; + } else if (glyph_is_cmap_sokoban(glyph)) { + cmap = (glyph - GLYPH_CMAP_SOKO_OFF) + S_vwall; + buf4 = "_sokoban"; + } else if (glyph_is_cmap_a(glyph)) { + cmap = (glyph - GLYPH_CMAP_A_OFF) + S_ndoor; + } else if (glyph_is_cmap_altar(glyph)) { + static const char *const altar_text[] = { + "unaligned", "chaotic", "neutral", + "lawful", "other", + }; + + j = (glyph - GLYPH_ALTAR_OFF); + cmap = S_altar; + if (j != altar_other) { + Snprintf(tmpbuf[2], sizeof tmpbuf[2], "%s_", altar_text[j]); + buf2 = tmpbuf[2]; + } else { + buf3 = "altar other"; + skip_base = TRUE; + } + } else if (glyph_is_cmap_b(glyph)) { + cmap = (glyph - GLYPH_CMAP_B_OFF) + S_grave; + } else if (glyph_is_cmap_zap(glyph)) { + static const char *const zap_texts[] = { + "missile", "fire", "frost", "sleep", + "death", "lightning", "poison gas", "acid" + }; + + j = (glyph - GLYPH_ZAP_OFF); + cmap = (j % 4) + S_vbeam; + Snprintf(tmpbuf[2], sizeof tmpbuf[2], "%s", + loadsyms[cmap + cmap_offset].name + 2); + Snprintf(tmpbuf[3], sizeof tmpbuf[3], "%s zap %s", + zap_texts[j / 4], fix_glyphname(tmpbuf[2])); + buf3 = tmpbuf[3]; + buf2 = ""; + skip_base = TRUE; + } else if (glyph_is_cmap_c(glyph)) { + cmap = (glyph - GLYPH_CMAP_C_OFF) + S_digbeam; + } else if (glyph_is_swallow(glyph)) { + static const char *const swallow_texts[] = { + "top left", "top center", "top right", + "middle left", "middle right", "bottom left", + "bottom center", "bottom right", + }; + + j = glyph - GLYPH_SWALLOW_OFF; + cmap = glyph_to_swallow(glyph); + mnum = j / ((S_sw_br - S_sw_tl) + 1); + Strcpy(tmpbuf[3], "swallow "); + Strcat(tmpbuf[3], monsdump[mnum].nm); + Strcat(tmpbuf[3], " "); + Strcat(tmpbuf[3], swallow_texts[cmap]); + buf3 = tmpbuf[3]; + skip_base = TRUE; + } else if (glyph_is_explosion(glyph)) { + static const char *const expl_type_texts[] = { + "dark", "noxious", "muddy", "wet", + "magical", "fiery", "frosty", + }; + static const char *const expl_texts[] = { + "tl", "tc", "tr", "ml", "mc", + "mr", "bl", "bc", "br", + }; + int expl; + + j = glyph - GLYPH_EXPLODE_OFF; + expl = j / ((S_expl_br - S_expl_tl) + 1); + cmap = glyph_to_explosion(glyph) + S_expl_tl; + i = cmap - S_expl_tl; + Snprintf(tmpbuf[2], sizeof tmpbuf[2], "%s ", + expl_type_texts[expl]); + buf2 = tmpbuf[2]; + Snprintf(tmpbuf[3], sizeof tmpbuf[3], "%s%s", "expl_", + expl_texts[i]); + buf3 = tmpbuf[3]; + skip_base = TRUE; + } + if (!skip_base) { + if (cmap >= 0 && cmap < MAXPCHARS) + buf3 = loadsyms[cmap + cmap_offset].name + 2; + } + Strcpy(buf, "G_"); + Strcat(buf, buf2); + Strcat(buf, buf3); + Strcat(buf, buf4); + } else if (glyph_is_invisible(glyph)) { + Strcpy(buf, "G_invisible"); + } else if (glyph_is_nothing(glyph)) { + Strcpy(buf, "G_nothing"); + } else if (glyph_is_unexplored(glyph)) { + Strcpy(buf, "G_unexplored"); + } else if (glyph_is_warning(glyph)) { + j = glyph - GLYPH_WARNING_OFF; + Snprintf(buf, bufsz, "G_%s%d", "warning", j); + } + + if (buf[0] == '\0') + return 0; + if (memchr(buf, '\0', bufsz) == NULL) { + /* defensive: caller passed an undersized buffer */ + buf[bufsz - 1] = '\0'; + return 0; + } + fix_glyphname(buf + 2); + nhUse(mnum); + return 1; +} + int glyph_to_cmap(int glyph) { @@ -283,152 +514,96 @@ glyph_find_core( } /* - When we start to process a config file or a symbol file, - that might have G_ entries, generating all 9000+ glyphid - for comparison repeatedly each time we encounter a G_ - entry to decipher, then comparing against them, is obviously - extremely performance-poor. + * glyphname_hashtable is a sorted (hash, glyph) index of canonical + * "G_xxx" identifiers. populate_glyphname_hashtable() allocates one + * block of MAX_GLYPH * sizeof(entry) (some entries go unused for the + * scroll/gem appearance gaps), fills it via compose_glyph_name(), and + * sorts ascending by hash. Lookup is bsearch on the hash with + * compose_glyph_name()+strcmpi to disambiguate the rare collision. + * + * The name "hashtable" is historical; this is a sorted array, not an + * open-addressed hash table. The on-disk API in extern.h is kept so + * that callers (wizcmds.c, options.c) don't need to change. + * + * Memory: one alloc, ~75 KB for the 9577 named slots on a typical 5.0 + * build (struct is 8 bytes, no per-name strings). The same data in + * upstream's open-addressed table cost ~256 KB for the buckets plus + * ~290 KB of dupstr'd names plus malloc overhead. + */ - Setting aside the "comparison" part for now (that has to be - done in some manner), we can likely do something about the - repeated "generation" of the names for parsing prior to the - actual comparison part by generating them once, ahead of the - bulk of the potential parsings. We can later free up - all the memory those names consumed once the bulk parsing is - over with. -*/ +staticfn int +cmp_glyphname_entry(const void *a, const void *b) +{ + uint32 ha = ((const struct glyphname_hashtable_entry_t *) a)->hash; + uint32 hb = ((const struct glyphname_hashtable_entry_t *) b)->hash; + if (ha < hb) + return -1; + if (ha > hb) + return 1; + return 0; +} void populate_glyphname_hashtable(void) { - int reslt = 0; + int glyph; + size_t n = 0; + char buf[BUFSZ]; - if (!glyphname_hashtable_ptr) { - init_glyphname_hashtable(); - } - if (glyphname_hashtable_ptr) { - glyphname_hashtable_find = zero_find; - glyphname_hashtable_find.findtype = find_nothing; - glyphname_hashtable_find.reserved = (genericptr_t) glyphname_hashtable_ptr; - glyphname_hashtable_find.restype = res_fill_hashtable; - reslt = parse_id((char *) 0, &glyphname_hashtable_find); - if (!reslt) { - empty_glyphname_hashtable(); - glyphname_hashtable_ptr = (struct glyphname_hashtable_entry_t *) 0; + if (glyphname_hashtable_ptr) + return; + glyphname_hashtable_ptr = (struct glyphname_hashtable_entry_t *) alloc( + MAX_GLYPH * sizeof (struct glyphname_hashtable_entry_t)); + + for (glyph = 0; glyph < MAX_GLYPH; ++glyph) { + if (compose_glyph_name(glyph, buf, sizeof buf)) { + glyphname_hashtable_ptr[n].hash = glyph_hash(buf); + glyphname_hashtable_ptr[n].glyphnum = glyph; + ++n; } } -} - -/* - * The glyph ID cache is a simple double-hash table. - * The cache size is a power of two, and two hashes are derived from the - * cache ID. The first is a location in the table, and the second is an - * offset. On any collision, the second hash is added to the first until - * a match or an empty bucket is found. - * The second hash is an odd number, which is necessary and sufficient - * to traverse the entire table. - */ - -staticfn void -init_glyphname_hashtable(void) -{ - size_t glyph; - - /* Cache size of power of 2 not less than 2*MAX_GLYPH */ - glyphname_hashtable_lsize = 0; - glyphname_hashtable_size = 1; - while (glyphname_hashtable_size < 2*MAX_GLYPH) { - ++glyphname_hashtable_lsize; - glyphname_hashtable_size <<= 1; - } - - glyphname_hashtable_ptr = (struct glyphname_hashtable_entry_t *) alloc( - glyphname_hashtable_size * sizeof (struct glyphname_hashtable_entry_t)); - for (glyph = 0; glyph < glyphname_hashtable_size; ++glyph) { - glyphname_hashtable_ptr[glyph].glyphnum = 0; - glyphname_hashtable_ptr[glyph].id = (char *) 0; - } + qsort(glyphname_hashtable_ptr, n, + sizeof glyphname_hashtable_ptr[0], cmp_glyphname_entry); + glyphname_hashtable_count = n; } void empty_glyphname_hashtable(void) { - size_t idx; - if (!glyphname_hashtable_ptr) return; - for (idx = 0; idx < glyphname_hashtable_size; ++idx) { - if (glyphname_hashtable_ptr[idx].id) { - free(glyphname_hashtable_ptr[idx].id); - glyphname_hashtable_ptr[idx].id = (char *) 0; - } - } free(glyphname_hashtable_ptr); glyphname_hashtable_ptr = (struct glyphname_hashtable_entry_t *) 0; -} - -staticfn void -add_glyph_to_glyphname_hashtable(int glyphnum, const char *id) -{ - uint32 hash = glyph_hash(id); - size_t hash1 = (size_t) (hash & (glyphname_hashtable_size - 1)); - size_t hash2 = (size_t) - (((hash >> glyphname_hashtable_lsize) & (glyphname_hashtable_size - 1)) | 1); - size_t i = hash1; - - do { - if (glyphname_hashtable_ptr[i].id == NULL) { - /* Empty bucket found */ - glyphname_hashtable_ptr[i].id = dupstr(id); - glyphname_hashtable_ptr[i].glyphnum = glyphnum; - return; - } - /* For speed, assume that no ID occurs twice */ - i = (i + hash2) & (glyphname_hashtable_size - 1); - } while (i != hash1); - /* This should never happen */ - panic("glyphname_hashtable_ptr full"); + glyphname_hashtable_count = 0; } staticfn int -find_glyph_in_cache(const char *id) +find_glyph_in_hashtable(const char *id) { - uint32 hash = glyph_hash(id); - size_t hash1 = (size_t) (hash & (glyphname_hashtable_size - 1)); - size_t hash2 = (size_t) - (((hash >> glyphname_hashtable_lsize) & (glyphname_hashtable_size - 1)) | 1); - size_t i = hash1; + uint32 want = glyph_hash(id); + size_t lo = 0, hi = glyphname_hashtable_count, mid; + char buf[BUFSZ]; - do { - if (glyphname_hashtable_ptr[i].id == NULL) { - /* Empty bucket found */ - return -1; - } - if (strcmpi(id, glyphname_hashtable_ptr[i].id) == 0) { - /* Match found */ - return glyphname_hashtable_ptr[i].glyphnum; - } - i = (i + hash2) & (glyphname_hashtable_size - 1); - } while (i != hash1); - return -1; -} - -staticfn char * -find_glyphname_in_hashtable_by_glyphnum(int glyphnum) -{ - size_t idx; - - if (!glyphname_hashtable_ptr) - return (char *) 0; - for (idx = 0; idx < glyphname_hashtable_size; ++idx) { - if (glyphname_hashtable_ptr[idx].glyphnum == glyphnum - && glyphname_hashtable_ptr[idx].id != 0) { - /* Match found */ - return glyphname_hashtable_ptr[idx].id; - } + /* Binary-search the sorted array for the first entry whose hash >= want. */ + while (lo < hi) { + mid = (lo + hi) >> 1; + if (glyphname_hashtable_ptr[mid].hash < want) + lo = mid + 1; + else + hi = mid; } - return (char *) 0; + /* Walk forward across any equal-hash neighbours, verifying each by + reconstructing the canonical name and strcmpi'ing it back. */ + while (lo < glyphname_hashtable_count + && glyphname_hashtable_ptr[lo].hash == want) { + int g = glyphname_hashtable_ptr[lo].glyphnum; + + if (compose_glyph_name(g, buf, sizeof buf) && !strcmpi(id, buf)) + return g; + ++lo; + } + return -1; } staticfn uint32 @@ -808,15 +983,11 @@ void wizcustom_glyphnames(winid win) { int glyphnum; - char *id; + char buf[BUFSZ]; - if (!glyphname_hashtable_ptr) - return; for (glyphnum = 0; glyphnum < MAX_GLYPH; ++glyphnum) { - id = find_glyphname_in_hashtable_by_glyphnum(glyphnum); - if (id) { - wizcustom_callback(win, glyphnum, id); - } + if (compose_glyph_name(glyphnum, buf, sizeof buf)) + wizcustom_callback(win, glyphnum, buf); } } @@ -826,12 +997,11 @@ parse_id( struct find_struct *findwhat) { FILE *fp = (FILE *) 0; - int i = 0, j, mnum, glyph, + int i = 0, glyph, pm_offset = 0, oc_offset = 0, cmap_offset = 0, pm_count = 0, oc_count = 0, cmap_count = 0; - boolean skip_base = FALSE, skip_this_one = FALSE, dump_ids = FALSE, - filling_cache = FALSE, is_S = FALSE, is_G = FALSE; - char buf[4][QBUFSZ]; + boolean dump_ids = FALSE, is_S = FALSE, is_G = FALSE; + char buf[BUFSZ]; if (findwhat->findtype == find_nothing && findwhat->restype) { if (findwhat->restype == res_dump_glyphnames) { @@ -842,20 +1012,12 @@ parse_id( return 0; } } - if (findwhat->restype == res_fill_hashtable) { - if (findwhat->reserved - && findwhat->reserved == (genericptr_t) glyphname_hashtable_ptr) { - filling_cache = TRUE; - } else { - return 0; - } - } } is_G = (id && id[0] == 'G' && id[1] == '_'); is_S = (id && id[0] == 'S' && id[1] == '_'); - if ((is_G && !glyphname_hashtable_ptr) || filling_cache || dump_ids || is_S) { + if (dump_ids || is_S) { while (loadsyms[i].range) { if (!pm_offset && loadsyms[i].range == SYM_MON) pm_offset = i; @@ -872,259 +1034,31 @@ parse_id( i++; } } - if (is_G || filling_cache || dump_ids) { - if (!filling_cache && id && glyphname_hashtable_ptr) { - int val = find_glyph_in_cache(id); + if (is_G && id) { + /* Populate the hash table lazily, on first G_xxx lookup. */ + if (!glyphname_hashtable_ptr) + populate_glyphname_hashtable(); + if (glyphname_hashtable_ptr) { + int val = find_glyph_in_hashtable(id); + if (val >= 0) { findwhat->findtype = find_glyph; findwhat->val = val; findwhat->loadsyms_offset = 0; return 1; - } else { - return 0; } - } else { - const char *buf2, *buf3, *buf4; - - /* individual matching glyph entries */ - for (glyph = 0; glyph < MAX_GLYPH; ++glyph) { - skip_base = FALSE; - skip_this_one = FALSE; - buf[0][0] = buf[1][0] = buf[2][0] = buf[3][0] = '\0'; - if (glyph_is_monster(glyph)) { - /* buf2 will hold the distinguishing prefix */ - /* buf3 will hold the base name */ - buf2 = ""; - buf3 = monsdump[glyph_to_mon(glyph)].nm; - - if (glyph_is_normal_male_monster(glyph)) { - buf2 = "male_"; - } else if (glyph_is_normal_female_monster(glyph)) { - buf2 = "female_"; - } else if (glyph_is_ridden_male_monster(glyph)) { - buf2 = "ridden_male_"; - } else if (glyph_is_ridden_female_monster(glyph)) { - buf2 = "ridden_female_"; - } else if (glyph_is_detected_male_monster(glyph)) { - buf2 = "detected_male_"; - } else if (glyph_is_detected_female_monster(glyph)) { - buf2 = "detected_female_"; - } else if (glyph_is_male_pet(glyph)) { - buf2 = "pet_male_"; - } else if (glyph_is_female_pet(glyph)) { - buf2 = "pet_female_"; - } - Strcpy(buf[0], "G_"); - Strcat(buf[0], buf2); - Strcat(buf[0], buf3); - } else if (glyph_is_body(glyph)) { - /* buf2 will hold the distinguishing prefix */ - /* buf3 will hold the base name */ - buf2 = glyph_is_body_piletop(glyph) - ? "piletop_body_" - : "body_"; - buf3 = monsdump[glyph_to_body_corpsenm(glyph)].nm; - Strcpy(buf[0], "G_"); - Strcat(buf[0], buf2); - Strcat(buf[0], buf3); - } else if (glyph_is_statue(glyph)) { - /* buf2 will hold the distinguishing prefix */ - /* buf3 will hold the base name */ - buf2 = glyph_is_fem_statue_piletop(glyph) - ? "piletop_statue_of_female_" - : glyph_is_fem_statue(glyph) - ? "statue_of_female_" - : glyph_is_male_statue_piletop(glyph) - ? "piletop_statue_of_male_" - : glyph_is_male_statue(glyph) - ? "statue_of_male_" - : ""; /* shouldn't happen */ - buf3 = monsdump[glyph_to_statue_corpsenm(glyph)].nm; - Strcpy(buf[0], "G_"); - Strcat(buf[0], buf2); - Strcat(buf[0], buf3); - } else if (glyph_is_object(glyph)) { - i = glyph_to_obj(glyph); - /* buf2 will hold the distinguishing prefix */ - /* buf3 will hold the base name */ - if (((i > SCR_STINKING_CLOUD) && (i < SCR_MAIL)) - || ((i > WAN_LIGHTNING) && (i < GOLD_PIECE))) - skip_this_one = TRUE; - if (!skip_this_one) { - if ((i >= WAN_LIGHT) && (i <= WAN_LIGHTNING)) - buf2 = "wand of "; - else if ((i >= SPE_DIG) && (i < SPE_BLANK_PAPER)) - buf2 = "spellbook of "; - else if ((i >= SCR_ENCHANT_ARMOR) - && (i <= SCR_STINKING_CLOUD)) - buf2 = "scroll of "; - else if ((i >= POT_GAIN_ABILITY) && (i <= POT_WATER)) - buf2 = (i == POT_WATER) ? "flask of n" - : "potion of "; - else if ((i >= RIN_ADORNMENT) - && (i <= RIN_PROTECTION_FROM_SHAPE_CHAN)) - buf2 = "ring of "; - else if (i == LAND_MINE) - buf2 = "unset "; - else - buf2 = ""; - buf3 = (i == SCR_BLANK_PAPER) ? "blank scroll" - : (i == SPE_BLANK_PAPER) ? "blank spellbook" - : (i == SLIME_MOLD) ? "slime mold" - : obj_descr[i].oc_name - ? obj_descr[i].oc_name - : obj_descr[i].oc_descr; - Strcpy(buf[0], "G_"); - if (glyph_is_normal_piletop_obj(glyph)) - Strcat(buf[0], "piletop_"); - Strcat(buf[0], buf2); - Strcat(buf[0], buf3); - } - } else if (glyph_is_cmap(glyph) || glyph_is_cmap_zap(glyph) - || glyph_is_swallow(glyph) - || glyph_is_explosion(glyph)) { - int cmap = -1; - - /* buf2 will hold the distinguishing prefix */ - /* buf3 will hold the base name */ - /* buf4 will hold the distinguishing suffix */ - buf2 = ""; - buf3 = ""; - buf4 = ""; - if (glyph == GLYPH_CMAP_OFF) { - cmap = S_stone; - buf3 = "stone substrate"; - skip_base = TRUE; - } else if (glyph_is_cmap_gehennom(glyph)) { - cmap = (glyph - GLYPH_CMAP_GEH_OFF) + S_vwall; - buf4 = "_gehennom"; - } else if (glyph_is_cmap_knox(glyph)) { - cmap = (glyph - GLYPH_CMAP_KNOX_OFF) + S_vwall; - buf4 = "_knox"; - } else if (glyph_is_cmap_main(glyph)) { - cmap = (glyph - GLYPH_CMAP_MAIN_OFF) + S_vwall; - buf4 = "_main"; - } else if (glyph_is_cmap_mines(glyph)) { - cmap = (glyph - GLYPH_CMAP_MINES_OFF) + S_vwall; - buf4 = "_mines"; - } else if (glyph_is_cmap_sokoban(glyph)) { - cmap = (glyph - GLYPH_CMAP_SOKO_OFF) + S_vwall; - buf4 = "_sokoban"; - } else if (glyph_is_cmap_a(glyph)) { - cmap = (glyph - GLYPH_CMAP_A_OFF) + S_ndoor; - } else if (glyph_is_cmap_altar(glyph)) { - static const char *const altar_text[] = { - "unaligned", "chaotic", "neutral", - "lawful", "other", - }; - - j = (glyph - GLYPH_ALTAR_OFF); - cmap = S_altar; - if (j != altar_other) { - Snprintf(buf[2], sizeof buf[2], "%s_", - altar_text[j]); - buf2 = buf[2]; - } else { - buf3 = "altar other"; - skip_base = TRUE; - } - } else if (glyph_is_cmap_b(glyph)) { - cmap = (glyph - GLYPH_CMAP_B_OFF) + S_grave; - } else if (glyph_is_cmap_zap(glyph)) { - static const char *const zap_texts[] = { - "missile", "fire", "frost", "sleep", - "death", "lightning", "poison gas", "acid" - }; - - j = (glyph - GLYPH_ZAP_OFF); - cmap = (j % 4) + S_vbeam; - Snprintf(buf[2], sizeof buf[2], "%s", - loadsyms[cmap + cmap_offset].name + 2); - Snprintf(buf[3], sizeof buf[3], "%s zap %s", - zap_texts[j / 4], fix_glyphname(buf[2])); - buf3 = buf[3]; - buf2 = ""; - skip_base = TRUE; - } else if (glyph_is_cmap_c(glyph)) { - cmap = (glyph - GLYPH_CMAP_C_OFF) + S_digbeam; - } else if (glyph_is_swallow(glyph)) { - static const char *const swallow_texts[] = { - "top left", "top center", "top right", - "middle left", "middle right", "bottom left", - "bottom center", "bottom right", - }; - - j = glyph - GLYPH_SWALLOW_OFF; - cmap = glyph_to_swallow(glyph); - mnum = j / ((S_sw_br - S_sw_tl) + 1); - Strcpy(buf[3], "swallow "); - Strcat(buf[3], monsdump[mnum].nm); - Strcat(buf[3], " "); - Strcat(buf[3], swallow_texts[cmap]); - buf3 = buf[3]; - skip_base = TRUE; - } else if (glyph_is_explosion(glyph)) { - static const char *const expl_type_texts[] = { - "dark", "noxious", "muddy", "wet", - "magical", "fiery", "frosty", - }; - static const char *const expl_texts[] = { - "tl", "tc", "tr", "ml", "mc", - "mr", "bl", "bc", "br", - }; - int expl; - - j = glyph - GLYPH_EXPLODE_OFF; - expl = j / ((S_expl_br - S_expl_tl) + 1); - cmap = glyph_to_explosion(glyph) + S_expl_tl; - i = cmap - S_expl_tl; - Snprintf(buf[2], sizeof buf[2], "%s ", - expl_type_texts[expl]); - buf2 = buf[2]; - Snprintf(buf[3], sizeof buf[3], "%s%s", "expl_", - expl_texts[i]); - buf3 = buf[3]; - skip_base = TRUE; - } - if (!skip_base) { - if (cmap >= 0 && cmap < MAXPCHARS) { - buf3 = loadsyms[cmap + cmap_offset].name + 2; - } - } - Strcpy(buf[0], "G_"); - Strcat(buf[0], buf2); - Strcat(buf[0], buf3); - Strcat(buf[0], buf4); - } else if (glyph_is_invisible(glyph)) { - Strcpy(buf[0], "G_invisible"); - } else if (glyph_is_nothing(glyph)) { - Strcpy(buf[0], "G_nothing"); - } else if (glyph_is_unexplored(glyph)) { - Strcpy(buf[0], "G_unexplored"); - } else if (glyph_is_warning(glyph)) { - j = glyph - GLYPH_WARNING_OFF; - Snprintf(buf[0], sizeof buf[0], "G_%s%d", "warning", j); - } - if (memchr(buf[0], '\0', sizeof buf[0]) == NULL) - panic("parse_id: buf[0] overflowed"); - if (!skip_this_one) { - fix_glyphname(buf[0]+2); - if (dump_ids) { - Fprintf(fp, "(%04d) %s\n", glyph, buf[0]); - } else if (filling_cache) { - add_glyph_to_glyphname_hashtable(glyph, buf[0]); - } else if (id) { - if (!strcmpi(id, buf[0])) { - findwhat->findtype = find_glyph; - findwhat->val = glyph; - findwhat->loadsyms_offset = 0; - return 1; - } - } - } - } - } /* not glyphname_hashtable_ptr */ - } else if (is_S) { + } + return 0; + } + if (dump_ids) { + /* iterate and dump every named glyph */ + for (glyph = 0; glyph < MAX_GLYPH; ++glyph) { + if (compose_glyph_name(glyph, buf, sizeof buf)) + Fprintf(fp, "(%04d) %s\n", glyph, buf); + } + return 1; + } + if (is_S) { /* cmap entries */ for (i = 0; i < cmap_count; ++i) { if (!strcmpi(loadsyms[i + cmap_offset].name + 2, id + 2)) { @@ -1153,8 +1087,6 @@ parse_id( } } } - if (dump_ids || filling_cache) - return 1; findwhat->findtype = find_nothing; findwhat->val = 0; findwhat->loadsyms_offset = 0; From 8b3eb77305f23e8b813fe949eb7c00ef2965ed1a Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 25 May 2026 14:30:02 -0400 Subject: [PATCH 381/702] cherry-pick pr #1548 52e0404 glyphname indexes --- doc/fixes5-0-1.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index b2d139880..5fd0d510c 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -39,8 +39,11 @@ add ANY_INT16 to any_types and use it for u.ux/uy/tx/ty and uz dlevel/dnum; those are coordxy (int16_t) but the Lua bindings were treating them as 1-byte fields, so on big-endian m68k Lua read the high byte (0) instead of the actual value. Symptom: place_object off map <0,0> - in the tutorial. + win the tutorial. fix an off-by-one in glyph_is_normal_piletop_obj (pr #1547 by ingpaschke) +replace the hashtable used for parsing glyphnames with sorted indices and + reduce the string allocation load during that processing (cherry-pick + of pr #1548 by ingpaschke) Platform- and/or Interface-Specific Fixes From 503355bb1185fda13f870ea58e26f68d1fd4578e Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 25 May 2026 14:44:32 -0400 Subject: [PATCH 382/702] yet another function and date name update Related to the overhaul of glyphname hash indices --- include/decl.h | 2 +- include/extern.h | 6 ++--- src/decl.c | 4 +-- src/glyphs.c | 68 ++++++++++++++++++++++++------------------------ src/options.c | 18 ++++++------- src/save.c | 4 +-- src/symbols.c | 8 +++--- src/wizcmds.c | 8 +++--- 8 files changed, 59 insertions(+), 59 deletions(-) diff --git a/include/decl.h b/include/decl.h index 4eca88060..6aa7ab4fa 100644 --- a/include/decl.h +++ b/include/decl.h @@ -344,7 +344,7 @@ struct instance_globals_d { /* new */ boolean deferred_showpaths; char *deferred_showpaths_dir; - boolean disable_glyphname_hashtable_prefill; + boolean disable_glyphname_hash_indices_prefill; boolean havestate; }; diff --git a/include/extern.h b/include/extern.h index 93a4083a2..90f14c21b 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1185,9 +1185,9 @@ extern int glyphrep(const char *) NONNULLARG1; extern int match_glyph(char *) NONNULLARG1; extern void dump_all_glyphnames(FILE *fp) NONNULLARG1; extern void wizcustom_glyphnames(winid win); -extern void populate_glyphname_hashtable(void); -extern void empty_glyphname_hashtable(void); -extern boolean glyphname_hashtable_loaded(void); +extern void populate_glyphname_hash_indices(void); +extern void empty_glyphname_hash_indices(void); +extern boolean glyphname_hash_indices_loaded(void); extern void apply_customizations(enum graphics_sets which_set, enum do_customizations docustomize); extern void purge_custom_entries(enum graphics_sets which_set); diff --git a/src/decl.c b/src/decl.c index 54110ab72..bb4485705 100644 --- a/src/decl.c +++ b/src/decl.c @@ -313,7 +313,7 @@ static const struct instance_globals_d g_init_d = { FALSE, /* decor_levitate_override */ FALSE, /* deferred_showpaths */ NULL, /* deferred_showpaths_dir */ - FALSE, /* disable_glyphname_hashtable_prefill */ + FALSE, /* disable_glyphname_hash_indices_prefill */ TRUE, /* havestate*/ }; @@ -1186,7 +1186,7 @@ decl_globals_init(void) gu.urole = urole_init_data; gu.urace = urace_init_data; #ifdef DISABLE_GLYPHID_CACHE_PREFILL - gd.disable_glyphname_hashtable_prefill = TRUE; + gd.disable_glyphname_hash_indices_prefill = TRUE; #endif } diff --git a/src/glyphs.c b/src/glyphs.c index 6132844e8..fb2c18404 100644 --- a/src/glyphs.c +++ b/src/glyphs.c @@ -26,12 +26,12 @@ struct find_struct { genericptr_t reserved; }; static const struct find_struct zero_find = { 0 }; -struct glyphname_hashtable_entry_t { +struct glyphname_hash_index_entry_t { uint32 hash; int glyphnum; /* NO_GLYPH (==MAX_GLYPH) marks an empty bucket */ }; -static struct glyphname_hashtable_entry_t *glyphname_hashtable_ptr; -static size_t glyphname_hashtable_count; +static struct glyphname_hash_index_entry_t *glyphname_hash_indices_ptr; +static size_t glyphname_hash_indices_count; static struct find_struct to_custom_symbol_find; static const long nonzero_black = CLR_BLACK | NH_BASIC_COLOR; @@ -117,7 +117,7 @@ glyphrep_to_custom_map_entries( long rgb = 0L; boolean slash = FALSE, colon = FALSE; - if (!glyphname_hashtable_ptr) + if (!glyphname_hash_indices_ptr) reslt = 1; /* for debugger use only; no cache available */ nhUse(reslt); @@ -198,7 +198,7 @@ fix_glyphname(char *str) * Returns 1 if a name was produced, 0 if this glyph has no canonical name * (a few unused object indices); buf[0] is set to '\0' in that case. * Used by parse_id's bulk-iteration paths, by find_glyph_in_hashtable to - * verify hash matches, by populate_glyphname_hashtable to fill the table, + * verify hash matches, by populate_glyphname_hash_indices to fill the table, * and by wizcustom_glyphnames. */ staticfn int compose_glyph_name(int glyph, char *buf, size_t bufsz) @@ -514,8 +514,8 @@ glyph_find_core( } /* - * glyphname_hashtable is a sorted (hash, glyph) index of canonical - * "G_xxx" identifiers. populate_glyphname_hashtable() allocates one + * glyphname_hash_indices is a sorted (hash, glyph) index of canonical + * "G_xxx" identifiers. populate_glyphname_hash_indices() allocates one * block of MAX_GLYPH * sizeof(entry) (some entries go unused for the * scroll/gem appearance gaps), fills it via compose_glyph_name(), and * sorts ascending by hash. Lookup is bsearch on the hash with @@ -534,8 +534,8 @@ glyph_find_core( staticfn int cmp_glyphname_entry(const void *a, const void *b) { - uint32 ha = ((const struct glyphname_hashtable_entry_t *) a)->hash; - uint32 hb = ((const struct glyphname_hashtable_entry_t *) b)->hash; + uint32 ha = ((const struct glyphname_hash_index_entry_t *) a)->hash; + uint32 hb = ((const struct glyphname_hash_index_entry_t *) b)->hash; if (ha < hb) return -1; @@ -545,59 +545,59 @@ cmp_glyphname_entry(const void *a, const void *b) } void -populate_glyphname_hashtable(void) +populate_glyphname_hash_indices(void) { int glyph; size_t n = 0; char buf[BUFSZ]; - if (glyphname_hashtable_ptr) + if (glyphname_hash_indices_ptr) return; - glyphname_hashtable_ptr = (struct glyphname_hashtable_entry_t *) alloc( - MAX_GLYPH * sizeof (struct glyphname_hashtable_entry_t)); + glyphname_hash_indices_ptr = (struct glyphname_hash_index_entry_t *) alloc( + MAX_GLYPH * sizeof (struct glyphname_hash_index_entry_t)); for (glyph = 0; glyph < MAX_GLYPH; ++glyph) { if (compose_glyph_name(glyph, buf, sizeof buf)) { - glyphname_hashtable_ptr[n].hash = glyph_hash(buf); - glyphname_hashtable_ptr[n].glyphnum = glyph; + glyphname_hash_indices_ptr[n].hash = glyph_hash(buf); + glyphname_hash_indices_ptr[n].glyphnum = glyph; ++n; } } - qsort(glyphname_hashtable_ptr, n, - sizeof glyphname_hashtable_ptr[0], cmp_glyphname_entry); - glyphname_hashtable_count = n; + qsort(glyphname_hash_indices_ptr, n, + sizeof glyphname_hash_indices_ptr[0], cmp_glyphname_entry); + glyphname_hash_indices_count = n; } void -empty_glyphname_hashtable(void) +empty_glyphname_hash_indices(void) { - if (!glyphname_hashtable_ptr) + if (!glyphname_hash_indices_ptr) return; - free(glyphname_hashtable_ptr); - glyphname_hashtable_ptr = (struct glyphname_hashtable_entry_t *) 0; - glyphname_hashtable_count = 0; + free(glyphname_hash_indices_ptr); + glyphname_hash_indices_ptr = (struct glyphname_hash_index_entry_t *) 0; + glyphname_hash_indices_count = 0; } staticfn int find_glyph_in_hashtable(const char *id) { uint32 want = glyph_hash(id); - size_t lo = 0, hi = glyphname_hashtable_count, mid; + size_t lo = 0, hi = glyphname_hash_indices_count, mid; char buf[BUFSZ]; /* Binary-search the sorted array for the first entry whose hash >= want. */ while (lo < hi) { mid = (lo + hi) >> 1; - if (glyphname_hashtable_ptr[mid].hash < want) + if (glyphname_hash_indices_ptr[mid].hash < want) lo = mid + 1; else hi = mid; } /* Walk forward across any equal-hash neighbours, verifying each by reconstructing the canonical name and strcmpi'ing it back. */ - while (lo < glyphname_hashtable_count - && glyphname_hashtable_ptr[lo].hash == want) { - int g = glyphname_hashtable_ptr[lo].glyphnum; + while (lo < glyphname_hash_indices_count + && glyphname_hash_indices_ptr[lo].hash == want) { + int g = glyphname_hash_indices_ptr[lo].glyphnum; if (compose_glyph_name(g, buf, sizeof buf) && !strcmpi(id, buf)) return g; @@ -624,9 +624,9 @@ glyph_hash(const char *id) } boolean -glyphname_hashtable_loaded(void) +glyphname_hash_indices_loaded(void) { - return (glyphname_hashtable_ptr != 0); + return (glyphname_hash_indices_ptr != 0); } int @@ -646,7 +646,7 @@ glyphrep(const char *op) { int reslt = 0, glyph = NO_GLYPH; - if (!glyphname_hashtable_ptr) + if (!glyphname_hash_indices_ptr) reslt = 1; /* for debugger use only; no cache available */ nhUse(reslt); reslt = glyphrep_to_custom_map_entries(op, &glyph); @@ -1036,9 +1036,9 @@ parse_id( } if (is_G && id) { /* Populate the hash table lazily, on first G_xxx lookup. */ - if (!glyphname_hashtable_ptr) - populate_glyphname_hashtable(); - if (glyphname_hashtable_ptr) { + if (!glyphname_hash_indices_ptr) + populate_glyphname_hash_indices(); + if (glyphname_hash_indices_ptr) { int val = find_glyph_in_hashtable(id); if (val >= 0) { diff --git a/src/options.c b/src/options.c index 2c8464294..1cbb64ac5 100644 --- a/src/options.c +++ b/src/options.c @@ -4224,11 +4224,11 @@ optfn_symset( if (req == do_handler) { int reslt; - if (!glyphname_hashtable_loaded()) - populate_glyphname_hashtable(); + if (!glyphname_hash_indices_loaded()) + populate_glyphname_hash_indices(); reslt = handler_symset(optidx); - if (glyphname_hashtable_loaded()) - empty_glyphname_hashtable(); + if (glyphname_hash_indices_loaded()) + empty_glyphname_hash_indices(); /* apply_customizations(gc.currentgraphics, (do_custom_colors | do_custom_symbols)); */ return reslt; @@ -7152,9 +7152,9 @@ initoptions_init(void) } /* make any symbol parsing quicker, but only if - * gd.disable_glyphname_hashtable_prefill is not set to TRUE */ - if (!glyphname_hashtable_loaded() && !gd.disable_glyphname_hashtable_prefill) - populate_glyphname_hashtable(); + * gd.disable_glyphname_hash_indices_prefill is not set to TRUE */ + if (!glyphname_hash_indices_loaded() && !gd.disable_glyphname_hash_indices_prefill) + populate_glyphname_hash_indices(); /* set up the command parsing */ reset_commands(TRUE); /* init */ @@ -7377,8 +7377,8 @@ initoptions_finish(void) iflags.wc_ascii_map = FALSE, iflags.wc_tiled_map = TRUE; #ifdef ENHANCED_SYMBOLS - if (glyphname_hashtable_loaded()) - empty_glyphname_hashtable(); + if (glyphname_hash_indices_loaded()) + empty_glyphname_hash_indices(); apply_customizations(gc.currentgraphics, do_custom_symbols | do_custom_colors); #endif diff --git a/src/save.c b/src/save.c index f9ab60115..bd2696e6c 100644 --- a/src/save.c +++ b/src/save.c @@ -1175,8 +1175,8 @@ freedynamicdata(void) if (options_set_window_colors_flag) options_free_window_colors(); - if (glyphname_hashtable_loaded()) - empty_glyphname_hashtable(); + if (glyphname_hash_indices_loaded()) + empty_glyphname_hash_indices(); if (tnhfp) { close_nhfile(tnhfp); diff --git a/src/symbols.c b/src/symbols.c index edc3f26a6..7b484505f 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -1069,12 +1069,12 @@ do_symset(boolean rogueflag) if (gs.symset[which_set].name) { /* non-default symbols */ int ok; - if (!glyphname_hashtable_loaded()) { - populate_glyphname_hashtable(); + if (!glyphname_hash_indices_loaded()) { + populate_glyphname_hash_indices(); } ok = read_sym_file(which_set); - if (glyphname_hashtable_loaded()) { - empty_glyphname_hashtable(); + if (glyphname_hash_indices_loaded()) { + empty_glyphname_hash_indices(); } if (ok) { ready_to_switch = TRUE; diff --git a/src/wizcmds.c b/src/wizcmds.c index 3ff2ec3c7..60b991db9 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -1945,8 +1945,8 @@ wiz_custom(void) #endif menu_item *pick_list = (menu_item *) 0; - if (!glyphname_hashtable_loaded()) - populate_glyphname_hashtable(); + if (!glyphname_hash_indices_loaded()) + populate_glyphname_hash_indices(); win = create_nhwindow(NHW_MENU); start_menu(win, MENU_BEHAVE_STANDARD); @@ -1975,8 +1975,8 @@ wiz_custom(void) #endif if (n >= 1) free((genericptr_t) pick_list); - if (glyphname_hashtable_loaded()) - empty_glyphname_hashtable(); + if (glyphname_hash_indices_loaded()) + empty_glyphname_hash_indices(); docrt(); } else pline(unavailcmd, ecname_from_fn(wiz_custom)); From 95d70ef5d8de0cd57560de024481e11e16738355 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 25 May 2026 21:19:51 +0200 Subject: [PATCH 383/702] glyphs: add piletop_ prefix to piletop-generic-obj canonical names parse_id's glyph_is_object branch only emitted the "piletop_" prefix when glyph_is_normal_piletop_obj(glyph) was true. Piletop-generic objects (the GLYPH_OBJ_PILETOP_OFF + 1 .. + LAST_GENERIC range) hit glyph_is_piletop_generic_obj() instead and got no prefix, so they produced the same canonical name as their non-piletop generic counterparts. For example glyph 3449 (GLYPH_OBJ_OFF + GENERIC_STRANGE) and glyph 7993 (GLYPH_OBJ_PILETOP_OFF + GENERIC_STRANGE) both yielded "G_generic_strange". 14 such pairs exist; the piletop variant is unreachable by name from nethackrc, and the runtime hashtable's "assume no id occurs twice" populate loop silently dropped them. Emit "piletop_" for both piletop predicates so each glyph gets a distinct canonical name. --dumpglyphnames now shows the 14 "G_piletop_generic_*" entries (and the count goes from 9577 to 9591; the existing off-by-one in glyph_is_normal_piletop_obj still hides slot GLYPH_OBJ_PILETOP_OFF + FIRST_OBJECT - 1, which is addressed by its own fix). --- src/glyphs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/glyphs.c b/src/glyphs.c index e38e1baa9..663d3bdde 100644 --- a/src/glyphs.c +++ b/src/glyphs.c @@ -975,7 +975,8 @@ parse_id( ? obj_descr[i].oc_name : obj_descr[i].oc_descr; Strcpy(buf[0], "G_"); - if (glyph_is_normal_piletop_obj(glyph)) + if (glyph_is_normal_piletop_obj(glyph) + || glyph_is_piletop_generic_obj(glyph)) Strcat(buf[0], "piletop_"); Strcat(buf[0], buf2); Strcat(buf[0], buf3); From bd67f3d0d6507798fa36de92f36a7bbb51ce11eb Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 25 May 2026 15:33:54 -0400 Subject: [PATCH 384/702] merge bit --- src/glyphs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/glyphs.c b/src/glyphs.c index 5c49d89a4..837190caf 100644 --- a/src/glyphs.c +++ b/src/glyphs.c @@ -291,7 +291,8 @@ compose_glyph_name(int glyph, char *buf, size_t bufsz) ? obj_descr[i].oc_name : obj_descr[i].oc_descr; Strcpy(buf, "G_"); - if (glyph_is_normal_piletop_obj(glyph)) + if (glyph_is_normal_piletop_obj(glyph) + || glyph_is_piletop_generic_obj(glyph)) Strcat(buf, "piletop_"); Strcat(buf, buf2); Strcat(buf, buf3); @@ -1046,8 +1047,6 @@ parse_id( findwhat->val = val; findwhat->loadsyms_offset = 0; return 1; - if (glyph_is_normal_piletop_obj(glyph) - || glyph_is_piletop_generic_obj(glyph)) } } return 0; From b4f417f2ca3503387a0872693ed0a1172f0fd38e Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Mon, 25 May 2026 14:16:09 -0400 Subject: [PATCH 385/702] This is cron-daily v1-May-7-2026. 005guidebook updated: doc/Guidebook.txt --- doc/Guidebook.txt | 242 +++++++++++++++++++++++----------------------- 1 file changed, 121 insertions(+), 121 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 113272b04..d5a6ffd11 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for NetHack 5.0.0 by Mike Stephenson and others) - May 11, 2026 + May 25, 2026 @@ -126,7 +126,7 @@ employ to great advantage. - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -192,7 +192,7 @@ NetHack continues this fine tradition. Unlike text adventure games - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -258,7 +258,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -324,7 +324,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -390,7 +390,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -456,7 +456,7 @@ The number of turns elapsed so far, displayed if you have the - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -522,7 +522,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -588,7 +588,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -654,7 +654,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -720,7 +720,7 @@ instead. Only these one-step movement commands cause you to - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -786,7 +786,7 @@ ing . ^ is used as shorthand elsewhere in the - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -852,7 +852,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -918,7 +918,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -984,7 +984,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -1050,7 +1050,7 @@ at an adjacent "remembered, unseen monster" marker. - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -1116,7 +1116,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -1182,7 +1182,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -1248,7 +1248,7 @@ (R)UNIX is a registered trademark of The Open Group. - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -1314,7 +1314,7 @@ inventory slot. If it has a name assigned, other stacks with the - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -1380,7 +1380,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -1446,7 +1446,7 @@ fight there. Default key is `F', or `-' with number_pad - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -1512,7 +1512,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -1578,7 +1578,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -1644,7 +1644,7 @@ Pick up things at the current location. Default key is `,'. The - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -1710,7 +1710,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -1776,7 +1776,7 @@ worn. - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -1842,7 +1842,7 @@ Suspend the game, switching from NetHack to the terminal it was - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -1908,7 +1908,7 @@ pick one from inventory, except for the special case of - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -1974,7 +1974,7 @@ menu of sorting orders available (provided that the vanquished - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -2040,7 +2040,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -2106,7 +2106,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -2172,7 +2172,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -2238,7 +2238,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -2304,7 +2304,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -2370,7 +2370,7 @@ them). Some monsters who can open doors can also use unlocking tools. - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -2436,7 +2436,7 @@ been nullified, giving access to whatever is beyond them. In the - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -2502,7 +2502,7 @@ play. - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -2568,7 +2568,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -2634,7 +2634,7 @@ attack, when guessing where an unseen monster is or when deliberately - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -2700,7 +2700,7 @@ noid_confirmation:attack option to require a response of "yes" - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -2766,7 +2766,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -2832,7 +2832,7 @@ are encumbered, one of the conditions Burdened, Stressed, Strained, - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -2898,7 +2898,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -2964,7 +2964,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -3030,7 +3030,7 @@ aklys, lucern hammer, and bec-de-corbin) are defined in an appendix to - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -3096,7 +3096,7 @@ shots by using a numeric prefix before the `t' or `f' command. For - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -3162,7 +3162,7 @@ first you need to have a weapon in each hand. (Note that your two - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -3228,7 +3228,7 @@ even further. Most of these provide a one or two point improvement to - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -3294,7 +3294,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -3360,7 +3360,7 @@ yourself (just give a `.' or `s' for the direction). Be warned, how- - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -3426,7 +3426,7 @@ your ken can be harmful to your health! - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -3492,7 +3492,7 @@ play the entire game without being able to see (a self-imposed chal- - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -3558,7 +3558,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -3624,7 +3624,7 @@ set the goldX option if you prefer to have gold pieces be treated as - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -3690,7 +3690,7 @@ eating such items still counts against foodless conduct. - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -3756,7 +3756,7 @@ monster (i.e. if you would get experience for the death). This is a - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -3822,7 +3822,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -3888,7 +3888,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -3954,7 +3954,7 @@ ning NetHack for the first time, you should find a default template - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -4020,7 +4020,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -4086,7 +4086,7 @@ begins; whatever follows will be common to all sections. Otherwise - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -4152,7 +4152,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -4218,7 +4218,7 @@ sign) to let NetHack know that the rest is intended as a file name. - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -4284,7 +4284,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -4350,7 +4350,7 @@ weapon or both. - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -4416,7 +4416,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -4482,7 +4482,7 @@ extended command, it controls whether the menu shows all available - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -4548,7 +4548,7 @@ might miss some interesting and/or important information. Persis- - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -4614,7 +4614,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -4680,7 +4680,7 @@ class(es). Combination starts with a prompt for object class(es) of - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -4746,7 +4746,7 @@ 5 - One-or-other - show symbols on headers, or on entries if no - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -4812,7 +4812,7 @@ port is the same as specifying 0. - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -4878,7 +4878,7 @@ ing 1 and negating number_pad is the same as specifying 0. (Set- - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -4944,7 +4944,7 @@ `y', set Confirm too); - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -5010,7 +5010,7 @@ ing pets on the map. Effectively a superset of the hilite_pet bool- - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -5076,7 +5076,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -5142,7 +5142,7 @@ game). This option exists partly as an acknowledgement that some - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -5208,7 +5208,7 @@ sistent. - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -5274,7 +5274,7 @@ Controls the sorting behavior for the output of the `\' and ``' com- - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -5340,7 +5340,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -5406,7 +5406,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -5472,7 +5472,7 @@ targets. - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -5538,7 +5538,7 @@ currently using by checking to see if it shows up in the Options list. - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -5604,7 +5604,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -5670,7 +5670,7 @@ this option. - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -5736,7 +5736,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -5802,7 +5802,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -5868,7 +5868,7 @@ hang if this is turned on. Cannot be set with the `O' command. - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -5934,7 +5934,7 @@ you can define patterns to be checked when the game is about to - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -6000,7 +6000,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -6066,7 +6066,7 @@ When asked for a location, the key to go to next closest door or - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -6132,7 +6132,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -6198,7 +6198,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -6264,7 +6264,7 @@ ple MENUCOLOR entries in your configuration file, and the last MENU- - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -6330,7 +6330,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -6396,7 +6396,7 @@ depending upon your other option settings. - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -6462,7 +6462,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -6528,7 +6528,7 @@ value, and the ^ prefix causes the following character to be treated - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -6594,7 +6594,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -6660,7 +6660,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -6726,7 +6726,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -6792,7 +6792,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -6804,13 +6804,13 @@ The format for defining a glyph representation is: - OPTIONS=glyph:glyphid/U+nnnn/R-G-B + OPTIONS=glyph:glyphname/U+nnnn/R-G-B The window port that is active needs to provide support for dis- playing UTF-8 character sequences and explicit red-green-blue colors in order for the glyph representation to be visible. For example, the following line in your configuration file will cause the glyph repre- - sentation for glyphid G_pool to use Unicode codepoint U+224B and the + sentation for glyphname G_pool to use Unicode codepoint U+224B and the color represented by R-G-B value 0-0-160: OPTIONS=glyph:G_pool/U+224B/0-0-160 @@ -6858,7 +6858,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -6924,7 +6924,7 @@ seen via the "#attributes" command. - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -6990,7 +6990,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -7056,7 +7056,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -7122,7 +7122,7 @@ connection between "wizard mode" and the Wizard role). Attempting to - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -7188,7 +7188,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -7254,7 +7254,7 @@ were distinct for specific types of monsters and objects rather than - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -7320,7 +7320,7 @@ file layout which prevented score entries from being read back in cor- - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -7386,7 +7386,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -7452,7 +7452,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -7518,7 +7518,7 @@ changes and new features almost immediately, and they often did. The - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -7584,7 +7584,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -7650,7 +7650,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -7716,7 +7716,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -7782,7 +7782,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 @@ -7848,7 +7848,7 @@ - NetHack 5.0.0 May 11, 2026 + NetHack 5.0.0 May 25, 2026 From 598253eac8f8dc93eaa1b19881db52cbfaf56819 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 25 May 2026 21:37:34 +0200 Subject: [PATCH 386/702] glyphs: rotate-5 in glyph_hash eliminates true collisions The previous rotate-1-xor put consecutive characters' bits in adjacent positions, so short similar names like fox/bat or jaguar/lichen collided -- 164 colliding buckets across the 9577 named glyphs. Rotate-5 spreads each character across a 5-bit window: zero true collisions, one m68k ROL.L, no multiplication. The 16 remaining same-hash buckets are name duplicates from a separate compose_glyph_name bug, addressed by its own fix. --- src/glyphs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/glyphs.c b/src/glyphs.c index 837190caf..1d57a4e78 100644 --- a/src/glyphs.c +++ b/src/glyphs.c @@ -618,7 +618,7 @@ glyph_hash(const char *id) if ('A' <= ch && ch <= 'Z') { ch += 'a' - 'A'; } - hash = (hash << 1) | (hash >> 31); + hash = (hash << 5) | (hash >> 27); hash ^= ch; } return hash; From e352048612cf55836b6c8f642c76f68720119195 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 26 May 2026 22:00:12 -0400 Subject: [PATCH 387/702] include MAXTCHARS in --dumpenums --- src/earlyarg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/earlyarg.c b/src/earlyarg.c index 3d360129f..8c03c0e19 100755 --- a/src/earlyarg.c +++ b/src/earlyarg.c @@ -791,6 +791,7 @@ static const struct enum_dump glyph_offsets_dump[] = { dump_om(NUM_REAL_GEMS), dump_om(NUM_GLASS_GEMS), dump_om(MAXEXPCHARS), + dump_om(MAXTCHARS), dump_om(WARNCOUNT), }; #undef dump_om From ce31feb2318160e212d3ddda58964b366faf28c7 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 27 May 2026 16:14:20 -0400 Subject: [PATCH 388/702] add some foundational work for uplifts Be able to carry out uplifts during minor release lifetimes. Document a way to be able to uplift struct content without incrementing EDITLEVEL and breaking existing savefiles. Use the mechanics outlined to uplift the contents instead, where it is feasible to do so. The uplift is currently one-way only. An uplifted savefile cannot be used with an earlier build of NetHack , one built with a lower SAVEFILE_REVISION_LEVEL, than the one which wrote the savefile. The final byte (byte 79) of the 80 critical bytes in the savefile, of which 10 are reserved for future expansion and not currently used, will now be used for holding the savefile revision level (SAVEFILE_REVISION_LEVEL in include/patchlevel.h) at the time the savefile was written. That leaves 9 of the bytes available for future use. --- include/decl.h | 3 + include/extern.h | 9 + include/patchlevel.h | 8 + include/revision.h | 228 +++++++++++++++++++++++ include/savefile.h | 14 +- include/sfmacros.h | 4 + include/sfprocs.h | 8 + src/decl.c | 2 + src/restore.c | 6 + src/revision.c | 89 +++++++++ src/sfbase.c | 15 ++ src/sfstruct.c | 9 +- src/version.c | 13 +- sys/msdos/Makefile.GCC | 22 +-- sys/unix/Makefile.src | 86 ++++----- sys/vms/Makefile.src | 23 +-- sys/vms/Makefile_src.vms | 3 +- sys/windows/GNUmakefile | 6 +- sys/windows/Makefile.nmake | 87 ++++----- sys/windows/vs/NetHack/NetHack.vcxproj | 4 +- sys/windows/vs/NetHackW/NetHackW.vcxproj | 4 +- 21 files changed, 526 insertions(+), 117 deletions(-) create mode 100644 include/revision.h create mode 100644 src/revision.c diff --git a/include/decl.h b/include/decl.h index 6aa7ab4fa..2eb47fcbd 100644 --- a/include/decl.h +++ b/include/decl.h @@ -978,6 +978,9 @@ struct instance_globals_u { /* decl.c */ boolean unweapon; + /* revision.c */ + int uplift_needed_rev0_to_rev1; + /* role.c */ struct Role urole; /* player's role. May be munged in role_init() */ struct Race urace; /* player's race. May be munged in role_init() */ diff --git a/include/extern.h b/include/extern.h index 90f14c21b..90af830f4 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2754,6 +2754,15 @@ void restore_msghistory(NHFILE *); extern void rest_adjust_levelflags(void); extern void moves_to_relative_time(long *); extern void relative_time_to_moves(long *); +extern boolean revision_increment(int, int, uchar *); + +/* ### revision.c ### */ + +extern boolean revision_increment(int, int, uchar *); +#ifdef DEMO_UPLIFTS +void uplift_mystruct_rev0_to_mystruct(struct mystruct_rev0 *rev0, + struct mystruct *rev1); +#endif /* DEMO_UPLIFTS */ /* ### rip.c ### */ diff --git a/include/patchlevel.h b/include/patchlevel.h index 94bfacf74..4c66c7fd2 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -43,6 +43,14 @@ #define COPYRIGHT_BANNER_C nomakedefs.copyright_banner_c #define COPYRIGHT_BANNER_D " See license for details." +/* + * SAVEFILE_REVISION_LEVEL + * Increment this if there has been a change to a data structure + * that the source code is prepared to handle and convert properly. + * The SAVEFILE_REVISION_LEVEL value needs to fit into an unsigned byte. + */ +#define SAVEFILE_REVISION_LEVEL 0x00 + /* * If two or more successive releases have compatible data files, define * this with the version number of the oldest such release so that the diff --git a/include/revision.h b/include/revision.h new file mode 100644 index 000000000..fa324132c --- /dev/null +++ b/include/revision.h @@ -0,0 +1,228 @@ +/* NetHack 5.0 revision.h $NHDT-Date: 1706213796 2024/01/25 20:16:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ +/* Copyright (c) Michael Allison, 2026. */ +/* NetHack may be freely redistributed. See license for details. */ + +/* + * Supporting revisions to NetHack structs via incemental + * uplifts, rather than incrementing EDITLEVEL and breaking + * savefile compatibility. + * + * Here is the contrived example struct we'll use for + * this document: + * + * The old revision: The new revision: + * + * struct mystruct { struct mystruct { + * int field1; int field1; + * int field2; int field2; + * char field3; char field3; + * long field4; long field4; + * }; int newfielda; + * int newfieldb; + * }; + * + * Steps (using mystruct as an example name) + * + * 1. Paste an exact copy of the struct declaration as it is/was + * in the previous revision into include/revision.h, shrouded by + * #if defined(MYSTRUCT_REV0), and tack a '_rev0' suffix onto the + * name of the struct. For example, + * + * #if defined(MYSTRUCT_REV0) + * struct mystruct_rev0 { + * int field1; + * int field2; + * char field3; + * long field4; + * }; + * + * That goes just ahead of this existing placeholder: + * + * #elif defined(XXX_REV0) + * + * 2. Place a comment ahead of the mystruct_rev0 declaration + * that explains what has changed, and why the revision + * is required. + * + * 3. Immediately following the revised struct declaration in the + * original header file where it is located, add the following: + * + * #define MYSTRUCT_REV0 + * #include "revision.h" + * #undef MYSTRUCT_REV0 + * + * 4. In include/savefile.h, add a new prototype for a function + * to read the previous revision from the savefile, ideally + * immediately following the prototype for the current active + * one that hasn't got the '_rev0' suffix: + * + * extern void sfi_mystruct(NHFILE *, struct mystruct *, + * const char *); + * extern void sfi_mystruct_rev0(NHFILE *, struct mystruct_rev0 *, + * const char *); + * + * 5. Also in include/savefile.h, in the '#if NH_C < 202300L' block, + * add an entry below the one that should already exist for the + * struct that hasn't got the '_rev0' suffix: + * + * #define Sfi_mystruct(a,b,c) sfi_rm(a, b, c) + * #define Sfi_mystruct_rev0(a, b, c) sfi_mystruct_rev0(a, b, c) + * + * 6. Also in include/savefile.h, in the '#define sfi(nhfp, dt, tag)' + * generic function definition, add an entry below the one + * that should already exist for the struct name that hasn't + * got the '_rev0' suffix: + * + * struct mystruct * : sfi_rm, \ + * struct mystruct_rev0 * : sfi_rm_rev0, \ + * + * 7. Also in include/savefile.h, a little further down in the + * 'Sfi_' macro defininitions, add one below the existing + * one for the struct without the '_rev0' suffix: + * + * #define Sfi_mystruct(a,b,c) sfi(a, b, c) + * #define Sfi_mystruct_rev0(a, b, c) sfi(a, b, c) + * + * Only the input 'Sfi_' is required, because the old revision + * will never be written out to a file, only read in from a + * a file, so no 'Sfo_' is needed. + * + * 8. In include/sfmacros.h, add a new entry below the existing + * entry that exists without the '_rev0' suffix: + * + * SF_C(struct, mystruct) + * SF_C(struct, mystruct_rev0) + * + * 9. In include/sfprocs.h, add a new SF_PROTO_C entry below the + * existing entry that already exists without the '_rev0' suffix: + * + * SF_PROTO_C(struct, mystruct); + * SF_PROTO_C(struct, mystruct_rev0); + * + * 10. Also in include/sfprocs.h, add a new SF_ENTRY_C entry below the + * entry that already exists without the '_rev0' suffix: + * + * SF_ENTRY_C(struct, mystruct); + * SF_ENTRY_C(struct, mystruct_rev0); + * + * 11. In src/sfbase.c, add a prototype for a 'norm_ptrs' stub function + * below the entry that already exists without the '_rev0' suffix: + * + * void norm_ptrs_mystruct(struct mystruct *d_mystruct); + * void norm_ptrs_mystruct_rev0(struct mystruct_rev0 *d_mystruct); + * + * 12. Also in src/sfbase.c, add a 'norm_ptrs' stub function below the + * stub function that already exists without the '_rev0' suffix: + * + * void + * norm_ptrs_mystruct(struct mystruct *d_mystruct UNUSED) + * { + * } + * + * void + * norm_ptrs_mystruct_rev0(struct mystruct_rev0 *d_mystruct_rev0 UNUSED) + * { + * } + * + * 13. In src/sfstruct.c, add entries to the 'historical' section below the + * existing entry that doesn't have a '_rev0' suffix. You need an 'sfo_' + * entry and an 'sfi_' entry here, because they have to match function + * pointers in another struct. The 'sfo_' function will not be called + * from anywhere. + * + * historical_sfo_rm, + * historical_sfo_rm_rev0, + * ... + * historical_sfi_rm, + * historical_sfi_rm_rev0, + * + * 14. In the C source file where the 'Sfi_' call is made for your struct, + * the current code likely has a line for reading the struct from + * a file, similar the one shown below for the mystruct example: + * + * Sfi_mystruct(nhfp, &svl.mystruct, "mystruct-example"); + * + * That single line will need to modified to become a code block similar + * to this, so that the uplift function will get called: + * + * if (!gu.uplift_needed_rev0_to_rev1) { + * Sfi_mystruct(nhfp, &svl.mystruct, "mystruct-example"); + * } else { + * struct mystruct_rev0 old_mystruct; + * + * Sfi_mystruct_rev0(nhfp, &old_mystruct, "mystruct-example"); + * uplift_mystruct_rev0_to_mystruct(&old_mystruct, &svl.mystruct); + * } + * } + * + * 15. Shortly after the reading of the struct by the 'Sfi_' function, + * if the newer revision of the struct added some new fields, new code + * will be needed to initialize the new fields to sane values. + * There is no data for the new fields in the exising savefile. + * + * if (gu.uplift_needed_rev0_to_rev1 == 1) { + * svl.mystruct.newfielda = sanevalue1; + * svl.mystruct.newfieldb = sanevalue2; + * } + * + * 16. In include/extern.h, add a prototype to the ' ### revision.c ###' + * section for the supporting uplift function: + * + * extern void uplift_mystruct_rev0_to_mystruct(struct mystruct_rev0 *, + * struct mystruct *); + * + * 17. Add the uplift function to src/revision.c. It needs to do + * field-by-field copies of the fields that exist in the old + * revision and the new revision. For now, it likely needs to + * be handcrafted using your knowledge of the struct's old + * and new revisions. + * + * Be sure that any new fields present in the newer revision + * of the struct get set to sane values or initialized to + * zero. Do whatever suits those fields best, based on your + * knowledge of the struct. + * + * void + * uplift_mystruct_rev0_to_mystruct(struct mystruct_rev0 *rev0, + * struct mystruct *rev1) + * { + * rev1->field1 = rev0->field1; + * rev1->field2 = rev0->field2; + * rev1->field3 = rev0->field3; + * rev1->field4 = rev0->field4; + * + * rev1->newfielda = 0; // new field + * rev1->newfieldb = 42; // new field + * } + * + */ + +#if defined(MYSTRUCT_REV0) +#ifdef DEMO_UPLIFTS +/* + * struct mystruct_rev0 + * + * This is the predecessor for 'struct mystruct' + * Revisions to 'struct mystruct' that 'struct mystruct_rev0' does not have: + * int newfielda; + * int newfieldb; + * + * The uplift function is: + * void uplift_mystruct_rev0_to_mystruct(struct *mystruct_rev0, + * struct *mystruct); + */ + +struct mystruct_rev0 { + int field1; + int field2; + char field3; + long field4; +}; +#endif /* DEMO_UPLIFTS */ + +#elif defined(XXX_REV0) + +#else +#error Unproductive inclusion of revision.h +#endif +/* revision.h */ diff --git a/include/savefile.h b/include/savefile.h index bfaea951d..3307de1ca 100644 --- a/include/savefile.h +++ b/include/savefile.h @@ -184,6 +184,10 @@ extern void sfi_int(NHFILE *, int *, const char *); extern void sfi_unsigned(NHFILE *, unsigned *, const char *); extern void sfi_long(NHFILE *, long *, const char *); extern void sfi_ulong(NHFILE *, ulong *, const char *); +#ifdef DEMO_UPLIFTS +extern void sfi_mystruct(NHFILE *, struct mystruct *, const char *); +extern void sfi_mystruct_rev0(NHFILE *, struct mystruct_rev0 *, const char *); +#endif #if NH_C < 202300L #define Sfo_aligntyp(a,b,c) sfo_aligntyp(a, b, c) #define Sfo_any(a,b,c) sfo_any(a, b, c) @@ -315,6 +319,10 @@ extern void sfi_ulong(NHFILE *, ulong *, const char *); #define Sfi_unsigned(a, b, c) sfi_unsigned(a, b, c); #define Sfi_xint8(a, b, c) sfi_xint8(a, b, c); #define Sfi_xint16(a, b, c) sfi_xint16(a, b, c); +#ifdef DEMO_UPLIFTS +#define Sfi_mystruct(a, b, c) sfi_mystruct(a, b, c) +#define Sfi_mystruct_rev0(a, b, c) sfi_mystruct_rev0(a, b, c) +#endif #else #define sfo(nhfp, dt, tag) \ @@ -553,7 +561,7 @@ extern void sfi_ulong(NHFILE *, ulong *, const char *); #define Sfi_dest_area(a,b,c) sfi(a, b, c) #define Sfi_levelflags(a,b,c) sfi(a, b, c) #define Sfi_rm(a,b,c) sfi(a, b, c) -#define Sfi_cemetery(a,b,c) sfi(a, b, c) +#define Sfi_cemetery(a,b,c) sfi_cemetery(a, b, c) #define Sfi_damage(a,b,c) sfi(a, b, c) #define Sfi_stairway(a,b,c) sfi(a, b, c) #define Sfi_obj(a,b,c) sfi(a, b, c) @@ -575,6 +583,10 @@ extern void sfi_ulong(NHFILE *, ulong *, const char *); #define Sfi_unsigned(a, b, c) sfi(a, b, c) #define Sfi_xint8(a, b, c) sfi(a, b, c) #define Sfi_xint16(a, b, c) sfi(a, b, c) +#ifdef DEMO_UPLIFTS +#define Sfi_mystruct(a, b, c) sfi(a, b, c) +#define Sfi_mystruct_rev0(a, b, c) sfi(a, b, c) +#endif #endif /* not in _Generic */ diff --git a/include/sfmacros.h b/include/sfmacros.h index d0bedf69f..0905effaf 100644 --- a/include/sfmacros.h +++ b/include/sfmacros.h @@ -49,6 +49,10 @@ SF_C(struct, s_level) SF_C(struct, trap) SF_C(struct, you) SF_C(union, any) +#ifdef DEMO_UPLIFTS +SF_C(struct, mystruct) +SF_C(struct, mystruct_rev0) +#endif SF_A(aligntyp) SF_A(boolean) diff --git a/include/sfprocs.h b/include/sfprocs.h index f544b04c9..63bb631fe 100644 --- a/include/sfprocs.h +++ b/include/sfprocs.h @@ -68,6 +68,10 @@ SF_PROTO_C(struct, trap); SF_PROTO_C(struct, version_info); SF_PROTO_C(struct, you); SF_PROTO_C(union, any); +#ifdef DEMO_UPLIFTS +SF_PROTO_C(struct, mystruct); +SF_PROTO_C(struct, mystruct_rev0); +#endif SF_PROTO(int16); SF_PROTO(int32); SF_PROTO(int64); @@ -149,6 +153,10 @@ struct sf_procs { SF_ENTRY_C(struct, version_info); SF_ENTRY_C(struct, you); SF_ENTRY_C(union, any); +#ifdef DEMO_UPLIFTS + SF_ENTRY_C(struct, mystruct); + SF_ENTRY_C(struct, mystruct_rev0); +#endif SF_ENTRY(aligntyp); SF_ENTRY(boolean); diff --git a/src/decl.c b/src/decl.c index bb4485705..587c83e90 100644 --- a/src/decl.c +++ b/src/decl.c @@ -770,6 +770,8 @@ static const struct instance_globals_u g_init_u = { FALSE, /* update_all */ /* decl.c */ FALSE, /* unweapon */ + /* revision.c */ + 0, /* uplift_needed_rev0_to_rev1 */ /* role.c */ UNDEFINED_ROLE, /* urole */ UNDEFINED_RACE, /* urace */ diff --git a/src/restore.c b/src/restore.c index fab825de3..870c678f5 100644 --- a/src/restore.c +++ b/src/restore.c @@ -30,6 +30,7 @@ staticfn int restlevelfile(xint8); staticfn void rest_bubbles(NHFILE *); staticfn void restore_gamelog(NHFILE *); staticfn void reset_oattached_mids(boolean); + /* these ones are declared non-static in extern.h if SFCTOOL is defined */ staticfn boolean restgamestate(NHFILE *); staticfn void rest_bubbles(NHFILE *); @@ -900,6 +901,11 @@ dorecover(NHFILE *nhfp) restlevelstate(); program_state.something_worth_saving = 1; /* useful data now exists */ + if (gu.uplift_needed_rev0_to_rev1 == 1) { + /* they've all been uplifted now */ + gu.uplift_needed_rev0_to_rev1 = 0; + } + if (!wizard && !discover) (void) delete_savefile(); if (Is_rogue_level(&u.uz)) diff --git a/src/revision.c b/src/revision.c new file mode 100644 index 000000000..97cdb7750 --- /dev/null +++ b/src/revision.c @@ -0,0 +1,89 @@ +/* NetHack 5.0 revision.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.234 $ */ +/*-Copyright (c) Michael Allison, 2026. */ +/* NetHack may be freely redistributed. See license for details. */ + +#include "hack.h" + +boolean revision_increment( + int file_rev_level, + int file_critical_byte_count, + uchar *csc) +{ + if (file_rev_level == 0 && SAVEFILE_REVISION_LEVEL == 1) { + /* + * Revision 1 + * We set a flag gu.uplift_needed_rev0_to_rev1 for use by restore routines. + * + */ + gu.uplift_needed_rev0_to_rev1 = 1; + if (csc[file_critical_byte_count - 1] == 0) + /* below may not be necessary, or even useful */ + csc[file_critical_byte_count - 1] = SAVEFILE_REVISION_LEVEL; + return TRUE; + } + return FALSE; +} + +#ifdef DEMO_UPLIFTS + +/* original revision 0 is in include/revision.h */ + +/* revision 1 */ +struct mystruct { + int field1; + int field2; + char field3; + long field4; + int newfielda; + int newfieldb; +}; + +void +uplift_mystruct_rev0_to_mystruct(struct mystruct_rev0 *rev0, + struct mystruct *rev1) +{ + rev1->field1 = rev0->field1; + rev1->field2 = rev0->field2; + rev1->field3 = rev0->field3; + rev1->field4 = rev0->field4; + rev1->newfielda = 0; // new field + rev1->newfieldb = 0; // new field +} + +void +read_mystruct(struct mystruct *ms) +{ +#ifdef SAVEFILE_REVISION_LEVEL + +#if (SAVEFILE_REVISION_LEVEL == 0) + Sfi_mystruct(nhfp, ms, "mystruct-example"); +#elif (SAVEFILE_REVISION_LEVEL == 1) + +#define MYSTRUCT_REV0 +#include "revision.h" +#undef MYSTRUCT_REV0 + + if (!gu.uplift_needed_rev0_to_rev1) { + Sfi_mystruct(nhfp, ms, "mystruct-example"); + } else { + struct mystruct_rev0 old_mystruct; + + Sfi_mystruct_rev0(nhfp, &old_mystruct, "mystruct-example"); + uplift_mystruct_rev0_to_mystruct(&old_mystruct, ms); + } + + /* this could be elsewhere in some other sourcefile for example, + * where it is needed */ + if (gu.uplift_needed_rev0_to_rev1 == 1) { + /* Provide suitable starting values for fields that were not + * present in the previous revision that was read */ + ms->newfielda = 0; // new field in Rev. 1 + ms->newfieldb = 42; // new field in Rev. 1 + } +#endif +#endif /* SAVEFILE_REVISION_LEVEL */ +} + +#endif /* DEMO_UPLIFTS */ + +/*revision.c*/ diff --git a/src/sfbase.c b/src/sfbase.c index 00c165c68..b26175b99 100644 --- a/src/sfbase.c +++ b/src/sfbase.c @@ -743,6 +743,10 @@ void norm_ptrs_version_info(struct version_info *d_version_info); void norm_ptrs_vlaunchinfo(union vlaunchinfo *d_vlaunchinfo); void norm_ptrs_vptrs(union vptrs *d_vptrs); void norm_ptrs_you(struct you *d_you); +#ifdef DEMO_UPLIFTS +void norm_ptrs_mystruct(struct mystruct *d_mystruct); +void norm_ptrs_mystruct_rev0(struct mystruct_rev0 *d_mystruct_rev0); +#endif void norm_ptrs_any(union any *d_any UNUSED) @@ -1038,6 +1042,17 @@ norm_ptrs_rm(struct rm *d_rm UNUSED) { } +#ifdef DEMO_UPLIFTS +void +norm_ptrs_mystruct(struct mystruct *d_mystruct UNUSED) +{ +} +void +norm_ptrs_mystruct_rev0(struct mystruct_rev0 *d_mystruct_rev0 UNUSED) +{ +} +#endif + void norm_ptrs_s_level(struct s_level *d_s_level UNUSED) { diff --git a/src/sfstruct.c b/src/sfstruct.c index 3c8b8fd66..424d57c88 100644 --- a/src/sfstruct.c +++ b/src/sfstruct.c @@ -194,7 +194,6 @@ struct sf_structlevel_procs historical_sfo_procs = { historical_sfo_version_info, historical_sfo_you, historical_sfo_any, - historical_sfo_aligntyp, historical_sfo_boolean, historical_sfo_coordxy, @@ -219,6 +218,10 @@ struct sf_structlevel_procs historical_sfo_procs = { historical_sfo_xint8, historical_sfo_char, historical_sfo_bitfield, +#ifdef DEMO_UPLIFTS + historical_sfo_mystruct, + historical_sfo_mystruct_rev0, +#endif } }; @@ -295,6 +298,10 @@ struct sf_structlevel_procs historical_sfi_procs = { historical_sfi_xint8, historical_sfi_char, historical_sfi_bitfield, +#ifdef DEMO_UPLIFTS + historical_sfi_mystruct, + historical_sfi_mystruct_rev0, +#endif } }; diff --git a/src/version.c b/src/version.c index 1958ae5ed..fb92ddbec 100644 --- a/src/version.c +++ b/src/version.c @@ -607,7 +607,7 @@ struct critical_sizes_with_names critical_sizes[] = { { (uchar) sizeof(struct objclass), "struct objclass" }, { (uchar) sizeof(struct oextra), "struct oextra" }, { (uchar) sizeof(struct q_score), "struct q_score" }, - { (uchar) sizeof(struct rm), "struct rm" }, + { (uchar) sizeof(struct rm), "struct rm" }, /* [61] */ { (uchar) sizeof(struct spell), "struct spell" }, { (uchar) sizeof(struct stairway), "struct stairway" }, { (uchar) sizeof(struct s_level), "struct s_level" }, @@ -660,7 +660,7 @@ struct critical_sizes_with_names critical_sizes[] = { { 0, "" }, { 0, "" }, { 0, "" }, - { 0, "" }, + { (uchar) SAVEFILE_REVISION_LEVEL, "savefile_revision_level" }, }; uchar cscbuf[SIZE(critical_sizes)]; @@ -780,6 +780,15 @@ compare_critical_bytes(NHFILE *nhfp, int *idx_1st_mismatch, unsigned long utdfla Sfi_uchar(nhfp, &cscbuf[i], "critical_sizes"); } for (i = 1; i < cnt; ++i) { + if (cscbuf[i] != critical_sizes[i].ucsize && i == cnt - 1) { + /* SAVEFILE_REVISION_LEVEL mismatch; attempt to deal with it */ + int file_rev_level = cscbuf[i]; + + if (revision_increment(file_rev_level, + file_csc_count, + cscbuf)) + continue; + } if (cscbuf[i] != critical_sizes[i].ucsize) { const char *dm = datamodel(0), *dmfile; diff --git a/sys/msdos/Makefile.GCC b/sys/msdos/Makefile.GCC index d7220fc10..1f8107826 100644 --- a/sys/msdos/Makefile.GCC +++ b/sys/msdos/Makefile.GCC @@ -288,18 +288,18 @@ VOBJ14 = $(O)muse.o $(O)music.o $(O)o_init.o $(O)objects.o $(O)objnam. VOBJ15 = $(O)options.o $(O)pickup.o $(O)pline.o $(O)polyself.o $(O)potion.o VOBJ16 = $(O)quest.o $(O)questpgr.o $(O)pager.o $(O)pray.o $(O)priest.o VOBJ17 = $(O)read.o $(O)rect.o $(O)region.o $(O)report.o $(O)restore.o -VOBJ18 = $(O)rip.o $(O)rnd.o $(O)role.o $(O)rumors.o $(O)save.o -VOBJ19 = $(O)selvar.o $(O)sfstruct.o $(O)shk.o $(O)shknam.o $(O)sit.o -VOBJ20 = $(O)sounds.o $(O)sp_lev.o $(O)spell.o $(O)stairs.o $(O)steal.o -VOBJ21 = $(O)steed.o $(O)symbols.o $(O)sys.o $(O)teleport.o $(O)strutil.o -VOBJ22 = $(O)termcap.o $(O)timeout.o $(O)topl.o $(O)topten.o $(O)trap.o -VOBJ23 = $(O)u_init.o $(O)uhitm.o $(O)utf8map.o $(O)vault.o $(O)track.o -VOBJ24 = $(O)vision.o $(O)weapon.o $(O)were.o $(O)wield.o $(O)windows.o -VOBJ25 = $(O)wintty.o $(O)wizard.o $(O)wizcmds.o $(O)worm.o $(O)worn.o -VOBJ26 = $(O)write.o $(O)zap.o $(O)light.o $(O)dlb.o $(REGEX) +VOBJ18 = $(O)revision.o $(O)rip.o $(O)rnd.o $(O)role.o $(O)rumors.o +VOBJ19 = $(O)save.o $(O)selvar.o $(O)sfstruct.o $(O)shk.o $(O)shknam.o +VOBJ20 = $(O)sit.o $(O)sounds.o $(O)sp_lev.o $(O)spell.o $(O)stairs.o +VOBJ21 = $(O)steal.o $(O)steed.o $(O)symbols.o $(O)sys.o $(O)teleport.o +VOBJ22 = $(O)strutil.o $(O)termcap.o $(O)timeout.o $(O)topl.o $(O)topten.o +VOBJ23 = $(O)trap.o $(O)u_init.o $(O)uhitm.o $(O)utf8map.o $(O)vault.o +VOBJ24 = $(O)track.o $(O)vision.o $(O)weapon.o $(O)were.o $(O)wield.o +VOBJ25 = $(O)windows.o $(O)wintty.o $(O)wizard.o $(O)wizcmds.o $(O)worm.o +VOBJ26 = $(O)worn.o $(O)write.o $(O)zap.o $(O)light.o $(O)dlb.o $(REGEX) -SOBJ = $(O)msdos.o $(O)pcsys.o $(O)tty.o $(O)unix.o \ - $(O)video.o $(O)vidtxt.o $(O)pckeys.o +SOBJ = $(O)msdos.o $(O)pcsys.o $(O)tty.o $(O)unix.o \ + $(O)video.o $(O)vidtxt.o $(O)pckeys.o VVOBJ = $(O)version.o diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 71d55b3ce..d89958d10 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -514,21 +514,21 @@ HACK_H = ../src/hack.h-t # all .c that are part of the main NetHack program and are not operating- or # windowing-system specific. Do not include date.c in this list. HACKCSRC ?= allmain.c alloc.c apply.c artifact.c attrib.c ball.c bones.c \ - botl.c calendar.c cmd.c coloratt.c dbridge.c decl.c detect.c dig.c display.c \ - dlb.c do.c do_name.c do_wear.c dog.c dogmove.c dokick.c dothrow.c \ - drawing.c dungeon.c earlyarg.c eat.c end.c engrave.c exper.c explode.c \ - extralev.c files.c fountain.c hack.c hacklib.c \ + botl.c calendar.c cmd.c coloratt.c dbridge.c decl.c detect.c dig.c \ + display.c dlb.c do.c do_name.c do_wear.c dog.c dogmove.c dokick.c \ + dothrow.c drawing.c dungeon.c earlyarg.c eat.c end.c engrave.c \ + exper.c explode.c extralev.c files.c fountain.c hack.c hacklib.c \ getpos.c glyphs.c iactions.c insight.c invent.c isaac64.c light.c \ lock.c mail.c makemon.c mcastu.c mdlib.c mhitm.c \ mhitu.c minion.c mklev.c mkmap.c mkmaze.c mkobj.c mkroom.c mon.c \ mondata.c monmove.c monst.c mplayer.c mthrowu.c muse.c music.c \ nhlua.c nhlsel.c nhlobj.c nhmd4.c o_init.c objects.c objnam.c \ options.c pager.c pickup.c pline.c polyself.c potion.c pray.c \ - priest.c quest.c questpgr.c read.c rect.c region.c report.c restore.c \ - rip.c rnd.c role.c rumors.c save.c selvar.c sfbase.c sfstruct.c \ - shk.c shknam.c sit.c sounds.c sp_lev.c spell.c stairs.c steal.c steed.c \ - strutil.c symbols.c sys.c teleport.c \ - timeout.c topten.c track.c trap.c u_init.c utf8map.c \ + priest.c quest.c questpgr.c read.c rect.c region.c report.c \ + restore.c revision.c rip.c rnd.c role.c rumors.c save.c selvar.c \ + sfbase.c sfstruct.c shk.c shknam.c sit.c sounds.c sp_lev.c \ + spell.c stairs.c steal.c steed.c strutil.c symbols.c sys.c \ + teleport.c timeout.c topten.c track.c trap.c u_init.c utf8map.c \ uhitm.c vault.c version.c vision.c weapon.c were.c wield.c \ windows.c wizard.c wizcmds.c worm.c worn.c write.c zap.c @@ -567,14 +567,13 @@ HACKINCL ?= align.h artifact.h artilist.h attrib.h botl.h \ color.h config.h config1.h context.h coord.h cstd.h decl.h \ defsym.h display.h dlb.h dungeon.h engrave.h extern.h flag.h \ fnamesiz.h func_tab.h global.h warnings.h hack.h lint.h mextra.h \ - mcastu.h \ - micro.h mfndpos.h mkroom.h monattk.h mondata.h monflag.h monst.h \ - monsters.h nhmd4.h obj.h objects.h objclass.h optlist.h patchlevel.h \ - pcconf.h permonst.h prop.h rect.h region.h savefile.h selvar.h sym.h \ - rm.h sp_lev.h spell.h sndprocs.h seffects.h stairs.h sys.h \ - tcap.h timeout.h tradstdc.h trap.h unixconf.h vision.h vmsconf.h \ - wintty.h wincurs.h winX.h winprocs.h wintype.h you.h youprop.h \ - weight.h + mcastu.h micro.h mfndpos.h mkroom.h monattk.h mondata.h monflag.h \ + monst.h monsters.h nhmd4.h obj.h objects.h objclass.h optlist.h \ + patchlevel.h pcconf.h permonst.h prop.h rect.h region.h revision.h \ + savefile.h selvar.h sym.h rm.h sp_lev.h spell.h sndprocs.h \ + seffects.h stairs.h sys.h tcap.h timeout.h tradstdc.h trap.h \ + unixconf.h vision.h vmsconf.h wintty.h wincurs.h winX.h winprocs.h \ + wintype.h you.h youprop.h weight.h HSOURCES ?= $(HACKINCL) dgn_file.h @@ -617,20 +616,20 @@ HOBJ ?= $(TARGETPFX)allmain.o $(TARGETPFX)alloc.o \ $(TARGETPFX)potion.o $(TARGETPFX)pray.o $(TARGETPFX)priest.o \ $(TARGETPFX)quest.o $(TARGETPFX)questpgr.o $(TARGETPFX)read.o \ $(TARGETPFX)rect.o $(TARGETPFX)region.o $(TARGETPFX)report.o \ - $(TARGETPFX)restore.o $(TARGETPFX)rip.o $(TARGETPFX)rnd.o \ - $(TARGETPFX)role.o $(TARGETPFX)rumors.o $(TARGETPFX)save.o \ - $(TARGETPFX)selvar.o $(TARGETPFX)sfbase.o $(TARGETPFX)sfstruct.o \ - $(TARGETPFX)shk.o $(TARGETPFX)shknam.o $(TARGETPFX)sit.o \ - $(TARGETPFX)sounds.o $(TARGETPFX)sp_lev.o $(TARGETPFX)spell.o \ - $(TARGETPFX)stairs.o $(TARGETPFX)symbols.o $(TARGETPFX)sys.o \ - $(TARGETPFX)steal.o $(TARGETPFX)steed.o $(TARGETPFX)strutil.o \ - $(TARGETPFX)teleport.o $(TARGETPFX)timeout.o $(TARGETPFX)topten.o \ - $(TARGETPFX)track.o $(TARGETPFX)trap.o $(TARGETPFX)u_init.o \ - $(TARGETPFX)uhitm.o $(TARGETPFX)utf8map.o $(TARGETPFX)vault.o \ - $(TARGETPFX)vision.o $(TARGETPFX)weapon.o $(TARGETPFX)were.o \ - $(TARGETPFX)wield.o $(TARGETPFX)windows.o $(TARGETPFX)wizard.o \ - $(TARGETPFX)wizcmds.o $(TARGETPFX)worm.o $(TARGETPFX)worn.o \ - $(TARGETPFX)write.o $(TARGETPFX)zap.o \ + $(TARGETPFX)restore.o $(TARGETPFX)revision.o $(TARGETPFX)rip.o \ + $(TARGETPFX)rnd.o $(TARGETPFX)role.o $(TARGETPFX)rumors.o \ + $(TARGETPFX)save.o $(TARGETPFX)selvar.o $(TARGETPFX)sfbase.o \ + $(TARGETPFX)sfstruct.o $(TARGETPFX)shk.o $(TARGETPFX)shknam.o \ + $(TARGETPFX)sit.o $(TARGETPFX)sounds.o $(TARGETPFX)sp_lev.o \ + $(TARGETPFX)spell.o $(TARGETPFX)stairs.o $(TARGETPFX)symbols.o \ + $(TARGETPFX)sys.o $(TARGETPFX)steal.o $(TARGETPFX)steed.o \ + $(TARGETPFX)strutil.o $(TARGETPFX)teleport.o $(TARGETPFX)timeout.o \ + $(TARGETPFX)topten.o $(TARGETPFX)track.o $(TARGETPFX)trap.o \ + $(TARGETPFX)u_init.o $(TARGETPFX)uhitm.o $(TARGETPFX)utf8map.o \ + $(TARGETPFX)vault.o $(TARGETPFX)vision.o $(TARGETPFX)weapon.o \ + $(TARGETPFX)were.o $(TARGETPFX)wield.o $(TARGETPFX)windows.o \ + $(TARGETPFX)wizard.o $(TARGETPFX)wizcmds.o $(TARGETPFX)worm.o \ + $(TARGETPFX)worn.o $(TARGETPFX)write.o $(TARGETPFX)zap.o \ $(REGEXOBJ) $(RANDOBJ) $(SYSOBJ) $(WINOBJ) \ $(HINTOBJ) $(SNDLIBOBJ) $(UUIDOBJ) \ $(TARGETPFX)version.o @@ -907,19 +906,19 @@ $(HACK_H): $(CONFIG_H) ../include/align.h ../include/artilist.h \ ../include/decl.h ../include/defsym.h ../include/display.h \ ../include/dungeon.h ../include/engrave.h ../include/flag.h \ ../include/hack.h ../include/lint.h ../include/mextra.h \ - ../include/mcastu.h \ - ../include/mkroom.h ../include/monattk.h ../include/mondata.h \ - ../include/monflag.h ../include/monst.h ../include/monsters.h \ - ../include/nhlua.h ../include/obj.h ../include/objclass.h \ - ../include/objects.h ../include/permonst.h ../include/prop.h \ - ../include/quest.h ../include/rect.h ../include/region.h \ + ../include/mcastu.h ../include/mkroom.h ../include/monattk.h \ + ../include/mondata.h ../include/monflag.h ../include/monst.h \ + ../include/monsters.h ../include/nhlua.h ../include/obj.h \ + ../include/objclass.h ../include/objects.h \ + ../include/permonst.h ../include/prop.h ../include/quest.h \ + ../include/rect.h ../include/region.h ../include/revision.h \ ../include/rm.h ../include/savefile.h ../include/sfprocs.h \ - ../include/seffects.h ../include/selvar.h \ - ../include/skills.h ../include/sndprocs.h ../include/spell.h \ - ../include/stairs.h ../include/sym.h ../include/sys.h \ - ../include/timeout.h ../include/trap.h ../include/vision.h \ - ../include/weight.h ../include/winprocs.h \ - ../include/wintype.h ../include/you.h ../include/youprop.h + ../include/seffects.h ../include/selvar.h ../include/skills.h \ + ../include/sndprocs.h ../include/spell.h ../include/stairs.h \ + ../include/sym.h ../include/sys.h ../include/timeout.h \ + ../include/trap.h ../include/vision.h ../include/weight.h \ + ../include/winprocs.h ../include/wintype.h ../include/you.h \ + ../include/youprop.h touch $(HACK_H) # $(TARGETPFX)cppregex.o: ../sys/share/cppregex.cpp $(CONFIG_H) @@ -1256,6 +1255,7 @@ $(TARGETPFX)rect.o: rect.c $(HACK_H) $(TARGETPFX)region.o: region.c $(HACK_H) $(TARGETPFX)report.o: report.c $(HACK_H) ../include/dlb.h ../include/nhmd4.h $(TARGETPFX)restore.o: restore.c $(HACK_H) ../include/tcap.h +$(TARGETPFX)revision.o: revision.c $(HACK_H) $(TARGETPFX)rip.o: rip.c $(HACK_H) $(TARGETPFX)rnd.o: rnd.c $(HACK_H) ../include/isaac64.h $(TARGETPFX)role.o: role.c $(HACK_H) diff --git a/sys/vms/Makefile.src b/sys/vms/Makefile.src index 4cdef1436..b810ad946 100644 --- a/sys/vms/Makefile.src +++ b/sys/vms/Makefile.src @@ -157,12 +157,12 @@ HACKCSRC = allmain.c alloc.c apply.c artifact.c attrib.c ball.c bones.c \ monmove.c monst.c mplayer.c mthrowu.c muse.c music.c o_init.c \ objects.c objnam.c options.c pager.c pickup.c pline.c polyself.c \ potion.c pray.c priest.c quest.c questpgr.c read.c rect.c \ - region.c report.c restore.c rip.c rnd.c role.c rumors.c save.c \ - selvar.c sfstruct.c shk.c shknam.c sit.c sounds.c sp_lev.c \ - spell.c stairs.c steal.c steed.c strutil.c sys.c teleport.c \ - timeout.c topten.c track.c trap.c u_init.c uhitm.c vault.c \ - version.c vision.c weapon.c were.c wield.c windows.c wizard.c \ - wizcmds.c worm.c worn.c write.c zap.c + region.c report.c restore.c revision.c rip.c rnd.c role.c \ + rumors.c save.c selvar.c sfstruct.c shk.c shknam.c sit.c sounds.c \ + sp_lev.c spell.c stairs.c steal.c steed.c strutil.c sys.c \ + teleport.c timeout.c topten.c track.c trap.c u_init.c uhitm.c \ + vault.c version.c vision.c weapon.c were.c wield.c windows.c \ + wizard.c wizcmds.c worm.c worn.c write.c zap.c #-# generated source files (vis_tab.c is gone; tile.c is handled separately #-# via WINxxxSRC) @@ -180,11 +180,11 @@ HACKINCL = align.h artifact.h artilist.h attrib.h botl.h \ fnamesiz.h func_tab.h global.h warnings.h hack.h lint.h mextra.h \ micro.h mkroom.h monattk.h mondata.h monflag.h monst.h monsters.h \ mfndpos.h nhmd4.h obj.h objects.h objclass.h optlist.h patchlevel.h \ - pcconf.h permonst.h prop.h rect.h region.h savefile.h selvar.h sym.h \ - rm.h sp_lev.h spell.h sndprocs.h seffects.h stairs.h sys.h \ - tcap.h timeout.h tradstdc.h trap.h unixconf.h vision.h vmsconf.h \ - wintty.h wincurs.h winX.h winprocs.h wintype.h you.h youprop.h \ - weight.h + pcconf.h permonst.h prop.h rect.h region.h revision.h savefile.h \ + selvar.h sym.h rm.h sp_lev.h spell.h sndprocs.h seffects.h \ + stairs.h sys.h tcap.h timeout.h tradstdc.h trap.h unixconf.h \ + vision.h vmsconf.h wintty.h wincurs.h winX.h winprocs.h wintype.h \ + you.h youprop.h weight.h #HSOURCES = $(HACKINCL) date.h onames.h pm.h @@ -575,6 +575,7 @@ read.obj : read.c $(HACK_H) rect.obj : rect.c $(HACK_H) region.obj : region.c $(HACK_H) restore.obj : restore.c $(HACK_H) $(INC)tcap.h +revision.obj : revision.c $(HACK_H) rip.obj : rip.c $(HACK_H) rnd.obj : rnd.c $(HACK_H) role.obj : role.c $(HACK_H) diff --git a/sys/vms/Makefile_src.vms b/sys/vms/Makefile_src.vms index 160ddb95d..31a4963af 100644 --- a/sys/vms/Makefile_src.vms +++ b/sys/vms/Makefile_src.vms @@ -102,7 +102,7 @@ CONFIGBASEH := color config config1 patchlevel tradstdc hacklib integer \ HACKBASEH := hack lint align dungeon wintype sym defsym \ mkroom artilist objclass objects youprop \ prop permonst monattk monflag monsters \ - mondata context rm botl rect region trap \ + mondata context rm botl rect region revision trap \ display vision seffects selvar sndprocs stairs decl \ quest spell obj engrave you attrib monst \ mextra skills timeout flag winprocs sys @@ -800,6 +800,7 @@ $(TARGETPFX)rect.obj: rect.c $(HACK_H) $(TARGETPFX)region.obj: region.c $(HACK_H) $(TARGETPFX)report.obj: report.c $(HACK_H) $(TARGETPFX)restore.obj: restore.c $(HACK_H) $(INCL)tcap.h +$(TARGETPFX)revision.obj: revision.c $(HACK_H) $(TARGETPFX)rip.obj: rip.c $(HACK_H) $(TARGETPFX)rnd.obj: rnd.c $(HACK_H) $(INCL)isaac64.h $(TARGETPFX)role.obj: role.c $(HACK_H) diff --git a/sys/windows/GNUmakefile b/sys/windows/GNUmakefile index cfbcead9e..43de44671 100644 --- a/sys/windows/GNUmakefile +++ b/sys/windows/GNUmakefile @@ -800,8 +800,8 @@ HACK_H = $(CONFIG_H) ../include/align.h ../include/artilist.h \ ../include/nhlua.h ../include/obj.h ../include/objclass.h \ ../include/objects.h ../include/permonst.h ../include/prop.h \ ../include/quest.h ../include/rect.h ../include/region.h \ - ../include/rm.h ../include/savefile.h ../include/sfprocs.h \ - ../include/seffects.h ../include/selvar.h \ + ../include/revision.h ../include/rm.h ../include/savefile.h \ + ../include/sfprocs.h ../include/seffects.h ../include/selvar.h \ ../include/skills.h ../include/sndprocs.h ../include/spell.h \ ../include/stairs.h ../include/sym.h ../include/sys.h \ ../include/timeout.h ../include/trap.h ../include/vision.h \ @@ -1238,7 +1238,7 @@ COREOBJS = $(addsuffix .o, allmain alloc apply artifact attrib ball bones botl \ mon mondata monmove monst mplayer mthrowu muse music \ nhlobj nhlsel nhlua windsound o_init objects objnam options \ pager pickup pline polyself potion pray priest quest questpgr \ - random read rect region report restore rip rnd role rumors \ + random read rect region report restore revision rip rnd role rumors \ save sfbase sfstruct shk shknam sit selvar sounds sp_lev \ spell stairs steal steed strutil \ symbols sys teleport timeout topten track trap u_init uhitm utf8map \ diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index 93df07466..53efb2b84 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -671,17 +671,17 @@ HACKCSRC = \ $(SRC)objnam.c $(SRC)options.c $(SRC)pager.c $(SRC)pickup.c \ $(SRC)pline.c $(SRC)polyself.c $(SRC)potion.c $(SRC)pray.c \ $(SRC)priest.c $(SRC)quest.c $(SRC)questpgr.c $(SRC)read.c \ - $(SRC)rect.c $(SRC)region.c $(SRC)restore.c $(SRC)rip.c \ - $(SRC)rnd.c $(SRC)role.c $(SRC)rumors.c $(SRC)save.c \ - $(SRC)selvar.c $(SRC)sfbase.c $(SRC)sfstruct.c $(SRC)shk.c \ - $(SRC)shknam.c $(SRC)sit.c $(SRC)sounds.c $(SRC)sp_lev.c \ - $(SRC)spell.c $(SRC)stairs.c $(SRC)steal.c $(SRC)steed.c \ - $(SRC)symbols.c $(SRC)sys.c $(SRC)teleport.c $(SRC)timeout.c \ - $(SRC)topten.c $(SRC)track.c $(SRC)trap.c $(SRC)u_init.c \ - $(SRC)uhitm.c $(SRC)utf8map.c $(SRC)vault.c $(SRC)version.c \ - $(SRC)vision.c $(SRC)weapon.c $(SRC)were.c $(SRC)wield.c \ - $(SRC)windows.c $(SRC)wizard.c $(SRC)worm.c $(SRC)worn.c \ - $(SRC)write.c $(SRC)zap.c + $(SRC)rect.c $(SRC)region.c $(SRC)restore.c $(SRC)revision.c \ + $(SRC)rip.c $(SRC)rnd.c $(SRC)role.c $(SRC)rumors.c \ + $(SRC)save.c $(SRC)selvar.c $(SRC)sfbase.c $(SRC)sfstruct.c \ + $(SRC)shk.c $(SRC)shknam.c $(SRC)sit.c $(SRC)sounds.c \ + $(SRC)sp_lev.c $(SRC)spell.c $(SRC)stairs.c $(SRC)steal.c \ + $(SRC)steed.c $(SRC)symbols.c $(SRC)sys.c $(SRC)teleport.c \ + $(SRC)timeout.c $(SRC)topten.c $(SRC)track.c $(SRC)trap.c \ + $(SRC)u_init.c $(SRC)uhitm.c $(SRC)utf8map.c $(SRC)vault.c \ + $(SRC)version.c $(SRC)vision.c $(SRC)weapon.c $(SRC)were.c \ + $(SRC)wield.c $(SRC)windows.c $(SRC)wizard.c $(SRC)worm.c \ + $(SRC)worn.c $(SRC)write.c $(SRC)zap.c # all .h files except date.h HACKINCL = \ @@ -700,15 +700,16 @@ HACKINCL = \ $(INCL)obj.h $(INCL)objects.h $(INCL)objclass.h \ $(INCL)optlist.h $(INCL)patchlevel.h $(INCL)pcconf.h \ $(INCL)permonst.h $(INCL)prop.h $(INCL)rect.h \ - $(INCL)region.h $(INCL)savefile.h $(INCL)selvar.h \ - $(INCL)sfprocs.h $(INCL)sym.h $(INCL)rm.h \ - $(INCL)sp_lev.h $(INCL)spell.h $(INCL)sndprocs.h \ - $(INCL)seffects.h $(INCL)stairs.h $(INCL)sys.h \ - $(INCL)tcap.h $(INCL)timeout.h $(INCL)tradstdc.h \ - $(INCL)trap.h $(INCL)unixconf.h $(INCL)vision.h \ - $(INCL)vmsconf.h $(INCL)wintty.h $(INCL)wincurs.h \ - $(INCL)winX.h $(INCL)winprocs.h $(INCL)wintype.h \ - $(INCL)you.h $(INCL)youprop.h $(INCL)weight.h + $(INCL)region.h $(INCL)revision.h $(INCL)savefile.h \ + $(INCL)selvar.h $(INCL)sfprocs.h $(INCL)sym.h \ + $(INCL)rm.h $(INCL)sp_lev.h $(INCL)spell.h \ + $(INCL)sndprocs.h $(INCL)seffects.h $(INCL)stairs.h \ + $(INCL)sys.h $(INCL)tcap.h $(INCL)timeout.h \ + $(INCL)tradstdc.h $(INCL)trap.h $(INCL)unixconf.h \ + $(INCL)vision.h $(INCL)vmsconf.h $(INCL)wintty.h \ + $(INCL)wincurs.h $(INCL)winX.h $(INCL)winprocs.h \ + $(INCL)wintype.h $(INCL)you.h $(INCL)youprop.h \ + $(INCL)weight.h LUA_FILES = $(DAT)asmodeus.lua $(DAT)baalz.lua $(DAT)bigrm-1.lua \ $(DAT)bigrm-10.lua $(DAT)bigrm-11.lua $(DAT)bigrm-12.lua \ @@ -873,17 +874,17 @@ COREOBJTTY = \ $(OTTY)pickup.o $(OTTY)pline.o $(OTTY)polyself.o $(OTTY)potion.o \ $(OTTY)pray.o $(OTTY)priest.o $(OTTY)quest.o $(OTTY)questpgr.o \ $(OTTY)read.o $(OTTY)rect.o $(OTTY)region.o $(OTTY)report.o \ - $(OTTY)restore.o $(OTTY)rip.o $(OTTY)rnd.o $(OTTY)role.o \ - $(OTTY)rumors.o $(OTTY)save.o $(OTTY)selvar.o $(OTTY)sfbase.o \ - $(OTTY)sfstruct.o $(OTTY)shk.o $(OTTY)shknam.o $(OTTY)sit.o \ - $(OTTY)sounds.o $(OTTY)sp_lev.o $(OTTY)spell.o $(OTTY)stairs.o \ - $(OTTY)steal.o $(OTTY)steed.o $(OTTY)strutil.o $(OTTY)symbols.o \ - $(OTTY)sys.o $(OTTY)teleport.o $(OTTY)timeout.o $(OTTY)topten.o \ - $(OTTY)track.o $(OTTY)trap.o $(OTTY)u_init.o $(OTTY)uhitm.o \ - $(OTTY)utf8map.o $(OTTY)vault.o $(OTTY)vision.o $(OTTY)weapon.o \ - $(OTTY)were.o $(OTTY)wield.o $(OTTY)windows.o $(OTTY)wizard.o \ - $(OTTY)wizcmds.o $(OTTY)worm.o $(OTTY)worn.o $(OTTY)write.o \ - $(OTTY)zap.o + $(OTTY)restore.o $(OTTY)revision.o $(OTTY)rip.o $(OTTY)rnd.o \ + $(OTTY)role.o $(OTTY)rumors.o $(OTTY)save.o $(OTTY)selvar.o \ + $(OTTY)sfbase.o $(OTTY)sfstruct.o $(OTTY)shk.o $(OTTY)shknam.o \ + $(OTTY)sit.o $(OTTY)sounds.o $(OTTY)sp_lev.o $(OTTY)spell.o \ + $(OTTY)stairs.o $(OTTY)steal.o $(OTTY)steed.o $(OTTY)strutil.o \ + $(OTTY)symbols.o $(OTTY)sys.o $(OTTY)teleport.o $(OTTY)timeout.o \ + $(OTTY)topten.o $(OTTY)track.o $(OTTY)trap.o $(OTTY)u_init.o \ + $(OTTY)uhitm.o $(OTTY)utf8map.o $(OTTY)vault.o $(OTTY)vision.o \ + $(OTTY)weapon.o $(OTTY)were.o $(OTTY)wield.o $(OTTY)windows.o \ + $(OTTY)wizard.o $(OTTY)wizcmds.o $(OTTY)worm.o $(OTTY)worn.o \ + $(OTTY)write.o $(OTTY)zap.o OBJSTTY = $(MDLIBTTY) $(COREOBJTTY) $(REGEXTTY) $(RANDOMTTY) @@ -936,17 +937,17 @@ COREOBJGUI = \ $(OGUI)pickup.o $(OGUI)pline.o $(OGUI)polyself.o $(OGUI)potion.o \ $(OGUI)pray.o $(OGUI)priest.o $(OGUI)quest.o $(OGUI)questpgr.o \ $(OGUI)read.o $(OGUI)rect.o $(OGUI)region.o $(OGUI)report.o \ - $(OGUI)restore.o $(OGUI)rip.o $(OGUI)rnd.o $(OGUI)role.o \ - $(OGUI)rumors.o $(OGUI)save.o $(OGUI)selvar.o $(OGUI)sfbase.o \ - $(OGUI)sfstruct.o $(OGUI)shk.o $(OGUI)shknam.o $(OGUI)sit.o \ - $(OGUI)sounds.o $(OGUI)sp_lev.o $(OGUI)spell.o $(OGUI)stairs.o \ - $(OGUI)steal.o $(OGUI)steed.o $(OGUI)strutil.o $(OGUI)symbols.o \ - $(OGUI)sys.o $(OGUI)teleport.o $(OGUI)timeout.o $(OGUI)topten.o \ - $(OGUI)track.o $(OGUI)trap.o $(OGUI)u_init.o $(OGUI)uhitm.o \ - $(OGUI)utf8map.o $(OGUI)vault.o $(OGUI)vision.o $(OGUI)weapon.o \ - $(OGUI)were.o $(OGUI)wield.o $(OGUI)windows.o $(OGUI)wizard.o \ - $(OGUI)wizcmds.o $(OGUI)worm.o $(OGUI)worn.o $(OGUI)write.o \ - $(OGUI)zap.o + $(OGUI)restore.o $(OGUI)revision.o $(OGUI)rip.o $(OGUI)rnd.o \ + $(OGUI)role.o $(OGUI)rumors.o $(OGUI)save.o $(OGUI)selvar.o \ + $(OGUI)sfbase.o $(OGUI)sfstruct.o $(OGUI)shk.o $(OGUI)shknam.o \ + $(OGUI)sit.o $(OGUI)sounds.o $(OGUI)sp_lev.o $(OGUI)spell.o \ + $(OGUI)stairs.o $(OGUI)steal.o $(OGUI)steed.o $(OGUI)strutil.o \ + $(OGUI)symbols.o $(OGUI)sys.o $(OGUI)teleport.o $(OGUI)timeout.o \ + $(OGUI)topten.o $(OGUI)track.o $(OGUI)trap.o $(OGUI)u_init.o \ + $(OGUI)uhitm.o $(OGUI)utf8map.o $(OGUI)vault.o $(OGUI)vision.o \ + $(OGUI)weapon.o $(OGUI)were.o $(OGUI)wield.o $(OGUI)windows.o \ + $(OGUI)wizard.o $(OGUI)wizcmds.o $(OGUI)worm.o $(OGUI)worn.o \ + $(OGUI)write.o $(OGUI)zap.o OBJSGUI = $(MDLIBGUI) $(COREOBJGUI) $(REGEXGUI) $(RANDOMGUI) @@ -3328,6 +3329,7 @@ $(OTTY)rect.o: rect.c $(HACK_H) $(OTTY)region.o: region.c $(HACK_H) $(OTTY)report.o: report.c $(HACK_H) $(INCL)dlb.h $(INCL)nhmd4.h $(OTTY)restore.o: restore.c $(HACK_H) $(INCL)tcap.h +$(OTTY)revision.o: revision.c $(HACK_H) $(OTTY)rip.o: rip.c $(HACK_H) $(OTTY)rnd.o: rnd.c $(HACK_H) $(INCL)isaac64.h $(OTTY)role.o: role.c $(HACK_H) @@ -3708,6 +3710,7 @@ $(OGUI)rect.o: rect.c $(HACK_H) $(OGUI)region.o: region.c $(HACK_H) $(OGUI)report.o: report.c $(HACK_H) $(INCL)dlb.h $(INCL)nhmd4.h $(OGUI)restore.o: restore.c $(HACK_H) $(INCL)tcap.h +$(OGUI)revision.o: revision.c $(HACK_H) $(OGUI)rip.o: rip.c $(HACK_H) $(OGUI)rnd.o: rnd.c $(HACK_H) $(INCL)isaac64.h $(OGUI)role.o: role.c $(HACK_H) diff --git a/sys/windows/vs/NetHack/NetHack.vcxproj b/sys/windows/vs/NetHack/NetHack.vcxproj index 1d29c4f80..2d76aa0b3 100644 --- a/sys/windows/vs/NetHack/NetHack.vcxproj +++ b/sys/windows/vs/NetHack/NetHack.vcxproj @@ -234,6 +234,7 @@ + @@ -312,6 +313,7 @@ + @@ -332,4 +334,4 @@ - \ No newline at end of file + diff --git a/sys/windows/vs/NetHackW/NetHackW.vcxproj b/sys/windows/vs/NetHackW/NetHackW.vcxproj index df2507e81..c3f17f6ea 100644 --- a/sys/windows/vs/NetHackW/NetHackW.vcxproj +++ b/sys/windows/vs/NetHackW/NetHackW.vcxproj @@ -281,6 +281,7 @@ + @@ -386,6 +387,7 @@ + @@ -409,4 +411,4 @@ - \ No newline at end of file + From d7d0e9061a976761563cb1cddd8002ce487832ac Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 27 May 2026 16:44:51 -0400 Subject: [PATCH 389/702] follow-up: trailing whitespace --- include/revision.h | 84 +++++++++++++++++++++++----------------------- src/revision.c | 6 ++-- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/include/revision.h b/include/revision.h index fa324132c..f8ff95acd 100644 --- a/include/revision.h +++ b/include/revision.h @@ -6,12 +6,12 @@ * Supporting revisions to NetHack structs via incemental * uplifts, rather than incrementing EDITLEVEL and breaking * savefile compatibility. - * + * * Here is the contrived example struct we'll use for * this document: - * + * * The old revision: The new revision: - * + * * struct mystruct { struct mystruct { * int field1; int field1; * int field2; int field2; @@ -20,14 +20,14 @@ * }; int newfielda; * int newfieldb; * }; - * + * * Steps (using mystruct as an example name) * * 1. Paste an exact copy of the struct declaration as it is/was * in the previous revision into include/revision.h, shrouded by * #if defined(MYSTRUCT_REV0), and tack a '_rev0' suffix onto the * name of the struct. For example, - * + * * #if defined(MYSTRUCT_REV0) * struct mystruct_rev0 { * int field1; @@ -35,11 +35,11 @@ * char field3; * long field4; * }; - * + * * That goes just ahead of this existing placeholder: - * + * * #elif defined(XXX_REV0) - * + * * 2. Place a comment ahead of the mystruct_rev0 declaration * that explains what has changed, and why the revision * is required. @@ -50,70 +50,70 @@ * #define MYSTRUCT_REV0 * #include "revision.h" * #undef MYSTRUCT_REV0 - * + * * 4. In include/savefile.h, add a new prototype for a function * to read the previous revision from the savefile, ideally * immediately following the prototype for the current active * one that hasn't got the '_rev0' suffix: - * + * * extern void sfi_mystruct(NHFILE *, struct mystruct *, * const char *); * extern void sfi_mystruct_rev0(NHFILE *, struct mystruct_rev0 *, * const char *); - * + * * 5. Also in include/savefile.h, in the '#if NH_C < 202300L' block, * add an entry below the one that should already exist for the * struct that hasn't got the '_rev0' suffix: - * + * * #define Sfi_mystruct(a,b,c) sfi_rm(a, b, c) * #define Sfi_mystruct_rev0(a, b, c) sfi_mystruct_rev0(a, b, c) - * + * * 6. Also in include/savefile.h, in the '#define sfi(nhfp, dt, tag)' * generic function definition, add an entry below the one * that should already exist for the struct name that hasn't * got the '_rev0' suffix: - * + * * struct mystruct * : sfi_rm, \ * struct mystruct_rev0 * : sfi_rm_rev0, \ - * + * * 7. Also in include/savefile.h, a little further down in the * 'Sfi_' macro defininitions, add one below the existing * one for the struct without the '_rev0' suffix: - * + * * #define Sfi_mystruct(a,b,c) sfi(a, b, c) * #define Sfi_mystruct_rev0(a, b, c) sfi(a, b, c) * * Only the input 'Sfi_' is required, because the old revision * will never be written out to a file, only read in from a * a file, so no 'Sfo_' is needed. - * + * * 8. In include/sfmacros.h, add a new entry below the existing * entry that exists without the '_rev0' suffix: - * + * * SF_C(struct, mystruct) * SF_C(struct, mystruct_rev0) - * + * * 9. In include/sfprocs.h, add a new SF_PROTO_C entry below the * existing entry that already exists without the '_rev0' suffix: - * + * * SF_PROTO_C(struct, mystruct); * SF_PROTO_C(struct, mystruct_rev0); - * + * * 10. Also in include/sfprocs.h, add a new SF_ENTRY_C entry below the * entry that already exists without the '_rev0' suffix: - * + * * SF_ENTRY_C(struct, mystruct); * SF_ENTRY_C(struct, mystruct_rev0); - * + * * 11. In src/sfbase.c, add a prototype for a 'norm_ptrs' stub function * below the entry that already exists without the '_rev0' suffix: - * + * * void norm_ptrs_mystruct(struct mystruct *d_mystruct); * void norm_ptrs_mystruct_rev0(struct mystruct_rev0 *d_mystruct); - * + * * 12. Also in src/sfbase.c, add a 'norm_ptrs' stub function below the * stub function that already exists without the '_rev0' suffix: - * + * * void * norm_ptrs_mystruct(struct mystruct *d_mystruct UNUSED) * { @@ -123,28 +123,28 @@ * norm_ptrs_mystruct_rev0(struct mystruct_rev0 *d_mystruct_rev0 UNUSED) * { * } - * + * * 13. In src/sfstruct.c, add entries to the 'historical' section below the - * existing entry that doesn't have a '_rev0' suffix. You need an 'sfo_' + * existing entry that doesn't have a '_rev0' suffix. You need an 'sfo_' * entry and an 'sfi_' entry here, because they have to match function * pointers in another struct. The 'sfo_' function will not be called * from anywhere. - * + * * historical_sfo_rm, * historical_sfo_rm_rev0, * ... * historical_sfi_rm, * historical_sfi_rm_rev0, - * + * * 14. In the C source file where the 'Sfi_' call is made for your struct, - * the current code likely has a line for reading the struct from + * the current code likely has a line for reading the struct from * a file, similar the one shown below for the mystruct example: - * + * * Sfi_mystruct(nhfp, &svl.mystruct, "mystruct-example"); * * That single line will need to modified to become a code block similar * to this, so that the uplift function will get called: - * + * * if (!gu.uplift_needed_rev0_to_rev1) { * Sfi_mystruct(nhfp, &svl.mystruct, "mystruct-example"); * } else { @@ -154,7 +154,7 @@ * uplift_mystruct_rev0_to_mystruct(&old_mystruct, &svl.mystruct); * } * } - * + * * 15. Shortly after the reading of the struct by the 'Sfi_' function, * if the newer revision of the struct added some new fields, new code * will be needed to initialize the new fields to sane values. @@ -164,24 +164,24 @@ * svl.mystruct.newfielda = sanevalue1; * svl.mystruct.newfieldb = sanevalue2; * } - * + * * 16. In include/extern.h, add a prototype to the ' ### revision.c ###' * section for the supporting uplift function: - * + * * extern void uplift_mystruct_rev0_to_mystruct(struct mystruct_rev0 *, * struct mystruct *); - * + * * 17. Add the uplift function to src/revision.c. It needs to do * field-by-field copies of the fields that exist in the old * revision and the new revision. For now, it likely needs to * be handcrafted using your knowledge of the struct's old * and new revisions. - * + * * Be sure that any new fields present in the newer revision * of the struct get set to sane values or initialized to * zero. Do whatever suits those fields best, based on your * knowledge of the struct. - * + * * void * uplift_mystruct_rev0_to_mystruct(struct mystruct_rev0 *rev0, * struct mystruct *rev1) @@ -190,12 +190,12 @@ * rev1->field2 = rev0->field2; * rev1->field3 = rev0->field3; * rev1->field4 = rev0->field4; - * + * * rev1->newfielda = 0; // new field * rev1->newfieldb = 42; // new field * } - * - */ + * + */ #if defined(MYSTRUCT_REV0) #ifdef DEMO_UPLIFTS diff --git a/src/revision.c b/src/revision.c index 97cdb7750..63d2d1225 100644 --- a/src/revision.c +++ b/src/revision.c @@ -13,7 +13,7 @@ boolean revision_increment( /* * Revision 1 * We set a flag gu.uplift_needed_rev0_to_rev1 for use by restore routines. - * + * */ gu.uplift_needed_rev0_to_rev1 = 1; if (csc[file_critical_byte_count - 1] == 0) @@ -26,7 +26,7 @@ boolean revision_increment( #ifdef DEMO_UPLIFTS -/* original revision 0 is in include/revision.h */ +/* original revision 0 is in include/revision.h */ /* revision 1 */ struct mystruct { @@ -54,7 +54,7 @@ void read_mystruct(struct mystruct *ms) { #ifdef SAVEFILE_REVISION_LEVEL - + #if (SAVEFILE_REVISION_LEVEL == 0) Sfi_mystruct(nhfp, ms, "mystruct-example"); #elif (SAVEFILE_REVISION_LEVEL == 1) From 94d3946ef134b61dd34c1070584aa865afd36a75 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 27 May 2026 17:09:43 -0400 Subject: [PATCH 390/702] follow-up: fix a couple of paste errors --- include/revision.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/revision.h b/include/revision.h index f8ff95acd..7bb8bcfc1 100644 --- a/include/revision.h +++ b/include/revision.h @@ -73,8 +73,8 @@ * that should already exist for the struct name that hasn't * got the '_rev0' suffix: * - * struct mystruct * : sfi_rm, \ - * struct mystruct_rev0 * : sfi_rm_rev0, \ + * struct mystruct * : sfi_mystruct, \ + * struct mystruct_rev0 * : sfi_mysruct_rev0, \ * * 7. Also in include/savefile.h, a little further down in the * 'Sfi_' macro defininitions, add one below the existing @@ -130,11 +130,11 @@ * pointers in another struct. The 'sfo_' function will not be called * from anywhere. * - * historical_sfo_rm, - * historical_sfo_rm_rev0, + * historical_sfo_mystruct, + * historical_sfo_mystruct_rev0, * ... - * historical_sfi_rm, - * historical_sfi_rm_rev0, + * historical_sfi_mystruct, + * historical_sfi_mystruct_rev0, * * 14. In the C source file where the 'Sfi_' call is made for your struct, * the current code likely has a line for reading the struct from From e31a104542021c3528ac61a04791e6a63372c483 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Wed, 27 May 2026 17:16:07 -0400 Subject: [PATCH 391/702] This is cron-daily v1-May-7-2026. 000files updated: Files --- Files | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Files b/Files index a520f9beb..c7e0916f8 100644 --- a/Files +++ b/Files @@ -98,13 +98,13 @@ mcastu.h mextra.h mfndpos.h micro.h mkroom.h monattk.h mondata.h monflag.h monst.h monsters.h nhmd4.h nhregex.h obj.h objclass.h objects.h optlist.h patchlevel.h pcconf.h permonst.h prop.h -quest.h rect.h region.h rm.h savefile.h -seffects.h selvar.h sfmacros.h sfprocs.h skills.h -sndprocs.h sp_lev.h spell.h stairs.h sym.h -sys.h tcap.h tileset.h timeout.h tradstdc.h -trap.h unixconf.h vision.h vmsconf.h warnings.h -weight.h winami.h wincurs.h windconf.h winprocs.h -wintype.h you.h youprop.h +quest.h rect.h region.h revision.h rm.h +savefile.h seffects.h selvar.h sfmacros.h sfprocs.h +skills.h sndprocs.h sp_lev.h spell.h stairs.h +sym.h sys.h tcap.h tileset.h timeout.h +tradstdc.h trap.h unixconf.h vision.h vmsconf.h +warnings.h weight.h winami.h wincurs.h windconf.h +winprocs.h wintype.h you.h youprop.h (file for tty versions) wintty.h @@ -289,14 +289,14 @@ mondata.c monmove.c monst.c mplayer.c mthrowu.c muse.c music.c nhlobj.c nhlsel.c nhlua.c nhmd4.c o_init.c objects.c objnam.c options.c pager.c pickup.c pline.c polyself.c potion.c pray.c priest.c quest.c questpgr.c -read.c rect.c region.c report.c restore.c rip.c -rnd.c role.c rumors.c save.c selvar.c sfbase.c -sfstruct.c shk.c shknam.c sit.c sounds.c sp_lev.c -spell.c stairs.c steal.c steed.c strutil.c symbols.c -sys.c teleport.c timeout.c topten.c track.c trap.c -u_init.c uhitm.c utf8map.c vault.c version.c vision.c -weapon.c were.c wield.c windows.c wizard.c wizcmds.c -worm.c worn.c write.c zap.c +read.c rect.c region.c report.c restore.c revision.c +rip.c rnd.c role.c rumors.c save.c selvar.c +sfbase.c sfstruct.c shk.c shknam.c sit.c sounds.c +sp_lev.c spell.c stairs.c steal.c steed.c strutil.c +symbols.c sys.c teleport.c timeout.c topten.c track.c +trap.c u_init.c uhitm.c utf8map.c vault.c version.c +vision.c weapon.c were.c wield.c windows.c wizard.c +wizcmds.c worm.c worn.c write.c zap.c submodules: (files in top directory) From 5d2dc1c85ef393c833be06383f05aa4dbb6ac733 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 27 May 2026 19:25:11 -0400 Subject: [PATCH 392/702] update tested versions of Visual Studio 2026-05-27 --- sys/windows/Makefile.nmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index 53efb2b84..7a3a1064e 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -9,7 +9,7 @@ # # Visual Studio Compilers Tested: # - Microsoft Visual Studio Community 2022 v 17.14.33 -# - Microsoft Visual Studio Community 2026 v 18.6.1 +# - Microsoft Visual Studio Community 2026 v 18.6.2 # #============================================================================== # This is used for building two distinct executables of NetHack: @@ -1190,6 +1190,7 @@ rc=Rc.exe # Recently tested versions: TESTEDVS2022 = 14.44.35225.0 TESTEDVS2026 = 14.51.36244.0 +TESTEDVS2026 = 14.51.36246.0 VS20261ST = 1450000000 VS2026CUR = $(TESTEDVS2026:.=) From 0bf0498155dd7a641c6982d3dd76b06c73e6e78b Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 27 May 2026 19:32:40 -0400 Subject: [PATCH 393/702] add dirs-perms.500 and a default build change The directories and permissions portion of the linux.500 and macOS.500 hints files and their included files has been consolidated to dirs-perms.500. The builder can edit that one file now, to identify the folders that will be utilised as part of the build. Alternatively, you can set those folders and permissions in a make.perms file in the top of the NetHack folder tree and they should take precedence over the ones in dirs-perms.500 because dirs-perms.500 uses '?=' variable assignment, which means "set the value of the variable if no value has been set." * NOTE: BUILD CHANGE * This also makes WANT_SOURCE_INSTALL=1 the default over WANT_SHARED_INSTALL=1, if neither is explicitly set. The new default is the safer and less-impacting default, but it will change where things get installed over earlier Makefile builds. You can be explicit with WANT_SHARED_INSTALL=1 in your make command to get that.. These are the differences between the two: make WANT_SHARED_INSTALL=1 Place the results of the install/update portion of the build into a shared area on a multiuser system. make WANT_SOURCE_INSTALL=1 Place the results of the install/update portion of the build into a subfolder of the source tree, rather than in a system-wide shared area. Also note that the macOS hints file behaves slightly differntly depending on whether WANT_SOURCE_INSTALL=1 was set versus letting it be the default. That's not new, it behaved that way before. --- sys/unix/README.hints | 4 +- sys/unix/hints/include/dirs-perms.500 | 123 ++++++++++++++++++++++++++ sys/unix/hints/linux.500 | 45 ++++------ sys/unix/hints/macOS.500 | 69 ++++----------- 4 files changed, 162 insertions(+), 79 deletions(-) create mode 100644 sys/unix/hints/include/dirs-perms.500 diff --git a/sys/unix/README.hints b/sys/unix/README.hints index 196f32734..a95ae711a 100644 --- a/sys/unix/README.hints +++ b/sys/unix/README.hints @@ -73,13 +73,15 @@ make WANT_ASAN=1 Include support for the address sanitizer in the make WANT_UBSAN=1 Include support for the undefined behaviour sanitizer in the build. -make WANT_SHARE_INSTALL=1 Place the results of the install/update portion +make WANT_SHARED_INSTALL=1 Place the results of the install/update portion of the build into a shared area on a multiuser system. make WANT_SOURCE_INSTALL=1 Place the results of the install/update portion of the build into a subfolder of the source tree, rather than in a system-wide shared area. + (This is now the default if WANT_SHARED_INSTALL=1 + wasn't specified) make WANT_NHUUID=1 Include support for a unique game identifier. On Linux, libuuid and its headers must be installed diff --git a/sys/unix/hints/include/dirs-perms.500 b/sys/unix/hints/include/dirs-perms.500 new file mode 100644 index 000000000..e0277f1f1 --- /dev/null +++ b/sys/unix/hints/include/dirs-perms.500 @@ -0,0 +1,123 @@ +#------------------------------------------------------------------------------ +# NetHack 5.0 directories.500 $NHDT-Date: 1668359835 2022/11/13 17:17:15 $ $NHDT-Branch: NetHack-5.0 $ + +ifndef WANT_SHARED_INSTALL +PREFIX=$(abspath $(NHSROOT)) +SOURCEINSTALL=1 + +# ----------------------------------------- +# This is for the Linux source tree install +# ----------------------------------------- +ifeq "$(WHICH_OS)" "Linux" + +HACKDIR ?=$(PREFIX)/playground +INSTDIR ?=$(HACKDIR) +VARDIR ?=$(HACKDIR) + +GAMEPERM ?= 0700 +VARFILEPERM ?= 0600 +VARDIRPERM ?= 0700 + +else # macOS +# +# ----------------------------------------- +# This is for the macOS source tree install +# ----------------------------------------- +# +# The macOS setup sets things up two different +# ways, depending on whether an explicit +# WANT_SOURCE_INSTALL=1 was given, or not. +ifdef WANT_SOURCE_INSTALL + +HACKDIR ?=$(PREFIX)/playground +CHOWN ?=/usr/bin/true +CHGRP ?=/usr/bin/true + +GAMEPERM ?= 0700 +VARFILEPERM ?= 0600 +VARDIRPERM ?= 0700 +else # WANT_SOURCE_INSTALL not expressed +PREFIX:=$(wildcard ~) +SHELLDIR ?=$(PREFIX)/bin +HACKDIR ?=$(PREFIX)/nethackdir +CHOWN ?=/usr/bin/true +CHGRP ?=/usr/bin/true +GAMEPERM ?= 0700 +VARFILEPERM ?= 0600 +VARDIRPERM ?= 0700 + +endif # WANT_SOURCE_INSTALL + +INSTDIR ?=$(HACKDIR) +VARDIR ?=$(HACKDIR) + +endif # macOS +endif # not WANT_SHARED_INSTALL + +ifneq "$(SOURCEINSTALL)" "1" +ifdef WANT_SHARED_INSTALL +ifeq "$(WHICH_OS)" "Linux" +# ----------------------------------------- +# This is for the Linux system-wide install +# ----------------------------------------- + +PREFIX ?=$(wildcard ~)/nh/install +HACKDIR ?=$(PREFIX)/games/lib/nethackdir +SHELLDIR ?= $(PREFIX)/games +INSTDIR ?=$(HACKDIR) +VARDIR ?=$(HACKDIR) +MANDIR ?=/usr/share/man/man6 + +VARDIRPERM ?= 0755 +VARFILEPERM ?= 0600 +GAMEPERM ?= 0755 + +# ---------------------------------- +# End of Linux system-wide install +# ---------------------------------- + +else # macOS +# ------------------------------------------------ +# This is for the macOS system-wide shared install +# ------------------------------------------------ + +# if $GAMEUID is root, we install into roughly +# proper Mac locations, otherwise we install +# into ~/nethackdir + +ifeq ($(GAMEUID),root) +PREFIX:=/Library/NetHack +SHELLDIR ?=/usr/local/bin +HACKDIR ?=$(PREFIX)/nethackdir +MANDIR ?=/usr/local/share/man/man6 +CHOWN ?=chown +CHGRP ?=chgrp +# We run sgid so the game has access to both HACKDIR +# and user preferences +GAMEPERM ?=02755 + +else # ! root +PREFIX:=/Users/$(GAMEUID) +SHELLDIR ?=$(PREFIX)/bin +HACKDIR ?=$(PREFIX)/Library/NetHack/nethackdir +CHOWN ?=/usr/bin/true +CHGRP ?=/usr/bin/true +GAMEPERM ?= 0500 +endif # ! root + +INSTDIR ?=$(HACKDIR) +VARDIR ?=$(HACKDIR) + +VARFILEPERM ?= 0664 +VARDIRPERM ?= 0775 + +# --------------------------------------- +# End of macOS system-wide shared install +# -------------------------------------- +endif # WHICH_OS? +endif # WANT_SHARED_INSTALL +endif # SOURCEINSTALL != 1 + +#end of dirs-perms.500 +#-------------------------------------- + diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index 64f2bfed6..dd2a2c3e3 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -12,14 +12,9 @@ # And let us know about it. # -#-PRE -# linux.500 hints file provides a single-user build for Linux (such -# as Ubuntu focal). - -# note: '#-INCLUDE' is not just a comment -# multiw-1.500 contains sections 1 to 2 -#-INCLUDE multiw-1.500 +#-PRE xxxx +WHICH_OS=Linux HINTSVERSION := 500 ifdef MAKEFILE_TOP @@ -28,16 +23,29 @@ ifeq ($(MAKELEVEL),0) PRECHECK+=checkmakefiles # all files included from this hints file get listed # in HINTSINCLNAMES (without suffix and without a path) -HINTSINCLNAMES := compiler cross-pre1 cross-pre2 cross-post \ +HINTSINCLNAMES := dirs-perms \ + compiler cross-pre1 cross-pre2 cross-post \ gbdates-pre gbdates-post \ + linuxdistro \ multiw-1 multiw-2 misc \ - multisnd1-pre multisnd2-pre multisnd-post + multisnd1-pre multisnd2-pre multisnd-post \ + response HINTSINCLFILES := $(addsuffix .$(HINTSVERSION), $(HINTSINCLNAMES)) endif endif -#-INCLUDE linuxdistro.500 +# linux.500 hints file provides a single-user build for Linux (such +# as Ubuntu focal). +# note: '#-INCLUDE' is not just a comment +# multiw-1.500 contains sections 1 to 2 +#-INCLUDE multiw-1.500 + +# note: '#-INCLUDE' is not just a comment +# it pulls in the contents of dirs-perms.500 +#-INCLUDE dirs-perms.500 + +#-INCLUDE linuxdistro.500 ifndef LIBXPM LIBXPM= -L/opt/X11/lib -lXpm @@ -523,27 +531,10 @@ SYSCONFENSURE = (if ! test -f $(INSTDIR)/sysconf ; then \ chmod $(VARFILEPERM) $(INSTDIR)/sysconf; fi ); ifdef WANT_SOURCE_INSTALL -PREFIX=$(abspath $(NHSROOT)) -#SHELLDIR= -HACKDIR=$(PREFIX)/playground -GAMEPERM = 0700 -VARFILEPERM = 0600 -VARDIRPERM = 0700 CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE MOREALL=$(MAKE) install -else #!WANT_SOURCE_INSTALL -#PREFIX=/usr -PREFIX=$(wildcard ~)/nh/install -HACKDIR=$(PREFIX)/games/lib/nethackdir -SHELLDIR = $(PREFIX)/games -VARDIRPERM = 0755 -VARFILEPERM = 0600 -GAMEPERM = 0755 endif #?WANT_SOURCE_INSTALL -INSTDIR=$(HACKDIR) -VARDIR = $(HACKDIR) - ifdef MAKEFILE_TOP TESTGDBPATH=/usr/bin/gdb POSTINSTALL+= test -f $(TESTGDBPATH) || \ diff --git a/sys/unix/hints/macOS.500 b/sys/unix/hints/macOS.500 index 5ac7e171c..679fa415d 100755 --- a/sys/unix/hints/macOS.500 +++ b/sys/unix/hints/macOS.500 @@ -17,24 +17,32 @@ # macOS hints file # -# note: '#-INCLUDE' is not just a comment; multiw-1 contains sections 1 to 2 -#-INCLUDE multiw-1.500 - +WHICH_OS=macOS HINTSVERSION := 500 ifdef MAKEFILE_TOP +LUA_VERSION=5.4.8 ifeq ($(MAKELEVEL),0) PRECHECK+=checkmakefiles # all files included from this hints file get listed # in HINTSINCLNAMES (without suffix and without a path) -HINTSINCLNAMES := compiler cross-pre1 cross-pre2 cross-post \ +HINTSINCLNAMES := dirs-perms \ + compiler cross-pre1 cross-pre2 cross-post \ gbdates-pre gbdates-post \ multiw-1 multiw-2 misc \ - multisnd1-pre multisnd2-pre multisnd-post + multisnd1-pre multisnd2-pre multisnd-post \ + response HINTSINCLFILES := $(addsuffix .$(HINTSVERSION), $(HINTSINCLNAMES)) endif endif +# note: '#-INCLUDE' is not just a comment; multiw-1 contains sections 1 to 2 +#-INCLUDE multiw-1.500 + +# note: '#-INCLUDE' is not just a comment +# it pulls in the contents of dirs-perms.500 +#-INCLUDE dirs-perms.500 + ifneq "$(USEMACPORTS)" "1" HAVE_HOMEBREW := $(shell expr `which -s brew; echo $$?` = 0) endif @@ -368,31 +376,11 @@ override LUA2NHTOP = ../.. override LUAMAKEFLAGS=$(LUAFLAGS) endif # GITSUBMODULES -ifdef WANT_SHARE_INSTALL +ifdef WANT_SHARED_INSTALL #ifdef MAKEFILE_SRC -#$(info WANT_SOURCE_INSTALL = $(WANT_SOURCE_INSTALL), WANT_SHARE_INSTALL = $(WANT_SHARE_INSTALL)) +#$(info WANT_SOURCE_INSTALL = $(WANT_SOURCE_INSTALL), WANT_SHARED_INSTALL = $(WANT_SHARED_INSTALL)) #endif -# if $GAMEUID is root, we install into roughly proper Mac locations, otherwise -# we install into ~/nethackdir -ifeq ($(GAMEUID),root) -PREFIX:=/Library/NetHack -SHELLDIR=/usr/local/bin -HACKDIR=$(PREFIX)/nethackdir -CHOWN=chown -CHGRP=chgrp -# We run sgid so the game has access to both HACKDIR and user preferences. -GAMEPERM = 02755 -else # ! root -PREFIX:=/Users/$(GAMEUID) -SHELLDIR=$(PREFIX)/bin -HACKDIR=$(PREFIX)/Library/NetHack/nethackdir -CHOWN=/usr/bin/true -CHGRP=/usr/bin/true -GAMEPERM = 0500 -endif # ! root -VARFILEPERM = 0664 -VARDIRPERM = 0775 ROOTCHECK= [[ `id -u` == 0 ]] || ( echo "Must run install with sudo."; exit 1) # XXX it's nice we don't write over sysconf, but we've already erased it # make sure we have group GAMEUID and group GAMEGRP @@ -409,17 +397,8 @@ PREINSTALL= . sys/unix/hints/macosx.sh user2 $(GAMEUID); \ else ifdef WANT_SOURCE_INSTALL #ifdef MAKEFILE_SRC -#$(info WANT_SOURCE_INSTALL = $(WANT_SOURCE_INSTALL), WANT_SHARE_INSTALL = $(WANT_SHARE_INSTALL)) +#$(info WANT_SOURCE_INSTALL = $(WANT_SOURCE_INSTALL), WANT_SHARED_INSTALL = $(WANT_SHARED_INSTALL)) #endif -PREFIX=$(abspath $(NHSROOT)) -# suppress nethack.sh -#SHELLDIR= -HACKDIR=$(PREFIX)/playground -CHOWN=/usr/bin/true -CHGRP=/usr/bin/true -GAMEPERM = 0700 -VARFILEPERM = 0600 -VARDIRPERM = 0700 POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; # We can use "make all" to build the whole thing - but it misses some things: @@ -429,17 +408,8 @@ CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE else # !WANT_SOURCE_INSTALL #ifdef MAKEFILE_SRC -#$(info WANT_SOURCE_INSTALL = $(WANT_SOURCE_INSTALL), WANT_SHARE_INSTALL = $(WANT_SHARE_INSTALL)) +#$(info WANT_SOURCE_INSTALL = $(WANT_SOURCE_INSTALL), WANT_SHARED_INSTALL = $(WANT_SHARED_INSTALL)) #endif -PREFIX:=$(wildcard ~) -SHELLDIR=$(PREFIX)/bin -HACKDIR=$(PREFIX)/nethackdir -CHOWN=/usr/bin/true -CHGRP=/usr/bin/true -GAMEPERM = 0700 -VARFILEPERM = 0600 -VARDIRPERM = 0700 - ifdef ($(WANT_DEFAULT),X11) # install nethack.rc as ~/.nethackrc if no ~/.nethackrc exists PREINSTALL+= cp -n win/X11/nethack.rc ~/.nethackrc || true; @@ -451,10 +421,7 @@ POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/s $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; \ chmod $(VARFILEPERM) $(HACKDIR)/sysconf; -endif # !WANT_SHARE_INSTALL - -INSTDIR=$(HACKDIR) -VARDIR=$(HACKDIR) +endif # !WANT_SHARED_INSTALL SYSCONFCREATE = sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf SYSCONFINSTALL = $(SYSCONFCREATE) && \ From 38d8d2972db7a8264e7b25e722f827e036aa1c9b Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 27 May 2026 20:05:59 -0400 Subject: [PATCH 394/702] README 3.6 vestige --- README | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README b/README index 4603e1033..76722294b 100644 --- a/README +++ b/README @@ -142,13 +142,13 @@ If a feature is not accepted you are free, of course, to post the patches to the net yourself and let the marketplace decide their worth. All of this amounts to the following: If you decide to apply a free-lanced -patch to your 3.6 code, you are welcome to do so, of course, but we won't -be able to provide support or receive bug reports for it. +patch to your NetHack 5.0 code, you are welcome to do so, of course, but we +won't be able to provide support or receive bug reports for it. In our own patches, we will assume that your code is synchronized with ours. -- Good luck, and happy Hacking -- -# $NHDT-Date: 1652133501 2022/05/09 21:58:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.97 $ +# $NHDT-Date: 1779926755 2026/05/28 00:05:55 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.113 $ # Copyright (c) 2012 by Michael Allison # NetHack may be freely redistributed. See license for details. From f88d410ba2e443c335562b18e415b266fa8bb8d6 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 27 May 2026 20:14:50 -0400 Subject: [PATCH 395/702] typos --- include/revision.h | 8 ++++---- src/revision.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/revision.h b/include/revision.h index 7bb8bcfc1..efb21bb30 100644 --- a/include/revision.h +++ b/include/revision.h @@ -1,9 +1,9 @@ -/* NetHack 5.0 revision.h $NHDT-Date: 1706213796 2024/01/25 20:16:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ +/* NetHack 5.0 revision.h $NHDT-Date: 1779927286 2026/05/28 00:14:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ */ /* Copyright (c) Michael Allison, 2026. */ /* NetHack may be freely redistributed. See license for details. */ /* - * Supporting revisions to NetHack structs via incemental + * Supporting revisions to NetHack structs via incremental * uplifts, rather than incrementing EDITLEVEL and breaking * savefile compatibility. * @@ -77,7 +77,7 @@ * struct mystruct_rev0 * : sfi_mysruct_rev0, \ * * 7. Also in include/savefile.h, a little further down in the - * 'Sfi_' macro defininitions, add one below the existing + * 'Sfi_' macro definitions, add one below the existing * one for the struct without the '_rev0' suffix: * * #define Sfi_mystruct(a,b,c) sfi(a, b, c) @@ -158,7 +158,7 @@ * 15. Shortly after the reading of the struct by the 'Sfi_' function, * if the newer revision of the struct added some new fields, new code * will be needed to initialize the new fields to sane values. - * There is no data for the new fields in the exising savefile. + * There is no data for the new fields in the existing savefile. * * if (gu.uplift_needed_rev0_to_rev1 == 1) { * svl.mystruct.newfielda = sanevalue1; diff --git a/src/revision.c b/src/revision.c index 63d2d1225..161c1508b 100644 --- a/src/revision.c +++ b/src/revision.c @@ -1,5 +1,5 @@ -/* NetHack 5.0 revision.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.234 $ */ -/*-Copyright (c) Michael Allison, 2026. */ +/* NetHack 5.0 revision.c $NHDT-Date: 1779927286 2026/05/28 00:14:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.1 $ */ +/* Copyright (c) Michael Allison, 2026. */ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" From 4e80fda31213b1ef293e0f7a6b88d46516c0faca Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 27 May 2026 20:51:51 -0400 Subject: [PATCH 396/702] build fix for util --- src/version.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/version.c b/src/version.c index fb92ddbec..117d7bdf0 100644 --- a/src/version.c +++ b/src/version.c @@ -779,7 +779,9 @@ compare_critical_bytes(NHFILE *nhfp, int *idx_1st_mismatch, unsigned long utdfla for (i = 0; i < (int) file_csc_count; ++i) { Sfi_uchar(nhfp, &cscbuf[i], "critical_sizes"); } + for (i = 1; i < cnt; ++i) { +#ifndef SFCTOOL if (cscbuf[i] != critical_sizes[i].ucsize && i == cnt - 1) { /* SAVEFILE_REVISION_LEVEL mismatch; attempt to deal with it */ int file_rev_level = cscbuf[i]; @@ -789,6 +791,7 @@ compare_critical_bytes(NHFILE *nhfp, int *idx_1st_mismatch, unsigned long utdfla cscbuf)) continue; } +#endif if (cscbuf[i] != critical_sizes[i].ucsize) { const char *dm = datamodel(0), *dmfile; From 6c950d958f920285fc29b2c16462587c951a530c Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 27 May 2026 20:58:29 -0400 Subject: [PATCH 397/702] util project needed strutil.c and alloc.c It was using dupstr(), so strutil had to be added to the project. --- sys/windows/vs/sftags/sftags.vcxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/windows/vs/sftags/sftags.vcxproj b/sys/windows/vs/sftags/sftags.vcxproj index fb1aa0c66..a712fd925 100644 --- a/sys/windows/vs/sftags/sftags.vcxproj +++ b/sys/windows/vs/sftags/sftags.vcxproj @@ -35,6 +35,8 @@ + + 17.0 From a9401fd78af5ad691d1837c42eb08e81ce459656 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 27 May 2026 23:02:19 -0400 Subject: [PATCH 398/702] =?UTF-8?q?Guidebook=20bits=20for=20Jon=20W=C3=A4t?= =?UTF-8?q?te=20(Jon=20W{tte)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no unintentional spelling mistake. Close #1523 --- doc/Guidebook.mn | 4 ++-- doc/tmac.nh | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index d90b4c4fd..b586163bd 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -6549,7 +6549,7 @@ developed NetHack 3.1 for the Amiga. \fBCarl Schelin\fP, \fBStephen Spackman\fP, \fBSteve VanDevender\fP, and \fBPaul Winner\fP, ported NetHack 3.1 to the PC. .pg -\fBJon W{tte\fP and \fBHao-yang Wang\fP, with help from \fBRoss Brown\fP, +\fB\*(JW\fP and \fBHao-yang Wang\fP, with help from \fBRoss Brown\fP, \fBMike Engber\fP, \fBDavid Hairston\fP, \fBMichael Hamel\fP, \fBJonathan Handler\fP, \fBJohnny Lee\fP, \fBTim Lennan\fP, \fBRob Menke\fP, and \fBAndy Swanson\fP, developed NetHack 3.1 for the Macintosh, @@ -6907,7 +6907,7 @@ Bart House John Kallen Pat Rankin Benson I. Margulies John Rupley Patric Mueller Bill Dyer John S. Bien Paul Winner Boudewijn Waijers Johnny Lee Pierre Martineau -Bruce Cox Jon W{tte Ralf Brown +Bruce Cox \*(JW Ralf Brown Bruce Holloway Jonathan Handler Ray Chason Bruce Mewborne Joshua Delahunty Richard Addison Cameron Root Karl Garrison Richard Beigel diff --git a/doc/tmac.nh b/doc/tmac.nh index a109c66af..aa2ed2a56 100644 --- a/doc/tmac.nh +++ b/doc/tmac.nh @@ -139,4 +139,6 @@ .\" before/after last/first 2 characters of a word. .ie \n(.g .hy 12 .el .hy 14 +.ds JW Jon W{tte\" +.if \n(.g .if !'\*[.T]'ascii' .ds Jw Jon W\(:atte .\"tmac.nh/" From f47edf59c3d280fde03d456dc8b08e7bfa0d2665 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 28 May 2026 11:17:46 -0400 Subject: [PATCH 399/702] Guidebook update Make it clear that the *DIR options are not available on Unix. Related to discussion on GitHub Issue #1552 --- doc/Guidebook.mn | 14 +++++++++++++- doc/Guidebook.tex | 8 +++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index b586163bd..2d16be04b 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -60,7 +60,7 @@ .ds f0 \*(vr .ds f1 \" empty .\"DO NOT REMOVE NH_DATESUB .ds f2 Date(%B %-d, %Y) -.ds f2 May 25, 2026 +.ds f2 May 28, 2026 . .\" A note on some special characters: .\" \(lq = left double quote @@ -3678,22 +3678,34 @@ OPTIONS=!legacy,autopickup,pickup_types:$\(dq=/!?+ .ft .ed .lp HACKDIR +[not availabe on Unix] +.br Default location of files NetHack needs. On Windows HACKDIR defaults to the location of the NetHack.exe or NetHackw.exe file so setting HACKDIR to override that is not usually necessary or recommended. .lp LEVELDIR +[not availabe on Unix] +.br The location that in-progress level files are stored. Defaults to HACKDIR, must be writable. .lp SAVEDIR +[not availabe on Unix] +.br The location where saved games are kept. Defaults to HACKDIR, must be writable. .lp BONESDIR +[not availabe on Unix] +.br The location that bones files are kept. Defaults to HACKDIR, must be writable. .lp LOCKDIR +[not availabe on Unix] +.br The location that file synchronization locks are stored. Defaults to HACKDIR, must be writable. .lp TROUBLEDIR +[not availabe on Unix] +.br The location that a record of game aborts and self-diagnosed game problems is kept. Defaults to HACKDIR, must be writable. .\" diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 5ce42112e..9f12cee0b 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -25,7 +25,7 @@ \author{Original version - Eric S. Raymond\\ (Edited and expanded for 5.0.0 by Mike Stephenson and others)} %DO NOT REMOVE NH_DATESUB \date{Date(%B %-d, %Y)} -\date{May 25, 2026} +\date{May 28, 2026} \maketitle @@ -3980,27 +3980,33 @@ Example: %.lp \item[HACKDIR] +{[}Not available on Unix{}]\\ Default location of files \textit{NetHack} needs. On Windows HACKDIR defaults to the location of the \textit{NetHack.exe} or \textit{NetHackw.exe} file so setting HACKDIR to override that is not usually necessary or recommended. %.lp \item[LEVELDIR] +{[}Not available on Unix{}]\\ The location that in-progress level files are stored. Defaults to HACKDIR, must be writable. %.lp \item[SAVEDIR] +{[}Not available on Unix{}]\\ The location where saved games are kept. Defaults to HACKDIR, must be writable. %.lp \item[BONESDIR] +{[}Not available on Unix{}]\\ The location that bones files are kept. Defaults to HACKDIR, must be writable. %.lp \item[LOCKDIR] +{[}Not available on Unix{}]\\ The location that file synchronization locks are stored. Defaults to HACKDIR, must be writable. %.lp \item[TROUBLEDIR] +{[}Not available on Unix{}]\\ The location that a record of game aborts and self-diagnosed game problems is kept. Defaults to HACKDIR, must be writable. % From 29380dfdb9fbef3eeeb99ac6ff5d4bf2b7581435 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 28 May 2026 11:32:06 -0400 Subject: [PATCH 400/702] follow-up: TeX doesn't require special handling for ']' --- doc/Guidebook.tex | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 9f12cee0b..7e51aa3de 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -3980,33 +3980,33 @@ Example: %.lp \item[HACKDIR] -{[}Not available on Unix{}]\\ +{[}Not available on Unix]\\ Default location of files \textit{NetHack} needs. On Windows HACKDIR defaults to the location of the \textit{NetHack.exe} or \textit{NetHackw.exe} file so setting HACKDIR to override that is not usually necessary or recommended. %.lp \item[LEVELDIR] -{[}Not available on Unix{}]\\ +{[}Not available on Unix]\\ The location that in-progress level files are stored. Defaults to HACKDIR, must be writable. %.lp \item[SAVEDIR] -{[}Not available on Unix{}]\\ +{[}Not available on Unix]\\ The location where saved games are kept. Defaults to HACKDIR, must be writable. %.lp \item[BONESDIR] -{[}Not available on Unix{}]\\ +{[}Not available on Unix]\\ The location that bones files are kept. Defaults to HACKDIR, must be writable. %.lp \item[LOCKDIR] -{[}Not available on Unix{}]\\ +{[}Not available on Unix]\\ The location that file synchronization locks are stored. Defaults to HACKDIR, must be writable. %.lp \item[TROUBLEDIR] -{[}Not available on Unix{}]\\ +{[}Not available on Unix]\\ The location that a record of game aborts and self-diagnosed game problems is kept. Defaults to HACKDIR, must be writable. % From 5f817fe9ad6cf8abad9b18733250be396b8dc6a4 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Thu, 28 May 2026 20:32:36 +0200 Subject: [PATCH 401/702] glyphs: code-review fixes and parse_id off-by-one - cmap_offset was calculated on every compose_glyph_name() call; calculate it once with a static function. - Drop parse_id's G_ auto-populate: an unbracketed lookup allocated the index with no matching free. Linear-scan instead when absent. - compose_glyph_name: require bufsz >= BUFSZ, build names with bounded Snprintf instead of Strcpy/Strcat, drop the dead memchr. - parse_id's permonst scan used i <= pm_count, reading one past the SYM_MON block (S_nothing) and matching it as a monster; use <. - Drop a stale NO_GLYPH empty-bucket comment from the open-addressed table. --- src/glyphs.c | 104 +++++++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 49 deletions(-) diff --git a/src/glyphs.c b/src/glyphs.c index 1d57a4e78..226a7f208 100644 --- a/src/glyphs.c +++ b/src/glyphs.c @@ -28,7 +28,7 @@ struct find_struct { static const struct find_struct zero_find = { 0 }; struct glyphname_hash_index_entry_t { uint32 hash; - int glyphnum; /* NO_GLYPH (==MAX_GLYPH) marks an empty bucket */ + int glyphnum; }; static struct glyphname_hash_index_entry_t *glyphname_hash_indices_ptr; static size_t glyphname_hash_indices_count; @@ -39,6 +39,7 @@ staticfn int find_glyph_in_hashtable(const char *id); staticfn int cmp_glyphname_entry(const void *a, const void *b); staticfn uint32 glyph_hash(const char *id); staticfn int compose_glyph_name(int glyph, char *buf, size_t bufsz); +staticfn int get_cmap_offset(void); staticfn void to_custom_symset_entry_callback(int glyph, struct find_struct *findwhat); staticfn int parse_id(const char *id, struct find_struct *findwhat); @@ -194,32 +195,46 @@ fix_glyphname(char *str) return str; } +/* First SYM_PCHAR index in loadsyms[], cached (0 = not computed yet; + SYM_PCHAR is never at index 0). */ +static int cached_cmap_offset = 0; + +staticfn int +get_cmap_offset(void) +{ + if (!cached_cmap_offset) { + int i; + + for (i = 0; loadsyms[i].range; i++) { + if (loadsyms[i].range == SYM_PCHAR) { + cached_cmap_offset = i; + break; + } + } + } + return cached_cmap_offset; +} + /* Build the canonical "G_xxx" identifier for the given glyph into buf. * Returns 1 if a name was produced, 0 if this glyph has no canonical name * (a few unused object indices); buf[0] is set to '\0' in that case. - * Used by parse_id's bulk-iteration paths, by find_glyph_in_hashtable to - * verify hash matches, by populate_glyphname_hash_indices to fill the table, - * and by wizcustom_glyphnames. */ + * Callers must pass a BUFSZ-sized buffer. + * Used by find_glyph_in_hashtable to verify hash matches, by the + * --dumpglyphnames path, by populate_glyphname_hash_indices to fill the + * table, and by wizcustom_glyphnames. */ staticfn int compose_glyph_name(int glyph, char *buf, size_t bufsz) { - int i, j, mnum, cmap_offset = 0; + int i, j, mnum, cmap_offset; boolean skip_base = FALSE; const char *buf2, *buf3, *buf4; char tmpbuf[4][QBUFSZ]; - if (bufsz < 2) + if (bufsz < BUFSZ) return 0; buf[0] = '\0'; tmpbuf[0][0] = tmpbuf[1][0] = tmpbuf[2][0] = tmpbuf[3][0] = '\0'; - - /* compute cmap_offset (the start of SYM_PCHAR entries in loadsyms[]) */ - i = 0; - while (loadsyms[i].range) { - if (!cmap_offset && loadsyms[i].range == SYM_PCHAR) - cmap_offset = i; - i++; - } + cmap_offset = get_cmap_offset(); if (glyph_is_monster(glyph)) { buf2 = ""; @@ -241,15 +256,11 @@ compose_glyph_name(int glyph, char *buf, size_t bufsz) } else if (glyph_is_female_pet(glyph)) { buf2 = "pet_female_"; } - Strcpy(buf, "G_"); - Strcat(buf, buf2); - Strcat(buf, buf3); + Snprintf(buf, bufsz, "G_%s%s", buf2, buf3); } else if (glyph_is_body(glyph)) { buf2 = glyph_is_body_piletop(glyph) ? "piletop_body_" : "body_"; buf3 = monsdump[glyph_to_body_corpsenm(glyph)].nm; - Strcpy(buf, "G_"); - Strcat(buf, buf2); - Strcat(buf, buf3); + Snprintf(buf, bufsz, "G_%s%s", buf2, buf3); } else if (glyph_is_statue(glyph)) { buf2 = glyph_is_fem_statue_piletop(glyph) ? "piletop_statue_of_female_" @@ -261,9 +272,7 @@ compose_glyph_name(int glyph, char *buf, size_t bufsz) ? "statue_of_male_" : ""; buf3 = monsdump[glyph_to_statue_corpsenm(glyph)].nm; - Strcpy(buf, "G_"); - Strcat(buf, buf2); - Strcat(buf, buf3); + Snprintf(buf, bufsz, "G_%s%s", buf2, buf3); } else if (glyph_is_object(glyph)) { i = glyph_to_obj(glyph); if (((i > SCR_STINKING_CLOUD) && (i < SCR_MAIL)) @@ -290,12 +299,10 @@ compose_glyph_name(int glyph, char *buf, size_t bufsz) : obj_descr[i].oc_name ? obj_descr[i].oc_name : obj_descr[i].oc_descr; - Strcpy(buf, "G_"); - if (glyph_is_normal_piletop_obj(glyph) - || glyph_is_piletop_generic_obj(glyph)) - Strcat(buf, "piletop_"); - Strcat(buf, buf2); - Strcat(buf, buf3); + Snprintf(buf, bufsz, "G_%s%s%s", + (glyph_is_normal_piletop_obj(glyph) + || glyph_is_piletop_generic_obj(glyph)) ? "piletop_" : "", + buf2, buf3); } else if (glyph_is_cmap(glyph) || glyph_is_cmap_zap(glyph) || glyph_is_swallow(glyph) || glyph_is_explosion(glyph)) { int cmap = -1; @@ -368,10 +375,8 @@ compose_glyph_name(int glyph, char *buf, size_t bufsz) j = glyph - GLYPH_SWALLOW_OFF; cmap = glyph_to_swallow(glyph); mnum = j / ((S_sw_br - S_sw_tl) + 1); - Strcpy(tmpbuf[3], "swallow "); - Strcat(tmpbuf[3], monsdump[mnum].nm); - Strcat(tmpbuf[3], " "); - Strcat(tmpbuf[3], swallow_texts[cmap]); + Snprintf(tmpbuf[3], sizeof tmpbuf[3], "swallow %s %s", + monsdump[mnum].nm, swallow_texts[cmap]); buf3 = tmpbuf[3]; skip_base = TRUE; } else if (glyph_is_explosion(glyph)) { @@ -401,16 +406,13 @@ compose_glyph_name(int glyph, char *buf, size_t bufsz) if (cmap >= 0 && cmap < MAXPCHARS) buf3 = loadsyms[cmap + cmap_offset].name + 2; } - Strcpy(buf, "G_"); - Strcat(buf, buf2); - Strcat(buf, buf3); - Strcat(buf, buf4); + Snprintf(buf, bufsz, "G_%s%s%s", buf2, buf3, buf4); } else if (glyph_is_invisible(glyph)) { - Strcpy(buf, "G_invisible"); + Snprintf(buf, bufsz, "G_invisible"); } else if (glyph_is_nothing(glyph)) { - Strcpy(buf, "G_nothing"); + Snprintf(buf, bufsz, "G_nothing"); } else if (glyph_is_unexplored(glyph)) { - Strcpy(buf, "G_unexplored"); + Snprintf(buf, bufsz, "G_unexplored"); } else if (glyph_is_warning(glyph)) { j = glyph - GLYPH_WARNING_OFF; Snprintf(buf, bufsz, "G_%s%d", "warning", j); @@ -418,11 +420,6 @@ compose_glyph_name(int glyph, char *buf, size_t bufsz) if (buf[0] == '\0') return 0; - if (memchr(buf, '\0', bufsz) == NULL) { - /* defensive: caller passed an undersized buffer */ - buf[bufsz - 1] = '\0'; - return 0; - } fix_glyphname(buf + 2); nhUse(mnum); return 1; @@ -1036,10 +1033,8 @@ parse_id( } } if (is_G && id) { - /* Populate the hash table lazily, on first G_xxx lookup. */ - if (!glyphname_hash_indices_ptr) - populate_glyphname_hash_indices(); if (glyphname_hash_indices_ptr) { + /* Fast path: bsearch the populated index. */ int val = find_glyph_in_hashtable(id); if (val >= 0) { @@ -1048,6 +1043,17 @@ parse_id( findwhat->loadsyms_offset = 0; return 1; } + } else { + /* Unpopulated: linear scan, no alloc. */ + for (glyph = 0; glyph < MAX_GLYPH; ++glyph) { + if (compose_glyph_name(glyph, buf, sizeof buf) + && !strcmpi(id, buf)) { + findwhat->findtype = find_glyph; + findwhat->val = glyph; + findwhat->loadsyms_offset = 0; + return 1; + } + } } return 0; } @@ -1079,7 +1085,7 @@ parse_id( } } /* permonst entries */ - for (i = 0; i <= pm_count; ++i) { + for (i = 0; i < pm_count; ++i) { if (!strcmpi(loadsyms[i + pm_offset].name + 2, id + 2)) { findwhat->findtype = find_pm; findwhat->val = i + 1; /* starts at 1 */ From 883620699f027e45d6913027c8e1cb91a7db229d Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 28 May 2026 17:43:02 -0400 Subject: [PATCH 402/702] Guidebook.txt update Created from make. The cron repo did not have today's updates. --- doc/Guidebook.txt | 2580 ++++++++++++++++++++++----------------------- 1 file changed, 1290 insertions(+), 1290 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index d5a6ffd11..67dbc3524 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,25 +15,25 @@ Original version - Eric S. Raymond (Edited and expanded for NetHack 5.0.0 by Mike Stephenson and others) - May 25, 2026 + May 28, 2026 1. Introduction Recently, you have begun to find yourself unfulfilled and distant - in your daily occupation. Strange dreams of prospecting, stealing, - crusading, and combat have haunted you in your sleep for many months, - but you aren't sure of the reason. You wonder whether you have in - fact been having those dreams all your life, and somehow managed to - forget about them until now. Some nights you awaken suddenly and cry - out, terrified at the vivid recollection of the strange and powerful - creatures that seem to be lurking behind every corner of the dungeon - in your dream. Could these details haunting your dreams be real? As + in your daily occupation. Strange dreams of prospecting, stealing, + crusading, and combat have haunted you in your sleep for many months, + but you aren't sure of the reason. You wonder whether you have in + fact been having those dreams all your life, and somehow managed to + forget about them until now. Some nights you awaken suddenly and cry + out, terrified at the vivid recollection of the strange and powerful + creatures that seem to be lurking behind every corner of the dungeon + in your dream. Could these details haunting your dreams be real? As each night passes, you feel the desire to enter the mysterious caverns near the ruins grow stronger. Each morning, however, you quickly put the idea out of your head as you recall the tales of those who entered - the caverns before you and did not return. Eventually you can resist + the caverns before you and did not return. Eventually you can resist the yearning to seek out the fantastic place in your dreams no longer. After all, when other adventurers came back this way after spending time in the caverns, they usually seemed better off than when they @@ -41,15 +41,15 @@ who did not return had not just kept going? Asking around, you hear about a bauble, called the Amulet of Yen- - dor by some, which, if you can find it, will bring you great wealth. - One legend you were told even mentioned that the one who finds the + dor by some, which, if you can find it, will bring you great wealth. + One legend you were told even mentioned that the one who finds the amulet will be granted immortality by the gods. The amulet is rumored to be somewhere beyond the Valley of Gehennom, deep within the Mazes of Menace. Upon hearing the legends, you immediately realize that there is some profound and undiscovered reason that you are to descend - into the caverns and seek out that amulet of which they spoke. Even - if the rumors of the amulet's powers are untrue, you decide that you - should at least be able to sell the tales of your adventures to the + into the caverns and seek out that amulet of which they spoke. Even + if the rumors of the amulet's powers are untrue, you decide that you + should at least be able to sell the tales of your adventures to the local minstrels for a tidy sum, especially if you encounter any of the terrifying and magical creatures of your dreams along the way. You spend one last night fortifying yourself at the local inn, becoming @@ -70,36 +70,36 @@ - ancient ruins that mark the entrance to the Mazes of Menace. It is - late at night, so you make camp at the entrance and spend the night - sleeping under the open skies. In the morning, you gather your gear, + ancient ruins that mark the entrance to the Mazes of Menace. It is + late at night, so you make camp at the entrance and spend the night + sleeping under the open skies. In the morning, you gather your gear, eat what may be your last meal outside, and enter the dungeon.... 2. What is going on here? - You have just begun a game of NetHack. Your goal is to grab as - much treasure as you can, retrieve the Amulet of Yendor, and escape + You have just begun a game of NetHack. Your goal is to grab as + much treasure as you can, retrieve the Amulet of Yendor, and escape the Mazes of Menace alive. - Your abilities and strengths for dealing with the hazards of + Your abilities and strengths for dealing with the hazards of adventure will vary with your background and training: - Archeologists understand dungeons pretty well; this enables them - to move quickly and sneak up on the local nasties. They start - equipped with the tools for a proper scientific expedition, and are + Archeologists understand dungeons pretty well; this enables them + to move quickly and sneak up on the local nasties. They start + equipped with the tools for a proper scientific expedition, and are able to read ancient languages. - Barbarians are warriors out of the hinterland, hardened to bat- - tle. They begin their quests with naught but uncommon strength, a + Barbarians are warriors out of the hinterland, hardened to bat- + tle. They begin their quests with naught but uncommon strength, a trusty hauberk, and a great two-handed sword. Cavemen and Cavewomen start with exceptional strength but, unfor- tunately, with neolithic weapons. Healers are wise in medicine and apothecary. They know the herbs - and simples that can restore vitality, ease pain, anesthetize, and - neutralize poisons; and with their instruments, they can divine a - being's state of health or sickness. Their medical practice earns + and simples that can restore vitality, ease pain, anesthetize, and + neutralize poisons; and with their instruments, they can divine a + being's state of health or sickness. Their medical practice earns them quite reasonable amounts of money, with which they enter the dun- geon. @@ -113,20 +113,20 @@ mobility. Priests and Priestesses are clerics militant, crusaders advancing - the cause of righteousness with arms, armor, and arts thaumaturgic. - Their ability to commune with deities via prayer occasionally extri- + the cause of righteousness with arms, armor, and arts thaumaturgic. + Their ability to commune with deities via prayer occasionally extri- cates them from peril, but can also put them in it. - Rangers are most at home in the woods, and some say slightly out - of place in a dungeon. They are, however, experts in archery as well + Rangers are most at home in the woods, and some say slightly out + of place in a dungeon. They are, however, experts in archery as well as tracking and stealthy movement. - Rogues are agile and stealthy thieves, with knowledge of locks, - traps, and poisons. Their advantage lies in surprise, which they + Rogues are agile and stealthy thieves, with knowledge of locks, + traps, and poisons. Their advantage lies in surprise, which they employ to great advantage. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -136,12 +136,12 @@ - Samurai are the elite warriors of feudal Nippon. They are - lightly armored and quick, and wear the dai-sho, two swords of the + Samurai are the elite warriors of feudal Nippon. They are + lightly armored and quick, and wear the dai-sho, two swords of the deadliest keenness. - Tourists start out with lots of gold (suitable for shopping - with), a credit card, lots of food, some maps, and an expensive cam- + Tourists start out with lots of gold (suitable for shopping + with), a credit card, lots of food, some maps, and an expensive cam- era. Most monsters don't like being photographed. Valkyries are hardy warrior women. Their upbringing in the harsh @@ -170,11 +170,11 @@ ground mine complex built by this race exists within the Mazes of Men- ace, filled with both riches and danger. - Humans are by far the most common race of the surface world, and - are thus the norm to which other races are often compared. Although + Humans are by far the most common race of the surface world, and + are thus the norm to which other races are often compared. Although they have no special abilities, they can succeed in any role. - Orcs are a cruel and barbaric race that hate every living thing + Orcs are a cruel and barbaric race that hate every living thing (including other orcs). Above all others, Orcs hate Elves with a pas- sion unequalled, and will go out of their way to kill one at any opportunity. The armor and weapons fashioned by the Orcs are typi- @@ -187,12 +187,12 @@ level, it appears on the screen in front of you. When NetHack's ancestor rogue first appeared, its screen orienta- - tion was almost unique among computer fantasy games. Since then, - screen orientation has become the norm rather than the exception; - NetHack continues this fine tradition. Unlike text adventure games + tion was almost unique among computer fantasy games. Since then, + screen orientation has become the norm rather than the exception; + NetHack continues this fine tradition. Unlike text adventure games - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -202,8 +202,8 @@ - that accept commands in pseudo-English sentences and explain the - results in words, NetHack commands are all one or two keystrokes and + that accept commands in pseudo-English sentences and explain the + results in words, NetHack commands are all one or two keystrokes and the results are displayed graphically on the screen. A minimum screen size of 24 lines by 80 columns is recommended; if the screen is larger, only a 21x80 section will be used for the map. @@ -212,21 +212,21 @@ of Braille readers or speech synthesisers. Instructions for configur- ing NetHack for the blind are included later in this document. - NetHack generates a new dungeon every time you play it; even the + NetHack generates a new dungeon every time you play it; even the authors still find it an entertaining and exciting game despite having won several times. NetHack offers a variety of display options. The options avail- able to you will vary from port to port, depending on the capabilities - of your hardware and software, and whether various compile-time + of your hardware and software, and whether various compile-time options were enabled when your executable was created. The three pos- sible display options are: a monochrome character interface, a color character interface, and a graphical interface using small pictures called tiles. The two character interfaces allow fonts with other characters to be substituted, but the default assignments use standard - ASCII characters to represent everything. There is no difference - between the various display options with respect to game play. - Because we cannot reproduce the tiles or colors in the Guidebook, and + ASCII characters to represent everything. There is no difference + between the various display options with respect to game play. + Because we cannot reproduce the tiles or colors in the Guidebook, and because it is common to all ports, we will use the default ASCII char- acters from the monochrome character display when referring to things you might see on the screen during your game. @@ -258,7 +258,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -268,21 +268,22 @@ - +---------------------------------------------------------------+ - |The bat bites! | - | | - | ------ | - | |....| ---------- | - | |.<..|####...@...$.| | - | |....-# |...B....+ | - | |....| |.d......| | - | ------ -------|-- | - | | - | | - | | - |Player the Rambler St:12 Dx:7 Co:18 In:11 Wi:9 Ch:15 Neutral | - |Dlvl:1 $:993 HP:9(12) Pw:3(3) AC:10 Exp:1/19 T:752 Hungry Conf | - +---------------------------Figure-1----------------------------+ + +----------------------------------------------------------------+ + | The bat bites! | + | | + | ------ | + | |....| ---------- | + | |.<..|####...@...$.| | + | |....-# |...B....+ | + | |....| |.d......| | + | ------ -------|-- | + | | + | | + | | + | Player the Rambler St:12 Dx:7 Co:18 In:11 Wi:9 Ch:15 Neutral | + | Dlvl:1 $:993 HP:9(12) Pw:3(3) AC:10 Exp:1/19 T:752 Hungry Conf | + +----------------------------------------------------------------+ + Figure 1 @@ -323,8 +324,7 @@ - - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -334,17 +334,18 @@ - +---------------------------------------------------------------+ - |Player the Rambler St:12 Dx:7 Co:18 In:11 Wi:9 Ch:15 | - |Neutral $:993 HP:9(12) Pw:3(3) AC:10 Exp:1/19 Hungry | - |Dlvl:1 T:752 Conf | - +---------------------------Figure-2----------------------------+ + +----------------------------------------------------------------+ + | Player the Rambler St:12 Dx:7 Co:18 In:11 Wi:9 Ch:15 | + | Neutral $:993 HP:9(12) Pw:3(3) AC:10 Exp:1/19 Hungry | + | Dlvl:1 T:752 Conf | + +----------------------------------------------------------------+ + Figure 2 3.1. The status lines (bottom) - The bottom two (or three) lines of the screen contain several - cryptic pieces of information describing your current status. Figure - 1 shows the traditional two-line status area below the map. Figure 2 + The bottom two (or three) lines of the screen contain several + cryptic pieces of information describing your current status. Figure + 1 shows the traditional two-line status area below the map. Figure 2 shows just the status area, when the statuslines:3 option has been set (not all interfaces support this option). If any status line becomes wider than the screen, you might not see all of it due to truncation. @@ -360,9 +361,9 @@ experience level, see below). Strength - A measure of your character's strength; one of your six basic - attributes. A human character's attributes can range from 3 to - 18 inclusive; non-humans may exceed these limits (occasionally + A measure of your character's strength; one of your six basic + attributes. A human character's attributes can range from 3 to + 18 inclusive; non-humans may exceed these limits (occasionally you may get super-strengths of the form 18/xx, and magic can also cause attributes to exceed the normal limits). The higher your strength, the stronger you are. Strength affects how success- @@ -381,16 +382,15 @@ your constitution no longer matters. Intelligence - Intelligence affects your ability to cast spells and read spell- + Intelligence affects your ability to cast spells and read spell- books. Wisdom - Wisdom comes from your practical experience (especially when + Wisdom comes from your practical experience (especially when dealing with magic). It affects your magical energy. - - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -420,11 +420,11 @@ level. Gold - The number of gold pieces you are openly carrying. Gold which + The number of gold pieces you are openly carrying. Gold which you have concealed in containers is not counted. Hit Points - Your current and maximum hit points. Hit points indicate how + Your current and maximum hit points. Hit points indicate how much damage you can take before you die. The more you get hit in a fight, the lower they get. You can regain hit points by rest- ing, or by using certain magical items or spells. The number in @@ -437,26 +437,26 @@ Armor Class A measure of how effectively your armor stops blows from - unfriendly creatures. The lower this number is, the more effec- - tive the armor; it is quite possible to have negative armor + unfriendly creatures. The lower this number is, the more effec- + tive the armor; it is quite possible to have negative armor class. See the Armor subsection of Objects for more information. Experience - Your current experience level. If the showexp option is set, it + Your current experience level. If the showexp option is set, it will be followed by a slash and experience points. As you adven- ture, you gain experience points. At certain experience point totals, you gain an experience level. The more experienced you are, the better you fight and withstand magical attacks. (By the - time your level reaches double digits, the usefulness of showing - the points with it has dropped significantly. You can use the - `O' command to turn showexp off to avoid using up the limited + time your level reaches double digits, the usefulness of showing + the points with it has dropped significantly. You can use the + `O' command to turn showexp off to avoid using up the limited status line space.) Time - The number of turns elapsed so far, displayed if you have the + The number of turns elapsed so far, displayed if you have the - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -469,13 +469,13 @@ time option set. Status - Hunger: your current hunger status. Values are Satiated, Not - Hungry (or Normal), Hungry, Weak, and Fainting. Not shown when + Hunger: your current hunger status. Values are Satiated, Not + Hungry (or Normal), Hungry, Weak, and Fainting. Not shown when Normal. - Encumbrance: an indication of how what you are carrying affects - your ability to move. Values are Unencumbered, Burdened, - Stressed, Strained, Overtaxed, and Overloaded. Not shown when + Encumbrance: an indication of how what you are carrying affects + your ability to move. Values are Unencumbered, Burdened, + Stressed, Strained, Overtaxed, and Overloaded. Not shown when Unencumbered. Fatal conditions: Stone (aka Petrifying, turning to stone), Slime @@ -492,8 +492,8 @@ Other conditions and modifiers exist, but there isn't enough room to display them with the other status fields. - The #attributes command (default key ^X) will show all current status - information in unabbreviated format. It also shows other information + The #attributes command (default key ^X) will show all current status + information in unabbreviated format. It also shows other information which might be included on the status lines if those had more room. 3.2. The message line (top) @@ -513,16 +513,16 @@ The rest of the screen is the map of the level as you have explored it so far. Each symbol on the screen represents something. You can set various graphics options to change some of the symbols the - game uses; otherwise, the game will use default symbols. Here is a + game uses; otherwise, the game will use default symbols. Here is a list of what the default symbols mean: - - The horizontal or corner walls of a room, or an open east/west + - The horizontal or corner walls of a room, or an open east/west door. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -532,13 +532,13 @@ - | The vertical walls of a room, or an open north/south door, or a + | The vertical walls of a room, or an open north/south door, or a grave. - . The floor of a room, or ice, or a doorless doorway, or the span + . The floor of a room, or ice, or a doorless doorway, or the span of an open drawbridge. - # A corridor, or iron bars, or a tree, or the portcullis of a + # A corridor, or iron bars, or a tree, or the portcullis of a closed drawbridge. Note: engravings in corridors also appear as # but are shown in a @@ -588,7 +588,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -610,8 +610,8 @@ A-HJ-Z and @&':; - Letters and certain other symbols represent the various inhabi- - tants of the Mazes of Menace. Watch out, they can be nasty and + Letters and certain other symbols represent the various inhabi- + tants of the Mazes of Menace. Watch out, they can be nasty and vicious. Sometimes, however, they can be helpful. I Rather than a specific type of monster, this marks the last known @@ -619,18 +619,18 @@ the monster could have moved. The `s', `F', and `m' commands may be useful here. - 1-5 The digits 1 through 5 may be displayed, marking unseen monsters - sensed via the Warning attribute. Less dangerous monsters are + 1-5 The digits 1 through 5 may be displayed, marking unseen monsters + sensed via the Warning attribute. Less dangerous monsters are indicated by lower values, more dangerous by higher values. - You need not memorize all these symbols; you can ask the game - what any symbol represents with the `/' command (see the next section + You need not memorize all these symbols; you can ask the game + what any symbol represents with the `/' command (see the next section for more info). 4. Commands - Commands can be initiated by typing one or two characters to - which the command is bound to, or typing the command name in the + Commands can be initiated by typing one or two characters to + which the command is bound to, or typing the command name in the extended commands entry. Some commands, like "search", do not require that any more information be collected by NetHack. Other commands might require additional information, for example a direction, or an @@ -647,14 +647,14 @@ indicating that you may choose an object not on the list, if you wanted to use something unexpected. Typing a `*' lists your entire inventory, so you can see the inventory letters of every object you're - carrying. Finally, if you change your mind and decide you don't want - to do this command after all, you can press the ESC key to abort the + carrying. Finally, if you change your mind and decide you don't want + to do this command after all, you can press the ESC key to abort the command. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -664,7 +664,7 @@ - You can put a number before some commands to repeat them that + You can put a number before some commands to repeat them that many times; for example, "10s" will search ten times. If you have the number_pad option set, you must type `n' to prefix a count, so the example above would be typed "n10s" instead. Commands for which @@ -678,18 +678,18 @@ ? Help menu: display one of several help texts available. - / The "whatis" command, to tell what a symbol represents. You may - choose to specify a location or type a symbol (or even a whole - word) to explain. Specifying a location is done by moving the - cursor to a particular spot on the map and then pressing one of + / The "whatis" command, to tell what a symbol represents. You may + choose to specify a location or type a symbol (or even a whole + word) to explain. Specifying a location is done by moving the + cursor to a particular spot on the map and then pressing one of `.', `,', `;', or `:'. `.' will explain the symbol at the chosen location, conditionally check for "More info?" depending upon whether the help option is on, and then you will be asked to pick - another location; `,' will explain the symbol but skip any addi- - tional information, then let you pick another location; `;' will - skip additional info and also not bother asking you to choose - another location to examine; `:' will show additional info, if - any, without asking for confirmation. When picking a location, + another location; `,' will explain the symbol but skip any addi- + tional information, then let you pick another location; `;' will + skip additional info and also not bother asking you to choose + another location to examine; `:' will show additional info, if + any, without asking for confirmation. When picking a location, pressing the ESC key will terminate this command, or pressing `?' will give a brief reminder about how it works. @@ -720,7 +720,7 @@ instead. Only these one-step movement commands cause you to - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -731,14 +731,15 @@ fight monsters; the others (below) are "safe." - +----------------------------------------------------------------+ - | y k u 7 8 9 | - | \ | / \ | / | - | h- . -l 4- . -6 | - | / | \ / | \ | - | b j n 1 2 3 | - | (number_pad off) (number_pad on) | - +---------------------------Figure-3-----------------------------+ + +-----------------------------------------------------+ + | y k u 7 8 9 | + | \ | / \ | / | + | h- . -l 4- . -6 | + | / | \ / | \ | + | b j n 1 2 3 | + | (number_pad off) (number_pad on) | + +-----------------------------------------------------+ + Figure 3 [YUHJKLBN] Go in that direction until you hit a wall or run into something. @@ -755,20 +756,20 @@ that prompt). The prefix will make "#travel" command show a menu of interesting - targets in sight. It can also be used with the `\' (known, show + targets in sight. It can also be used with the `\' (known, show a list of all discovered objects) and the ``' (knownclass, show a list of discovered objects in a particular class) commands to offer a menu of several sorting alternatives (which sets a new value for the sortdiscoveries option); also for "#vanquished" and "#genocided" commands to offer a sorting menu. - A few other commands (eat food, offer sacrifice, apply tinning- - kit, drink/quaff, dip, tip container) use the `m' prefix to skip - checking for applicable objects on the floor and go straight to - checking inventory, or (for "#loot" to remove a saddle), skip + A few other commands (eat food, offer sacrifice, apply tinning- + kit, drink/quaff, dip, tip container) use the `m' prefix to skip + checking for applicable objects on the floor and go straight to + checking inventory, or (for "#loot" to remove a saddle), skip containers and go straight to adjacent monsters. - In debug mode (aka "wizard mode"), the `m' prefix may also be + In debug mode (aka "wizard mode"), the `m' prefix may also be used with the "#teleport" and "#wizlevelport" commands. F[yuhjklbn] @@ -778,15 +779,14 @@ Prefix: move until something interesting is found. G[yuhjklbn] or +[yuhjklbn] - Prefix: similar to `g', but forking of corridors is not consid- + Prefix: similar to `g', but forking of corridors is not consid- ered interesting. - Note: + means holding the or key - down like while typing and releasing , then releas- - ing . ^ is used as shorthand elsewhere in the + Note: + means holding the or key + down like while typing and releasing , then releas- - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -796,12 +796,13 @@ - Guidebook to mean the same thing. Control characters are case- + ing . ^ is used as shorthand elsewhere in the + Guidebook to mean the same thing. Control characters are case- insensitive so ^x and ^X are the same. M[yuhjklbn] - Old versions supported `M' as a movement prefix which combined - the effect of `m' with +. That is no longer + Old versions supported `M' as a movement prefix which combined + the effect of `m' with +. That is no longer supported as a prefix but similar effect can be achieved by using `m' and G in combination. m can also be used in com- bination with g, +, or @@ -818,17 +819,17 @@ location other than the current position. . Wait or rest, do nothing for one turn. Precede with the `m' pre- - fix to wait for a turn even next to a hostile monster, if + fix to wait for a turn even next to a hostile monster, if safe_wait is on. a Apply (use) a tool (pick-axe, key, lamp...). - If used on a wand, that wand will be broken, releasing its magic + If used on a wand, that wand will be broken, releasing its magic in the process. Confirmation is required. A Remove one or more worn items, such as armor. - Use `T' (take off) to take off only one piece of armor or `R' + Use `T' (take off) to take off only one piece of armor or `R' (remove) to take off only one accessory. ^A Repeat the previous command. @@ -851,8 +852,7 @@ - - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -864,8 +864,8 @@ "What kinds of things do you want to drop? [!%= BUCXPaium]" - you should type zero or more object symbols possibly followed by - `a' and/or `i' and/or `u' and/or `m'. In addition, one or more + you should type zero or more object symbols possibly followed by + `a' and/or `i' and/or `u' and/or `m'. In addition, one or more of the blessed/uncursed/cursed groups may be typed. DB - drop all objects known to be blessed. @@ -879,16 +879,16 @@ Dm - use a menu to pick which object(s) to drop. D%u - drop only unpaid food. - The last example shows a combination. There are four categories + The last example shows a combination. There are four categories of object filtering: class (`!' for potions, `?' for scrolls, and so on), shop status (`u' for unpaid, in other words, owned by the shop), bless/curse state (`B', `U', `C', and `X' as shown above), and novelty (`P', recently picked up items; controlled by picking up or dropping things rather than by any time factor). - If you specify more than one value in a category (such as "!?" - for potions and scrolls or "BU" for blessed and uncursed), an - inventory object will meet the criteria if it matches any of the + If you specify more than one value in a category (such as "!?" + for potions and scrolls or "BU" for blessed and uncursed), an + inventory object will meet the criteria if it matches any of the specified values (so "!?" means `!' or `?'). If you specify more than one category, an inventory object must meet each of the cat- egory criteria (so "%u" means class `%' and unpaid `u'). Lastly, @@ -918,7 +918,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -932,14 +932,14 @@ attack you hand-to-hand (but if you attack, you will rub it out); this is often useful to give yourself a breather. - f Fire (shoot or throw) one of the objects placed in your quiver - (or quiver sack, or that you have at the ready). You may select - ammunition with a previous `Q' command, or let the computer pick - something appropriate if autoquiver is true. If your wielded - weapon has the throw-and-return property, your quiver is empty, - and autoquiver is false, you will throw that wielded weapon - instead of filling the quiver. This will also automatically use - a polearm if wielded. If fireassist is true, firing will auto- + f Fire (shoot or throw) one of the objects placed in your quiver + (or quiver sack, or that you have at the ready). You may select + ammunition with a previous `Q' command, or let the computer pick + something appropriate if autoquiver is true. If your wielded + weapon has the throw-and-return property, your quiver is empty, + and autoquiver is false, you will throw that wielded weapon + instead of filling the quiver. This will also automatically use + a polearm if wielded. If fireassist is true, firing will auto- matically try to wield a launcher (for example, a bow or a sling) matching the ammo in the quiver; this might take multiple turns, and get interrupted by a monster. Remember to swap back to your @@ -969,22 +969,22 @@ A menu showing the current option values will be displayed. You can change most values simply by selecting the menu entry for the - given option (ie, by typing its letter or clicking upon it, - depending on your user interface). For the non-boolean choices, - a further menu or prompt will appear once you've closed this - menu. The available options are listed later in this Guidebook. - Options are usually set before the game rather than with the `O' - command; see the section on options below. Precede `O' with the + given option (ie, by typing its letter or clicking upon it, + depending on your user interface). For the non-boolean choices, + a further menu or prompt will appear once you've closed this + menu. The available options are listed later in this Guidebook. + Options are usually set before the game rather than with the `O' + command; see the section on options below. Precede `O' with the `m' prefix to show advanced options. ^O Show overview. - Shortcut for "#overview": list interesting dungeon levels vis- + Shortcut for "#overview": list interesting dungeon levels vis- ited. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -994,16 +994,16 @@ - (Prior to 3.6.0, `^O' was a debug mode command which listed the - placement of all special levels. Use "#wizwhere" to run that + (Prior to 3.6.0, `^O' was a debug mode command which listed the + placement of all special levels. Use "#wizwhere" to run that command.) p Pay your shopping bill. P Put on an accessory (ring, amulet, or blindfold). - This command may also be used to wear armor. The prompt for - which inventory item to use will only list accessories, but + This command may also be used to wear armor. The prompt for + which inventory item to use will only list accessories, but choosing an unlisted item of armor will attempt to wear it. (See the `W' command below. It lists armor as the inventory choices but will accept an accessory and attempt to put that on.) @@ -1017,10 +1017,10 @@ When there is a fountain or sink present, it asks whether to drink from that. If that is declined, then it offers a chance to - choose a potion from inventory. Precede `q' with the `m' prefix + choose a potion from inventory. Precede `q' with the `m' prefix to skip asking about drinking from a fountain or sink. - Q Select an object for your quiver, quiver sack, or just generally + Q Select an object for your quiver, quiver sack, or just generally at the ready (only one of these is available at a time). You can then throw this (or one of these) using the `f' command. @@ -1033,16 +1033,16 @@ be removed without asking, but you can set the paranoid_confirma- tion:Remove option to require a prompt. - This command may also be used to take off armor. The prompt for - which inventory item to remove only lists worn accessories, but + This command may also be used to take off armor. The prompt for + which inventory item to remove only lists worn accessories, but an item of worn armor can be chosen. (See the `T' command below. It lists armor as the inventory choices but will accept an acces- sory and attempt to remove it.) ^R Redraw the screen. - s Search for secret doors and traps around you. It usually takes - several tries to find something. Precede with the `m' prefix to + s Search for secret doors and traps around you. It usually takes + several tries to find something. Precede with the `m' prefix to search for a turn even next to a hostile monster, if safe_wait is on. @@ -1050,7 +1050,7 @@ at an adjacent "remembered, unseen monster" marker. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -1077,9 +1077,9 @@ t Throw an object or shoot a projectile. There's no separate "shoot" command. If you throw an arrow while - wielding a bow, you are shooting that arrow and any weapon skill - bonus or penalty for bow applies. If you throw an arrow while - not wielding a bow, you are throwing it by hand and it will gen- + wielding a bow, you are shooting that arrow and any weapon skill + bonus or penalty for bow applies. If you throw an arrow while + not wielding a bow, you are throwing it by hand and it will gen- erally be less effective than when shot. See also `f' (fire) for throwing or shooting an item pre-selected @@ -1096,27 +1096,27 @@ This command may also be used to remove accessories. The prompt for which inventory item to take off only lists worn armor, but a - worn accessory can be chosen. (See the `R' command above. It - lists accessories as the inventory choices but will accept an + worn accessory can be chosen. (See the `R' command above. It + lists accessories as the inventory choices but will accept an item of armor and attempt to take it off.) ^T Teleport, if you have the ability. - v Display a list of significant events in the current game, also + v Display a list of significant events in the current game, also shown by #chronicle. - `v' used to display the game's version number. Use `V' for that + `v' used to display the game's version number. Use `V' for that now. V Display version number. - `V' used to display a summary of the game's history. Still + `V' used to display a summary of the game's history. Still available via #history. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -1130,13 +1130,13 @@ w- - wield nothing, use your bare (or gloved) hands. - Some characters can wield two weapons at once; use the `X' com- + Some characters can wield two weapons at once; use the `X' com- mand (or the "#twoweapon" extended command) to do so. W Wear armor. - This command may also be used to put on an accessory (ring, - amulet, or blindfold). The prompt for which inventory item to + This command may also be used to put on an accessory (ring, + amulet, or blindfold). The prompt for which inventory item to use will only list armor, but choosing an unlisted accessory will attempt to put it on. (See the `P' command above. It lists accessories as the inventory choices but will accept an item of @@ -1146,13 +1146,13 @@ weapon slot. The latter is used as your secondary weapon when engaging in two- - weapon combat. Note that if one of these slots is empty, the + weapon combat. Note that if one of these slots is empty, the exchange still takes place. - X Toggle two-weapon combat, if your character can do it. Also + X Toggle two-weapon combat, if your character can do it. Also available via the "#twoweapon" extended command. - (In versions prior to 3.6 this keystroke ran the command to + (In versions prior to 3.6 this keystroke ran the command to switch from normal play to "explore mode", also known as "discov- ery mode", which has now been moved to "#exploremode" and M-X.) @@ -1166,7 +1166,7 @@ don't appear in the normal status display due to space considera- tions. - In normal play, that's all that `^X' displays. In explore mode, + In normal play, that's all that `^X' displays. In explore mode, the role and status feedback is augmented by the information pro- vided by enlightenment magic. @@ -1182,7 +1182,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -1226,15 +1226,15 @@ + List the spells you know. - Using this command, you can also rearrange the order in which - your spells are listed, either by sorting the entire list or by - picking one spell from the menu then picking another to swap - places with it. Swapping pairs of spells changes their casting - letters, so the change lasts after the current `+' command fin- - ishes. Sorting the whole list is temporary. To make the most - recent sort order persist beyond the current `+' command, choose - the sort option again and then pick "reassign casting letters". - (Any spells learned after that will be added to the end of the + Using this command, you can also rearrange the order in which + your spells are listed, either by sorting the entire list or by + picking one spell from the menu then picking another to swap + places with it. Swapping pairs of spells changes their casting + letters, so the change lasts after the current `+' command fin- + ishes. Sorting the whole list is temporary. To make the most + recent sort order persist beyond the current `+' command, choose + the sort option again and then pick "reassign casting letters". + (Any spells learned after that will be added to the end of the list rather than be inserted into the sorted ordering.) \ Show what types of objects have been discovered. @@ -1248,7 +1248,7 @@ (R)UNIX is a registered trademark of The Open Group. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -1260,14 +1260,14 @@ May be preceded by `m' to select preferred display order. - | If persistent inventory display is supported and enabled (with - the perm_invent option), interact with it instead of with the + | If persistent inventory display is supported and enabled (with + the perm_invent option), interact with it instead of with the map. - Allows scrolling with the menu_first_page, menu_previous_page, - menu_next_page, and menu_last_page keys (`^', `<', `>', `|' by + Allows scrolling with the menu_first_page, menu_previous_page, + menu_next_page, and menu_last_page keys (`^', `<', `>', `|' by default). Some interfaces also support menu_shift_left and - menu_shift_right keys (`{' and `}' by default). Use the Return + menu_shift_right keys (`{' and `}' by default). Use the Return (aka Enter) or Escape key to resume play. ! Escape to a shell. See "#shell" below for more details. @@ -1276,20 +1276,20 @@ of the current level's map without monsters; without monsters and objects; or without monsters, objects, and traps. - The key is also shown as on some keyboards or - on others. It is sometimes displayed as ^? even though + The key is also shown as on some keyboards or + on others. It is sometimes displayed as ^? even though that is not an actual control character. - Many terminals have an option to swap the and - keys, so typing the key might not execute this - command. If that happens, you can use the extended command - "#terrain" instead. + Many terminals have an option to swap the and keys, so typing the key might not execute this com- + mand. If that happens, you can use the extended command "#ter- + rain" instead. # Perform an extended command. - As you can see, the authors of NetHack used up all the letters, + As you can see, the authors of NetHack used up all the letters, so this is a way to introduce the less frequently used commands. What extended commands are available depends on what features the game was compiled with. @@ -1308,13 +1308,13 @@ when choosing the item to adjust, enter a count prior to its let- ter. - Adjusting without a count used to collect all compatible stacks - when moving to the destination. That behavior has been changed; - to gather compatible stacks, "#adjust" a stack into its own + Adjusting without a count used to collect all compatible stacks + when moving to the destination. That behavior has been changed; + to gather compatible stacks, "#adjust" a stack into its own inventory slot. If it has a name assigned, other stacks with the - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -1327,7 +1327,7 @@ same name or with no name will merge provided that all their other attributes match. If it does not have a name, only other stacks with no name are eligible. In either case, otherwise com- - patible stacks with a different name will not be merged. This + patible stacks with a different name will not be merged. This contrasts with using "#adjust" to move from one slot to a differ- ent slot. In that situation, moving (no count given) a compati- ble stack will merge if either stack has a name when the other @@ -1380,7 +1380,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -1409,7 +1409,7 @@ Dip an object into something. Autocompletes. Default key is `M- d'. - The `m' prefix skips dipping into a fountain or pool if there is + The `m' prefix skips dipping into a fountain or pool if there is one at your location. #down @@ -1422,14 +1422,14 @@ Drop specific item types. Default key is `D'. #eat - Eat something. Default key is `e'. The `m' prefix skips eating + Eat something. Default key is `e'. The `m' prefix skips eating items on the floor. #engrave Engrave writing on the floor. Default key is `E'. #enhance - Advance or check weapon and spell skills. Autocompletes. + Advance or check weapon and spell skills. Autocompletes. Default key is `M-e'. #exploremode @@ -1446,7 +1446,7 @@ fight there. Default key is `F', or `-' with number_pad - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -1469,13 +1469,13 @@ extinct. The display order is the same as is used by #vanquished. The `m' - prefix brings up a menu of available sorting orders, and doing - that for either #genocided or #vanquished changes the order for + prefix brings up a menu of available sorting orders, and doing + that for either #genocided or #vanquished changes the order for both. - If the sorting order is "count high to low" or "count low to - high" (which are applicable for #vanquished), that will be - ignored for #genocided and alphabetical will be used instead. + If the sorting order is "count high to low" or "count low to + high" (which are applicable for #vanquished), that will be + ignored for #genocided and alphabetical will be used instead. The menu omits those two choices when used for #genocide. Autocompletes. Default key is `M-g'. @@ -1512,7 +1512,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -1538,7 +1538,7 @@ played. #knownclass - Show discovered types for one class of objects. Default key is + Show discovered types for one class of objects. Default key is ``'. The `m' prefix operates the same as for "#known". @@ -1556,7 +1556,7 @@ Describe what you can see, or remember, of your surroundings. #loot - Loot a box or bag on the floor beneath you, or the saddle from a + Loot a box or bag on the floor beneath you, or the saddle from a steed standing next to you. Autocompletes. Precede with the `m' prefix to skip containers at your location and go directly to removing a saddle. Default key is `M-l', and also `l' if num- @@ -1572,13 +1572,13 @@ N'. #offer - Offer a sacrifice to the gods. Autocompletes. Default key is + Offer a sacrifice to the gods. Autocompletes. Default key is `M-o'. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -1588,7 +1588,7 @@ - You'll need to find an altar to have any chance at success. + You'll need to find an altar to have any chance at success. Corpses of recently killed monsters are the fodder of choice. The `m' prefix skips offering any items which are on the altar. @@ -1597,36 +1597,36 @@ Open a door. Default key is `o'. #options - Show and change option settings. Default key is `O'. Precede + Show and change option settings. Default key is `O'. Precede with the `m' prefix to show advanced options. #optionsfull - Show advanced game option settings. No default key. Precede - with the `m' prefix to execute the simpler options command. - (Mainly useful if you use BINDING=O:optionsfull to switch `O' + Show advanced game option settings. No default key. Precede + with the `m' prefix to execute the simpler options command. + (Mainly useful if you use BINDING=O:optionsfull to switch `O' from simple options back to traditional advanced options.) #overview - Display information you've discovered about the dungeon. Any - visited level with an annotation is included, and many things - (altars, thrones, fountains, and so on; extra stairs leading to + Display information you've discovered about the dungeon. Any + visited level with an annotation is included, and many things + (altars, thrones, fountains, and so on; extra stairs leading to another dungeon branch) trigger an automatic annotation. If dun- geon overview is chosen during end-of-game disclosure, every vis- ited level will be included regardless of annotations. - Precede #overview with the `m' prefix to display the dungeon - overview as a menu where you can select any visited level to add - or remove an annotation without needing to return to that level. - This will also force all visited levels to be displayed rather + Precede #overview with the `m' prefix to display the dungeon + overview as a menu where you can select any visited level to add + or remove an annotation without needing to return to that level. + This will also force all visited levels to be displayed rather than just the "interesting" subset. Autocompletes. Default keys are `^O', and `M-O'. #panic - Test the panic routine. Terminates the current game. Autocom- + Test the panic routine. Terminates the current game. Autocom- pletes. Debug mode only. - Asks for confirmation; default is n (no); continue playing. To + Asks for confirmation; default is n (no); continue playing. To really panic, respond with y. You can set the paranoid_confirma- tion:quit option to require a response of yes instead. @@ -1644,7 +1644,7 @@ Pick up things at the current location. Default key is `,'. The - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -1662,12 +1662,12 @@ #pray Pray to the gods for help. Autocompletes. Default key is `M-p'. - Praying too soon after receiving prior help is a bad idea. - (Hint: entering the dungeon alive is treated as having received - help. You probably shouldn't start off a new game by praying - right away.) Since using this command by accident can cause - trouble, there is an option to make you confirm your intent - before praying. It is enabled by default, and you can reset the + Praying too soon after receiving prior help is a bad idea. + (Hint: entering the dungeon alive is treated as having received + help. You probably shouldn't start off a new game by praying + right away.) Since using this command by accident can cause + trouble, there is an option to make you confirm your intent + before praying. It is enabled by default, and you can reset the paranoid_confirmation option to disable it. #prevmsg @@ -1686,20 +1686,20 @@ Quit the program without saving your game. Autocompletes. Since using this command by accident would throw away the current - game, you are asked to confirm your intent before quitting. - Default response is n (no); continue playing. To really quit, - respond with y. You can set the paranoid_confirmation:quit + game, you are asked to confirm your intent before quitting. + Default response is n (no); continue playing. To really quit, + respond with y. You can set the paranoid_confirmation:quit option to require a response of yes instead. #quiver Select ammunition for quiver. Default key is `Q'. #read - Read a scroll, a spellbook, or something else. Default key is + Read a scroll, a spellbook, or something else. Default key is `r'. #redraw - Redraw the screen. Default key is `^R', and also `^L' if num- + Redraw the screen. Default key is `^R', and also `^L' if num- ber_pad is on. #remove @@ -1710,7 +1710,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -1721,24 +1721,24 @@ #reqmenu - Prefix key to modify the behavior or request menu from some com- - mands. Prevents autopickup when used with movement commands. + Prefix key to modify the behavior or request menu from some com- + mands. Prevents autopickup when used with movement commands. Default key is `m'. #retravel - Travel to a previously selected travel destination. Default key + Travel to a previously selected travel destination. Default key is `C-_'. See also #travel. #ride - Ride (or stop riding) a saddled creature. Autocompletes. + Ride (or stop riding) a saddled creature. Autocompletes. Default key is `M-R'. #rub Rub a lamp or a stone. Autocompletes. Default key is `M-r'. #run - Prefix key to run towards a direction. Default key is `G' when - number_pad is off, `5' when number_pad is set to 1 or 3, other- + Prefix key to run towards a direction. Default key is `G' when + number_pad is off, `5' when number_pad is set to 1 or 3, other- wise `M-5' when it is set to 2 or 4. #rush @@ -1750,12 +1750,12 @@ Save the game and exit the program. Default key is `S'. #saveoptions - Save configuration options to the config file. This will over- - write the file, removing all comments, so if you have manually + Save configuration options to the config file. This will over- + write the file, removing all comments, so if you have manually edited the config file, don't use this. #search - Search for traps and secret doors around you. Default key is + Search for traps and secret doors around you. Default key is `s'. #seeall @@ -1776,7 +1776,7 @@ worn. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -1807,12 +1807,12 @@ If dual-wielding, a separate message about the secondary weapon will be given. Using the `m' prefix will force a menu and it will include primary weapon, alternate weapon even when not dual- - wielding, and also whatever is currently assigned to the quiver + wielding, and also whatever is currently assigned to the quiver slot. #shell - Do a shell escape, switching from NetHack to a subprocess. Can - be disabled at the time the program is built. When enabled, + Do a shell escape, switching from NetHack to a subprocess. Can + be disabled at the time the program is built. When enabled, access for specific users can be controlled by the system config- uration file. Use the shell command `exit' to return to the game. Default key is `!'. @@ -1842,7 +1842,7 @@ Suspend the game, switching from NetHack to the terminal it was - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -1876,19 +1876,19 @@ traps. If there are visible clouds of gas in view, they are treated like - traps when deciding whether to show them or the floor underneath + traps when deciding whether to show them or the floor underneath them. - In explore mode, you can choose to view the full map rather than - just its explored portion. In debug mode there are additional + In explore mode, you can choose to view the full map rather than + just its explored portion. In debug mode there are additional choices. - Autocompletes. Default key is `' or `' (see Del + Autocompletes. Default key is `' or `' (see Del above). #therecmdmenu - Show a menu of possible actions directed at a location next to - you. The menu is limited to a subset of the likeliest actions, + Show a menu of possible actions directed at a location next to + you. The menu is limited to a subset of the likeliest actions, not an exhaustive set of all possibilities. Autocompletes. #throw @@ -1905,10 +1905,10 @@ tory to tip. The `m' prefix makes the command skip containers on the floor and - pick one from inventory, except for the special case of + pick one from inventory, except for the special case of - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -1918,14 +1918,14 @@ - menustyle:traditional with two or more containers present; that + menustyle:traditional with two or more containers present; that situation will start with the floor container menu. Autocompletes. Default key is `M-T'. #toggle - Toggle a boolean option on or off. Requires a parameter in - parenthesis, the name of the option to toggle. The option must + Toggle a boolean option on or off. Requires a parameter in + parenthesis, the name of the option to toggle. The option must be settable in-game. For example: @@ -1934,10 +1934,10 @@ BIND=@:toggle(autopickup) #travel - Travel to a specific location on the map. Default key is `_'. - Using the "request menu" prefix shows a menu of interesting tar- - gets in sight without asking to move the cursor. When picking a - target with cursor and the autodescribe option is on, the top + Travel to a specific location on the map. Default key is `_'. + Using the "request menu" prefix shows a menu of interesting tar- + gets in sight without asking to move the cursor. When picking a + target with cursor and the autodescribe option is on, the top line will show "(no travel path)" if your character does not know of a path to that location. See also #retravel. @@ -1974,7 +1974,7 @@ menu of sorting orders available (provided that the vanquished - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -1984,13 +1984,13 @@ - monsters list contains at least two types of monsters). Which- - ever ordering is picked gets assigned to the sortvanquished + monsters list contains at least two types of monsters). + Whichever ordering is picked gets assigned to the sortvanquished option so is remembered for subsequent #vanquished requests. The "#genocided" command shares this sorting order. - During end-of-game disclosure, when asked whether to show van- - quished monsters answering `a' will let you choose from the sort + During end-of-game disclosure, when asked whether to show van- + quished monsters answering `a' will let you choose from the sort menu. Autocompletes. Default key is `M-V'. @@ -2040,7 +2040,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -2067,7 +2067,7 @@ one. Autocompletes. Debug mode only. Default key is `^G'. #wizidentify - Identify all items in inventory. Autocompletes. Debug mode + Identify all items in inventory. Autocompletes. Debug mode only. Default key is `^I'. #wizintrinsic @@ -2106,7 +2106,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -2142,17 +2142,17 @@ first letter of the command. On Windows and MS-DOS, the "Alt" key can be used in this fashion. - On other systems, if typing "Alt" plus another key transmits a two - character sequence consisting of an Escape followed by the other key, - you may set the altmeta option to have NetHack combine them into - meta+. (This combining action only takes place when NetHack is + On other systems, if typing "Alt" plus another key transmits a two + character sequence consisting of an Escape followed by the other key, + you may set the altmeta option to have NetHack combine them into + meta+. (This combining action only takes place when NetHack is expecting a command to execute, not when accepting input to name some- thing or to make a wish.) Unlike control characters, where ^x and ^X denote the same thing, - meta characters are case-sensitive: M-x and M-X represent different - things. Some commands which can be run via a meta character require - that the letter be capitalized because the lower-case equivalent is + meta characters are case-sensitive: M-x and M-X represent different + things. Some commands which can be run via a meta character require + that the letter be capitalized because the lower-case equivalent is used for another command, so the three key combination meta+Shift+ is needed. @@ -2172,7 +2172,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -2238,7 +2238,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -2252,7 +2252,7 @@ - If the number_pad option is on, some additional letter commands + If the number_pad option is on, some additional letter commands are available: h #help @@ -2304,7 +2304,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -2316,61 +2316,61 @@ 5. Rooms and corridors - Rooms and corridors in the dungeon are either lit or dark. Any - lit areas within your line of sight will be displayed; dark areas are - only displayed if they are within one space of you. Walls and corri- + Rooms and corridors in the dungeon are either lit or dark. Any + lit areas within your line of sight will be displayed; dark areas are + only displayed if they are within one space of you. Walls and corri- dors remain on the map as you explore them. Secret corridors are hidden and appear to be solid rock. You can find them with the `s' (search) command when adjacent to them. Multi- - ple search attempts may be needed. When searching is successful, - secret corridors become ordinary open corridor locations. Mapping - magic reveals secret corridors, so converts them into ordinary corri- + ple search attempts may be needed. When searching is successful, + secret corridors become ordinary open corridor locations. Mapping + magic reveals secret corridors, so converts them into ordinary corri- dors and shows them as such. 5.1. Doorways - Doorways connect rooms and corridors. Some doorways have no - doors; you can walk right through. Others have doors in them, which - may be open, closed, or locked. To open a closed door, use the `o' - (open) command; to close it again, use the `c' (close) command. By - default the autoopen option is enabled, so simply attempting to walk - onto a closed door's location will attempt to open it without needing - `o'. Opening via autoopen will not work if you are confused or + Doorways connect rooms and corridors. Some doorways have no + doors; you can walk right through. Others have doors in them, which + may be open, closed, or locked. To open a closed door, use the `o' + (open) command; to close it again, use the `c' (close) command. By + default the autoopen option is enabled, so simply attempting to walk + onto a closed door's location will attempt to open it without needing + `o'. Opening via autoopen will not work if you are confused or stunned or suffer from the fumbling attribute. - Open doors cannot be entered diagonally; you must approach them - straight on, horizontally or vertically. Doorways without doors are + Open doors cannot be entered diagonally; you must approach them + straight on, horizontally or vertically. Doorways without doors are not restricted in this fashion except on one particular level (described by "#overview" as "a primitive area"). - Unlocking magic exists but usually won't be available early on. - You can get through a locked door without magic by first using an - unlocking tool with the `a' (apply) command, and then opening it. By - default the autounlock option is also enabled, so if you attempt to - open (via `o' or autoopen) a locked door while carrying an unlocking - tool, you'll be asked whether to use it on the door's lock. Alterna- - tively, you can break a closed door (whether locked or not) down by - kicking it via the `^D' (kick) command. Kicking down a door destroys + Unlocking magic exists but usually won't be available early on. + You can get through a locked door without magic by first using an + unlocking tool with the `a' (apply) command, and then opening it. By + default the autounlock option is also enabled, so if you attempt to + open (via `o' or autoopen) a locked door while carrying an unlocking + tool, you'll be asked whether to use it on the door's lock. Alterna- + tively, you can break a closed door (whether locked or not) down by + kicking it via the `^D' (kick) command. Kicking down a door destroys it and makes a lot of noise which might wake sleeping monsters. - Some closed doors are booby-trapped and will explode if an - attempt is made to open (when unlocked) or unlock (when locked) or - kick down. Like kicking, an explosion destroys the door and makes a - lot of noise. The "#untrap" command can be used to search a door for - traps but might take multiple attempts to find one. When one is - found, you'll be asked whether to try to disarm it. If you accede, - success will eliminate the trap but failure will set off the trap's - explosion. (If you decline, you effectively forget that a trap was + Some closed doors are booby-trapped and will explode if an + attempt is made to open (when unlocked) or unlock (when locked) or + kick down. Like kicking, an explosion destroys the door and makes a + lot of noise. The "#untrap" command can be used to search a door for + traps but might take multiple attempts to find one. When one is + found, you'll be asked whether to try to disarm it. If you accede, + success will eliminate the trap but failure will set off the trap's + explosion. (If you decline, you effectively forget that a trap was found there.) - Closed doors can be useful for shutting out monsters. Most mon- - sters cannot open closed doors, although a few don't need to (for - example, ghosts can walk through doors and fog clouds can flow under + Closed doors can be useful for shutting out monsters. Most mon- + sters cannot open closed doors, although a few don't need to (for + example, ghosts can walk through doors and fog clouds can flow under them). Some monsters who can open doors can also use unlocking tools. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -2394,7 +2394,7 @@ There are traps throughout the dungeon to snare the unwary intruder. For example, you may suddenly fall into a pit and be stuck for a few turns trying to climb out (see below). A trap usually won't - appear on your map until you trigger it by moving onto it, you see + appear on your map until you trigger it by moving onto it, you see someone else trigger it, or you discover it with the `s' (search) com- mand (multiple attempts are often needed; if your luck is poor, many attempts might be needed). Wands of secret door detection and spell @@ -2402,9 +2402,9 @@ the trap is also within line-of-sight (whether you can see at the time or not). There is also other magic which can reveal traps. - Monsters can fall prey to traps, too, which can potentially be - used as a defensive strategy. Unfortunately traps can be harmful to - your pet(s) as well. Monsters, including pets, usually will avoid + Monsters can fall prey to traps, too, which can potentially be + used as a defensive strategy. Unfortunately traps can be harmful to + your pet(s) as well. Monsters, including pets, usually will avoid moving onto a trap which is shown on your map if they have encountered that type of trap before. @@ -2420,23 +2420,23 @@ to another level, but one which is always below the current level. Usually that will be the next level down but it can be farther. Unlike (level) teleporters, the destination level of a particular trap - door or hole is persistent, so falling into one will bring you to the - same level each time--though not necessarily the same spot on the + door or hole is persistent, so falling into one will bring you to the + same level each time--though not necessarily the same spot on the level. Magic portals behave similarly, but with some additional vari- ation. Some portals are two-way and their remote destination is always the same: another portal which can take you back. Others are one-way and send you to a specific destination level but not necessar- ily to a specific location there. - There is a special multi-level branch of the dungeon with pre- - mapped levels based on the classic computer game "Sokoban." In that - game, you operate as a warehouse worker who pushes crates around - obstacles to position them at designated locations. In NetHack, the + There is a special multi-level branch of the dungeon with pre- + mapped levels based on the classic computer game "Sokoban." In that + game, you operate as a warehouse worker who pushes crates around + obstacles to position them at designated locations. In NetHack, the goal is to push boulders into pits or holes until those traps have all been nullified, giving access to whatever is beyond them. In the - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -2470,19 +2470,19 @@ 5.3. Stairs and ladders (`<', `>') In general, each level in the dungeon will have a staircase going - up (`<') to the previous level and another going down (`>') to the - next level. There are some exceptions though. For instance, fairly - early in the dungeon you will find a level with two down staircases, - one continuing into the dungeon and the other branching into an area + up (`<') to the previous level and another going down (`>') to the + next level. There are some exceptions though. For instance, fairly + early in the dungeon you will find a level with two down staircases, + one continuing into the dungeon and the other branching into an area known as the Gnomish Mines. Those mines eventually hit a dead end, so after exploring them (if you choose to do so), you'll need to climb back up to the main dungeon. When you traverse a set of stairs, or trigger a trap which sends you to another level, the level you're leaving will be deactivated and - stored in a file on disk. If you're moving to a previously visited - level, it will be loaded from its file on disk and reactivated. If - you're moving to a level which has not yet been visited, it will be + stored in a file on disk. If you're moving to a previously visited + level, it will be loaded from its file on disk and reactivated. If + you're moving to a level which has not yet been visited, it will be created (from scratch for most random levels, from a template for some "special" levels, or loaded from the remains of an earlier game for a "bones" level as briefly described below). Monsters are only active @@ -2490,19 +2490,19 @@ into stasis. Ordinarily when you climb a set of stairs, you will arrive on the - corresponding staircase at your destination. However, pets (see - below) and some other monsters will follow along if they're close - enough when you travel up or down stairs, and occasionally one of + corresponding staircase at your destination. However, pets (see + below) and some other monsters will follow along if they're close + enough when you travel up or down stairs, and occasionally one of these creatures will displace you during the climb. When that occurs, the pet or other monster will arrive on the staircase and you will end up nearby. - Ladders serve the same purpose as staircases, and the two types - of inter-level connections are nearly indistinguishable during game + Ladders serve the same purpose as staircases, and the two types + of inter-level connections are nearly indistinguishable during game play. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -2514,8 +2514,8 @@ 5.4. Shops and shopping - Occasionally you will run across a room with a shopkeeper near - the door and many items lying on the floor. You can buy items by + Occasionally you will run across a room with a shopkeeper near + the door and many items lying on the floor. You can buy items by picking them up and then using the `p' command. You can inquire about the price of an item prior to picking it up by using the "#chat" com- mand while standing on it. Using an item prior to paying for it will @@ -2533,8 +2533,8 @@ have to buy it back if you want to reclaim it. Shopkeepers sometime run out of money. When that happens, you'll - be offered credit instead of gold when you try to sell something. - Credit can be used to pay for purchases, but it is only good in the + be offered credit instead of gold when you try to sell something. + Credit can be used to pay for purchases, but it is only good in the shop where it was obtained; other shopkeepers won't honor it. (If you happen to find a "credit card" in the dungeon, don't bother trying to use it in shops; shopkeepers will not accept it.) @@ -2568,7 +2568,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -2602,18 +2602,18 @@ and without giving feedback about them. The mention_walls option controls whether you get feedback if you - try to walk into a wall or solid stone or off the edge of the map. - Normally nothing happens (unless the hero is blind and no wall is - shown, then the wall that is being bumped into will be drawn on the - map). This option also gives feedback when rushing or running stops + try to walk into a wall or solid stone or off the edge of the map. + Normally nothing happens (unless the hero is blind and no wall is + shown, then the wall that is being bumped into will be drawn on the + map). This option also gives feedback when rushing or running stops for some non-obvious reason. - The mention_decor option controls whether you get feedback when - walking on "furniture." Normally stepping onto stairs or a fountain - or an altar or various other things doesn't elicit anything unless it - is covered by one or more objects so is obscured on the map. Setting - this option to true will describe such things even when they aren't - obscured. Doorless doorways and open doors aren't considered worthy + The mention_decor option controls whether you get feedback when + walking on "furniture." Normally stepping onto stairs or a fountain + or an altar or various other things doesn't elicit anything unless it + is covered by one or more objects so is obscured on the map. Setting + this option to true will describe such things even when they aren't + obscured. Doorless doorways and open doors aren't considered worthy of mention; closed doors (if you can move onto their spots) and broken doors are. Assuming that you're able to do so, moving onto water or lava or ice will give feedback if not yet on that type of terrain but @@ -2628,13 +2628,13 @@ The "nopickup" command prefix (default `m') is also the move- without-attacking prefix and can be used to try to step onto a visible - monster's spot without the move being considered an attack (see the - Fighting subsection of Monsters below). The "fight" command prefix - (default `F'; also `-' if number_pad is on) can be used to force an - attack, when guessing where an unseen monster is or when deliberately + monster's spot without the move being considered an attack (see the + Fighting subsection of Monsters below). The "fight" command prefix + (default `F'; also `-' if number_pad is on) can be used to force an + attack, when guessing where an unseen monster is or when deliberately - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -2646,22 +2646,22 @@ attacking a peaceful or tame creature. - The run_mode option controls how frequently the map gets redrawn - when moving more than one step in a single command (so when rushing, + The run_mode option controls how frequently the map gets redrawn + when moving more than one step in a single command (so when rushing, running, or traveling). 5.6. Rogue level - One dungeon level (occurring in mid to late teens of the main + One dungeon level (occurring in mid to late teens of the main dungeon) is a tribute to the ancestor game hack's inspiration rogue. - It is usually displayed differently from other levels: possibly - in characters instead of tiles, or without line-drawing symbols if - already in characters; also, gold is shown as * rather than $ and - stairs are shown as % rather than < and >. There are some minor dif- - ferences in actual game play: doorways lack doors; a scroll, wand, or - spell of light used in a room lights up the whole room rather than - within a radius around your character. And monsters represented by + It is usually displayed differently from other levels: possibly + in characters instead of tiles, or without line-drawing symbols if + already in characters; also, gold is shown as * rather than $ and + stairs are shown as % rather than < and >. There are some minor dif- + ferences in actual game play: doorways lack doors; a scroll, wand, or + spell of light used in a room lights up the whole room rather than + within a radius around your character. And monsters represented by lower-case letters aren't randomly generated on the rogue level. The slight strangeness of this level is a feature, not a bug.... @@ -2677,19 +2677,19 @@ those monsters who are displayed on the screen. The command "#name" (by default bound to `C'), allows you to assign a name to a monster, which may be useful to help distinguish one from another when multiple - monsters are present. Assigning a name which is just a space will + monsters are present. Assigning a name which is just a space will remove any prior name. - The extended command "#chat" can be used to interact with an - adjacent monster. There is no actual dialog (in other words, you - don't get to choose what you'll say), but chatting with some monsters - such as a shopkeeper or the Oracle of Delphi can produce useful + The extended command "#chat" can be used to interact with an + adjacent monster. There is no actual dialog (in other words, you + don't get to choose what you'll say), but chatting with some monsters + such as a shopkeeper or the Oracle of Delphi can produce useful results. 6.1. Fighting - If you see a monster and you wish to fight it, just attempt to - walk into it. Many monsters you find will mind their own business + If you see a monster and you wish to fight it, just attempt to + walk into it. Many monsters you find will mind their own business unless you attack them. Some of them are very dangerous when angered. Remember: discretion is the better part of valor. @@ -2697,10 +2697,10 @@ ster by moving into its location, you'll be asked to confirm your intent. By default an answer of `y' acknowledges that intent, which can be error prone if you're using `y' to move. You can set the para- - noid_confirmation:attack option to require a response of "yes" + noid_confirmation:attack option to require a response of "yes" - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -2712,7 +2712,7 @@ instead. - If you can't see a monster (if it is invisible, or if you are + If you can't see a monster (if it is invisible, or if you are blinded), the symbol `I' will be shown when you learn of its presence. If you attempt to walk into it, you will try to fight it just like a monster that you can see; of course, if the monster has moved, you @@ -2724,7 +2724,7 @@ 6.2. Your pet You start the game with a little dog (`d'), kitten (`f'), or pony - (`u'), which follows you about the dungeon and fights monsters with + (`u'), which follows you about the dungeon and fights monsters with you. Like you, your pet needs food to survive. Dogs and cats usually feed themselves on fresh carrion and other meats; horses need vegetar- ian food which is harder to come by. If you're worried about your pet @@ -2738,9 +2738,9 @@ Your pet will follow you up and down staircases if it is next to you when you move. Otherwise your pet will be stranded and may become - wild. Similarly, when you trigger certain types of traps which alter - your location (for instance, a trap door which drops you to a lower - dungeon level), any adjacent pet will accompany you and any non-adja- + wild. Similarly, when you trigger certain types of traps which alter + your location (for instance, a trap door which drops you to a lower + dungeon level), any adjacent pet will accompany you and any non-adja- cent pet will be left behind. Your pet may trigger such traps itself; you will not be carried along with it even if adjacent at the time. @@ -2749,24 +2749,24 @@ Some types of creatures in the dungeon can actually be ridden if you have the right equipment and skill. Convincing a wild beast to let you saddle it up is difficult to say the least. Many a dungeoneer - has had to resort to magic and wizardry in order to forge the - alliance. Once you do have the beast under your control however, you - can easily climb in and out of the saddle with the "#ride" command. - Lead the beast around the dungeon when riding, in the same manner as - you would move yourself. It is the beast that you will see displayed + has had to resort to magic and wizardry in order to forge the + alliance. Once you do have the beast under your control however, you + can easily climb in and out of the saddle with the "#ride" command. + Lead the beast around the dungeon when riding, in the same manner as + you would move yourself. It is the beast that you will see displayed on the map. - Riding skill is managed by the "#enhance" command. See the sec- + Riding skill is managed by the "#enhance" command. See the sec- tion on Weapon proficiency for more information about that. - Use the `a' (apply) command and pick a saddle in your inventory + Use the `a' (apply) command and pick a saddle in your inventory to attempt to put that saddle on an adjacent creature. If successful, it will be transferred to that creature's inventory. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -2783,8 +2783,8 @@ 6.4. Bones levels You may encounter the shades and corpses of other adventurers (or - even former incarnations of yourself!) and their personal effects. - Ghosts are hard to kill, but easy to avoid, since they're slow and do + even former incarnations of yourself!) and their personal effects. + Ghosts are hard to kill, but easy to avoid, since they're slow and do little damage. You can plunder the deceased adventurer's possessions; however, they are likely to be cursed. Beware of whatever killed the former player; it is probably still lurking around, gloating over its @@ -2823,16 +2823,16 @@ are, the less the additional load will affect you. There comes a point, though, when the weight of all of that stuff you are carrying around with you through the dungeon will encumber you. Your reactions - will get slower and you'll burn calories faster, requiring food more - frequently to cope with it. Eventually, you'll be so overloaded that + will get slower and you'll burn calories faster, requiring food more + frequently to cope with it. Eventually, you'll be so overloaded that you'll either have to discard some of what you're carrying or collapse under its weight. NetHack will tell you how badly you have loaded yourself. If you - are encumbered, one of the conditions Burdened, Stressed, Strained, + are encumbered, one of the conditions Burdened, Stressed, Strained, - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -2842,25 +2842,25 @@ - Overtaxed, or Overloaded will be shown on the bottom line status dis- + Overtaxed, or Overloaded will be shown on the bottom line status dis- play. - When you pick up an object, it is assigned an inventory letter. - Many commands that operate on objects must ask you to find out which - object you want to use. When NetHack asks you to choose a particular - object you are carrying, you are usually presented with a list of + When you pick up an object, it is assigned an inventory letter. + Many commands that operate on objects must ask you to find out which + object you want to use. When NetHack asks you to choose a particular + object you are carrying, you are usually presented with a list of inventory letters to choose from (see Commands, above). - Some objects, such as weapons, are easily differentiated. Oth- - ers, like scrolls and potions, are given descriptions which vary - according to type. During a game, any two objects with the same - description are the same type. However, the descriptions will vary + Some objects, such as weapons, are easily differentiated. Oth- + ers, like scrolls and potions, are given descriptions which vary + according to type. During a game, any two objects with the same + description are the same type. However, the descriptions will vary from game to game. - When you use one of these objects, if its effect is obvious, - NetHack will remember what it is for you. If its effect isn't - extremely obvious, you will be asked what you want to call this type - of object so you will recognize it later. You can also use the + When you use one of these objects, if its effect is obvious, + NetHack will remember what it is for you. If its effect isn't + extremely obvious, you will be asked what you want to call this type + of object so you will recognize it later. You can also use the "#name" command, for the same purpose at any time, to name all objects of a particular type or just an individual object. When you use "#name" on an object which has already been named, specifying a space @@ -2873,32 +2873,32 @@ otherwise helpful. The most common effect of a curse is being stuck with (and to) the item. Cursed weapons weld themselves to your hand when wielded, so you cannot unwield them. Any cursed item you wear is - not removable by ordinary means. In addition, cursed arms and armor - usually, but not always, bear negative enchantments that make them - less effective in combat. Other cursed objects may act poorly or + not removable by ordinary means. In addition, cursed arms and armor + usually, but not always, bear negative enchantments that make them + less effective in combat. Other cursed objects may act poorly or detrimentally in other ways. - Objects can also be blessed instead. Blessed items usually work - better or more beneficially than normal uncursed items. For example, + Objects can also be blessed instead. Blessed items usually work + better or more beneficially than normal uncursed items. For example, a blessed weapon will do slightly more damage against demons. - Objects which are neither cursed nor blessed are referred to as + Objects which are neither cursed nor blessed are referred to as uncursed. They could just as easily have been described as unblessed, but the uncursed designation is what you will see within the game. A "glass half full versus glass half empty" situation; make of that what you will. - There are magical means of bestowing or removing curses upon - objects, so even if you are stuck with one, you can still have the - curse lifted and the item removed. Priests and Priestesses have an - innate sensitivity to this property in any object, so they can more - easily avoid cursed objects than other character roles. Dropping - objects onto an altar will reveal their bless or curse state provided + There are magical means of bestowing or removing curses upon + objects, so even if you are stuck with one, you can still have the + curse lifted and the item removed. Priests and Priestesses have an + innate sensitivity to this property in any object, so they can more + easily avoid cursed objects than other character roles. Dropping + objects onto an altar will reveal their bless or curse state provided that you can see them land. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -2908,10 +2908,10 @@ - An item with unknown status will be reported in your inventory - with no prefix. An item which you know the state of will be distin- - guished in your inventory by the presence of the word cursed, - uncursed, or blessed in the description of the item. In some cases + An item with unknown status will be reported in your inventory + with no prefix. An item which you know the state of will be distin- + guished in your inventory by the presence of the word cursed, + uncursed, or blessed in the description of the item. In some cases uncursed will be omitted as being redundant when enough other informa- tion is displayed. The implicit_uncursed option can be used to con- trol this; toggle it off to have uncursed be displayed even when that @@ -2924,8 +2924,8 @@ 7.2. Artifacts - Some objects have been imbued with special powers and are known - as Artifacts. They have specific types (such as long sword or orcish + Some objects have been imbued with special powers and are known + as Artifacts. They have specific types (such as long sword or orcish dagger) and distinct names such as Giantslayer or Grimtooth. Artifact weapons typically do more damage than their ordinary counterparts. Some do extra damage against all monsters, others only against spe- @@ -2955,16 +2955,16 @@ 7.3. Relics There are three unique items that are named and have limited spe- - cial powers but aren't classified as artifacts. Each is guarded by a - particular monster and you'll need to collect all three for use late - in the game. They are the Bell of Opening, the Book of the Dead, and - the Candelabrum of Invocation. Their corresponding descriptions when - not yet identified are silver bell, papyrus spellbook, and cande- + cial powers but aren't classified as artifacts. Each is guarded by a + particular monster and you'll need to collect all three for use late + in the game. They are the Bell of Opening, the Book of the Dead, and + the Candelabrum of Invocation. Their corresponding descriptions when + not yet identified are silver bell, papyrus spellbook, and cande- labrum. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -2976,23 +2976,23 @@ 7.4. Weapons (`)') - Given a chance, most monsters in the Mazes of Menace will gratu- - itously try to kill you. You need weapons for self-defense (killing - them first). Without a weapon, you do only 1-2 hit points of damage - (plus bonuses, if any). Monk characters are an exception; they nor- - mally do more damage with bare (or gloved) hands than they do with + Given a chance, most monsters in the Mazes of Menace will gratu- + itously try to kill you. You need weapons for self-defense (killing + them first). Without a weapon, you do only 1-2 hit points of damage + (plus bonuses, if any). Monk characters are an exception; they nor- + mally do more damage with bare (or gloved) hands than they do with weapons. - There are wielded weapons, like maces and swords, and thrown - weapons, like arrows and spears. To hit monsters with a weapon, you - must wield it and attack them, or throw it at them. You can simply - elect to throw a spear. To shoot an arrow, you should first wield a - bow, then throw the arrow. Crossbows shoot crossbow bolts. Slings + There are wielded weapons, like maces and swords, and thrown + weapons, like arrows and spears. To hit monsters with a weapon, you + must wield it and attack them, or throw it at them. You can simply + elect to throw a spear. To shoot an arrow, you should first wield a + bow, then throw the arrow. Crossbows shoot crossbow bolts. Slings hurl rocks and (other) stones (like gems). - Enchanted weapons have a "plus" (or "to hit enhancement" which - can be either positive or negative) that adds to your chance to hit - and the damage you do to a monster. The only way to determine a + Enchanted weapons have a "plus" (or "to hit enhancement" which + can be either positive or negative) that adds to your chance to hit + and the damage you do to a monster. The only way to determine a weapon's enchantment is to have it magically identified somehow. Most weapons are subject to some type of damage like rust. Such "erosion" damage can be repaired. @@ -3001,9 +3001,9 @@ the amount of damage such a hit will do, depends upon many factors. Among them are: type of weapon, quality of weapon (enchantment and/or erosion), experience level, strength, dexterity, encumbrance, and pro- - ficiency (see below). The monster's armor class--a general defense - rating, not necessarily due to wearing of armor--is a factor too; - also, some monsters are particularly vulnerable to certain types of + ficiency (see below). The monster's armor class--a general defense + rating, not necessarily due to wearing of armor--is a factor too; + also, some monsters are particularly vulnerable to certain types of weapons. Many weapons can be wielded in one hand; some require both hands. @@ -3021,16 +3021,16 @@ There might be times when you'd rather not wield any weapon at all. To accomplish that, wield `-', or else use the `A' command which - allows you to unwield the current weapon in addition to taking off + allows you to unwield the current weapon in addition to taking off other worn items. - Those of you in the audience who are AD&D players, be aware that + Those of you in the audience who are AD&D players, be aware that each weapon which existed in AD&D does roughly the same damage to mon- sters in NetHack. Some of the more obscure weapons (such as the aklys, lucern hammer, and bec-de-corbin) are defined in an appendix to - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -3042,22 +3042,22 @@ Unearthed Arcana, an AD&D supplement. - Some interfaces support the weaponstatus option. When it is - enabled, an extra status condition is displayed, describing the cur- + Some interfaces support the weaponstatus option. When it is + enabled, an extra status condition is displayed, describing the cur- rently wielded weapon. - The commands to use weapons are `w' (wield), `t' (throw), `f' - (fire), `Q' (quiver), `x' (exchange), `X' (twoweapon), and "#enhance" + The commands to use weapons are `w' (wield), `t' (throw), `f' + (fire), `Q' (quiver), `x' (exchange), `X' (twoweapon), and "#enhance" (see below). 7.4.1. Throwing and shooting - You can throw just about anything via the `t' command. It will - prompt for the item to throw; picking `?' will list things in your - inventory which are considered likely to be thrown, or picking `*' - will list your entire inventory. After you've chosen what to throw, - you will be prompted for a direction rather than for a specific tar- - get. The distance something can be thrown depends mainly on the type + You can throw just about anything via the `t' command. It will + prompt for the item to throw; picking `?' will list things in your + inventory which are considered likely to be thrown, or picking `*' + will list your entire inventory. After you've chosen what to throw, + you will be prompted for a direction rather than for a specific tar- + get. The distance something can be thrown depends mainly on the type of object and your strength. Arrows can be thrown by hand, but can be thrown much farther and will be more likely to hit when thrown while you are wielding a bow. @@ -3080,23 +3080,23 @@ when the inventory slot used for `Q' runs out. If your quiver is empty, autoquiver is false, and you are wielding a weapon which returns when thrown, you will throw that weapon instead of filling the - quiver. The fire command also has extra assistance, if fireassist is + quiver. The fire command also has extra assistance, if fireassist is on it will try to wield a launcher matching the ammo in the quiver. - Some characters have the ability to throw or shoot a volley of - multiple items (from the same stack) in a single action. Knowing how + Some characters have the ability to throw or shoot a volley of + multiple items (from the same stack) in a single action. Knowing how to load several rounds of ammunition at once--or hold several missiles in your hand--and still hit a target is not an easy task. Rangers are among those who are adept at this task, as are those with a high level of proficiency in the relevant weapon skill (in bow skill if you're wielding one to shoot arrows, in crossbow skill if you're wielding one - to shoot bolts, or in sling skill if you're wielding one to shoot - stones). The number of items that the character has a chance to fire - varies from turn to turn. You can explicitly limit the number of - shots by using a numeric prefix before the `t' or `f' command. For + to shoot bolts, or in sling skill if you're wielding one to shoot + stones). The number of items that the character has a chance to fire + varies from turn to turn. You can explicitly limit the number of + shots by using a numeric prefix before the `t' or `f' command. For - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -3108,24 +3108,24 @@ example, "2f" (or "n2f" if using number_pad mode) would ensure that at most 2 arrows are shot even if you could have fired 3. If you specify - a larger number than would have been shot ("4f" in this example), - you'll just end up shooting the same number (3, here) as if no limit - had been specified. Once the volley is in motion, all of the items - will travel in the same direction; if the first ones kill a monster, + a larger number than would have been shot ("4f" in this example), + you'll just end up shooting the same number (3, here) as if no limit + had been specified. Once the volley is in motion, all of the items + will travel in the same direction; if the first ones kill a monster, the others can still continue beyond that spot. 7.4.2. Weapon proficiency - You will have varying degrees of skill in the weapons available. + You will have varying degrees of skill in the weapons available. Weapon proficiency, or weapon skills, affect how well you can use par- ticular types of weapons, and you'll be able to improve your skills as - you progress through a game, depending on your role, your experience + you progress through a game, depending on your role, your experience level, and use of the weapons. - For the purposes of proficiency, weapons have been divided up - into various groups such as daggers, broadswords, and polearms. Each - role has a limit on what level of proficiency a character can achieve - for each group. For instance, wizards can become highly skilled in + For the purposes of proficiency, weapons have been divided up + into various groups such as daggers, broadswords, and polearms. Each + role has a limit on what level of proficiency a character can achieve + for each group. For instance, wizards can become highly skilled in daggers or staves but not in swords or bows. The "#enhance" extended command is used to review current weapons @@ -3137,13 +3137,13 @@ appear in the list shown by "#enhance". (Divine intervention might unrestrict a particular skill, in which case it will start at unskilled and be limited to basic.) Some characters can enhance their - barehanded combat or martial arts skill beyond expert to "master" or + barehanded combat or martial arts skill beyond expert to "master" or "grand master". - Use of a weapon in which you're restricted or unskilled will - incur a modest penalty in the chance to hit a monster and also in the - amount of damage done when you do hit; at basic level, there is no - penalty or bonus; at skilled level, you receive a modest bonus in the + Use of a weapon in which you're restricted or unskilled will + incur a modest penalty in the chance to hit a monster and also in the + amount of damage done when you do hit; at basic level, there is no + penalty or bonus; at skilled level, you receive a modest bonus in the chance to hit and amount of damage done; at expert level, the bonus is higher. A successful hit has a chance to boost your training towards the next skill level (unless you've already reached the limit for this @@ -3156,13 +3156,13 @@ 7.4.3. Two-Weapon combat - Some characters can use two weapons at once. Setting things up - to do so can seem cumbersome but becomes second nature with use. To - wield two weapons, you need to use the "#twoweapon" command. But - first you need to have a weapon in each hand. (Note that your two + Some characters can use two weapons at once. Setting things up + to do so can seem cumbersome but becomes second nature with use. To + wield two weapons, you need to use the "#twoweapon" command. But + first you need to have a weapon in each hand. (Note that your two - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -3172,8 +3172,8 @@ - weapons are not fully equal; the one in the hand you normally wield - with is considered primary and the other one is considered secondary. + weapons are not fully equal; the one in the hand you normally wield + with is considered primary and the other one is considered secondary. The most noticeable difference is after you stop--or before you begin, for that matter--wielding two weapons at once. The primary is your wielded weapon and the secondary is just an item in your inventory @@ -3188,28 +3188,28 @@ the correct weapon, use `w', `x', `w' to first wield the intended sec- ondary, swap it to off hand, and then wield the primary. - The whole process can be simplified via use of the pushweapon - option. When it is enabled, then using `w' to wield something causes - the currently wielded weapon to become your alternate weapon. So the - sequence `w', `w' can be used to first wield the weapon you intend to - be secondary, and then wield the one you want as primary which will + The whole process can be simplified via use of the pushweapon + option. When it is enabled, then using `w' to wield something causes + the currently wielded weapon to become your alternate weapon. So the + sequence `w', `w' can be used to first wield the weapon you intend to + be secondary, and then wield the one you want as primary which will push the first into secondary position. - When in two-weapon combat mode, using the `X' command toggles - back to single-weapon mode. Throwing or dropping either of the weap- - ons or having one of them be stolen or destroyed will also make you - revert to single-weapon combat. + When in two-weapon combat mode, using the `X' command toggles + back to single-weapon mode. Throwing or dropping either of the + weapons or having one of them be stolen or destroyed will also make + you revert to single-weapon combat. 7.5. Armor (`[') - Lots of unfriendly things lurk about; you need armor to protect - yourself from their blows. Some types of armor offer better protec- - tion than others. Your armor class is a measure of this protection. - Armor class (AC) is measured as in AD&D, with 10 being the equivalent - of no armor, and lower numbers meaning better armor. Each suit of + Lots of unfriendly things lurk about; you need armor to protect + yourself from their blows. Some types of armor offer better protec- + tion than others. Your armor class is a measure of this protection. + Armor class (AC) is measured as in AD&D, with 10 being the equivalent + of no armor, and lower numbers meaning better armor. Each suit of armor which exists in AD&D gives the same protection in NetHack. - Here is a list of the armor class values provided by suits of + Here is a list of the armor class values provided by suits of armor: Dragon scale mail 1 Plate mail, Crystal plate mail 3 @@ -3223,12 +3223,12 @@ Leather jacket 9 none 10 - You can also wear other pieces of armor (cloak over suit, shirt - under suit, helmet, gloves, boots, shield) to lower your armor class + You can also wear other pieces of armor (cloak over suit, shirt + under suit, helmet, gloves, boots, shield) to lower your armor class even further. Most of these provide a one or two point improvement to - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -3247,11 +3247,11 @@ If a piece of armor is enchanted, its armor protection will be better (or worse) than normal, and its "plus" (or minus) will subtract - from your armor class. For example, a +1 chain mail would give you - better protection than normal chain mail, lowering your armor class - one unit further to 4. When you put on a piece of armor, you immedi- - ately find out the armor class and any "plusses" it provides. Cursed - pieces of armor usually have negative enchantments (minuses) in addi- + from your armor class. For example, a +1 chain mail would give you + better protection than normal chain mail, lowering your armor class + one unit further to 4. When you put on a piece of armor, you immedi- + ately find out the armor class and any "plusses" it provides. Cursed + pieces of armor usually have negative enchantments (minuses) in addi- tion to being unremovable. Many types of armor are subject to some kind of damage like rust. @@ -3281,11 +3281,11 @@ boxes are heavy, and tins take a while to open. When you kill monsters, they usually leave corpses which are also - "food." Many, but not all, of these are edible; some also give you - special powers when you eat them. A good rule of thumb is "you are + "food." Many, but not all, of these are edible; some also give you + special powers when you eat them. A good rule of thumb is "you are what you eat." - Some character roles and some monsters are vegetarian. Vegetar- + Some character roles and some monsters are vegetarian. Vegetar- ian monsters will typically never eat animal corpses, while vegetarian players can, but with some rather unpleasant side-effects. @@ -3294,7 +3294,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -3323,10 +3323,10 @@ tory by type rather than by label, but the label is known in that sit- uation even though it isn't shown. - Many scrolls produce a different effect from usual if they are + Many scrolls produce a different effect from usual if they are blessed or cursed, or read while the hero is confused. - A mail daemon may run up and deliver mail to you as a scroll of + A mail daemon may run up and deliver mail to you as a scroll of mail (on versions compiled with this feature). To use this feature on versions where NetHack mail delivery is triggered by electronic mail appearing in your system mailbox, you must let NetHack know where to @@ -3342,11 +3342,11 @@ 7.8. Potions (`!') - Potions are distinguished by the color of the liquid inside the + Potions are distinguished by the color of the liquid inside the flask. They disappear after you quaff them. - Clear potions are potions of water. Sometimes these are blessed - or cursed, resulting in holy or unholy water. Holy water is the bane + Clear potions are potions of water. Sometimes these are blessed + or cursed, resulting in holy or unholy water. Holy water is the bane of the undead, so potions of holy water are good things to throw (`t') at them. It is also sometimes very useful to dip ("#dip") an object into a potion. @@ -3356,11 +3356,11 @@ 7.9. Wands (`/') Wands usually have multiple magical charges. Some types of wands - require a direction in which to zap them. You can also zap them at - yourself (just give a `.' or `s' for the direction). Be warned, how- + require a direction in which to zap them. You can also zap them at + yourself (just give a `.' or `s' for the direction). Be warned, how- - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -3370,7 +3370,7 @@ - ever, for this is often unwise. Other types of wands don't require a + ever, for this is often unwise. Other types of wands don't require a direction. The number of charges in a wand is random and decreases by one whenever you use it. @@ -3382,12 +3382,12 @@ of causing it to explode. The chance for such an explosion starts out very small and increases each time the wand is recharged. - In a truly desperate situation, when your back is up against the - wall, you might decide to go for broke and break your wand. This is - not for the faint of heart. Doing so will almost certainly cause a + In a truly desperate situation, when your back is up against the + wall, you might decide to go for broke and break your wand. This is + not for the faint of heart. Doing so will almost certainly cause a catastrophic release of magical energies. - When you have fully identified a particular wand, inventory dis- + When you have fully identified a particular wand, inventory dis- play will include additional information in parentheses: the number of times it has been recharged followed by a colon and then by its cur- rent number of charges. A current charge count of -1 is a special @@ -3422,11 +3422,11 @@ Spellbooks are tomes of mighty magic. When studied with the `r' (read) command, they transfer to the reader the knowledge of a spell (and therefore eventually become unreadable)--unless the attempt back- - fires. Reading a cursed spellbook or one with mystic runes beyond + fires. Reading a cursed spellbook or one with mystic runes beyond your ken can be harmful to your health! - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -3436,14 +3436,14 @@ - A spell (even when learned) can also backfire when you cast it. + A spell (even when learned) can also backfire when you cast it. If you attempt to cast a spell well above your experience level, or if you have little skill with the appropriate spell type, or cast it at a - time when your luck is particularly bad, you can end up wasting both + time when your luck is particularly bad, you can end up wasting both the energy and the time required in casting. - Casting a spell calls forth magical energies and focuses them - with your naked mind. Some of the magical energy released comes from + Casting a spell calls forth magical energies and focuses them + with your naked mind. Some of the magical energy released comes from within you. Casting temporarily drains your magical power, which will slowly be recovered, and causes you to need additional food. Casting of spells also requires practice. With practice, your skill in each @@ -3452,16 +3452,16 @@ Some spells require a direction in which to cast them, similar to wands. To cast one at yourself, just give a `.' or `s' for the direc- - tion. A few spells require you to pick a target location rather than - just specify a particular direction. Other spells don't require any + tion. A few spells require you to pick a target location rather than + just specify a particular direction. Other spells don't require any direction or target. - Just as weapons are divided into groups in which a character can - become proficient (to varying degrees), spells are similarly grouped. - Successfully casting a spell exercises its skill group; using the - "#enhance" command to advance a sufficiently exercised skill will - affect all spells within the group. Advanced skill may increase the - potency of spells, reduce their risk of failure during casting + Just as weapons are divided into groups in which a character can + become proficient (to varying degrees), spells are similarly grouped. + Successfully casting a spell exercises its skill group; using the + "#enhance" command to advance a sufficiently exercised skill will + affect all spells within the group. Advanced skill may increase the + potency of spells, reduce their risk of failure during casting attempts, and improve the accuracy of the estimate for how much longer they will be retained in your memory. Skill slots are shared with weapons skills. (See also the section on "Weapon proficiency".) @@ -3469,8 +3469,8 @@ Casting a spell also requires flexible movement, and wearing var- ious types of armor may interfere with that. - The command to read a spellbook is the same as for scrolls, `r' - (read). The `+' command lists each spell you know along with its + The command to read a spellbook is the same as for scrolls, `r' + (read). The `+' command lists each spell you know along with its level, skill category, chance of failure when casting, and an estimate of how strongly it is remembered. The `Z' (cast) command casts a spell. @@ -3492,7 +3492,7 @@ play the entire game without being able to see (a self-imposed chal- - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -3510,26 +3510,26 @@ You may encounter bags, boxes, and chests in your travels. A tool of this sort can be opened with the "#loot" extended command when - you are standing on top of it (that is, on the same floor spot), or - with the `a' (apply) command when you are carrying it. However, - chests are often locked, and are in any case unwieldy objects. You - must set one down before unlocking it by using a key or lock-picking - tool with the `a' (apply) command, by kicking it with the `^D' com- - mand, or by using a weapon to force the lock with the "#force" + you are standing on top of it (that is, on the same floor spot), or + with the `a' (apply) command when you are carrying it. However, + chests are often locked, and are in any case unwieldy objects. You + must set one down before unlocking it by using a key or lock-picking + tool with the `a' (apply) command, by kicking it with the `^D' com- + mand, or by using a weapon to force the lock with the "#force" extended command. - Some chests are trapped, causing nasty things to happen when you - unlock or open them. You can check for and try to deactivate traps + Some chests are trapped, causing nasty things to happen when you + unlock or open them. You can check for and try to deactivate traps with the "#untrap" extended command. - When the contents of a container are known, that container will - be described as something like "a sack containing 3 items". In this - example, the 3 refers to number of stacks of compatible items, not to - the total number of individual items. So a sack holding 2 sky blue - potions, 7 arrows, and 350 gold pieces would be described as having 3 - items rather than 10 or 359. And you would need to have 3 unused - inventory slots available in order to take everything out (for the - case where the items you remove don't combine into bigger stacks with + When the contents of a container are known, that container will + be described as something like "a sack containing 3 items". In this + example, the 3 refers to number of stacks of compatible items, not to + the total number of individual items. So a sack holding 2 sky blue + potions, 7 arrows, and 350 gold pieces would be described as having 3 + items rather than 10 or 359. And you would need to have 3 unused + inventory slots available in order to take everything out (for the + case where the items you remove don't combine into bigger stacks with things you're already carrying). If a chest or large box is described as "broken", that means that @@ -3548,17 +3548,17 @@ 7.13. Amulets (`"') Amulets are very similar to rings, and often more powerful. Like - rings, amulets have various magical properties, some beneficial, some + rings, amulets have various magical properties, some beneficial, some harmful, which are activated by putting them on. - Only one amulet may be worn at a time, around your neck. Like - wearing rings, wearing an amulet affects your metabolism, causing you + Only one amulet may be worn at a time, around your neck. Like + wearing rings, wearing an amulet affects your metabolism, causing you to grow hungry more rapidly. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -3568,8 +3568,8 @@ - The commands to use amulets are the same as for rings, `P' (put - on) and `R' (remove). `A' can be used to remove various worn items + The commands to use amulets are the same as for rings, `P' (put + on) and `R' (remove). `A' can be used to remove various worn items including amulets. Also, `W' (wear) and `T' (take off) which are nor- mally for armor can be used for amulets and other accessories (rings and eyewear), but accessories won't be shown as likely candidates in a @@ -3577,8 +3577,8 @@ 7.14. Gems (`*') - Some gems are valuable, and can be sold for a lot of gold. They - are also a far more efficient way of carrying your riches. Valuable + Some gems are valuable, and can be sold for a lot of gold. They + are also a far more efficient way of carrying your riches. Valuable gems increase your score if you bring them with you when you exit. Other small rocks are also categorized as gems, but they are much @@ -3593,23 +3593,23 @@ Boulders occasionally block your path. You can push one forward (by attempting to walk onto its spot) when nothing blocks its path, or - you can smash it into a pile of small rocks with breaking magic or a + you can smash it into a pile of small rocks with breaking magic or a pick-axe. It is possible to move onto a boulder's location if certain conditions are met; ordinarily one of those conditions is that pushing - it any further be blocked. Using the move-without-picking-up prefix - (default key `m') prior to the direction of movement will attempt to - move to a boulder's location without pushing it in addition to the + it any further be blocked. Using the move-without-picking-up prefix + (default key `m') prior to the direction of movement will attempt to + move to a boulder's location without pushing it in addition to the prefix's usual action of suppressing auto-pickup at the destination. - Very large humanoids (giants and their ilk) have been known to + Very large humanoids (giants and their ilk) have been known to pick up boulders and use them as missile weapons. - Unlike boulders, statues can't be pushed, but don't need to be - because they don't block movement. They can be smashed into rocks + Unlike boulders, statues can't be pushed, but don't need to be + because they don't block movement. They can be smashed into rocks though. - For some configurations of the program, statues are no longer - shown as ``' but by the letter representing the monster they depict + For some configurations of the program, statues are no longer + shown as ``' but by the letter representing the monster they depict instead. 7.16. Gold (`$') @@ -3624,7 +3624,7 @@ set the goldX option if you prefer to have gold pieces be treated as - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -3641,12 +3641,12 @@ 7.17. Persistence of Objects Normally, if you have seen an object at a particular map location - and move to another location where you can't directly see that object - any more, it will continue to be displayed on your map. That remains - the case even if it is not actually there any more--perhaps a monster + and move to another location where you can't directly see that object + any more, it will continue to be displayed on your map. That remains + the case even if it is not actually there any more--perhaps a monster has picked it up or it has rotted away--until you can see or feel that location again. One notable exception is that if the object gets cov- - ered by the "remembered, unseen monster" marker. When that marker is + ered by the "remembered, unseen monster" marker. When that marker is later removed after you've verified that no monster is there, you will have forgotten that there was any object there regardless of whether the unseen monster actually took the object. If the object is still @@ -3654,7 +3654,7 @@ cover the object and resume remembering it. The situation is the same for a pile of objects, except that only - the top item of the pile is displayed. The hilite_pile option can be + the top item of the pile is displayed. The hilite_pile option can be enabled in order to show an item differently when it is the top one of a pile. @@ -3673,9 +3673,9 @@ Several of the challenges are related to eating behavior. The most difficult of these is the foodless challenge. Although creatures - can survive long periods of time without food, there is a physiologi- - cal need for water; thus there is no restriction on drinking bever- - ages, even if they provide some minor food benefits. Calling upon + can survive long periods of time without food, there is a physiologi- + cal need for water; thus there is no restriction on drinking bever- + ages, even if they provide some minor food benefits. Calling upon your god for help with starvation does not violate any food challenges either. @@ -3684,13 +3684,13 @@ The corpses and tins of blobs (`b'), jellies (`j'), and fungi (`F') are also considered to be vegetable matter. Certain human food is prepared without animal products; namely, lembas wafers, cram rations, - food rations (gunyoki), K-rations, and C-rations. Metal or another + food rations (gunyoki), K-rations, and C-rations. Metal or another normally indigestible material eaten while polymorphed into a creature that can digest it is also considered vegan food. Note however that eating such items still counts against foodless conduct. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -3708,7 +3708,7 @@ of royal jelly. Monks are expected to observe a vegetarian diet. Eating any kind of meat violates the vegetarian, vegan, and food- - less conducts. This includes tripe rations, the corpses or tins of + less conducts. This includes tripe rations, the corpses or tins of any monsters not mentioned above, and the various other chunks of meat found in the dungeon. Swallowing and digesting a monster while poly- morphed is treated as if you ate the creature's corpse. Eating @@ -3719,14 +3719,14 @@ Regardless of conduct, there will be some items which are indi- gestible, and others which are hazardous to eat. Using a swallow-and- - digest attack against a monster is equivalent to eating the monster's - corpse. Please note that the term "vegan" is used here only in the - context of diet. You are still free to choose not to use or wear - items derived from animals (e.g. leather, dragon hide, bone, horns, - coral), but the game will not keep track of this for you. Also note - that "milky" potions may be a translucent white, but they do not con- - tain milk, so they are compatible with a vegan diet. Slime molds or - player-defined "fruits", although they could be anything from "cher- + digest attack against a monster is equivalent to eating the monster's + corpse. Please note that the term "vegan" is used here only in the + context of diet. You are still free to choose not to use or wear + items derived from animals (e.g. leather, dragon hide, bone, horns, + coral), but the game will not keep track of this for you. Also note + that "milky" potions may be a translucent white, but they do not con- + tain milk, so they are compatible with a vegan diet. Slime molds or + player-defined "fruits", although they could be anything from "cher- ries" to "pork chops", are also assumed to be vegan. An atheist is one who rejects religion. This means that you can- @@ -3739,7 +3739,7 @@ other religious figure; a true atheist would hear the words but attach no special meaning to them. - A pauper starts the game with no possessions, no spells, and no + A pauper starts the game with no possessions, no spells, and no weapon or spell skills (and if playing as a knight, your pony will not have a saddle). Can only be initiated by starting a new game with OPTIONS=pauper set in your run-time configurtion file or NETHACKOP- @@ -3756,7 +3756,7 @@ monster (i.e. if you would get experience for the death). This is a - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -3771,26 +3771,26 @@ An illiterate character does not read or write. This includes reading a scroll, spellbook, fortune cookie message, or t-shirt; writ- - ing a scroll; or making an engraving of anything other than a single - "X" (the traditional signature of an illiterate person). Reading an - engraving, or any item that is absolutely necessary to win the game, - is not counted against this conduct. The identity of scrolls and - spellbooks (and knowledge of spells) in your starting inventory is - assumed to be learned from your teachers prior to the start of the + ing a scroll; or making an engraving of anything other than a single + "X" (the traditional signature of an illiterate person). Reading an + engraving, or any item that is absolutely necessary to win the game, + is not counted against this conduct. The identity of scrolls and + spellbooks (and knowledge of spells) in your starting inventory is + assumed to be learned from your teachers prior to the start of the game and isn't counted. - There is a side-branch to the main dungeon called "Sokoban," - briefly described in the earlier section about Traps. As mentioned - there, the goal is to push boulders into pits and/or holes to plug - those in order to both get the boulders out of the way and be able to - go past the traps. There are some special "rules" that are active - when in that branch of the dungeon. Some rules can't be bypassed, - such as being unable to push a boulder diagonally. Other rules can, + There is a side-branch to the main dungeon called "Sokoban," + briefly described in the earlier section about Traps. As mentioned + there, the goal is to push boulders into pits and/or holes to plug + those in order to both get the boulders out of the way and be able to + go past the traps. There are some special "rules" that are active + when in that branch of the dungeon. Some rules can't be bypassed, + such as being unable to push a boulder diagonally. Other rules can, such as not smashing boulders with magic or tools, but doing so causes you to receive a luck penalty. No message about that is given at the time, but it is tracked as a conduct. The #conduct command and end of - game disclosure will report whether you have abided by the special - rules of Sokoban, and if not, how many times you violated them, pro- + game disclosure will report whether you have abided by the special + rules of Sokoban, and if not, how many times you violated them, pro- viding you with a way to discover which actions incur bad luck so that you can be better informed about whether or not to avoid repeating those actions in the future. (Note: the Sokoban conduct will only be @@ -3804,10 +3804,10 @@ There are several other challenges tracked by the game. It is possible to eliminate one or more species of monsters by genocide; playing without this feature is considered a challenge. When the game - offers you an opportunity to genocide monsters, you may respond with - the monster type "none" if you want to decline. You can change the - form of an item into another item of the same type ("polypiling") or - the form of your own body into another creature ("polyself") by wand, + offers you an opportunity to genocide monsters, you may respond with + the monster type "none" if you want to decline. You can change the + form of an item into another item of the same type ("polypiling") or + the form of your own body into another creature ("polyself") by wand, spell, or potion of polymorph; avoiding these effects are each consid- ered challenges. Polymorphing monsters, including pets, does not break either of these challenges. Finally, you may sometimes receive @@ -3822,7 +3822,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -3888,7 +3888,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -3898,18 +3898,18 @@ - There's no guaranteed Novel so the achievement to read one might - not always be attainable (except perhaps by wishing). Similarly, the - Big Room level is not always present. Unlike with the Novel, there's + There's no guaranteed Novel so the achievement to read one might + not always be attainable (except perhaps by wishing). Similarly, the + Big Room level is not always present. Unlike with the Novel, there's no way to wish for this opportunity. - The "special items" hidden in Mines' End and Sokoban are not - unique but are considered to be prizes or rewards for exploring those - levels since doing so is not necessary to complete the game. Finding - other instances of the same objects doesn't record the corresponding + The "special items" hidden in Mines' End and Sokoban are not + unique but are considered to be prizes or rewards for exploring those + levels since doing so is not necessary to complete the game. Finding + other instances of the same objects doesn't record the corresponding achievement. - The Medusa achievement is recorded if she dies for any reason, + The Medusa achievement is recorded if she dies for any reason, even if you are not directly responsible, and only if she dies. The 5-note tune can be learned via trial and error with a musical @@ -3919,14 +3919,14 @@ Blind, Deaf, Nudist, and Pauper are also conducts, and they can only be enabled by setting the correspondingly named option in NETHACKOPTIONS or run-time configuration file prior to game start. In - the case of Blind and Deaf, the option also enforces the conduct. - They aren't really significant accomplishments unless/until you make + the case of Blind and Deaf, the option also enforces the conduct. + They aren't really significant accomplishments unless/until you make substantial progress into the dungeon. 9. Options - Due to variations in personal tastes and conceptions of how - NetHack should do things, there are options you can set to change how + Due to variations in personal tastes and conceptions of how + NetHack should do things, there are options you can set to change how NetHack behaves. 9.1. Setting the options @@ -3935,7 +3935,7 @@ command allows you to view all options and change most of them. You can also set options automatically by placing them in a configuration file, or in the NETHACKOPTIONS environment variable. Some versions of - NetHack also have front-end programs that allow you to set options + NetHack also have front-end programs that allow you to set options before starting the game or a global configuration for system adminis- trators. @@ -3948,13 +3948,13 @@ directory. The file may not exist, but it is a normal ASCII text file and can be created with any text editor. - On Windows, the name is ".nethackrc" located in the folder - "%USERPROFILE%\NetHack\". The file may not exist, but it is a normal - ASCII text file can can be created with any text editor. After run- - ning NetHack for the first time, you should find a default template + On Windows, the name is ".nethackrc" located in the folder + "%USERPROFILE%\NetHack\". The file may not exist, but it is a normal + ASCII text file can can be created with any text editor. After run- + ning NetHack for the first time, you should find a default template - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -3964,13 +3964,13 @@ - for the configuration file named ".nethackrc.template" in - "%USERPROFILE%\NetHack\". If you have not created the configuration + for the configuration file named ".nethackrc.template" in + "%USERPROFILE%\NetHack\". If you have not created the configuration file, NetHack will create one for you using the default template file. On MS-DOS, it is "defaults.nh" in the same folder as nethack.exe. - Any line in the configuration file starting with `#' is treated + Any line in the configuration file starting with `#' is treated as a comment and ignored. Empty lines are ignored. Any line beginning with `[' and ending in `]' is a section marker @@ -3978,26 +3978,26 @@ comment beginning with `#'). The text between the square brackets is the section name. Section markers are only valid after a CHOOSE directive and their names are case-insensitive. Lines after a section - marker belong to that section up until another section starts or a - marker without a name is encountered or the file ends. Lines within - sections are ignored unless a CHOOSE directive has selected that sec- + marker belong to that section up until another section starts or a + marker without a name is encountered or the file ends. Lines within + sections are ignored unless a CHOOSE directive has selected that sec- tion. - You can use different configuration directives in the file, some - of which can be used multiple times. In general, the directives are - written in capital letters, followed by an equals sign, followed by + You can use different configuration directives in the file, some + of which can be used multiple times. In general, the directives are + written in capital letters, followed by an equals sign, followed by settings particular to that directive. Here is a list of allowed directives: OPTIONS - There are two types of options, boolean and compound options. Bool- - ean options toggle a setting on or off, while compound options take - more diverse values. Prefix a boolean option with "no" or `!' to - turn it off. For compound options, the option name and value are + There are two types of options, boolean and compound options. + Boolean options toggle a setting on or off, while compound options + take more diverse values. Prefix a boolean option with "no" or `!' + to turn it off. For compound options, the option name and value are separated by a colon. Some options are persistent, and apply only to new games. You can specify multiple OPTIONS directives, and mul- - tiple options separated by commas in a single OPTIONS directive. + tiple options separated by commas in a single OPTIONS directive. (Comma separated options are processed from right to left.) Example: @@ -4006,21 +4006,21 @@ OPTIONS=!legacy,autopickup,pickup_types:$"=/!?+ HACKDIR + [not availabe on Unix] Default location of files NetHack needs. On Windows HACKDIR defaults to the location of the NetHack.exe or NetHackw.exe file so setting HACKDIR to override that is not usually necessary or recommended. LEVELDIR + [not availabe on Unix] The location that in-progress level files are stored. Defaults to HACKDIR, must be writable. SAVEDIR - The location where saved games are kept. Defaults to HACKDIR, must - be writable. + [not availabe on Unix] - - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -4030,22 +4030,28 @@ + The location where saved games are kept. Defaults to HACKDIR, must + be writable. + BONESDIR + [not availabe on Unix] The location that bones files are kept. Defaults to HACKDIR, must be writable. LOCKDIR + [not availabe on Unix] The location that file synchronization locks are stored. Defaults to HACKDIR, must be writable. TROUBLEDIR + [not availabe on Unix] The location that a record of game aborts and self-diagnosed game problems is kept. Defaults to HACKDIR, must be writable. AUTOCOMPLETE Enable or disable an extended command autocompletion. Autocomple- tion has no effect for the X11 windowport. You can specify multiple - autocompletions. To enable autocompletion, list the extended com- + autocompletions. To enable autocompletion, list the extended com- mand. Prefix the command with "!" to disable the autocompletion for that command. @@ -4060,7 +4066,7 @@ BINDINGS Change the key bindings of some special keys, menu accelerators, extended commands, or mouse buttons. You can specify multiple bind- - ings. Format is key followed by the command, separated by a colon. + ings. Format is key followed by the command, separated by a colon. See the "Changing Key Bindings" section for more information. Example: @@ -4073,6 +4079,23 @@ Example: + + + + + + + + NetHack 5.0.0 May 28, 2026 + + + + + + NetHack Guidebook 63 + + + OPTIONS=color CHOOSE=char A,char B [char A] @@ -4083,23 +4106,11 @@ OPTIONS=!rest_on_space If [] is present, the preceding section is closed and no new section - begins; whatever follows will be common to all sections. Otherwise - - - NetHack 5.0.0 May 25, 2026 - - - - - - NetHack Guidebook 63 - - - + begins; whatever follows will be common to all sections. Otherwise the last section extends to the end of the options file. MENUCOLOR - Highlight menu lines with different colors. See the "Configuring + Highlight menu lines with different colors. See the "Configuring Menu Colors" section. MSGTYPE @@ -4128,9 +4139,9 @@ WIZKIT Debug mode only: extra items to add to initial inventory. Value is - the name of a text file containing a list of item names, one per - line, up to a maximum of 128 lines. Each line is processed by the - function that handles wishing. Entries are added to the wish his- + the name of a text file containing a list of item names, one per + line, up to a maximum of 128 lines. Each line is processed by the + function that handles wishing. Entries are added to the wish his- tory; see the wizwish-command. Example: @@ -4139,20 +4150,9 @@ - Here is an example of configuration file contents: - - - - - - - - - - - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -4162,6 +4162,8 @@ + Here is an example of configuration file contents: + # Set your character's role, race, gender, and alignment. OPTIONS=role:Valkyrie, race:Human, gender:female, align:lawful # @@ -4183,8 +4185,8 @@ 9.3. Using the NETHACKOPTIONS environment variable - The NETHACKOPTIONS variable is a comma-separated list of initial - values for the various options. Some can only be turned on or off. + The NETHACKOPTIONS variable is a comma-separated list of initial + values for the various options. Some can only be turned on or off. You turn one of these on by adding the name of the option to the list, and turn it off by typing a `!' or "no" before the name. Others take a character string as a value. You can set string options by typing @@ -4214,11 +4216,9 @@ Instead of a comma-separated list of options, NETHACKOPTIONS can be set to the full name of a configuration file you want to use. If - that full name doesn't start with a slash, precede it with `@' (at- - sign) to let NetHack know that the rest is intended as a file name. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -4228,6 +4228,8 @@ + that full name doesn't start with a slash, precede it with `@' (at- + sign) to let NetHack know that the rest is intended as a file name. If it does start with `/', the at-sign is optional. 9.4. Customization options @@ -4244,7 +4246,7 @@ Add location or direction information to messages (default is off). acoustics - Enable messages about what your character hears (default on). Note + Enable messages about what your character hears (default on). Note that this has nothing to do with your computer's audio capabilities. Persistent. @@ -4255,14 +4257,14 @@ role for a description of how to use negation to exclude choices. If align is not specified, there is no default value; player will be - prompted unless role and/or race forces a choice for alignment. + prompted unless role and/or race forces a choice for alignment. Cannot be set with the `O' command. Persistent. armorstatus - Display an extra status condition which summarizes currently worn + Display an extra status condition which summarizes currently worn armor (default off, not supported by all interfaces). - For the usual case where more than one piece of armor is worn, a + For the usual case where more than one piece of armor is worn, a list of letters is shown in the following order: G - gloves; @@ -4274,17 +4276,15 @@ S - shield. autodescribe - Automatically describe the terrain under cursor when asked to get a - location on the map (default true). The whatis_coord option con- + Automatically describe the terrain under cursor when asked to get a + location on the map (default true). The whatis_coord option con- trols whether the description includes map coordinates. autodig Automatically dig if you are wielding a digging tool and moving into - a place that can be dug (default false). Persistent. - - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -4294,23 +4294,25 @@ + a place that can be dug (default false). Persistent. + autoopen Walking into a closed door attempts to open it (default true). Per- sistent. autopickup - Automatically pick up things onto which you move (default off). + Automatically pick up things onto which you move (default off). Persistent. - See pickup_types and also autopickup_exception for ways to refine + See pickup_types and also autopickup_exception for ways to refine the behavior. Note: prior to version 5.0.0, the default for autopickup was on. autoquiver - This option controls what happens when you attempt the `f' (fire) - command when nothing is quivered or readied (default false). When - true, the computer will fill your quiver or quiver sack or make + This option controls what happens when you attempt the `f' (fire) + command when nothing is quivered or readied (default false). When + true, the computer will fill your quiver or quiver sack or make ready some suitable weapon. Note that it will not take into account the blessed/cursed status, enchantment, damage, or quality of the weapon; you are free to manually fill your quiver or quiver sack or @@ -4328,12 +4330,12 @@ it will ask whether you want to try to disarm the trap; if you decline, your character will forget that the door or box is trapped; - Apply-Key - if carrying a key or other unlocking tool, prompt about + Apply-Key - if carrying a key or other unlocking tool, prompt about using it; - Kick - kick the door (if you omit untrap or decline to attempt - untrap and you omit apply-key or you lack a key or you + Kick - kick the door (if you omit untrap or decline to attempt + untrap and you omit apply-key or you lack a key or you decline to use the key; has no effect on containers); - Force - try to force a container's lid with your currently + Force - try to force a container's lid with your currently wielded weapon (if you omit untrap or decline to attempt untrap and you omit apply-key or you lack a key or you decline to use the key; has no effect on doors); @@ -4343,14 +4345,12 @@ Omitting the value is treated as if autounlock:apply-key. Preceding autounlock with `!' or "no" is treated as autounlock:none. - Applying a key might set off a trap if the door or container is - trapped. Successfully kicking a door will break it and wake up - nearby monsters. Successfully forcing a container open will break - its lock and might also destroy some of its contents or damage your - weapon or both. + Applying a key might set off a trap if the door or container is + trapped. Successfully kicking a door will break it and wake up + nearby monsters. Successfully forcing a container open will break - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -4360,6 +4360,9 @@ + its lock and might also destroy some of its contents or damage your + weapon or both. + The default is Apply-Key. Persistent. blind @@ -4369,15 +4372,15 @@ Allow saving and loading bones files (default true). Persistent. boulder - Set the character used to display boulders (default is the "large + Set the character used to display boulders (default is the "large rock" class symbol, ``'). catname - Name your starting cat (for example "catname:Morris"). Cannot be + Name your starting cat (for example "catname:Morris"). Cannot be set with the `O' command. character - Synonym for "role" to pick the type of your character (for example + Synonym for "role" to pick the type of your character (for example "character:Monk"). See role for more details. checkpoint @@ -4413,10 +4416,7 @@ - - - - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -4458,12 +4458,12 @@ of-game disclosure follows a set sequence. (for example "disclose:yi na +v -g o") The example sets inventory to - prompt and default to yes, attributes to prompt and default to no, - vanquished to disclose without prompting, genocided to not disclose - and not prompt, conduct to implicitly prompt and default to no, and + prompt and default to yes, attributes to prompt and default to no, + vanquished to disclose without prompting, genocided to not disclose + and not prompt, conduct to implicitly prompt and default to no, and overview to disclose without prompting. - Note that the vanquished monsters list includes all monsters killed + Note that the vanquished monsters list includes all monsters killed by traps and each other as well as by you. And the dungeon overview shows all levels you had visited but does not reveal things about them that you hadn't discovered. @@ -4478,11 +4478,11 @@ interface except that it does not require that you hit Enter. It is implemented for the tty interface (default off). - For the X11 interface, which always uses a menu for choosing an - extended command, it controls whether the menu shows all available + For the X11 interface, which always uses a menu for choosing an + extended command, it controls whether the menu shows all available - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -4492,7 +4492,7 @@ - commands (on) or just the subset of commands which have tradition- + commands (on) or just the subset of commands which have tradition- ally been considered extended ones (off). female @@ -4507,15 +4507,15 @@ fixinv An object's inventory letter sticks to it when it's dropped (default - on). If this is off, dropping an object shifts all the remaining + on). If this is off, dropping an object shifts all the remaining inventory letters. Persistent. force_invmenu - Commands asking for an inventory item show a menu instead of a text + Commands asking for an inventory item show a menu instead of a text query with possible menu letters. Default is off. fruit - Name a fruit after something you enjoy eating (for example + Name a fruit after something you enjoy eating (for example "fruit:mango") (default "slime mold"). Basically a nostalgic whimsy that NetHack uses from time to time. You should set this to some- thing you find more appetizing than slime mold. Apples, oranges, @@ -4529,8 +4529,8 @@ gender option is also present it will take precedence. See role for a description of how to use negation to exclude choices. - If gender is not specified, there is no default value; player will - be prompted unless role and/or race forces a choice for gender. + If gender is not specified, there is no default value; player will + be prompted unless role and/or race forces a choice for gender. Cannot be set with the `O' command. Persistent. goldX @@ -4548,7 +4548,7 @@ might miss some interesting and/or important information. Persis- - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -4562,43 +4562,43 @@ herecmd_menu When using a windowport that supports mouse and clicking on yourself - or next to you, show a menu of possible actions for the location. + or next to you, show a menu of possible actions for the location. Same as "#herecmdmenu" and "#therecmdmenu" commands. hilite_pet - Visually distinguish pets from similar animals (default off). The - behavior of this option depends on the type of windowing you use. + Visually distinguish pets from similar animals (default off). The + behavior of this option depends on the type of windowing you use. In text windowing, text highlighting or inverse video is often used; with tiles, generally displays a heart symbol near pets. With the tty or curses interface, the petattr option controls how to - highlight pets and setting it will turn the hilite_pet option on or + highlight pets and setting it will turn the hilite_pet option on or off as warranted. hilite_pile Visually distinguish piles of objects from individual objects - (default off). The behavior of this option depends on the type of - windowing you use. In text windowing, text highlighting or inverse - video is often used; with tiles, generally displays a small plus- + (default off). The behavior of this option depends on the type of + windowing you use. In text windowing, text highlighting or inverse + video is often used; with tiles, generally displays a small plus- symbol beside the object on the top of the pile. hitpointbar - Show a hit point bar graph behind your name and title in the status + Show a hit point bar graph behind your name and title in the status display (default off). - The "curses" interface supports it even if the status highlighting - feature has been disabled when building the program. The "tty" and - "mswin" (aka "Windows GUI") interfaces support it only if status - highlighting is left enabled when building. You don't need to set - up any highlighting rules in order to display the bar. If there is - one for hitpoints in effect and it specifies color, that color will + The "curses" interface supports it even if the status highlighting + feature has been disabled when building the program. The "tty" and + "mswin" (aka "Windows GUI") interfaces support it only if status + highlighting is left enabled when building. You don't need to set + up any highlighting rules in order to display the bar. If there is + one for hitpoints in effect and it specifies color, that color will be used for the bar. However if it specifies video attributes, they will be ignored in favor of inverse. For tty and curses, blink will also be used if the current hitpoint value is at or below the criti- cal HP threshold. The "Qt" interface also supports hitpointbar, by drawing a solid bar - above the name and title with a hard-coded color scheme. (As of + above the name and title with a hard-coded color scheme. (As of this writing, having the bar enabled unintentionally inhibits resiz- ing the status panel. To resize that, use the #optionsfull command to toggle the hitpointbar option off, perform the resize while it's @@ -4614,7 +4614,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -4639,32 +4639,32 @@ your character as lit (default off). Persistent. lootabc - When using a menu to interact with a container, use the old `a', - `b', and `c' keyboard shortcuts rather than the mnemonics `o', `i', + When using a menu to interact with a container, use the old `a', + `b', and `c' keyboard shortcuts rather than the mnemonics `o', `i', and `b' (default off). Persistent. mail Enable mail delivery during the game (default on). Persistent. male - An obsolete synonym for "gender:male". Cannot be set with the `O' + An obsolete synonym for "gender:male". Cannot be set with the `O' command. mention_decor - Give feedback when walking onto various dungeon features such as - stairs, fountains, or altars which are ordinarily only described - when covered by one or more objects (default off). Cannot be set + Give feedback when walking onto various dungeon features such as + stairs, fountains, or altars which are ordinarily only described + when covered by one or more objects (default off). Cannot be set with the `O' command. Persistent. mention_map Give feedback when interesting map locations change (default off). mention_walls - Give feedback when walking against a wall (default off). Persis- + Give feedback when walking against a wall (default off). Persis- tent. menucolors - Enable coloring menu lines (default off). See "Configuring Menu + Enable coloring menu lines (default off). See "Configuring Menu Colors" on how to configure the colors. menustyle @@ -4680,7 +4680,7 @@ class(es). Combination starts with a prompt for object class(es) of - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -4690,12 +4690,12 @@ - interest, but then displays a menu of matching objects rather than + interest, but then displays a menu of matching objects rather than prompting one-by-one. Full displays a menu of object classes rather than a character prompt, and then a menu of matching objects for selection. (Choosing its `A' (Autoselect-All) choice skips the sec- - ond menu. To avoid choosing that by accident, set paranoid_con- - firm:AutoAll to require confirmation.) Partial skips the object + ond menu. To avoid choosing that by accident, set paranoid_con- + firm:AutoAll to require confirmation.) Partial skips the object class filtering and immediately displays a menu of all objects. menu_deselect_all @@ -4708,9 +4708,9 @@ Key to jump to the first page in a menu. Default `^'. menu_headings - Controls how the headings in a menu are highlighted. Takes a text - attribute, or text color and attribute separated by ampersand. For - allowed attributes and colors, see "Configuring Menu Colors". Not + Controls how the headings in a menu are highlighted. Takes a text + attribute, or text color and attribute separated by ampersand. For + allowed attributes and colors, see "Configuring Menu Colors". Not all ports can actually display all types. menu_invert_all @@ -4726,11 +4726,11 @@ Key to go to the next menu page. Default `>'. menu_objsyms - Inventory and other object menus are normally separated by object + Inventory and other object menus are normally separated by object class (weapons, armor, and so forth), with a menu header line at the beginning of each group. You can have menus add the display symbol for the class of objects for each header line. You can also add the - display symbol for the individual item in each menu entry. For a + display symbol for the individual item in each menu entry. For a tiles map, that would be a small rendition of an object's tile. For a text map, it is the same character as is used for the object's class, which would be most useful when there are no headers separat- @@ -4741,12 +4741,12 @@ 1 - Headers - show symbols on header lines but not entries; 2 - Entries - show symbols on menu entry lines but not headers; 3 - Both - show symbols on headers and entries; - 4 - Conditional - only show symbols for entries if there are no + 4 - Conditional - only show symbols for entries if there are no headers; - 5 - One-or-other - show symbols on headers, or on entries if no + 5 - One-or-other - show symbols on headers, or on entries if no - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -4758,8 +4758,8 @@ headers. - Supported by tty and curses. When setting the value, it can be - specified by digit or keyword. The default value is Conditional + Supported by tty and curses. When setting the value, it can be + specified by digit or keyword. The default value is Conditional (4). menu_overlay @@ -4781,11 +4781,11 @@ menu_shift_left Key to scroll a menu--one which has been scrolled right--back to the - left. Implemented for perm_invent only by curses and X11. Default + left. Implemented for perm_invent only by curses and X11. Default `{'. menu_shift_right - Key to scroll a menu which has text beyond the right edge to the + Key to scroll a menu which has text beyond the right edge to the right. Implemented for perm_invent only by curses and X11. Default `}'. @@ -4812,7 +4812,7 @@ port is the same as specifying 0. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -4849,7 +4849,7 @@ On some systems, the default is the player's user name; on others, there is no default and the player will be prompted. The former can - made to behave like the latter by specifying a generic name such as + made to behave like the latter by specifying a generic name such as ``player''. Cannot be set with the `O' command. news @@ -4878,7 +4878,7 @@ ing 1 and negating number_pad is the same as specifying 0. (Set- - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -4911,17 +4911,17 @@ than `y', also require "no" to reject instead of accepting any non-yes response as no; changes pray and AutoAll to require "yes" or `no' too; - quit - require "yes" rather than `y' to confirm quitting the + quit - require "yes" rather than `y' to confirm quitting the game or switching into non-scoring explore mode; - die - require "yes" rather than `y' to confirm dying (not + die - require "yes" rather than `y' to confirm dying (not useful in normal play; applies to explore mode); - bones - require "yes" rather than `y' to confirm saving bones + bones - require "yes" rather than `y' to confirm saving bones data when dying in debug mode; - attack - require "yes" rather than `y' to confirm attacking a + attack - require "yes" rather than `y' to confirm attacking a peaceful monster; - wand-break - require "yes" rather than `y' to confirm breaking a + wand-break - require "yes" rather than `y' to confirm breaking a wand with the apply command; - eating - require "yes" rather than `y' to confirm whether to + eating - require "yes" rather than `y' to confirm whether to continue eating; Were-change - require "yes" rather than `y' to confirm changing form due to lycanthropy when hero has polymorph control; @@ -4929,22 +4929,22 @@ immediately praying; on by default; (to require "yes" rather than just `y', set Confirm too); trap - require `y' to confirm an attempt to move into or onto - a known trap, unless doing so is considered to be + a known trap, unless doing so is considered to be harmless; when enabled, this confirmation is also used for moving into visible gas cloud regions; (to require - "yes" rather than just `y', set Confirm too); confir- - mation can be skipped by using the `m' movement pre- + "yes" rather than just `y', set Confirm too); confir- + mation can be skipped by using the `m' movement pre- fix; swim - prevent walking into water or lava; on by default; (to deliberately step onto/into such terrain when this is set, use the `m' movement prefix when adjacent); AutoAll - require confirmation when the `A' (Autoselect-All) choice is selected in object class filtering menus for - menustyle:Full; (to require "yes" rather than just + menustyle:Full; (to require "yes" rather than just `y', set Confirm too); - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -4954,14 +4954,14 @@ - Remove - require selection from inventory for `R' and `T' com- + Remove - require selection from inventory for `R' and `T' com- mands even when wearing just one applicable item; all - turn on all of the above. By default, the pray, swim, and trap choices are enabled, the others disabled. To disable them without setting any of the other choices, - use paranoid_confirmation:none. To keep them enabled while setting - any of the others, you can include them in the new list, such as + use paranoid_confirmation:none. To keep them enabled while setting + any of the others, you can include them in the new list, such as paranoid_confirmation:attack pray swim Remove or you can precede the first entry in the list with a plus sign, paranoid_confirma- tion:+attack Remove. To remove an entry that has been previously @@ -4974,15 +4974,15 @@ can be intermixed. pauper - Start the character with no possessions (default false). Persis- + Start the character with no possessions (default false). Persis- tent. - Also start with no spells or skills, which are tied to starting - equipment. Does not inhibit acquiring and using items, spells, and + Also start with no spells or skills, which are tied to starting + equipment. Does not inhibit acquiring and using items, spells, and skills once play has started. perm_invent - If true, always display your current inventory in a window (default + If true, always display your current inventory in a window (default false). This only makes sense for windowing system interfaces that implement @@ -5007,10 +5007,10 @@ petattr Specifies one or more text highlighting attributes to use when show- - ing pets on the map. Effectively a superset of the hilite_pet bool- + ing pets on the map. Effectively a superset of the hilite_pet - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -5020,7 +5020,7 @@ - ean option. Curses or tty interface only; value is one of none, + boolean option. Curses or tty interface only; value is one of none, bold, dim, underline, italic, blink, and inverse. Some of those choices might not work, depending upon terminal hardware or terminal emulation software. @@ -5028,20 +5028,20 @@ pettype Specify the type of your initial pet, if you are playing a character class that uses multiple types of pets; or choose to have no initial - pet at all. Possible values are "cat", "dog", "horse", and "none". + pet at all. Possible values are "cat", "dog", "horse", and "none". If the choice is not allowed for the role you are currently playing, it will be silently ignored. For example, "horse" will only be hon- ored when playing a knight. Cannot be set with the `O' command. pickup_burden - When you pick up an item that would exceed this encumbrance level - (Unencumbered, Burdened, streSsed, straiNed, overTaxed, or over- - Loaded), you will be asked if you want to continue. (Default `S'). + When you pick up an item that would exceed this encumbrance level + (Unencumbered, Burdened, streSsed, straiNed, overTaxed, or over- + Loaded), you will be asked if you want to continue. (Default `S'). Persistent. pickup_stolen - If this option is on and autopickup is also on, try to pick up - things that a monster stole from you, even if they aren't in + If this option is on and autopickup is also on, try to pick up + things that a monster stole from you, even if they aren't in pickup_types or match an autopickup exception. Default is on. Per- sistent. @@ -5069,14 +5069,14 @@ pile_limit When walking across a pile of objects on the floor, threshold at which the message "there are few/several/many objects here" is given - instead of showing a popup list of those objects. A value of 0 + instead of showing a popup list of those objects. A value of 0 means "no limit" (always list the objects); a value of 1 effectively means "never show the objects" since the pile size will always be at least that big; default value is 5. Persistent. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -5087,8 +5087,8 @@ playmode - Values are "normal", "explore", or "debug". Allows selection of - explore mode (also known as discovery mode) or debug mode (also + Values are "normal", "explore", or "debug". Allows selection of + explore mode (also known as discovery mode) or debug mode (also known as wizard mode) instead of normal play. Debug mode might only be allowed for someone logged in under a particular user name (on multi-user systems) or specifying a particular character name (on @@ -5099,10 +5099,10 @@ price_quotes Whenever the game mentions the name of an object you haven't identi- fied yet, it also mentions the range of buy and sell prices you have - seen for that item (to help narrow down what it could be). The - price shown is the unit price for one item (even when you are look- - ing at a stack of multiple items). Many players may want to turn - this on while identifying objects, and then turn it back off again + seen for that item (to help narrow down what it could be). The + price shown is the unit price for one item (even when you are look- + ing at a stack of multiple items). Many players may want to turn + this on while identifying objects, and then turn it back off again for general play. Default is off. pushweapon @@ -5116,14 +5116,14 @@ quick_farsight When set, usually prevents the "you sense your surroundings" message - where play pauses to allow you to browse the map whenever clairvoy- - ance randomly activates. Some situations, such as being underwater - or engulfed, ignore this option. It does not affect the clairvoy- - ance spell where pausing to examine revealed objects or monsters is + where play pauses to allow you to browse the map whenever clairvoy- + ance randomly activates. Some situations, such as being underwater + or engulfed, ignore this option. It does not affect the clairvoy- + ance spell where pausing to examine revealed objects or monsters is less intrusive. Default is off. Persistent. race - Selects your race (for example, race:human). Choices are human, + Selects your race (for example, race:human). Choices are human, dwarf, elf, gnome, and orc but most roles restrict which of the non- human races are allowed. See role for a description of how to use negation to exclude choices. @@ -5142,7 +5142,7 @@ game). This option exists partly as an acknowledgement that some - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -5156,7 +5156,7 @@ may be necessary for certain types of challenge games. rest_on_space - Make the space bar a synonym for the `.' (#wait) command (default + Make the space bar a synonym for the `.' (#wait) command (default off). Persistent. role @@ -5174,10 +5174,10 @@ OPTIONS=role:!arc !bar !kni OPTIONS=!role:arc bar kni - There can be multiple instances of the role option if they're all + There can be multiple instances of the role option if they're all negations. - If role is not specified, there is no default value; player will be + If role is not specified, there is no default value; player will be prompted. Cannot be set with the `O' command. Persistent. roguesymset @@ -5186,7 +5186,7 @@ rogue level. rlecomp - When writing out a save file, perform run length compression of the + When writing out a save file, perform run length compression of the map. Not all ports support run length compression. It has no effect on reading an existing save file. @@ -5208,7 +5208,7 @@ sistent. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -5223,35 +5223,35 @@ sistent. safe_wait - Prevents you from waiting or searching when next to a hostile mon- + Prevents you from waiting or searching when next to a hostile mon- ster (default on). Persistent. sanity_check - Evaluate monsters, objects, and map prior to each turn (default + Evaluate monsters, objects, and map prior to each turn (default off). Debug mode only. scores - Control what parts of the score list you are shown at the end (for - example "scores:5 top scores/4 around my score/own scores"). Only - the first letter of each category (`t', `a', or `o') is necessary. + Control what parts of the score list you are shown at the end (for + example "scores:5 top scores/4 around my score/own scores"). Only + the first letter of each category (`t', `a', or `o') is necessary. Persistent. showdamage - Whenever your character takes damage, show a message of the damage + Whenever your character takes damage, show a message of the damage taken, and the amount of hit points left. showexp - Show your accumulated experience points on bottom line (default + Show your accumulated experience points on bottom line (default off). Persistent. showrace - Display yourself as the glyph for your race, rather than the glyph - for your role (default off). Note that this setting affects only - the appearance of the display, not the way the game treats you. + Display yourself as the glyph for your race, rather than the glyph + for your role (default off). Note that this setting affects only + the appearance of the display, not the way the game treats you. Persistent. showscore - Show your approximate accumulated score on bottom line (default + Show your approximate accumulated score on bottom line (default off). By default, this feature is suppressed when building the pro- gram. Persistent. @@ -5274,7 +5274,7 @@ Controls the sorting behavior for the output of the `\' and ``' com- - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -5288,32 +5288,32 @@ The possible values are: - o - list object types by class, in discovery order within each + o - list object types by class, in discovery order within each class; default; - s - list object types by sortloot classification: by class, by sub- - class within class for classes which have substantial groupings - (like helmets, boots, gloves, and so forth for armor), with - object types partly-discovered via assigned name coming before + s - list object types by sortloot classification: by class, by sub- + class within class for classes which have substantial groupings + (like helmets, boots, gloves, and so forth for armor), with + object types partly-discovered via assigned name coming before fully identified types; c - list by class, alphabetically within each class; a - list alphabetically across all classes. - Can be interactively set via the `O' command or via using the `m' + Can be interactively set via the `O' command or via using the `m' prefix before the `\' or ``' command. sortloot - Controls the sorting behavior of the pickup lists for inventory and + Controls the sorting behavior of the pickup lists for inventory and #loot commands and some others. Persistent. The possible values are: full - always sort the lists; - loot - only sort the lists that don't use inventory letters, like + loot - only sort the lists that don't use inventory letters, like with the #loot and pickup commands; none - show lists the traditional way without sorting; default. sortpack - Sort the pack contents by type when displaying inventory (default + Sort the pack contents by type when displaying inventory (default on). Persistent. sortvanquished @@ -5324,9 +5324,9 @@ t - traditional--order by monster level; ties are broken by internal monster index; default; - d - order by monster difficulty rating; ties broken by internal + d - order by monster difficulty rating; ties broken by internal index; - a - order alphabetically, first any unique monsters then all the + a - order alphabetically, first any unique monsters then all the others; c - order by monster class, by low to high level within each class; n - order by count, high to low; ties are broken by internal monster @@ -5340,7 +5340,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -5355,7 +5355,7 @@ on). sparkle - Display a sparkly effect when a monster (including yourself) is hit + Display a sparkly effect when a monster (including yourself) is hit by an attack to which it is resistant (default on). Persistent. spot_monsters @@ -5370,12 +5370,12 @@ ing Status Hilites" for further information. status_updates - Allow updates to the status lines at the bottom of the screen + Allow updates to the status lines at the bottom of the screen (default true). suppress_alert - This option may be set to a NetHack version level to suppress alert - notification messages about feature changes for that and prior ver- + This option may be set to a NetHack version level to suppress alert + notification messages about feature changes for that and prior ver- sions (for example "suppress_alert:3.3.1"). symset @@ -5406,7 +5406,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -5440,7 +5440,7 @@ Controls what the showvers option displays on the status lines. weaponstatus - Display an extra status condition which describes currently wielded + Display an extra status condition which describes currently wielded weapon (default off, not supported by all interfaces). Some possible displayed values are: @@ -5450,8 +5450,8 @@ dual-weps - wielding two weapons. whatis_coord - When using the `/' or `;' commands to look around on the map with - autodescribe on, display coordinates after the description. Also + When using the `/' or `;' commands to look around on the map with + autodescribe on, display coordinates after the description. Also works in other situations where you are asked to pick a location. The possible settings are: @@ -5462,17 +5462,17 @@ s - screen [row,column] (row is offset to match tty usage); n - none (no coordinates shown) [default]. - The whatis_coord option is also used with the "/m", "/M", "/o", and - "/O" sub-commands of `/', where the "none" setting is overridden + The whatis_coord option is also used with the "/m", "/M", "/o", and + "/O" sub-commands of `/', where the "none" setting is overridden with "map". whatis_filter - When getting a location on the map, and using the keys to cycle - through next and previous targets, allows filtering the possible + When getting a location on the map, and using the keys to cycle + through next and previous targets, allows filtering the possible targets. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -5486,8 +5486,8 @@ v - in view only a - in same area only - The area-filter tries to be slightly predictive--if you're standing - on a doorway, it will consider the area on the side of the door you + The area-filter tries to be slightly predictive--if you're standing + on a doorway, it will consider the area on the side of the door you were last moving towards. Filtering can also be changed when getting a location with the "get- @@ -5495,22 +5495,22 @@ whatis_menu When getting a location on the map, and using a key to cycle through - next and previous targets, use a menu instead to pick a target. + next and previous targets, use a menu instead to pick a target. (default off) whatis_moveskip - When getting a location on the map, and using shifted movement keys - or meta-digit keys to fast-move, instead of moving 8 units at a + When getting a location on the map, and using shifted movement keys + or meta-digit keys to fast-move, instead of moving 8 units at a time, move by skipping the same glyphs. (default off) windowtype - When the program has been built to support multiple interfaces, - select which one to use, such as "tty" or "X11" (default depends on - build-time settings; use "#version" to check). Cannot be set with + When the program has been built to support multiple interfaces, + select which one to use, such as "tty" or "X11" (default depends on + build-time settings; use "#version" to check). Cannot be set with the `O' command. - When used, it should be the first option set since its value might - enable or disable the availability of various other options. For + When used, it should be the first option set since its value might + enable or disable the availability of various other options. For multiple lines in a configuration file, that would be the first non- comment line. For a comma-separated list in NETHACKOPTIONS or an OPTIONS line in a configuration file, that would be the rightmost @@ -5532,13 +5532,13 @@ have chosen. Character strings that are too long may be truncated. Not all window ports will adjust for all settings listed here. You can safely add any of these options to your configuration file, and if - the window port is capable of adjusting to suit your preferences, it - will attempt to do so. If it can't it will silently ignore it. You + the window port is capable of adjusting to suit your preferences, it + will attempt to do so. If it can't it will silently ignore it. You can find out if an option is supported by the window port that you are currently using by checking to see if it shows up in the Options list. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -5604,7 +5604,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -5628,8 +5628,8 @@ than in a window. guicolor - Use color text and/or highlighting attributes when displaying some - non-map data (such as menu selector letters). Curses interface + Use color text and/or highlighting attributes when displaying some + non-map data (such as menu selector letters). Curses interface only; default is on. large_font @@ -5639,17 +5639,17 @@ If NetHack can, it should display the map in the manner specified. player_selection - If NetHack can, it should pop up dialog boxes, or use prompts for + If NetHack can, it should pop up dialog boxes, or use prompts for character selection. popup_dialog If NetHack can, it should pop up dialog boxes for input. preload_tiles - If NetHack can, it should preload tiles into memory. For example, + If NetHack can, it should preload tiles into memory. For example, in the protected mode MS-DOS version, control whether tiles get pre- loaded into RAM at the start of the game. Doing so enhances perfor- - mance of the tile graphics, but uses more memory. (default on). + mance of the tile graphics, but uses more memory. (default on). Cannot be set with the `O' command. scroll_amount @@ -5666,11 +5666,11 @@ support this option. softkeyboard - Display an onscreen keyboard. Handhelds are most likely to support + Display an onscreen keyboard. Handhelds are most likely to support this option. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -5681,7 +5681,7 @@ splash_screen - If NetHack can, it should display an opening splash screen when it + If NetHack can, it should display an opening splash screen when it starts up (default yes). statuslines @@ -5696,11 +5696,11 @@ The curses interface does likewise if the align_status option is set to top or bottom but ignores statuslines when set to left or right. - The Qt interface already displays more than 3 lines for status so + The Qt interface already displays more than 3 lines for status so uses the statuslines value differently. A value of 3 renders status in the Qt interface's original format, with the status window spread - out vertically. A value of 2 makes status be slightly condensed, - moving some fields to different lines to eliminate one whole line, + out vertically. A value of 2 makes status be slightly condensed, + moving some fields to different lines to eliminate one whole line, reducing the height needed. (If NetHack has been built using a ver- sion of Qt older than qt-5.9, statuslines can only be set in the run-time configuration file or via NETHACKOPTIONS, not during play @@ -5736,7 +5736,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -5759,7 +5759,7 @@ windowborders Whether to draw boxes around the map, status area, message area, and - persistent inventory window if enabled. Curses interface only. + persistent inventory window if enabled. Curses interface only. Acceptable values are 0 - off, never show borders @@ -5768,17 +5768,17 @@ 3 - on, except forced off for perm_invent 4 - auto, except forced off for perm_invent - (The 26x82 size threshold for `2' refers to number of rows and col- - umns of the display. A width of at least 110 columns (80+2+26+2) is - needed to show borders if align_status is set to left or right.) + (The 26x82 size threshold for `2' refers to number of rows and + columns of the display. A width of at least 110 columns (80+2+26+2) + is needed to show borders if align_status is set to left or right.) The persistent inventory window, when enabled, can grow until it is too big to fit on most displays, resulting in truncation of its con- tents. If borders are forced on (1) or the display is big enough to show them (2), setting the value to 3 or 4 instead will keep borders for the map, message, and status windows but have room for two addi- - tional lines of inventory plus widen each inventory line by two col- - umns. + tional lines of inventory plus widen each inventory line by two + columns. windowcolors If NetHack can, it should display all windows of a particular style @@ -5789,7 +5789,7 @@ where style is one of "menu", "message", "status", or "text", and foreground and background are colors, either numeric (hash sign fol- - lowed by three pairs of hexadecimal digits, #rrggbb), one of the + lowed by three pairs of hexadecimal digits, #rrggbb), one of the named colors (black, red, green, brown, blue, magenta, cyan, orange, bright-green, yellow, bright-blue, bright-magenta, bright-cyan, white, gray, purple, silver, maroon, fuchsia, lime, olive, navy, @@ -5802,7 +5802,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -5851,13 +5851,13 @@ prompts. Note that typing one or more digits as a count prefix prior to a command--preceded by n if the number_pad option is set-- is also subject to this conversion, so attempting to abort the count - by typing ESC will leave NetHack waiting for another character to - complete the two character sequence. Type a second ESC to finish + by typing ESC will leave NetHack waiting for another character to + complete the two character sequence. Type a second ESC to finish cancelling such a count. At other prompts a single ESC suffices. BIOS - Use BIOS calls to update the screen display quickly and to read the - keyboard (allowing the use of arrow keys to move) on machines with + Use BIOS calls to update the screen display quickly and to read the + keyboard (allowing the use of arrow keys to move) on machines with an IBM PC compatible BIOS ROM (default off, OS/2, PC, and ST NetHack only). @@ -5868,7 +5868,7 @@ hang if this is turned on. Cannot be set with the `O' command. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -5881,9 +5881,9 @@ subkeyvalue (Win32 tty NetHack only). May be used to alter the value of key- strokes that the operating system returns to NetHack to help compen- - sate for international keyboard issues. OPTIONS=subkeyvalue:171/92 - will return 92 to NetHack, if 171 was originally going to be - returned. You can use multiple subkeyvalue assignments in the con- + sate for international keyboard issues. OPTIONS=subkeyvalue:171/92 + will return 92 to NetHack, if 171 was originally going to be + returned. You can use multiple subkeyvalue assignments in the con- figuration file if needed. Cannot be set with the `O' command. video @@ -5891,9 +5891,9 @@ "default", "vga", or "vesa". Setting "vesa" will cause the game to display tiles, using the full capability of the VGA hardware. Set- ting "vga" will cause the game to display tiles, fixed at 640x480 in - 16 colors, a mode that is compatible with all VGA hardware. Third - party tilesets will probably not work. Setting "autodetect" - attempts "vesa", then "vga", and finally sets "default" if neither + 16 colors, a mode that is compatible with all VGA hardware. Third + party tilesets will probably not work. Setting "autodetect" + attempts "vesa", then "vga", and finally sets "default" if neither of those modes works. Cannot be set with the `O' command. video_height @@ -5903,38 +5903,38 @@ Set the VGA mode resolution width (MS-DOS only, with video:vesa) videocolors - Set the color palette for PC systems using NO_TERMS (default - 4-2-6-1-5-3-15-12-10-14-9-13-11, (PC NetHack only). The order of - colors is red, green, brown, blue, magenta, cyan, bright.white, - bright.red, bright.green, yellow, bright.blue, bright.magenta, and + Set the color palette for PC systems using NO_TERMS (default + 4-2-6-1-5-3-15-12-10-14-9-13-11, (PC NetHack only). The order of + colors is red, green, brown, blue, magenta, cyan, bright.white, + bright.red, bright.green, yellow, bright.blue, bright.magenta, and bright.cyan. Cannot be set with the `O' command. videoshades - Set the intensity level of the three gray scales available (default - dark normal light, PC NetHack only). If the game display is diffi- - cult to read, try adjusting these scales; if this does not correct + Set the intensity level of the three gray scales available (default + dark normal light, PC NetHack only). If the game display is diffi- + cult to read, try adjusting these scales; if this does not correct the problem, try !color. Cannot be set with the `O' command. 9.8. Regular Expressions - Regular expressions are normally POSIX extended regular expres- - sions. It is possible to compile NetHack without regular expression - support on a platform where there is no regular expression library. - While this is not true of any modern platform, if your NetHack was - built this way, patterns are instead glob patterns; regardless, this - document refers to both as `regular expressions.' This applies to + Regular expressions are normally POSIX extended regular expres- + sions. It is possible to compile NetHack without regular expression + support on a platform where there is no regular expression library. + While this is not true of any modern platform, if your NetHack was + built this way, patterns are instead glob patterns; regardless, this + document refers to both as `regular expressions.' This applies to Autopickup exceptions, Message types, Menu colors, and User sounds. 9.9. Configuring Autopickup Exceptions - You can further refine the behavior of the autopickup option + You can further refine the behavior of the autopickup option beyond what is available through the pickup_types option. By placing autopickup_exception lines in your configuration file, you can define patterns to be checked when the game is about to - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -5963,7 +5963,7 @@ to override an earlier rule. Exceptions can be set with the `O' command, but because they are not - included in your configuration file, they won't be in effect if you + included in your configuration file, they won't be in effect if you save and then restore your game. autopickup_exception rules and not saved with the game. @@ -5975,7 +5975,7 @@ The first example above will result in autopickup of any type of arrow. The second example results in the exclusion of any corpse from - autopickup. The last example results in the exclusion of items known + autopickup. The last example results in the exclusion of items known to be cursed from autopickup. 9.10. Changing Key Bindings @@ -6000,7 +6000,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -6012,7 +6012,7 @@ Menu accelerator keys The menu control or accelerator keys can also be rebound via OPTIONS - lines in the configuration file. You cannot bind object symbols or + lines in the configuration file. You cannot bind object symbols or selection letters into menu accelerators. Some interfaces only sup- port some of the menu accelerators. @@ -6027,17 +6027,17 @@ available. Special command can only be bound to a single key. count - Prefix key to start a count, to repeat a command this many times. + Prefix key to start a count, to repeat a command this many times. With number_pad only. Default is `n'. getdir.help - When asked for a direction, the key to show the help. Default is + When asked for a direction, the key to show the help. Default is `?'. getdir.mouse - When asked for a direction, the key to initiate a simulated mouse - click. You will be asked to pick a location. Use movement key- - strokes to move the cursor around the map, then type the get- + When asked for a direction, the key to initiate a simulated mouse + click. You will be asked to pick a location. Use movement key- + strokes to move the cursor around the map, then type the get- pos.pick.once key (default `,') or the getpos.pick key (default `.') to finish as if performing a left or right click. Only useful when using the #therecmdmenu command. Default is `_'. @@ -6059,14 +6059,14 @@ thing. Default is `a'. getpos.all.prev - When asked for a location, the key to go to previous closest inter- + When asked for a location, the key to go to previous closest inter- esting thing. Default is `A'. getpos.door.next - When asked for a location, the key to go to next closest door or + When asked for a location, the key to go to next closest door or - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -6102,37 +6102,37 @@ Default is `O'. getpos.menu - When asked for a location, and using one of the next or previous - keys to cycle through targets, toggle showing a menu instead. + When asked for a location, and using one of the next or previous + keys to cycle through targets, toggle showing a menu instead. Default is `!'. getpos.moveskip - When asked for a location, and using the shifted movement keys or - meta-digit keys to fast-move around, move by skipping the same + When asked for a location, and using the shifted movement keys or + meta-digit keys to fast-move around, move by skipping the same glyphs instead of by 8 units. Default is `*'. getpos.filter - When asked for a location, change the filtering mode when using one - of the next or previous keys to cycle through targets. Toggles - between no filtering, in view only, and in the same area only. + When asked for a location, change the filtering mode when using one + of the next or previous keys to cycle through targets. Toggles + between no filtering, in view only, and in the same area only. Default is `"'. getpos.pick - When asked for a location, the key to choose the location, and pos- - sibly ask for more info. When simulating a mouse click after being - asked for a direction (see getdir.mouse above), the key to use to + When asked for a location, the key to choose the location, and pos- + sibly ask for more info. When simulating a mouse click after being + asked for a direction (see getdir.mouse above), the key to use to respond as right click. Default is `.'. getpos.pick.once - When asked for a location, the key to choose the location, and skip - asking for more info. When simulating a mouse click after being + When asked for a location, the key to choose the location, and skip + asking for more info. When simulating a mouse click after being asked for a direction, the key to respond as left click. Default is `,'. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -6144,27 +6144,27 @@ getpos.pick.quick When asked for a location, the key to choose the location, skip ask- - ing for more info, and exit the location asking loop. Default is + ing for more info, and exit the location asking loop. Default is `;'. getpos.pick.verbose - When asked for a location, the key to choose the location, and show + When asked for a location, the key to choose the location, and show more info without asking. Default is `:'. getpos.self - When asked for a location, the key to go to your location. Default + When asked for a location, the key to go to your location. Default is `@'. getpos.unexplored.next - When asked for a location, the key to go to next closest unexplored + When asked for a location, the key to go to next closest unexplored location. Default is `x'. getpos.unexplored.prev - When asked for a location, the key to go to previous closest unex- + When asked for a location, the key to go to previous closest unex- plored location. Default is `X'. getpos.valid - When asked for a location, the key to go to show valid target loca- + When asked for a location, the key to go to show valid target loca- tions. Default is `$'. getpos.valid.next @@ -6198,7 +6198,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -6243,10 +6243,10 @@ Allowed colors are black, red, green, brown, blue, magenta, cyan, gray, orange, light-green, yellow, light-blue, light-magenta, light- - cyan, and white. And no-color, the default foreground color, which + cyan, and white. And no-color, the default foreground color, which isn't necessarily the same as any of the other colors. - Allowed attributes are none, bold, dim, italic, underline, blink, + Allowed attributes are none, bold, dim, italic, underline, blink, and inverse. "Normal" is a synonym for "none". Note that the plat- form used may interpret the attributes any way it wants. @@ -6259,12 +6259,12 @@ specifies that any menu line with " blessed " contained in it will be shown in green color, lines with " cursed " will be shown in red, - and lines with " cursed " followed by "(being worn)" on the same + and lines with " cursed " followed by "(being worn)" on the same line will be shown in red color and underlined. You can have multi- ple MENUCOLOR entries in your configuration file, and the last MENU- - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -6276,14 +6276,14 @@ COLOR line that matches a menu line will be used for the line. - Note that if you intend to have one or more color specifications + Note that if you intend to have one or more color specifications match " uncursed ", you will probably want to turn the - implicit_uncursed option off so that all items known to be uncursed + implicit_uncursed option off so that all items known to be uncursed are actually displayed with the "uncursed" description. 9.13. Configuring User Sounds - Some platforms allow you to define sound files to be played when + Some platforms allow you to define sound files to be played when a message that matches a user-defined pattern is delivered to the mes- sage window. At this time the Qt port and the win32tty and win32gui ports support the use of user sounds. @@ -6298,9 +6298,9 @@ An entry that maps a sound file to a user-specified message pattern. Each SOUND entry is broken down into the following parts: - MESG - message window mapping (the only one supported in + MESG - message window mapping (the only one supported in 5.0.0); - msgtype - optional; message type to use, see "Configuring Mes- + msgtype - optional; message type to use, see "Configuring Mes- sage Types" pattern - the pattern to match; sound file - the sound file to play; @@ -6319,9 +6319,9 @@ 9.14. Configuring Status Hilites - Your copy of NetHack may have been compiled with support for - "Status Hilites". If so, you can customize your game display by set- - ting thresholds to change the color or appearance of fields in the + Your copy of NetHack may have been compiled with support for + "Status Hilites". If so, you can customize your game display by set- + ting thresholds to change the color or appearance of fields in the status display. The format for defining status colors is: @@ -6330,7 +6330,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -6340,44 +6340,44 @@ - For example, the following line in your configuration file will - cause the hitpoints field to display in the color red if your hit- + For example, the following line in your configuration file will + cause the hitpoints field to display in the color red if your hit- points drop to or below a threshold of 30%: OPTION=hilite_status:hitpoints/<=30%/red/normal - (That example is actually specifying red&normal for <=30% and no- + (That example is actually specifying red&normal for <=30% and no- color&normal for >30%.) - For another example, the following line in your configuration + For another example, the following line in your configuration file will cause wisdom to be displayed red if it drops and green if it rises: OPTION=hilite_status:wisdom/down/red/up/green Allowed colors are black, red, green, brown, blue, magenta, cyan, - gray, orange, light-green, yellow, light-blue, light-magenta, light- - cyan, and white. And "no-color", the default foreground color on the + gray, orange, light-green, yellow, light-blue, light-magenta, light- + cyan, and white. And "no-color", the default foreground color on the display, which is not necessarily the same as black or white or any of the other colors. Allowed attributes are none, bold, dim, underline, italic, blink, - and inverse. "Normal" is a synonym for "none"; they should not be + and inverse. "Normal" is a synonym for "none"; they should not be used in combination with any of the other attributes. - To specify both a color and an attribute, use `&' to combine - them. To specify multiple attributes, use `+' to combine those. For + To specify both a color and an attribute, use `&' to combine + them. To specify multiple attributes, use `+' to combine those. For example: "magenta&inverse+dim". - Note that the display may substitute or ignore particular - attributes depending upon its capabilities, and in general may inter- - pret the attributes any way it wants. For example, on some display - systems a request for bold might yield blink or vice versa. On oth- - ers, issuing an attribute request while another is already set up will - replace the earlier attribute rather than combine with it. Since - NetHack issues attribute requests sequentially (at least with the tty - interface) rather than all at once, the only way a situation like that - can be controlled is to specify just one attribute. + Note that the display may substitute or ignore particular attrib- + utes depending upon its capabilities, and in general may interpret the + attributes any way it wants. For example, on some display systems a + request for bold might yield blink or vice versa. On others, issuing + an attribute request while another is already set up will replace the + earlier attribute rather than combine with it. Since NetHack issues + attribute requests sequentially (at least with the tty interface) + rather than all at once, the only way a situation like that can be + controlled is to specify just one attribute. You can adjust the appearance of the following status fields: title dungeon-level experience-level @@ -6389,14 +6389,14 @@ charisma armor-class condition alignment score - The pseudo-field "characteristics" can be used to set all six of - Str, Dex, Con, Int, Wis, and Cha at once. "HD" is "hit dice", an - approximation of experience level displayed when polymorphed. - "experience", "time", and "score" are conditionally displayed + The pseudo-field "characteristics" can be used to set all six of + Str, Dex, Con, Int, Wis, and Cha at once. "HD" is "hit dice", an + approximation of experience level displayed when polymorphed. + "experience", "time", and "score" are conditionally displayed depending upon your other option settings. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -6406,14 +6406,14 @@ - Instead of a behavior, "condition" takes the following condition - flags: stone, slime, strngl, foodpois, termill, blind, deaf, stun, + Instead of a behavior, "condition" takes the following condition + flags: stone, slime, strngl, foodpois, termill, blind, deaf, stun, conf, hallu, lev, fly, and ride. You can use "major_troubles" as an alias for stone through termill, "minor_troubles" for blind through hallu, "movement" for lev, fly, and ride, and "all" for every condi- tion. - Allowed behaviors are "always", "up", "down", "changed", a percent- + Allowed behaviors are "always", "up", "down", "changed", a percent- age or absolute number threshold, or text to match against. For the hitpoints field, the additional behavior "criticalhp" is available. It overrides other behavior rules if hit points are at or below the @@ -6436,13 +6436,13 @@ matches the percentage. It is specified as a number between 0 and 100, followed by `%' (percent sign). If the percentage is prefixed with `<=' or `>=', it also matches when value is below - or above the percentage. Use prefix `<' or `>' to match when + or above the percentage. Use prefix `<' or `>' to match when strictly below or above. (The numeric limit is relaxed - slightly for those: >-1% and <101% are allowed.) Only four - fields support percentage rules. Percentages for "hitpoints" - and "power" are straightforward; they're based on the corre- - sponding maximum field. Percentage highlight rules are also - allowed for "experience level" and "experience points" (valid + slightly for those: >-1% and <101% are allowed.) Only four + fields support percentage rules. Percentages for "hitpoints" + and "power" are straightforward; they're based on the corre- + sponding maximum field. Percentage highlight rules are also + allowed for "experience level" and "experience points" (valid when the showexp option is enabled). For those, the percentage is based on the progress from the start of the current experi- ence level to the start of the next level. So if level 2 @@ -6453,16 +6453,16 @@ allowed and matches the special case of being exactly 1 experi- ence point short of the next level. - * absolute value sets the attribute when the field value matches - that number. The number must be 0 or higher, except for - "armor-class' which allows negative values, and may optionally - be preceded by `='. If the number is preceded by `<=' or `>=' - instead, it also matches when value is below or above. If the + * absolute value sets the attribute when the field value matches + that number. The number must be 0 or higher, except for + "armor-class' which allows negative values, and may optionally + be preceded by `='. If the number is preceded by `<=' or `>=' + instead, it also matches when value is below or above. If the prefix is `<' or `>', only match when strictly above or below. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -6472,7 +6472,7 @@ - * criticalhp only applies to the hitpoints field and only when + * criticalhp only applies to the hitpoints field and only when current hit points are below a threshold (which varies by maxi- mum hit points and experience level). When the threshold is met, a criticalhp rule takes precedence over all other hit- @@ -6509,18 +6509,18 @@ NetHack can load entire symbol sets from the symbol file. - The options that are used to select a particular symbol set from + The options that are used to select a particular symbol set from the symbol file are: symset Set the name of the symbol set that you want to load. roguesymset - Set the name of the symbol set that you want to load for display on + Set the name of the symbol set that you want to load for display on the rogue level. - You can also override one or more symbols using the SYMBOLS and - ROGUESYMBOLS configuration file options. Symbols are specified as + You can also override one or more symbols using the SYMBOLS and + ROGUESYMBOLS configuration file options. Symbols are specified as name:value pairs. Note that NetHack escape-processes the value string in conventional C fashion. This means that \ is a prefix to take the following character literally. Thus \ needs to be represented as \\. @@ -6528,7 +6528,7 @@ value, and the ^ prefix causes the following character to be treated - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -6594,7 +6594,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -6660,7 +6660,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -6726,7 +6726,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -6771,18 +6771,18 @@ * Several symbols in this table appear to be blank. They are the space character, except for S_pet_override and S_hero_override which - don't have any default value and can only be used if enabled in the + don't have any default value and can only be used if enabled in the "sysconf" file. - * S_rock is misleadingly named; rocks and stones use S_gem. Statues - and boulders are the rock being referred to, but since version - 3.6.0, statues are displayed as the monster they depict. So S_rock - is only used for boulders and not used at all if overridden by the + * S_rock is misleadingly named; rocks and stones use S_gem. Statues + and boulders are the rock being referred to, but since version + 3.6.0, statues are displayed as the monster they depict. So S_rock + is only used for boulders and not used at all if overridden by the more specific S_boulder. 9.16. Customizing Map Glyph Representations Using Unicode - If your platform or terminal supports the display of UTF-8 char- + If your platform or terminal supports the display of UTF-8 char- acter sequences, you can customize your game display by assigning Uni- code codepoint values and red-green-blue colors to glyph representa- tions. The customizations can be specified for use with a symset that @@ -6792,7 +6792,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -6809,32 +6809,32 @@ The window port that is active needs to provide support for dis- playing UTF-8 character sequences and explicit red-green-blue colors in order for the glyph representation to be visible. For example, the - following line in your configuration file will cause the glyph repre- + following line in your configuration file will cause the glyph repre- sentation for glyphname G_pool to use Unicode codepoint U+224B and the color represented by R-G-B value 0-0-160: OPTIONS=glyph:G_pool/U+224B/0-0-160 - The list of acceptable glyphid's can be produced by nethack --dumpg- - lyphids. Individual NetHack glyphs can be specified using the G_ pre- - fix, or you can use an S_ symbol for a glyphid and store the custom - representation for all NetHack glyphs that would map to that particu- - lar symbol. + The list of acceptable glyphnames can be produced by nethack --dumpg- + lyphnames. Individual NetHack glyphs can be specified using the G_ + prefix, or you can use an S_ symbol for a glyphname and store the cus- + tom representation for all NetHack glyphs that would map to that par- + ticular symbol. - You will need to select a symset with a UTF8 handler to enable + You will need to select a symset with a UTF8 handler to enable the display of the customizations, such as the Enhanced symset. 9.17. Configuring NetHack for Play by the Blind - NetHack can be set up to use only standard ASCII characters for - making maps of the dungeons. This makes even the MS-DOS versions of - NetHack (which use special line-drawing characters by default) com- - pletely accessible to the blind who use speech and/or Braille access - technologies. Players will require a good working knowledge of their + NetHack can be set up to use only standard ASCII characters for + making maps of the dungeons. This makes even the MS-DOS versions of + NetHack (which use special line-drawing characters by default) com- + pletely accessible to the blind who use speech and/or Braille access + technologies. Players will require a good working knowledge of their screen-reader's review features, and will have to know how to navigate horizontally and vertically character by character. They will also find the search capabilities of their screen-readers to be quite valu- - able. Be certain to examine this Guidebook before playing so you have + able. Be certain to examine this Guidebook before playing so you have an idea what the screen layout is like. You'll also need to be able to locate the PC cursor. It is always where your character is located. Merely searching for an @-sign will not always find your character @@ -6844,7 +6844,7 @@ are often useful in giving players a better sense of the overall loca- tion of items on the screen. - NetHack can also be compiled with support for sending the game + NetHack can also be compiled with support for sending the game messages to an external program, such as a text-to-speech synthesizer. If the "#version" extended command shows "external program as a mes- sage handler", your NetHack has been compiled with the capability. @@ -6858,7 +6858,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -6919,12 +6919,12 @@ instead of moving 8 units at a time. nostatus_updates - Prevent updates to the status lines at the bottom of the screen, if - your screen-reader reads those lines. The same information can be + Prevent updates to the status lines at the bottom of the screen, if + your screen-reader reads those lines. The same information can be seen via the "#attributes" command. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -6939,46 +6939,46 @@ 9.18. Global Configuration for System Administrators - If NetHack is compiled with the SYSCF option, a system adminis- - trator should set up a global configuration; this is a file in the - same format as the traditional per-user configuration file (see - above). This file should be named sysconf and placed in the same - directory as the other NetHack support files. The options recognized - in this file are listed below. Any option not set uses a compiled-in + If NetHack is compiled with the SYSCF option, a system adminis- + trator should set up a global configuration; this is a file in the + same format as the traditional per-user configuration file (see + above). This file should be named sysconf and placed in the same + directory as the other NetHack support files. The options recognized + in this file are listed below. Any option not set uses a compiled-in default (which may not be appropriate for your system). - WIZARDS = A space-separated list of user names who are allowed to - play in debug mode (commonly referred to as wizard mode). A value - of a single asterisk (*) allows anyone to start a game in debug + WIZARDS = A space-separated list of user names who are allowed to + play in debug mode (commonly referred to as wizard mode). A value + of a single asterisk (*) allows anyone to start a game in debug mode. - SHELLERS = A list of users who are allowed to use the shell escape + SHELLERS = A list of users who are allowed to use the shell escape command (!). The syntax is the same as WIZARDS. EXPLORERS = A list of users who are allowed to use the explore mode. The syntax is the same as WIZARDS. MSGHANDLER = A path and filename of executable. Whenever a message- - window message is shown, NetHack runs this program. The program + window message is shown, NetHack runs this program. The program will get the message as the only parameter. - MAXPLAYERS = Limit the maximum number of games that can be running + MAXPLAYERS = Limit the maximum number of games that can be running at the same time. - SUPPORT = A string explaining how to get local support (no default + SUPPORT = A string explaining how to get local support (no default value). - RECOVER = A string explaining how to recover a game on this system + RECOVER = A string explaining how to recover a game on this system (no default value). - SEDUCE = 0 or 1 to disable or enable, respectively, the SEDUCE + SEDUCE = 0 or 1 to disable or enable, respectively, the SEDUCE option. When disabled, incubi and succubi behave like nymphs. - CHECK_PLNAME = Setting this to 1 will make the EXPLORERS, WIZARDS, - and SHELLERS check for the player name instead of the user's login + CHECK_PLNAME = Setting this to 1 will make the EXPLORERS, WIZARDS, + and SHELLERS check for the player name instead of the user's login name. - CHECK_SAVE_UID = 0 or 1 to disable or enable, respectively, the UID + CHECK_SAVE_UID = 0 or 1 to disable or enable, respectively, the UID (used identification number) checking for save files (to verify that the user who is restoring is the same one who saved). @@ -6990,7 +6990,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -7035,10 +7035,10 @@ %n - player name %N - first character of player name - LIVELOG = A bit-mask of types of events that should be written to - the livelog file if one is present. The sample sysconf file accom- - panying the program contains a comment which lists the meaning of - the various bits used. Intended for server systems supporting + LIVELOG = A bit-mask of types of events that should be written to + the livelog file if one is present. The sample sysconf file accom- + panying the program contains a comment which lists the meaning of + the various bits used. Intended for server systems supporting simultaneous play by multiple players (to be clear, each one running a separate single player game), for displaying their game progress to observers. Only relevant if the program was built with LIVELOG @@ -7048,15 +7048,15 @@ CRASHREPORTURL = If set to https://www.nethack.org/links/cr-37BETA.html and support is compiled - in, brings up a browser window pre-populated with the information - needed to report a problem if the game panics or ends up in an - internally inconsistent state, or if the #bugreport command is + in, brings up a browser window pre-populated with the information + needed to report a problem if the game panics or ends up in an + internally inconsistent state, or if the #bugreport command is invoked. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -7068,33 +7068,33 @@ 10. Scoring - NetHack maintains a list of the top scores or scorers on your - machine, depending on how it is set up. In the latter case, each - account on the machine can post only one non-winning score on this - list. If you score higher than someone else on this list, or better - your previous score, you will be inserted in the proper place under - your current name. How many scores are kept can also be set up when + NetHack maintains a list of the top scores or scorers on your + machine, depending on how it is set up. In the latter case, each + account on the machine can post only one non-winning score on this + list. If you score higher than someone else on this list, or better + your previous score, you will be inserted in the proper place under + your current name. How many scores are kept can also be set up when NetHack is compiled. - Your score is chiefly based upon how much experience you gained, + Your score is chiefly based upon how much experience you gained, how much loot you accumulated, how deep you explored, and how the game ended. If you quit the game, you escape with all of your gold intact. - If, however, you get killed in the Mazes of Menace, the guild will - only hear about 90% of your gold when your corpse is discovered - (adventurers have been known to collect finder's fees). So, consider - whether you want to take one last hit at that monster and possibly - live, or quit and stop with whatever you have. If you quit, you keep + If, however, you get killed in the Mazes of Menace, the guild will + only hear about 90% of your gold when your corpse is discovered + (adventurers have been known to collect finder's fees). So, consider + whether you want to take one last hit at that monster and possibly + live, or quit and stop with whatever you have. If you quit, you keep all your gold, but if you swing and live, you might find more. - If you just want to see what the current top players/games list + If you just want to see what the current top players/games list is, you can type nethack -s all on most versions. 11. Explore mode NetHack is an intricate and difficult game. Novices might falter in fear, aware of their ignorance of the means to survive. Well, fear - not. Your dungeon comes equipped with an "explore" or "discovery" - mode that enables you to keep old save files and cheat death, at the + not. Your dungeon comes equipped with an "explore" or "discovery" + mode that enables you to keep old save files and cheat death, at the paltry cost of not getting on the high score list. There are two ways of enabling explore mode. One is to start the @@ -7108,12 +7108,12 @@ 11.1. Debug mode Debug mode, also known as wizard mode, is undocumented aside from - this brief description and the various "debug mode only" commands - listed among the command descriptions. It is intended for tracking - down problems within the program rather than to provide god-like pow- - ers to your character, and players who attempt debugging are expected - to figure out how to use it themselves. It is initiated by starting - the game with the -D command-line switch or with the playmode:debug + this brief description and the various "debug mode only" commands + listed among the command descriptions. It is intended for tracking + down problems within the program rather than to provide god-like pow- + ers to your character, and players who attempt debugging are expected + to figure out how to use it themselves. It is initiated by starting + the game with the -D command-line switch or with the playmode:debug option. For some systems, the player must be logged in under a particular @@ -7122,7 +7122,7 @@ connection between "wizard mode" and the Wizard role). Attempting to - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -7139,36 +7139,36 @@ The original hack game was modeled on the Berkeley UNIX rogue game. Large portions of this document were shamelessly cribbed from A - Guide to the Dungeons of Doom, by Michael C. Toy and Kenneth C. R. C. - Arnold. Small portions were adapted from Further Exploration of the + Guide to the Dungeons of Doom, by Michael C. Toy and Kenneth C. R. C. + Arnold. Small portions were adapted from Further Exploration of the Dungeons of Doom, by Ken Arromdee. - NetHack is the product of literally scores of people's work. + NetHack is the product of literally scores of people's work. Main events in the course of the game development are described below: - Jay Fenlason wrote the original Hack, with help from Kenny Wood- + Jay Fenlason wrote the original Hack, with help from Kenny Wood- land, Mike Thome, and Jon Payne. - Andries Brouwer did a major re-write while at Stichting Mathema- - tisch Centrum (now Centrum Wiskunde & Informatica), transforming Hack + Andries Brouwer did a major re-write while at Stichting Mathema- + tisch Centrum (now Centrum Wiskunde & Informatica), transforming Hack into a very different game. He published the Hack source code for use on UNIX systems by posting that to Usenet newsgroup net.sources (later - renamed comp.sources) releasing version 1.0 in December of 1984, then - versions 1.0.1, 1.0.2, and finally 1.0.3 in July of 1985. Usenet - newsgroup net.games.hack (later renamed rec.games.hack, eventually - replaced by rec.games.roguelike.nethack) was created for discussing + renamed comp.sources) releasing version 1.0 in December of 1984, then + versions 1.0.1, 1.0.2, and finally 1.0.3 in July of 1985. Usenet + newsgroup net.games.hack (later renamed rec.games.hack, eventually + replaced by rec.games.roguelike.nethack) was created for discussing it. - Don G. Kneller ported Hack 1.0.3 to Microsoft C and MS-DOS, pro- - ducing PC HACK 1.01e, added support for DEC Rainbow graphics in ver- - sion 1.03g, and went on to produce at least four more versions (3.0, - 3.2, 3.51, and 3.6; note that these are old Hack version numbers, not + Don G. Kneller ported Hack 1.0.3 to Microsoft C and MS-DOS, pro- + ducing PC HACK 1.01e, added support for DEC Rainbow graphics in ver- + sion 1.03g, and went on to produce at least four more versions (3.0, + 3.2, 3.51, and 3.6; note that these are old Hack version numbers, not contemporary NetHack ones). - R. Black ported PC HACK 3.51 to Lattice C and the Atari + R. Black ported PC HACK 3.51 to Lattice C and the Atari 520/1040ST, producing ST Hack 1.03. - Mike Stephenson merged these various versions back together, + Mike Stephenson merged these various versions back together, incorporating many of the added features, and produced NetHack version 1.4 in 1987. He then coordinated a cast of thousands in enhancing and debugging NetHack 1.4 and released NetHack versions 2.2 and 2.3. Like @@ -7178,17 +7178,17 @@ Later, Mike coordinated a major re-write of the game, heading a team which included Ken Arromdee, Jean-Christophe Collet, Steve Creps, - Eric Hendrickson, Izchak Miller, Eric S. Raymond, John Rupley, Mike + Eric Hendrickson, Izchak Miller, Eric S. Raymond, John Rupley, Mike Threepoint, and Janet Walz, to produce NetHack 3.0c. - NetHack 3.0 was ported to the Atari by Eric R. Smith, to OS/2 by - Timo Hakulinen, and to VMS by David Gentzel. The three of them and - Kevin Darcy later joined the main NetHack Development Team to produce + NetHack 3.0 was ported to the Atari by Eric R. Smith, to OS/2 by + Timo Hakulinen, and to VMS by David Gentzel. The three of them and + Kevin Darcy later joined the main NetHack Development Team to produce subsequent revisions of 3.0. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -7198,27 +7198,27 @@ - Olaf Seibert ported NetHack 2.3 and 3.0 to the Amiga. Norm - Meluch, Stephen Spackman and Pierre Martineau designed overlay code - for PC NetHack 3.0. Johnny Lee ported NetHack 3.0 to the Macintosh. - Along with various other Dungeoneers, they continued to enhance the + Olaf Seibert ported NetHack 2.3 and 3.0 to the Amiga. Norm + Meluch, Stephen Spackman and Pierre Martineau designed overlay code + for PC NetHack 3.0. Johnny Lee ported NetHack 3.0 to the Macintosh. + Along with various other Dungeoneers, they continued to enhance the PC, Macintosh, and Amiga ports through the later revisions of 3.0. - Version 3.0 went through ten relatively rapidly released "patch- + Version 3.0 went through ten relatively rapidly released "patch- level" revisions. Versions at the time were known as 3.0 for the base release and variously as "3.0a" through "3.0j", "3.0 patchlevel 1" through "3.0 patchlevel 10", or "3.0pl1" through "3.0pl10" rather than - 3.0.0 and 3.0.1 through 3.0.10; the three component numbering scheme + 3.0.0 and 3.0.1 through 3.0.10; the three component numbering scheme began to be used with 3.1.0. - Headed by Mike Stephenson and coordinated by Izchak Miller and - Janet Walz, the NetHack Development Team which now included Ken - Arromdee, David Cohrs, Jean-Christophe Collet, Kevin Darcy, Matt Day, - Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Eric Raymond, - and Eric Smith undertook a radical revision of 3.0. They re-struc- - tured the game's design, and re-wrote major parts of the code. They - added multiple dungeons, a new display, special individual character - quests, a new endgame and many other new features, and produced + Headed by Mike Stephenson and coordinated by Izchak Miller and + Janet Walz, the NetHack Development Team which now included Ken + Arromdee, David Cohrs, Jean-Christophe Collet, Kevin Darcy, Matt Day, + Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Eric Raymond, + and Eric Smith undertook a radical revision of 3.0. They re-struc- + tured the game's design, and re-wrote major parts of the code. They + added multiple dungeons, a new display, special individual character + quests, a new endgame and many other new features, and produced NetHack 3.1. Version 3.1.0 was released in January of 1993. Ken Lorber, Gregg Wonderly and Greg Olson, with help from Richard @@ -7230,14 +7230,14 @@ 3.1 to the PC. Jon W{tte and Hao-yang Wang, with help from Ross Brown, Mike Eng- - ber, David Hairston, Michael Hamel, Jonathan Handler, Johnny Lee, Tim - Lennan, Rob Menke, and Andy Swanson, developed NetHack 3.1 for the - Macintosh, porting it for MPW. Building on their development, Bart + ber, David Hairston, Michael Hamel, Jonathan Handler, Johnny Lee, Tim + Lennan, Rob Menke, and Andy Swanson, developed NetHack 3.1 for the + Macintosh, porting it for MPW. Building on their development, Bart House added a Think C port. - Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith ported + Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith ported NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua - Delahunty, was responsible for the VMS version of NetHack 3.1. + Delahunty, was responsible for the VMS version of NetHack 3.1. Michael Allison ported NetHack 3.1 to Windows NT. Dean Luick, with help from David Cohrs, developed NetHack 3.1 for @@ -7245,16 +7245,16 @@ nh10.bdf, an optionally used custom X11 font which has tiny images in place of letters and punctuation, a precursor of tiles. Those images don't extend to individual monster and object types, just replacements - for monster and object classes (so one custom image for all "a" - insects and another for all "[" armor and so forth, not separate + for monster and object classes (so one custom image for all "a" + insects and another for all "[" armor and so forth, not separate images for beetles and ants or for cloaks and boots). - Warwick Allison wrote a graphically displayed version of NetHack - for the Atari where the tiny pictures were described as "icons" and - were distinct for specific types of monsters and objects rather than + Warwick Allison wrote a graphically displayed version of NetHack + for the Atari where the tiny pictures were described as "icons" and + were distinct for specific types of monsters and objects rather than - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -7264,24 +7264,24 @@ - just their classes. He contributed them to the NetHack Development - Team which rechristened them "tiles", original usage which has subse- - quently been picked up by various other games. NetHack's tiles sup- - port was then implemented on other platforms (initially MS-DOS but + just their classes. He contributed them to the NetHack Development + Team which rechristened them "tiles", original usage which has subse- + quently been picked up by various other games. NetHack's tiles sup- + port was then implemented on other platforms (initially MS-DOS but eventually Windows, Qt, and X11 too). - The 3.2 NetHack Development Team, comprised of Michael Allison, - Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, - Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Eric Smith, - Mike Stephenson, Janet Walz, and Paul Winner, released version 3.2.0 + The 3.2 NetHack Development Team, comprised of Michael Allison, + Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, + Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Eric Smith, + Mike Stephenson, Janet Walz, and Paul Winner, released version 3.2.0 in April of 1996. - Version 3.2 marked the tenth anniversary of the formation of the + Version 3.2 marked the tenth anniversary of the formation of the development team. In a testament to their dedication to the game, all thirteen members of the original NetHack Development Team remained on the team at the start of work on that release. During the interval between the release of 3.1.3 and 3.2.0, one of the founding members of - the NetHack Development Team, Dr. Izchak Miller, was diagnosed with + the NetHack Development Team, Dr. Izchak Miller, was diagnosed with cancer and passed away. That release of the game was dedicated to him by the development and porting teams. @@ -7294,22 +7294,22 @@ "variants" publicly available: Tom Proudfoot and Yuval Oren created NetHack++, which was quickly - renamed NetHack-- when some people incorrectly assumed that it was a - conversion of the C source code to C++. Working independently, - Stephen White wrote NetHack Plus. Tom Proudfoot later merged NetHack - Plus and his own NetHack-- to produce SLASH. Larry Stewart-Zerba and - Warwick Allison improved the spell casting system with the Wizard + renamed NetHack-- when some people incorrectly assumed that it was a + conversion of the C source code to C++. Working independently, + Stephen White wrote NetHack Plus. Tom Proudfoot later merged NetHack + Plus and his own NetHack-- to produce SLASH. Larry Stewart-Zerba and + Warwick Allison improved the spell casting system with the Wizard Patch. Warwick Allison also ported NetHack to use the Qt interface. - Warren Cheung combined SLASH with the Wizard Patch to produce + Warren Cheung combined SLASH with the Wizard Patch to produce Slash'EM, and with the help of Kevin Hugo, added more features. Kevin later joined the NetHack Development Team and incorporated the best of these ideas into NetHack 3.3. - The final update to 3.2 was the bug fix release 3.2.3, which was - released simultaneously with 3.3.0 in December 1999 just in time for - the Year 2000. Because of the newer version, 3.2.3 was released as a - source code patch only, without any ready-to-play distribution for + The final update to 3.2 was the bug fix release 3.2.3, which was + released simultaneously with 3.3.0 in December 1999 just in time for + the Year 2000. Because of the newer version, 3.2.3 was released as a + source code patch only, without any ready-to-play distribution for systems that usually had such. (To anyone considering resurrecting an old version: all versions @@ -7320,7 +7320,7 @@ file layout which prevented score entries from being read back in cor- - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -7330,63 +7330,63 @@ - rectly, interfering with insertion of new high scores and with - retrieval of old character names to use for random ghost and statue + rectly, interfering with insertion of new high scores and with + retrieval of old character names to use for random ghost and statue names in the current game.) - The 3.3 NetHack Development Team, consisting of Michael Allison, - Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, + The 3.3 NetHack Development Team, consisting of Michael Allison, + Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lorber, Dean Luick, Pat Rankin, Eric Smith, Mike Stephenson, Janet Walz, and Paul Winner, released 3.3.0 in December 1999 and 3.3.1 in August of 2000. Version 3.3 offered many firsts. It was the first version to sep- - arate race and profession. The Elf class was removed in preference to - an elf race, and the races of dwarves, gnomes, and orcs made their - first appearance in the game alongside the familiar human race. Monk - and Ranger roles joined Archeologists, Barbarians, Cavemen, Healers, - Knights, Priests, Rogues, Samurai, Tourists, Valkyries and of course, - Wizards. It was also the first version to allow you to ride a steed, - and was the first version to have a publicly available web-site list- - ing all the bugs that had been discovered. Despite that constantly - growing bug list, 3.3 proved stable enough to last for more than a + arate race and profession. The Elf class was removed in preference to + an elf race, and the races of dwarves, gnomes, and orcs made their + first appearance in the game alongside the familiar human race. Monk + and Ranger roles joined Archeologists, Barbarians, Cavemen, Healers, + Knights, Priests, Rogues, Samurai, Tourists, Valkyries and of course, + Wizards. It was also the first version to allow you to ride a steed, + and was the first version to have a publicly available web-site list- + ing all the bugs that had been discovered. Despite that constantly + growing bug list, 3.3 proved stable enough to last for more than a year and a half. - The 3.4 NetHack Development Team initially consisted of Michael - Allison, Ken Arromdee, David Cohrs, Jessie Collet, Kevin Hugo, Ken - Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet Walz, and Paul - Winner, with Warwick Allison joining just before the release of + The 3.4 NetHack Development Team initially consisted of Michael + Allison, Ken Arromdee, David Cohrs, Jessie Collet, Kevin Hugo, Ken + Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet Walz, and Paul + Winner, with Warwick Allison joining just before the release of NetHack 3.4.0 in March 2002. - As with version 3.3, various people contributed to the game as a - whole as well as supporting ports on the different platforms that + As with version 3.3, various people contributed to the game as a + whole as well as supporting ports on the different platforms that NetHack runs on: Pat Rankin maintained 3.4 for VMS. - Michael Allison maintained NetHack 3.4 for the MS-DOS platform. + Michael Allison maintained NetHack 3.4 for the MS-DOS platform. Paul Winner and Yitzhak Sapir provided encouragement. - Dean Luick, Mark Modrall, and Kevin Hugo maintained and enhanced + Dean Luick, Mark Modrall, and Kevin Hugo maintained and enhanced the Macintosh port of 3.4. - Michael Allison, David Cohrs, Alex Kompel, Dion Nicolaas, and - Yitzhak Sapir maintained and enhanced 3.4 for the Microsoft Windows - platform. Alex Kompel contributed a new graphical interface for the - Windows port. Alex Kompel also contributed a Windows CE port for + Michael Allison, David Cohrs, Alex Kompel, Dion Nicolaas, and + Yitzhak Sapir maintained and enhanced 3.4 for the Microsoft Windows + platform. Alex Kompel contributed a new graphical interface for the + Windows port. Alex Kompel also contributed a Windows CE port for 3.4.1. - Ron Van Iwaarden was the sole maintainer of NetHack for OS/2 the - past several releases. Unfortunately Ron's last OS/2 machine stopped - working in early 2006. A great many thanks to Ron for keeping NetHack + Ron Van Iwaarden was the sole maintainer of NetHack for OS/2 the + past several releases. Unfortunately Ron's last OS/2 machine stopped + working in early 2006. A great many thanks to Ron for keeping NetHack alive on OS/2 all these years. - Janne Salmijarvi and Teemu Suikki maintained and enhanced the + Janne Salmijarvi and Teemu Suikki maintained and enhanced the Amiga port of 3.4 after Janne Salmijarvi resurrected it for 3.3.1. - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -7403,37 +7403,37 @@ ning of a long release hiatus. 3.4.3 proved to be a remarkably stable version that provided continued enjoyment by the community for more than a decade. The NetHack Development Team slowly and quietly contin- - ued to work on the game behind the scenes during the tenure of 3.4.3. - It was during that same period that several new variants emerged - within the NetHack community. Notably sporkhack by Derek S. Ray, - unnethack by Patric Mueller, nitrohack and its successors originally - by Daniel Thaler and then by Alex Smith, and Dynahack by Tung Nguyen. - Some of those variants continue to be developed, maintained, and + ued to work on the game behind the scenes during the tenure of 3.4.3. + It was during that same period that several new variants emerged + within the NetHack community. Notably sporkhack by Derek S. Ray, + unnethack by Patric Mueller, nitrohack and its successors originally + by Daniel Thaler and then by Alex Smith, and Dynahack by Tung Nguyen. + Some of those variants continue to be developed, maintained, and enjoyed by the community to this day. In September 2014, an interim snapshot of the code under develop- ment was released publicly by other parties. Since that code was a work-in-progress and had not gone through the process of debugging it as a suitable release, it was decided that the version numbers present - on that code snapshot would be retired and never used in an official - NetHack release. An announcement was posted on the NetHack Develop- - ment Team's official https://www.nethack.org website to that effect, - stating that there would never be a 3.4.4, 3.5, or 3.5.0 official + on that code snapshot would be retired and never used in an official + NetHack release. An announcement was posted on the NetHack Develop- + ment Team's official https://www.nethack.org website to that effect, + stating that there would never be a 3.4.4, 3.5, or 3.5.0 official release version. - In January 2015, preparation began for the release of NetHack + In January 2015, preparation began for the release of NetHack 3.6. - At the beginning of development for what would eventually get - released as 3.6.0, the NetHack Development Team consisted of Warwick - Allison, Michael Allison, Ken Arromdee, David Cohrs, Jessie Collet, - Ken Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet Walz, and - Paul Winner. In early 2015, ahead of the release of 3.6.0, new mem- - bers Sean Hunt, Pasi Kallinen, and Derek S. Ray joined the NetHack + At the beginning of development for what would eventually get + released as 3.6.0, the NetHack Development Team consisted of Warwick + Allison, Michael Allison, Ken Arromdee, David Cohrs, Jessie Collet, + Ken Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet Walz, and + Paul Winner. In early 2015, ahead of the release of 3.6.0, new mem- + bers Sean Hunt, Pasi Kallinen, and Derek S. Ray joined the NetHack Development Team. - Near the end of the development of 3.6.0, one of the significant - inspirations for many of the humorous and fun features found in the + Near the end of the development of 3.6.0, one of the significant + inspirations for many of the humorous and fun features found in the game, author Terry Pratchett, passed away. NetHack 3.6.0 introduced a tribute to him. @@ -7452,7 +7452,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -7485,17 +7485,17 @@ In early May 2019, another 320 bug fixes along with some enhance- ments and the adopted curses window port, were released as 3.6.2. - Bart House, who had contributed to the game as a porting team - participant for decades, joined the NetHack Development Team in late + Bart House, who had contributed to the game as a porting team + participant for decades, joined the NetHack Development Team in late May 2019. - NetHack 3.6.3 was released on December 5, 2019 containing over + NetHack 3.6.3 was released on December 5, 2019 containing over 190 bug fixes to NetHack 3.6.2. - NetHack 3.6.4 was released on December 18, 2019 containing a + NetHack 3.6.4 was released on December 18, 2019 containing a security fix and a few bug fixes. - NetHack 3.6.5 was released on January 27, 2020 containing some + NetHack 3.6.5 was released on January 27, 2020 containing some security fixes and a small number of bug fixes. NetHack 3.6.6 was released on March 8, 2020 containing a security @@ -7515,10 +7515,10 @@ Exposure of the development to the public brought many good things, and some challenges. People were able to observe and criticize - changes and new features almost immediately, and they often did. The + changes and new features almost immediately, and they often did. The - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -7528,8 +7528,8 @@ - GitHub pull request system made it straightforward for people to con- - tribute directly to development. Contributions resolved many, many + GitHub pull request system made it straightforward for people to con- + tribute directly to development. Contributions resolved many, many bugs in the game and we thank all the contributors. In early 2026, with the game development getting stable enough to @@ -7552,13 +7552,13 @@ the quest texts in NetHack 5.0.0. The entire development team acknowl- edges the work done by Pasi Kallinen to make that happen. - At the time of the NetHack 5.0 release, the core development + At the time of the NetHack 5.0 release, the core development team, active and erstwhile, included Warwick Allison, Michael Allison, Ken Arromdee, David Cohrs, Jessie Collet, Bart House, Kevin Hugo, Pasi - Kallinen, Ken Lorber, Dean Luick, Pat Rankin, Derek S. Ray, Alex + Kallinen, Ken Lorber, Dean Luick, Pat Rankin, Derek S. Ray, Alex Smith, Patric Mueller, Mike Stephenson, Janet Walz, Paul Winner. - Ken Lorber, Pat Rankin, Patrick Mueller and Michael Allison + Ken Lorber, Pat Rankin, Patrick Mueller and Michael Allison helped ensure that NetHack 5.0 would run on macOS. Ingo Paschke somehow managed to revive a NetHack 5.0 port for the @@ -7566,7 +7566,7 @@ was shared so others can straightforwardly produce NetHack 5.0 for the Amiga thanks to his efforts. - Ray Chason contributed the majority of maintenance work for the + Ray Chason contributed the majority of maintenance work for the NetHack 5.0 MS-DOS port, including porting the curses interface to it. Michael Allison ensured that NetHack 5.0 core changes continued to work with the msdos port and keep it alive. Cross-compiling the MS- @@ -7584,7 +7584,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -7594,7 +7594,7 @@ - The official NetHack web site is maintained by Ken Lorber at + The official NetHack web site is maintained by Ken Lorber at https://www.nethack.org/. @@ -7639,18 +7639,18 @@ 12.1. Special Thanks - On behalf of the NetHack community, thank you very much once - again to M. Drew Streib and Pasi Kallinen for providing a public - NetHack server at nethack.alt.org. Thanks to Keith Simpson and Andy - Thomson for hardfought.org. Thanks to all those unnamed dungeoneers - who invest their time and effort into annual NetHack tournaments such - as Junethack, The November NetHack Tournament, and in days past, + On behalf of the NetHack community, thank you very much once + again to M. Drew Streib and Pasi Kallinen for providing a public + NetHack server at nethack.alt.org. Thanks to Keith Simpson and Andy + Thomson for hardfought.org. Thanks to all those unnamed dungeoneers + who invest their time and effort into annual NetHack tournaments such + as Junethack, The November NetHack Tournament, and in days past, devnull.net (gone for now, but not forgotten). - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -7662,9 +7662,9 @@ 12.2. Dungeoneers - From time to time, some depraved individual out there in netland - sends a particularly intriguing modification to help out with the - game. The NetHack Development Team sometimes makes note of the names + From time to time, some depraved individual out there in netland + sends a particularly intriguing modification to help out with the + game. The NetHack Development Team sometimes makes note of the names of the worst of these miscreants in this, the list of Dungeoneers: @@ -7716,7 +7716,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -7782,7 +7782,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 @@ -7792,7 +7792,7 @@ - Brand and product names are trademarks or registered trademarks + Brand and product names are trademarks or registered trademarks of their respective holders. @@ -7848,7 +7848,7 @@ - NetHack 5.0.0 May 25, 2026 + NetHack 5.0.0 May 28, 2026 From 287d3f60b578b3dab6133e425f783a5b412b59c7 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 28 May 2026 21:06:39 -0400 Subject: [PATCH 403/702] tone down header lines on GitHub Contributing pg --- Contributing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Contributing.md b/Contributing.md index 754f3ee9e..560efe6a7 100644 --- a/Contributing.md +++ b/Contributing.md @@ -9,7 +9,7 @@ and the body. This helps Git tools correctly parse the message. -# NetHack 5.0 Contributing.txt $NHDT-Date: 1778531111 2026/05/11 20:25:11 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -# NetHack may be freely redistributed. See license for details. + + From 942f34c8830379ff2eb3811727979a367d72baa7 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 28 May 2026 21:11:38 -0400 Subject: [PATCH 404/702] fix file name in header line --- Contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Contributing.md b/Contributing.md index 560efe6a7..7614809f0 100644 --- a/Contributing.md +++ b/Contributing.md @@ -9,7 +9,7 @@ and the body. This helps Git tools correctly parse the message. - + From 898a430617235a6eb3e2c5d70d67eed3709a0508 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 29 May 2026 06:27:02 -0400 Subject: [PATCH 405/702] follow-up bits for Guidebook.mn processing --- doc/Guidebook.mn | 12 ++++++------ doc/tmac.nh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 2d16be04b..e6536f1d4 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -3678,33 +3678,33 @@ OPTIONS=!legacy,autopickup,pickup_types:$\(dq=/!?+ .ft .ed .lp HACKDIR -[not availabe on Unix] +[not available on Unix] .br Default location of files NetHack needs. On Windows HACKDIR defaults to the location of the NetHack.exe or NetHackw.exe file so setting HACKDIR to override that is not usually necessary or recommended. .lp LEVELDIR -[not availabe on Unix] +[not available on Unix] .br The location that in-progress level files are stored. Defaults to HACKDIR, must be writable. .lp SAVEDIR -[not availabe on Unix] +[not available on Unix] .br The location where saved games are kept. Defaults to HACKDIR, must be writable. .lp BONESDIR -[not availabe on Unix] +[not available on Unix] .br The location that bones files are kept. Defaults to HACKDIR, must be writable. .lp LOCKDIR -[not availabe on Unix] +[not available on Unix] .br The location that file synchronization locks are stored. Defaults to HACKDIR, must be writable. .lp TROUBLEDIR -[not availabe on Unix] +[not available on Unix] .br The location that a record of game aborts and self-diagnosed game problems is kept. Defaults to HACKDIR, must be writable. diff --git a/doc/tmac.nh b/doc/tmac.nh index aa2ed2a56..459ee623d 100644 --- a/doc/tmac.nh +++ b/doc/tmac.nh @@ -140,5 +140,5 @@ .ie \n(.g .hy 12 .el .hy 14 .ds JW Jon W{tte\" -.if \n(.g .if !'\*[.T]'ascii' .ds Jw Jon W\(:atte +.if \n(.g .if !'\*[.T]'ascii' .ds JW Jon W\(:atte .\"tmac.nh/" From d676206200ac3ec0bb7669a7996e8a59936fe9ef Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 29 May 2026 06:31:01 -0400 Subject: [PATCH 406/702] follow-up bit Contributing.md --- Contributing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Contributing.md b/Contributing.md index 7614809f0..c304499ad 100644 --- a/Contributing.md +++ b/Contributing.md @@ -9,7 +9,7 @@ and the body. This helps Git tools correctly parse the message. - - + + From 0c7070037dd790ccdd8d3ac2f6e3361cb45387e3 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 29 May 2026 06:42:39 -0400 Subject: [PATCH 407/702] yet another Guidebook follow-up --- doc/Guidebook.mn | 2 +- doc/Guidebook.tex | 2 +- doc/Guidebook.txt | 250 +++++++++++++++++++++++----------------------- 3 files changed, 127 insertions(+), 127 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index e6536f1d4..eae8626c7 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -60,7 +60,7 @@ .ds f0 \*(vr .ds f1 \" empty .\"DO NOT REMOVE NH_DATESUB .ds f2 Date(%B %-d, %Y) -.ds f2 May 28, 2026 +.ds f2 May 29, 2026 . .\" A note on some special characters: .\" \(lq = left double quote diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 7e51aa3de..8ba048b5e 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -25,7 +25,7 @@ \author{Original version - Eric S. Raymond\\ (Edited and expanded for 5.0.0 by Mike Stephenson and others)} %DO NOT REMOVE NH_DATESUB \date{Date(%B %-d, %Y)} -\date{May 28, 2026} +\date{May 29, 2026} \maketitle diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 67dbc3524..c3a55f2d5 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for NetHack 5.0.0 by Mike Stephenson and others) - May 28, 2026 + May 29, 2026 @@ -126,7 +126,7 @@ employ to great advantage. - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -192,7 +192,7 @@ NetHack continues this fine tradition. Unlike text adventure games - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -258,7 +258,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -324,7 +324,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -390,7 +390,7 @@ dealing with magic). It affects your magical energy. - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -456,7 +456,7 @@ The number of turns elapsed so far, displayed if you have the - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -522,7 +522,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -588,7 +588,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -654,7 +654,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -720,7 +720,7 @@ instead. Only these one-step movement commands cause you to - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -786,7 +786,7 @@ down like while typing and releasing , then releas- - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -852,7 +852,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -918,7 +918,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -984,7 +984,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -1050,7 +1050,7 @@ at an adjacent "remembered, unseen monster" marker. - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -1116,7 +1116,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -1182,7 +1182,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -1248,7 +1248,7 @@ (R)UNIX is a registered trademark of The Open Group. - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -1314,7 +1314,7 @@ inventory slot. If it has a name assigned, other stacks with the - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -1380,7 +1380,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -1446,7 +1446,7 @@ fight there. Default key is `F', or `-' with number_pad - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -1512,7 +1512,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -1578,7 +1578,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -1644,7 +1644,7 @@ Pick up things at the current location. Default key is `,'. The - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -1710,7 +1710,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -1776,7 +1776,7 @@ worn. - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -1842,7 +1842,7 @@ Suspend the game, switching from NetHack to the terminal it was - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -1908,7 +1908,7 @@ pick one from inventory, except for the special case of - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -1974,7 +1974,7 @@ menu of sorting orders available (provided that the vanquished - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -2040,7 +2040,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -2106,7 +2106,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -2172,7 +2172,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -2238,7 +2238,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -2304,7 +2304,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -2370,7 +2370,7 @@ them). Some monsters who can open doors can also use unlocking tools. - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -2436,7 +2436,7 @@ been nullified, giving access to whatever is beyond them. In the - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -2502,7 +2502,7 @@ play. - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -2568,7 +2568,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -2634,7 +2634,7 @@ attack, when guessing where an unseen monster is or when deliberately - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -2700,7 +2700,7 @@ noid_confirmation:attack option to require a response of "yes" - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -2766,7 +2766,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -2832,7 +2832,7 @@ are encumbered, one of the conditions Burdened, Stressed, Strained, - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -2898,7 +2898,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -2964,7 +2964,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -3030,7 +3030,7 @@ aklys, lucern hammer, and bec-de-corbin) are defined in an appendix to - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -3096,7 +3096,7 @@ shots by using a numeric prefix before the `t' or `f' command. For - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -3162,7 +3162,7 @@ first you need to have a weapon in each hand. (Note that your two - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -3228,7 +3228,7 @@ even further. Most of these provide a one or two point improvement to - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -3294,7 +3294,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -3360,7 +3360,7 @@ yourself (just give a `.' or `s' for the direction). Be warned, how- - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -3426,7 +3426,7 @@ your ken can be harmful to your health! - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -3492,7 +3492,7 @@ play the entire game without being able to see (a self-imposed chal- - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -3558,7 +3558,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -3624,7 +3624,7 @@ set the goldX option if you prefer to have gold pieces be treated as - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -3690,7 +3690,7 @@ eating such items still counts against foodless conduct. - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -3756,7 +3756,7 @@ monster (i.e. if you would get experience for the death). This is a - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -3822,7 +3822,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -3888,7 +3888,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -3954,7 +3954,7 @@ ning NetHack for the first time, you should find a default template - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -4006,21 +4006,21 @@ OPTIONS=!legacy,autopickup,pickup_types:$"=/!?+ HACKDIR - [not availabe on Unix] + [not available on Unix] Default location of files NetHack needs. On Windows HACKDIR defaults to the location of the NetHack.exe or NetHackw.exe file so setting HACKDIR to override that is not usually necessary or recommended. LEVELDIR - [not availabe on Unix] + [not available on Unix] The location that in-progress level files are stored. Defaults to HACKDIR, must be writable. SAVEDIR - [not availabe on Unix] + [not available on Unix] - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -4034,17 +4034,17 @@ be writable. BONESDIR - [not availabe on Unix] + [not available on Unix] The location that bones files are kept. Defaults to HACKDIR, must be writable. LOCKDIR - [not availabe on Unix] + [not available on Unix] The location that file synchronization locks are stored. Defaults to HACKDIR, must be writable. TROUBLEDIR - [not availabe on Unix] + [not available on Unix] The location that a record of game aborts and self-diagnosed game problems is kept. Defaults to HACKDIR, must be writable. @@ -4086,7 +4086,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -4152,7 +4152,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -4218,7 +4218,7 @@ be set to the full name of a configuration file you want to use. If - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -4284,7 +4284,7 @@ Automatically dig if you are wielding a digging tool and moving into - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -4350,7 +4350,7 @@ nearby monsters. Successfully forcing a container open will break - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -4416,7 +4416,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -4482,7 +4482,7 @@ extended command, it controls whether the menu shows all available - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -4548,7 +4548,7 @@ might miss some interesting and/or important information. Persis- - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -4614,7 +4614,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -4680,7 +4680,7 @@ class(es). Combination starts with a prompt for object class(es) of - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -4746,7 +4746,7 @@ 5 - One-or-other - show symbols on headers, or on entries if no - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -4812,7 +4812,7 @@ port is the same as specifying 0. - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -4878,7 +4878,7 @@ ing 1 and negating number_pad is the same as specifying 0. (Set- - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -4944,7 +4944,7 @@ `y', set Confirm too); - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -5010,7 +5010,7 @@ ing pets on the map. Effectively a superset of the hilite_pet - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -5076,7 +5076,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -5142,7 +5142,7 @@ game). This option exists partly as an acknowledgement that some - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -5208,7 +5208,7 @@ sistent. - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -5274,7 +5274,7 @@ Controls the sorting behavior for the output of the `\' and ``' com- - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -5340,7 +5340,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -5406,7 +5406,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -5472,7 +5472,7 @@ targets. - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -5538,7 +5538,7 @@ currently using by checking to see if it shows up in the Options list. - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -5604,7 +5604,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -5670,7 +5670,7 @@ this option. - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -5736,7 +5736,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -5802,7 +5802,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -5868,7 +5868,7 @@ hang if this is turned on. Cannot be set with the `O' command. - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -5934,7 +5934,7 @@ you can define patterns to be checked when the game is about to - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -6000,7 +6000,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -6066,7 +6066,7 @@ When asked for a location, the key to go to next closest door or - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -6132,7 +6132,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -6198,7 +6198,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -6264,7 +6264,7 @@ ple MENUCOLOR entries in your configuration file, and the last MENU- - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -6330,7 +6330,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -6396,7 +6396,7 @@ depending upon your other option settings. - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -6462,7 +6462,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -6528,7 +6528,7 @@ value, and the ^ prefix causes the following character to be treated - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -6594,7 +6594,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -6660,7 +6660,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -6726,7 +6726,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -6792,7 +6792,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -6858,7 +6858,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -6924,7 +6924,7 @@ seen via the "#attributes" command. - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -6990,7 +6990,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -7056,7 +7056,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -7122,7 +7122,7 @@ connection between "wizard mode" and the Wizard role). Attempting to - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -7188,7 +7188,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -7254,7 +7254,7 @@ were distinct for specific types of monsters and objects rather than - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -7320,7 +7320,7 @@ file layout which prevented score entries from being read back in cor- - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -7386,7 +7386,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -7452,7 +7452,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -7518,7 +7518,7 @@ changes and new features almost immediately, and they often did. The - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -7584,7 +7584,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -7650,7 +7650,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -7716,7 +7716,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -7782,7 +7782,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 @@ -7848,7 +7848,7 @@ - NetHack 5.0.0 May 28, 2026 + NetHack 5.0.0 May 29, 2026 From 526ffaa58242bfce4f039ff4a79bfed41f145a6a Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Fri, 29 May 2026 08:16:07 -0400 Subject: [PATCH 408/702] This is cron-daily v1-May-7-2026. 005guidebook updated: doc/Guidebook.txt --- doc/Guidebook.txt | 2268 ++++++++++++++++++++++----------------------- 1 file changed, 1134 insertions(+), 1134 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index c3a55f2d5..de1b25558 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -22,18 +22,18 @@ 1. Introduction Recently, you have begun to find yourself unfulfilled and distant - in your daily occupation. Strange dreams of prospecting, stealing, - crusading, and combat have haunted you in your sleep for many months, - but you aren't sure of the reason. You wonder whether you have in - fact been having those dreams all your life, and somehow managed to - forget about them until now. Some nights you awaken suddenly and cry - out, terrified at the vivid recollection of the strange and powerful - creatures that seem to be lurking behind every corner of the dungeon - in your dream. Could these details haunting your dreams be real? As + in your daily occupation. Strange dreams of prospecting, stealing, + crusading, and combat have haunted you in your sleep for many months, + but you aren't sure of the reason. You wonder whether you have in + fact been having those dreams all your life, and somehow managed to + forget about them until now. Some nights you awaken suddenly and cry + out, terrified at the vivid recollection of the strange and powerful + creatures that seem to be lurking behind every corner of the dungeon + in your dream. Could these details haunting your dreams be real? As each night passes, you feel the desire to enter the mysterious caverns near the ruins grow stronger. Each morning, however, you quickly put the idea out of your head as you recall the tales of those who entered - the caverns before you and did not return. Eventually you can resist + the caverns before you and did not return. Eventually you can resist the yearning to seek out the fantastic place in your dreams no longer. After all, when other adventurers came back this way after spending time in the caverns, they usually seemed better off than when they @@ -41,15 +41,15 @@ who did not return had not just kept going? Asking around, you hear about a bauble, called the Amulet of Yen- - dor by some, which, if you can find it, will bring you great wealth. - One legend you were told even mentioned that the one who finds the + dor by some, which, if you can find it, will bring you great wealth. + One legend you were told even mentioned that the one who finds the amulet will be granted immortality by the gods. The amulet is rumored to be somewhere beyond the Valley of Gehennom, deep within the Mazes of Menace. Upon hearing the legends, you immediately realize that there is some profound and undiscovered reason that you are to descend - into the caverns and seek out that amulet of which they spoke. Even - if the rumors of the amulet's powers are untrue, you decide that you - should at least be able to sell the tales of your adventures to the + into the caverns and seek out that amulet of which they spoke. Even + if the rumors of the amulet's powers are untrue, you decide that you + should at least be able to sell the tales of your adventures to the local minstrels for a tidy sum, especially if you encounter any of the terrifying and magical creatures of your dreams along the way. You spend one last night fortifying yourself at the local inn, becoming @@ -70,36 +70,36 @@ - ancient ruins that mark the entrance to the Mazes of Menace. It is - late at night, so you make camp at the entrance and spend the night - sleeping under the open skies. In the morning, you gather your gear, + ancient ruins that mark the entrance to the Mazes of Menace. It is + late at night, so you make camp at the entrance and spend the night + sleeping under the open skies. In the morning, you gather your gear, eat what may be your last meal outside, and enter the dungeon.... 2. What is going on here? - You have just begun a game of NetHack. Your goal is to grab as - much treasure as you can, retrieve the Amulet of Yendor, and escape + You have just begun a game of NetHack. Your goal is to grab as + much treasure as you can, retrieve the Amulet of Yendor, and escape the Mazes of Menace alive. - Your abilities and strengths for dealing with the hazards of + Your abilities and strengths for dealing with the hazards of adventure will vary with your background and training: - Archeologists understand dungeons pretty well; this enables them - to move quickly and sneak up on the local nasties. They start - equipped with the tools for a proper scientific expedition, and are + Archeologists understand dungeons pretty well; this enables them + to move quickly and sneak up on the local nasties. They start + equipped with the tools for a proper scientific expedition, and are able to read ancient languages. - Barbarians are warriors out of the hinterland, hardened to bat- - tle. They begin their quests with naught but uncommon strength, a + Barbarians are warriors out of the hinterland, hardened to bat- + tle. They begin their quests with naught but uncommon strength, a trusty hauberk, and a great two-handed sword. Cavemen and Cavewomen start with exceptional strength but, unfor- tunately, with neolithic weapons. Healers are wise in medicine and apothecary. They know the herbs - and simples that can restore vitality, ease pain, anesthetize, and - neutralize poisons; and with their instruments, they can divine a - being's state of health or sickness. Their medical practice earns + and simples that can restore vitality, ease pain, anesthetize, and + neutralize poisons; and with their instruments, they can divine a + being's state of health or sickness. Their medical practice earns them quite reasonable amounts of money, with which they enter the dun- geon. @@ -113,16 +113,16 @@ mobility. Priests and Priestesses are clerics militant, crusaders advancing - the cause of righteousness with arms, armor, and arts thaumaturgic. - Their ability to commune with deities via prayer occasionally extri- + the cause of righteousness with arms, armor, and arts thaumaturgic. + Their ability to commune with deities via prayer occasionally extri- cates them from peril, but can also put them in it. - Rangers are most at home in the woods, and some say slightly out - of place in a dungeon. They are, however, experts in archery as well + Rangers are most at home in the woods, and some say slightly out + of place in a dungeon. They are, however, experts in archery as well as tracking and stealthy movement. - Rogues are agile and stealthy thieves, with knowledge of locks, - traps, and poisons. Their advantage lies in surprise, which they + Rogues are agile and stealthy thieves, with knowledge of locks, + traps, and poisons. Their advantage lies in surprise, which they employ to great advantage. @@ -136,12 +136,12 @@ - Samurai are the elite warriors of feudal Nippon. They are - lightly armored and quick, and wear the dai-sho, two swords of the + Samurai are the elite warriors of feudal Nippon. They are + lightly armored and quick, and wear the dai-sho, two swords of the deadliest keenness. - Tourists start out with lots of gold (suitable for shopping - with), a credit card, lots of food, some maps, and an expensive cam- + Tourists start out with lots of gold (suitable for shopping + with), a credit card, lots of food, some maps, and an expensive cam- era. Most monsters don't like being photographed. Valkyries are hardy warrior women. Their upbringing in the harsh @@ -170,11 +170,11 @@ ground mine complex built by this race exists within the Mazes of Men- ace, filled with both riches and danger. - Humans are by far the most common race of the surface world, and - are thus the norm to which other races are often compared. Although + Humans are by far the most common race of the surface world, and + are thus the norm to which other races are often compared. Although they have no special abilities, they can succeed in any role. - Orcs are a cruel and barbaric race that hate every living thing + Orcs are a cruel and barbaric race that hate every living thing (including other orcs). Above all others, Orcs hate Elves with a pas- sion unequalled, and will go out of their way to kill one at any opportunity. The armor and weapons fashioned by the Orcs are typi- @@ -187,9 +187,9 @@ level, it appears on the screen in front of you. When NetHack's ancestor rogue first appeared, its screen orienta- - tion was almost unique among computer fantasy games. Since then, - screen orientation has become the norm rather than the exception; - NetHack continues this fine tradition. Unlike text adventure games + tion was almost unique among computer fantasy games. Since then, + screen orientation has become the norm rather than the exception; + NetHack continues this fine tradition. Unlike text adventure games NetHack 5.0.0 May 29, 2026 @@ -202,8 +202,8 @@ - that accept commands in pseudo-English sentences and explain the - results in words, NetHack commands are all one or two keystrokes and + that accept commands in pseudo-English sentences and explain the + results in words, NetHack commands are all one or two keystrokes and the results are displayed graphically on the screen. A minimum screen size of 24 lines by 80 columns is recommended; if the screen is larger, only a 21x80 section will be used for the map. @@ -212,21 +212,21 @@ of Braille readers or speech synthesisers. Instructions for configur- ing NetHack for the blind are included later in this document. - NetHack generates a new dungeon every time you play it; even the + NetHack generates a new dungeon every time you play it; even the authors still find it an entertaining and exciting game despite having won several times. NetHack offers a variety of display options. The options avail- able to you will vary from port to port, depending on the capabilities - of your hardware and software, and whether various compile-time + of your hardware and software, and whether various compile-time options were enabled when your executable was created. The three pos- sible display options are: a monochrome character interface, a color character interface, and a graphical interface using small pictures called tiles. The two character interfaces allow fonts with other characters to be substituted, but the default assignments use standard - ASCII characters to represent everything. There is no difference - between the various display options with respect to game play. - Because we cannot reproduce the tiles or colors in the Guidebook, and + ASCII characters to represent everything. There is no difference + between the various display options with respect to game play. + Because we cannot reproduce the tiles or colors in the Guidebook, and because it is common to all ports, we will use the default ASCII char- acters from the monochrome character display when referring to things you might see on the screen during your game. @@ -268,22 +268,22 @@ - +----------------------------------------------------------------+ - | The bat bites! | - | | - | ------ | - | |....| ---------- | - | |.<..|####...@...$.| | - | |....-# |...B....+ | - | |....| |.d......| | - | ------ -------|-- | - | | - | | - | | - | Player the Rambler St:12 Dx:7 Co:18 In:11 Wi:9 Ch:15 Neutral | - | Dlvl:1 $:993 HP:9(12) Pw:3(3) AC:10 Exp:1/19 T:752 Hungry Conf | - +----------------------------------------------------------------+ - Figure 1 + +---------------------------------------------------------------+ + |The bat bites! | + | | + | ------ | + | |....| ---------- | + | |.<..|####...@...$.| | + | |....-# |...B....+ | + | |....| |.d......| | + | ------ -------|-- | + | | + | | + | | + |Player the Rambler St:12 Dx:7 Co:18 In:11 Wi:9 Ch:15 Neutral | + |Dlvl:1 $:993 HP:9(12) Pw:3(3) AC:10 Exp:1/19 T:752 Hungry Conf | + +---------------------------Figure-1----------------------------+ + @@ -334,18 +334,17 @@ - +----------------------------------------------------------------+ - | Player the Rambler St:12 Dx:7 Co:18 In:11 Wi:9 Ch:15 | - | Neutral $:993 HP:9(12) Pw:3(3) AC:10 Exp:1/19 Hungry | - | Dlvl:1 T:752 Conf | - +----------------------------------------------------------------+ - Figure 2 + +---------------------------------------------------------------+ + |Player the Rambler St:12 Dx:7 Co:18 In:11 Wi:9 Ch:15 | + |Neutral $:993 HP:9(12) Pw:3(3) AC:10 Exp:1/19 Hungry | + |Dlvl:1 T:752 Conf | + +---------------------------Figure-2----------------------------+ 3.1. The status lines (bottom) - The bottom two (or three) lines of the screen contain several - cryptic pieces of information describing your current status. Figure - 1 shows the traditional two-line status area below the map. Figure 2 + The bottom two (or three) lines of the screen contain several + cryptic pieces of information describing your current status. Figure + 1 shows the traditional two-line status area below the map. Figure 2 shows just the status area, when the statuslines:3 option has been set (not all interfaces support this option). If any status line becomes wider than the screen, you might not see all of it due to truncation. @@ -361,9 +360,9 @@ experience level, see below). Strength - A measure of your character's strength; one of your six basic - attributes. A human character's attributes can range from 3 to - 18 inclusive; non-humans may exceed these limits (occasionally + A measure of your character's strength; one of your six basic + attributes. A human character's attributes can range from 3 to + 18 inclusive; non-humans may exceed these limits (occasionally you may get super-strengths of the form 18/xx, and magic can also cause attributes to exceed the normal limits). The higher your strength, the stronger you are. Strength affects how success- @@ -382,14 +381,15 @@ your constitution no longer matters. Intelligence - Intelligence affects your ability to cast spells and read spell- + Intelligence affects your ability to cast spells and read spell- books. Wisdom - Wisdom comes from your practical experience (especially when + Wisdom comes from your practical experience (especially when dealing with magic). It affects your magical energy. + NetHack 5.0.0 May 29, 2026 @@ -420,11 +420,11 @@ level. Gold - The number of gold pieces you are openly carrying. Gold which + The number of gold pieces you are openly carrying. Gold which you have concealed in containers is not counted. Hit Points - Your current and maximum hit points. Hit points indicate how + Your current and maximum hit points. Hit points indicate how much damage you can take before you die. The more you get hit in a fight, the lower they get. You can regain hit points by rest- ing, or by using certain magical items or spells. The number in @@ -437,23 +437,23 @@ Armor Class A measure of how effectively your armor stops blows from - unfriendly creatures. The lower this number is, the more effec- - tive the armor; it is quite possible to have negative armor + unfriendly creatures. The lower this number is, the more effec- + tive the armor; it is quite possible to have negative armor class. See the Armor subsection of Objects for more information. Experience - Your current experience level. If the showexp option is set, it + Your current experience level. If the showexp option is set, it will be followed by a slash and experience points. As you adven- ture, you gain experience points. At certain experience point totals, you gain an experience level. The more experienced you are, the better you fight and withstand magical attacks. (By the - time your level reaches double digits, the usefulness of showing - the points with it has dropped significantly. You can use the - `O' command to turn showexp off to avoid using up the limited + time your level reaches double digits, the usefulness of showing + the points with it has dropped significantly. You can use the + `O' command to turn showexp off to avoid using up the limited status line space.) Time - The number of turns elapsed so far, displayed if you have the + The number of turns elapsed so far, displayed if you have the NetHack 5.0.0 May 29, 2026 @@ -469,13 +469,13 @@ time option set. Status - Hunger: your current hunger status. Values are Satiated, Not - Hungry (or Normal), Hungry, Weak, and Fainting. Not shown when + Hunger: your current hunger status. Values are Satiated, Not + Hungry (or Normal), Hungry, Weak, and Fainting. Not shown when Normal. - Encumbrance: an indication of how what you are carrying affects - your ability to move. Values are Unencumbered, Burdened, - Stressed, Strained, Overtaxed, and Overloaded. Not shown when + Encumbrance: an indication of how what you are carrying affects + your ability to move. Values are Unencumbered, Burdened, + Stressed, Strained, Overtaxed, and Overloaded. Not shown when Unencumbered. Fatal conditions: Stone (aka Petrifying, turning to stone), Slime @@ -492,8 +492,8 @@ Other conditions and modifiers exist, but there isn't enough room to display them with the other status fields. - The #attributes command (default key ^X) will show all current status - information in unabbreviated format. It also shows other information + The #attributes command (default key ^X) will show all current status + information in unabbreviated format. It also shows other information which might be included on the status lines if those had more room. 3.2. The message line (top) @@ -513,10 +513,10 @@ The rest of the screen is the map of the level as you have explored it so far. Each symbol on the screen represents something. You can set various graphics options to change some of the symbols the - game uses; otherwise, the game will use default symbols. Here is a + game uses; otherwise, the game will use default symbols. Here is a list of what the default symbols mean: - - The horizontal or corner walls of a room, or an open east/west + - The horizontal or corner walls of a room, or an open east/west door. @@ -532,13 +532,13 @@ - | The vertical walls of a room, or an open north/south door, or a + | The vertical walls of a room, or an open north/south door, or a grave. - . The floor of a room, or ice, or a doorless doorway, or the span + . The floor of a room, or ice, or a doorless doorway, or the span of an open drawbridge. - # A corridor, or iron bars, or a tree, or the portcullis of a + # A corridor, or iron bars, or a tree, or the portcullis of a closed drawbridge. Note: engravings in corridors also appear as # but are shown in a @@ -610,8 +610,8 @@ A-HJ-Z and @&':; - Letters and certain other symbols represent the various inhabi- - tants of the Mazes of Menace. Watch out, they can be nasty and + Letters and certain other symbols represent the various inhabi- + tants of the Mazes of Menace. Watch out, they can be nasty and vicious. Sometimes, however, they can be helpful. I Rather than a specific type of monster, this marks the last known @@ -619,18 +619,18 @@ the monster could have moved. The `s', `F', and `m' commands may be useful here. - 1-5 The digits 1 through 5 may be displayed, marking unseen monsters - sensed via the Warning attribute. Less dangerous monsters are + 1-5 The digits 1 through 5 may be displayed, marking unseen monsters + sensed via the Warning attribute. Less dangerous monsters are indicated by lower values, more dangerous by higher values. - You need not memorize all these symbols; you can ask the game - what any symbol represents with the `/' command (see the next section + You need not memorize all these symbols; you can ask the game + what any symbol represents with the `/' command (see the next section for more info). 4. Commands - Commands can be initiated by typing one or two characters to - which the command is bound to, or typing the command name in the + Commands can be initiated by typing one or two characters to + which the command is bound to, or typing the command name in the extended commands entry. Some commands, like "search", do not require that any more information be collected by NetHack. Other commands might require additional information, for example a direction, or an @@ -647,8 +647,8 @@ indicating that you may choose an object not on the list, if you wanted to use something unexpected. Typing a `*' lists your entire inventory, so you can see the inventory letters of every object you're - carrying. Finally, if you change your mind and decide you don't want - to do this command after all, you can press the ESC key to abort the + carrying. Finally, if you change your mind and decide you don't want + to do this command after all, you can press the ESC key to abort the command. @@ -664,7 +664,7 @@ - You can put a number before some commands to repeat them that + You can put a number before some commands to repeat them that many times; for example, "10s" will search ten times. If you have the number_pad option set, you must type `n' to prefix a count, so the example above would be typed "n10s" instead. Commands for which @@ -678,18 +678,18 @@ ? Help menu: display one of several help texts available. - / The "whatis" command, to tell what a symbol represents. You may - choose to specify a location or type a symbol (or even a whole - word) to explain. Specifying a location is done by moving the - cursor to a particular spot on the map and then pressing one of + / The "whatis" command, to tell what a symbol represents. You may + choose to specify a location or type a symbol (or even a whole + word) to explain. Specifying a location is done by moving the + cursor to a particular spot on the map and then pressing one of `.', `,', `;', or `:'. `.' will explain the symbol at the chosen location, conditionally check for "More info?" depending upon whether the help option is on, and then you will be asked to pick - another location; `,' will explain the symbol but skip any addi- - tional information, then let you pick another location; `;' will - skip additional info and also not bother asking you to choose - another location to examine; `:' will show additional info, if - any, without asking for confirmation. When picking a location, + another location; `,' will explain the symbol but skip any addi- + tional information, then let you pick another location; `;' will + skip additional info and also not bother asking you to choose + another location to examine; `:' will show additional info, if + any, without asking for confirmation. When picking a location, pressing the ESC key will terminate this command, or pressing `?' will give a brief reminder about how it works. @@ -731,15 +731,14 @@ fight monsters; the others (below) are "safe." - +-----------------------------------------------------+ - | y k u 7 8 9 | - | \ | / \ | / | - | h- . -l 4- . -6 | - | / | \ / | \ | - | b j n 1 2 3 | - | (number_pad off) (number_pad on) | - +-----------------------------------------------------+ - Figure 3 + +----------------------------------------------------------------+ + | y k u 7 8 9 | + | \ | / \ | / | + | h- . -l 4- . -6 | + | / | \ / | \ | + | b j n 1 2 3 | + | (number_pad off) (number_pad on) | + +---------------------------Figure-3-----------------------------+ [YUHJKLBN] Go in that direction until you hit a wall or run into something. @@ -756,20 +755,20 @@ that prompt). The prefix will make "#travel" command show a menu of interesting - targets in sight. It can also be used with the `\' (known, show + targets in sight. It can also be used with the `\' (known, show a list of all discovered objects) and the ``' (knownclass, show a list of discovered objects in a particular class) commands to offer a menu of several sorting alternatives (which sets a new value for the sortdiscoveries option); also for "#vanquished" and "#genocided" commands to offer a sorting menu. - A few other commands (eat food, offer sacrifice, apply tinning- - kit, drink/quaff, dip, tip container) use the `m' prefix to skip - checking for applicable objects on the floor and go straight to - checking inventory, or (for "#loot" to remove a saddle), skip + A few other commands (eat food, offer sacrifice, apply tinning- + kit, drink/quaff, dip, tip container) use the `m' prefix to skip + checking for applicable objects on the floor and go straight to + checking inventory, or (for "#loot" to remove a saddle), skip containers and go straight to adjacent monsters. - In debug mode (aka "wizard mode"), the `m' prefix may also be + In debug mode (aka "wizard mode"), the `m' prefix may also be used with the "#teleport" and "#wizlevelport" commands. F[yuhjklbn] @@ -779,11 +778,12 @@ Prefix: move until something interesting is found. G[yuhjklbn] or +[yuhjklbn] - Prefix: similar to `g', but forking of corridors is not consid- + Prefix: similar to `g', but forking of corridors is not consid- ered interesting. - Note: + means holding the or key - down like while typing and releasing , then releas- + Note: + means holding the or key + down like while typing and releasing , then releas- + ing . ^ is used as shorthand elsewhere in the NetHack 5.0.0 May 29, 2026 @@ -796,13 +796,12 @@ - ing . ^ is used as shorthand elsewhere in the - Guidebook to mean the same thing. Control characters are case- + Guidebook to mean the same thing. Control characters are case- insensitive so ^x and ^X are the same. M[yuhjklbn] - Old versions supported `M' as a movement prefix which combined - the effect of `m' with +. That is no longer + Old versions supported `M' as a movement prefix which combined + the effect of `m' with +. That is no longer supported as a prefix but similar effect can be achieved by using `m' and G in combination. m can also be used in com- bination with g, +, or @@ -819,17 +818,17 @@ location other than the current position. . Wait or rest, do nothing for one turn. Precede with the `m' pre- - fix to wait for a turn even next to a hostile monster, if + fix to wait for a turn even next to a hostile monster, if safe_wait is on. a Apply (use) a tool (pick-axe, key, lamp...). - If used on a wand, that wand will be broken, releasing its magic + If used on a wand, that wand will be broken, releasing its magic in the process. Confirmation is required. A Remove one or more worn items, such as armor. - Use `T' (take off) to take off only one piece of armor or `R' + Use `T' (take off) to take off only one piece of armor or `R' (remove) to take off only one accessory. ^A Repeat the previous command. @@ -852,6 +851,7 @@ + NetHack 5.0.0 May 29, 2026 @@ -864,8 +864,8 @@ "What kinds of things do you want to drop? [!%= BUCXPaium]" - you should type zero or more object symbols possibly followed by - `a' and/or `i' and/or `u' and/or `m'. In addition, one or more + you should type zero or more object symbols possibly followed by + `a' and/or `i' and/or `u' and/or `m'. In addition, one or more of the blessed/uncursed/cursed groups may be typed. DB - drop all objects known to be blessed. @@ -879,16 +879,16 @@ Dm - use a menu to pick which object(s) to drop. D%u - drop only unpaid food. - The last example shows a combination. There are four categories + The last example shows a combination. There are four categories of object filtering: class (`!' for potions, `?' for scrolls, and so on), shop status (`u' for unpaid, in other words, owned by the shop), bless/curse state (`B', `U', `C', and `X' as shown above), and novelty (`P', recently picked up items; controlled by picking up or dropping things rather than by any time factor). - If you specify more than one value in a category (such as "!?" - for potions and scrolls or "BU" for blessed and uncursed), an - inventory object will meet the criteria if it matches any of the + If you specify more than one value in a category (such as "!?" + for potions and scrolls or "BU" for blessed and uncursed), an + inventory object will meet the criteria if it matches any of the specified values (so "!?" means `!' or `?'). If you specify more than one category, an inventory object must meet each of the cat- egory criteria (so "%u" means class `%' and unpaid `u'). Lastly, @@ -932,14 +932,14 @@ attack you hand-to-hand (but if you attack, you will rub it out); this is often useful to give yourself a breather. - f Fire (shoot or throw) one of the objects placed in your quiver - (or quiver sack, or that you have at the ready). You may select - ammunition with a previous `Q' command, or let the computer pick - something appropriate if autoquiver is true. If your wielded - weapon has the throw-and-return property, your quiver is empty, - and autoquiver is false, you will throw that wielded weapon - instead of filling the quiver. This will also automatically use - a polearm if wielded. If fireassist is true, firing will auto- + f Fire (shoot or throw) one of the objects placed in your quiver + (or quiver sack, or that you have at the ready). You may select + ammunition with a previous `Q' command, or let the computer pick + something appropriate if autoquiver is true. If your wielded + weapon has the throw-and-return property, your quiver is empty, + and autoquiver is false, you will throw that wielded weapon + instead of filling the quiver. This will also automatically use + a polearm if wielded. If fireassist is true, firing will auto- matically try to wield a launcher (for example, a bow or a sling) matching the ammo in the quiver; this might take multiple turns, and get interrupted by a monster. Remember to swap back to your @@ -969,17 +969,17 @@ A menu showing the current option values will be displayed. You can change most values simply by selecting the menu entry for the - given option (ie, by typing its letter or clicking upon it, - depending on your user interface). For the non-boolean choices, - a further menu or prompt will appear once you've closed this - menu. The available options are listed later in this Guidebook. - Options are usually set before the game rather than with the `O' - command; see the section on options below. Precede `O' with the + given option (ie, by typing its letter or clicking upon it, + depending on your user interface). For the non-boolean choices, + a further menu or prompt will appear once you've closed this + menu. The available options are listed later in this Guidebook. + Options are usually set before the game rather than with the `O' + command; see the section on options below. Precede `O' with the `m' prefix to show advanced options. ^O Show overview. - Shortcut for "#overview": list interesting dungeon levels vis- + Shortcut for "#overview": list interesting dungeon levels vis- ited. @@ -994,16 +994,16 @@ - (Prior to 3.6.0, `^O' was a debug mode command which listed the - placement of all special levels. Use "#wizwhere" to run that + (Prior to 3.6.0, `^O' was a debug mode command which listed the + placement of all special levels. Use "#wizwhere" to run that command.) p Pay your shopping bill. P Put on an accessory (ring, amulet, or blindfold). - This command may also be used to wear armor. The prompt for - which inventory item to use will only list accessories, but + This command may also be used to wear armor. The prompt for + which inventory item to use will only list accessories, but choosing an unlisted item of armor will attempt to wear it. (See the `W' command below. It lists armor as the inventory choices but will accept an accessory and attempt to put that on.) @@ -1017,10 +1017,10 @@ When there is a fountain or sink present, it asks whether to drink from that. If that is declined, then it offers a chance to - choose a potion from inventory. Precede `q' with the `m' prefix + choose a potion from inventory. Precede `q' with the `m' prefix to skip asking about drinking from a fountain or sink. - Q Select an object for your quiver, quiver sack, or just generally + Q Select an object for your quiver, quiver sack, or just generally at the ready (only one of these is available at a time). You can then throw this (or one of these) using the `f' command. @@ -1033,16 +1033,16 @@ be removed without asking, but you can set the paranoid_confirma- tion:Remove option to require a prompt. - This command may also be used to take off armor. The prompt for - which inventory item to remove only lists worn accessories, but + This command may also be used to take off armor. The prompt for + which inventory item to remove only lists worn accessories, but an item of worn armor can be chosen. (See the `T' command below. It lists armor as the inventory choices but will accept an acces- sory and attempt to remove it.) ^R Redraw the screen. - s Search for secret doors and traps around you. It usually takes - several tries to find something. Precede with the `m' prefix to + s Search for secret doors and traps around you. It usually takes + several tries to find something. Precede with the `m' prefix to search for a turn even next to a hostile monster, if safe_wait is on. @@ -1077,9 +1077,9 @@ t Throw an object or shoot a projectile. There's no separate "shoot" command. If you throw an arrow while - wielding a bow, you are shooting that arrow and any weapon skill - bonus or penalty for bow applies. If you throw an arrow while - not wielding a bow, you are throwing it by hand and it will gen- + wielding a bow, you are shooting that arrow and any weapon skill + bonus or penalty for bow applies. If you throw an arrow while + not wielding a bow, you are throwing it by hand and it will gen- erally be less effective than when shot. See also `f' (fire) for throwing or shooting an item pre-selected @@ -1096,21 +1096,21 @@ This command may also be used to remove accessories. The prompt for which inventory item to take off only lists worn armor, but a - worn accessory can be chosen. (See the `R' command above. It - lists accessories as the inventory choices but will accept an + worn accessory can be chosen. (See the `R' command above. It + lists accessories as the inventory choices but will accept an item of armor and attempt to take it off.) ^T Teleport, if you have the ability. - v Display a list of significant events in the current game, also + v Display a list of significant events in the current game, also shown by #chronicle. - `v' used to display the game's version number. Use `V' for that + `v' used to display the game's version number. Use `V' for that now. V Display version number. - `V' used to display a summary of the game's history. Still + `V' used to display a summary of the game's history. Still available via #history. @@ -1130,13 +1130,13 @@ w- - wield nothing, use your bare (or gloved) hands. - Some characters can wield two weapons at once; use the `X' com- + Some characters can wield two weapons at once; use the `X' com- mand (or the "#twoweapon" extended command) to do so. W Wear armor. - This command may also be used to put on an accessory (ring, - amulet, or blindfold). The prompt for which inventory item to + This command may also be used to put on an accessory (ring, + amulet, or blindfold). The prompt for which inventory item to use will only list armor, but choosing an unlisted accessory will attempt to put it on. (See the `P' command above. It lists accessories as the inventory choices but will accept an item of @@ -1146,13 +1146,13 @@ weapon slot. The latter is used as your secondary weapon when engaging in two- - weapon combat. Note that if one of these slots is empty, the + weapon combat. Note that if one of these slots is empty, the exchange still takes place. - X Toggle two-weapon combat, if your character can do it. Also + X Toggle two-weapon combat, if your character can do it. Also available via the "#twoweapon" extended command. - (In versions prior to 3.6 this keystroke ran the command to + (In versions prior to 3.6 this keystroke ran the command to switch from normal play to "explore mode", also known as "discov- ery mode", which has now been moved to "#exploremode" and M-X.) @@ -1166,7 +1166,7 @@ don't appear in the normal status display due to space considera- tions. - In normal play, that's all that `^X' displays. In explore mode, + In normal play, that's all that `^X' displays. In explore mode, the role and status feedback is augmented by the information pro- vided by enlightenment magic. @@ -1226,15 +1226,15 @@ + List the spells you know. - Using this command, you can also rearrange the order in which - your spells are listed, either by sorting the entire list or by - picking one spell from the menu then picking another to swap - places with it. Swapping pairs of spells changes their casting - letters, so the change lasts after the current `+' command fin- - ishes. Sorting the whole list is temporary. To make the most - recent sort order persist beyond the current `+' command, choose - the sort option again and then pick "reassign casting letters". - (Any spells learned after that will be added to the end of the + Using this command, you can also rearrange the order in which + your spells are listed, either by sorting the entire list or by + picking one spell from the menu then picking another to swap + places with it. Swapping pairs of spells changes their casting + letters, so the change lasts after the current `+' command fin- + ishes. Sorting the whole list is temporary. To make the most + recent sort order persist beyond the current `+' command, choose + the sort option again and then pick "reassign casting letters". + (Any spells learned after that will be added to the end of the list rather than be inserted into the sorted ordering.) \ Show what types of objects have been discovered. @@ -1260,14 +1260,14 @@ May be preceded by `m' to select preferred display order. - | If persistent inventory display is supported and enabled (with - the perm_invent option), interact with it instead of with the + | If persistent inventory display is supported and enabled (with + the perm_invent option), interact with it instead of with the map. - Allows scrolling with the menu_first_page, menu_previous_page, - menu_next_page, and menu_last_page keys (`^', `<', `>', `|' by + Allows scrolling with the menu_first_page, menu_previous_page, + menu_next_page, and menu_last_page keys (`^', `<', `>', `|' by default). Some interfaces also support menu_shift_left and - menu_shift_right keys (`{' and `}' by default). Use the Return + menu_shift_right keys (`{' and `}' by default). Use the Return (aka Enter) or Escape key to resume play. ! Escape to a shell. See "#shell" below for more details. @@ -1276,20 +1276,20 @@ of the current level's map without monsters; without monsters and objects; or without monsters, objects, and traps. - The key is also shown as on some keyboards or - on others. It is sometimes displayed as ^? even though + The key is also shown as on some keyboards or + on others. It is sometimes displayed as ^? even though that is not an actual control character. - Many terminals have an option to swap the and keys, so typing the key might not execute this com- - mand. If that happens, you can use the extended command "#ter- - rain" instead. + Many terminals have an option to swap the and + keys, so typing the key might not execute this + command. If that happens, you can use the extended command + "#terrain" instead. # Perform an extended command. - As you can see, the authors of NetHack used up all the letters, + As you can see, the authors of NetHack used up all the letters, so this is a way to introduce the less frequently used commands. What extended commands are available depends on what features the game was compiled with. @@ -1308,9 +1308,9 @@ when choosing the item to adjust, enter a count prior to its let- ter. - Adjusting without a count used to collect all compatible stacks - when moving to the destination. That behavior has been changed; - to gather compatible stacks, "#adjust" a stack into its own + Adjusting without a count used to collect all compatible stacks + when moving to the destination. That behavior has been changed; + to gather compatible stacks, "#adjust" a stack into its own inventory slot. If it has a name assigned, other stacks with the @@ -1327,7 +1327,7 @@ same name or with no name will merge provided that all their other attributes match. If it does not have a name, only other stacks with no name are eligible. In either case, otherwise com- - patible stacks with a different name will not be merged. This + patible stacks with a different name will not be merged. This contrasts with using "#adjust" to move from one slot to a differ- ent slot. In that situation, moving (no count given) a compati- ble stack will merge if either stack has a name when the other @@ -1409,7 +1409,7 @@ Dip an object into something. Autocompletes. Default key is `M- d'. - The `m' prefix skips dipping into a fountain or pool if there is + The `m' prefix skips dipping into a fountain or pool if there is one at your location. #down @@ -1422,14 +1422,14 @@ Drop specific item types. Default key is `D'. #eat - Eat something. Default key is `e'. The `m' prefix skips eating + Eat something. Default key is `e'. The `m' prefix skips eating items on the floor. #engrave Engrave writing on the floor. Default key is `E'. #enhance - Advance or check weapon and spell skills. Autocompletes. + Advance or check weapon and spell skills. Autocompletes. Default key is `M-e'. #exploremode @@ -1469,13 +1469,13 @@ extinct. The display order is the same as is used by #vanquished. The `m' - prefix brings up a menu of available sorting orders, and doing - that for either #genocided or #vanquished changes the order for + prefix brings up a menu of available sorting orders, and doing + that for either #genocided or #vanquished changes the order for both. - If the sorting order is "count high to low" or "count low to - high" (which are applicable for #vanquished), that will be - ignored for #genocided and alphabetical will be used instead. + If the sorting order is "count high to low" or "count low to + high" (which are applicable for #vanquished), that will be + ignored for #genocided and alphabetical will be used instead. The menu omits those two choices when used for #genocide. Autocompletes. Default key is `M-g'. @@ -1538,7 +1538,7 @@ played. #knownclass - Show discovered types for one class of objects. Default key is + Show discovered types for one class of objects. Default key is ``'. The `m' prefix operates the same as for "#known". @@ -1556,7 +1556,7 @@ Describe what you can see, or remember, of your surroundings. #loot - Loot a box or bag on the floor beneath you, or the saddle from a + Loot a box or bag on the floor beneath you, or the saddle from a steed standing next to you. Autocompletes. Precede with the `m' prefix to skip containers at your location and go directly to removing a saddle. Default key is `M-l', and also `l' if num- @@ -1572,7 +1572,7 @@ N'. #offer - Offer a sacrifice to the gods. Autocompletes. Default key is + Offer a sacrifice to the gods. Autocompletes. Default key is `M-o'. @@ -1588,7 +1588,7 @@ - You'll need to find an altar to have any chance at success. + You'll need to find an altar to have any chance at success. Corpses of recently killed monsters are the fodder of choice. The `m' prefix skips offering any items which are on the altar. @@ -1597,36 +1597,36 @@ Open a door. Default key is `o'. #options - Show and change option settings. Default key is `O'. Precede + Show and change option settings. Default key is `O'. Precede with the `m' prefix to show advanced options. #optionsfull - Show advanced game option settings. No default key. Precede - with the `m' prefix to execute the simpler options command. - (Mainly useful if you use BINDING=O:optionsfull to switch `O' + Show advanced game option settings. No default key. Precede + with the `m' prefix to execute the simpler options command. + (Mainly useful if you use BINDING=O:optionsfull to switch `O' from simple options back to traditional advanced options.) #overview - Display information you've discovered about the dungeon. Any - visited level with an annotation is included, and many things - (altars, thrones, fountains, and so on; extra stairs leading to + Display information you've discovered about the dungeon. Any + visited level with an annotation is included, and many things + (altars, thrones, fountains, and so on; extra stairs leading to another dungeon branch) trigger an automatic annotation. If dun- geon overview is chosen during end-of-game disclosure, every vis- ited level will be included regardless of annotations. - Precede #overview with the `m' prefix to display the dungeon - overview as a menu where you can select any visited level to add - or remove an annotation without needing to return to that level. - This will also force all visited levels to be displayed rather + Precede #overview with the `m' prefix to display the dungeon + overview as a menu where you can select any visited level to add + or remove an annotation without needing to return to that level. + This will also force all visited levels to be displayed rather than just the "interesting" subset. Autocompletes. Default keys are `^O', and `M-O'. #panic - Test the panic routine. Terminates the current game. Autocom- + Test the panic routine. Terminates the current game. Autocom- pletes. Debug mode only. - Asks for confirmation; default is n (no); continue playing. To + Asks for confirmation; default is n (no); continue playing. To really panic, respond with y. You can set the paranoid_confirma- tion:quit option to require a response of yes instead. @@ -1662,12 +1662,12 @@ #pray Pray to the gods for help. Autocompletes. Default key is `M-p'. - Praying too soon after receiving prior help is a bad idea. - (Hint: entering the dungeon alive is treated as having received - help. You probably shouldn't start off a new game by praying - right away.) Since using this command by accident can cause - trouble, there is an option to make you confirm your intent - before praying. It is enabled by default, and you can reset the + Praying too soon after receiving prior help is a bad idea. + (Hint: entering the dungeon alive is treated as having received + help. You probably shouldn't start off a new game by praying + right away.) Since using this command by accident can cause + trouble, there is an option to make you confirm your intent + before praying. It is enabled by default, and you can reset the paranoid_confirmation option to disable it. #prevmsg @@ -1686,20 +1686,20 @@ Quit the program without saving your game. Autocompletes. Since using this command by accident would throw away the current - game, you are asked to confirm your intent before quitting. - Default response is n (no); continue playing. To really quit, - respond with y. You can set the paranoid_confirmation:quit + game, you are asked to confirm your intent before quitting. + Default response is n (no); continue playing. To really quit, + respond with y. You can set the paranoid_confirmation:quit option to require a response of yes instead. #quiver Select ammunition for quiver. Default key is `Q'. #read - Read a scroll, a spellbook, or something else. Default key is + Read a scroll, a spellbook, or something else. Default key is `r'. #redraw - Redraw the screen. Default key is `^R', and also `^L' if num- + Redraw the screen. Default key is `^R', and also `^L' if num- ber_pad is on. #remove @@ -1721,24 +1721,24 @@ #reqmenu - Prefix key to modify the behavior or request menu from some com- - mands. Prevents autopickup when used with movement commands. + Prefix key to modify the behavior or request menu from some com- + mands. Prevents autopickup when used with movement commands. Default key is `m'. #retravel - Travel to a previously selected travel destination. Default key + Travel to a previously selected travel destination. Default key is `C-_'. See also #travel. #ride - Ride (or stop riding) a saddled creature. Autocompletes. + Ride (or stop riding) a saddled creature. Autocompletes. Default key is `M-R'. #rub Rub a lamp or a stone. Autocompletes. Default key is `M-r'. #run - Prefix key to run towards a direction. Default key is `G' when - number_pad is off, `5' when number_pad is set to 1 or 3, other- + Prefix key to run towards a direction. Default key is `G' when + number_pad is off, `5' when number_pad is set to 1 or 3, other- wise `M-5' when it is set to 2 or 4. #rush @@ -1750,12 +1750,12 @@ Save the game and exit the program. Default key is `S'. #saveoptions - Save configuration options to the config file. This will over- - write the file, removing all comments, so if you have manually + Save configuration options to the config file. This will over- + write the file, removing all comments, so if you have manually edited the config file, don't use this. #search - Search for traps and secret doors around you. Default key is + Search for traps and secret doors around you. Default key is `s'. #seeall @@ -1807,12 +1807,12 @@ If dual-wielding, a separate message about the secondary weapon will be given. Using the `m' prefix will force a menu and it will include primary weapon, alternate weapon even when not dual- - wielding, and also whatever is currently assigned to the quiver + wielding, and also whatever is currently assigned to the quiver slot. #shell - Do a shell escape, switching from NetHack to a subprocess. Can - be disabled at the time the program is built. When enabled, + Do a shell escape, switching from NetHack to a subprocess. Can + be disabled at the time the program is built. When enabled, access for specific users can be controlled by the system config- uration file. Use the shell command `exit' to return to the game. Default key is `!'. @@ -1876,19 +1876,19 @@ traps. If there are visible clouds of gas in view, they are treated like - traps when deciding whether to show them or the floor underneath + traps when deciding whether to show them or the floor underneath them. - In explore mode, you can choose to view the full map rather than - just its explored portion. In debug mode there are additional + In explore mode, you can choose to view the full map rather than + just its explored portion. In debug mode there are additional choices. - Autocompletes. Default key is `' or `' (see Del + Autocompletes. Default key is `' or `' (see Del above). #therecmdmenu - Show a menu of possible actions directed at a location next to - you. The menu is limited to a subset of the likeliest actions, + Show a menu of possible actions directed at a location next to + you. The menu is limited to a subset of the likeliest actions, not an exhaustive set of all possibilities. Autocompletes. #throw @@ -1905,7 +1905,7 @@ tory to tip. The `m' prefix makes the command skip containers on the floor and - pick one from inventory, except for the special case of + pick one from inventory, except for the special case of NetHack 5.0.0 May 29, 2026 @@ -1918,14 +1918,14 @@ - menustyle:traditional with two or more containers present; that + menustyle:traditional with two or more containers present; that situation will start with the floor container menu. Autocompletes. Default key is `M-T'. #toggle - Toggle a boolean option on or off. Requires a parameter in - parenthesis, the name of the option to toggle. The option must + Toggle a boolean option on or off. Requires a parameter in + parenthesis, the name of the option to toggle. The option must be settable in-game. For example: @@ -1934,10 +1934,10 @@ BIND=@:toggle(autopickup) #travel - Travel to a specific location on the map. Default key is `_'. - Using the "request menu" prefix shows a menu of interesting tar- - gets in sight without asking to move the cursor. When picking a - target with cursor and the autodescribe option is on, the top + Travel to a specific location on the map. Default key is `_'. + Using the "request menu" prefix shows a menu of interesting tar- + gets in sight without asking to move the cursor. When picking a + target with cursor and the autodescribe option is on, the top line will show "(no travel path)" if your character does not know of a path to that location. See also #retravel. @@ -1984,13 +1984,13 @@ - monsters list contains at least two types of monsters). - Whichever ordering is picked gets assigned to the sortvanquished + monsters list contains at least two types of monsters). Which- + ever ordering is picked gets assigned to the sortvanquished option so is remembered for subsequent #vanquished requests. The "#genocided" command shares this sorting order. - During end-of-game disclosure, when asked whether to show van- - quished monsters answering `a' will let you choose from the sort + During end-of-game disclosure, when asked whether to show van- + quished monsters answering `a' will let you choose from the sort menu. Autocompletes. Default key is `M-V'. @@ -2067,7 +2067,7 @@ one. Autocompletes. Debug mode only. Default key is `^G'. #wizidentify - Identify all items in inventory. Autocompletes. Debug mode + Identify all items in inventory. Autocompletes. Debug mode only. Default key is `^I'. #wizintrinsic @@ -2142,17 +2142,17 @@ first letter of the command. On Windows and MS-DOS, the "Alt" key can be used in this fashion. - On other systems, if typing "Alt" plus another key transmits a two - character sequence consisting of an Escape followed by the other key, - you may set the altmeta option to have NetHack combine them into - meta+. (This combining action only takes place when NetHack is + On other systems, if typing "Alt" plus another key transmits a two + character sequence consisting of an Escape followed by the other key, + you may set the altmeta option to have NetHack combine them into + meta+. (This combining action only takes place when NetHack is expecting a command to execute, not when accepting input to name some- thing or to make a wish.) Unlike control characters, where ^x and ^X denote the same thing, - meta characters are case-sensitive: M-x and M-X represent different - things. Some commands which can be run via a meta character require - that the letter be capitalized because the lower-case equivalent is + meta characters are case-sensitive: M-x and M-X represent different + things. Some commands which can be run via a meta character require + that the letter be capitalized because the lower-case equivalent is used for another command, so the three key combination meta+Shift+ is needed. @@ -2252,7 +2252,7 @@ - If the number_pad option is on, some additional letter commands + If the number_pad option is on, some additional letter commands are available: h #help @@ -2316,57 +2316,57 @@ 5. Rooms and corridors - Rooms and corridors in the dungeon are either lit or dark. Any - lit areas within your line of sight will be displayed; dark areas are - only displayed if they are within one space of you. Walls and corri- + Rooms and corridors in the dungeon are either lit or dark. Any + lit areas within your line of sight will be displayed; dark areas are + only displayed if they are within one space of you. Walls and corri- dors remain on the map as you explore them. Secret corridors are hidden and appear to be solid rock. You can find them with the `s' (search) command when adjacent to them. Multi- - ple search attempts may be needed. When searching is successful, - secret corridors become ordinary open corridor locations. Mapping - magic reveals secret corridors, so converts them into ordinary corri- + ple search attempts may be needed. When searching is successful, + secret corridors become ordinary open corridor locations. Mapping + magic reveals secret corridors, so converts them into ordinary corri- dors and shows them as such. 5.1. Doorways - Doorways connect rooms and corridors. Some doorways have no - doors; you can walk right through. Others have doors in them, which - may be open, closed, or locked. To open a closed door, use the `o' - (open) command; to close it again, use the `c' (close) command. By - default the autoopen option is enabled, so simply attempting to walk - onto a closed door's location will attempt to open it without needing - `o'. Opening via autoopen will not work if you are confused or + Doorways connect rooms and corridors. Some doorways have no + doors; you can walk right through. Others have doors in them, which + may be open, closed, or locked. To open a closed door, use the `o' + (open) command; to close it again, use the `c' (close) command. By + default the autoopen option is enabled, so simply attempting to walk + onto a closed door's location will attempt to open it without needing + `o'. Opening via autoopen will not work if you are confused or stunned or suffer from the fumbling attribute. - Open doors cannot be entered diagonally; you must approach them - straight on, horizontally or vertically. Doorways without doors are + Open doors cannot be entered diagonally; you must approach them + straight on, horizontally or vertically. Doorways without doors are not restricted in this fashion except on one particular level (described by "#overview" as "a primitive area"). - Unlocking magic exists but usually won't be available early on. - You can get through a locked door without magic by first using an - unlocking tool with the `a' (apply) command, and then opening it. By - default the autounlock option is also enabled, so if you attempt to - open (via `o' or autoopen) a locked door while carrying an unlocking - tool, you'll be asked whether to use it on the door's lock. Alterna- - tively, you can break a closed door (whether locked or not) down by - kicking it via the `^D' (kick) command. Kicking down a door destroys + Unlocking magic exists but usually won't be available early on. + You can get through a locked door without magic by first using an + unlocking tool with the `a' (apply) command, and then opening it. By + default the autounlock option is also enabled, so if you attempt to + open (via `o' or autoopen) a locked door while carrying an unlocking + tool, you'll be asked whether to use it on the door's lock. Alterna- + tively, you can break a closed door (whether locked or not) down by + kicking it via the `^D' (kick) command. Kicking down a door destroys it and makes a lot of noise which might wake sleeping monsters. - Some closed doors are booby-trapped and will explode if an - attempt is made to open (when unlocked) or unlock (when locked) or - kick down. Like kicking, an explosion destroys the door and makes a - lot of noise. The "#untrap" command can be used to search a door for - traps but might take multiple attempts to find one. When one is - found, you'll be asked whether to try to disarm it. If you accede, - success will eliminate the trap but failure will set off the trap's - explosion. (If you decline, you effectively forget that a trap was + Some closed doors are booby-trapped and will explode if an + attempt is made to open (when unlocked) or unlock (when locked) or + kick down. Like kicking, an explosion destroys the door and makes a + lot of noise. The "#untrap" command can be used to search a door for + traps but might take multiple attempts to find one. When one is + found, you'll be asked whether to try to disarm it. If you accede, + success will eliminate the trap but failure will set off the trap's + explosion. (If you decline, you effectively forget that a trap was found there.) - Closed doors can be useful for shutting out monsters. Most mon- - sters cannot open closed doors, although a few don't need to (for - example, ghosts can walk through doors and fog clouds can flow under + Closed doors can be useful for shutting out monsters. Most mon- + sters cannot open closed doors, although a few don't need to (for + example, ghosts can walk through doors and fog clouds can flow under them). Some monsters who can open doors can also use unlocking tools. @@ -2394,7 +2394,7 @@ There are traps throughout the dungeon to snare the unwary intruder. For example, you may suddenly fall into a pit and be stuck for a few turns trying to climb out (see below). A trap usually won't - appear on your map until you trigger it by moving onto it, you see + appear on your map until you trigger it by moving onto it, you see someone else trigger it, or you discover it with the `s' (search) com- mand (multiple attempts are often needed; if your luck is poor, many attempts might be needed). Wands of secret door detection and spell @@ -2402,9 +2402,9 @@ the trap is also within line-of-sight (whether you can see at the time or not). There is also other magic which can reveal traps. - Monsters can fall prey to traps, too, which can potentially be - used as a defensive strategy. Unfortunately traps can be harmful to - your pet(s) as well. Monsters, including pets, usually will avoid + Monsters can fall prey to traps, too, which can potentially be + used as a defensive strategy. Unfortunately traps can be harmful to + your pet(s) as well. Monsters, including pets, usually will avoid moving onto a trap which is shown on your map if they have encountered that type of trap before. @@ -2420,18 +2420,18 @@ to another level, but one which is always below the current level. Usually that will be the next level down but it can be farther. Unlike (level) teleporters, the destination level of a particular trap - door or hole is persistent, so falling into one will bring you to the - same level each time--though not necessarily the same spot on the + door or hole is persistent, so falling into one will bring you to the + same level each time--though not necessarily the same spot on the level. Magic portals behave similarly, but with some additional vari- ation. Some portals are two-way and their remote destination is always the same: another portal which can take you back. Others are one-way and send you to a specific destination level but not necessar- ily to a specific location there. - There is a special multi-level branch of the dungeon with pre- - mapped levels based on the classic computer game "Sokoban." In that - game, you operate as a warehouse worker who pushes crates around - obstacles to position them at designated locations. In NetHack, the + There is a special multi-level branch of the dungeon with pre- + mapped levels based on the classic computer game "Sokoban." In that + game, you operate as a warehouse worker who pushes crates around + obstacles to position them at designated locations. In NetHack, the goal is to push boulders into pits or holes until those traps have all been nullified, giving access to whatever is beyond them. In the @@ -2470,19 +2470,19 @@ 5.3. Stairs and ladders (`<', `>') In general, each level in the dungeon will have a staircase going - up (`<') to the previous level and another going down (`>') to the - next level. There are some exceptions though. For instance, fairly - early in the dungeon you will find a level with two down staircases, - one continuing into the dungeon and the other branching into an area + up (`<') to the previous level and another going down (`>') to the + next level. There are some exceptions though. For instance, fairly + early in the dungeon you will find a level with two down staircases, + one continuing into the dungeon and the other branching into an area known as the Gnomish Mines. Those mines eventually hit a dead end, so after exploring them (if you choose to do so), you'll need to climb back up to the main dungeon. When you traverse a set of stairs, or trigger a trap which sends you to another level, the level you're leaving will be deactivated and - stored in a file on disk. If you're moving to a previously visited - level, it will be loaded from its file on disk and reactivated. If - you're moving to a level which has not yet been visited, it will be + stored in a file on disk. If you're moving to a previously visited + level, it will be loaded from its file on disk and reactivated. If + you're moving to a level which has not yet been visited, it will be created (from scratch for most random levels, from a template for some "special" levels, or loaded from the remains of an earlier game for a "bones" level as briefly described below). Monsters are only active @@ -2490,15 +2490,15 @@ into stasis. Ordinarily when you climb a set of stairs, you will arrive on the - corresponding staircase at your destination. However, pets (see - below) and some other monsters will follow along if they're close - enough when you travel up or down stairs, and occasionally one of + corresponding staircase at your destination. However, pets (see + below) and some other monsters will follow along if they're close + enough when you travel up or down stairs, and occasionally one of these creatures will displace you during the climb. When that occurs, the pet or other monster will arrive on the staircase and you will end up nearby. - Ladders serve the same purpose as staircases, and the two types - of inter-level connections are nearly indistinguishable during game + Ladders serve the same purpose as staircases, and the two types + of inter-level connections are nearly indistinguishable during game play. @@ -2514,8 +2514,8 @@ 5.4. Shops and shopping - Occasionally you will run across a room with a shopkeeper near - the door and many items lying on the floor. You can buy items by + Occasionally you will run across a room with a shopkeeper near + the door and many items lying on the floor. You can buy items by picking them up and then using the `p' command. You can inquire about the price of an item prior to picking it up by using the "#chat" com- mand while standing on it. Using an item prior to paying for it will @@ -2533,8 +2533,8 @@ have to buy it back if you want to reclaim it. Shopkeepers sometime run out of money. When that happens, you'll - be offered credit instead of gold when you try to sell something. - Credit can be used to pay for purchases, but it is only good in the + be offered credit instead of gold when you try to sell something. + Credit can be used to pay for purchases, but it is only good in the shop where it was obtained; other shopkeepers won't honor it. (If you happen to find a "credit card" in the dungeon, don't bother trying to use it in shops; shopkeepers will not accept it.) @@ -2602,18 +2602,18 @@ and without giving feedback about them. The mention_walls option controls whether you get feedback if you - try to walk into a wall or solid stone or off the edge of the map. - Normally nothing happens (unless the hero is blind and no wall is - shown, then the wall that is being bumped into will be drawn on the - map). This option also gives feedback when rushing or running stops + try to walk into a wall or solid stone or off the edge of the map. + Normally nothing happens (unless the hero is blind and no wall is + shown, then the wall that is being bumped into will be drawn on the + map). This option also gives feedback when rushing or running stops for some non-obvious reason. - The mention_decor option controls whether you get feedback when - walking on "furniture." Normally stepping onto stairs or a fountain - or an altar or various other things doesn't elicit anything unless it - is covered by one or more objects so is obscured on the map. Setting - this option to true will describe such things even when they aren't - obscured. Doorless doorways and open doors aren't considered worthy + The mention_decor option controls whether you get feedback when + walking on "furniture." Normally stepping onto stairs or a fountain + or an altar or various other things doesn't elicit anything unless it + is covered by one or more objects so is obscured on the map. Setting + this option to true will describe such things even when they aren't + obscured. Doorless doorways and open doors aren't considered worthy of mention; closed doors (if you can move onto their spots) and broken doors are. Assuming that you're able to do so, moving onto water or lava or ice will give feedback if not yet on that type of terrain but @@ -2628,10 +2628,10 @@ The "nopickup" command prefix (default `m') is also the move- without-attacking prefix and can be used to try to step onto a visible - monster's spot without the move being considered an attack (see the - Fighting subsection of Monsters below). The "fight" command prefix - (default `F'; also `-' if number_pad is on) can be used to force an - attack, when guessing where an unseen monster is or when deliberately + monster's spot without the move being considered an attack (see the + Fighting subsection of Monsters below). The "fight" command prefix + (default `F'; also `-' if number_pad is on) can be used to force an + attack, when guessing where an unseen monster is or when deliberately NetHack 5.0.0 May 29, 2026 @@ -2646,22 +2646,22 @@ attacking a peaceful or tame creature. - The run_mode option controls how frequently the map gets redrawn - when moving more than one step in a single command (so when rushing, + The run_mode option controls how frequently the map gets redrawn + when moving more than one step in a single command (so when rushing, running, or traveling). 5.6. Rogue level - One dungeon level (occurring in mid to late teens of the main + One dungeon level (occurring in mid to late teens of the main dungeon) is a tribute to the ancestor game hack's inspiration rogue. - It is usually displayed differently from other levels: possibly - in characters instead of tiles, or without line-drawing symbols if - already in characters; also, gold is shown as * rather than $ and - stairs are shown as % rather than < and >. There are some minor dif- - ferences in actual game play: doorways lack doors; a scroll, wand, or - spell of light used in a room lights up the whole room rather than - within a radius around your character. And monsters represented by + It is usually displayed differently from other levels: possibly + in characters instead of tiles, or without line-drawing symbols if + already in characters; also, gold is shown as * rather than $ and + stairs are shown as % rather than < and >. There are some minor dif- + ferences in actual game play: doorways lack doors; a scroll, wand, or + spell of light used in a room lights up the whole room rather than + within a radius around your character. And monsters represented by lower-case letters aren't randomly generated on the rogue level. The slight strangeness of this level is a feature, not a bug.... @@ -2677,19 +2677,19 @@ those monsters who are displayed on the screen. The command "#name" (by default bound to `C'), allows you to assign a name to a monster, which may be useful to help distinguish one from another when multiple - monsters are present. Assigning a name which is just a space will + monsters are present. Assigning a name which is just a space will remove any prior name. - The extended command "#chat" can be used to interact with an - adjacent monster. There is no actual dialog (in other words, you - don't get to choose what you'll say), but chatting with some monsters - such as a shopkeeper or the Oracle of Delphi can produce useful + The extended command "#chat" can be used to interact with an + adjacent monster. There is no actual dialog (in other words, you + don't get to choose what you'll say), but chatting with some monsters + such as a shopkeeper or the Oracle of Delphi can produce useful results. 6.1. Fighting - If you see a monster and you wish to fight it, just attempt to - walk into it. Many monsters you find will mind their own business + If you see a monster and you wish to fight it, just attempt to + walk into it. Many monsters you find will mind their own business unless you attack them. Some of them are very dangerous when angered. Remember: discretion is the better part of valor. @@ -2697,7 +2697,7 @@ ster by moving into its location, you'll be asked to confirm your intent. By default an answer of `y' acknowledges that intent, which can be error prone if you're using `y' to move. You can set the para- - noid_confirmation:attack option to require a response of "yes" + noid_confirmation:attack option to require a response of "yes" NetHack 5.0.0 May 29, 2026 @@ -2712,7 +2712,7 @@ instead. - If you can't see a monster (if it is invisible, or if you are + If you can't see a monster (if it is invisible, or if you are blinded), the symbol `I' will be shown when you learn of its presence. If you attempt to walk into it, you will try to fight it just like a monster that you can see; of course, if the monster has moved, you @@ -2724,7 +2724,7 @@ 6.2. Your pet You start the game with a little dog (`d'), kitten (`f'), or pony - (`u'), which follows you about the dungeon and fights monsters with + (`u'), which follows you about the dungeon and fights monsters with you. Like you, your pet needs food to survive. Dogs and cats usually feed themselves on fresh carrion and other meats; horses need vegetar- ian food which is harder to come by. If you're worried about your pet @@ -2738,9 +2738,9 @@ Your pet will follow you up and down staircases if it is next to you when you move. Otherwise your pet will be stranded and may become - wild. Similarly, when you trigger certain types of traps which alter - your location (for instance, a trap door which drops you to a lower - dungeon level), any adjacent pet will accompany you and any non-adja- + wild. Similarly, when you trigger certain types of traps which alter + your location (for instance, a trap door which drops you to a lower + dungeon level), any adjacent pet will accompany you and any non-adja- cent pet will be left behind. Your pet may trigger such traps itself; you will not be carried along with it even if adjacent at the time. @@ -2749,17 +2749,17 @@ Some types of creatures in the dungeon can actually be ridden if you have the right equipment and skill. Convincing a wild beast to let you saddle it up is difficult to say the least. Many a dungeoneer - has had to resort to magic and wizardry in order to forge the - alliance. Once you do have the beast under your control however, you - can easily climb in and out of the saddle with the "#ride" command. - Lead the beast around the dungeon when riding, in the same manner as - you would move yourself. It is the beast that you will see displayed + has had to resort to magic and wizardry in order to forge the + alliance. Once you do have the beast under your control however, you + can easily climb in and out of the saddle with the "#ride" command. + Lead the beast around the dungeon when riding, in the same manner as + you would move yourself. It is the beast that you will see displayed on the map. - Riding skill is managed by the "#enhance" command. See the sec- + Riding skill is managed by the "#enhance" command. See the sec- tion on Weapon proficiency for more information about that. - Use the `a' (apply) command and pick a saddle in your inventory + Use the `a' (apply) command and pick a saddle in your inventory to attempt to put that saddle on an adjacent creature. If successful, it will be transferred to that creature's inventory. @@ -2783,8 +2783,8 @@ 6.4. Bones levels You may encounter the shades and corpses of other adventurers (or - even former incarnations of yourself!) and their personal effects. - Ghosts are hard to kill, but easy to avoid, since they're slow and do + even former incarnations of yourself!) and their personal effects. + Ghosts are hard to kill, but easy to avoid, since they're slow and do little damage. You can plunder the deceased adventurer's possessions; however, they are likely to be cursed. Beware of whatever killed the former player; it is probably still lurking around, gloating over its @@ -2823,13 +2823,13 @@ are, the less the additional load will affect you. There comes a point, though, when the weight of all of that stuff you are carrying around with you through the dungeon will encumber you. Your reactions - will get slower and you'll burn calories faster, requiring food more - frequently to cope with it. Eventually, you'll be so overloaded that + will get slower and you'll burn calories faster, requiring food more + frequently to cope with it. Eventually, you'll be so overloaded that you'll either have to discard some of what you're carrying or collapse under its weight. NetHack will tell you how badly you have loaded yourself. If you - are encumbered, one of the conditions Burdened, Stressed, Strained, + are encumbered, one of the conditions Burdened, Stressed, Strained, NetHack 5.0.0 May 29, 2026 @@ -2842,25 +2842,25 @@ - Overtaxed, or Overloaded will be shown on the bottom line status dis- + Overtaxed, or Overloaded will be shown on the bottom line status dis- play. - When you pick up an object, it is assigned an inventory letter. - Many commands that operate on objects must ask you to find out which - object you want to use. When NetHack asks you to choose a particular - object you are carrying, you are usually presented with a list of + When you pick up an object, it is assigned an inventory letter. + Many commands that operate on objects must ask you to find out which + object you want to use. When NetHack asks you to choose a particular + object you are carrying, you are usually presented with a list of inventory letters to choose from (see Commands, above). - Some objects, such as weapons, are easily differentiated. Oth- - ers, like scrolls and potions, are given descriptions which vary - according to type. During a game, any two objects with the same - description are the same type. However, the descriptions will vary + Some objects, such as weapons, are easily differentiated. Oth- + ers, like scrolls and potions, are given descriptions which vary + according to type. During a game, any two objects with the same + description are the same type. However, the descriptions will vary from game to game. - When you use one of these objects, if its effect is obvious, - NetHack will remember what it is for you. If its effect isn't - extremely obvious, you will be asked what you want to call this type - of object so you will recognize it later. You can also use the + When you use one of these objects, if its effect is obvious, + NetHack will remember what it is for you. If its effect isn't + extremely obvious, you will be asked what you want to call this type + of object so you will recognize it later. You can also use the "#name" command, for the same purpose at any time, to name all objects of a particular type or just an individual object. When you use "#name" on an object which has already been named, specifying a space @@ -2873,27 +2873,27 @@ otherwise helpful. The most common effect of a curse is being stuck with (and to) the item. Cursed weapons weld themselves to your hand when wielded, so you cannot unwield them. Any cursed item you wear is - not removable by ordinary means. In addition, cursed arms and armor - usually, but not always, bear negative enchantments that make them - less effective in combat. Other cursed objects may act poorly or + not removable by ordinary means. In addition, cursed arms and armor + usually, but not always, bear negative enchantments that make them + less effective in combat. Other cursed objects may act poorly or detrimentally in other ways. - Objects can also be blessed instead. Blessed items usually work - better or more beneficially than normal uncursed items. For example, + Objects can also be blessed instead. Blessed items usually work + better or more beneficially than normal uncursed items. For example, a blessed weapon will do slightly more damage against demons. - Objects which are neither cursed nor blessed are referred to as + Objects which are neither cursed nor blessed are referred to as uncursed. They could just as easily have been described as unblessed, but the uncursed designation is what you will see within the game. A "glass half full versus glass half empty" situation; make of that what you will. - There are magical means of bestowing or removing curses upon - objects, so even if you are stuck with one, you can still have the - curse lifted and the item removed. Priests and Priestesses have an - innate sensitivity to this property in any object, so they can more - easily avoid cursed objects than other character roles. Dropping - objects onto an altar will reveal their bless or curse state provided + There are magical means of bestowing or removing curses upon + objects, so even if you are stuck with one, you can still have the + curse lifted and the item removed. Priests and Priestesses have an + innate sensitivity to this property in any object, so they can more + easily avoid cursed objects than other character roles. Dropping + objects onto an altar will reveal their bless or curse state provided that you can see them land. @@ -2908,10 +2908,10 @@ - An item with unknown status will be reported in your inventory - with no prefix. An item which you know the state of will be distin- - guished in your inventory by the presence of the word cursed, - uncursed, or blessed in the description of the item. In some cases + An item with unknown status will be reported in your inventory + with no prefix. An item which you know the state of will be distin- + guished in your inventory by the presence of the word cursed, + uncursed, or blessed in the description of the item. In some cases uncursed will be omitted as being redundant when enough other informa- tion is displayed. The implicit_uncursed option can be used to con- trol this; toggle it off to have uncursed be displayed even when that @@ -2924,8 +2924,8 @@ 7.2. Artifacts - Some objects have been imbued with special powers and are known - as Artifacts. They have specific types (such as long sword or orcish + Some objects have been imbued with special powers and are known + as Artifacts. They have specific types (such as long sword or orcish dagger) and distinct names such as Giantslayer or Grimtooth. Artifact weapons typically do more damage than their ordinary counterparts. Some do extra damage against all monsters, others only against spe- @@ -2955,11 +2955,11 @@ 7.3. Relics There are three unique items that are named and have limited spe- - cial powers but aren't classified as artifacts. Each is guarded by a - particular monster and you'll need to collect all three for use late - in the game. They are the Bell of Opening, the Book of the Dead, and - the Candelabrum of Invocation. Their corresponding descriptions when - not yet identified are silver bell, papyrus spellbook, and cande- + cial powers but aren't classified as artifacts. Each is guarded by a + particular monster and you'll need to collect all three for use late + in the game. They are the Bell of Opening, the Book of the Dead, and + the Candelabrum of Invocation. Their corresponding descriptions when + not yet identified are silver bell, papyrus spellbook, and cande- labrum. @@ -2976,23 +2976,23 @@ 7.4. Weapons (`)') - Given a chance, most monsters in the Mazes of Menace will gratu- - itously try to kill you. You need weapons for self-defense (killing - them first). Without a weapon, you do only 1-2 hit points of damage - (plus bonuses, if any). Monk characters are an exception; they nor- - mally do more damage with bare (or gloved) hands than they do with + Given a chance, most monsters in the Mazes of Menace will gratu- + itously try to kill you. You need weapons for self-defense (killing + them first). Without a weapon, you do only 1-2 hit points of damage + (plus bonuses, if any). Monk characters are an exception; they nor- + mally do more damage with bare (or gloved) hands than they do with weapons. - There are wielded weapons, like maces and swords, and thrown - weapons, like arrows and spears. To hit monsters with a weapon, you - must wield it and attack them, or throw it at them. You can simply - elect to throw a spear. To shoot an arrow, you should first wield a - bow, then throw the arrow. Crossbows shoot crossbow bolts. Slings + There are wielded weapons, like maces and swords, and thrown + weapons, like arrows and spears. To hit monsters with a weapon, you + must wield it and attack them, or throw it at them. You can simply + elect to throw a spear. To shoot an arrow, you should first wield a + bow, then throw the arrow. Crossbows shoot crossbow bolts. Slings hurl rocks and (other) stones (like gems). - Enchanted weapons have a "plus" (or "to hit enhancement" which - can be either positive or negative) that adds to your chance to hit - and the damage you do to a monster. The only way to determine a + Enchanted weapons have a "plus" (or "to hit enhancement" which + can be either positive or negative) that adds to your chance to hit + and the damage you do to a monster. The only way to determine a weapon's enchantment is to have it magically identified somehow. Most weapons are subject to some type of damage like rust. Such "erosion" damage can be repaired. @@ -3001,9 +3001,9 @@ the amount of damage such a hit will do, depends upon many factors. Among them are: type of weapon, quality of weapon (enchantment and/or erosion), experience level, strength, dexterity, encumbrance, and pro- - ficiency (see below). The monster's armor class--a general defense - rating, not necessarily due to wearing of armor--is a factor too; - also, some monsters are particularly vulnerable to certain types of + ficiency (see below). The monster's armor class--a general defense + rating, not necessarily due to wearing of armor--is a factor too; + also, some monsters are particularly vulnerable to certain types of weapons. Many weapons can be wielded in one hand; some require both hands. @@ -3021,10 +3021,10 @@ There might be times when you'd rather not wield any weapon at all. To accomplish that, wield `-', or else use the `A' command which - allows you to unwield the current weapon in addition to taking off + allows you to unwield the current weapon in addition to taking off other worn items. - Those of you in the audience who are AD&D players, be aware that + Those of you in the audience who are AD&D players, be aware that each weapon which existed in AD&D does roughly the same damage to mon- sters in NetHack. Some of the more obscure weapons (such as the aklys, lucern hammer, and bec-de-corbin) are defined in an appendix to @@ -3042,22 +3042,22 @@ Unearthed Arcana, an AD&D supplement. - Some interfaces support the weaponstatus option. When it is - enabled, an extra status condition is displayed, describing the cur- + Some interfaces support the weaponstatus option. When it is + enabled, an extra status condition is displayed, describing the cur- rently wielded weapon. - The commands to use weapons are `w' (wield), `t' (throw), `f' - (fire), `Q' (quiver), `x' (exchange), `X' (twoweapon), and "#enhance" + The commands to use weapons are `w' (wield), `t' (throw), `f' + (fire), `Q' (quiver), `x' (exchange), `X' (twoweapon), and "#enhance" (see below). 7.4.1. Throwing and shooting - You can throw just about anything via the `t' command. It will - prompt for the item to throw; picking `?' will list things in your - inventory which are considered likely to be thrown, or picking `*' - will list your entire inventory. After you've chosen what to throw, - you will be prompted for a direction rather than for a specific tar- - get. The distance something can be thrown depends mainly on the type + You can throw just about anything via the `t' command. It will + prompt for the item to throw; picking `?' will list things in your + inventory which are considered likely to be thrown, or picking `*' + will list your entire inventory. After you've chosen what to throw, + you will be prompted for a direction rather than for a specific tar- + get. The distance something can be thrown depends mainly on the type of object and your strength. Arrows can be thrown by hand, but can be thrown much farther and will be more likely to hit when thrown while you are wielding a bow. @@ -3080,20 +3080,20 @@ when the inventory slot used for `Q' runs out. If your quiver is empty, autoquiver is false, and you are wielding a weapon which returns when thrown, you will throw that weapon instead of filling the - quiver. The fire command also has extra assistance, if fireassist is + quiver. The fire command also has extra assistance, if fireassist is on it will try to wield a launcher matching the ammo in the quiver. - Some characters have the ability to throw or shoot a volley of - multiple items (from the same stack) in a single action. Knowing how + Some characters have the ability to throw or shoot a volley of + multiple items (from the same stack) in a single action. Knowing how to load several rounds of ammunition at once--or hold several missiles in your hand--and still hit a target is not an easy task. Rangers are among those who are adept at this task, as are those with a high level of proficiency in the relevant weapon skill (in bow skill if you're wielding one to shoot arrows, in crossbow skill if you're wielding one - to shoot bolts, or in sling skill if you're wielding one to shoot - stones). The number of items that the character has a chance to fire - varies from turn to turn. You can explicitly limit the number of - shots by using a numeric prefix before the `t' or `f' command. For + to shoot bolts, or in sling skill if you're wielding one to shoot + stones). The number of items that the character has a chance to fire + varies from turn to turn. You can explicitly limit the number of + shots by using a numeric prefix before the `t' or `f' command. For NetHack 5.0.0 May 29, 2026 @@ -3108,24 +3108,24 @@ example, "2f" (or "n2f" if using number_pad mode) would ensure that at most 2 arrows are shot even if you could have fired 3. If you specify - a larger number than would have been shot ("4f" in this example), - you'll just end up shooting the same number (3, here) as if no limit - had been specified. Once the volley is in motion, all of the items - will travel in the same direction; if the first ones kill a monster, + a larger number than would have been shot ("4f" in this example), + you'll just end up shooting the same number (3, here) as if no limit + had been specified. Once the volley is in motion, all of the items + will travel in the same direction; if the first ones kill a monster, the others can still continue beyond that spot. 7.4.2. Weapon proficiency - You will have varying degrees of skill in the weapons available. + You will have varying degrees of skill in the weapons available. Weapon proficiency, or weapon skills, affect how well you can use par- ticular types of weapons, and you'll be able to improve your skills as - you progress through a game, depending on your role, your experience + you progress through a game, depending on your role, your experience level, and use of the weapons. - For the purposes of proficiency, weapons have been divided up - into various groups such as daggers, broadswords, and polearms. Each - role has a limit on what level of proficiency a character can achieve - for each group. For instance, wizards can become highly skilled in + For the purposes of proficiency, weapons have been divided up + into various groups such as daggers, broadswords, and polearms. Each + role has a limit on what level of proficiency a character can achieve + for each group. For instance, wizards can become highly skilled in daggers or staves but not in swords or bows. The "#enhance" extended command is used to review current weapons @@ -3137,13 +3137,13 @@ appear in the list shown by "#enhance". (Divine intervention might unrestrict a particular skill, in which case it will start at unskilled and be limited to basic.) Some characters can enhance their - barehanded combat or martial arts skill beyond expert to "master" or + barehanded combat or martial arts skill beyond expert to "master" or "grand master". - Use of a weapon in which you're restricted or unskilled will - incur a modest penalty in the chance to hit a monster and also in the - amount of damage done when you do hit; at basic level, there is no - penalty or bonus; at skilled level, you receive a modest bonus in the + Use of a weapon in which you're restricted or unskilled will + incur a modest penalty in the chance to hit a monster and also in the + amount of damage done when you do hit; at basic level, there is no + penalty or bonus; at skilled level, you receive a modest bonus in the chance to hit and amount of damage done; at expert level, the bonus is higher. A successful hit has a chance to boost your training towards the next skill level (unless you've already reached the limit for this @@ -3156,10 +3156,10 @@ 7.4.3. Two-Weapon combat - Some characters can use two weapons at once. Setting things up - to do so can seem cumbersome but becomes second nature with use. To - wield two weapons, you need to use the "#twoweapon" command. But - first you need to have a weapon in each hand. (Note that your two + Some characters can use two weapons at once. Setting things up + to do so can seem cumbersome but becomes second nature with use. To + wield two weapons, you need to use the "#twoweapon" command. But + first you need to have a weapon in each hand. (Note that your two NetHack 5.0.0 May 29, 2026 @@ -3172,8 +3172,8 @@ - weapons are not fully equal; the one in the hand you normally wield - with is considered primary and the other one is considered secondary. + weapons are not fully equal; the one in the hand you normally wield + with is considered primary and the other one is considered secondary. The most noticeable difference is after you stop--or before you begin, for that matter--wielding two weapons at once. The primary is your wielded weapon and the secondary is just an item in your inventory @@ -3188,28 +3188,28 @@ the correct weapon, use `w', `x', `w' to first wield the intended sec- ondary, swap it to off hand, and then wield the primary. - The whole process can be simplified via use of the pushweapon - option. When it is enabled, then using `w' to wield something causes - the currently wielded weapon to become your alternate weapon. So the - sequence `w', `w' can be used to first wield the weapon you intend to - be secondary, and then wield the one you want as primary which will + The whole process can be simplified via use of the pushweapon + option. When it is enabled, then using `w' to wield something causes + the currently wielded weapon to become your alternate weapon. So the + sequence `w', `w' can be used to first wield the weapon you intend to + be secondary, and then wield the one you want as primary which will push the first into secondary position. - When in two-weapon combat mode, using the `X' command toggles - back to single-weapon mode. Throwing or dropping either of the - weapons or having one of them be stolen or destroyed will also make - you revert to single-weapon combat. + When in two-weapon combat mode, using the `X' command toggles + back to single-weapon mode. Throwing or dropping either of the weap- + ons or having one of them be stolen or destroyed will also make you + revert to single-weapon combat. 7.5. Armor (`[') - Lots of unfriendly things lurk about; you need armor to protect - yourself from their blows. Some types of armor offer better protec- - tion than others. Your armor class is a measure of this protection. - Armor class (AC) is measured as in AD&D, with 10 being the equivalent - of no armor, and lower numbers meaning better armor. Each suit of + Lots of unfriendly things lurk about; you need armor to protect + yourself from their blows. Some types of armor offer better protec- + tion than others. Your armor class is a measure of this protection. + Armor class (AC) is measured as in AD&D, with 10 being the equivalent + of no armor, and lower numbers meaning better armor. Each suit of armor which exists in AD&D gives the same protection in NetHack. - Here is a list of the armor class values provided by suits of + Here is a list of the armor class values provided by suits of armor: Dragon scale mail 1 Plate mail, Crystal plate mail 3 @@ -3223,8 +3223,8 @@ Leather jacket 9 none 10 - You can also wear other pieces of armor (cloak over suit, shirt - under suit, helmet, gloves, boots, shield) to lower your armor class + You can also wear other pieces of armor (cloak over suit, shirt + under suit, helmet, gloves, boots, shield) to lower your armor class even further. Most of these provide a one or two point improvement to @@ -3247,11 +3247,11 @@ If a piece of armor is enchanted, its armor protection will be better (or worse) than normal, and its "plus" (or minus) will subtract - from your armor class. For example, a +1 chain mail would give you - better protection than normal chain mail, lowering your armor class - one unit further to 4. When you put on a piece of armor, you immedi- - ately find out the armor class and any "plusses" it provides. Cursed - pieces of armor usually have negative enchantments (minuses) in addi- + from your armor class. For example, a +1 chain mail would give you + better protection than normal chain mail, lowering your armor class + one unit further to 4. When you put on a piece of armor, you immedi- + ately find out the armor class and any "plusses" it provides. Cursed + pieces of armor usually have negative enchantments (minuses) in addi- tion to being unremovable. Many types of armor are subject to some kind of damage like rust. @@ -3281,11 +3281,11 @@ boxes are heavy, and tins take a while to open. When you kill monsters, they usually leave corpses which are also - "food." Many, but not all, of these are edible; some also give you - special powers when you eat them. A good rule of thumb is "you are + "food." Many, but not all, of these are edible; some also give you + special powers when you eat them. A good rule of thumb is "you are what you eat." - Some character roles and some monsters are vegetarian. Vegetar- + Some character roles and some monsters are vegetarian. Vegetar- ian monsters will typically never eat animal corpses, while vegetarian players can, but with some rather unpleasant side-effects. @@ -3323,10 +3323,10 @@ tory by type rather than by label, but the label is known in that sit- uation even though it isn't shown. - Many scrolls produce a different effect from usual if they are + Many scrolls produce a different effect from usual if they are blessed or cursed, or read while the hero is confused. - A mail daemon may run up and deliver mail to you as a scroll of + A mail daemon may run up and deliver mail to you as a scroll of mail (on versions compiled with this feature). To use this feature on versions where NetHack mail delivery is triggered by electronic mail appearing in your system mailbox, you must let NetHack know where to @@ -3342,11 +3342,11 @@ 7.8. Potions (`!') - Potions are distinguished by the color of the liquid inside the + Potions are distinguished by the color of the liquid inside the flask. They disappear after you quaff them. - Clear potions are potions of water. Sometimes these are blessed - or cursed, resulting in holy or unholy water. Holy water is the bane + Clear potions are potions of water. Sometimes these are blessed + or cursed, resulting in holy or unholy water. Holy water is the bane of the undead, so potions of holy water are good things to throw (`t') at them. It is also sometimes very useful to dip ("#dip") an object into a potion. @@ -3356,8 +3356,8 @@ 7.9. Wands (`/') Wands usually have multiple magical charges. Some types of wands - require a direction in which to zap them. You can also zap them at - yourself (just give a `.' or `s' for the direction). Be warned, how- + require a direction in which to zap them. You can also zap them at + yourself (just give a `.' or `s' for the direction). Be warned, how- NetHack 5.0.0 May 29, 2026 @@ -3370,7 +3370,7 @@ - ever, for this is often unwise. Other types of wands don't require a + ever, for this is often unwise. Other types of wands don't require a direction. The number of charges in a wand is random and decreases by one whenever you use it. @@ -3382,12 +3382,12 @@ of causing it to explode. The chance for such an explosion starts out very small and increases each time the wand is recharged. - In a truly desperate situation, when your back is up against the - wall, you might decide to go for broke and break your wand. This is - not for the faint of heart. Doing so will almost certainly cause a + In a truly desperate situation, when your back is up against the + wall, you might decide to go for broke and break your wand. This is + not for the faint of heart. Doing so will almost certainly cause a catastrophic release of magical energies. - When you have fully identified a particular wand, inventory dis- + When you have fully identified a particular wand, inventory dis- play will include additional information in parentheses: the number of times it has been recharged followed by a colon and then by its cur- rent number of charges. A current charge count of -1 is a special @@ -3422,7 +3422,7 @@ Spellbooks are tomes of mighty magic. When studied with the `r' (read) command, they transfer to the reader the knowledge of a spell (and therefore eventually become unreadable)--unless the attempt back- - fires. Reading a cursed spellbook or one with mystic runes beyond + fires. Reading a cursed spellbook or one with mystic runes beyond your ken can be harmful to your health! @@ -3436,14 +3436,14 @@ - A spell (even when learned) can also backfire when you cast it. + A spell (even when learned) can also backfire when you cast it. If you attempt to cast a spell well above your experience level, or if you have little skill with the appropriate spell type, or cast it at a - time when your luck is particularly bad, you can end up wasting both + time when your luck is particularly bad, you can end up wasting both the energy and the time required in casting. - Casting a spell calls forth magical energies and focuses them - with your naked mind. Some of the magical energy released comes from + Casting a spell calls forth magical energies and focuses them + with your naked mind. Some of the magical energy released comes from within you. Casting temporarily drains your magical power, which will slowly be recovered, and causes you to need additional food. Casting of spells also requires practice. With practice, your skill in each @@ -3452,16 +3452,16 @@ Some spells require a direction in which to cast them, similar to wands. To cast one at yourself, just give a `.' or `s' for the direc- - tion. A few spells require you to pick a target location rather than - just specify a particular direction. Other spells don't require any + tion. A few spells require you to pick a target location rather than + just specify a particular direction. Other spells don't require any direction or target. - Just as weapons are divided into groups in which a character can - become proficient (to varying degrees), spells are similarly grouped. - Successfully casting a spell exercises its skill group; using the - "#enhance" command to advance a sufficiently exercised skill will - affect all spells within the group. Advanced skill may increase the - potency of spells, reduce their risk of failure during casting + Just as weapons are divided into groups in which a character can + become proficient (to varying degrees), spells are similarly grouped. + Successfully casting a spell exercises its skill group; using the + "#enhance" command to advance a sufficiently exercised skill will + affect all spells within the group. Advanced skill may increase the + potency of spells, reduce their risk of failure during casting attempts, and improve the accuracy of the estimate for how much longer they will be retained in your memory. Skill slots are shared with weapons skills. (See also the section on "Weapon proficiency".) @@ -3469,8 +3469,8 @@ Casting a spell also requires flexible movement, and wearing var- ious types of armor may interfere with that. - The command to read a spellbook is the same as for scrolls, `r' - (read). The `+' command lists each spell you know along with its + The command to read a spellbook is the same as for scrolls, `r' + (read). The `+' command lists each spell you know along with its level, skill category, chance of failure when casting, and an estimate of how strongly it is remembered. The `Z' (cast) command casts a spell. @@ -3510,26 +3510,26 @@ You may encounter bags, boxes, and chests in your travels. A tool of this sort can be opened with the "#loot" extended command when - you are standing on top of it (that is, on the same floor spot), or - with the `a' (apply) command when you are carrying it. However, - chests are often locked, and are in any case unwieldy objects. You - must set one down before unlocking it by using a key or lock-picking - tool with the `a' (apply) command, by kicking it with the `^D' com- - mand, or by using a weapon to force the lock with the "#force" + you are standing on top of it (that is, on the same floor spot), or + with the `a' (apply) command when you are carrying it. However, + chests are often locked, and are in any case unwieldy objects. You + must set one down before unlocking it by using a key or lock-picking + tool with the `a' (apply) command, by kicking it with the `^D' com- + mand, or by using a weapon to force the lock with the "#force" extended command. - Some chests are trapped, causing nasty things to happen when you - unlock or open them. You can check for and try to deactivate traps + Some chests are trapped, causing nasty things to happen when you + unlock or open them. You can check for and try to deactivate traps with the "#untrap" extended command. - When the contents of a container are known, that container will - be described as something like "a sack containing 3 items". In this - example, the 3 refers to number of stacks of compatible items, not to - the total number of individual items. So a sack holding 2 sky blue - potions, 7 arrows, and 350 gold pieces would be described as having 3 - items rather than 10 or 359. And you would need to have 3 unused - inventory slots available in order to take everything out (for the - case where the items you remove don't combine into bigger stacks with + When the contents of a container are known, that container will + be described as something like "a sack containing 3 items". In this + example, the 3 refers to number of stacks of compatible items, not to + the total number of individual items. So a sack holding 2 sky blue + potions, 7 arrows, and 350 gold pieces would be described as having 3 + items rather than 10 or 359. And you would need to have 3 unused + inventory slots available in order to take everything out (for the + case where the items you remove don't combine into bigger stacks with things you're already carrying). If a chest or large box is described as "broken", that means that @@ -3548,11 +3548,11 @@ 7.13. Amulets (`"') Amulets are very similar to rings, and often more powerful. Like - rings, amulets have various magical properties, some beneficial, some + rings, amulets have various magical properties, some beneficial, some harmful, which are activated by putting them on. - Only one amulet may be worn at a time, around your neck. Like - wearing rings, wearing an amulet affects your metabolism, causing you + Only one amulet may be worn at a time, around your neck. Like + wearing rings, wearing an amulet affects your metabolism, causing you to grow hungry more rapidly. @@ -3568,8 +3568,8 @@ - The commands to use amulets are the same as for rings, `P' (put - on) and `R' (remove). `A' can be used to remove various worn items + The commands to use amulets are the same as for rings, `P' (put + on) and `R' (remove). `A' can be used to remove various worn items including amulets. Also, `W' (wear) and `T' (take off) which are nor- mally for armor can be used for amulets and other accessories (rings and eyewear), but accessories won't be shown as likely candidates in a @@ -3577,8 +3577,8 @@ 7.14. Gems (`*') - Some gems are valuable, and can be sold for a lot of gold. They - are also a far more efficient way of carrying your riches. Valuable + Some gems are valuable, and can be sold for a lot of gold. They + are also a far more efficient way of carrying your riches. Valuable gems increase your score if you bring them with you when you exit. Other small rocks are also categorized as gems, but they are much @@ -3593,23 +3593,23 @@ Boulders occasionally block your path. You can push one forward (by attempting to walk onto its spot) when nothing blocks its path, or - you can smash it into a pile of small rocks with breaking magic or a + you can smash it into a pile of small rocks with breaking magic or a pick-axe. It is possible to move onto a boulder's location if certain conditions are met; ordinarily one of those conditions is that pushing - it any further be blocked. Using the move-without-picking-up prefix - (default key `m') prior to the direction of movement will attempt to - move to a boulder's location without pushing it in addition to the + it any further be blocked. Using the move-without-picking-up prefix + (default key `m') prior to the direction of movement will attempt to + move to a boulder's location without pushing it in addition to the prefix's usual action of suppressing auto-pickup at the destination. - Very large humanoids (giants and their ilk) have been known to + Very large humanoids (giants and their ilk) have been known to pick up boulders and use them as missile weapons. - Unlike boulders, statues can't be pushed, but don't need to be - because they don't block movement. They can be smashed into rocks + Unlike boulders, statues can't be pushed, but don't need to be + because they don't block movement. They can be smashed into rocks though. - For some configurations of the program, statues are no longer - shown as ``' but by the letter representing the monster they depict + For some configurations of the program, statues are no longer + shown as ``' but by the letter representing the monster they depict instead. 7.16. Gold (`$') @@ -3641,12 +3641,12 @@ 7.17. Persistence of Objects Normally, if you have seen an object at a particular map location - and move to another location where you can't directly see that object - any more, it will continue to be displayed on your map. That remains - the case even if it is not actually there any more--perhaps a monster + and move to another location where you can't directly see that object + any more, it will continue to be displayed on your map. That remains + the case even if it is not actually there any more--perhaps a monster has picked it up or it has rotted away--until you can see or feel that location again. One notable exception is that if the object gets cov- - ered by the "remembered, unseen monster" marker. When that marker is + ered by the "remembered, unseen monster" marker. When that marker is later removed after you've verified that no monster is there, you will have forgotten that there was any object there regardless of whether the unseen monster actually took the object. If the object is still @@ -3654,7 +3654,7 @@ cover the object and resume remembering it. The situation is the same for a pile of objects, except that only - the top item of the pile is displayed. The hilite_pile option can be + the top item of the pile is displayed. The hilite_pile option can be enabled in order to show an item differently when it is the top one of a pile. @@ -3673,9 +3673,9 @@ Several of the challenges are related to eating behavior. The most difficult of these is the foodless challenge. Although creatures - can survive long periods of time without food, there is a physiologi- - cal need for water; thus there is no restriction on drinking bever- - ages, even if they provide some minor food benefits. Calling upon + can survive long periods of time without food, there is a physiologi- + cal need for water; thus there is no restriction on drinking bever- + ages, even if they provide some minor food benefits. Calling upon your god for help with starvation does not violate any food challenges either. @@ -3684,7 +3684,7 @@ The corpses and tins of blobs (`b'), jellies (`j'), and fungi (`F') are also considered to be vegetable matter. Certain human food is prepared without animal products; namely, lembas wafers, cram rations, - food rations (gunyoki), K-rations, and C-rations. Metal or another + food rations (gunyoki), K-rations, and C-rations. Metal or another normally indigestible material eaten while polymorphed into a creature that can digest it is also considered vegan food. Note however that eating such items still counts against foodless conduct. @@ -3708,7 +3708,7 @@ of royal jelly. Monks are expected to observe a vegetarian diet. Eating any kind of meat violates the vegetarian, vegan, and food- - less conducts. This includes tripe rations, the corpses or tins of + less conducts. This includes tripe rations, the corpses or tins of any monsters not mentioned above, and the various other chunks of meat found in the dungeon. Swallowing and digesting a monster while poly- morphed is treated as if you ate the creature's corpse. Eating @@ -3719,14 +3719,14 @@ Regardless of conduct, there will be some items which are indi- gestible, and others which are hazardous to eat. Using a swallow-and- - digest attack against a monster is equivalent to eating the monster's - corpse. Please note that the term "vegan" is used here only in the - context of diet. You are still free to choose not to use or wear - items derived from animals (e.g. leather, dragon hide, bone, horns, - coral), but the game will not keep track of this for you. Also note - that "milky" potions may be a translucent white, but they do not con- - tain milk, so they are compatible with a vegan diet. Slime molds or - player-defined "fruits", although they could be anything from "cher- + digest attack against a monster is equivalent to eating the monster's + corpse. Please note that the term "vegan" is used here only in the + context of diet. You are still free to choose not to use or wear + items derived from animals (e.g. leather, dragon hide, bone, horns, + coral), but the game will not keep track of this for you. Also note + that "milky" potions may be a translucent white, but they do not con- + tain milk, so they are compatible with a vegan diet. Slime molds or + player-defined "fruits", although they could be anything from "cher- ries" to "pork chops", are also assumed to be vegan. An atheist is one who rejects religion. This means that you can- @@ -3739,7 +3739,7 @@ other religious figure; a true atheist would hear the words but attach no special meaning to them. - A pauper starts the game with no possessions, no spells, and no + A pauper starts the game with no possessions, no spells, and no weapon or spell skills (and if playing as a knight, your pony will not have a saddle). Can only be initiated by starting a new game with OPTIONS=pauper set in your run-time configurtion file or NETHACKOP- @@ -3771,26 +3771,26 @@ An illiterate character does not read or write. This includes reading a scroll, spellbook, fortune cookie message, or t-shirt; writ- - ing a scroll; or making an engraving of anything other than a single - "X" (the traditional signature of an illiterate person). Reading an - engraving, or any item that is absolutely necessary to win the game, - is not counted against this conduct. The identity of scrolls and - spellbooks (and knowledge of spells) in your starting inventory is - assumed to be learned from your teachers prior to the start of the + ing a scroll; or making an engraving of anything other than a single + "X" (the traditional signature of an illiterate person). Reading an + engraving, or any item that is absolutely necessary to win the game, + is not counted against this conduct. The identity of scrolls and + spellbooks (and knowledge of spells) in your starting inventory is + assumed to be learned from your teachers prior to the start of the game and isn't counted. - There is a side-branch to the main dungeon called "Sokoban," - briefly described in the earlier section about Traps. As mentioned - there, the goal is to push boulders into pits and/or holes to plug - those in order to both get the boulders out of the way and be able to - go past the traps. There are some special "rules" that are active - when in that branch of the dungeon. Some rules can't be bypassed, - such as being unable to push a boulder diagonally. Other rules can, + There is a side-branch to the main dungeon called "Sokoban," + briefly described in the earlier section about Traps. As mentioned + there, the goal is to push boulders into pits and/or holes to plug + those in order to both get the boulders out of the way and be able to + go past the traps. There are some special "rules" that are active + when in that branch of the dungeon. Some rules can't be bypassed, + such as being unable to push a boulder diagonally. Other rules can, such as not smashing boulders with magic or tools, but doing so causes you to receive a luck penalty. No message about that is given at the time, but it is tracked as a conduct. The #conduct command and end of - game disclosure will report whether you have abided by the special - rules of Sokoban, and if not, how many times you violated them, pro- + game disclosure will report whether you have abided by the special + rules of Sokoban, and if not, how many times you violated them, pro- viding you with a way to discover which actions incur bad luck so that you can be better informed about whether or not to avoid repeating those actions in the future. (Note: the Sokoban conduct will only be @@ -3804,10 +3804,10 @@ There are several other challenges tracked by the game. It is possible to eliminate one or more species of monsters by genocide; playing without this feature is considered a challenge. When the game - offers you an opportunity to genocide monsters, you may respond with - the monster type "none" if you want to decline. You can change the - form of an item into another item of the same type ("polypiling") or - the form of your own body into another creature ("polyself") by wand, + offers you an opportunity to genocide monsters, you may respond with + the monster type "none" if you want to decline. You can change the + form of an item into another item of the same type ("polypiling") or + the form of your own body into another creature ("polyself") by wand, spell, or potion of polymorph; avoiding these effects are each consid- ered challenges. Polymorphing monsters, including pets, does not break either of these challenges. Finally, you may sometimes receive @@ -3898,18 +3898,18 @@ - There's no guaranteed Novel so the achievement to read one might - not always be attainable (except perhaps by wishing). Similarly, the - Big Room level is not always present. Unlike with the Novel, there's + There's no guaranteed Novel so the achievement to read one might + not always be attainable (except perhaps by wishing). Similarly, the + Big Room level is not always present. Unlike with the Novel, there's no way to wish for this opportunity. - The "special items" hidden in Mines' End and Sokoban are not - unique but are considered to be prizes or rewards for exploring those - levels since doing so is not necessary to complete the game. Finding - other instances of the same objects doesn't record the corresponding + The "special items" hidden in Mines' End and Sokoban are not + unique but are considered to be prizes or rewards for exploring those + levels since doing so is not necessary to complete the game. Finding + other instances of the same objects doesn't record the corresponding achievement. - The Medusa achievement is recorded if she dies for any reason, + The Medusa achievement is recorded if she dies for any reason, even if you are not directly responsible, and only if she dies. The 5-note tune can be learned via trial and error with a musical @@ -3919,14 +3919,14 @@ Blind, Deaf, Nudist, and Pauper are also conducts, and they can only be enabled by setting the correspondingly named option in NETHACKOPTIONS or run-time configuration file prior to game start. In - the case of Blind and Deaf, the option also enforces the conduct. - They aren't really significant accomplishments unless/until you make + the case of Blind and Deaf, the option also enforces the conduct. + They aren't really significant accomplishments unless/until you make substantial progress into the dungeon. 9. Options - Due to variations in personal tastes and conceptions of how - NetHack should do things, there are options you can set to change how + Due to variations in personal tastes and conceptions of how + NetHack should do things, there are options you can set to change how NetHack behaves. 9.1. Setting the options @@ -3935,7 +3935,7 @@ command allows you to view all options and change most of them. You can also set options automatically by placing them in a configuration file, or in the NETHACKOPTIONS environment variable. Some versions of - NetHack also have front-end programs that allow you to set options + NetHack also have front-end programs that allow you to set options before starting the game or a global configuration for system adminis- trators. @@ -3948,10 +3948,10 @@ directory. The file may not exist, but it is a normal ASCII text file and can be created with any text editor. - On Windows, the name is ".nethackrc" located in the folder - "%USERPROFILE%\NetHack\". The file may not exist, but it is a normal - ASCII text file can can be created with any text editor. After run- - ning NetHack for the first time, you should find a default template + On Windows, the name is ".nethackrc" located in the folder + "%USERPROFILE%\NetHack\". The file may not exist, but it is a normal + ASCII text file can can be created with any text editor. After run- + ning NetHack for the first time, you should find a default template NetHack 5.0.0 May 29, 2026 @@ -3964,13 +3964,13 @@ - for the configuration file named ".nethackrc.template" in - "%USERPROFILE%\NetHack\". If you have not created the configuration + for the configuration file named ".nethackrc.template" in + "%USERPROFILE%\NetHack\". If you have not created the configuration file, NetHack will create one for you using the default template file. On MS-DOS, it is "defaults.nh" in the same folder as nethack.exe. - Any line in the configuration file starting with `#' is treated + Any line in the configuration file starting with `#' is treated as a comment and ignored. Empty lines are ignored. Any line beginning with `[' and ending in `]' is a section marker @@ -3978,26 +3978,26 @@ comment beginning with `#'). The text between the square brackets is the section name. Section markers are only valid after a CHOOSE directive and their names are case-insensitive. Lines after a section - marker belong to that section up until another section starts or a - marker without a name is encountered or the file ends. Lines within - sections are ignored unless a CHOOSE directive has selected that sec- + marker belong to that section up until another section starts or a + marker without a name is encountered or the file ends. Lines within + sections are ignored unless a CHOOSE directive has selected that sec- tion. - You can use different configuration directives in the file, some - of which can be used multiple times. In general, the directives are - written in capital letters, followed by an equals sign, followed by + You can use different configuration directives in the file, some + of which can be used multiple times. In general, the directives are + written in capital letters, followed by an equals sign, followed by settings particular to that directive. Here is a list of allowed directives: OPTIONS - There are two types of options, boolean and compound options. - Boolean options toggle a setting on or off, while compound options - take more diverse values. Prefix a boolean option with "no" or `!' - to turn it off. For compound options, the option name and value are + There are two types of options, boolean and compound options. Bool- + ean options toggle a setting on or off, while compound options take + more diverse values. Prefix a boolean option with "no" or `!' to + turn it off. For compound options, the option name and value are separated by a colon. Some options are persistent, and apply only to new games. You can specify multiple OPTIONS directives, and mul- - tiple options separated by commas in a single OPTIONS directive. + tiple options separated by commas in a single OPTIONS directive. (Comma separated options are processed from right to left.) Example: @@ -4051,7 +4051,7 @@ AUTOCOMPLETE Enable or disable an extended command autocompletion. Autocomple- tion has no effect for the X11 windowport. You can specify multiple - autocompletions. To enable autocompletion, list the extended com- + autocompletions. To enable autocompletion, list the extended com- mand. Prefix the command with "!" to disable the autocompletion for that command. @@ -4066,7 +4066,7 @@ BINDINGS Change the key bindings of some special keys, menu accelerators, extended commands, or mouse buttons. You can specify multiple bind- - ings. Format is key followed by the command, separated by a colon. + ings. Format is key followed by the command, separated by a colon. See the "Changing Key Bindings" section for more information. Example: @@ -4106,11 +4106,11 @@ OPTIONS=!rest_on_space If [] is present, the preceding section is closed and no new section - begins; whatever follows will be common to all sections. Otherwise + begins; whatever follows will be common to all sections. Otherwise the last section extends to the end of the options file. MENUCOLOR - Highlight menu lines with different colors. See the "Configuring + Highlight menu lines with different colors. See the "Configuring Menu Colors" section. MSGTYPE @@ -4139,9 +4139,9 @@ WIZKIT Debug mode only: extra items to add to initial inventory. Value is - the name of a text file containing a list of item names, one per - line, up to a maximum of 128 lines. Each line is processed by the - function that handles wishing. Entries are added to the wish his- + the name of a text file containing a list of item names, one per + line, up to a maximum of 128 lines. Each line is processed by the + function that handles wishing. Entries are added to the wish his- tory; see the wizwish-command. Example: @@ -4185,8 +4185,8 @@ 9.3. Using the NETHACKOPTIONS environment variable - The NETHACKOPTIONS variable is a comma-separated list of initial - values for the various options. Some can only be turned on or off. + The NETHACKOPTIONS variable is a comma-separated list of initial + values for the various options. Some can only be turned on or off. You turn one of these on by adding the name of the option to the list, and turn it off by typing a `!' or "no" before the name. Others take a character string as a value. You can set string options by typing @@ -4246,7 +4246,7 @@ Add location or direction information to messages (default is off). acoustics - Enable messages about what your character hears (default on). Note + Enable messages about what your character hears (default on). Note that this has nothing to do with your computer's audio capabilities. Persistent. @@ -4257,14 +4257,14 @@ role for a description of how to use negation to exclude choices. If align is not specified, there is no default value; player will be - prompted unless role and/or race forces a choice for alignment. + prompted unless role and/or race forces a choice for alignment. Cannot be set with the `O' command. Persistent. armorstatus - Display an extra status condition which summarizes currently worn + Display an extra status condition which summarizes currently worn armor (default off, not supported by all interfaces). - For the usual case where more than one piece of armor is worn, a + For the usual case where more than one piece of armor is worn, a list of letters is shown in the following order: G - gloves; @@ -4276,8 +4276,8 @@ S - shield. autodescribe - Automatically describe the terrain under cursor when asked to get a - location on the map (default true). The whatis_coord option con- + Automatically describe the terrain under cursor when asked to get a + location on the map (default true). The whatis_coord option con- trols whether the description includes map coordinates. autodig @@ -4301,18 +4301,18 @@ sistent. autopickup - Automatically pick up things onto which you move (default off). + Automatically pick up things onto which you move (default off). Persistent. - See pickup_types and also autopickup_exception for ways to refine + See pickup_types and also autopickup_exception for ways to refine the behavior. Note: prior to version 5.0.0, the default for autopickup was on. autoquiver - This option controls what happens when you attempt the `f' (fire) - command when nothing is quivered or readied (default false). When - true, the computer will fill your quiver or quiver sack or make + This option controls what happens when you attempt the `f' (fire) + command when nothing is quivered or readied (default false). When + true, the computer will fill your quiver or quiver sack or make ready some suitable weapon. Note that it will not take into account the blessed/cursed status, enchantment, damage, or quality of the weapon; you are free to manually fill your quiver or quiver sack or @@ -4330,12 +4330,12 @@ it will ask whether you want to try to disarm the trap; if you decline, your character will forget that the door or box is trapped; - Apply-Key - if carrying a key or other unlocking tool, prompt about + Apply-Key - if carrying a key or other unlocking tool, prompt about using it; - Kick - kick the door (if you omit untrap or decline to attempt - untrap and you omit apply-key or you lack a key or you + Kick - kick the door (if you omit untrap or decline to attempt + untrap and you omit apply-key or you lack a key or you decline to use the key; has no effect on containers); - Force - try to force a container's lid with your currently + Force - try to force a container's lid with your currently wielded weapon (if you omit untrap or decline to attempt untrap and you omit apply-key or you lack a key or you decline to use the key; has no effect on doors); @@ -4345,9 +4345,9 @@ Omitting the value is treated as if autounlock:apply-key. Preceding autounlock with `!' or "no" is treated as autounlock:none. - Applying a key might set off a trap if the door or container is - trapped. Successfully kicking a door will break it and wake up - nearby monsters. Successfully forcing a container open will break + Applying a key might set off a trap if the door or container is + trapped. Successfully kicking a door will break it and wake up + nearby monsters. Successfully forcing a container open will break NetHack 5.0.0 May 29, 2026 @@ -4360,7 +4360,7 @@ - its lock and might also destroy some of its contents or damage your + its lock and might also destroy some of its contents or damage your weapon or both. The default is Apply-Key. Persistent. @@ -4372,15 +4372,15 @@ Allow saving and loading bones files (default true). Persistent. boulder - Set the character used to display boulders (default is the "large + Set the character used to display boulders (default is the "large rock" class symbol, ``'). catname - Name your starting cat (for example "catname:Morris"). Cannot be + Name your starting cat (for example "catname:Morris"). Cannot be set with the `O' command. character - Synonym for "role" to pick the type of your character (for example + Synonym for "role" to pick the type of your character (for example "character:Monk"). See role for more details. checkpoint @@ -4458,12 +4458,12 @@ of-game disclosure follows a set sequence. (for example "disclose:yi na +v -g o") The example sets inventory to - prompt and default to yes, attributes to prompt and default to no, - vanquished to disclose without prompting, genocided to not disclose - and not prompt, conduct to implicitly prompt and default to no, and + prompt and default to yes, attributes to prompt and default to no, + vanquished to disclose without prompting, genocided to not disclose + and not prompt, conduct to implicitly prompt and default to no, and overview to disclose without prompting. - Note that the vanquished monsters list includes all monsters killed + Note that the vanquished monsters list includes all monsters killed by traps and each other as well as by you. And the dungeon overview shows all levels you had visited but does not reveal things about them that you hadn't discovered. @@ -4478,8 +4478,8 @@ interface except that it does not require that you hit Enter. It is implemented for the tty interface (default off). - For the X11 interface, which always uses a menu for choosing an - extended command, it controls whether the menu shows all available + For the X11 interface, which always uses a menu for choosing an + extended command, it controls whether the menu shows all available NetHack 5.0.0 May 29, 2026 @@ -4492,7 +4492,7 @@ - commands (on) or just the subset of commands which have tradition- + commands (on) or just the subset of commands which have tradition- ally been considered extended ones (off). female @@ -4507,15 +4507,15 @@ fixinv An object's inventory letter sticks to it when it's dropped (default - on). If this is off, dropping an object shifts all the remaining + on). If this is off, dropping an object shifts all the remaining inventory letters. Persistent. force_invmenu - Commands asking for an inventory item show a menu instead of a text + Commands asking for an inventory item show a menu instead of a text query with possible menu letters. Default is off. fruit - Name a fruit after something you enjoy eating (for example + Name a fruit after something you enjoy eating (for example "fruit:mango") (default "slime mold"). Basically a nostalgic whimsy that NetHack uses from time to time. You should set this to some- thing you find more appetizing than slime mold. Apples, oranges, @@ -4529,8 +4529,8 @@ gender option is also present it will take precedence. See role for a description of how to use negation to exclude choices. - If gender is not specified, there is no default value; player will - be prompted unless role and/or race forces a choice for gender. + If gender is not specified, there is no default value; player will + be prompted unless role and/or race forces a choice for gender. Cannot be set with the `O' command. Persistent. goldX @@ -4562,43 +4562,43 @@ herecmd_menu When using a windowport that supports mouse and clicking on yourself - or next to you, show a menu of possible actions for the location. + or next to you, show a menu of possible actions for the location. Same as "#herecmdmenu" and "#therecmdmenu" commands. hilite_pet - Visually distinguish pets from similar animals (default off). The - behavior of this option depends on the type of windowing you use. + Visually distinguish pets from similar animals (default off). The + behavior of this option depends on the type of windowing you use. In text windowing, text highlighting or inverse video is often used; with tiles, generally displays a heart symbol near pets. With the tty or curses interface, the petattr option controls how to - highlight pets and setting it will turn the hilite_pet option on or + highlight pets and setting it will turn the hilite_pet option on or off as warranted. hilite_pile Visually distinguish piles of objects from individual objects - (default off). The behavior of this option depends on the type of - windowing you use. In text windowing, text highlighting or inverse - video is often used; with tiles, generally displays a small plus- + (default off). The behavior of this option depends on the type of + windowing you use. In text windowing, text highlighting or inverse + video is often used; with tiles, generally displays a small plus- symbol beside the object on the top of the pile. hitpointbar - Show a hit point bar graph behind your name and title in the status + Show a hit point bar graph behind your name and title in the status display (default off). - The "curses" interface supports it even if the status highlighting - feature has been disabled when building the program. The "tty" and - "mswin" (aka "Windows GUI") interfaces support it only if status - highlighting is left enabled when building. You don't need to set - up any highlighting rules in order to display the bar. If there is - one for hitpoints in effect and it specifies color, that color will + The "curses" interface supports it even if the status highlighting + feature has been disabled when building the program. The "tty" and + "mswin" (aka "Windows GUI") interfaces support it only if status + highlighting is left enabled when building. You don't need to set + up any highlighting rules in order to display the bar. If there is + one for hitpoints in effect and it specifies color, that color will be used for the bar. However if it specifies video attributes, they will be ignored in favor of inverse. For tty and curses, blink will also be used if the current hitpoint value is at or below the criti- cal HP threshold. The "Qt" interface also supports hitpointbar, by drawing a solid bar - above the name and title with a hard-coded color scheme. (As of + above the name and title with a hard-coded color scheme. (As of this writing, having the bar enabled unintentionally inhibits resiz- ing the status panel. To resize that, use the #optionsfull command to toggle the hitpointbar option off, perform the resize while it's @@ -4639,32 +4639,32 @@ your character as lit (default off). Persistent. lootabc - When using a menu to interact with a container, use the old `a', - `b', and `c' keyboard shortcuts rather than the mnemonics `o', `i', + When using a menu to interact with a container, use the old `a', + `b', and `c' keyboard shortcuts rather than the mnemonics `o', `i', and `b' (default off). Persistent. mail Enable mail delivery during the game (default on). Persistent. male - An obsolete synonym for "gender:male". Cannot be set with the `O' + An obsolete synonym for "gender:male". Cannot be set with the `O' command. mention_decor - Give feedback when walking onto various dungeon features such as - stairs, fountains, or altars which are ordinarily only described - when covered by one or more objects (default off). Cannot be set + Give feedback when walking onto various dungeon features such as + stairs, fountains, or altars which are ordinarily only described + when covered by one or more objects (default off). Cannot be set with the `O' command. Persistent. mention_map Give feedback when interesting map locations change (default off). mention_walls - Give feedback when walking against a wall (default off). Persis- + Give feedback when walking against a wall (default off). Persis- tent. menucolors - Enable coloring menu lines (default off). See "Configuring Menu + Enable coloring menu lines (default off). See "Configuring Menu Colors" on how to configure the colors. menustyle @@ -4690,12 +4690,12 @@ - interest, but then displays a menu of matching objects rather than + interest, but then displays a menu of matching objects rather than prompting one-by-one. Full displays a menu of object classes rather than a character prompt, and then a menu of matching objects for selection. (Choosing its `A' (Autoselect-All) choice skips the sec- - ond menu. To avoid choosing that by accident, set paranoid_con- - firm:AutoAll to require confirmation.) Partial skips the object + ond menu. To avoid choosing that by accident, set paranoid_con- + firm:AutoAll to require confirmation.) Partial skips the object class filtering and immediately displays a menu of all objects. menu_deselect_all @@ -4708,9 +4708,9 @@ Key to jump to the first page in a menu. Default `^'. menu_headings - Controls how the headings in a menu are highlighted. Takes a text - attribute, or text color and attribute separated by ampersand. For - allowed attributes and colors, see "Configuring Menu Colors". Not + Controls how the headings in a menu are highlighted. Takes a text + attribute, or text color and attribute separated by ampersand. For + allowed attributes and colors, see "Configuring Menu Colors". Not all ports can actually display all types. menu_invert_all @@ -4726,11 +4726,11 @@ Key to go to the next menu page. Default `>'. menu_objsyms - Inventory and other object menus are normally separated by object + Inventory and other object menus are normally separated by object class (weapons, armor, and so forth), with a menu header line at the beginning of each group. You can have menus add the display symbol for the class of objects for each header line. You can also add the - display symbol for the individual item in each menu entry. For a + display symbol for the individual item in each menu entry. For a tiles map, that would be a small rendition of an object's tile. For a text map, it is the same character as is used for the object's class, which would be most useful when there are no headers separat- @@ -4741,9 +4741,9 @@ 1 - Headers - show symbols on header lines but not entries; 2 - Entries - show symbols on menu entry lines but not headers; 3 - Both - show symbols on headers and entries; - 4 - Conditional - only show symbols for entries if there are no + 4 - Conditional - only show symbols for entries if there are no headers; - 5 - One-or-other - show symbols on headers, or on entries if no + 5 - One-or-other - show symbols on headers, or on entries if no NetHack 5.0.0 May 29, 2026 @@ -4758,8 +4758,8 @@ headers. - Supported by tty and curses. When setting the value, it can be - specified by digit or keyword. The default value is Conditional + Supported by tty and curses. When setting the value, it can be + specified by digit or keyword. The default value is Conditional (4). menu_overlay @@ -4781,11 +4781,11 @@ menu_shift_left Key to scroll a menu--one which has been scrolled right--back to the - left. Implemented for perm_invent only by curses and X11. Default + left. Implemented for perm_invent only by curses and X11. Default `{'. menu_shift_right - Key to scroll a menu which has text beyond the right edge to the + Key to scroll a menu which has text beyond the right edge to the right. Implemented for perm_invent only by curses and X11. Default `}'. @@ -4849,7 +4849,7 @@ On some systems, the default is the player's user name; on others, there is no default and the player will be prompted. The former can - made to behave like the latter by specifying a generic name such as + made to behave like the latter by specifying a generic name such as ``player''. Cannot be set with the `O' command. news @@ -4911,17 +4911,17 @@ than `y', also require "no" to reject instead of accepting any non-yes response as no; changes pray and AutoAll to require "yes" or `no' too; - quit - require "yes" rather than `y' to confirm quitting the + quit - require "yes" rather than `y' to confirm quitting the game or switching into non-scoring explore mode; - die - require "yes" rather than `y' to confirm dying (not + die - require "yes" rather than `y' to confirm dying (not useful in normal play; applies to explore mode); - bones - require "yes" rather than `y' to confirm saving bones + bones - require "yes" rather than `y' to confirm saving bones data when dying in debug mode; - attack - require "yes" rather than `y' to confirm attacking a + attack - require "yes" rather than `y' to confirm attacking a peaceful monster; - wand-break - require "yes" rather than `y' to confirm breaking a + wand-break - require "yes" rather than `y' to confirm breaking a wand with the apply command; - eating - require "yes" rather than `y' to confirm whether to + eating - require "yes" rather than `y' to confirm whether to continue eating; Were-change - require "yes" rather than `y' to confirm changing form due to lycanthropy when hero has polymorph control; @@ -4929,18 +4929,18 @@ immediately praying; on by default; (to require "yes" rather than just `y', set Confirm too); trap - require `y' to confirm an attempt to move into or onto - a known trap, unless doing so is considered to be + a known trap, unless doing so is considered to be harmless; when enabled, this confirmation is also used for moving into visible gas cloud regions; (to require - "yes" rather than just `y', set Confirm too); confir- - mation can be skipped by using the `m' movement pre- + "yes" rather than just `y', set Confirm too); confir- + mation can be skipped by using the `m' movement pre- fix; swim - prevent walking into water or lava; on by default; (to deliberately step onto/into such terrain when this is set, use the `m' movement prefix when adjacent); AutoAll - require confirmation when the `A' (Autoselect-All) choice is selected in object class filtering menus for - menustyle:Full; (to require "yes" rather than just + menustyle:Full; (to require "yes" rather than just `y', set Confirm too); @@ -4954,14 +4954,14 @@ - Remove - require selection from inventory for `R' and `T' com- + Remove - require selection from inventory for `R' and `T' com- mands even when wearing just one applicable item; all - turn on all of the above. By default, the pray, swim, and trap choices are enabled, the others disabled. To disable them without setting any of the other choices, - use paranoid_confirmation:none. To keep them enabled while setting - any of the others, you can include them in the new list, such as + use paranoid_confirmation:none. To keep them enabled while setting + any of the others, you can include them in the new list, such as paranoid_confirmation:attack pray swim Remove or you can precede the first entry in the list with a plus sign, paranoid_confirma- tion:+attack Remove. To remove an entry that has been previously @@ -4974,15 +4974,15 @@ can be intermixed. pauper - Start the character with no possessions (default false). Persis- + Start the character with no possessions (default false). Persis- tent. - Also start with no spells or skills, which are tied to starting - equipment. Does not inhibit acquiring and using items, spells, and + Also start with no spells or skills, which are tied to starting + equipment. Does not inhibit acquiring and using items, spells, and skills once play has started. perm_invent - If true, always display your current inventory in a window (default + If true, always display your current inventory in a window (default false). This only makes sense for windowing system interfaces that implement @@ -5007,7 +5007,7 @@ petattr Specifies one or more text highlighting attributes to use when show- - ing pets on the map. Effectively a superset of the hilite_pet + ing pets on the map. Effectively a superset of the hilite_pet bool- NetHack 5.0.0 May 29, 2026 @@ -5020,7 +5020,7 @@ - boolean option. Curses or tty interface only; value is one of none, + ean option. Curses or tty interface only; value is one of none, bold, dim, underline, italic, blink, and inverse. Some of those choices might not work, depending upon terminal hardware or terminal emulation software. @@ -5028,20 +5028,20 @@ pettype Specify the type of your initial pet, if you are playing a character class that uses multiple types of pets; or choose to have no initial - pet at all. Possible values are "cat", "dog", "horse", and "none". + pet at all. Possible values are "cat", "dog", "horse", and "none". If the choice is not allowed for the role you are currently playing, it will be silently ignored. For example, "horse" will only be hon- ored when playing a knight. Cannot be set with the `O' command. pickup_burden - When you pick up an item that would exceed this encumbrance level - (Unencumbered, Burdened, streSsed, straiNed, overTaxed, or over- - Loaded), you will be asked if you want to continue. (Default `S'). + When you pick up an item that would exceed this encumbrance level + (Unencumbered, Burdened, streSsed, straiNed, overTaxed, or over- + Loaded), you will be asked if you want to continue. (Default `S'). Persistent. pickup_stolen - If this option is on and autopickup is also on, try to pick up - things that a monster stole from you, even if they aren't in + If this option is on and autopickup is also on, try to pick up + things that a monster stole from you, even if they aren't in pickup_types or match an autopickup exception. Default is on. Per- sistent. @@ -5069,7 +5069,7 @@ pile_limit When walking across a pile of objects on the floor, threshold at which the message "there are few/several/many objects here" is given - instead of showing a popup list of those objects. A value of 0 + instead of showing a popup list of those objects. A value of 0 means "no limit" (always list the objects); a value of 1 effectively means "never show the objects" since the pile size will always be at least that big; default value is 5. Persistent. @@ -5087,8 +5087,8 @@ playmode - Values are "normal", "explore", or "debug". Allows selection of - explore mode (also known as discovery mode) or debug mode (also + Values are "normal", "explore", or "debug". Allows selection of + explore mode (also known as discovery mode) or debug mode (also known as wizard mode) instead of normal play. Debug mode might only be allowed for someone logged in under a particular user name (on multi-user systems) or specifying a particular character name (on @@ -5099,10 +5099,10 @@ price_quotes Whenever the game mentions the name of an object you haven't identi- fied yet, it also mentions the range of buy and sell prices you have - seen for that item (to help narrow down what it could be). The - price shown is the unit price for one item (even when you are look- - ing at a stack of multiple items). Many players may want to turn - this on while identifying objects, and then turn it back off again + seen for that item (to help narrow down what it could be). The + price shown is the unit price for one item (even when you are look- + ing at a stack of multiple items). Many players may want to turn + this on while identifying objects, and then turn it back off again for general play. Default is off. pushweapon @@ -5116,14 +5116,14 @@ quick_farsight When set, usually prevents the "you sense your surroundings" message - where play pauses to allow you to browse the map whenever clairvoy- - ance randomly activates. Some situations, such as being underwater - or engulfed, ignore this option. It does not affect the clairvoy- - ance spell where pausing to examine revealed objects or monsters is + where play pauses to allow you to browse the map whenever clairvoy- + ance randomly activates. Some situations, such as being underwater + or engulfed, ignore this option. It does not affect the clairvoy- + ance spell where pausing to examine revealed objects or monsters is less intrusive. Default is off. Persistent. race - Selects your race (for example, race:human). Choices are human, + Selects your race (for example, race:human). Choices are human, dwarf, elf, gnome, and orc but most roles restrict which of the non- human races are allowed. See role for a description of how to use negation to exclude choices. @@ -5156,7 +5156,7 @@ may be necessary for certain types of challenge games. rest_on_space - Make the space bar a synonym for the `.' (#wait) command (default + Make the space bar a synonym for the `.' (#wait) command (default off). Persistent. role @@ -5174,10 +5174,10 @@ OPTIONS=role:!arc !bar !kni OPTIONS=!role:arc bar kni - There can be multiple instances of the role option if they're all + There can be multiple instances of the role option if they're all negations. - If role is not specified, there is no default value; player will be + If role is not specified, there is no default value; player will be prompted. Cannot be set with the `O' command. Persistent. roguesymset @@ -5186,7 +5186,7 @@ rogue level. rlecomp - When writing out a save file, perform run length compression of the + When writing out a save file, perform run length compression of the map. Not all ports support run length compression. It has no effect on reading an existing save file. @@ -5223,35 +5223,35 @@ sistent. safe_wait - Prevents you from waiting or searching when next to a hostile mon- + Prevents you from waiting or searching when next to a hostile mon- ster (default on). Persistent. sanity_check - Evaluate monsters, objects, and map prior to each turn (default + Evaluate monsters, objects, and map prior to each turn (default off). Debug mode only. scores - Control what parts of the score list you are shown at the end (for - example "scores:5 top scores/4 around my score/own scores"). Only - the first letter of each category (`t', `a', or `o') is necessary. + Control what parts of the score list you are shown at the end (for + example "scores:5 top scores/4 around my score/own scores"). Only + the first letter of each category (`t', `a', or `o') is necessary. Persistent. showdamage - Whenever your character takes damage, show a message of the damage + Whenever your character takes damage, show a message of the damage taken, and the amount of hit points left. showexp - Show your accumulated experience points on bottom line (default + Show your accumulated experience points on bottom line (default off). Persistent. showrace - Display yourself as the glyph for your race, rather than the glyph - for your role (default off). Note that this setting affects only - the appearance of the display, not the way the game treats you. + Display yourself as the glyph for your race, rather than the glyph + for your role (default off). Note that this setting affects only + the appearance of the display, not the way the game treats you. Persistent. showscore - Show your approximate accumulated score on bottom line (default + Show your approximate accumulated score on bottom line (default off). By default, this feature is suppressed when building the pro- gram. Persistent. @@ -5288,32 +5288,32 @@ The possible values are: - o - list object types by class, in discovery order within each + o - list object types by class, in discovery order within each class; default; - s - list object types by sortloot classification: by class, by sub- - class within class for classes which have substantial groupings - (like helmets, boots, gloves, and so forth for armor), with - object types partly-discovered via assigned name coming before + s - list object types by sortloot classification: by class, by sub- + class within class for classes which have substantial groupings + (like helmets, boots, gloves, and so forth for armor), with + object types partly-discovered via assigned name coming before fully identified types; c - list by class, alphabetically within each class; a - list alphabetically across all classes. - Can be interactively set via the `O' command or via using the `m' + Can be interactively set via the `O' command or via using the `m' prefix before the `\' or ``' command. sortloot - Controls the sorting behavior of the pickup lists for inventory and + Controls the sorting behavior of the pickup lists for inventory and #loot commands and some others. Persistent. The possible values are: full - always sort the lists; - loot - only sort the lists that don't use inventory letters, like + loot - only sort the lists that don't use inventory letters, like with the #loot and pickup commands; none - show lists the traditional way without sorting; default. sortpack - Sort the pack contents by type when displaying inventory (default + Sort the pack contents by type when displaying inventory (default on). Persistent. sortvanquished @@ -5324,9 +5324,9 @@ t - traditional--order by monster level; ties are broken by internal monster index; default; - d - order by monster difficulty rating; ties broken by internal + d - order by monster difficulty rating; ties broken by internal index; - a - order alphabetically, first any unique monsters then all the + a - order alphabetically, first any unique monsters then all the others; c - order by monster class, by low to high level within each class; n - order by count, high to low; ties are broken by internal monster @@ -5355,7 +5355,7 @@ on). sparkle - Display a sparkly effect when a monster (including yourself) is hit + Display a sparkly effect when a monster (including yourself) is hit by an attack to which it is resistant (default on). Persistent. spot_monsters @@ -5370,12 +5370,12 @@ ing Status Hilites" for further information. status_updates - Allow updates to the status lines at the bottom of the screen + Allow updates to the status lines at the bottom of the screen (default true). suppress_alert - This option may be set to a NetHack version level to suppress alert - notification messages about feature changes for that and prior ver- + This option may be set to a NetHack version level to suppress alert + notification messages about feature changes for that and prior ver- sions (for example "suppress_alert:3.3.1"). symset @@ -5440,7 +5440,7 @@ Controls what the showvers option displays on the status lines. weaponstatus - Display an extra status condition which describes currently wielded + Display an extra status condition which describes currently wielded weapon (default off, not supported by all interfaces). Some possible displayed values are: @@ -5450,8 +5450,8 @@ dual-weps - wielding two weapons. whatis_coord - When using the `/' or `;' commands to look around on the map with - autodescribe on, display coordinates after the description. Also + When using the `/' or `;' commands to look around on the map with + autodescribe on, display coordinates after the description. Also works in other situations where you are asked to pick a location. The possible settings are: @@ -5462,13 +5462,13 @@ s - screen [row,column] (row is offset to match tty usage); n - none (no coordinates shown) [default]. - The whatis_coord option is also used with the "/m", "/M", "/o", and - "/O" sub-commands of `/', where the "none" setting is overridden + The whatis_coord option is also used with the "/m", "/M", "/o", and + "/O" sub-commands of `/', where the "none" setting is overridden with "map". whatis_filter - When getting a location on the map, and using the keys to cycle - through next and previous targets, allows filtering the possible + When getting a location on the map, and using the keys to cycle + through next and previous targets, allows filtering the possible targets. @@ -5486,8 +5486,8 @@ v - in view only a - in same area only - The area-filter tries to be slightly predictive--if you're standing - on a doorway, it will consider the area on the side of the door you + The area-filter tries to be slightly predictive--if you're standing + on a doorway, it will consider the area on the side of the door you were last moving towards. Filtering can also be changed when getting a location with the "get- @@ -5495,22 +5495,22 @@ whatis_menu When getting a location on the map, and using a key to cycle through - next and previous targets, use a menu instead to pick a target. + next and previous targets, use a menu instead to pick a target. (default off) whatis_moveskip - When getting a location on the map, and using shifted movement keys - or meta-digit keys to fast-move, instead of moving 8 units at a + When getting a location on the map, and using shifted movement keys + or meta-digit keys to fast-move, instead of moving 8 units at a time, move by skipping the same glyphs. (default off) windowtype - When the program has been built to support multiple interfaces, - select which one to use, such as "tty" or "X11" (default depends on - build-time settings; use "#version" to check). Cannot be set with + When the program has been built to support multiple interfaces, + select which one to use, such as "tty" or "X11" (default depends on + build-time settings; use "#version" to check). Cannot be set with the `O' command. - When used, it should be the first option set since its value might - enable or disable the availability of various other options. For + When used, it should be the first option set since its value might + enable or disable the availability of various other options. For multiple lines in a configuration file, that would be the first non- comment line. For a comma-separated list in NETHACKOPTIONS or an OPTIONS line in a configuration file, that would be the rightmost @@ -5532,8 +5532,8 @@ have chosen. Character strings that are too long may be truncated. Not all window ports will adjust for all settings listed here. You can safely add any of these options to your configuration file, and if - the window port is capable of adjusting to suit your preferences, it - will attempt to do so. If it can't it will silently ignore it. You + the window port is capable of adjusting to suit your preferences, it + will attempt to do so. If it can't it will silently ignore it. You can find out if an option is supported by the window port that you are currently using by checking to see if it shows up in the Options list. @@ -5628,8 +5628,8 @@ than in a window. guicolor - Use color text and/or highlighting attributes when displaying some - non-map data (such as menu selector letters). Curses interface + Use color text and/or highlighting attributes when displaying some + non-map data (such as menu selector letters). Curses interface only; default is on. large_font @@ -5639,17 +5639,17 @@ If NetHack can, it should display the map in the manner specified. player_selection - If NetHack can, it should pop up dialog boxes, or use prompts for + If NetHack can, it should pop up dialog boxes, or use prompts for character selection. popup_dialog If NetHack can, it should pop up dialog boxes for input. preload_tiles - If NetHack can, it should preload tiles into memory. For example, + If NetHack can, it should preload tiles into memory. For example, in the protected mode MS-DOS version, control whether tiles get pre- loaded into RAM at the start of the game. Doing so enhances perfor- - mance of the tile graphics, but uses more memory. (default on). + mance of the tile graphics, but uses more memory. (default on). Cannot be set with the `O' command. scroll_amount @@ -5666,7 +5666,7 @@ support this option. softkeyboard - Display an onscreen keyboard. Handhelds are most likely to support + Display an onscreen keyboard. Handhelds are most likely to support this option. @@ -5681,7 +5681,7 @@ splash_screen - If NetHack can, it should display an opening splash screen when it + If NetHack can, it should display an opening splash screen when it starts up (default yes). statuslines @@ -5696,11 +5696,11 @@ The curses interface does likewise if the align_status option is set to top or bottom but ignores statuslines when set to left or right. - The Qt interface already displays more than 3 lines for status so + The Qt interface already displays more than 3 lines for status so uses the statuslines value differently. A value of 3 renders status in the Qt interface's original format, with the status window spread - out vertically. A value of 2 makes status be slightly condensed, - moving some fields to different lines to eliminate one whole line, + out vertically. A value of 2 makes status be slightly condensed, + moving some fields to different lines to eliminate one whole line, reducing the height needed. (If NetHack has been built using a ver- sion of Qt older than qt-5.9, statuslines can only be set in the run-time configuration file or via NETHACKOPTIONS, not during play @@ -5759,7 +5759,7 @@ windowborders Whether to draw boxes around the map, status area, message area, and - persistent inventory window if enabled. Curses interface only. + persistent inventory window if enabled. Curses interface only. Acceptable values are 0 - off, never show borders @@ -5768,17 +5768,17 @@ 3 - on, except forced off for perm_invent 4 - auto, except forced off for perm_invent - (The 26x82 size threshold for `2' refers to number of rows and - columns of the display. A width of at least 110 columns (80+2+26+2) - is needed to show borders if align_status is set to left or right.) + (The 26x82 size threshold for `2' refers to number of rows and col- + umns of the display. A width of at least 110 columns (80+2+26+2) is + needed to show borders if align_status is set to left or right.) The persistent inventory window, when enabled, can grow until it is too big to fit on most displays, resulting in truncation of its con- tents. If borders are forced on (1) or the display is big enough to show them (2), setting the value to 3 or 4 instead will keep borders for the map, message, and status windows but have room for two addi- - tional lines of inventory plus widen each inventory line by two - columns. + tional lines of inventory plus widen each inventory line by two col- + umns. windowcolors If NetHack can, it should display all windows of a particular style @@ -5789,7 +5789,7 @@ where style is one of "menu", "message", "status", or "text", and foreground and background are colors, either numeric (hash sign fol- - lowed by three pairs of hexadecimal digits, #rrggbb), one of the + lowed by three pairs of hexadecimal digits, #rrggbb), one of the named colors (black, red, green, brown, blue, magenta, cyan, orange, bright-green, yellow, bright-blue, bright-magenta, bright-cyan, white, gray, purple, silver, maroon, fuchsia, lime, olive, navy, @@ -5851,13 +5851,13 @@ prompts. Note that typing one or more digits as a count prefix prior to a command--preceded by n if the number_pad option is set-- is also subject to this conversion, so attempting to abort the count - by typing ESC will leave NetHack waiting for another character to - complete the two character sequence. Type a second ESC to finish + by typing ESC will leave NetHack waiting for another character to + complete the two character sequence. Type a second ESC to finish cancelling such a count. At other prompts a single ESC suffices. BIOS - Use BIOS calls to update the screen display quickly and to read the - keyboard (allowing the use of arrow keys to move) on machines with + Use BIOS calls to update the screen display quickly and to read the + keyboard (allowing the use of arrow keys to move) on machines with an IBM PC compatible BIOS ROM (default off, OS/2, PC, and ST NetHack only). @@ -5881,9 +5881,9 @@ subkeyvalue (Win32 tty NetHack only). May be used to alter the value of key- strokes that the operating system returns to NetHack to help compen- - sate for international keyboard issues. OPTIONS=subkeyvalue:171/92 - will return 92 to NetHack, if 171 was originally going to be - returned. You can use multiple subkeyvalue assignments in the con- + sate for international keyboard issues. OPTIONS=subkeyvalue:171/92 + will return 92 to NetHack, if 171 was originally going to be + returned. You can use multiple subkeyvalue assignments in the con- figuration file if needed. Cannot be set with the `O' command. video @@ -5891,9 +5891,9 @@ "default", "vga", or "vesa". Setting "vesa" will cause the game to display tiles, using the full capability of the VGA hardware. Set- ting "vga" will cause the game to display tiles, fixed at 640x480 in - 16 colors, a mode that is compatible with all VGA hardware. Third - party tilesets will probably not work. Setting "autodetect" - attempts "vesa", then "vga", and finally sets "default" if neither + 16 colors, a mode that is compatible with all VGA hardware. Third + party tilesets will probably not work. Setting "autodetect" + attempts "vesa", then "vga", and finally sets "default" if neither of those modes works. Cannot be set with the `O' command. video_height @@ -5903,31 +5903,31 @@ Set the VGA mode resolution width (MS-DOS only, with video:vesa) videocolors - Set the color palette for PC systems using NO_TERMS (default - 4-2-6-1-5-3-15-12-10-14-9-13-11, (PC NetHack only). The order of - colors is red, green, brown, blue, magenta, cyan, bright.white, - bright.red, bright.green, yellow, bright.blue, bright.magenta, and + Set the color palette for PC systems using NO_TERMS (default + 4-2-6-1-5-3-15-12-10-14-9-13-11, (PC NetHack only). The order of + colors is red, green, brown, blue, magenta, cyan, bright.white, + bright.red, bright.green, yellow, bright.blue, bright.magenta, and bright.cyan. Cannot be set with the `O' command. videoshades - Set the intensity level of the three gray scales available (default - dark normal light, PC NetHack only). If the game display is diffi- - cult to read, try adjusting these scales; if this does not correct + Set the intensity level of the three gray scales available (default + dark normal light, PC NetHack only). If the game display is diffi- + cult to read, try adjusting these scales; if this does not correct the problem, try !color. Cannot be set with the `O' command. 9.8. Regular Expressions - Regular expressions are normally POSIX extended regular expres- - sions. It is possible to compile NetHack without regular expression - support on a platform where there is no regular expression library. - While this is not true of any modern platform, if your NetHack was - built this way, patterns are instead glob patterns; regardless, this - document refers to both as `regular expressions.' This applies to + Regular expressions are normally POSIX extended regular expres- + sions. It is possible to compile NetHack without regular expression + support on a platform where there is no regular expression library. + While this is not true of any modern platform, if your NetHack was + built this way, patterns are instead glob patterns; regardless, this + document refers to both as `regular expressions.' This applies to Autopickup exceptions, Message types, Menu colors, and User sounds. 9.9. Configuring Autopickup Exceptions - You can further refine the behavior of the autopickup option + You can further refine the behavior of the autopickup option beyond what is available through the pickup_types option. By placing autopickup_exception lines in your configuration file, @@ -5963,7 +5963,7 @@ to override an earlier rule. Exceptions can be set with the `O' command, but because they are not - included in your configuration file, they won't be in effect if you + included in your configuration file, they won't be in effect if you save and then restore your game. autopickup_exception rules and not saved with the game. @@ -5975,7 +5975,7 @@ The first example above will result in autopickup of any type of arrow. The second example results in the exclusion of any corpse from - autopickup. The last example results in the exclusion of items known + autopickup. The last example results in the exclusion of items known to be cursed from autopickup. 9.10. Changing Key Bindings @@ -6012,7 +6012,7 @@ Menu accelerator keys The menu control or accelerator keys can also be rebound via OPTIONS - lines in the configuration file. You cannot bind object symbols or + lines in the configuration file. You cannot bind object symbols or selection letters into menu accelerators. Some interfaces only sup- port some of the menu accelerators. @@ -6027,17 +6027,17 @@ available. Special command can only be bound to a single key. count - Prefix key to start a count, to repeat a command this many times. + Prefix key to start a count, to repeat a command this many times. With number_pad only. Default is `n'. getdir.help - When asked for a direction, the key to show the help. Default is + When asked for a direction, the key to show the help. Default is `?'. getdir.mouse - When asked for a direction, the key to initiate a simulated mouse - click. You will be asked to pick a location. Use movement key- - strokes to move the cursor around the map, then type the get- + When asked for a direction, the key to initiate a simulated mouse + click. You will be asked to pick a location. Use movement key- + strokes to move the cursor around the map, then type the get- pos.pick.once key (default `,') or the getpos.pick key (default `.') to finish as if performing a left or right click. Only useful when using the #therecmdmenu command. Default is `_'. @@ -6059,11 +6059,11 @@ thing. Default is `a'. getpos.all.prev - When asked for a location, the key to go to previous closest inter- + When asked for a location, the key to go to previous closest inter- esting thing. Default is `A'. getpos.door.next - When asked for a location, the key to go to next closest door or + When asked for a location, the key to go to next closest door or NetHack 5.0.0 May 29, 2026 @@ -6102,30 +6102,30 @@ Default is `O'. getpos.menu - When asked for a location, and using one of the next or previous - keys to cycle through targets, toggle showing a menu instead. + When asked for a location, and using one of the next or previous + keys to cycle through targets, toggle showing a menu instead. Default is `!'. getpos.moveskip - When asked for a location, and using the shifted movement keys or - meta-digit keys to fast-move around, move by skipping the same + When asked for a location, and using the shifted movement keys or + meta-digit keys to fast-move around, move by skipping the same glyphs instead of by 8 units. Default is `*'. getpos.filter - When asked for a location, change the filtering mode when using one - of the next or previous keys to cycle through targets. Toggles - between no filtering, in view only, and in the same area only. + When asked for a location, change the filtering mode when using one + of the next or previous keys to cycle through targets. Toggles + between no filtering, in view only, and in the same area only. Default is `"'. getpos.pick - When asked for a location, the key to choose the location, and pos- - sibly ask for more info. When simulating a mouse click after being - asked for a direction (see getdir.mouse above), the key to use to + When asked for a location, the key to choose the location, and pos- + sibly ask for more info. When simulating a mouse click after being + asked for a direction (see getdir.mouse above), the key to use to respond as right click. Default is `.'. getpos.pick.once - When asked for a location, the key to choose the location, and skip - asking for more info. When simulating a mouse click after being + When asked for a location, the key to choose the location, and skip + asking for more info. When simulating a mouse click after being asked for a direction, the key to respond as left click. Default is `,'. @@ -6144,27 +6144,27 @@ getpos.pick.quick When asked for a location, the key to choose the location, skip ask- - ing for more info, and exit the location asking loop. Default is + ing for more info, and exit the location asking loop. Default is `;'. getpos.pick.verbose - When asked for a location, the key to choose the location, and show + When asked for a location, the key to choose the location, and show more info without asking. Default is `:'. getpos.self - When asked for a location, the key to go to your location. Default + When asked for a location, the key to go to your location. Default is `@'. getpos.unexplored.next - When asked for a location, the key to go to next closest unexplored + When asked for a location, the key to go to next closest unexplored location. Default is `x'. getpos.unexplored.prev - When asked for a location, the key to go to previous closest unex- + When asked for a location, the key to go to previous closest unex- plored location. Default is `X'. getpos.valid - When asked for a location, the key to go to show valid target loca- + When asked for a location, the key to go to show valid target loca- tions. Default is `$'. getpos.valid.next @@ -6243,10 +6243,10 @@ Allowed colors are black, red, green, brown, blue, magenta, cyan, gray, orange, light-green, yellow, light-blue, light-magenta, light- - cyan, and white. And no-color, the default foreground color, which + cyan, and white. And no-color, the default foreground color, which isn't necessarily the same as any of the other colors. - Allowed attributes are none, bold, dim, italic, underline, blink, + Allowed attributes are none, bold, dim, italic, underline, blink, and inverse. "Normal" is a synonym for "none". Note that the plat- form used may interpret the attributes any way it wants. @@ -6259,7 +6259,7 @@ specifies that any menu line with " blessed " contained in it will be shown in green color, lines with " cursed " will be shown in red, - and lines with " cursed " followed by "(being worn)" on the same + and lines with " cursed " followed by "(being worn)" on the same line will be shown in red color and underlined. You can have multi- ple MENUCOLOR entries in your configuration file, and the last MENU- @@ -6276,14 +6276,14 @@ COLOR line that matches a menu line will be used for the line. - Note that if you intend to have one or more color specifications + Note that if you intend to have one or more color specifications match " uncursed ", you will probably want to turn the - implicit_uncursed option off so that all items known to be uncursed + implicit_uncursed option off so that all items known to be uncursed are actually displayed with the "uncursed" description. 9.13. Configuring User Sounds - Some platforms allow you to define sound files to be played when + Some platforms allow you to define sound files to be played when a message that matches a user-defined pattern is delivered to the mes- sage window. At this time the Qt port and the win32tty and win32gui ports support the use of user sounds. @@ -6298,9 +6298,9 @@ An entry that maps a sound file to a user-specified message pattern. Each SOUND entry is broken down into the following parts: - MESG - message window mapping (the only one supported in + MESG - message window mapping (the only one supported in 5.0.0); - msgtype - optional; message type to use, see "Configuring Mes- + msgtype - optional; message type to use, see "Configuring Mes- sage Types" pattern - the pattern to match; sound file - the sound file to play; @@ -6319,9 +6319,9 @@ 9.14. Configuring Status Hilites - Your copy of NetHack may have been compiled with support for - "Status Hilites". If so, you can customize your game display by set- - ting thresholds to change the color or appearance of fields in the + Your copy of NetHack may have been compiled with support for + "Status Hilites". If so, you can customize your game display by set- + ting thresholds to change the color or appearance of fields in the status display. The format for defining status colors is: @@ -6340,44 +6340,44 @@ - For example, the following line in your configuration file will - cause the hitpoints field to display in the color red if your hit- + For example, the following line in your configuration file will + cause the hitpoints field to display in the color red if your hit- points drop to or below a threshold of 30%: OPTION=hilite_status:hitpoints/<=30%/red/normal - (That example is actually specifying red&normal for <=30% and no- + (That example is actually specifying red&normal for <=30% and no- color&normal for >30%.) - For another example, the following line in your configuration + For another example, the following line in your configuration file will cause wisdom to be displayed red if it drops and green if it rises: OPTION=hilite_status:wisdom/down/red/up/green Allowed colors are black, red, green, brown, blue, magenta, cyan, - gray, orange, light-green, yellow, light-blue, light-magenta, light- - cyan, and white. And "no-color", the default foreground color on the + gray, orange, light-green, yellow, light-blue, light-magenta, light- + cyan, and white. And "no-color", the default foreground color on the display, which is not necessarily the same as black or white or any of the other colors. Allowed attributes are none, bold, dim, underline, italic, blink, - and inverse. "Normal" is a synonym for "none"; they should not be + and inverse. "Normal" is a synonym for "none"; they should not be used in combination with any of the other attributes. - To specify both a color and an attribute, use `&' to combine - them. To specify multiple attributes, use `+' to combine those. For + To specify both a color and an attribute, use `&' to combine + them. To specify multiple attributes, use `+' to combine those. For example: "magenta&inverse+dim". - Note that the display may substitute or ignore particular attrib- - utes depending upon its capabilities, and in general may interpret the - attributes any way it wants. For example, on some display systems a - request for bold might yield blink or vice versa. On others, issuing - an attribute request while another is already set up will replace the - earlier attribute rather than combine with it. Since NetHack issues - attribute requests sequentially (at least with the tty interface) - rather than all at once, the only way a situation like that can be - controlled is to specify just one attribute. + Note that the display may substitute or ignore particular + attributes depending upon its capabilities, and in general may inter- + pret the attributes any way it wants. For example, on some display + systems a request for bold might yield blink or vice versa. On oth- + ers, issuing an attribute request while another is already set up will + replace the earlier attribute rather than combine with it. Since + NetHack issues attribute requests sequentially (at least with the tty + interface) rather than all at once, the only way a situation like that + can be controlled is to specify just one attribute. You can adjust the appearance of the following status fields: title dungeon-level experience-level @@ -6389,10 +6389,10 @@ charisma armor-class condition alignment score - The pseudo-field "characteristics" can be used to set all six of - Str, Dex, Con, Int, Wis, and Cha at once. "HD" is "hit dice", an - approximation of experience level displayed when polymorphed. - "experience", "time", and "score" are conditionally displayed + The pseudo-field "characteristics" can be used to set all six of + Str, Dex, Con, Int, Wis, and Cha at once. "HD" is "hit dice", an + approximation of experience level displayed when polymorphed. + "experience", "time", and "score" are conditionally displayed depending upon your other option settings. @@ -6406,14 +6406,14 @@ - Instead of a behavior, "condition" takes the following condition - flags: stone, slime, strngl, foodpois, termill, blind, deaf, stun, + Instead of a behavior, "condition" takes the following condition + flags: stone, slime, strngl, foodpois, termill, blind, deaf, stun, conf, hallu, lev, fly, and ride. You can use "major_troubles" as an alias for stone through termill, "minor_troubles" for blind through hallu, "movement" for lev, fly, and ride, and "all" for every condi- tion. - Allowed behaviors are "always", "up", "down", "changed", a percent- + Allowed behaviors are "always", "up", "down", "changed", a percent- age or absolute number threshold, or text to match against. For the hitpoints field, the additional behavior "criticalhp" is available. It overrides other behavior rules if hit points are at or below the @@ -6436,13 +6436,13 @@ matches the percentage. It is specified as a number between 0 and 100, followed by `%' (percent sign). If the percentage is prefixed with `<=' or `>=', it also matches when value is below - or above the percentage. Use prefix `<' or `>' to match when + or above the percentage. Use prefix `<' or `>' to match when strictly below or above. (The numeric limit is relaxed - slightly for those: >-1% and <101% are allowed.) Only four - fields support percentage rules. Percentages for "hitpoints" - and "power" are straightforward; they're based on the corre- - sponding maximum field. Percentage highlight rules are also - allowed for "experience level" and "experience points" (valid + slightly for those: >-1% and <101% are allowed.) Only four + fields support percentage rules. Percentages for "hitpoints" + and "power" are straightforward; they're based on the corre- + sponding maximum field. Percentage highlight rules are also + allowed for "experience level" and "experience points" (valid when the showexp option is enabled). For those, the percentage is based on the progress from the start of the current experi- ence level to the start of the next level. So if level 2 @@ -6453,11 +6453,11 @@ allowed and matches the special case of being exactly 1 experi- ence point short of the next level. - * absolute value sets the attribute when the field value matches - that number. The number must be 0 or higher, except for - "armor-class' which allows negative values, and may optionally - be preceded by `='. If the number is preceded by `<=' or `>=' - instead, it also matches when value is below or above. If the + * absolute value sets the attribute when the field value matches + that number. The number must be 0 or higher, except for + "armor-class' which allows negative values, and may optionally + be preceded by `='. If the number is preceded by `<=' or `>=' + instead, it also matches when value is below or above. If the prefix is `<' or `>', only match when strictly above or below. @@ -6472,7 +6472,7 @@ - * criticalhp only applies to the hitpoints field and only when + * criticalhp only applies to the hitpoints field and only when current hit points are below a threshold (which varies by maxi- mum hit points and experience level). When the threshold is met, a criticalhp rule takes precedence over all other hit- @@ -6509,18 +6509,18 @@ NetHack can load entire symbol sets from the symbol file. - The options that are used to select a particular symbol set from + The options that are used to select a particular symbol set from the symbol file are: symset Set the name of the symbol set that you want to load. roguesymset - Set the name of the symbol set that you want to load for display on + Set the name of the symbol set that you want to load for display on the rogue level. - You can also override one or more symbols using the SYMBOLS and - ROGUESYMBOLS configuration file options. Symbols are specified as + You can also override one or more symbols using the SYMBOLS and + ROGUESYMBOLS configuration file options. Symbols are specified as name:value pairs. Note that NetHack escape-processes the value string in conventional C fashion. This means that \ is a prefix to take the following character literally. Thus \ needs to be represented as \\. @@ -6771,18 +6771,18 @@ * Several symbols in this table appear to be blank. They are the space character, except for S_pet_override and S_hero_override which - don't have any default value and can only be used if enabled in the + don't have any default value and can only be used if enabled in the "sysconf" file. - * S_rock is misleadingly named; rocks and stones use S_gem. Statues - and boulders are the rock being referred to, but since version - 3.6.0, statues are displayed as the monster they depict. So S_rock - is only used for boulders and not used at all if overridden by the + * S_rock is misleadingly named; rocks and stones use S_gem. Statues + and boulders are the rock being referred to, but since version + 3.6.0, statues are displayed as the monster they depict. So S_rock + is only used for boulders and not used at all if overridden by the more specific S_boulder. 9.16. Customizing Map Glyph Representations Using Unicode - If your platform or terminal supports the display of UTF-8 char- + If your platform or terminal supports the display of UTF-8 char- acter sequences, you can customize your game display by assigning Uni- code codepoint values and red-green-blue colors to glyph representa- tions. The customizations can be specified for use with a symset that @@ -6809,7 +6809,7 @@ The window port that is active needs to provide support for dis- playing UTF-8 character sequences and explicit red-green-blue colors in order for the glyph representation to be visible. For example, the - following line in your configuration file will cause the glyph repre- + following line in your configuration file will cause the glyph repre- sentation for glyphname G_pool to use Unicode codepoint U+224B and the color represented by R-G-B value 0-0-160: @@ -6818,23 +6818,23 @@ The list of acceptable glyphnames can be produced by nethack --dumpg- lyphnames. Individual NetHack glyphs can be specified using the G_ prefix, or you can use an S_ symbol for a glyphname and store the cus- - tom representation for all NetHack glyphs that would map to that par- + tom representation for all NetHack glyphs that would map to that par- ticular symbol. - You will need to select a symset with a UTF8 handler to enable + You will need to select a symset with a UTF8 handler to enable the display of the customizations, such as the Enhanced symset. 9.17. Configuring NetHack for Play by the Blind - NetHack can be set up to use only standard ASCII characters for - making maps of the dungeons. This makes even the MS-DOS versions of - NetHack (which use special line-drawing characters by default) com- - pletely accessible to the blind who use speech and/or Braille access - technologies. Players will require a good working knowledge of their + NetHack can be set up to use only standard ASCII characters for + making maps of the dungeons. This makes even the MS-DOS versions of + NetHack (which use special line-drawing characters by default) com- + pletely accessible to the blind who use speech and/or Braille access + technologies. Players will require a good working knowledge of their screen-reader's review features, and will have to know how to navigate horizontally and vertically character by character. They will also find the search capabilities of their screen-readers to be quite valu- - able. Be certain to examine this Guidebook before playing so you have + able. Be certain to examine this Guidebook before playing so you have an idea what the screen layout is like. You'll also need to be able to locate the PC cursor. It is always where your character is located. Merely searching for an @-sign will not always find your character @@ -6844,7 +6844,7 @@ are often useful in giving players a better sense of the overall loca- tion of items on the screen. - NetHack can also be compiled with support for sending the game + NetHack can also be compiled with support for sending the game messages to an external program, such as a text-to-speech synthesizer. If the "#version" extended command shows "external program as a mes- sage handler", your NetHack has been compiled with the capability. @@ -6919,8 +6919,8 @@ instead of moving 8 units at a time. nostatus_updates - Prevent updates to the status lines at the bottom of the screen, if - your screen-reader reads those lines. The same information can be + Prevent updates to the status lines at the bottom of the screen, if + your screen-reader reads those lines. The same information can be seen via the "#attributes" command. @@ -6939,46 +6939,46 @@ 9.18. Global Configuration for System Administrators - If NetHack is compiled with the SYSCF option, a system adminis- - trator should set up a global configuration; this is a file in the - same format as the traditional per-user configuration file (see - above). This file should be named sysconf and placed in the same - directory as the other NetHack support files. The options recognized - in this file are listed below. Any option not set uses a compiled-in + If NetHack is compiled with the SYSCF option, a system adminis- + trator should set up a global configuration; this is a file in the + same format as the traditional per-user configuration file (see + above). This file should be named sysconf and placed in the same + directory as the other NetHack support files. The options recognized + in this file are listed below. Any option not set uses a compiled-in default (which may not be appropriate for your system). - WIZARDS = A space-separated list of user names who are allowed to - play in debug mode (commonly referred to as wizard mode). A value - of a single asterisk (*) allows anyone to start a game in debug + WIZARDS = A space-separated list of user names who are allowed to + play in debug mode (commonly referred to as wizard mode). A value + of a single asterisk (*) allows anyone to start a game in debug mode. - SHELLERS = A list of users who are allowed to use the shell escape + SHELLERS = A list of users who are allowed to use the shell escape command (!). The syntax is the same as WIZARDS. EXPLORERS = A list of users who are allowed to use the explore mode. The syntax is the same as WIZARDS. MSGHANDLER = A path and filename of executable. Whenever a message- - window message is shown, NetHack runs this program. The program + window message is shown, NetHack runs this program. The program will get the message as the only parameter. - MAXPLAYERS = Limit the maximum number of games that can be running + MAXPLAYERS = Limit the maximum number of games that can be running at the same time. - SUPPORT = A string explaining how to get local support (no default + SUPPORT = A string explaining how to get local support (no default value). - RECOVER = A string explaining how to recover a game on this system + RECOVER = A string explaining how to recover a game on this system (no default value). - SEDUCE = 0 or 1 to disable or enable, respectively, the SEDUCE + SEDUCE = 0 or 1 to disable or enable, respectively, the SEDUCE option. When disabled, incubi and succubi behave like nymphs. - CHECK_PLNAME = Setting this to 1 will make the EXPLORERS, WIZARDS, - and SHELLERS check for the player name instead of the user's login + CHECK_PLNAME = Setting this to 1 will make the EXPLORERS, WIZARDS, + and SHELLERS check for the player name instead of the user's login name. - CHECK_SAVE_UID = 0 or 1 to disable or enable, respectively, the UID + CHECK_SAVE_UID = 0 or 1 to disable or enable, respectively, the UID (used identification number) checking for save files (to verify that the user who is restoring is the same one who saved). @@ -7035,10 +7035,10 @@ %n - player name %N - first character of player name - LIVELOG = A bit-mask of types of events that should be written to - the livelog file if one is present. The sample sysconf file accom- - panying the program contains a comment which lists the meaning of - the various bits used. Intended for server systems supporting + LIVELOG = A bit-mask of types of events that should be written to + the livelog file if one is present. The sample sysconf file accom- + panying the program contains a comment which lists the meaning of + the various bits used. Intended for server systems supporting simultaneous play by multiple players (to be clear, each one running a separate single player game), for displaying their game progress to observers. Only relevant if the program was built with LIVELOG @@ -7048,9 +7048,9 @@ CRASHREPORTURL = If set to https://www.nethack.org/links/cr-37BETA.html and support is compiled - in, brings up a browser window pre-populated with the information - needed to report a problem if the game panics or ends up in an - internally inconsistent state, or if the #bugreport command is + in, brings up a browser window pre-populated with the information + needed to report a problem if the game panics or ends up in an + internally inconsistent state, or if the #bugreport command is invoked. @@ -7068,33 +7068,33 @@ 10. Scoring - NetHack maintains a list of the top scores or scorers on your - machine, depending on how it is set up. In the latter case, each - account on the machine can post only one non-winning score on this - list. If you score higher than someone else on this list, or better - your previous score, you will be inserted in the proper place under - your current name. How many scores are kept can also be set up when + NetHack maintains a list of the top scores or scorers on your + machine, depending on how it is set up. In the latter case, each + account on the machine can post only one non-winning score on this + list. If you score higher than someone else on this list, or better + your previous score, you will be inserted in the proper place under + your current name. How many scores are kept can also be set up when NetHack is compiled. - Your score is chiefly based upon how much experience you gained, + Your score is chiefly based upon how much experience you gained, how much loot you accumulated, how deep you explored, and how the game ended. If you quit the game, you escape with all of your gold intact. - If, however, you get killed in the Mazes of Menace, the guild will - only hear about 90% of your gold when your corpse is discovered - (adventurers have been known to collect finder's fees). So, consider - whether you want to take one last hit at that monster and possibly - live, or quit and stop with whatever you have. If you quit, you keep + If, however, you get killed in the Mazes of Menace, the guild will + only hear about 90% of your gold when your corpse is discovered + (adventurers have been known to collect finder's fees). So, consider + whether you want to take one last hit at that monster and possibly + live, or quit and stop with whatever you have. If you quit, you keep all your gold, but if you swing and live, you might find more. - If you just want to see what the current top players/games list + If you just want to see what the current top players/games list is, you can type nethack -s all on most versions. 11. Explore mode NetHack is an intricate and difficult game. Novices might falter in fear, aware of their ignorance of the means to survive. Well, fear - not. Your dungeon comes equipped with an "explore" or "discovery" - mode that enables you to keep old save files and cheat death, at the + not. Your dungeon comes equipped with an "explore" or "discovery" + mode that enables you to keep old save files and cheat death, at the paltry cost of not getting on the high score list. There are two ways of enabling explore mode. One is to start the @@ -7108,12 +7108,12 @@ 11.1. Debug mode Debug mode, also known as wizard mode, is undocumented aside from - this brief description and the various "debug mode only" commands - listed among the command descriptions. It is intended for tracking - down problems within the program rather than to provide god-like pow- - ers to your character, and players who attempt debugging are expected - to figure out how to use it themselves. It is initiated by starting - the game with the -D command-line switch or with the playmode:debug + this brief description and the various "debug mode only" commands + listed among the command descriptions. It is intended for tracking + down problems within the program rather than to provide god-like pow- + ers to your character, and players who attempt debugging are expected + to figure out how to use it themselves. It is initiated by starting + the game with the -D command-line switch or with the playmode:debug option. For some systems, the player must be logged in under a particular @@ -7139,36 +7139,36 @@ The original hack game was modeled on the Berkeley UNIX rogue game. Large portions of this document were shamelessly cribbed from A - Guide to the Dungeons of Doom, by Michael C. Toy and Kenneth C. R. C. - Arnold. Small portions were adapted from Further Exploration of the + Guide to the Dungeons of Doom, by Michael C. Toy and Kenneth C. R. C. + Arnold. Small portions were adapted from Further Exploration of the Dungeons of Doom, by Ken Arromdee. - NetHack is the product of literally scores of people's work. + NetHack is the product of literally scores of people's work. Main events in the course of the game development are described below: - Jay Fenlason wrote the original Hack, with help from Kenny Wood- + Jay Fenlason wrote the original Hack, with help from Kenny Wood- land, Mike Thome, and Jon Payne. - Andries Brouwer did a major re-write while at Stichting Mathema- - tisch Centrum (now Centrum Wiskunde & Informatica), transforming Hack + Andries Brouwer did a major re-write while at Stichting Mathema- + tisch Centrum (now Centrum Wiskunde & Informatica), transforming Hack into a very different game. He published the Hack source code for use on UNIX systems by posting that to Usenet newsgroup net.sources (later - renamed comp.sources) releasing version 1.0 in December of 1984, then - versions 1.0.1, 1.0.2, and finally 1.0.3 in July of 1985. Usenet - newsgroup net.games.hack (later renamed rec.games.hack, eventually - replaced by rec.games.roguelike.nethack) was created for discussing + renamed comp.sources) releasing version 1.0 in December of 1984, then + versions 1.0.1, 1.0.2, and finally 1.0.3 in July of 1985. Usenet + newsgroup net.games.hack (later renamed rec.games.hack, eventually + replaced by rec.games.roguelike.nethack) was created for discussing it. - Don G. Kneller ported Hack 1.0.3 to Microsoft C and MS-DOS, pro- - ducing PC HACK 1.01e, added support for DEC Rainbow graphics in ver- - sion 1.03g, and went on to produce at least four more versions (3.0, - 3.2, 3.51, and 3.6; note that these are old Hack version numbers, not + Don G. Kneller ported Hack 1.0.3 to Microsoft C and MS-DOS, pro- + ducing PC HACK 1.01e, added support for DEC Rainbow graphics in ver- + sion 1.03g, and went on to produce at least four more versions (3.0, + 3.2, 3.51, and 3.6; note that these are old Hack version numbers, not contemporary NetHack ones). - R. Black ported PC HACK 3.51 to Lattice C and the Atari + R. Black ported PC HACK 3.51 to Lattice C and the Atari 520/1040ST, producing ST Hack 1.03. - Mike Stephenson merged these various versions back together, + Mike Stephenson merged these various versions back together, incorporating many of the added features, and produced NetHack version 1.4 in 1987. He then coordinated a cast of thousands in enhancing and debugging NetHack 1.4 and released NetHack versions 2.2 and 2.3. Like @@ -7178,12 +7178,12 @@ Later, Mike coordinated a major re-write of the game, heading a team which included Ken Arromdee, Jean-Christophe Collet, Steve Creps, - Eric Hendrickson, Izchak Miller, Eric S. Raymond, John Rupley, Mike + Eric Hendrickson, Izchak Miller, Eric S. Raymond, John Rupley, Mike Threepoint, and Janet Walz, to produce NetHack 3.0c. - NetHack 3.0 was ported to the Atari by Eric R. Smith, to OS/2 by - Timo Hakulinen, and to VMS by David Gentzel. The three of them and - Kevin Darcy later joined the main NetHack Development Team to produce + NetHack 3.0 was ported to the Atari by Eric R. Smith, to OS/2 by + Timo Hakulinen, and to VMS by David Gentzel. The three of them and + Kevin Darcy later joined the main NetHack Development Team to produce subsequent revisions of 3.0. @@ -7198,27 +7198,27 @@ - Olaf Seibert ported NetHack 2.3 and 3.0 to the Amiga. Norm - Meluch, Stephen Spackman and Pierre Martineau designed overlay code - for PC NetHack 3.0. Johnny Lee ported NetHack 3.0 to the Macintosh. - Along with various other Dungeoneers, they continued to enhance the + Olaf Seibert ported NetHack 2.3 and 3.0 to the Amiga. Norm + Meluch, Stephen Spackman and Pierre Martineau designed overlay code + for PC NetHack 3.0. Johnny Lee ported NetHack 3.0 to the Macintosh. + Along with various other Dungeoneers, they continued to enhance the PC, Macintosh, and Amiga ports through the later revisions of 3.0. - Version 3.0 went through ten relatively rapidly released "patch- + Version 3.0 went through ten relatively rapidly released "patch- level" revisions. Versions at the time were known as 3.0 for the base release and variously as "3.0a" through "3.0j", "3.0 patchlevel 1" through "3.0 patchlevel 10", or "3.0pl1" through "3.0pl10" rather than - 3.0.0 and 3.0.1 through 3.0.10; the three component numbering scheme + 3.0.0 and 3.0.1 through 3.0.10; the three component numbering scheme began to be used with 3.1.0. - Headed by Mike Stephenson and coordinated by Izchak Miller and - Janet Walz, the NetHack Development Team which now included Ken - Arromdee, David Cohrs, Jean-Christophe Collet, Kevin Darcy, Matt Day, - Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Eric Raymond, - and Eric Smith undertook a radical revision of 3.0. They re-struc- - tured the game's design, and re-wrote major parts of the code. They - added multiple dungeons, a new display, special individual character - quests, a new endgame and many other new features, and produced + Headed by Mike Stephenson and coordinated by Izchak Miller and + Janet Walz, the NetHack Development Team which now included Ken + Arromdee, David Cohrs, Jean-Christophe Collet, Kevin Darcy, Matt Day, + Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Eric Raymond, + and Eric Smith undertook a radical revision of 3.0. They re-struc- + tured the game's design, and re-wrote major parts of the code. They + added multiple dungeons, a new display, special individual character + quests, a new endgame and many other new features, and produced NetHack 3.1. Version 3.1.0 was released in January of 1993. Ken Lorber, Gregg Wonderly and Greg Olson, with help from Richard @@ -7230,14 +7230,14 @@ 3.1 to the PC. Jon W{tte and Hao-yang Wang, with help from Ross Brown, Mike Eng- - ber, David Hairston, Michael Hamel, Jonathan Handler, Johnny Lee, Tim - Lennan, Rob Menke, and Andy Swanson, developed NetHack 3.1 for the - Macintosh, porting it for MPW. Building on their development, Bart + ber, David Hairston, Michael Hamel, Jonathan Handler, Johnny Lee, Tim + Lennan, Rob Menke, and Andy Swanson, developed NetHack 3.1 for the + Macintosh, porting it for MPW. Building on their development, Bart House added a Think C port. - Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith ported + Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith ported NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua - Delahunty, was responsible for the VMS version of NetHack 3.1. + Delahunty, was responsible for the VMS version of NetHack 3.1. Michael Allison ported NetHack 3.1 to Windows NT. Dean Luick, with help from David Cohrs, developed NetHack 3.1 for @@ -7245,13 +7245,13 @@ nh10.bdf, an optionally used custom X11 font which has tiny images in place of letters and punctuation, a precursor of tiles. Those images don't extend to individual monster and object types, just replacements - for monster and object classes (so one custom image for all "a" - insects and another for all "[" armor and so forth, not separate + for monster and object classes (so one custom image for all "a" + insects and another for all "[" armor and so forth, not separate images for beetles and ants or for cloaks and boots). - Warwick Allison wrote a graphically displayed version of NetHack - for the Atari where the tiny pictures were described as "icons" and - were distinct for specific types of monsters and objects rather than + Warwick Allison wrote a graphically displayed version of NetHack + for the Atari where the tiny pictures were described as "icons" and + were distinct for specific types of monsters and objects rather than NetHack 5.0.0 May 29, 2026 @@ -7264,24 +7264,24 @@ - just their classes. He contributed them to the NetHack Development - Team which rechristened them "tiles", original usage which has subse- - quently been picked up by various other games. NetHack's tiles sup- - port was then implemented on other platforms (initially MS-DOS but + just their classes. He contributed them to the NetHack Development + Team which rechristened them "tiles", original usage which has subse- + quently been picked up by various other games. NetHack's tiles sup- + port was then implemented on other platforms (initially MS-DOS but eventually Windows, Qt, and X11 too). - The 3.2 NetHack Development Team, comprised of Michael Allison, - Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, - Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Eric Smith, - Mike Stephenson, Janet Walz, and Paul Winner, released version 3.2.0 + The 3.2 NetHack Development Team, comprised of Michael Allison, + Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, + Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Eric Smith, + Mike Stephenson, Janet Walz, and Paul Winner, released version 3.2.0 in April of 1996. - Version 3.2 marked the tenth anniversary of the formation of the + Version 3.2 marked the tenth anniversary of the formation of the development team. In a testament to their dedication to the game, all thirteen members of the original NetHack Development Team remained on the team at the start of work on that release. During the interval between the release of 3.1.3 and 3.2.0, one of the founding members of - the NetHack Development Team, Dr. Izchak Miller, was diagnosed with + the NetHack Development Team, Dr. Izchak Miller, was diagnosed with cancer and passed away. That release of the game was dedicated to him by the development and porting teams. @@ -7294,22 +7294,22 @@ "variants" publicly available: Tom Proudfoot and Yuval Oren created NetHack++, which was quickly - renamed NetHack-- when some people incorrectly assumed that it was a - conversion of the C source code to C++. Working independently, - Stephen White wrote NetHack Plus. Tom Proudfoot later merged NetHack - Plus and his own NetHack-- to produce SLASH. Larry Stewart-Zerba and - Warwick Allison improved the spell casting system with the Wizard + renamed NetHack-- when some people incorrectly assumed that it was a + conversion of the C source code to C++. Working independently, + Stephen White wrote NetHack Plus. Tom Proudfoot later merged NetHack + Plus and his own NetHack-- to produce SLASH. Larry Stewart-Zerba and + Warwick Allison improved the spell casting system with the Wizard Patch. Warwick Allison also ported NetHack to use the Qt interface. - Warren Cheung combined SLASH with the Wizard Patch to produce + Warren Cheung combined SLASH with the Wizard Patch to produce Slash'EM, and with the help of Kevin Hugo, added more features. Kevin later joined the NetHack Development Team and incorporated the best of these ideas into NetHack 3.3. - The final update to 3.2 was the bug fix release 3.2.3, which was - released simultaneously with 3.3.0 in December 1999 just in time for - the Year 2000. Because of the newer version, 3.2.3 was released as a - source code patch only, without any ready-to-play distribution for + The final update to 3.2 was the bug fix release 3.2.3, which was + released simultaneously with 3.3.0 in December 1999 just in time for + the Year 2000. Because of the newer version, 3.2.3 was released as a + source code patch only, without any ready-to-play distribution for systems that usually had such. (To anyone considering resurrecting an old version: all versions @@ -7330,58 +7330,58 @@ - rectly, interfering with insertion of new high scores and with - retrieval of old character names to use for random ghost and statue + rectly, interfering with insertion of new high scores and with + retrieval of old character names to use for random ghost and statue names in the current game.) - The 3.3 NetHack Development Team, consisting of Michael Allison, - Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, + The 3.3 NetHack Development Team, consisting of Michael Allison, + Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lorber, Dean Luick, Pat Rankin, Eric Smith, Mike Stephenson, Janet Walz, and Paul Winner, released 3.3.0 in December 1999 and 3.3.1 in August of 2000. Version 3.3 offered many firsts. It was the first version to sep- - arate race and profession. The Elf class was removed in preference to - an elf race, and the races of dwarves, gnomes, and orcs made their - first appearance in the game alongside the familiar human race. Monk - and Ranger roles joined Archeologists, Barbarians, Cavemen, Healers, - Knights, Priests, Rogues, Samurai, Tourists, Valkyries and of course, - Wizards. It was also the first version to allow you to ride a steed, - and was the first version to have a publicly available web-site list- - ing all the bugs that had been discovered. Despite that constantly - growing bug list, 3.3 proved stable enough to last for more than a + arate race and profession. The Elf class was removed in preference to + an elf race, and the races of dwarves, gnomes, and orcs made their + first appearance in the game alongside the familiar human race. Monk + and Ranger roles joined Archeologists, Barbarians, Cavemen, Healers, + Knights, Priests, Rogues, Samurai, Tourists, Valkyries and of course, + Wizards. It was also the first version to allow you to ride a steed, + and was the first version to have a publicly available web-site list- + ing all the bugs that had been discovered. Despite that constantly + growing bug list, 3.3 proved stable enough to last for more than a year and a half. - The 3.4 NetHack Development Team initially consisted of Michael - Allison, Ken Arromdee, David Cohrs, Jessie Collet, Kevin Hugo, Ken - Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet Walz, and Paul - Winner, with Warwick Allison joining just before the release of + The 3.4 NetHack Development Team initially consisted of Michael + Allison, Ken Arromdee, David Cohrs, Jessie Collet, Kevin Hugo, Ken + Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet Walz, and Paul + Winner, with Warwick Allison joining just before the release of NetHack 3.4.0 in March 2002. - As with version 3.3, various people contributed to the game as a - whole as well as supporting ports on the different platforms that + As with version 3.3, various people contributed to the game as a + whole as well as supporting ports on the different platforms that NetHack runs on: Pat Rankin maintained 3.4 for VMS. - Michael Allison maintained NetHack 3.4 for the MS-DOS platform. + Michael Allison maintained NetHack 3.4 for the MS-DOS platform. Paul Winner and Yitzhak Sapir provided encouragement. - Dean Luick, Mark Modrall, and Kevin Hugo maintained and enhanced + Dean Luick, Mark Modrall, and Kevin Hugo maintained and enhanced the Macintosh port of 3.4. - Michael Allison, David Cohrs, Alex Kompel, Dion Nicolaas, and - Yitzhak Sapir maintained and enhanced 3.4 for the Microsoft Windows - platform. Alex Kompel contributed a new graphical interface for the - Windows port. Alex Kompel also contributed a Windows CE port for + Michael Allison, David Cohrs, Alex Kompel, Dion Nicolaas, and + Yitzhak Sapir maintained and enhanced 3.4 for the Microsoft Windows + platform. Alex Kompel contributed a new graphical interface for the + Windows port. Alex Kompel also contributed a Windows CE port for 3.4.1. - Ron Van Iwaarden was the sole maintainer of NetHack for OS/2 the - past several releases. Unfortunately Ron's last OS/2 machine stopped - working in early 2006. A great many thanks to Ron for keeping NetHack + Ron Van Iwaarden was the sole maintainer of NetHack for OS/2 the + past several releases. Unfortunately Ron's last OS/2 machine stopped + working in early 2006. A great many thanks to Ron for keeping NetHack alive on OS/2 all these years. - Janne Salmijarvi and Teemu Suikki maintained and enhanced the + Janne Salmijarvi and Teemu Suikki maintained and enhanced the Amiga port of 3.4 after Janne Salmijarvi resurrected it for 3.3.1. @@ -7403,37 +7403,37 @@ ning of a long release hiatus. 3.4.3 proved to be a remarkably stable version that provided continued enjoyment by the community for more than a decade. The NetHack Development Team slowly and quietly contin- - ued to work on the game behind the scenes during the tenure of 3.4.3. - It was during that same period that several new variants emerged - within the NetHack community. Notably sporkhack by Derek S. Ray, - unnethack by Patric Mueller, nitrohack and its successors originally - by Daniel Thaler and then by Alex Smith, and Dynahack by Tung Nguyen. - Some of those variants continue to be developed, maintained, and + ued to work on the game behind the scenes during the tenure of 3.4.3. + It was during that same period that several new variants emerged + within the NetHack community. Notably sporkhack by Derek S. Ray, + unnethack by Patric Mueller, nitrohack and its successors originally + by Daniel Thaler and then by Alex Smith, and Dynahack by Tung Nguyen. + Some of those variants continue to be developed, maintained, and enjoyed by the community to this day. In September 2014, an interim snapshot of the code under develop- ment was released publicly by other parties. Since that code was a work-in-progress and had not gone through the process of debugging it as a suitable release, it was decided that the version numbers present - on that code snapshot would be retired and never used in an official - NetHack release. An announcement was posted on the NetHack Develop- - ment Team's official https://www.nethack.org website to that effect, - stating that there would never be a 3.4.4, 3.5, or 3.5.0 official + on that code snapshot would be retired and never used in an official + NetHack release. An announcement was posted on the NetHack Develop- + ment Team's official https://www.nethack.org website to that effect, + stating that there would never be a 3.4.4, 3.5, or 3.5.0 official release version. - In January 2015, preparation began for the release of NetHack + In January 2015, preparation began for the release of NetHack 3.6. - At the beginning of development for what would eventually get - released as 3.6.0, the NetHack Development Team consisted of Warwick - Allison, Michael Allison, Ken Arromdee, David Cohrs, Jessie Collet, - Ken Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet Walz, and - Paul Winner. In early 2015, ahead of the release of 3.6.0, new mem- - bers Sean Hunt, Pasi Kallinen, and Derek S. Ray joined the NetHack + At the beginning of development for what would eventually get + released as 3.6.0, the NetHack Development Team consisted of Warwick + Allison, Michael Allison, Ken Arromdee, David Cohrs, Jessie Collet, + Ken Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet Walz, and + Paul Winner. In early 2015, ahead of the release of 3.6.0, new mem- + bers Sean Hunt, Pasi Kallinen, and Derek S. Ray joined the NetHack Development Team. - Near the end of the development of 3.6.0, one of the significant - inspirations for many of the humorous and fun features found in the + Near the end of the development of 3.6.0, one of the significant + inspirations for many of the humorous and fun features found in the game, author Terry Pratchett, passed away. NetHack 3.6.0 introduced a tribute to him. @@ -7485,17 +7485,17 @@ In early May 2019, another 320 bug fixes along with some enhance- ments and the adopted curses window port, were released as 3.6.2. - Bart House, who had contributed to the game as a porting team - participant for decades, joined the NetHack Development Team in late + Bart House, who had contributed to the game as a porting team + participant for decades, joined the NetHack Development Team in late May 2019. - NetHack 3.6.3 was released on December 5, 2019 containing over + NetHack 3.6.3 was released on December 5, 2019 containing over 190 bug fixes to NetHack 3.6.2. - NetHack 3.6.4 was released on December 18, 2019 containing a + NetHack 3.6.4 was released on December 18, 2019 containing a security fix and a few bug fixes. - NetHack 3.6.5 was released on January 27, 2020 containing some + NetHack 3.6.5 was released on January 27, 2020 containing some security fixes and a small number of bug fixes. NetHack 3.6.6 was released on March 8, 2020 containing a security @@ -7515,7 +7515,7 @@ Exposure of the development to the public brought many good things, and some challenges. People were able to observe and criticize - changes and new features almost immediately, and they often did. The + changes and new features almost immediately, and they often did. The NetHack 5.0.0 May 29, 2026 @@ -7528,8 +7528,8 @@ - GitHub pull request system made it straightforward for people to con- - tribute directly to development. Contributions resolved many, many + GitHub pull request system made it straightforward for people to con- + tribute directly to development. Contributions resolved many, many bugs in the game and we thank all the contributors. In early 2026, with the game development getting stable enough to @@ -7552,13 +7552,13 @@ the quest texts in NetHack 5.0.0. The entire development team acknowl- edges the work done by Pasi Kallinen to make that happen. - At the time of the NetHack 5.0 release, the core development + At the time of the NetHack 5.0 release, the core development team, active and erstwhile, included Warwick Allison, Michael Allison, Ken Arromdee, David Cohrs, Jessie Collet, Bart House, Kevin Hugo, Pasi - Kallinen, Ken Lorber, Dean Luick, Pat Rankin, Derek S. Ray, Alex + Kallinen, Ken Lorber, Dean Luick, Pat Rankin, Derek S. Ray, Alex Smith, Patric Mueller, Mike Stephenson, Janet Walz, Paul Winner. - Ken Lorber, Pat Rankin, Patrick Mueller and Michael Allison + Ken Lorber, Pat Rankin, Patrick Mueller and Michael Allison helped ensure that NetHack 5.0 would run on macOS. Ingo Paschke somehow managed to revive a NetHack 5.0 port for the @@ -7566,7 +7566,7 @@ was shared so others can straightforwardly produce NetHack 5.0 for the Amiga thanks to his efforts. - Ray Chason contributed the majority of maintenance work for the + Ray Chason contributed the majority of maintenance work for the NetHack 5.0 MS-DOS port, including porting the curses interface to it. Michael Allison ensured that NetHack 5.0 core changes continued to work with the msdos port and keep it alive. Cross-compiling the MS- @@ -7594,7 +7594,7 @@ - The official NetHack web site is maintained by Ken Lorber at + The official NetHack web site is maintained by Ken Lorber at https://www.nethack.org/. @@ -7639,12 +7639,12 @@ 12.1. Special Thanks - On behalf of the NetHack community, thank you very much once - again to M. Drew Streib and Pasi Kallinen for providing a public - NetHack server at nethack.alt.org. Thanks to Keith Simpson and Andy - Thomson for hardfought.org. Thanks to all those unnamed dungeoneers - who invest their time and effort into annual NetHack tournaments such - as Junethack, The November NetHack Tournament, and in days past, + On behalf of the NetHack community, thank you very much once + again to M. Drew Streib and Pasi Kallinen for providing a public + NetHack server at nethack.alt.org. Thanks to Keith Simpson and Andy + Thomson for hardfought.org. Thanks to all those unnamed dungeoneers + who invest their time and effort into annual NetHack tournaments such + as Junethack, The November NetHack Tournament, and in days past, devnull.net (gone for now, but not forgotten). @@ -7662,9 +7662,9 @@ 12.2. Dungeoneers - From time to time, some depraved individual out there in netland - sends a particularly intriguing modification to help out with the - game. The NetHack Development Team sometimes makes note of the names + From time to time, some depraved individual out there in netland + sends a particularly intriguing modification to help out with the + game. The NetHack Development Team sometimes makes note of the names of the worst of these miscreants in this, the list of Dungeoneers: @@ -7792,7 +7792,7 @@ - Brand and product names are trademarks or registered trademarks + Brand and product names are trademarks or registered trademarks of their respective holders. From a24a0240ce0f6b78d984a837de7950a9e5ed9b3a Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Fri, 29 May 2026 08:16:06 -0400 Subject: [PATCH 409/702] This is cron-daily v1-May-7-2026. 000files updated: Files --- Files | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Files b/Files index c7e0916f8..42dc61957 100644 --- a/Files +++ b/Files @@ -408,9 +408,9 @@ solaris-playground unix sys/unix/hints/include: (files for configuring UNIX NetHack versions) compiler.500 cross-post.500 cross-pre1.500 cross-pre2.500 -gbdates-post.500 gbdates-pre.500 linuxdistro.500 misc.500 -multisnd-post.500 multisnd1-pre.500 multisnd2-pre.500 multiw-1.500 -multiw-2.500 response.500 whichbsd.500 +dirs-perms.500 gbdates-post.500 gbdates-pre.500 linuxdistro.500 +misc.500 multisnd-post.500 multisnd1-pre.500 multisnd2-pre.500 +multiw-1.500 multiw-2.500 response.500 whichbsd.500 sys/vms: (files for VMS version) From 207db14301fe3374da7fefc0f891a2a450392e53 Mon Sep 17 00:00:00 2001 From: Patric Mueller Date: Sat, 30 May 2026 13:53:13 +0200 Subject: [PATCH 410/702] tty: handle indexed colors separately from RGB color space The terminfo entries from the standard ncurses distribution have peculiar settings for entries supporting 24 bit colors. The direct entries mix indexed and RGB values into an incompatible mess. This commit adds a simple workaround for the tty port. Colors are initialised as if only 8 ANSI colors are available. This does not affect color customisation from the symsets. The curses port is affected as well. But I am not yet comfortable to refactor a large part of the code for an absolute edge case. --- win/tty/termcap.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/win/tty/termcap.c b/win/tty/termcap.c index d5fb0f755..ff8c4c2bf 100644 --- a/win/tty/termcap.c +++ b/win/tty/termcap.c @@ -31,6 +31,7 @@ static void analyze_seq(char *, int *, int *); #if (defined(TERMLIB) || defined(ANSI_DEFAULT)) static void init_hilite(void); static void kill_hilite(void); +static int indexed_color_count(void); #endif /* (see tcap.h) -- nh_CM, nh_ND, nh_CD, nh_HI,nh_HE, nh_US,nh_UE, ul_hack */ @@ -947,6 +948,15 @@ init_hilite(void) colors = tgetnum(nhStr("Co")); iflags.colorcount = colors; +#ifdef NCURSES_VERSION + /* The standard ncurses terminfo entries that support 24-bit colors + (*-direct) map the standard 8/16/256 colors onto the beginning + of the 24-bit color range. For example, rgb(0,0,1) appears as red + instead of nearly black. iflags.colorcount should retain the actual + supported color count, while for default color initialization we + take the available indexed colors into consieration. */ + colors = indexed_color_count(); +#endif int md_len = 0; if (colors < 8 || !MD || !*MD @@ -1054,7 +1064,7 @@ kill_hilite(void) if (hilites[CLR_BLACK] != hilites[CLR_BLUE]) free(hilites[CLR_BLACK]), hilites[CLR_BLACK] = NULL; } - if (tgetnum(nhStr("Co")) >= 16) { + if (indexed_color_count() >= 16) { if (hilites[CLR_BLUE]) free(hilites[CLR_BLUE]); if (hilites[CLR_GREEN]) @@ -1096,6 +1106,21 @@ kill_hilite(void) hilites[c] = NULL; } +static int +indexed_color_count(void) +{ +#ifdef NCURSES_VERSION + /* ncurses adds the non-standard attribute CO for "number of indexed + colors overlaying RGB space". */ + int idx_colors = tgetnum(nhStr("CO")); + if (idx_colors > 0) { + return idx_colors; + } +#endif + + return tgetnum(nhStr("Co")); +} + #else /* UNIX && TERMINFO */ #ifndef TOS From 2a912fe001fb8cee03d615906b20ecf8c56f6c1f Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 30 May 2026 11:32:37 -0400 Subject: [PATCH 411/702] SELECTSAVE update In SELECTSAVE implementations, out of date savefiles in the tree were triggering error messages to the user during the building of the pick list. The file with the error never ended up on the pick list, or got removed, so the error was perpetual on every SELECTSAVE startup. This passes the UTD_QUIETLY flag down the the small set of callers involved, so that when it was received by uptodate(), it went about its verification work quietly. --- include/extern.h | 4 ++-- src/bones.c | 2 +- src/files.c | 17 +++++++++++------ src/restore.c | 2 +- src/version.c | 5 ++++- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/include/extern.h b/include/extern.h index 90af830f4..6dd14db52 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1102,7 +1102,7 @@ extern NHFILE *get_freeing_nhfile(void); extern NHFILE *restore_saved_game(void); extern int check_panic_save(void); #ifdef SELECTSAVED -extern char *plname_from_file(const char *, boolean) NONNULLARG1; +extern char *plname_from_file(const char *, boolean, int) NONNULLARG1; #endif extern char **get_saved_games(void); extern void free_saved_games(char **); @@ -3602,7 +3602,7 @@ extern void dump_version_info(void); extern void store_critical_bytes(NHFILE *) NONNULLARG1; extern int compare_critical_bytes(NHFILE *, int *, unsigned long) NONNULLARG1; extern int get_critical_size_count(void); -extern int validate(NHFILE *, const char *, boolean) NONNULLARG1; +extern int validate(NHFILE *, const char *, boolean, int) NONNULLARG1; /* ### video.c ### */ diff --git a/src/bones.c b/src/bones.c index 092ed203a..e55857d4b 100644 --- a/src/bones.c +++ b/src/bones.c @@ -661,7 +661,7 @@ getbones(void) } program_state.reading_bonesfile = 1; - if (validate(nhfp, gb.bones, FALSE) != SF_UPTODATE) { + if (validate(nhfp, gb.bones, FALSE, 0) != SF_UPTODATE) { if (!wizard) pline("Discarding unusable bones; no need to panic..."); ok = FALSE; diff --git a/src/files.c b/src/files.c index 16c0f32c8..bb6e7c5a8 100644 --- a/src/files.c +++ b/src/files.c @@ -1269,7 +1269,7 @@ restore_saved_game(void) nh_uncompress(fq_save); if ((nhfp = open_savefile()) != 0) { - if ((sfstatus = validate(nhfp, fq_save, FALSE)) != SF_UPTODATE) { + if ((sfstatus = validate(nhfp, fq_save, FALSE, 0)) != SF_UPTODATE) { close_nhfile(nhfp); nhfp = problematic_savefile(sfstatus, fq_save); } @@ -1347,7 +1347,7 @@ check_panic_save(void) char * plname_from_file( const char *filename, - boolean without_wait_synch_per_file) + boolean without_wait_synch_per_file, int additional_utd_flags) { NHFILE *nhfp; unsigned ln; @@ -1368,7 +1368,8 @@ plname_from_file( nh_uncompress(gs.SAVEF); if ((nhfp = open_savefile()) != 0) { if ((sfstatus = validate(nhfp, filename, - without_wait_synch_per_file)) == SF_UPTODATE) { + without_wait_synch_per_file, + additional_utd_flags)) == SF_UPTODATE) { /* room for "name+role+race+gend+algn X" where the space before X is actually NUL and X is playmode: one of '-', 'X', or 'D' */ ln = (unsigned) PL_NSIZ_PLUS; @@ -1405,7 +1406,7 @@ get_saved_games(void) const char *fq_old_save; #endif char **files = 0; - int i, count_failures = 0; + int i, count_failures = 0, utd_flags_to_pass_downstream = 0; Strcpy(svp.plname, "*"); set_savefile_name(FALSE); @@ -1438,7 +1439,11 @@ get_saved_games(void) (void) memset((genericptr_t) result, 0, (n + 1) * sizeof (char *)); for(i = 0; i < n; i++) { char *r; - r = plname_from_file(files[i], SUPPRESS_WAITSYNCH_PERFILE); + if (!wizard) + utd_flags_to_pass_downstream = UTD_QUIETLY; + r = plname_from_file(files[i], + SUPPRESS_WAITSYNCH_PERFILE, + utd_flags_to_pass_downstream); if (r) { /* this renaming of the savefile is not compatible @@ -1465,7 +1470,7 @@ get_saved_games(void) } free_saved_games(files); - if (count_failures) + if (count_failures && !(utd_flags_to_pass_downstream & UTD_QUIETLY)) wait_synch(); } #endif /* WIN32 */ diff --git a/src/restore.c b/src/restore.c index 870c678f5..318f90e53 100644 --- a/src/restore.c +++ b/src/restore.c @@ -890,7 +890,7 @@ dorecover(NHFILE *nhfp) restoreinfo.mread_flags = 0; rewind_nhfile(nhfp); /* return to beginning of file */ - (void) validate(nhfp, (char *) 0, FALSE); + (void) validate(nhfp, (char *) 0, FALSE, 0); get_plname_from_file(nhfp, svp.plname, TRUE); /* not 0 nor REST_GSTATE nor REST_LEVELS */ diff --git a/src/version.c b/src/version.c index 117d7bdf0..8fa0e0398 100644 --- a/src/version.c +++ b/src/version.c @@ -849,11 +849,14 @@ compare_critical_bytes(NHFILE *nhfp, int *idx_1st_mismatch, unsigned long utdfla * SF_DM_MISMATCH (9) some other mismatch */ int -validate(NHFILE *nhfp, const char *name, boolean without_waitsynch_perfile) +validate(NHFILE *nhfp, const char *name, boolean without_waitsynch_perfile, + int additional_utd_flags) { unsigned long utdflags = 0L; int validsf = 0; +if (additional_utd_flags) + utdflags |= additional_utd_flags; #ifdef SFCTOOL utdflags |= UTD_QUIETLY; #endif From bb407a84da3864fedd2b6b91c6db23179f12806e Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 30 May 2026 11:38:38 -0400 Subject: [PATCH 412/702] follow-up: fixes5-0-1.txt entry re:previous commit --- doc/fixes5-0-1.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 5fd0d510c..3bad1c0a1 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -44,7 +44,11 @@ fix an off-by-one in glyph_is_normal_piletop_obj (pr #1547 by ingpaschke) replace the hashtable used for parsing glyphnames with sorted indices and reduce the string allocation load during that processing (cherry-pick of pr #1548 by ingpaschke) - +for SELECTSAVE, don't display error messages to a regular player about + out-of-date save file encountered while building the saved-game list + to select from; the game doesn't offer any action to assist with them + presently, and they would have to be dealt with external to the game + Platform- and/or Interface-Specific Fixes ----------------------------------------- From 78e7b23b1ea9078a5080afb4869b0a5b641a4854 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 30 May 2026 11:40:54 -0400 Subject: [PATCH 413/702] follow-up: Unix uses different code; build fix --- src/files.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/files.c b/src/files.c index bb6e7c5a8..a4748790e 100644 --- a/src/files.c +++ b/src/files.c @@ -1504,7 +1504,7 @@ get_saved_games(void) Sprintf(filename, "save/%d%s", uid, name); r = plname_from_file(filename, - ALLOW_WAITSYNCH_PERFILE); + ALLOW_WAITSYNCH_PERFILE, 0); if (r) result[j++] = r; } From 13ff430b14aaf9dbc82f7d6a0966ca6ced71f6bb Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 30 May 2026 11:45:20 -0400 Subject: [PATCH 414/702] Alter the fixes5-0-1.txt entry to match code --- doc/fixes5-0-1.txt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 3bad1c0a1..aee7eb937 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -44,10 +44,8 @@ fix an off-by-one in glyph_is_normal_piletop_obj (pr #1547 by ingpaschke) replace the hashtable used for parsing glyphnames with sorted indices and reduce the string allocation load during that processing (cherry-pick of pr #1548 by ingpaschke) -for SELECTSAVE, don't display error messages to a regular player about - out-of-date save file encountered while building the saved-game list - to select from; the game doesn't offer any action to assist with them - presently, and they would have to be dealt with external to the game +for SELECTSAVE, allow utd flags for uptodate() to be passed down through + the small set of callers that eventually call uptodate(). Platform- and/or Interface-Specific Fixes @@ -160,6 +158,11 @@ Windows: setting any map_mode option in the config file could trigger Windows: a Windows console debug line began showing up after the sources switched patchlevel.h NH_DEVEL_STATUS from NH_STATUS_RELEASED to NH_STATUS_POSTRELEASE; make it only ever show if (wizard) is true +Windows: with SELECTSAVE don't display error messages to a regular + don't display error messages to a regular player about out-of-date + save files encountered while building the saved-game list to + select from; the game doesn't offer any action to assist with them + presently, and they would have to be dealt with external to the game tty: allow custom glyph colors if they're basic 16 nethack colors on terminals with less than 256 colors From b6b35a8d0fd03c879695d74368cd7982debd3c20 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 30 May 2026 11:48:31 -0400 Subject: [PATCH 415/702] yet-another fixes5-0-1.txt update --- doc/fixes5-0-1.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index aee7eb937..cbcc5c14f 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -45,7 +45,7 @@ replace the hashtable used for parsing glyphnames with sorted indices and reduce the string allocation load during that processing (cherry-pick of pr #1548 by ingpaschke) for SELECTSAVE, allow utd flags for uptodate() to be passed down through - the small set of callers that eventually call uptodate(). + the small set of callers that eventually call uptodate() Platform- and/or Interface-Specific Fixes @@ -158,11 +158,11 @@ Windows: setting any map_mode option in the config file could trigger Windows: a Windows console debug line began showing up after the sources switched patchlevel.h NH_DEVEL_STATUS from NH_STATUS_RELEASED to NH_STATUS_POSTRELEASE; make it only ever show if (wizard) is true -Windows: with SELECTSAVE don't display error messages to a regular - don't display error messages to a regular player about out-of-date - save files encountered while building the saved-game list to - select from; the game doesn't offer any action to assist with them - presently, and they would have to be dealt with external to the game +Windows: with SELECTSAVE don't display error messages to a regular player + about out-of-date save files encountered while building the + saved-game list to select from; the game doesn't offer any + action to assist with them presently, and they would have to be + dealt with external to the game, so try not to annoy tty: allow custom glyph colors if they're basic 16 nethack colors on terminals with less than 256 colors From f72554a238eda7a5280d96bbfb7665eb73ad78e6 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 30 May 2026 15:54:18 -0400 Subject: [PATCH 416/702] avoid shk interaction too early --- src/mkobj.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mkobj.c b/src/mkobj.c index 93f047d14..822badf51 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -2354,7 +2354,9 @@ place_object(struct obj *otmp, coordxy x, coordxy y) otmp->where = OBJ_FLOOR; /* if placed outside of shop, no_charge is no longer applicable */ - if (otmp->no_charge && !costly_spot(x, y) + if (program_state.beyond_savefile_load + && otmp->no_charge + && !costly_spot(x, y) && !costly_adjacent(find_objowner(otmp, x, y), x, y)) otmp->no_charge = 0; From 3096da48fec09f322be7c3b8091dd06a08c32c23 Mon Sep 17 00:00:00 2001 From: Housebot Date: Sun, 31 May 2026 11:21:25 -0600 Subject: [PATCH 417/702] libnh: export GLYPH_PILETOP_OFF constant Expose GLYPH_PILETOP_OFF in libnh JS constants so embedding apps can distinguish statue glyphs from piletop glyphs. --- sys/libnh/libnhmain.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index 67b38e4e0..acdea170e 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -1092,6 +1092,7 @@ void js_constants_init() { SET_CONSTANT("GLYPH", GLYPH_SWALLOW_OFF); SET_CONSTANT("GLYPH", GLYPH_WARNING_OFF); SET_CONSTANT("GLYPH", GLYPH_STATUE_OFF); + SET_CONSTANT("GLYPH", GLYPH_PILETOP_OFF); SET_CONSTANT("GLYPH", GLYPH_UNEXPLORED_OFF); SET_CONSTANT("GLYPH", GLYPH_NOTHING_OFF); SET_CONSTANT("GLYPH", MAX_GLYPH); From 055caaffbfd2c15a57bd711e8c713e9351008dc0 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 31 May 2026 13:26:34 -0400 Subject: [PATCH 418/702] revisit shop_keeper() readiness During a restore from a savefiles is not the only time that levels are processed by getlev() in NetHack. They are read back in as the hero moves up and down between levels and dungeons. The previous fix checked for program_state.beyond_savefile_load, but once set, that remains static through level changes. It would be better to check the status of the level being read, because those operations do placements as well. Add the following: struct levelstatus level_status; level_status.making - in the midst of makelevel processing level_status.loading - in the midst of loading a level via getlev() level_status.ready - the level is fully ready (all 3 of the above status settings are mutually exclusive) level_status.shkready - the level processing is far enough along to allow shop keeper tests and actions This also relocates the find_lev_obj() call in getlev() down several lines, so that it falls after any set_residency() calls, so that it has a better chance of carrying out what it was intending to do with the shop_keeper() checks made by its subfunctions. --- doc/fixes5-0-1.txt | 4 ++++ include/decl.h | 5 +++++ include/extern.h | 1 + include/hack.h | 8 ++++++++ src/decl.c | 8 ++++++++ src/mklev.c | 6 +++++- src/mkobj.c | 4 +--- src/restore.c | 21 +++++++++++++++------ src/shk.c | 11 +++++++++++ 9 files changed, 58 insertions(+), 10 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index cbcc5c14f..5b7180122 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -46,6 +46,10 @@ replace the hashtable used for parsing glyphnames with sorted indices and of pr #1548 by ingpaschke) for SELECTSAVE, allow utd flags for uptodate() to be passed down through the small set of callers that eventually call uptodate() +avoid calling costly_spot(), costly_adjacent(), find_byowner(), which + all rely on shop_keeper() under the hood, in the midst of the level + loading process before all the required data structures have + been finalized Platform- and/or Interface-Specific Fixes diff --git a/include/decl.h b/include/decl.h index 2eb47fcbd..c6dbe7072 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1288,6 +1288,11 @@ extern struct instance_globals_saved_w svw; extern struct instance_globals_saved_x svx; extern struct instance_globals_saved_y svy; extern struct sinfo program_state; /* flags describing game's current state */ +/* flags describing current level's loading/making/readiness status; + * restlevelstate() already associated term 'levelstate' for a different + * purpose, so attempt to avoid confusion + */ +extern struct levelstatus level_status; struct const_globals { const struct obj zeroobj; /* used to zero out a struct obj */ diff --git a/include/extern.h b/include/extern.h index 6dd14db52..5e8b9fa26 100644 --- a/include/extern.h +++ b/include/extern.h @@ -520,6 +520,7 @@ extern void destroy_drawbridge(coordxy, coordxy); /* ### decl.c ### */ extern void program_state_init(void); +extern void level_status_init(void); extern void decl_globals_init(void); extern void sa_victual(volatile struct victual_info *); diff --git a/include/hack.h b/include/hack.h index acf93509b..c98c8ab8a 100644 --- a/include/hack.h +++ b/include/hack.h @@ -821,6 +821,14 @@ struct sinfo { #endif }; +/* structure for current 'level_status'; not saved and restored */ +struct levelstatus { + int making; /* makelevel has begun */ + int loading; /* level loading has begun */ + int shkready; /* shops ready */ + int ready; /* level is ready */ +}; + /* value of program_state.input_state, significant during readchar(); get_count() expects digits then a command so sets it to commandInp */ enum InputState { diff --git a/src/decl.c b/src/decl.c index 587c83e90..8b04a05ac 100644 --- a/src/decl.c +++ b/src/decl.c @@ -1002,6 +1002,7 @@ static const struct instance_globals_saved_y init_svy = { }; static const struct sinfo init_program_state = { 0 }; +static const struct levelstatus init_level_status = { 0 }; #if 0 struct instance_globals g; @@ -1054,6 +1055,7 @@ struct instance_globals_saved_w svw; struct instance_globals_saved_x svx; struct instance_globals_saved_y svy; struct sinfo program_state; +struct levelstatus level_status; const struct const_globals cg = { DUMMY, /* zeroobj */ @@ -1079,6 +1081,12 @@ program_state_init(void) program_state = init_program_state; } +void +level_status_init(void) +{ + level_status = init_level_status; +} + void decl_globals_init(void) { diff --git a/src/mklev.c b/src/mklev.c index f11c2b1e8..2c48af09a 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -1261,6 +1261,9 @@ makelevel(void) impossible("makelevel() called when dungeon not yet initialized."); init_dungeons(); } + level_status_init(); + level_status.making = 1; + oinit(); /* assign level dependent obj probabilities */ clear_level_structures(); @@ -1416,7 +1419,7 @@ makelevel(void) for (i = 0; i < svn.nroom; ++i) { fill_special_room(&svr.rooms[i]); } - + level_status.shkready = 1; themerooms_post_level_generate(); if (gl.luacore && nhcb_counts[NHCB_LVL_ENTER]) { @@ -1425,6 +1428,7 @@ makelevel(void) nhl_pcall_handle(gl.luacore, 1, 0, "makelevel", NHLpa_panic); lua_settop(gl.luacore, 0); } + level_status.making = 0, level_status.ready = 1; } /* return TRUE if water location at (x,y) should have kelp. */ diff --git a/src/mkobj.c b/src/mkobj.c index 822badf51..735c88d34 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -2354,9 +2354,7 @@ place_object(struct obj *otmp, coordxy x, coordxy y) otmp->where = OBJ_FLOOR; /* if placed outside of shop, no_charge is no longer applicable */ - if (program_state.beyond_savefile_load - && otmp->no_charge - && !costly_spot(x, y) + if (level_status.shkready && otmp->no_charge && !costly_spot(x, y) && !costly_adjacent(find_objowner(otmp, x, y), x, y)) otmp->no_charge = 0; diff --git a/src/restore.c b/src/restore.c index 318f90e53..50c3a0137 100644 --- a/src/restore.c +++ b/src/restore.c @@ -1068,6 +1068,8 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) #endif program_state.in_getlev = TRUE; + level_status_init(); + level_status.loading = 1; #ifndef SFCTOOL if (ghostly) @@ -1170,9 +1172,11 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) dealloc_trap(trap); fobj = restobjchn(nhfp, FALSE); -#ifndef SFCTOOL - find_lev_obj(); -#endif /* !SFCTOOL */ + /* more work needs to be done on fobj in find_lev_obj() further down, + * but that needs to happen after set_residency() so that shop_keeper() + * will return correct results during the processing. + */ + /* restobjchn()'s `frozen' argument probably ought to be a callback routine so that we can check for objects being buried under ice */ svl.level.buriedobjlist = restobjchn(nhfp, FALSE); @@ -1202,7 +1206,6 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) if (hides_under(mtmp->data) && mtmp->mundetected) (void) hideunder(mtmp); } - /* regenerate monsters while on another level */ if (!u.uz.dlevel || program_state.restoring == REST_LEVELS) continue; @@ -1225,6 +1228,11 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) if (ghostly || (elapsed > 0L && elapsed > (long) rnd(10))) hide_monst(mtmp); } + level_status.shkready = 1; + /* post-5.0.0: this is now postponed until here so that it takes place + after set_residency() has been called */ + find_lev_obj(); + #endif /* !SFCTOOL */ restdamage(nhfp); @@ -1308,12 +1316,13 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) if (ghostly) clear_id_mapping(); +#endif + level_status.loading = 0, level_status.ready = 1; program_state.in_getlev = FALSE; -#else +#ifdef SFCTOOL nhUse(pid); nhUse(lev); #endif /* !SFCTOOL */ - program_state.in_getlev = FALSE; } void diff --git a/src/shk.c b/src/shk.c index cb86dfaa5..099215697 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1075,6 +1075,17 @@ shop_keeper(char rmno) correct the underlying svr.rooms[].resident issue but... */ return (struct monst *) 0; } + } else { + if (!level_status.shkready) { + int hmm UNUSED = 1; +#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED \ + && NH_DEVEL_STATUS != NH_STATUS_POSTRELEASE) + impossible("untrustworthy null shkp; level_status.shkready" + " is FALSE (%d, %d, %d, &d)", + level_status.making, level_status.loading, + level_status.shkready, level_status.ready); +#endif + } } return shkp; } From c112e50afef5cfd7a6d365e1bac205b9f5836e07 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 31 May 2026 13:57:56 -0400 Subject: [PATCH 419/702] follow-up: indentation bit --- src/shk.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/shk.c b/src/shk.c index 099215697..fd451eaaf 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1080,10 +1080,10 @@ shop_keeper(char rmno) int hmm UNUSED = 1; #if (NH_DEVEL_STATUS != NH_STATUS_RELEASED \ && NH_DEVEL_STATUS != NH_STATUS_POSTRELEASE) - impossible("untrustworthy null shkp; level_status.shkready" - " is FALSE (%d, %d, %d, &d)", - level_status.making, level_status.loading, - level_status.shkready, level_status.ready); + impossible("untrustworthy null shkp; level_status.shkready" + " is FALSE (%d, %d, %d, &d)", + level_status.making, level_status.loading, + level_status.shkready, level_status.ready); #endif } } From a31a9cb15203b2f04bf90d6a24ed8e74037a37e0 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 31 May 2026 18:28:06 -0400 Subject: [PATCH 420/702] Makefile.nmake updates for git_sha --- sys/windows/Makefile.nmake | 119 ++++++++++++++++++++----------------- 1 file changed, 66 insertions(+), 53 deletions(-) diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index 7a3a1064e..07e974d29 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -54,27 +54,30 @@ SOUND_LIBRARIES = windsound #------------------------------------------------------------------------------ # Curses options. # + +WANT_CURSES=Y + # Do you want console curses included? -CURSES_CONSOLE = Y +CURSES_CONSOLE=Y # Do you want graphical curses included? -CURSES_GRAPHICAL = Y +CURSES_GRAPHICAL=Y # #------------------------------------------------------------------------------ # Do you want debug information available to the executable? # -DEBUGINFO = Y +DEBUGINFO=Y # #------------------------------------------------------------------------------ # Do you want to include the address sanitizer? # -#WANT_ASAN = Y +#WANT_ASAN=Y #------------------------------------------------------------------------------ # Do you have a connection to the internet available that you want @@ -82,13 +85,13 @@ DEBUGINFO = Y # pdcursesmod source code? # Default is now Y. Set it to N if that won't work for you. -INTERNET_AVAILABLE = Y +INTERNET_AVAILABLE=1 #------------------------------------------------------------------------------ # # Do you have git commands available and NetHack in a git repository? -GIT_AVAILABLE = N +GIT_AVAILABLE=1 # If not, because you obtained the NetHack sources in a zip file download, # set GIT_AVAILABLE = N @@ -147,12 +150,24 @@ LUAVER=$(LUA_VERSION) # if GIT=1 is passed on the make command, allow use of git and internet !IF "$(GIT)" == "1" -INTERNET_AVAILABLE=Y -GIT_AVAILABLE=Y +INTERNET_AVAILABLE=1 +GIT_AVAILABLE=1 !ENDIF !IF "$(git)" == "1" -INTERNET_AVAILABLE=Y -GIT_AVAILABLE=Y +INTERNET_AVAILABLE=1 +GIT_AVAILABLE=1 +!ENDIF +!IF "$(GIT)" == "Y" +INTERNET_AVAILABLE=1 +GIT_AVAILABLE=1 +!ENDIF +!IF "$(git)" == "y" +INTERNET_AVAILABLE=1 +GIT_AVAILABLE=1 +!ENDIF +!IF "$(git)" == "Y" +INTERNET_AVAILABLE=1 +GIT_AVAILABLE=1 !ENDIF #============================================================================== @@ -252,8 +267,8 @@ LUA_MAY_PROCEED=N ADD_CURSES=N # First, Lua -!IF "$(INTERNET_AVAILABLE)" == "Y" -!IF "$(GIT_AVAILABLE)" == "Y" +!IF "$(INTERNET_AVAILABLE)" == "1" +!IF "$(GIT_AVAILABLE)" == "1" R_LUATOP=$(SUBM)lua LUATOP=$(SUBM)lua$(BACKSLASH) R_LUASRC=$(R_LUATOP) @@ -302,15 +317,15 @@ LUA_MAY_PROCEED=Y #!MESSAGE LUASRC=$(LUASRC) !IF "$(LUA_MAY_PROCEED)" != "Y" -!IF "$(INTERNET_AVAILABLE)" != "Y" +!IF "$(INTERNET_AVAILABLE)" != "1" !MESSAGE Your Makefile settings do not allow use of the internet to obtain Lua !ENDIF # INTERNET_AVAILABLE !MESSAGE and no copy of Lua was found in either $(SUBM)lua or $(LIBDIR)lua-$(LUAVER). !MESSAGE Change your nmake command line to include: !MESSAGE GIT=1 !MESSAGE or modify your Makefile to set the following: -!MESSAGE INTERNET_AVAILABLE=Y -!MESSAGE GIT_AVAILABLE=Y +!MESSAGE INTERNET_AVAILABLE=1 +!MESSAGE GIT_AVAILABLE=1 !ERROR Stopping because NetHack 5.0 requires Lua for its build. !ENDIF # LUA_MAY_PROCEED @@ -334,8 +349,8 @@ ADD_CURSES=N R_PDCDIST=pdcursesmod PDCDIST=$(R_PDCDIST)$(BACKSLASH) #U_PDCDIST=$(PDCDIST:\=/) -! IF "$(INTERNET_AVAILABLE)" == "Y" -! IF "$(GIT_AVAILABLE)" == "Y" +! IF "$(INTERNET_AVAILABLE)" == "1" +! IF "$(GIT_AVAILABLE)" == "1" #!MESSAGE debug spot1 R_PDCURSES_TOP=$(SUBM)$(R_PDCDIST) PDCURSES_TOP=$(R_PDCURSES_TOP)$(BACKSLASH) @@ -349,7 +364,7 @@ PDCURSES_TOP=$(R_PDCURSES_TOP)$(BACKSLASH) ADD_CURSES=Y ! ENDIF # GIT_AVAILABLE ! ELSE # NO internet available -# Your Makefile settings do not allow $(PDCDIST) to be obtained by +# Your Makefile settings do not allow $(R_PDCDIST) to be obtained by # git or by download. Check to see if it is available at one of # the expected locations already, with precedence given to ../submodules, # then ../lib. @@ -1593,8 +1608,8 @@ DLB = all : package -!IF "$(INTERNET_AVAILABLE)" == "Y" -!IF "$(GIT_AVAILABLE)" == "Y" +!IF "$(INTERNET_AVAILABLE)" == "1" +!IF "$(GIT_AVAILABLE)" == "1" $(LUASRC)lua.h: git submodule init $(SUBM)lua git submodule update $(SUBM)lua @@ -1829,7 +1844,7 @@ $(OUTL)makedefs.o: $(U)makedefs.c $(SRC)mdlib.c $(CONFIG_H) $(INCL)permonst.h \ # # This is awful, but it allows the GITHASH, GITBRANCH and GITPREFIX macros to be -# defined and utilized, using only build-in Windows and nmake commands, +# defined and utilized, using only built-in Windows and nmake commands, # as well as the necessary git commands. # # We build a temporary Makefile on-the-fly for compiling date.c and @@ -1839,44 +1854,42 @@ $(OTTY)date.o: $(HACKINCL) $(HACKSRC) $(HACKOBJ) $(ALLOBJTTY) $(CURSESOBJ) !IF "$(GIT_AVAILABLE)" == "1" @git rev-parse --verify HEAD 2>&1 >$(OTTY)date1.tmp @git rev-parse --abbrev-ref HEAD 2>&1 >$(OTTY)date2.tmp - @git config nethack.substprefix 2>&1 >$(OTTY)date3.tmp - @echo.>date.nmk - @echo OBJ = $(OBJTTY)>>date.nmk - @echo O = ^$(OBJTTY)^^^\>>date.nmk - @echo cc = $(cc)>>date.nmk - @echo CFLAGS = $(CFLAGS) ^\>>date.nmk - @for /F "usebackq" %%A IN ("$(OTTY)date1.tmp") DO @echo. -DNETHACK_GIT_SHA=\"%%A\" ^\>>date.nmk - @for /F "usebackq" %%A IN ("$(OTTY)date2.tmp") DO @echo. -DNETHACK_GIT_BRANCH=\"%%A\">>date.nmk - @for /F "usebackq" %%A IN ("$(OTTY)date3.tmp") DO @echo. -DNETHACK_GIT_PREFIX=\"%%A\">>date.nmk - @echo.>>date.nmk - @echo default: ^$(OTTY)date.o>>date.nmk - @echo.>>date.nmk - @echo ^$(OTTY)date.o: >>date.nmk - @echo. ^$(cc) ^$(CFLAGS) -Fo^$@ date.c>>date.nmk - @echo.>>date.nmk - @$(MAKE) /NOLOGO /A -f date.nmk +# @git config nethack.substprefix 2>&1 >$(OTTY)date3.tmp + @echo.>date-tty.nmk + @echo cc = $(cc)>>date-tty.nmk + @echo CFLAGS = $(CFLAGS) ^\>>date-tty.nmk + @for /F "usebackq" %%A IN ("$(OTTY)date1.tmp") DO @echo. -DNETHACK_GIT_SHA=\"%%A\" ^\>>date-tty.nmk + @for /F "usebackq" %%A IN ("$(OTTY)date2.tmp") DO @echo. -DNETHACK_GIT_BRANCH=\"%%A\">>date-tty.nmk +# @for /F "usebackq" %%A IN ("$(OTTY)date2.tmp") DO @echo. -DNETHACK_GIT_BRANCH=\"%%A\" ^\>>date-tty.nmk +# @for /F "usebackq" %%A IN ("$(OTTY)date3.tmp") DO @echo. -DNETHACK_GIT_PREFIX=\"%%A\">>date-tty.nmk + @echo.>>date-tty.nmk + @echo default: ^$(OTTY)date.o>>date-tty.nmk + @echo.>>date-tty.nmk + @echo ^$(OTTY)date.o: >>date-tty.nmk + @echo. ^$(cc) ^$(CFLAGS) -Fo^$@ date.c>>date-tty.nmk + @echo.>>date-tty.nmk + @$(MAKE) /NOLOGO /A OTTY=objtty\x64\ -f date-tty.nmk !ENDIF $(OGUI)date.o: $(HACKINCL) $(HACKSRC) $(HACKOBJ) $(ALLOBJGUI) !IF "$(GIT_AVAILABLE)" == "1" @git rev-parse --verify HEAD 2>&1 >$(OGUI)date1.tmp @git rev-parse --abbrev-ref HEAD 2>&1 >$(OGUI)date2.tmp - @git config nethack.substprefix 2>&1 >$(OTTY)date3.tmp - @echo.>date.nmk - @echo OBJ = $(OBJGUI)>>date.nmk - @echo O = ^$(OBJGUI)^^^\>>date.nmk - @echo cc = $(cc)>>date.nmk - @echo CFLAGS = $(CFLAGS) ^\>>date.nmk - @for /F "usebackq" %%A IN ("$(OGUI)date1.tmp") DO @echo. -DNETHACK_GIT_SHA=\"%%A\" ^\>>date.nmk - @for /F "usebackq" %%A IN ("$(OGUI)date2.tmp") DO @echo. -DNETHACK_GIT_BRANCH=\"%%A\">>date.nmk - @for /F "usebackq" %%A IN ("$(OTTY)date3.tmp") DO @echo. -DNETHACK_GIT_PREFIX=\"%%A\">>date.nmk - @echo.>>date.nmk - @echo default: ^$(OGUI)date.o>>date.nmk - @echo.>>date.nmk - @echo ^$(OGUI)date.o: >>date.nmk - @echo. ^$(cc) ^$(CFLAGS) -Fo^$@ date.c>>date.nmk - @echo.>>date.nmk - @$(MAKE) /NOLOGO /A -f date.nmk +# @git config nethack.substprefix 2>&1 >$(OGUI)date3.tmp + @echo.>date-gui.nmk + @echo cc = $(cc)>>date-gui.nmk + @echo CFLAGS = $(CFLAGS) ^\>>date-gui.nmk + @for /F "usebackq" %%A IN ("$(OGUI)date1.tmp") DO @echo. -DNETHACK_GIT_SHA=\"%%A\" ^\>>date-gui.nmk + @for /F "usebackq" %%A IN ("$(OGUI)date2.tmp") DO @echo. -DNETHACK_GIT_BRANCH=\"%%A\">>date-gui.nmk +# @for /F "usebackq" %%A IN ("$(OGUI)date2.tmp") DO @echo. -DNETHACK_GIT_BRANCH=\"%%A\" ^\>>date-gui.nmk +# @for /F "usebackq" %%A IN ("$(OGUI)date3.tmp") DO @echo. -DNETHACK_GIT_PREFIX=\"%%A\">>date-gui.nmk + @echo.>>date-gui.nmk + @echo default: ^$(OGUI)date.o>>date-gui.nmk + @echo.>>date-gui.nmk + @echo ^$(OGUI)date.o: >>date-gui.nmk + @echo. ^$(cc) ^$(CFLAGS) -Fo^$@ date.c>>date-gui.nmk + @echo.>>date-gui.nmk + @$(MAKE) /NOLOGO /A OGUI=$(OGUI) -f date-gui.nmk !ENDIF $(OGUI)sfbase.o: sfbase.c $(HACK_H) $(INCL)sfmacros.h From 29c300b4e0c212ab30b775c39b83af73d3ae0811 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 1 Jun 2026 20:44:17 -0400 Subject: [PATCH 421/702] stale engraving marker still showing at prompt --- doc/fixes5-0-1.txt | 5 ++++- src/engrave.c | 19 +++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 5b7180122..faec1ddd3 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -50,7 +50,10 @@ avoid calling costly_spot(), costly_adjacent(), find_byowner(), which all rely on shop_keeper() under the hood, in the midst of the level loading process before all the required data structures have been finalized - +if the hero has already been told that an engraving vanished, ensure that + the engraving marker isn't still showing when prompted for a + new engraving + Platform- and/or Interface-Specific Fixes ----------------------------------------- diff --git a/src/engrave.c b/src/engrave.c index 2e06ebc12..256439bc4 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -18,6 +18,7 @@ struct _doengrave_ctx { boolean disprefresh; /* TRUE if the display needs a refresh */ boolean frosted; /* TRUE if engraving on ice */ boolean adding; /* TRUE if adding to existing engraving */ + boolean hero_told_it_vanished; int ret; /* doengrave return value */ int type; /* Type of engraving made */ @@ -553,6 +554,7 @@ doengrave_ctx_init(struct _doengrave_ctx *de) de->zapwand = FALSE; de->disprefresh = FALSE; de->adding = FALSE; + de->hero_told_it_vanished = FALSE; de->ret = ECMD_OK; de->type = DUST; @@ -666,17 +668,21 @@ doengrave_sfx_item_WAN(struct _doengrave_ctx *de) case WAN_CANCELLATION: case WAN_MAKE_INVISIBLE: if (de->oep && de->oep->engr_type != HEADSTONE) { - if (!Blind) + if (!Blind) { pline_The("engraving on the %s vanishes!", surface(u.ux, u.uy)); + de->hero_told_it_vanished = TRUE; + } de->dengr = TRUE; } break; case WAN_TELEPORTATION: if (de->oep && de->oep->engr_type != HEADSTONE) { - if (!Blind) + if (!Blind) { pline_The("engraving on the %s vanishes!", surface(u.ux, u.uy)); + de->hero_told_it_vanished = TRUE; + } de->teleengr = TRUE; } break; @@ -1171,6 +1177,15 @@ doengrave(void) de->adding = (de->oep && !de->eow); doengrave_ctx_verb(de); + /* The old engraving indictor is probably still showing + * if, for example, the hero is invisible. Get rid of it + * right now, if the player has already been told that + * it vanished, before proceeding with a new engraving. + */ + if (de->hero_told_it_vanished) + newsym(u.ux, u.uy); + + /* Tell adventurer what is going on */ if (de->otmp != &hands_obj) You("%s the %s with %s%s.", de->everb, de->eloc, From 0aba284106f4bb11e06788b2488416fa73563fd7 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 2 Jun 2026 09:34:52 -0400 Subject: [PATCH 422/702] better placement for ensuring graving vanishes This is better placement for making the original engraving vanish when told that it vanishes; helps to ensure that it isn't showing for any next steps. also, a warning bit --- src/engrave.c | 25 ++++++++++++++++--------- src/shk.c | 1 + 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/engrave.c b/src/engrave.c index 256439bc4..c16db8150 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -1066,12 +1066,28 @@ doengrave(void) rloc_engr(de->oep); de->oep->eread = 0; de->oep->erevealed = 0; + /* The old engraving indicator is probably still showing + * if, for example, the hero is invisible. Get rid of it + * right now, if the player has already been told that + * it vanished. + */ + if (de->hero_told_it_vanished) + newsym(u.ux, u.uy); + de->disprefresh = TRUE; de->oep = (struct engr *) 0; } if (de->dengr) { del_engr(de->oep); de->oep = (struct engr *) 0; + /* The old engraving indicator is probably still showing + * if, for example, the hero is invisible. Get rid of it + * right now, if the player has already been told that + * it vanished. + */ + if (de->hero_told_it_vanished) + newsym(u.ux, u.uy); + de->disprefresh = TRUE; } /* Something has changed the engraving here */ @@ -1177,15 +1193,6 @@ doengrave(void) de->adding = (de->oep && !de->eow); doengrave_ctx_verb(de); - /* The old engraving indictor is probably still showing - * if, for example, the hero is invisible. Get rid of it - * right now, if the player has already been told that - * it vanished, before proceeding with a new engraving. - */ - if (de->hero_told_it_vanished) - newsym(u.ux, u.uy); - - /* Tell adventurer what is going on */ if (de->otmp != &hands_obj) You("%s the %s with %s%s.", de->everb, de->eloc, diff --git a/src/shk.c b/src/shk.c index fd451eaaf..749df40ae 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1085,6 +1085,7 @@ shop_keeper(char rmno) level_status.making, level_status.loading, level_status.shkready, level_status.ready); #endif + nhUse(hmm); } } return shkp; From 4fadc7c96f9ccae2f26e901704c3a112dc5d27a0 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 3 Jun 2026 10:53:02 +0300 Subject: [PATCH 423/702] Fix qt compile Some recent Makefile hints reorg messed with the Qt compile, it needs to be linked tiles --- sys/unix/hints/linux.500 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index dd2a2c3e3..2823d2fad 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -412,6 +412,9 @@ endif # WANT_WIN_X11 ifdef WANT_WIN_QT LINK = $(CXX) +ifndef CROSSCOMPILE +GENTILEOFILE = $(SRCDIR)/tile.o +endif ifdef WANT_WIN_QT4 QTCXXFLAGS += $(sort $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config QtGui --cflags)) -DQT_NO_SOUND=1 WINLIB += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config QtGui --libs) From 49d3d5ecd8aa38c106f4f2c936537c0c02f469a0 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 3 Jun 2026 13:27:19 -0400 Subject: [PATCH 424/702] Makefile.utl would allow hints file to specify TARGET_CC --- sys/unix/Makefile.utl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sys/unix/Makefile.utl b/sys/unix/Makefile.utl index 89fc4899b..4370ad61d 100644 --- a/sys/unix/Makefile.utl +++ b/sys/unix/Makefile.utl @@ -223,13 +223,13 @@ DLBOBJS = dlb_main.o $(OBJDIR)/dlb.o $(OALLOC) # files or on the command line. TARGETPFX= -TARGET_CC = $(CC) -TARGET_CFLAGS = $(CFLAGS) $(CSTD) -TARGET_CLINK = $(CLINK) -TARGET_LFLAGS = $(LFLAGS) -TARGET_CXX = $(CXX) -TARGET_CXXFLAGS = $(CXXFLAGS) -TARGET_AR = $(AR) +TARGET_CC ?= $(CC) +TARGET_CFLAGS ?= $(CFLAGS) $(CSTD) +TARGET_CLINK ?= $(CLINK) +TARGET_LFLAGS ?= $(LFLAGS) +TARGET_CXX ?= $(CXX) +TARGET_CXXFLAGS ?= $(CXXFLAGS) +TARGET_AR ?= $(AR) # # dependencies for makedefs From 4b65360d3cf0a92ef2d6fa790487892067e387eb Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 3 Jun 2026 13:45:49 -0400 Subject: [PATCH 425/702] allow hints file to specify compiler for Lua --- sys/unix/Makefile.top | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 80b89870d..2d283d338 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -27,6 +27,7 @@ GAME = nethack # GAME = nethack.prg #GAMEUID = games #GAMEGRP = bin +TARGET_CC ?= $(CC) # Permissions - some places use setgid instead of setuid, for instance. # See also the option "SECURE" in include/config.h. @@ -144,7 +145,7 @@ $(GAME): lua_support lua_support: include/nhlua.h @true $(LUATOP)/liblua.a: $(LUAHEADERS)/lua.h - ( cd $(LUATOP) && make $(LUAMAKEFLAGS) a ) + ( cd $(LUATOP) && make $(LUAMAKEFLAGS) CC=$(TARGET_CC) a ) lib/lua/$(LUABASELIB): $(LUALIBBUILT) @( if test -d lib/lua ; then true ; else mkdir -p lib/lua ; fi ) cp $(LUATOP)/liblua.a $@ @@ -164,7 +165,7 @@ lib/lua-$(LUA_VERSION)/src/lua.h: @false luabin: ( cd $(LUATOP) \ - && make $(LUAMAKEFILES) all && cd $(LUA2NHTOP) ) + && make $(LUAMAKEFILES) CC=$(TARGET_CC) all && cd $(LUA2NHTOP) ) # This is only needed for some internal tools. nhlua: From d4e2c577ba6353a5628783db3cb66a2e4a015085 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 3 Jun 2026 13:49:43 -0400 Subject: [PATCH 426/702] follow-up: CC override was in MAKELUAFLAGS Just make sure it is uing the correct one remove the addition in the previous commit --- sys/unix/Makefile.top | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 2d283d338..046cf4844 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -125,7 +125,7 @@ RECOVERBIN = recover LUAHEADERS ?= lib/lua-$(LUA_VERSION)/src LUATESTTARGET ?= $(LUAHEADERS)/lua.h LUATOP = $(LUAHEADERS) -LUAMAKEFLAGS = CC='$(CC)' SYSCFLAGS='$(SYSCFLAGS)' +LUAMAKEFLAGS = CC='$(TARGET_CC)' SYSCFLAGS='$(SYSCFLAGS)' LUA2NHTOP ?= ../../.. LUABASELIB ?= liblua-$(LUA_VERSION).a LUATOPLIB ?= lib/lua/$(LUABASELIB) @@ -145,7 +145,7 @@ $(GAME): lua_support lua_support: include/nhlua.h @true $(LUATOP)/liblua.a: $(LUAHEADERS)/lua.h - ( cd $(LUATOP) && make $(LUAMAKEFLAGS) CC=$(TARGET_CC) a ) + ( cd $(LUATOP) && make $(LUAMAKEFLAGS) a ) lib/lua/$(LUABASELIB): $(LUALIBBUILT) @( if test -d lib/lua ; then true ; else mkdir -p lib/lua ; fi ) cp $(LUATOP)/liblua.a $@ @@ -165,7 +165,7 @@ lib/lua-$(LUA_VERSION)/src/lua.h: @false luabin: ( cd $(LUATOP) \ - && make $(LUAMAKEFILES) CC=$(TARGET_CC) all && cd $(LUA2NHTOP) ) + && make $(LUAMAKEFILES) all && cd $(LUA2NHTOP) ) # This is only needed for some internal tools. nhlua: From eb4d09871740fbcac1bd6669134283bd22f59b03 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 3 Jun 2026 18:58:12 +0300 Subject: [PATCH 427/702] X11: Obey timed_delay I noticed a strange thing where the X11 windowport didn't show the tethered thrown aklys animation correctly. Interestingly, other stuff, such as zapped wands did show the path. I didn't bother trying to figure out what the core was doing differently, as the animation worked in all the other windowports, so instead fix the issue in X11, so it behaves the same as all the others. The issue seems to be that the event loop exited on any(?) event, instead of our specific timed event. So, create our event with a magic id number, and exit only when we encounter that. Also: Obey the timed_delay option, and change the delay from 30ms to 50ms, like in other windowports. --- doc/fixes5-0-1.txt | 1 + include/winX.h | 2 ++ win/X11/winX.c | 13 ++++++++----- win/X11/winmap.c | 4 ++-- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index faec1ddd3..cf4641a86 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -172,6 +172,7 @@ Windows: with SELECTSAVE don't display error messages to a regular player dealt with external to the game, so try not to annoy tty: allow custom glyph colors if they're basic 16 nethack colors on terminals with less than 256 colors +X11: obey timed_delay General New Features diff --git a/include/winX.h b/include/winX.h index 495a2d29f..e26faf5b8 100644 --- a/include/winX.h +++ b/include/winX.h @@ -287,6 +287,8 @@ struct xwindow { * and dumplog message history */ #define YN_NO_DEFAULT 2U /* don't convert quitchars to 0 or ESC to q/n/def */ +#define DELAY_EVENT_ID 66 /* arbitrary byte value */ + /* Window variables (winX.c). */ extern struct xwindow window_list[MAX_WINDOWS]; extern XtAppContext app_context; /* context of application */ diff --git a/win/X11/winX.c b/win/X11/winX.c index 24fb4fcff..f4725399b 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -1750,6 +1750,7 @@ d_timeout(XtPointer client_data, XtIntervalId *id) mesg->type = ClientMessage; mesg->message_type = XA_STRING; mesg->format = 8; + mesg->data.b[0] = DELAY_EVENT_ID; XSendEvent(XtDisplay(window_list[WIN_MAP].w), XtWindow(window_list[WIN_MAP].w), False, NoEventMask, (XEvent *) mesg); @@ -1766,11 +1767,13 @@ X11_delay_output(void) { if (!x_inited) return; - - (void) XtAppAddTimeOut(app_context, 30L, d_timeout, (XtPointer) 0); - - /* The timeout function will enable the event loop exit. */ - (void) x_event(EXIT_ON_SENT_EVENT); +#ifdef TIMED_DELAY + if (flags.nap && !iflags.debug_fuzzer) { + (void) XtAppAddTimeOut(app_context, 50L, d_timeout, (XtPointer) 0); + /* The timeout function will enable the event loop exit. */ + (void) x_event(EXIT_ON_SENT_EVENT); + } +#endif } /* X11_hangup ------------------------------------------------------------- */ diff --git a/win/X11/winmap.c b/win/X11/winmap.c index 7c2dbfcac..97e17eaee 100644 --- a/win/X11/winmap.c +++ b/win/X11/winmap.c @@ -1969,9 +1969,9 @@ x_event(int exit_condition) try_test: switch (exit_condition) { case EXIT_ON_SENT_EVENT: { - XAnyEvent *any = (XAnyEvent *) &event; + XClientMessageEvent *cle = (XClientMessageEvent *) &event; - if (any->send_event) { + if (cle->send_event && cle->data.b[0] == DELAY_EVENT_ID) { retval = 0; keep_going = FALSE; } From 8182cf39826ef83c3eb09993af8eb44c2a006b45 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 3 Jun 2026 16:29:51 -0400 Subject: [PATCH 428/702] required after TIMED_DELAY fix previously committed --- sys/unix/hints/macOS.500 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/unix/hints/macOS.500 b/sys/unix/hints/macOS.500 index 679fa415d..d84baa7c6 100755 --- a/sys/unix/hints/macOS.500 +++ b/sys/unix/hints/macOS.500 @@ -121,7 +121,8 @@ NHCFLAGS+=-DDLB NHCFLAGS+=-DHACKDIR=\"$(HACKDIR)\" NHCFLAGS+=-DDEFAULT_WINDOW_SYS=\"$(WANT_DEFAULT)\" NHCFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE -#NHCFLAGS+=-DTIMED_DELAY +#define this after Qt timed_delay fix +NHCFLAGS+=-DTIMED_DELAY #NHCFLAGS+=-DDUMPLOG #NHCFLAGS+=-DCONFIG_ERROR_SECURE=FALSE NHCFLAGS+=-DGREPPATH=\"/usr/bin/grep\" From cd047cc6b81be9928a8f9bdd062e09ea36ebf5d3 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 3 Jun 2026 16:38:53 -0400 Subject: [PATCH 429/702] thinko in comment --- sys/unix/hints/macOS.500 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/unix/hints/macOS.500 b/sys/unix/hints/macOS.500 index d84baa7c6..be6402ace 100755 --- a/sys/unix/hints/macOS.500 +++ b/sys/unix/hints/macOS.500 @@ -121,7 +121,7 @@ NHCFLAGS+=-DDLB NHCFLAGS+=-DHACKDIR=\"$(HACKDIR)\" NHCFLAGS+=-DDEFAULT_WINDOW_SYS=\"$(WANT_DEFAULT)\" NHCFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE -#define this after Qt timed_delay fix +#define this after X11 timed_delay fix NHCFLAGS+=-DTIMED_DELAY #NHCFLAGS+=-DDUMPLOG #NHCFLAGS+=-DCONFIG_ERROR_SECURE=FALSE From fd0a4ec878d7c51d73d01dbcddbc13fc1395e80d Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 3 Jun 2026 17:44:49 -0400 Subject: [PATCH 430/702] optlist.h maintenance A very small number of boolean options had drifted, such that their initval setting did not match its opt_in or opt_out value. Correct that, by ensuring opt_in or opt_out reflects what was actually happening. The only option whose initial value is changing as a result of this is timed_delay. It was listed as an opt_out option, but was not being initialized as such. Now it is. This makes the Mac X11 throwing animations work correctly with the earlier timed_delay option adjustments for X11. There was nothing displaying on Mac X11 after those earlier changes, unless the timed_delay option was turned on. Going forward, for boolean options, setting opt_in or opt_out is all that is required, as that was the original intention of those fields. It will take precedence if they fall out of sync again. --- include/optlist.h | 16 ++++++++-------- include/windconf.h | 2 ++ src/options.c | 16 +++++++++++++++- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/include/optlist.h b/include/optlist.h index c723e4981..fdc92d1d7 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -137,7 +137,7 @@ static int optfn_##a(int, int, boolean, char *, char *); "your starting alignment (lawful, neutral, or chaotic)") /* end of special ordering; remainder of entries are in alphabetical order */ - NHOPTB(accessiblemsg, Advanced, 0, opt_out, set_in_game, + NHOPTB(accessiblemsg, Advanced, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &a11y.accessiblemsg, Term_False, "add location information to messages") NHOPTB(acoustics, Advanced, 0, opt_out, set_in_game, @@ -171,7 +171,7 @@ static int optfn_##a(int, int, boolean, char *, char *); NHOPTB(armorstatus, Advanced, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &flags.armorstatus, Term_False, "summarize currently worn armor in a status field") - NHOPTB(ascii_map, Advanced, 0, opt_in, set_in_game, + NHOPTB(ascii_map, Advanced, 0, opt_out, set_in_game, ascii_map_Def, Yes, No, No, NoAlias, &iflags.wc_ascii_map, Term_False, "show map as text") NHOPTO("autocompletions", Advanced, o_autocomplete, BUFSZ, opt_in, @@ -185,7 +185,7 @@ static int optfn_##a(int, int, boolean, char *, char *); NHOPTB(autoopen, Behavior, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias, &flags.autoopen, Term_False, "walking into a door attempts to open it") - NHOPTB(autopickup, Behavior, 0, opt_out, set_in_game, + NHOPTB(autopickup, Behavior, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &flags.pickup, Term_False, "automatically pick up objects") NHOPTO("autopickup exceptions", Behavior, o_autopickup_exceptions, BUFSZ, @@ -237,7 +237,7 @@ static int optfn_##a(int, int, boolean, char *, char *); NHOPTB(cmdassist, Behavior, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias, &iflags.cmdassist, Term_False, "give help for errors on direction input") - NHOPTB(color, Map, 0, opt_in, set_in_game, + NHOPTB(color, Map, 0, opt_out, set_in_game, On, Yes, No, No, "colour", &iflags.wc_color, Term_False, "use color in map") NHOPTB(confirm, Advanced, 0, opt_out, set_in_game, @@ -456,7 +456,7 @@ static int optfn_##a(int, int, boolean, char *, char *); Yes, Yes, No, Yes, "use_menu_glyphs", "show object symbols in menus") #ifdef TTY_GRAPHICS - NHOPTB(menu_overlay, Advanced, 0, opt_in, set_in_game, + NHOPTB(menu_overlay, Advanced, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias, &iflags.menu_overlay, Term_False, "menus overlay and align to right") #else @@ -768,7 +768,7 @@ static int optfn_##a(int, int, boolean, char *, char *); "display game turns in status line") #ifdef TIMED_DELAY NHOPTB(timed_delay, Map, 0, opt_out, set_in_game, - Off, Yes, No, No, NoAlias, &flags.nap, Term_False, + On, Yes, No, No, NoAlias, &flags.nap, Term_False, "use delay when pausing for display effects") #else NHOPTB(timed_delay, Map, 0, opt_in, set_in_config, @@ -791,11 +791,11 @@ static int optfn_##a(int, int, boolean, char *, char *); On, Yes, No, No, NoAlias, &flags.travelcmd, Term_False, "enable traveling via mouse click") #ifdef DEBUG - NHOPTB(travel_debug, Advanced, 0, opt_out, set_wizonly, + NHOPTB(travel_debug, Advanced, 0, opt_in, set_wizonly, Off, Yes, No, No, NoAlias, &iflags.trav_debug, Term_False, (char *)0) #else - NHOPTB(travel_debug, Advanced, 0, opt_out, set_wizonly, + NHOPTB(travel_debug, Advanced, 0, opt_in, set_wizonly, Off, No, No, No, NoAlias, (boolean *) 0, Term_False, (char *)0) #endif diff --git a/include/windconf.h b/include/windconf.h index 0f493ca76..cf113aee1 100644 --- a/include/windconf.h +++ b/include/windconf.h @@ -39,6 +39,8 @@ #define IDLECHECKPOINT #endif +#define TIMED_DELAY + /* * ----------------------------------------------------------------- * The remaining code shouldn't need modification. diff --git a/src/options.c b/src/options.c index 1cbb64ac5..4f0cd9eea 100644 --- a/src/options.c +++ b/src/options.c @@ -7414,8 +7414,22 @@ allopt_array_init(void) memcpy(allopt, allopt_init, sizeof(allopt)); determine_ambiguities(); for (i = 0; allopt[i].name; i++) { - if (allopt[i].addr) + if (allopt[i].addr) { +#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED \ + && NH_DEVEL_STATUS != NH_STATUS_POSTRELEASE) + if (allopt[i].opttyp == BoolOpt + && allopt[i].initval != allopt[i].opt_in_out) + if (wizard) + impossible("conflicting option init for %s: %s is %s, %s is %s", + allopt[i].name, + "opt_in_out", + allopt[i].opt_in_out ? "on" : "off", "initval", + allopt[i].initval ? "on" : "off"); +#endif + if (allopt[i].opttyp == BoolOpt) + allopt[i].initval = allopt[i].opt_in_out; *(allopt[i].addr) = allopt[i].initval; + } } heed_all_options(); /* From 006867cf0da2df9bf77486ad9f05ba30cee7375a Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 3 Jun 2026 19:48:46 -0400 Subject: [PATCH 431/702] catch-up entry for fixes5-0-1.txt --- doc/fixes5-0-1.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index cf4641a86..90990b988 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -148,6 +148,7 @@ libnh: sys/unix/hints/macOS.500 in the WANT_LIBNH block, add an explicit $(GAME) is overridden to empty, the regular `recover: $(GAME)` chain no longer triggers `lua_support`, so include/nhlua.h never gets generated and recover.c's transitive #include of hack.h fails +libnh: export GLYPH_PILETOP_OFF constant (pr #1562 by avgas3) Linux: add WANT_SYSTEM_LUA=1 support to the linux.500 hints files and its included files, making it possible to avoid the 'fetch-lua' step and the subsequent compiling of Lua; it tries to use use From 63cb04f410033b31a2a427f45a4b38e376fd9bb1 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Thu, 4 Jun 2026 12:23:33 +0200 Subject: [PATCH 432/702] hints: keep host CC for top-level lua in cross builds LUAMAKEFLAGS uses TARGET_CC, which the cross hints override to the target compiler. The top-level liblua.a is a host-side prerequisite of the generated include/nhlua.h; the target lua is built separately under BUILD_TARGET_LUA. --- sys/unix/hints/include/cross-post.500 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/unix/hints/include/cross-post.500 b/sys/unix/hints/include/cross-post.500 index 2d6ef3546..db5eebe6f 100644 --- a/sys/unix/hints/include/cross-post.500 +++ b/sys/unix/hints/include/cross-post.500 @@ -351,6 +351,10 @@ $(TARGETPFX)giftiles.o : ../win/share/giftiles.c endif # CROSS_SHARED # ifdef CROSS +ifdef MAKEFILE_TOP +# top-level liblua.a is a host-side build; keep TARGET_CC out of it +LUAMAKEFLAGS = CC='$(CC)' SYSCFLAGS='$(SYSCFLAGS)' +endif # MAKEFILE_TOP $(TARGETPFX)hacklib.a: $(TARGETPFX)hacklib.o $(TARGET_AR) $(TARGET_ARFLAGS) $@ $(TARGETPFX)hacklib.o ifdef MAKEFILE_UTL From ecfa78f9740b520c4a86395f60b51f2992783adc Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 4 Jun 2026 07:21:22 -0400 Subject: [PATCH 433/702] cherry-pick for CROSS; use "?=" for MAKELUAFLAGS Using "?=" allows a hints file to set that ahead of Makefile --- sys/unix/Makefile.top | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 046cf4844..136e6997e 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -125,7 +125,7 @@ RECOVERBIN = recover LUAHEADERS ?= lib/lua-$(LUA_VERSION)/src LUATESTTARGET ?= $(LUAHEADERS)/lua.h LUATOP = $(LUAHEADERS) -LUAMAKEFLAGS = CC='$(TARGET_CC)' SYSCFLAGS='$(SYSCFLAGS)' +LUAMAKEFLAGS ?= CC='$(TARGET_CC)' SYSCFLAGS='$(SYSCFLAGS)' LUA2NHTOP ?= ../../.. LUABASELIB ?= liblua-$(LUA_VERSION).a LUATOPLIB ?= lib/lua/$(LUABASELIB) From 2edf27f0f0edb6fb75ae8f68ee788ee51220e9ca Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 4 Jun 2026 15:36:12 -0400 Subject: [PATCH 434/702] aklys fixes track which locations had updates that could be seen in tmp_at() to aid in cleanup. ensure that nothing is shown for places that the hero can't see (internal buglist entry 3161). adjust several aklys messages to better reflect the tethering aspect. --- src/display.c | 77 ++++++++++++++++++++++++++++++++----------- src/dothrow.c | 90 +++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 125 insertions(+), 42 deletions(-) diff --git a/src/display.c b/src/display.c index 6f4f5f74a..e1e301905 100644 --- a/src/display.c +++ b/src/display.c @@ -1164,6 +1164,7 @@ tether_glyph(coordxy x, coordxy y) static struct tmp_glyph { coord saved[TMP_AT_MAX_GLYPHS]; /* previously updated positions */ + boolean shown_on_map[TMP_AT_MAX_GLYPHS]; int sidx; /* index of next unused slot in saved[] */ int style; /* either DISP_BEAM or DISP_FLASH or DISP_ALWAYS */ int glyph; /* glyph to use when printing */ @@ -1175,6 +1176,7 @@ tmp_at(coordxy x, coordxy y) { static struct tmp_glyph *tglyph = (struct tmp_glyph *) 0; struct tmp_glyph *tmp; + boolean suppress_show = FALSE; switch (x) { case DISP_BEAM: @@ -1220,27 +1222,42 @@ tmp_at(coordxy x, coordxy y) int i; /* Erase (reset) from source to end */ - for (i = 0; i < tglyph->sidx; i++) + for (i = 0; i < tglyph->sidx; i++) { newsym(tglyph->saved[i].x, tglyph->saved[i].y); + tglyph->shown_on_map[i] = FALSE; + } } else if (tglyph->style == DISP_TETHER) { int i; if (y == BACKTRACK && tglyph->sidx > 1) { /* backtrack */ for (i = tglyph->sidx - 1; i > 0; i--) { - newsym(tglyph->saved[i].x, tglyph->saved[i].y); - show_glyph(tglyph->saved[i - 1].x, - tglyph->saved[i - 1].y, tglyph->glyph); - flush_screen(0); /* make sure it shows up */ - nh_delay_output(); + if (tglyph->shown_on_map[i]) { + newsym(tglyph->saved[i].x, tglyph->saved[i].y); + tglyph->shown_on_map[i] = FALSE; + } + if (cansee(tglyph->saved[i - 1].x, + tglyph->saved[i - 1].y)) { + tglyph->shown_on_map[i - 1] = TRUE; + show_glyph(tglyph->saved[i - 1].x, + tglyph->saved[i - 1].y, tglyph->glyph); + flush_screen(0); /* make sure it shows up */ + nh_delay_output(); + } } tglyph->sidx = 1; } - for (i = 0; i < tglyph->sidx; i++) - newsym(tglyph->saved[i].x, tglyph->saved[i].y); + for (i = 0; i < tglyph->sidx; i++) { + if (tglyph->shown_on_map[i]) + newsym(tglyph->saved[i].x, tglyph->saved[i].y); + } } else { /* DISP_FLASH or DISP_ALWAYS */ - if (tglyph->sidx) /* been called at least once */ - newsym(tglyph->saved[0].x, tglyph->saved[0].y); + if (tglyph->sidx) { /* been called at least once */ + if (tglyph->shown_on_map[0]) { + newsym(tglyph->saved[0].x, tglyph->saved[0].y); + tglyph->shown_on_map[0] = FALSE; + } + } } /* tglyph->sidx = 0; -- about to be freed, so not necessary */ tmp = tglyph->prev; @@ -1253,10 +1270,13 @@ tmp_at(coordxy x, coordxy y) if (!isok(x, y)) break; if (tglyph->style == DISP_BEAM || tglyph->style == DISP_ALL) { - if (tglyph->style != DISP_ALL && !cansee(x, y)) - break; if (tglyph->sidx >= TMP_AT_MAX_GLYPHS) break; /* too many locations */ + if (tglyph->style != DISP_ALL && !cansee(x, y)) { + tglyph->shown_on_map[tglyph->sidx] = FALSE; + suppress_show = TRUE; + break; + } /* save pos for later erasing */ tglyph->saved[tglyph->sidx].x = x; tglyph->saved[tglyph->sidx].y = y; @@ -1269,27 +1289,48 @@ tmp_at(coordxy x, coordxy y) px = tglyph->saved[tglyph->sidx - 1].x; py = tglyph->saved[tglyph->sidx - 1].y; - show_glyph(px, py, tether_glyph(px, py)); + if (cansee(px, py)) { + tglyph->shown_on_map[tglyph->sidx - 1] = TRUE; + show_glyph(px, py, tether_glyph(px, py)); + } else { + tglyph->shown_on_map[tglyph->sidx - 1] = FALSE; + suppress_show = TRUE; + } } /* save pos for later use or erasure */ tglyph->saved[tglyph->sidx].x = x; tglyph->saved[tglyph->sidx].y = y; + if (!cansee(x, y)) { + tglyph->shown_on_map[tglyph->sidx] = FALSE; + suppress_show = TRUE; + } else { + /* happens at end of this default case */ + tglyph->shown_on_map[tglyph->sidx] = TRUE; + } tglyph->sidx += 1; } else { /* DISP_FLASH/ALWAYS */ - if (tglyph - ->sidx) { /* not first call, so reset previous pos */ + if (tglyph->sidx) { /* not first call, so reset previous pos */ newsym(tglyph->saved[0].x, tglyph->saved[0].y); + tglyph->shown_on_map[0] = FALSE; tglyph->sidx = 0; /* display is presently up to date */ } - if (!cansee(x, y) && tglyph->style != DISP_ALWAYS) + if (!cansee(x, y) && tglyph->style != DISP_ALWAYS) { + suppress_show = TRUE; + tglyph->shown_on_map[0] = FALSE; break; + } else { + /* happens at end of this default case */ + tglyph->shown_on_map[0] = TRUE; + } tglyph->saved[0].x = x; tglyph->saved[0].y = y; tglyph->sidx = 1; } - show_glyph(x, y, tglyph->glyph); /* show it */ - flush_screen(0); /* make sure it shows up */ + if (!suppress_show) { + show_glyph(x, y, tglyph->glyph); /* show it */ + flush_screen(0); /* make sure it shows up */ + } break; } /* end switch */ } diff --git a/src/dothrow.c b/src/dothrow.c index 1d729ef69..82028f321 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1729,46 +1729,88 @@ throwit( } else { int dmg = rn2(2); + if (tethered_weapon) { + /* It's tethered, so it usually returns to your + * inventory, despite impairment */ + obj = addinv_before(obj, oldslot); + encumber_msg(); + /* addinv autoquivers an aklys if quiver is empty; + if obj is quivered, remove it before wielding */ + if (obj->owornmask & W_QUIVER) + setuqwep((struct obj *) 0); +#if 0 + setuwep(obj); + set_twoweap(twoweap); /* u.twoweap = twoweap */ +#endif + if (cansee(gb.bhitpos.x, gb.bhitpos.y)) + newsym(gb.bhitpos.x, gb.bhitpos.y); + } if (!dmg) { - pline(Blind ? "%s lands %s your %s." - : "%s back to you, landing %s your %s.", - Blind ? Something : Tobjnam(obj, "return"), - Levitation ? "beneath" : "at", - makeplural(body_part(FOOT))); + if (tethered_weapon) { + pline(Blind ? "%s%s back and is left" + " dangling from your %s." + : "%s is left dangling from your %s.", + Blind ? "Your tethered weapon" : Tobjnam(obj, "return"), + Blind ? " snaps" : "", + body_part(ARM)); + } else { + pline(Blind + ? "%s lands %s your %s." + : "%s back to you, landing %s your %s.", + Blind ? Something : Tobjnam(obj, "return"), + Levitation ? "beneath" : "at", + makeplural(body_part(FOOT))); + } } else { dmg += rnd(3); - pline(Blind ? "%s your %s!" + if (tethered_weapon) { + Your("tethered %s your %s!", + Blind ? "weapon returns and hits" : Tobjnam(obj, "hit"), + body_part(ARM)); + } else { + pline( + Blind + ? "%s your %s!" : "%s back toward you, hitting your %s!", - Tobjnam(obj, Blind ? "hit" : "fly"), - body_part(ARM)); + Tobjnam(obj, Blind ? "hit" : "fly"), + body_part(ARM)); + } if (obj->oartifact) (void) artifact_hit((struct monst *) 0, &gy.youmonst, obj, &dmg, 0); losehp(Maybe_Half_Phys(dmg), killer_xname(obj), KILLED_BY); } - - if (u.uswallow) { - swallowit(obj); - return; + if (!tethered_weapon) { + if (u.uswallow) { + swallowit(obj); + return; + } + if (!ship_object(obj, u.ux, u.uy, FALSE)) + dropy(obj); + } else { + pline_The("%s tether releases from your %s!", + s_suffix(simpleonames(obj)), body_part(ARM)); } - if (!ship_object(obj, u.ux, u.uy, FALSE)) - dropy(obj); } throwit_return(TRUE); return; } else { - if (tethered_weapon) + if (tethered_weapon) { tmp_at(DISP_END, 0); - /* when this location is stepped on, the weapon will be - auto-picked up due to 'obj->how_lost' of LOST_THROWN; - addinv() prevents thrown Mjollnir from being placed - into the quiver slot, but an aklys will end up there if - that slot is empty at the time; since hero will need to - explicitly rewield the weapon to get throw-and-return - capability back anyway, quivered or not shouldn't matter */ - pline("%s to return!", Tobjnam(obj, "fail")); - + /* when this location is stepped on, the weapon will be + auto-picked up due to 'obj->how_lost' of LOST_THROWN; + addinv() prevents thrown Mjollnir from being placed + into the quiver slot, but an aklys will end up there if + that slot is empty at the time; since hero will need to + explicitly rewield the weapon to get throw-and-return + capability back anyway, quivered or not shouldn't + matter */ + pline("The tether snaps off your %s!", + body_part(ARM)); + } else { + pline("%s to return!", Tobjnam(obj, "fail")); + } if (u.uswallow) { swallowit(obj); return; From 93e7928a6f98bccd3a8608db7a342273838e1d0a Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 4 Jun 2026 15:44:41 -0400 Subject: [PATCH 435/702] follow-up: fixes5-0-1.txt update --- doc/fixes5-0-1.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 90990b988..850c7576b 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -53,6 +53,8 @@ avoid calling costly_spot(), costly_adjacent(), find_byowner(), which if the hero has already been told that an engraving vanished, ensure that the engraving marker isn't still showing when prompted for a new engraving +aklys path shouldn't be shown for locations that the hero cannot see +keep the player better-informed about status of the tether on their weapon Platform- and/or Interface-Specific Fixes From 6c1d7c074d069a97777fbe6d38273f481c806a08 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 4 Jun 2026 15:54:11 -0400 Subject: [PATCH 436/702] follow-up: do the flush_screen(0) at end always --- src/display.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/display.c b/src/display.c index e1e301905..ffb9b2cbc 100644 --- a/src/display.c +++ b/src/display.c @@ -1327,10 +1327,10 @@ tmp_at(coordxy x, coordxy y) tglyph->sidx = 1; } - if (!suppress_show) { + if (!suppress_show) show_glyph(x, y, tglyph->glyph); /* show it */ - flush_screen(0); /* make sure it shows up */ - } + + flush_screen(0); /* make sure it shows up */ break; } /* end switch */ } From 3d46ee9523b5f72f5e2491259cbe6ac23c55e2fe Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 4 Jun 2026 15:57:53 -0400 Subject: [PATCH 437/702] follow-up from yesterday: ascii_map done uniquely --- include/optlist.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/optlist.h b/include/optlist.h index fdc92d1d7..9631efd15 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -171,7 +171,9 @@ static int optfn_##a(int, int, boolean, char *, char *); NHOPTB(armorstatus, Advanced, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &flags.armorstatus, Term_False, "summarize currently worn armor in a status field") - NHOPTB(ascii_map, Advanced, 0, opt_out, set_in_game, + /* this one needs unique handling because different window ports + expect different defaults */ + NHOPTB(ascii_map, Advanced, 0, ascii_map_Def, set_in_game, ascii_map_Def, Yes, No, No, NoAlias, &iflags.wc_ascii_map, Term_False, "show map as text") NHOPTO("autocompletions", Advanced, o_autocomplete, BUFSZ, opt_in, From 19f0ae07cc66d456b8695d9548ec32d3bca28180 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 4 Jun 2026 16:55:33 -0400 Subject: [PATCH 438/702] follow-up: regression reported, so comment out until researched --- src/options.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/options.c b/src/options.c index 4f0cd9eea..e5d2623e2 100644 --- a/src/options.c +++ b/src/options.c @@ -7426,9 +7426,11 @@ allopt_array_init(void) allopt[i].opt_in_out ? "on" : "off", "initval", allopt[i].initval ? "on" : "off"); #endif - if (allopt[i].opttyp == BoolOpt) +#if 0 + if (allopt[i].opttyp == BoolOpt && i != opt_ascii_map) allopt[i].initval = allopt[i].opt_in_out; - *(allopt[i].addr) = allopt[i].initval; +#endif + *(allopt[i].addr) = allopt[i].initval; } } heed_all_options(); From cdd42b88a2d6f1add4f5ff5a95cfd96d489df0c9 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 4 Jun 2026 19:21:26 -0400 Subject: [PATCH 439/702] curl was not returning an error to shell on 404 error Add the --fail option to curl to make it do so. --- sys/unix/Makefile.top | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 136e6997e..239e148d7 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -345,6 +345,10 @@ LUA_URL :=www.lua.org/ftp LUA_URL_MIRROR :=www.tecgraf.puc-rio.br/lua/mirror/ftp LUA_URL_NHD :=www.nethack.org/download/thirdparty LUA_URL_list:=$(LUA_URL) $(LUA_URL_MIRROR) $(LUA_URL_NHD) +# +#CURL := curl +#ask curl to return a failure code if error 404 is encountered +CURL := curl --fail fetch-lua-mirror: LUA_URL_list:=$(LUA_URL_MIRROR) fetch-lua-mirror: fetch-Lua @@ -374,7 +378,7 @@ fetch-Lua: if [ $$curlstatus -ne 0 ]; then \ luaurl=https://$$1/$$luafile; \ echo Trying $$luaurl; \ - curl -R -O $$luaurl; \ + $(CURL) -R -O $$luaurl; \ curlstatus=$$?; \ if [ $$curlstatus -eq 0 ]; then \ if [ ! -z "$$shac" ]; then \ @@ -401,7 +405,7 @@ fetch-Lua: fetch-lua-http: ( mkdir -p lib && cd lib && \ - curl -R -O http://$(LUA_URL)/lua-$(LUA_VERSION).tar.gz && \ + $(CURL) -R -O http://$(LUA_URL)/lua-$(LUA_VERSION).tar.gz && \ tar zxf lua-$(LUA_VERSION).tar.gz && \ rm -f lua-$(LUA_VERSION).tar.gz ) From 9566605ba2c24ab5055f5ba2cce1f559de81e2f8 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 4 Jun 2026 20:01:46 -0400 Subject: [PATCH 440/702] don't attempt with a blank host name in fetch-lua After exhausting the three URL's for fetch-lua, exit with error, don't try to connect to a URL with a blank host name. --- sys/unix/Makefile.top | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 239e148d7..3a96459b9 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -344,7 +344,8 @@ dofiles-nodlb: LUA_URL :=www.lua.org/ftp LUA_URL_MIRROR :=www.tecgraf.puc-rio.br/lua/mirror/ftp LUA_URL_NHD :=www.nethack.org/download/thirdparty -LUA_URL_list:=$(LUA_URL) $(LUA_URL_MIRROR) $(LUA_URL_NHD) +LUA_CEASE_TRYING := __cease_trying__ +LUA_URL_list:=$(LUA_URL) $(LUA_URL_MIRROR) $(LUA_URL_NHD) $(LUA_CEASE_TRYING) # #CURL := curl #ask curl to return a failure code if error 404 is encountered @@ -375,13 +376,14 @@ fetch-Lua: mkdir -p lib && cd lib && \ while [ $$# -gt 0 ]; do \ shift; \ - if [ $$curlstatus -ne 0 ]; then \ - luaurl=https://$$1/$$luafile; \ - echo Trying $$luaurl; \ - $(CURL) -R -O $$luaurl; \ - curlstatus=$$?; \ - if [ $$curlstatus -eq 0 ]; then \ - if [ ! -z "$$shac" ]; then \ + if [ "$$1" != "$(LUA_CEASE_TRYING)" ]; then \ + if [ $$curlstatus -ne 0 ]; then \ + luaurl=https://$$1/$$luafile; \ + echo Trying $$luaurl; \ + $(CURL) -R -O $$luaurl; \ + curlstatus=$$?; \ + if [ $$curlstatus -eq 0 ]; then \ + if [ ! -z "$$shac" ]; then \ CHKSUMS=../submodules/CHKSUMS; \ CHKSUMSTMP=../submodules/CHKSUMS.tmp; \ fgrep $$luafile < $$CHKSUMS > $$CHKSUMSTMP; \ @@ -391,10 +393,13 @@ fetch-Lua: echo Checking integrity of $$luafile with $$shac; \ $$shac -w --ignore-missing -c $$CHKSUMSTMP < $$luafile; \ fi; \ + fi; \ + tar zxf $$luafile && \ + rm -f $$luafile; \ fi; \ - tar zxf $$luafile && \ - rm -f $$luafile; \ fi; \ + else \ + exit 1; \ fi; \ done; \ true ) From 0ea0de530119966f601bba2267b90dd7e8d63b87 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 4 Jun 2026 20:14:29 -0400 Subject: [PATCH 441/702] follow-up --- sys/unix/Makefile.top | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 3a96459b9..788a7dfc5 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -399,7 +399,8 @@ fetch-Lua: fi; \ fi; \ else \ - exit 1; \ + echo All three sites failed!; \ + break; \ fi; \ done; \ true ) From 784692fd408517fc164cb634e7a6560748d85cc8 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 4 Jun 2026 20:22:50 -0400 Subject: [PATCH 442/702] yet another follow-up for Makefile.top fetch-Lua --- sys/unix/Makefile.top | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 788a7dfc5..5c6ca214b 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -392,6 +392,7 @@ fetch-Lua: else \ echo Checking integrity of $$luafile with $$shac; \ $$shac -w --ignore-missing -c $$CHKSUMSTMP < $$luafile; \ + break; \ fi; \ fi; \ tar zxf $$luafile && \ From 1c649facea979c433918c6f3c0f978005908fb4d Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 4 Jun 2026 20:32:50 -0400 Subject: [PATCH 443/702] one more follow-up --- sys/unix/Makefile.top | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 5c6ca214b..c73f42ab1 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -392,16 +392,12 @@ fetch-Lua: else \ echo Checking integrity of $$luafile with $$shac; \ $$shac -w --ignore-missing -c $$CHKSUMSTMP < $$luafile; \ - break; \ fi; \ fi; \ tar zxf $$luafile && \ rm -f $$luafile; \ fi; \ fi; \ - else \ - echo All three sites failed!; \ - break; \ fi; \ done; \ true ) From c20f5acbb5b9f058983cb42ad8ed6f42924461e9 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 4 Jun 2026 21:16:17 -0400 Subject: [PATCH 444/702] Revert "one more follow-up" This reverts commit 1c649facea979c433918c6f3c0f978005908fb4d. --- sys/unix/Makefile.top | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index c73f42ab1..5c6ca214b 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -392,12 +392,16 @@ fetch-Lua: else \ echo Checking integrity of $$luafile with $$shac; \ $$shac -w --ignore-missing -c $$CHKSUMSTMP < $$luafile; \ + break; \ fi; \ fi; \ tar zxf $$luafile && \ rm -f $$luafile; \ fi; \ fi; \ + else \ + echo All three sites failed!; \ + break; \ fi; \ done; \ true ) From d1f9c1741805c33dc45252617504b9a32f1784a9 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 4 Jun 2026 21:16:44 -0400 Subject: [PATCH 445/702] Revert "yet another follow-up for Makefile.top fetch-Lua" This reverts commit 784692fd408517fc164cb634e7a6560748d85cc8. --- sys/unix/Makefile.top | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 5c6ca214b..788a7dfc5 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -392,7 +392,6 @@ fetch-Lua: else \ echo Checking integrity of $$luafile with $$shac; \ $$shac -w --ignore-missing -c $$CHKSUMSTMP < $$luafile; \ - break; \ fi; \ fi; \ tar zxf $$luafile && \ From f2fc324befb2a1994c632a2b9fc4903ca3f91174 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 4 Jun 2026 21:17:15 -0400 Subject: [PATCH 446/702] Revert "follow-up" This reverts commit 0ea0de530119966f601bba2267b90dd7e8d63b87. --- sys/unix/Makefile.top | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 788a7dfc5..3a96459b9 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -399,8 +399,7 @@ fetch-Lua: fi; \ fi; \ else \ - echo All three sites failed!; \ - break; \ + exit 1; \ fi; \ done; \ true ) From 2950bd85cbd1d75965898d25b473f8f1136d4d55 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 4 Jun 2026 21:17:41 -0400 Subject: [PATCH 447/702] Revert "don't attempt with a blank host name in fetch-lua" This reverts commit 9566605ba2c24ab5055f5ba2cce1f559de81e2f8. --- sys/unix/Makefile.top | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 3a96459b9..239e148d7 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -344,8 +344,7 @@ dofiles-nodlb: LUA_URL :=www.lua.org/ftp LUA_URL_MIRROR :=www.tecgraf.puc-rio.br/lua/mirror/ftp LUA_URL_NHD :=www.nethack.org/download/thirdparty -LUA_CEASE_TRYING := __cease_trying__ -LUA_URL_list:=$(LUA_URL) $(LUA_URL_MIRROR) $(LUA_URL_NHD) $(LUA_CEASE_TRYING) +LUA_URL_list:=$(LUA_URL) $(LUA_URL_MIRROR) $(LUA_URL_NHD) # #CURL := curl #ask curl to return a failure code if error 404 is encountered @@ -376,14 +375,13 @@ fetch-Lua: mkdir -p lib && cd lib && \ while [ $$# -gt 0 ]; do \ shift; \ - if [ "$$1" != "$(LUA_CEASE_TRYING)" ]; then \ - if [ $$curlstatus -ne 0 ]; then \ - luaurl=https://$$1/$$luafile; \ - echo Trying $$luaurl; \ - $(CURL) -R -O $$luaurl; \ - curlstatus=$$?; \ - if [ $$curlstatus -eq 0 ]; then \ - if [ ! -z "$$shac" ]; then \ + if [ $$curlstatus -ne 0 ]; then \ + luaurl=https://$$1/$$luafile; \ + echo Trying $$luaurl; \ + $(CURL) -R -O $$luaurl; \ + curlstatus=$$?; \ + if [ $$curlstatus -eq 0 ]; then \ + if [ ! -z "$$shac" ]; then \ CHKSUMS=../submodules/CHKSUMS; \ CHKSUMSTMP=../submodules/CHKSUMS.tmp; \ fgrep $$luafile < $$CHKSUMS > $$CHKSUMSTMP; \ @@ -393,13 +391,10 @@ fetch-Lua: echo Checking integrity of $$luafile with $$shac; \ $$shac -w --ignore-missing -c $$CHKSUMSTMP < $$luafile; \ fi; \ - fi; \ - tar zxf $$luafile && \ - rm -f $$luafile; \ fi; \ + tar zxf $$luafile && \ + rm -f $$luafile; \ fi; \ - else \ - exit 1; \ fi; \ done; \ true ) From 28ca8b26c3cda5085016c3e3a00c612d202275e5 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Fri, 5 Jun 2026 16:30:09 +0200 Subject: [PATCH 448/702] rename MACOS9 to MAC68K to avoid confusion with modern macOS --- include/config.h | 12 ++++++------ include/config1.h | 8 ++++---- include/dlb.h | 2 +- include/extern.h | 2 +- include/flag.h | 2 +- include/global.h | 2 +- include/optlist.h | 6 +++--- include/tcap.h | 2 +- include/winprocs.h | 6 +++--- include/wintty.h | 6 +++--- outdated/include/mac-carbon.h | 2 +- outdated/include/mac-qt.h | 2 +- outdated/include/mac-term.h | 2 +- outdated/include/macconf.h | 6 +++--- outdated/include/system.h | 12 ++++++------ outdated/win/gem/wingem.c | 4 ++-- src/allmain.c | 2 +- src/cfgfiles.c | 8 ++++---- src/eat.c | 2 +- src/end.c | 2 +- src/files.c | 30 +++++++++++++++--------------- src/getpos.c | 4 ++-- src/mdlib.c | 4 ++-- src/options.c | 12 ++++++------ src/shknam.c | 2 +- src/windows.c | 12 ++++++------ util/dlb_main.c | 2 +- util/makedefs.c | 18 +++++++++--------- win/curses/cursmain.c | 2 +- win/share/tilemap.c | 2 +- win/tty/getline.c | 2 +- win/tty/wintty.c | 4 ++-- 32 files changed, 92 insertions(+), 92 deletions(-) diff --git a/include/config.h b/include/config.h index 21556bcc4..9b5216377 100644 --- a/include/config.h +++ b/include/config.h @@ -36,7 +36,7 @@ /* Hint: if you're not developing code, don't define ULTRIX_PROTO. */ -#include "config1.h" /* should auto-detect MSDOS, MACOS9, AMIGA, and WIN32 */ +#include "config1.h" /* should auto-detect MSDOS, MAC68K, AMIGA, and WIN32 */ /* * Consolidated version, patchlevel, development status. @@ -67,8 +67,8 @@ * tty, X11, mac, amii, BeOS, Qt, Gem, Gnome, shim */ -/* MACOS9 also means MAC windows */ -#ifdef MACOS9 +/* MAC68K also means MAC windows */ +#ifdef MAC68K #ifndef AUX #define DEFAULT_WINDOW_SYS "mac" #endif @@ -339,7 +339,7 @@ #define ENTRYMAX 100 /* must be >= 10 */ #endif #ifndef PERS_IS_UID -#if !defined(MICRO) && !defined(MACOS9) && !defined(WIN32) +#if !defined(MICRO) && !defined(MAC68K) && !defined(WIN32) #define PERS_IS_UID 1 /* delete for PERSMAX per name; now per uid */ #else #define PERS_IS_UID 0 @@ -434,7 +434,7 @@ */ #define INSURANCE /* allow crashed game recovery */ -#if !defined(MACOS9) && !defined(SHIM_GRAPHICS) +#if !defined(MAC68K) && !defined(SHIM_GRAPHICS) #define CHDIR /* delete if no chdir() available */ #endif @@ -533,7 +533,7 @@ typedef unsigned char uchar; #define MACRO_CPATH /* use clear_path macros instead of functions */ #endif -#if !defined(MACOS9) +#if !defined(MAC68K) #if !defined(NOCLIPPING) #define CLIPPING /* allow smaller screens -- ERS */ #endif diff --git a/include/config1.h b/include/config1.h index 190c47f97..ecf3ce7b0 100644 --- a/include/config1.h +++ b/include/config1.h @@ -45,23 +45,23 @@ #endif #ifdef macintosh /* Auto-defined symbol for MPW compilers (sc and mrc) */ -#define MACOS9 +#define MAC68K #endif #ifdef THINK_C /* Think C auto-defined symbol */ -#define MACOS9 +#define MAC68K #define NEED_VARARGS #endif #ifdef __MWERKS__ /* defined by Metrowerks' Codewarrior compiler */ #ifndef __BEOS__ /* BeOS */ -#define MACOS9 +#define MAC68K #endif #define NEED_VARARGS #define USE_STDARG #endif -#if defined(MACOS9) || defined(__BEOS__) +#if defined(MAC68K) || defined(__BEOS__) #define DLB #undef UNIX #endif diff --git a/include/dlb.h b/include/dlb.h index b090a6f8d..a94a3aab4 100644 --- a/include/dlb.h +++ b/include/dlb.h @@ -9,7 +9,7 @@ #ifdef DLB /* implementations */ -#if defined(MACOS9) && !defined(MACOS9_CROSS) +#if defined(MAC68K) && !defined(MAC68K_CROSS) #define DLBRSRC /* use Mac resources */ #else #define DLBLIB /* use a set of external files */ diff --git a/include/extern.h b/include/extern.h index 5e8b9fa26..194547d2b 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1461,7 +1461,7 @@ extern boolean stumble_on_door_mimic(coordxy, coordxy); extern int doopen_indir(coordxy, coordxy); extern int doclose(void); -#ifdef MACOS9 +#ifdef MAC68K /* outdated functions removed */ /* ### macfile.c ### */ /* ### macmain.c ### */ diff --git a/include/flag.h b/include/flag.h index 541343d41..205de909d 100644 --- a/include/flag.h +++ b/include/flag.h @@ -510,7 +510,7 @@ struct instance_flags { #ifdef MAC_GRAPHICS_ENV #define large_font obsolete #endif -#ifdef MACOS9 +#ifdef MAC68K #define popup_dialog wc_popup_dialog #endif #define preload_tiles wc_preload_tiles diff --git a/include/global.h b/include/global.h index d5e3981c8..e3bac1ea4 100644 --- a/include/global.h +++ b/include/global.h @@ -185,7 +185,7 @@ typedef uchar nhsym; #ifdef AMIGA #define PORT_ID "Amiga" #endif -#ifdef MACOS9 +#ifdef MAC68K #define PORT_ID "Mac" #endif #ifdef __APPLE__ diff --git a/include/optlist.h b/include/optlist.h index 9631efd15..67ace7b32 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -363,7 +363,7 @@ static int optfn_##a(int, int, boolean, char *, char *); NHOPTB(herecmd_menu, Advanced, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &iflags.herecmd_menu, Term_False, "show commands available in this location") -#if defined(MACOS9) +#if defined(MAC68K) NHOPTC(hicolor, Advanced, 15, opt_in, set_in_config, No, Yes, No, No, NoAlias, "same as palette, only order is reversed") @@ -396,7 +396,7 @@ static int optfn_##a(int, int, boolean, char *, char *); NHOPTB(idlecheckpoint, Advanced, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &iflags.idlecheckpoint, Term_Off, "update checkpoint file if input is idle for 10 seconds") -#ifndef MACOS9 +#ifndef MAC68K NHOPTB(ignintr, Advanced, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &flags.ignintr, Term_False, "ignore interrupt signals") @@ -548,7 +548,7 @@ static int optfn_##a(int, int, boolean, char *, char *); No, Yes, No, No, NoAlias, "the inventory order of the items in your pack") #ifdef CHANGE_COLOR -#ifndef MACOS9 /* not old Mac OS9 */ +#ifndef MAC68K /* not old Mac OS9 */ NHOPTC(palette, Advanced, 15, opt_in, set_gameview, No, Yes, Yes, No, "hicolor", "palette (adjust an RGB color in palette (color/R-G-B)") diff --git a/include/tcap.h b/include/tcap.h index ca6282723..785458ed1 100644 --- a/include/tcap.h +++ b/include/tcap.h @@ -13,7 +13,7 @@ #endif /* might display need graphics code? */ -#if !defined(AMIGA) && !defined(TOS) && !defined(MACOS9) +#if !defined(AMIGA) && !defined(TOS) && !defined(MAC68K) #if defined(TERMLIB) || defined(OS2) || defined(MSDOS) #define ASCIIGRAPH #endif diff --git a/include/winprocs.h b/include/winprocs.h index 7ec7de01a..fea60cf0b 100644 --- a/include/winprocs.h +++ b/include/winprocs.h @@ -76,7 +76,7 @@ struct window_procs { void (*win_delay_output)(void); #ifdef CHANGE_COLOR void (*win_change_color)(int, long, int); -#ifdef MACOS9 +#ifdef MAC68K void (*win_change_background)(int); short (*win_set_font_name)(winid, char *); #endif @@ -162,7 +162,7 @@ extern #define nh_delay_output (*windowprocs.win_delay_output) #ifdef CHANGE_COLOR #define change_color (*windowprocs.win_change_color) -#ifdef MACOS9 +#ifdef MAC68K #define change_background (*windowprocs.win_change_background) #define set_font_name (*windowprocs.win_set_font_name) #endif @@ -394,7 +394,7 @@ struct chain_procs { void (*win_delay_output)(CARGS); #ifdef CHANGE_COLOR void (*win_change_color)(CARGS, int, long, int); -#ifdef MACOS9 +#ifdef MAC68K void (*win_change_background)(CARGS, int); short (*win_set_font_name)(CARGS, winid, char *); #endif diff --git a/include/wintty.h b/include/wintty.h index ea62459d0..f59b87229 100644 --- a/include/wintty.h +++ b/include/wintty.h @@ -280,7 +280,7 @@ extern void tty_number_pad(int); extern void tty_delay_output(void); #ifdef CHANGE_COLOR extern void tty_change_color(int color, long rgb, int reverse); -#ifdef MACOS9 +#ifdef MAC68K extern void tty_change_background(int white_or_black); extern short set_tty_font_name(winid, char *); #endif @@ -331,7 +331,7 @@ extern char *tgetstr(const char *, char **); extern char *tgoto(const char *, int, int); #endif /* NO_TERMCAP_HEADERS */ #else /* ?NO_TERMS */ -#ifdef MACOS9 +#ifdef MAC68K #ifdef putchar #undef putchar #undef putc @@ -342,7 +342,7 @@ extern char *tgoto(const char *, int, int); extern int term_putc(int c); extern int term_flush(void *desc); extern int term_puts(const char *str); -#endif /* MACOS9 */ +#endif /* MAC68K */ #if defined(MSDOS) || defined(WIN32) #if defined(SCREEN_BIOS) || defined(SCREEN_DJGPPFAST) || defined(WIN32) #undef putchar diff --git a/outdated/include/mac-carbon.h b/outdated/include/mac-carbon.h index d4d957e99..e77e2223f 100644 --- a/outdated/include/mac-carbon.h +++ b/outdated/include/mac-carbon.h @@ -21,7 +21,7 @@ * set "Prefix File" to include/mac-carbon.h */ -#define MACOS9 +#define MAC68K #define MAC #undef UNIX diff --git a/outdated/include/mac-qt.h b/outdated/include/mac-qt.h index 866105d9c..41f61d9f9 100644 --- a/outdated/include/mac-qt.h +++ b/outdated/include/mac-qt.h @@ -22,7 +22,7 @@ */ #undef MAC -#undef MACOS9 +#undef MAC68K #define UNIX #define BSD diff --git a/outdated/include/mac-term.h b/outdated/include/mac-term.h index 003ad6f8b..3aa0c3aa5 100644 --- a/outdated/include/mac-term.h +++ b/outdated/include/mac-term.h @@ -23,7 +23,7 @@ /* Stuff needed for the core of NetHack */ #undef MAC -#undef MACOS9 +#undef MAC68K #define UNIX #define BSD #define __FreeBSD__ /* Darwin is based on FreeBSD */ diff --git a/outdated/include/macconf.h b/outdated/include/macconf.h index 76b7548d8..596609d16 100644 --- a/outdated/include/macconf.h +++ b/outdated/include/macconf.h @@ -3,7 +3,7 @@ /*-Copyright (c) Kevin Hugo, 2004. */ /* NetHack may be freely redistributed. See license for details. */ -#ifdef MACOS9 +#ifdef MAC68K #ifndef MACCONF_H #define MACCONF_H @@ -16,7 +16,7 @@ * __MWERKS__ Metrowerks' Codewarrior compiler * * We use these early in config.h to define some needed symbols, - * including MACOS9. + * including MAC68K. # # The Metrowerks compiler defines __STDC__ (which sets NHSTC) and uses # WIDENED_PROTOTYPES (defined if UNWIDENED_PROTOTYPES is undefined and @@ -123,4 +123,4 @@ extern void error(const char *, ...); #define MAC_GRAPHICS_ENV #endif /* ! MACCONF_H */ -#endif /* MACOS9 */ +#endif /* MAC68K */ diff --git a/outdated/include/system.h b/outdated/include/system.h index 936fbdb42..bd7045620 100644 --- a/outdated/include/system.h +++ b/outdated/include/system.h @@ -21,7 +21,7 @@ /* some old may not define off_t and size_t; if your system is * one of these, define them by hand below */ -#if (defined(VMS) && !defined(__GNUC__)) || defined(MACOS9) +#if (defined(VMS) && !defined(__GNUC__)) || defined(MAC68K) #include #else #ifndef AMIGA @@ -41,7 +41,7 @@ typedef unsigned int size_t; #endif #endif /* MICRO && !TOS */ -#if defined(__TURBOC__) || defined(MACOS9) +#if defined(__TURBOC__) || defined(MAC68K) #include /* time_t is not in */ #endif #if defined(ULTRIX) && !(defined(ULTRIX_PROTO) || defined(NHSTDC)) @@ -200,7 +200,7 @@ extern int unlink(const char *); #endif /* AZTEC_50 && __GNUC__ */ -#ifdef MACOS9 +#ifdef MAC68K #ifndef __CONDITIONALMACROS__ /* universal headers */ extern int close(int); /* unistd.h */ extern int read(int, char *, int); /* unistd.h */ @@ -313,7 +313,7 @@ extern long fork(void); /* The POSIX string.h is required to define all the mem* and str* functions */ #include #else -#if defined(SYSV) || defined(VMS) || defined(MACOS9) || defined(SUNOS4) +#if defined(SYSV) || defined(VMS) || defined(MAC68K) || defined(SUNOS4) #if defined(NHSTDC) || (defined(VMS) && !defined(ANCIENT_VAXC)) #if !defined(_AIX32) && !(defined(SUNOS4) && defined(__STDC__)) /* Solaris unbundled cc (acc) */ @@ -423,7 +423,7 @@ extern char *strncat(char *, const char *, size_t); extern char *strpbrk(const char *, const char *); #ifdef NOT_C99 -#if defined(SYSV) || defined(MICRO) || defined(MACOS9) || defined(VMS) \ +#if defined(SYSV) || defined(MICRO) || defined(MAC68K) || defined(VMS) \ || defined(HPUX) extern char *strchr(const char *, int); extern char *strrchr(const char *, int); @@ -435,7 +435,7 @@ extern char *rindex(const char *, int); extern int strcmp(const char *, const char *); extern int strncmp(const char *, const char *, size_t); -#if defined(MICRO) || defined(MACOS9) || defined(VMS) +#if defined(MICRO) || defined(MAC68K) || defined(VMS) extern size_t strlen(const char *); #else #ifdef HPUX diff --git a/outdated/win/gem/wingem.c b/outdated/win/gem/wingem.c index b41991f93..65e599885 100644 --- a/outdated/win/gem/wingem.c +++ b/outdated/win/gem/wingem.c @@ -63,7 +63,7 @@ struct window_procs Gem_procs = { Gem_getlin, Gem_get_ext_cmd, Gem_number_pad, Gem_delay_output, #ifdef CHANGE_COLOR /* the Mac uses a palette device */ Gem_change_color, -#ifdef MACOS9 +#ifdef MAC68K Gem_change_background, Gem_set_font_name, #endif Gem_get_color_string, @@ -76,7 +76,7 @@ struct window_procs Gem_procs = { genl_can_suspend_no, }; -#ifdef MACOS9 +#ifdef MAC68K void * Gem_change_background(dummy) int dummy; diff --git a/src/allmain.c b/src/allmain.c index 90c4932ad..75e54027a 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -739,7 +739,7 @@ init_sound_disp_gamewindows(void) ever having been used, use it here to pacify the Qt interface */ start_menu(WIN_INVEN, menu_behavior), end_menu(WIN_INVEN, (char *) 0); -#ifdef MACOS9 +#ifdef MAC68K /* This _is_ the right place for this - maybe we will * have to split init_sound_disp_gamewindows into * create_gamewindows and show_gamewindows to get rid of this ifdef... diff --git a/src/cfgfiles.c b/src/cfgfiles.c index 438c65478..f3138920c 100644 --- a/src/cfgfiles.c +++ b/src/cfgfiles.c @@ -9,7 +9,7 @@ #include "dlb.h" #include -#if (!defined(MACOS9) && !defined(O_WRONLY) && !defined(AZTEC_C)) \ +#if (!defined(MAC68K) && !defined(O_WRONLY) && !defined(AZTEC_C)) \ || defined(USE_FCNTL) #include #endif @@ -131,7 +131,7 @@ static const char *default_configfile = #ifdef UNIX ".nethackrc"; #else -#if defined(MACOS9) || defined(__BEOS__) +#if defined(MAC68K) || defined(__BEOS__) "NetHack Defaults"; #else #if defined(MSDOS) || defined(WIN32) @@ -280,7 +280,7 @@ fopen_config_file(const char *filename, int src) } /* fall through to standard names */ -#if defined(MICRO) || defined(MACOS9) || defined(__BEOS__) || defined(WIN32) +#if defined(MICRO) || defined(MAC68K) || defined(__BEOS__) || defined(WIN32) set_configfile_name(fqname(default_configfile, CONFIGPREFIX, 0)); if ((fp = fopen(configfile, "r")) != (FILE *) 0) { return fp; @@ -371,7 +371,7 @@ fopen_config_file(const char *filename, int src) wait_synch(); } #endif /* !VMS => Unix */ -#endif /* !(MICRO || MACOS9 || __BEOS__ || WIN32) */ +#endif /* !(MICRO || MAC68K || __BEOS__ || WIN32) */ return (FILE *) 0; } diff --git a/src/eat.c b/src/eat.c index 05b41f62a..c7f0bd58c 100644 --- a/src/eat.c +++ b/src/eat.c @@ -2176,7 +2176,7 @@ fprefx(struct obj *otmp) } else if (otmp->otyp == APPLE && otmp->cursed && !Sleep_resistance) { ; /* skip core joke; feedback deferred til fpostfx() */ -#if defined(MACOS9) || defined(MACOS) +#if defined(MAC68K) || defined(MACOS) /* KMH -- Why should Unix have all the fun? We check MACOS before UNIX to get the Apple-specific apple message; the '#if UNIX' code will still kick in for pear. */ diff --git a/src/end.c b/src/end.c index 27040abe7..45eace422 100644 --- a/src/end.c +++ b/src/end.c @@ -1679,7 +1679,7 @@ nh_terminate(int status) program_state.in_moveloop = 0; /* won't be returning to normal play */ l_nhcore_call(NHCORE_GAME_EXIT); -#ifdef MACOS9 +#ifdef MAC68K getreturn("to exit"); #endif /* don't bother to try to release memory if we're in panic mode, to diff --git a/src/files.c b/src/files.c index a4748790e..88e5adfa2 100644 --- a/src/files.c +++ b/src/files.c @@ -38,7 +38,7 @@ #include "wintty.h" /* more() */ #endif -#if (!defined(MACOS9) && !defined(O_WRONLY) && !defined(AZTEC_C)) \ +#if (!defined(MAC68K) && !defined(O_WRONLY) && !defined(AZTEC_C)) \ || defined(USE_FCNTL) #include #endif @@ -133,7 +133,7 @@ extern boolean get_user_home_folder(char *, size_t); #endif #endif -#ifdef MACOS9 +#ifdef MAC68K #undef unlink #define unlink macunlink #endif @@ -643,7 +643,7 @@ create_levelfile(int lev, char errbuf[]) nhfp->fd = open(fq_lock, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, FCMASK); #else -#ifdef MACOS9 +#ifdef MAC68K nhfp->fd = maccreat(fq_lock, LEVL_TYPE); #else nhfp->fd = creat(fq_lock, FCMASK); @@ -689,7 +689,7 @@ open_levelfile(int lev, char errbuf[]) nhfp->fpdef = (FILE *) 0; } if (nhfp && nhfp->structlevel) { -#ifdef MACOS9 +#ifdef MAC68K nhfp->fd = macopen(fq_lock, O_RDONLY | O_BINARY, LEVL_TYPE); #else nhfp->fd = open(fq_lock, O_RDONLY | O_BINARY, 0); @@ -872,12 +872,12 @@ create_bonesfile(d_level *lev, char **bonesid, char errbuf[]) O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, _SH_DENYRW, _S_IREAD | _S_IWRITE); #else /* ?MICRO || WIN32 */ -/* implies UNIX or MACOS9 (MACOS9 is for OS9 or earlier) */ -#ifdef MACOS9 +/* implies UNIX or MAC68K (MAC68K is for OS9 or earlier) */ +#ifdef MAC68K nhfp->fd = maccreat(file, BONE_TYPE); #else nhfp->fd = creat(file, FCMASK); -#endif /* ?MACOS9 */ +#endif /* ?MAC68K */ #endif /* ?MICRO || WIN32 */ if (nhfp->fd < 0) failed = errno; @@ -967,7 +967,7 @@ open_bonesfile(d_level *lev, char **bonesid) #endif } if (nhfp->structlevel) { -#if defined(MACOS9) +#if defined(MAC68K) nhfp->fd = macopen(fq_bones, O_RDONLY | O_BINARY, BONE_TYPE); #elif defined(WIN32) err = _sopen_s(&nhfp->fd, fq_bones, _O_RDONLY | _O_BINARY, @@ -1136,7 +1136,7 @@ set_error_savefile(void) } Strcat(gs.SAVEF, ".e;1"); #else -#ifdef MACOS9 +#ifdef MAC68K Strcat(gs.SAVEF, "-e"); #else Strcat(gs.SAVEF, ".e"); @@ -1175,8 +1175,8 @@ create_savefile(void) nhfp->fd = open(fq_save, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK); #else /* !MICRO && !WIN32 */ -/* UNIX || MACOS9 implied (MACOS9 is OS9 or earlier only) */ -#ifdef MACOS9 +/* UNIX || MAC68K implied (MAC68K is OS9 or earlier only) */ +#ifdef MAC68K nhfp->fd = maccreat(fq_save, SAVE_TYPE); #else nhfp->fd = creat(fq_save, FCMASK); @@ -1231,7 +1231,7 @@ open_savefile(void) nhfp->fplog = fopen("open-savefile.log", "w"); #endif } -#ifdef MACOS9 +#ifdef MAC68K nhfp->fd = macopen(fq_save, O_RDONLY | O_BINARY, SAVE_TYPE); #else nhfp->fd = open(fq_save, O_RDONLY | O_BINARY, 0); @@ -2496,7 +2496,7 @@ fopen_wizkit_file(void) #endif } -#if defined(MICRO) || defined(MACOS9) || defined(__BEOS__) || defined(WIN32) +#if defined(MICRO) || defined(MAC68K) || defined(__BEOS__) || defined(WIN32) if ((fp = fopen(fqname(gw.wizkit, CONFIGPREFIX, 0), "r")) != (FILE *) 0) return fp; #else @@ -2775,13 +2775,13 @@ check_recordfile(const char *dir UNUSED_if_not_OS2_CODEVIEW) } #else /* MICRO || WIN32*/ -#ifdef MACOS9 +#ifdef MAC68K /* Create the "record" file, if necessary */ fq_record = fqname(RECORD, SCOREPREFIX, 0); fd = macopen(fq_record, O_RDWR | O_CREAT, TEXT_TYPE); if (fd != -1) macclose(fd); -#endif /* MACOS9 */ +#endif /* MAC68K */ #endif /* MICRO || WIN32*/ } diff --git a/src/getpos.c b/src/getpos.c index 68be1f8a1..25813d6a4 100644 --- a/src/getpos.c +++ b/src/getpos.c @@ -852,7 +852,7 @@ getpos(coord *ccp, boolean force, const char *goal) #endif curs(WIN_MAP, cx, cy); flush_screen(0); -#ifdef MACOS9 +#ifdef MAC68K lock_mouse_cursor(TRUE); #endif lock_mouse_buttons(TRUE); @@ -1149,7 +1149,7 @@ getpos(coord *ccp, boolean force, const char *goal) flush_screen(0); } exitgetpos: -#ifdef MACOS9 +#ifdef MAC68K lock_mouse_cursor(FALSE); #endif lock_mouse_buttons(FALSE); diff --git a/src/mdlib.c b/src/mdlib.c index b7e0810c6..dfa3fb72b 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -151,7 +151,7 @@ static struct win_information window_opts[] = { #ifdef GNOME_GRAPHICS /* unmaintained/defunct */ { "Gnome", "Gnome", TRUE }, #endif -#ifdef MACOS9 /* defunct OS 9 interface */ +#ifdef MAC68K /* defunct OS 9 interface */ { "mac", "Mac", TRUE }, #endif #ifdef GEM_GRAPHICS /* defunct Atari interface */ @@ -536,7 +536,7 @@ static const char *const build_opts[] = { "screen clipping", #endif #ifdef NO_TERMS -#ifdef MACOS9 +#ifdef MAC68K "screen control via mactty", #endif #ifdef SCREEN_BIOS diff --git a/src/options.c b/src/options.c index e5d2623e2..bfcef4576 100644 --- a/src/options.c +++ b/src/options.c @@ -2731,7 +2731,7 @@ optfn_palette( } #if 0 -/* old MACOS9 OS9 code */ +/* old MAC68K OS9 code */ staticfn int optfn_palette( int optidx UNUSED, int req, boolean negated UNUSED, @@ -5108,7 +5108,7 @@ pfxfn_font(int optidx, int req, boolean negated, char *opts, char *op) if (opttype > 0 && (op = string_for_opt(opts, FALSE)) != empty_optstr) { wc_set_font_name(opttype, op); -#ifdef MACOS9 +#ifdef MAC68K set_font_name(opttype, op); #endif return optn_ok; @@ -6792,12 +6792,12 @@ complain_about_duplicate(int optidx) { char buf[BUFSZ]; -#ifdef MACOS9 +#ifdef MAC68K /* the Mac has trouble dealing with the output of messages while * processing the config file. That should get fixed one day. * For now just return. */ -#else /* !MACOS9 */ +#else /* !MAC68K */ buf[0] = '\0'; if (using_alias) Sprintf(buf, " (via alias: %s)", allopt[optidx].alias); @@ -6805,7 +6805,7 @@ complain_about_duplicate(int optidx) (allopt[optidx].opttyp == CompOpt) ? "compound" : "boolean", allopt[optidx].name, buf); -#endif /* ?MACOS9 */ +#endif /* ?MAC68K */ return; } @@ -9450,7 +9450,7 @@ static const char *opt_intro[] = { " NetHack Options Help:", "", #define CONFIG_SLOT 3 /* fill in next value at run-time */ (char *) 0, -#if !defined(MICRO) && !defined(MACOS9) +#if !defined(MICRO) && !defined(MAC68K) "or use `NETHACKOPTIONS=\"\"' in your environment", #endif "( is a list of options separated by commas)", diff --git a/src/shknam.c b/src/shknam.c index d93f6adab..393204ca5 100644 --- a/src/shknam.c +++ b/src/shknam.c @@ -128,7 +128,7 @@ static const char *const shktools[] = { #ifdef WIN32 "Lexa", "Niod", #endif -#ifdef MACOS9 +#ifdef MAC68K "Nhoj-lee", "Evad\'kh", "Ettaw-noj", "Tsew-mot", "Ydna-s", "Yao-hang", "Tonbar", "Kivenhoug", "Llardom", #endif diff --git a/src/windows.c b/src/windows.c index f8490f9b5..8337d9bbe 100644 --- a/src/windows.c +++ b/src/windows.c @@ -22,7 +22,7 @@ extern struct window_procs Qt_procs; #ifdef GEM_GRAPHICS /*#include "wingem.h"*/ #endif -#ifdef MACOS9 +#ifdef MAC68K extern struct window_procs mac_procs; #endif #ifdef BEOS_GRAPHICS @@ -111,7 +111,7 @@ static struct win_choices { #ifdef GEM_GRAPHICS { &Gem_procs, win_Gem_init CHAINR(0) }, #endif -#ifdef MACOS9 +#ifdef MAC68K { &mac_procs, 0 CHAINR(0) }, #endif #ifdef BEOS_GRAPHICS @@ -543,7 +543,7 @@ staticfn void hup_cliparound(int, int); #endif #ifdef CHANGE_COLOR staticfn void hup_change_color(int, long, int); -#ifdef MACOS9 +#ifdef MAC68K staticfn short hup_set_font_name(winid, char *); #endif staticfn char *hup_get_color_string(void); @@ -592,7 +592,7 @@ static struct window_procs hup_procs = { hup_void_ndecl, /* nh_delay_output */ #ifdef CHANGE_COLOR hup_change_color, -#ifdef MACOS9 +#ifdef MAC68K hup_void_fdecl_int, /* change_background */ hup_set_font_name, #endif @@ -795,14 +795,14 @@ hup_change_color(int color UNUSED, long rgb UNUSED, int reverse UNUSED) return; } -#ifdef MACOS9 +#ifdef MAC68K /*ARGSUSED*/ staticfn short hup_set_font_name(winid window UNUSED, char *fontname UNUSED) { return 0; } -#endif /* MACOS9 */ +#endif /* MAC68K */ staticfn char * hup_get_color_string(void) diff --git a/util/dlb_main.c b/util/dlb_main.c index a77277eea..3b0aaf421 100644 --- a/util/dlb_main.c +++ b/util/dlb_main.c @@ -9,7 +9,7 @@ #include "dlb.h" #include "hacklib.h" -#if !defined(O_WRONLY) && !defined(MACOS9) && !defined(AZTEC_C) +#if !defined(O_WRONLY) && !defined(MAC68K) && !defined(AZTEC_C) #include #endif #if defined(__DJGPP__) diff --git a/util/makedefs.c b/util/makedefs.c index 177fc53df..21dbb1089 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -23,15 +23,15 @@ #include "dlb.h" #include "hacklib.h" -#ifdef MACOS9 +#ifdef MAC68K #if defined(__SC__) || defined(__MRC__) /* MPW compilers */ #define MPWTOOL #include #include -#else /* MACOS9 without MPWTOOL */ +#else /* MAC68K without MPWTOOL */ #define MACsansMPWTOOL #endif -#endif /* MACOS9 */ +#endif /* MAC68K */ #ifndef MPWTOOL #define SpinCursor(x) @@ -78,7 +78,7 @@ #define DGN_TEMPLATE "NH:dat/%s" /* where dungeon.pdf file goes */ #endif /* OLD_MAKEDEFS_OPTIONS */ #else /* not AMIGA */ -#if defined(MACOS9) && !defined(__MACH__) +#if defined(MAC68K) && !defined(__MACH__) /* MacOS 9 or earlier */ #define SOURCE_TEMPLATE ":src:%s" #if __SC__ || __MRC__ @@ -91,7 +91,7 @@ #define INCLUDE_TEMPLATE ":include:%s" #define DGN_TEMPLATE ":dat:%s" /* where dungeon.pdf file goes */ #endif /* OLD_MAKEDEFS_OPTIONS */ -#else /* neither AMIGA nor MACOS9 */ +#else /* neither AMIGA nor MAC68K */ #ifdef OS2 #define SOURCE_TEMPLATE "..\\src\\%s" #define DATA_TEMPLATE "..\\dat\\%s" @@ -100,7 +100,7 @@ #define INCLUDE_TEMPLATE "..\\include\\%s" #define DGN_TEMPLATE "..\\dat\\%s" /* where dungeon.pdf file goes */ #endif /* OLD_MAKEDEFS_OPTIONS */ -#else /* not AMIGA, MACOS9, or OS2 */ +#else /* not AMIGA, MAC68K, or OS2 */ #define SOURCE_TEMPLATE "../src/%s" #define DATA_TEMPLATE "../dat/%s" #define DATA_IN_TEMPLATE "../dat/%s" @@ -109,7 +109,7 @@ #define DGN_TEMPLATE "../dat/%s" /* where dungeon.pdf file goes */ #endif /* OLD_MAKEDEFS_OPTIONS */ #endif /* else !OS2 */ -#endif /* else !MACOS9 */ +#endif /* else !MAC68K */ #endif /* else !AMIGA */ static const char @@ -257,7 +257,7 @@ main(void) return 0; } -#else /* ! MACOS9 */ +#else /* ! MAC68K */ DISABLE_WARNING_UNREACHABLE_CODE @@ -1551,7 +1551,7 @@ do_oracles(void) break; if (!(ok = (fscanf(ofp, "%5lx", &offset) == 1))) break; -#ifdef MACOS9 +#ifdef MAC68K #ifdef __MWERKS__ /* MetroWerks CodeWarrior Pro 1's (AKA CW12) version of MSL diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 52b034410..448d8c77d 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -122,7 +122,7 @@ struct window_procs curses_procs = { curses_delay_output, #ifdef CHANGE_COLOR curses_change_color, -#ifdef MACOS9 /* old OS 9, not OSX */ +#ifdef MAC68K /* old OS 9, not OSX */ (void (*)(int)) 0, (short (*)(winid, char *)) 0, #endif diff --git a/win/share/tilemap.c b/win/share/tilemap.c index 302372c4a..90bb6b85a 100644 --- a/win/share/tilemap.c +++ b/win/share/tilemap.c @@ -541,7 +541,7 @@ tilename(int set, const int file_entry, int gend UNUSED) #define SOURCE_TEMPLATE "NH:src/%s" #define INCLUDE_TEMPLATE "NH:include/t.%s" #else -#ifdef MACOS9 +#ifdef MAC68K #define SOURCE_TEMPLATE ":src:%s" #define INCLUDE_TEMPLATE ":include:%s" #else diff --git a/win/tty/getline.c b/win/tty/getline.c index b969681ce..8dbd43f67 100644 --- a/win/tty/getline.c +++ b/win/tty/getline.c @@ -7,7 +7,7 @@ #ifdef TTY_GRAPHICS -#if !defined(MACOS9) +#if !defined(MAC68K) #define NEWAUTOCOMP #endif diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 68cce5c6a..a018d3bc0 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -20,7 +20,7 @@ /* leave this undefined; it produces bad screen output with rxvt-unicode */ /*#define DECgraphicsOptimization*/ -#ifdef MACOS9 +#ifdef MAC68K #define MICRO /* The Mac is a MICRO only for this file, not in general! */ #ifdef THINK_C extern void msmsg(const char *, ...); @@ -143,7 +143,7 @@ struct window_procs tty_procs = { tty_getlin, tty_get_ext_cmd, tty_number_pad, tty_delay_output, #ifdef CHANGE_COLOR /* the Mac uses a palette device */ tty_change_color, -#ifdef MACOS9 +#ifdef MAC68K tty_change_background, set_tty_font_name, #endif tty_get_color_string, From 78f59660d04609d799b693e5baac40fd6417b690 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Fri, 5 Jun 2026 19:46:05 +0200 Subject: [PATCH 449/702] mac: drop the obsolete exit getreturn The revived mac68k port (on the m68k-wip branch) removed it: it runs an event loop after exit_nhwindows() has torn the windowing system down and crashes; the tombstone already pauses. Removing it here too keeps the block from resurfacing in NetHack-5.0 <-> m68k-wip merges. --- src/end.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/end.c b/src/end.c index 45eace422..9bee60b87 100644 --- a/src/end.c +++ b/src/end.c @@ -1679,9 +1679,6 @@ nh_terminate(int status) program_state.in_moveloop = 0; /* won't be returning to normal play */ l_nhcore_call(NHCORE_GAME_EXIT); -#ifdef MAC68K - getreturn("to exit"); -#endif /* don't bother to try to release memory if we're in panic mode, to avoid trouble in case that happens to be due to memory problems */ if (!program_state.panicking) { From 393f42cd6fbd5ffd46c662c119adc49fee46af61 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 5 Jun 2026 20:17:48 -0400 Subject: [PATCH 450/702] follow-up: grammar and format string --- src/dothrow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dothrow.c b/src/dothrow.c index 82028f321..c10d6ccb0 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1749,7 +1749,7 @@ throwit( if (tethered_weapon) { pline(Blind ? "%s%s back and is left" " dangling from your %s." - : "%s is left dangling from your %s.", + : "%s%s and is left dangling from your %s.", Blind ? "Your tethered weapon" : Tobjnam(obj, "return"), Blind ? " snaps" : "", body_part(ARM)); From ed1b4af5cdc255f79e52b3cfda37e4aa6c7962c8 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 6 Jun 2026 10:36:47 -0400 Subject: [PATCH 451/702] fix build on Windows arm64 --- sys/windows/Makefile.nmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index 07e974d29..a90c673c3 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -1868,7 +1868,7 @@ $(OTTY)date.o: $(HACKINCL) $(HACKSRC) $(HACKOBJ) $(ALLOBJTTY) $(CURSESOBJ) @echo ^$(OTTY)date.o: >>date-tty.nmk @echo. ^$(cc) ^$(CFLAGS) -Fo^$@ date.c>>date-tty.nmk @echo.>>date-tty.nmk - @$(MAKE) /NOLOGO /A OTTY=objtty\x64\ -f date-tty.nmk + @$(MAKE) /NOLOGO /A OTTY=$(OTTY) -f date-tty.nmk !ENDIF $(OGUI)date.o: $(HACKINCL) $(HACKSRC) $(HACKOBJ) $(ALLOBJGUI) From 19c85c1987ec8253b12af52df715dde78a875687 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 6 Jun 2026 12:10:15 -0400 Subject: [PATCH 452/702] Don't overflow svp.plname on restore --- src/restore.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/restore.c b/src/restore.c index 50c3a0137..7e1911e21 100644 --- a/src/restore.c +++ b/src/restore.c @@ -713,6 +713,14 @@ restgamestate(NHFILE *nhfp) restore_oracles(nhfp); Sfi_char(nhfp, svp.pl_character, "gamestate-pl_character", sizeof svp.pl_character); + /* Previous versions had a bug that clobbered pl_character on restore. + Fill it in if it was clobbered. */ + if (svp.pl_character[0] == '\0') { + if ((Upolyd ? u.mfemale : flags.female) && gu.urole.name.f) + Strcpy(svp.pl_character, gu.urole.name.f); + else + Strcpy(svp.pl_character, gu.urole.name.m); + } Sfi_char(nhfp, svp.pl_fruit, "gamestate-pl_fruit", sizeof svp.pl_fruit); freefruitchn(gf.ffruit); /* clean up fruit(s) made by initoptions() */ gf.ffruit = loadfruitchn(nhfp); @@ -791,11 +799,13 @@ dorecover(NHFILE *nhfp) { xint8 ltmp = 0; int rtmp; + char plname[PL_NSIZ_PLUS]; /* suppress map display if some part of the code tries to update that */ program_state.restoring = REST_GSTATE; - get_plname_from_file(nhfp, svp.plname, TRUE); + get_plname_from_file(nhfp, plname, TRUE); + Snprintf(svp.plname, sizeof(svp.plname), "%s", plname); /* * The position in the save file is now here: * @@ -891,7 +901,8 @@ dorecover(NHFILE *nhfp) rewind_nhfile(nhfp); /* return to beginning of file */ (void) validate(nhfp, (char *) 0, FALSE, 0); - get_plname_from_file(nhfp, svp.plname, TRUE); + get_plname_from_file(nhfp, plname, TRUE); + Snprintf(svp.plname, sizeof(svp.plname), "%s", plname); /* not 0 nor REST_GSTATE nor REST_LEVELS */ program_state.restoring = REST_CURRENT_LEVEL; From 498db9043709a9b022532fa158bf0ec2fa822084 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 6 Jun 2026 12:29:39 -0400 Subject: [PATCH 453/702] follow-up: fixes5-0-1.txt entry --- doc/fixes5-0-1.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 850c7576b..96dba1c4d 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -55,6 +55,7 @@ if the hero has already been told that an engraving vanished, ensure that new engraving aklys path shouldn't be shown for locations that the hero cannot see keep the player better-informed about status of the tether on their weapon +don't overflow svp.plname on restore (pr #1570 by chasonr) Platform- and/or Interface-Specific Fixes From 1f4198c705de6fed709cc57b732a2320cf8992a0 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 6 Jun 2026 15:01:54 -0400 Subject: [PATCH 454/702] aklys message improvements --- src/dothrow.c | 54 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/src/dothrow.c b/src/dothrow.c index c10d6ccb0..45a0e00cf 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1437,7 +1437,8 @@ throwing_weapon(struct obj *obj) || obj->otyp == WAR_HAMMER || obj->otyp == AKLYS); } -/* the currently thrown object is returning to you (not for boomerangs) */ +/* the currently thrown object is returning to you (not for boomerangs + or tethered weapons) */ staticfn void sho_obj_return_to_u(struct obj *obj) { @@ -1520,7 +1521,8 @@ throwit( boolean crossbowing, impaired = (Confusion || Stunned || Blind || Hallucination || Fumbling), - tethered_weapon = (arw && arw->tethered && (wep_mask & W_WEP) != 0); + tethered_weapon = (arw && arw->tethered && (wep_mask & W_WEP) != 0), + tether_released_msg = FALSE; gn.notonhead = FALSE; /* reset potentially stale value */ if ((obj->cursed || obj->greased) && (u.dx || u.dy) && !rn2(7)) { @@ -1685,8 +1687,14 @@ throwit( /* bhit display cleanup was left with this caller for tethered_weapon, but clean it up now since we're about to return */ - if (tethered_weapon) + if (tethered_weapon) { + if (!tether_released_msg) { + pline("The tether comes off your %s.", + body_part(ARM)); + tether_released_msg = TRUE; + } tmp_at(DISP_END, 0); + } throwit_return(FALSE); return; } @@ -1699,8 +1707,14 @@ throwit( if (!gt.thrownobj) { /* missile has already been handled */ - if (tethered_weapon) + if (tethered_weapon) { + if (!tether_released_msg) { + pline("The tether comes off your %s.", + body_part(ARM)); + tether_released_msg = TRUE; + } tmp_at(DISP_END, 0); + } } else if (u.uswallow && !iflags.returning_missile) { swallowit(obj); return; @@ -1738,21 +1752,16 @@ throwit( if obj is quivered, remove it before wielding */ if (obj->owornmask & W_QUIVER) setuqwep((struct obj *) 0); -#if 0 - setuwep(obj); - set_twoweap(twoweap); /* u.twoweap = twoweap */ -#endif if (cansee(gb.bhitpos.x, gb.bhitpos.y)) newsym(gb.bhitpos.x, gb.bhitpos.y); } if (!dmg) { if (tethered_weapon) { - pline(Blind ? "%s%s back and is left" - " dangling from your %s." - : "%s%s and is left dangling from your %s.", - Blind ? "Your tethered weapon" : Tobjnam(obj, "return"), - Blind ? " snaps" : "", - body_part(ARM)); + /* Blind mods unnecessary; you know what you threw, + * and it is tethered to your arm */ + pline("Your tethered %s snaps back but the tether slips from your %s.", + simpleonames(obj), body_part(ARM)); + tether_released_msg = TRUE; } else { pline(Blind ? "%s lands %s your %s." @@ -1764,9 +1773,8 @@ throwit( } else { dmg += rnd(3); if (tethered_weapon) { - Your("tethered %s your %s!", - Blind ? "weapon returns and hits" : Tobjnam(obj, "hit"), - body_part(ARM)); + Your("tethered %s returns and hits your %s!", + simpleonames(obj), body_part(ARM)); } else { pline( Blind @@ -1789,14 +1797,22 @@ throwit( if (!ship_object(obj, u.ux, u.uy, FALSE)) dropy(obj); } else { - pline_The("%s tether releases from your %s!", + if (!tether_released_msg) { + pline_The("%s tether comes off your %s.", s_suffix(simpleonames(obj)), body_part(ARM)); + tether_released_msg = TRUE; + } } } throwit_return(TRUE); return; } else { if (tethered_weapon) { + if (!tether_released_msg) { + pline("The tether comes off your %s.", + body_part(ARM)); + tether_released_msg = TRUE; + } tmp_at(DISP_END, 0); /* when this location is stepped on, the weapon will be auto-picked up due to 'obj->how_lost' of LOST_THROWN; @@ -1806,8 +1822,6 @@ throwit( explicitly rewield the weapon to get throw-and-return capability back anyway, quivered or not shouldn't matter */ - pline("The tether snaps off your %s!", - body_part(ARM)); } else { pline("%s to return!", Tobjnam(obj, "fail")); } From 51486d0c02492933080de8a689b3de9e5c693799 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 7 Jun 2026 01:31:19 -0400 Subject: [PATCH 455/702] fix recover failure after unexpected exit u.ustuck and u.usteed are handled differently in 5.0.0 than in previous releases, and an unexpected halt to NetHack could result in an inability to use recover to get the game back. If the hero was engulfed, u.uswallow, could get saved to the checkpoint file with a value of 1 without a corresponding u.ustuck_mid value representing the m_id of the engulfing monster. Recover had no information to use to restore the u.ustuck pointer when loading the monsters on the level. With u.uswallow set to 1, the game would proceed to enter if-blocks based on that, and then crash/fault when it attempted to dereference u.ustuck, during the recover attempt. This updates the values of u.ustuck_mid immediately before saving struct you during a checkpoint, so that the resulting file had u.uswallow and u.ustuck_mid values that were in concert. It does the same for u.usteed and u.usteed_mid. This also now adds a save_currentstate() checkpoint call when the swallowed/unswallowed status changes, that is whenever set_ustuck() is called. --- src/do.c | 4 +++- src/mon.c | 3 +++ src/save.c | 10 ++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/do.c b/src/do.c index 54cfd5960..ea55197d7 100644 --- a/src/do.c +++ b/src/do.c @@ -1376,7 +1376,9 @@ save_currentstate(void) { NHFILE *nhfp; - if (!program_state.something_worth_saving) + if (!program_state.something_worth_saving + || program_state.in_self_recover + || program_state.in_checkpoint) return; program_state.in_checkpoint++; diff --git a/src/mon.c b/src/mon.c index c67785325..aca835286 100644 --- a/src/mon.c +++ b/src/mon.c @@ -3432,6 +3432,9 @@ set_ustuck(struct monst *mtmp) u.uswallow = 0; u.uswldtim = 0; } +#ifdef INSURANCE + save_currentstate(); +#endif } void diff --git a/src/save.c b/src/save.c index bd2696e6c..d31e23148 100644 --- a/src/save.c +++ b/src/save.c @@ -284,6 +284,13 @@ savegamestate(NHFILE *nhfp) urealtime.start_timing); Sfo_long(nhfp, &svw.wreserve, "wreserve"); Sfo_int32(nhfp, &svw.wtreserved, "wtreserved"); + /* + * It is critical to ensure that u.ustuck_mid and u.usteed_mid + * hold current and correct data, in case this is needed by + * recover. + */ + u.ustuck_mid = (u.ustuck) ? u.ustuck->m_id : 0; + u.usteed_mid = (u.usteed) ? u.usteed->m_id : 0; Sfo_you(nhfp, &u, "gamestate-you"); Sfo_char(nhfp, yyyymmddhhmmss(ubirthday), "gamestate-ubirthday", 14); Sfo_long(nhfp, &urealtime.realtime, "gamestate-realtime"); @@ -354,6 +361,9 @@ savestateinlock(void) char whynot[BUFSZ]; NHFILE *nhfp; + if (!program_state.something_worth_saving || program_state.in_self_recover) + return; + program_state.saving++; /* inhibit status and perm_invent updates */ /* When checkpointing is on, the full state needs to be written * on each checkpoint. When checkpointing is off, only the pid From cbfd3aa94476c6383040b57ea6a613c4b5568d5d Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 7 Jun 2026 01:52:54 -0400 Subject: [PATCH 456/702] placement for the added save_currentstate() call wasn't right in gulpmu() that particular placement would result in u.uswallow = 0, and u.ustuck set. A better optimal location needs to be sought. --- src/mon.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/mon.c b/src/mon.c index aca835286..c67785325 100644 --- a/src/mon.c +++ b/src/mon.c @@ -3432,9 +3432,6 @@ set_ustuck(struct monst *mtmp) u.uswallow = 0; u.uswldtim = 0; } -#ifdef INSURANCE - save_currentstate(); -#endif } void From 4d590abac1274c796dab8fd9f6b86f5015aa87d6 Mon Sep 17 00:00:00 2001 From: 0x0b1ade Date: Sun, 7 Jun 2026 22:02:20 +0800 Subject: [PATCH 457/702] Add length checks in init_dungeon_dungeons --- src/dungeon.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/dungeon.c b/src/dungeon.c index 89afa002b..f299632a6 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1058,11 +1058,22 @@ init_dungeon_dungeons( pd->tmpdungeon[dngidx].chance = dgn_chance; pd->tmpdungeon[dngidx].entry_lev = dgn_entry; - /* FIXME: these should have length checks */ + if (Strlen(dgn_fill) >= sizeof svd.dungeons[dngidx].fill_lvl) + panic("fill_lvl too long for dungeon %d", dngidx); Strcpy(svd.dungeons[dngidx].fill_lvl, dgn_fill); + + if (Strlen(dgn_name) >= sizeof svd.dungeons[dngidx].dname) + panic("dname too long for dungeon %d", dngidx); Strcpy(svd.dungeons[dngidx].dname, dgn_name); + + if (Strlen(dgn_protoname) >= sizeof svd.dungeons[dngidx].proto) + panic("proto too long for dungeon %d", dngidx); Strcpy(svd.dungeons[dngidx].proto, dgn_protoname); + + if (Strlen(dgn_themerms) >= sizeof svd.dungeons[dngidx].themerms) + panic("themerms too long for dungeon %d", dngidx); Strcpy(svd.dungeons[dngidx].themerms, dgn_themerms); + /* FIXME: accept "none", convert that to '\0' */ svd.dungeons[dngidx].boneid = *dgn_bonetag ? *dgn_bonetag : 0; free((genericptr) dgn_fill); From a160322aef573ae280f31481d51aadb4c0334c58 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sun, 7 Jun 2026 17:09:27 -0400 Subject: [PATCH 458/702] MS-DOS: Fix custom colors in VESA BIOS mode The basic colors are being displayed as black. Colors specified as RGB are not being converted to the pixel format for the current mode. This manifests as walls in dungeon branches being drawn in black when the symbol set is IBMgraphics, and in the wrong color when Enhanced1 is in use and the display mode uses 15 or 16 bits per pixel. A particular mode that shows this bug is 1024 by 768 under DOSBox. --- sys/msdos/vidvesa.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/sys/msdos/vidvesa.c b/sys/msdos/vidvesa.c index 8a3423bc0..8a5ec21dd 100644 --- a/sys/msdos/vidvesa.c +++ b/sys/msdos/vidvesa.c @@ -691,9 +691,16 @@ vesa_xputg(const glyph_info *glyphinfo, const glyph_info *bkglyphinfo UNUSED) } #endif if (vesa_pixel_size > 8 && glyphinfo->gm.customcolor != 0) { - /* FIXME: won't display black (0,0,0) correctly, but the background - is usually black anyway */ - attr = glyphinfo->gm.customcolor | 0x80000000; + attr = glyphinfo->gm.customcolor; + if (attr & NH_BASIC_COLOR) { + attr &= 0x0F; + } else { + struct Pixel p; + p.r = (unsigned char)(attr >> 16); + p.g = (unsigned char)(attr >> 8); + p.b = (unsigned char)(attr >> 0); + attr = vesa_MakeColor(p) | 0x80000000; + } } row = currow; From 9f7a9d2c88aacb080d95e7f8c24b36802b09e7a9 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Mon, 8 Jun 2026 04:04:12 +0100 Subject: [PATCH 459/702] Prevent off-map monsters banking turns If a monster is marked as off the map, then it is included in iterations over the monster list, but not allowed to move. This meant that such monsters would gain movement points on every turn but not spend them, which could lead to the monster taking a lot of turns in a row when placed back onto the map. This commit removes the movement allocation from monsters that are flagged as dead or removed from the map, meaning that they neve get more than one turn's worth of movement allocation. --- src/mon.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/mon.c b/src/mon.c index c67785325..cc70c0453 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1236,14 +1236,19 @@ movemon_singlemon(struct monst *mtmp) (void) gd_move(mtmp); mtmp->mlstmv = svm.moves; } + mtmp->movement = 0; return FALSE; } - if (DEADMONSTER(mtmp)) + if (DEADMONSTER(mtmp)) { + mtmp->movement = 0; return FALSE; + } /* monster isn't on this map anymore */ - if (mon_offmap(mtmp)) + if (mon_offmap(mtmp)) { + mtmp->movement = 0; return FALSE; + } m_everyturn_effect(mtmp); From 738aa5c076ac370357576541fa7f37cd3ad9ada9 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Mon, 8 Jun 2026 04:39:46 +0100 Subject: [PATCH 460/702] Make monsters not scared of the Sokoban rolling boulder traps They aren't initially loaded with boulders, thus aren't dangerous. This is particularly relevant for pets, who would otherwise be very reluctant to follow their owners up to the level above. --- doc/fixes5-0-1.txt | 1 + src/trap.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 96dba1c4d..80f9e20a3 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -56,6 +56,7 @@ if the hero has already been told that an engraving vanished, ensure that aklys path shouldn't be shown for locations that the hero cannot see keep the player better-informed about status of the tether on their weapon don't overflow svp.plname on restore (pr #1570 by chasonr) +monsters (including pets) aren't scared of the Sokoban rolling boulder traps Platform- and/or Interface-Specific Fixes diff --git a/src/trap.c b/src/trap.c index 1804f7fc8..c9ab97563 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1129,6 +1129,9 @@ m_harmless_trap(struct monst *mtmp, struct trap *ttmp) case LANDMINE: break; case ROLLING_BOULDER_TRAP: + /* the Sokoban rolling boulder traps are not dangerous */ + if (In_sokoban(&u.uz)) + return TRUE; break; case SLP_GAS_TRAP: if (resists_sleep(mtmp) || defended(mtmp, AD_SLEE)) From b309392b5a2fc2ef961a5bf4181496ab38115c32 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Mon, 8 Jun 2026 04:42:44 +0100 Subject: [PATCH 461/702] Fixes entry for the recent bugfix --- doc/fixes5-0-1.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 80f9e20a3..df0990233 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -57,6 +57,8 @@ aklys path shouldn't be shown for locations that the hero cannot see keep the player better-informed about status of the tether on their weapon don't overflow svp.plname on restore (pr #1570 by chasonr) monsters (including pets) aren't scared of the Sokoban rolling boulder traps +fix a bug in which steeds would continuously gain movement points while + being ridden Platform- and/or Interface-Specific Fixes From c0f06ac4fd7365887989bbd2e5290d57d5b93a30 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 7 Jun 2026 23:54:43 -0400 Subject: [PATCH 462/702] follow-up to 84a6eb5e Ensure MON_STILL_ARRIVING bit is cleared before an early return. --- src/dog.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dog.c b/src/dog.c index 13ea0b137..05e7e9e88 100644 --- a/src/dog.c +++ b/src/dog.c @@ -463,8 +463,10 @@ mon_arrive(struct monst *mtmp, int when) here for monsters migrating to a newly created level */ restore_cham(mtmp); - if (mtmp == u.usteed) + if (mtmp == u.usteed) { + mtmp->mstate &= ~MON_STILL_ARRIVING; return; /* don't place steed on the map */ + } if (when == With_you) { /* When a monster accompanies you, sometimes it will arrive at your intended destination and you'll end up next to From 7e18df3c5f342e25e41866ef34097425f4b88a0b Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 8 Jun 2026 00:06:59 -0400 Subject: [PATCH 463/702] ensure sane values for monst fields from bones --- src/restore.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/restore.c b/src/restore.c index 7e1911e21..0cc82f30f 100644 --- a/src/restore.c +++ b/src/restore.c @@ -1202,6 +1202,10 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { if (mtmp->isshk) set_residency(mtmp, FALSE); + /* set some monst fields to sane values when coming from a bones file */ + if (ghostly) { + mtmp->movement = 0; + } if (mtmp->m_id == u.usteed_mid) { /* steed is kept on fmon list but off the map */ u.usteed = mtmp; From 917cc1a5967a025097793eef80b94cf315fc6736 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 8 Jun 2026 13:47:55 -0400 Subject: [PATCH 464/702] add pair of generated files to .gitignore --- src/.gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/.gitignore b/src/.gitignore index 30c020d13..5d660d4a5 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -33,3 +33,7 @@ GNUmakefile GNUmakefile.depend .*.c .depend +date-gui.nmk +date-tty.nmk + + From 57111e3c1f8194d0d77005adc10f324aceb820a1 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 9 Jun 2026 09:40:15 -0400 Subject: [PATCH 465/702] update pdcursesmod submodule --- submodules/pdcursesmod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/pdcursesmod b/submodules/pdcursesmod index 5a2554607..6cd9c1690 160000 --- a/submodules/pdcursesmod +++ b/submodules/pdcursesmod @@ -1 +1 @@ -Subproject commit 5a255460769fd70067ee46989e85570729ceeae8 +Subproject commit 6cd9c16900fef82754923c718fab7fe85f761bb6 From c8b15fe8544760b143541f9cfe378667971c7747 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 9 Jun 2026 13:00:22 -0700 Subject: [PATCH 466/702] pull request #1557 - erinyes level adjustments Pull request from youbo0: when hero's alignment gets low enough, the adjusted experience level for erinyes effetively dropped instead of increased. It was being capped at 50 which has a special meaning for monsters. Change the level limit to 49 which is as high as ordinary monsters go. Does not affect saved data. Fixes #1557 --- doc/fixes5-0-1.txt | 3 ++- src/mon.c | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index df0990233..9c3acac1f 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.20 $ $NHDT-Date: 1779581008 2026/05/24 00:03:28 $ +NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.36 $ $NHDT-Date: 1781062909 2026/06/09 19:41:49 $ General Fixes and Modified Features ----------------------------------- @@ -59,6 +59,7 @@ don't overflow svp.plname on restore (pr #1570 by chasonr) monsters (including pets) aren't scared of the Sokoban rolling boulder traps fix a bug in which steeds would continuously gain movement points while being ridden +when hero's behavior makes erinyes stronger, cap level at 49 rather than 50 Platform- and/or Interface-Specific Fixes diff --git a/src/mon.c b/src/mon.c index cc70c0453..a69a1aedf 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mon.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.621 $ */ +/* NetHack 5.0 mon.c $NHDT-Date: 1781062909 2026/06/09 19:41:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.634 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -5965,8 +5965,9 @@ adj_erinys(unsigned abuse) pm->mattk[2].damd = 4; } - /* also adjust level and difficulty */ - pm->mlevel = min(7 + u.ualign.abuse, 50); + /* also adjust level and difficulty; + mlevel >= 50 has a special meaning, so don't exceed 49 */ + pm->mlevel = min(7 + u.ualign.abuse, 49); pm->difficulty = min(10 + (u.ualign.abuse / 3), 25); } From 1ac6ec5d1e9623e50849ddaa65b52159186d583e Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Tue, 9 Jun 2026 16:25:46 -0400 Subject: [PATCH 467/702] MS-DOS: several fixes for the tiled map VESA mode: Set the viewport size correctly so the position bar does not overlay the map. VESA mode: Correctly set the size to which tiles are stretched when overview mode (F4) is selected. Both VESA and 16 color modes: Pass correct parameters to vga_userpan and vesa_userpan, so the pan keys (CTRL+arrow) work correctly. Some emulations don't report CTRL with up or down arrows, so accept CTRL-home, CTRL-page up, CTRL page down and CTRL-end. 16 color mode: Set the panning direction so CTRL-left and CTRL-right pan in the same direction as 3.4.3. --- sys/msdos/pckeys.c | 26 ++++++++++++++++++++------ sys/msdos/vidvesa.c | 24 +++++++++++++----------- sys/msdos/vidvga.c | 4 ++-- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/sys/msdos/pckeys.c b/sys/msdos/pckeys.c index 51eb0cf0c..b8997f9c3 100644 --- a/sys/msdos/pckeys.c +++ b/sys/msdos/pckeys.c @@ -14,7 +14,7 @@ #include "pcvideo.h" boolean pckeys(unsigned char, unsigned char); -static void userpan(boolean); +static void userpan(enum vga_pan_direction pan); static void overview(boolean); static void traditional(boolean); static void refresh(void); @@ -49,11 +49,25 @@ pckeys(unsigned char scancode, unsigned char shift) #endif case 0x74: /* Control-right_arrow = scroll horizontal to right */ if ((shift & CTRL) && iflags.tile_view && !opening_dialog) - userpan(1); + userpan(pan_right); break; case 0x73: /* Control-left_arrow = scroll horizontal to left */ if ((shift & CTRL) && iflags.tile_view && !opening_dialog) - userpan(0); + userpan(pan_left); + break; + /* Dosbox reports control-up and down arrows, but VirtualBox and QEMU + don't; accept home, end, page up and page down also */ + case 0x77: /* control-home */ + case 0x8D: /* control-up_arrow */ + case 0x84: /* control-page_up */ + if ((shift & CTRL) && iflags.tile_view && !opening_dialog) + userpan(pan_up); + break; + case 0x75: /* control-end */ + case 0x91: /* control-down_arrow */ + case 0x76: /* control-page_down */ + if ((shift & CTRL) && iflags.tile_view && !opening_dialog) + userpan(pan_down); break; case 0x3E: /* F4 = toggle overview mode */ if (iflags.tile_view && !opening_dialog && !Is_rogue_level(&u.uz)) { @@ -76,15 +90,15 @@ pckeys(unsigned char scancode, unsigned char shift) } static void -userpan(boolean on) +userpan(enum vga_pan_direction pan) { #ifdef SCREEN_VGA if (iflags.usevga) - vga_userpan(on); + vga_userpan(pan); #endif #ifdef SCREEN_VESA if (iflags.usevesa) - vesa_userpan(on); + vesa_userpan(pan); #endif } diff --git a/sys/msdos/vidvesa.c b/sys/msdos/vidvesa.c index 8a5ec21dd..bb66379ad 100644 --- a/sys/msdos/vidvesa.c +++ b/sys/msdos/vidvesa.c @@ -1128,17 +1128,6 @@ vesa_Init(void) clipy = 0; clipymax = clipy + (viewport_rows - 1); - /* Set the size of the tiles for the overview mode */ - vesa_oview_width = vesa_x_res / COLNO; - if (vesa_oview_width > (unsigned) iflags.wc_tile_width) { - vesa_oview_width = (unsigned) iflags.wc_tile_width; - } - vesa_oview_height = (vesa_y_res - (TOP_MAP_ROW + 4) * vesa_char_height) - / ROWNO; - if (vesa_oview_height > (unsigned) iflags.wc_tile_height) { - vesa_oview_height = (unsigned) iflags.wc_tile_height; - } - /* Load a font of size appropriate to the screen size */ if (vesa_x_res >= 1280 && vesa_y_res >= 960) font_name = "ter-u32b.psf"; @@ -1182,6 +1171,19 @@ vesa_Init(void) vesa_char_width = vesa_char_height / 2; } + vesa_SetViewPort(); + + /* Set the size of the tiles for the overview mode */ + vesa_oview_width = vesa_x_res / COLNO; + if (vesa_oview_width > (unsigned) iflags.wc_tile_width) { + vesa_oview_width = (unsigned) iflags.wc_tile_width; + } + vesa_oview_height = (vesa_y_res - (TOP_MAP_ROW + 5) * vesa_char_height) + / ROWNO; + if (vesa_oview_height > (unsigned) iflags.wc_tile_height) { + vesa_oview_height = (unsigned) iflags.wc_tile_height; + } + /* Process tiles for the current video mode */ vesa_tiles = (unsigned char **) alloc(total_tiles_used * sizeof(void *)); vesa_oview_tiles = (unsigned char **) alloc(total_tiles_used * sizeof(void *)); diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index 6b1a81239..c69823d74 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -533,9 +533,9 @@ vga_userpan(enum vga_pan_direction pan) /* pline("Into userpan"); */ if (iflags.over_view || iflags.traditional_view) return; - if (pan == pan_left) + if (pan == pan_right) x = min(COLNO - 1, clipxmax + 10); - else if (pan == pan_right) + else if (pan == pan_left) x = max(0, clipx - 10); else return; From e34238d2bc7092117b12d14927c1c62200dc658d Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 9 Jun 2026 16:48:02 -0400 Subject: [PATCH 468/702] MS-DOS: several fixes for the tiled map --- doc/fixes5-0-1.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 9c3acac1f..3832e4f35 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -161,6 +161,15 @@ Linux: add WANT_SYSTEM_LUA=1 support to the linux.500 hints files and step and the subsequent compiling of Lua; it tries to use use the Lua5.4 package that is already installed on the system macOS: fix ncurses build with Homebrew +MS-DOS: Fix custom colors in VESA BIOS mode (pr #1577 by chasonr) +MS-DOS: VESA mode: set the viewport size correctly so the position bar + does not overlap the map; correctly set the size to which tiles are + stretched when overview mode (F4) is selected (pr #1579 by chasonr) +MS-DOS: VESA and 16 color modes: Pass correct parameters to vga_userpan + and vesa_userpan, so the pan keys (CTRL+arrow) work correctly. Some + emulations don't report CTRL with up or down arrows, so accept + CTRL-home, CTRL-page up, CTRL page down and CTRL-end + (pr #1579 by chasonr) musl: musl libc does not have __sighandler_t so don't use it in the macro definition for SIG_RET_TYPE with musl WASM: resolve some build failures in 'make CROSS_TO_WASM=1' From 383d810357f2e095509929b69958ac647f00a685 Mon Sep 17 00:00:00 2001 From: nhkeni Date: Tue, 9 Jun 2026 17:22:12 -0400 Subject: [PATCH 469/702] re-write fetch-Lua target cleaner output better structure better error checking and recovery --- sys/unix/Makefile.top | 100 +++++++++++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 30 deletions(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 239e148d7..1dba21622 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -348,8 +348,12 @@ LUA_URL_list:=$(LUA_URL) $(LUA_URL_MIRROR) $(LUA_URL_NHD) # #CURL := curl #ask curl to return a failure code if error 404 is encountered -CURL := curl --fail +CURL := curl -q --fail --no-progress-meter +# Set this to 1 to bypass checksum verification. _Highly_ discouraged. +#NOCHKSUM=1 + +#debugging targets fetch-lua-mirror: LUA_URL_list:=$(LUA_URL_MIRROR) fetch-lua-mirror: fetch-Lua @true @@ -358,50 +362,86 @@ fetch-lua-nhd: LUA_URL_list:=$(LUA_URL_NHD) fetch-lua-nhd: fetch-Lua @true +# normal entry point fetch-lua: fetch-Lua @true fetch-Lua: @( \ - shac1=`command -v shasum`; \ - shac2=`command -v sha256sum`; \ - if [ ! -z $$shac1 ]; then \ - shac="$$shac1 -a 256"; elif [ ! -z $$shac2 ]; then \ - shac=$$shac2; else echo "CAUTION: no way to check integrity"; \ - fi; \ - set -- DUMMY $(LUA_URL_list); \ - luafile=lua-$(LUA_VERSION).tar.gz; \ - export curlstatus=1; \ - mkdir -p lib && cd lib && \ - while [ $$# -gt 0 ]; do \ + `: $1 = file to check`; \ + chksum_or_fail(){ \ + local shac shac1 shac2; \ + shac1=`command -v shasum`; \ + shac2=`command -v sha256sum`; \ + if [ ! -z $$shac1 ]; then \ + shac="$$shac1 -a 256"; \ + elif [ ! -z $$shac2 ]; then \ + shac=$$shac2; \ + else \ + echo "CAUTION: no way to check integrity"; \ + echo "Rerun with 'NOCHKSUM=1' to skip this check"; \ + exit 1; \ + fi; \ + echo "Checking integrity of $$1 with $$shac"; \ + $$shac -w --ignore-missing -c $$CHKSUMSTMP < $$1; \ + if [ $$? -ne 0 ]; then \ + echo "Integrity check FAILED - STOPPING"; \ + exit 1; \ + fi; \ + echo "Integrity check passed"; \ + }; \ + `: $1 = name of tarfile`; \ + untar_and_cleanup(){ \ + echo "Unpacking $$1"; \ + tar zxf $$1; \ + if [ $$? -eq '0' ]; then \ + rm -f $$1; \ + echo "Unpacked successfully into `pwd`"; \ + return 0; \ + else \ + echo "tar failed to extract $$1 - trying next source"; \ + return 1; \ + fi; \ + }; \ + `: main`; \ + set -- $(LUA_URL_list); \ + luafile=lua-$(LUA_VERSION).tar.gz; \ + mkdir -p lib; \ + cd lib || { \ + echo "Unable to find lib directory"; \ + exit 1; \ + }; \ + while [ $$# -gt 0 ]; do \ + iter=$$1; \ shift; \ - if [ $$curlstatus -ne 0 ]; then \ - luaurl=https://$$1/$$luafile; \ - echo Trying $$luaurl; \ - $(CURL) -R -O $$luaurl; \ - curlstatus=$$?; \ - if [ $$curlstatus -eq 0 ]; then \ - if [ ! -z "$$shac" ]; then \ + luaurl=https://$$iter/$$luafile; \ + echo "Fetching $$luaurl"; \ + if $(CURL) -R -O $$luaurl ; then \ + if [ -z $(NOCHKSUM) ]; then \ + echo "Searching for known checksum"; \ CHKSUMS=../submodules/CHKSUMS; \ CHKSUMSTMP=../submodules/CHKSUMS.tmp; \ fgrep $$luafile < $$CHKSUMS > $$CHKSUMSTMP; \ if [ -z $$CHKSUMSTMP ]; then \ - echo "Cannot check $$luafile - no checksum known"; \ + echo "Cannot check $$luafile - no checksum known"; \ + echo "Rerun with 'NOCHKSUM=1' to skip this check"; \ + exit 1; \ else \ - echo Checking integrity of $$luafile with $$shac; \ - $$shac -w --ignore-missing -c $$CHKSUMSTMP < $$luafile; \ + echo "Checksum found"; \ + chksum_or_fail $$luafile; \ fi; \ - fi; \ - tar zxf $$luafile && \ - rm -f $$luafile; \ - fi; \ + fi; \ + `: If we can unpack it, we are done.`; \ + untar_and_cleanup $$luafile && exit 0; \ + `: fallthrough to next source `; \ fi; \ - done; \ - true ) - + done; \ + echo "Unable to find a valid source - STOPPING" \ + exit 1; \ + ) # remove include/nhlua.h in case it was created for some other Lua version @( if test -f include/nhlua.h ; then \ - rm -f include/nhlua.h && echo 'rm include/nhlua.h' ; fi ) + rm -f include/nhlua.h && echo 'rm include/nhlua.h' ; fi ) fetch-lua-http: ( mkdir -p lib && cd lib && \ From 9d44b1dbce75f1dba0e80c4c4e91b2b1f34f8c08 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 9 Jun 2026 22:49:36 -0400 Subject: [PATCH 470/702] follow-up: fixes5-0-1.txt --- doc/fixes5-0-1.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 3832e4f35..22147068f 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -170,6 +170,8 @@ MS-DOS: VESA and 16 color modes: Pass correct parameters to vga_userpan emulations don't report CTRL with up or down arrows, so accept CTRL-home, CTRL-page up, CTRL page down and CTRL-end (pr #1579 by chasonr) +MS-DOS: 16 color mode: Set the panning direction so CTRL-left and CTRL-right + pan in the same direction as 3.4.3. (pr #1579 by chasonr) musl: musl libc does not have __sighandler_t so don't use it in the macro definition for SIG_RET_TYPE with musl WASM: resolve some build failures in 'make CROSS_TO_WASM=1' From e5a3ec92198c4de7751f5c36be44498af6f775e6 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 9 Jun 2026 22:50:33 -0400 Subject: [PATCH 471/702] follow-up: whitespace bit --- doc/fixes5-0-1.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 22147068f..c3f747534 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -171,7 +171,7 @@ MS-DOS: VESA and 16 color modes: Pass correct parameters to vga_userpan CTRL-home, CTRL-page up, CTRL page down and CTRL-end (pr #1579 by chasonr) MS-DOS: 16 color mode: Set the panning direction so CTRL-left and CTRL-right - pan in the same direction as 3.4.3. (pr #1579 by chasonr) + pan in the same direction as 3.4.3. (pr #1579 by chasonr) musl: musl libc does not have __sighandler_t so don't use it in the macro definition for SIG_RET_TYPE with musl WASM: resolve some build failures in 'make CROSS_TO_WASM=1' From 49ac96188432483317bc9ecefed79a41ca18cfc6 Mon Sep 17 00:00:00 2001 From: Patric Mueller Date: Wed, 10 Jun 2026 09:45:58 +0200 Subject: [PATCH 472/702] replace NOTPARMDECL with TPARM_WORKAROUND The old logic used a negative check to emit an extern declaration for tparm(). This guarded against old platforms whose curses implementations did not declare their own functions. If there are still any platforms left that need this declaration, they can set TPARM_WORKAROUND to get the old behavior back. --- sys/unix/Install.unx | 8 ++++---- sys/unix/NetHack.xcodeproj/project.pbxproj | 8 -------- sys/unix/hints/include/compiler.500 | 4 ++-- sys/unix/hints/include/cross-pre2.500 | 4 ++-- util/mdgrep.pl | 2 +- win/tty/termcap.c | 3 +-- 6 files changed, 10 insertions(+), 19 deletions(-) diff --git a/sys/unix/Install.unx b/sys/unix/Install.unx index b257ff164..c2230a452 100644 --- a/sys/unix/Install.unx +++ b/sys/unix/Install.unx @@ -246,10 +246,10 @@ Notes: 13. If you get a compiler warning about 'get_colors()' being implicitly declared, try uncommenting NEED_GET_COLORS_DECL in unixconf.h. - If you get a compiler complaint about tparmdecl() having conflicting - declarations, add '#define NOTPARMDECL' to unixconf.h or '-DNOTPARMDECL' - to CFLAGS in src/Makefile. (The hints files for Mac OSX already do the - latter.) + If you get a compiler warning about tparm() being implicitly + declared, add '#define TPARM_WORKAROUND' to unixconf.h or + '-DTPARM_WORKAROUND' to CFLAGS. (This should not be needed + on any modern system.) # NetHack 5.0 Install.unx $NHDT-Date: 1577568915 2019/12/28 21:35:15 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ # Copyright (c) 2012 by Kenneth Lorber, Kensington, Maryland diff --git a/sys/unix/NetHack.xcodeproj/project.pbxproj b/sys/unix/NetHack.xcodeproj/project.pbxproj index 81a1eb1b9..21666b10e 100644 --- a/sys/unix/NetHack.xcodeproj/project.pbxproj +++ b/sys/unix/NetHack.xcodeproj/project.pbxproj @@ -2219,7 +2219,6 @@ ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = ( "-DNOMAIL", - "-DNOTPARMDECL", "-DDEFAULT_WINDOW_SYS=\\\"tty\\\"", "-DDLB", "-DGREPPATH=\\\"/usr/bin/grep\\\"", @@ -2301,7 +2300,6 @@ NH_UTIL_DIR = "$(NH_ROOT_DIR)/util"; OTHER_CFLAGS = ( "-DNOMAIL", - "-DNOTPARMDECL", "-DDEFAULT_WINDOW_SYS=\\\"tty\\\"", "-DDLB", "-DGREPPATH=\\\"/usr/bin/grep\\\"", @@ -2332,7 +2330,6 @@ OTHER_CFLAGS = ( "-Wno-ambiguous-macro", "-DNOMAIL", - "-DNOTPARMDECL", "-DDEFAULT_WINDOW_SYS=\\\"tty\\\"", "-DDLB", "-DGREPPATH=\\\"/usr/bin/grep\\\"", @@ -2366,7 +2363,6 @@ OTHER_CFLAGS = ( "-Wno-ambiguous-macro", "-DNOMAIL", - "-DNOTPARMDECL", "-DDEFAULT_WINDOW_SYS=\\\"tty\\\"", "-DDLB", "-DGREPPATH=\\\"/usr/bin/grep\\\"", @@ -2415,7 +2411,6 @@ OTHER_CFLAGS = ( "-DMINIMAL_FOR_RECOVER", "-DNOMAIL", - "-DNOTPARMDECL", "-DDEFAULT_WINDOW_SYS=\\\"tty\\\"", "-DDLB", "-DGREPPATH=\\\"/usr/bin/grep\\\"", @@ -2442,7 +2437,6 @@ OTHER_CFLAGS = ( "-DMINIMAL_FOR_RECOVER", "-DNOMAIL", - "-DNOTPARMDECL", "-DDEFAULT_WINDOW_SYS=\\\"tty\\\"", "-DDLB", "-DGREPPATH=\\\"/usr/bin/grep\\\"", @@ -2498,7 +2492,6 @@ MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; OTHER_CFLAGS = ( "-DNOMAIL", - "-DNOTPARMDECL", "-DDEFAULT_WINDOW_SYS=\\\"tty\\\"", "-DDLB", "-DGREPPATH=\\\"/usr/bin/grep\\\"", @@ -2535,7 +2528,6 @@ MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; OTHER_CFLAGS = ( "-DNOMAIL", - "-DNOTPARMDECL", "-DDEFAULT_WINDOW_SYS=\\\"tty\\\"", "-DDLB", "-DGREPPATH=\\\"/usr/bin/grep\\\"", diff --git a/sys/unix/hints/include/compiler.500 b/sys/unix/hints/include/compiler.500 index acc5662d1..aa140c413 100755 --- a/sys/unix/hints/include/compiler.500 +++ b/sys/unix/hints/include/compiler.500 @@ -49,7 +49,7 @@ endif #CC= clang #CXX=clang++ -std=gnu++11 -CFLAGS=$(CCFLAGS) -I../include -DNOTPARMDECL +CFLAGS=$(CCFLAGS) -I../include CFLAGS+=-Wall -Wextra \ -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings CFLAGS+=-pedantic @@ -133,7 +133,7 @@ endif # clang-specific ends here ifdef MAKEFILE_SRC ifdef CPLUSPLUS_NEEDED -CCXXFLAGS = -g -I../include -DNOTPARMDECL +CCXXFLAGS = -g -I../include CCXXFLAGS+=-Wall -Wextra -Wno-missing-field-initializers \ -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings CCXXFLAGS+=-pedantic diff --git a/sys/unix/hints/include/cross-pre2.500 b/sys/unix/hints/include/cross-pre2.500 index ef6f1c04f..3a69cbe9f 100644 --- a/sys/unix/hints/include/cross-pre2.500 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -338,8 +338,8 @@ WASM_CFLAGS += -Wshadow # Nethack C flags WASM_CFLAGS += $(WINCFLAGS) #WINCFLAGS set from multiw-2.500 WASM_CFLAGS += -DSYSCF -DSYSCF_FILE=\"/sysconf\" -DSECURE -DNHUUID -#WASM_CFLAGS += -g -I../include -DNOTPARMDECL -WASM_CFLAGS += -I../include -DNOTPARMDECL +#WASM_CFLAGS += -g -I../include +WASM_CFLAGS += -I../include # NetHack sources control WASM_CFLAGS += -DDLB WASM_CFLAGS += -DHACKDIR=\"$(HACKDIR)\" diff --git a/util/mdgrep.pl b/util/mdgrep.pl index 24dd3d0a8..888820a4c 100644 --- a/util/mdgrep.pl +++ b/util/mdgrep.pl @@ -51,7 +51,7 @@ $specials = { # TIMED_DELAY DEF_MAILREADER DEF_PAGER NO_SIGNAL PC_LOCKING LATTICE __GO32__ # msleep NO_FILE_LINKS bsdi HPUX AMIFLUSH # SCREEN_BIOS SCREEN_DJGPPFAST SCREEN_VGA SCREEN_8514 -# EXEPATH NOTSTDC SELECTSAVED NOTPARMDECL +# EXEPATH NOTSTDC SELECTSAVE # constants @const_true = qw/1 TRUE/; diff --git a/win/tty/termcap.c b/win/tty/termcap.c index ff8c4c2bf..a44e84ca5 100644 --- a/win/tty/termcap.c +++ b/win/tty/termcap.c @@ -895,8 +895,7 @@ cl_eos(void) /* free after Robert Viduya */ #include -#if !defined(LINUX) && !defined(__FreeBSD__) && !defined(__OpenBSD__) \ - && !defined(NOTPARMDECL) +#if defined(TPARM_WORKAROUND) extern char *tparm(); #endif From 958415607b0d3c1c8a9a1c80c58bd4b4e7cf6345 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 10 Jun 2026 15:52:13 -0400 Subject: [PATCH 473/702] periodic style check: whitespace cleanup leading tabs and trailing blanks --- include/integer.h | 2 +- include/revision.h | 2 +- include/unixconf.h | 8 ++++---- src/dothrow.c | 10 +++++----- src/hacklib.c | 2 +- src/options.c | 4 ++-- src/sfbase.c | 9 +++++---- 7 files changed, 19 insertions(+), 18 deletions(-) diff --git a/include/integer.h b/include/integer.h index 479ccc9bd..64d597030 100644 --- a/include/integer.h +++ b/include/integer.h @@ -50,7 +50,7 @@ #endif /* !HAS_INTTYPES_H */ #if defined(__GNUC__) && defined(__INT64_MAX__) && !defined(HAS_STDINT_H) #define HAS_STDINT_H -#endif +#endif #endif /* claims to be C99 */ #endif /*?__DECC*/ diff --git a/include/revision.h b/include/revision.h index efb21bb30..70c0dd6fe 100644 --- a/include/revision.h +++ b/include/revision.h @@ -171,7 +171,7 @@ * extern void uplift_mystruct_rev0_to_mystruct(struct mystruct_rev0 *, * struct mystruct *); * - * 17. Add the uplift function to src/revision.c. It needs to do + * 17. Add the uplift function to src/revision.c. It needs to do * field-by-field copies of the fields that exist in the old * revision and the new revision. For now, it likely needs to * be handcrafted using your knowledge of the struct's old diff --git a/include/unixconf.h b/include/unixconf.h index 0bae0ddf0..ffe5d7a03 100644 --- a/include/unixconf.h +++ b/include/unixconf.h @@ -332,15 +332,15 @@ #endif #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) -#define tparm2(s, x) tparm(s,x,0,0,0,0,0,0,0,0) +#define tparm2(s, x) tparm(s,x,0,0,0,0,0,0,0,0) #else -#define tparm2(s, x) tparm(s,x) +#define tparm2(s, x) tparm(s,x) #endif #if defined(BSD) || defined(ULTRIX) #if !defined(DGUX) && !defined(SUNOS4) \ - && !defined(__NetBSD__) && !defined(__FreeBSD__) \ - && !defined(__OpenBSD__) + && !defined(__NetBSD__) && !defined(__FreeBSD__) \ + && !defined(__OpenBSD__) #define memcpy(d, s, n) bcopy(s, d, n) #define memcmp(s1, s2, n) bcmp(s2, s1, n) #endif diff --git a/src/dothrow.c b/src/dothrow.c index 45a0e00cf..4d61959eb 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1757,11 +1757,11 @@ throwit( } if (!dmg) { if (tethered_weapon) { - /* Blind mods unnecessary; you know what you threw, - * and it is tethered to your arm */ - pline("Your tethered %s snaps back but the tether slips from your %s.", - simpleonames(obj), body_part(ARM)); - tether_released_msg = TRUE; + /* Blind mods unnecessary; you know what you threw, + * and it is tethered to your arm */ + pline("Your tethered %s snaps back but the tether slips from your %s.", + simpleonames(obj), body_part(ARM)); + tether_released_msg = TRUE; } else { pline(Blind ? "%s lands %s your %s." diff --git a/src/hacklib.c b/src/hacklib.c index 103443c0d..35757e4ed 100644 --- a/src/hacklib.c +++ b/src/hacklib.c @@ -974,7 +974,7 @@ static struct datamodel_information dm[] = { "", "" }, { { 2, 4, 4, 8, 4 }, "ILP32LL64", "x86 32-bit" }, /* Windows or Unix */ { { 2, 4, 4, 8, 8 }, "IL32LLP64", "Windows x64 64-bit" }, - { { 2, 4, 8, 8, 8 }, "I32LP64", "Unix 64-bit"}, + { { 2, 4, 8, 8, 8 }, "I32LP64", "Unix 64-bit"}, { { 2, 8, 8, 8, 8 }, "ILP64", "Unix ILP64"}, /* HAL, SPARC64 */ }; diff --git a/src/options.c b/src/options.c index bfcef4576..e9c576399 100644 --- a/src/options.c +++ b/src/options.c @@ -5314,7 +5314,7 @@ optfn_boolean( #ifndef IDLECHECKPOINT case opt_idlecheckpoint: pline("There is no underlying support for 'idlecheckpoint'" - " compiled in."); + " compiled in."); iflags.idlecheckpoint = FALSE; give_opt_msg = FALSE; break; @@ -7430,7 +7430,7 @@ allopt_array_init(void) if (allopt[i].opttyp == BoolOpt && i != opt_ascii_map) allopt[i].initval = allopt[i].opt_in_out; #endif - *(allopt[i].addr) = allopt[i].initval; + *(allopt[i].addr) = allopt[i].initval; } } heed_all_options(); diff --git a/src/sfbase.c b/src/sfbase.c index b26175b99..b78cd3167 100644 --- a/src/sfbase.c +++ b/src/sfbase.c @@ -106,7 +106,7 @@ void sf_log(NHFILE *, const char *, size_t, int, char *); #define Sfvalue_xint16(a) sfvalue(a) #endif -/* not in _Generic */ +/* not in _Generic */ #define Sfvalue_long(a) sfvalue_long(a) #define Sfvalue_ulong(a) sfvalue_ulong(a) #define Sfvalue_char(a, d) sfvalue_char(a, d) @@ -195,7 +195,7 @@ void sfi_##dtyp(NHFILE *nhfp, keyw dtyp *d_##dtyp, const char *myname) complex_dump((uchar *) d_##dtyp)); \ } \ } - + #define SF_X(xxx, dtyp) \ void sfo_##dtyp(NHFILE *nhfp, xxx *d_##dtyp, const char *myname, int bfsz) \ { \ @@ -461,7 +461,7 @@ sfvalue_genericptr(genericptr a) { static char buf[20]; - Snprintf(buf, sizeof buf, "%s", + Snprintf(buf, sizeof buf, "%s", (a == 0) ? "0" : "glorkum"); return buf; } @@ -632,7 +632,8 @@ complex_dump(uchar *a) for (i = 0; i < SIZE(x); ++i) { x[i] = *uc++; } - Snprintf(buf, sizeof buf, "%03x %03x %03x %03x %03x %03x %03x %03x %03x %03x", + Snprintf(buf, sizeof buf, + "%03x %03x %03x %03x %03x %03x %03x %03x %03x %03x", x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9]); buf[40] = '\0'; return buf; From 0248dbf55026f114f0e37fcbc4bb6da52e15260b Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Wed, 10 Jun 2026 23:14:09 -0400 Subject: [PATCH 474/702] MSDOS: Accept only single character font mappings * makefont.lua generates incorrect PSF fonts. There can be multiple characters mapped to a single glyph, but the mappings should be separated by FE bytes. * font.c should accept only single character mappings -- not combining sequences. The bundled fonts have no combining sequences, but I am exploring other options that provide more Unicode coverate. --- sys/msdos/font.c | 24 ++++++++++++++++++++---- sys/msdos/fonts/makefont.lua | 3 +++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/sys/msdos/font.c b/sys/msdos/font.c index f3dfe7d10..810cb0139 100755 --- a/sys/msdos/font.c +++ b/sys/msdos/font.c @@ -112,11 +112,27 @@ load_font(const char *filename) bufsize -= strsize; memmove(buf, buf + strsize, bufsize); } - codepoints = uni_8to32(buf2); - for (j = 0; codepoints[j] != 0; ++j) { - add_unicode_index(font, codepoints[j], i); + /* Split the individual mappings and use only single character + mappings */ + char *start = buf2; + while (*start != '\0') { + /* Mapping ends with a 0xFE byte */ + char *end = strchr(start, 0xFE); + if (end == NULL) { + end = start + strlen(start); + } else { + *end = '\0'; + ++end; + } + /* Convert this mapping */ + codepoints = uni_8to32(start); + /* Accept it if it is a single character */ + if (codepoints[0] != 0 && codepoints[1] == 0) { + add_unicode_index(font, codepoints[0], i); + } + free(codepoints); + start = end; } - free(codepoints); if (p != NULL) ++i; } diff --git a/sys/msdos/fonts/makefont.lua b/sys/msdos/fonts/makefont.lua index 78ec760dd..3d9ada65b 100755 --- a/sys/msdos/fonts/makefont.lua +++ b/sys/msdos/fonts/makefont.lua @@ -220,6 +220,9 @@ end for i = 1, next_pos-1 do glyph = font[i] for j = 1, #glyph.code do + if j ~= 1 then + outfile:write("\xFE") + end outfile:write(utf8.char(glyph.code[j])) end outfile:write("\xFF") From 6c11cac0f7067d9aebff9b1c0f5de48e64cf05fb Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 11 Jun 2026 14:09:25 -0400 Subject: [PATCH 475/702] fixes5-0-1.txt entry for pull request #1581 --- doc/fixes5-0-1.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index c3f747534..ffa76e493 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -172,6 +172,10 @@ MS-DOS: VESA and 16 color modes: Pass correct parameters to vga_userpan (pr #1579 by chasonr) MS-DOS: 16 color mode: Set the panning direction so CTRL-left and CTRL-right pan in the same direction as 3.4.3. (pr #1579 by chasonr) +MS-DOS: makefont.lua was generating incorrect PSF fonts; there can be + multiple characters mapped to a single glyph, but the mappings + should be separated by FE bytes (pr #1581 by chasonr) +MS-DOS: accept only single character font mappings (pr #1581 by chasonr) musl: musl libc does not have __sighandler_t so don't use it in the macro definition for SIG_RET_TYPE with musl WASM: resolve some build failures in 'make CROSS_TO_WASM=1' From dfd6e0739ffaddff0c21565abd41a94e075672d7 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 12 Jun 2026 01:11:43 -0700 Subject: [PATCH 476/702] fix issue #1580 - item action for leash in use Issue reported by JodiJodington: the item action for a leash didn't distringuish a leash that is already in use from one that isn't. Fixes 1580 --- doc/fixes5-0-1.txt | 1 + src/iactions.c | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index ffa76e493..3fa4b761d 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -60,6 +60,7 @@ monsters (including pets) aren't scared of the Sokoban rolling boulder traps fix a bug in which steeds would continuously gain movement points while being ridden when hero's behavior makes erinyes stronger, cap level at 49 rather than 50 +with inventory item action for leash, distingluish leash-in-use from empty one Platform- and/or Interface-Specific Fixes diff --git a/src/iactions.c b/src/iactions.c index 164bf2f5b..62566569c 100644 --- a/src/iactions.c +++ b/src/iactions.c @@ -331,9 +331,17 @@ itemactions(struct obj *otmp) ia_addmenu(win, IA_APPLY_OBJ, 'a', "Use this tool to pick a lock"); else if (otmp->otyp == TINNING_KIT) ia_addmenu(win, IA_APPLY_OBJ, 'a', "Use this kit to tin a corpse"); - else if (otmp->otyp == LEASH) - ia_addmenu(win, IA_APPLY_OBJ, 'a', "Tie a pet to this leash"); - else if (otmp->otyp == SADDLE) + else if (otmp->otyp == LEASH) { + if (!otmp->leashmon) { + Strcpy(buf, "Attach this leash to a pet"); + } else { + mtmp = find_mid(otmp->leashmon, FM_FMON); + if (!mtmp) /* assume this won't happen */ + panic("Can't find leash's monster"); + Sprintf(buf, "Detach this leash from %s", some_mon_nam(mtmp)); + } + ia_addmenu(win, IA_APPLY_OBJ, 'a', buf); + } else if (otmp->otyp == SADDLE) ia_addmenu(win, IA_APPLY_OBJ, 'a', "Place this saddle on a pet"); else if (otmp->otyp == MAGIC_WHISTLE || otmp->otyp == TIN_WHISTLE) From b0e24236e33fe6a6d6d3966581fbc17e0230f805 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 12 Jun 2026 06:07:27 -0400 Subject: [PATCH 477/702] update tested versions of Visual Studio 2026-06-12 --- sys/windows/Makefile.nmake | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index a90c673c3..1029b68a9 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -9,7 +9,7 @@ # # Visual Studio Compilers Tested: # - Microsoft Visual Studio Community 2022 v 17.14.33 -# - Microsoft Visual Studio Community 2026 v 18.6.2 +# - Microsoft Visual Studio Community 2026 v 18.7.0 # #============================================================================== # This is used for building two distinct executables of NetHack: @@ -1204,8 +1204,7 @@ rc=Rc.exe # # Recently tested versions: TESTEDVS2022 = 14.44.35225.0 -TESTEDVS2026 = 14.51.36244.0 -TESTEDVS2026 = 14.51.36246.0 +TESTEDVS2026 = 14.51.36247.0 VS20261ST = 1450000000 VS2026CUR = $(TESTEDVS2026:.=) From 8e9d23b5787c05ccde89a22a4acde46fe0fe3930 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 12 Jun 2026 11:00:28 -0400 Subject: [PATCH 478/702] msdos warning bit ../sys/msdos/font.c: In function 'load_font': ../sys/msdos/font.c:89:22: warning: unused variable 'j' [-Wunused-variable] 89 | unsigned j; | ^ --- sys/msdos/font.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/msdos/font.c b/sys/msdos/font.c index 810cb0139..3d2c6471f 100755 --- a/sys/msdos/font.c +++ b/sys/msdos/font.c @@ -86,7 +86,7 @@ load_font(const char *filename) bufsize = 0; i = 0; while (i < length) { - unsigned j; + /* unsigned j; */ size = fread(buf + bufsize, 1, sizeof(buf) - bufsize, fp); if (ferror(fp)) goto error; From d13eceb28bc84a36d09254a7e1d8b939115afab6 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 14 Jun 2026 14:19:34 -0400 Subject: [PATCH 479/702] eliminate one more source of vault guard newsym msgs see_monsters() was producing spurious vault guard at 0,0 messages Reproduce issue by: 1. Entering vault via teleport. 2. Wait for guard to enter. 3. Drop gold (if necessary) and follow guard. 4. Right after the guard disappears, but before the corridor does, the following can lead to the messages: a) control-R to refresh the display. or b) save the game and restore. In both cases, see_monsters() will get called and lead to the spurious messages for the vault guard that is parked. Also, add a macro PARKEDMONSTER(mon) instead of checking the the isgd bit and the value of mon->mx being zero in multiple places Also, adds MON_PARKED bit to mstate. Currently the PARKEDMONSTER(mon) macro mentioned above, does not use the new bit. --- include/monst.h | 25 +++++++++++++++---------- src/detect.c | 22 +++++++++++----------- src/display.c | 2 +- src/light.c | 4 ++-- src/minion.c | 4 +--- src/mon.c | 2 +- src/monmove.c | 2 +- src/restore.c | 7 +++++++ src/steed.c | 20 ++++++++++++++++---- src/vault.c | 5 ++++- src/wizcmds.c | 1 + 11 files changed, 60 insertions(+), 34 deletions(-) diff --git a/include/monst.h b/include/monst.h index a94bf2bc7..3a9bf151a 100644 --- a/include/monst.h +++ b/include/monst.h @@ -55,16 +55,17 @@ enum m_ap_types { M_AP_MONSTER = 3 /* a monster; mostly used for cloned Wizard */ }; -#define MON_FLOOR 0x00 -#define MON_OFFMAP 0x01 -#define MON_DETACH 0x02 -#define MON_MIGRATING 0x04 -#define MON_LIMBO 0x08 -#define MON_BUBBLEMOVE 0x10 -#define MON_ENDGAME_FREE 0x20 -#define MON_ENDGAME_MIGR 0x40 -#define MON_OBLITERATE 0x80 -#define MON_STILL_ARRIVING 0x100 +#define MON_FLOOR 0x0000 +#define MON_OFFMAP 0x0001 +#define MON_DETACH 0x0002 +#define MON_MIGRATING 0x0004 +#define MON_LIMBO 0x0008 +#define MON_BUBBLEMOVE 0x0010 +#define MON_ENDGAME_FREE 0x0020 +#define MON_ENDGAME_MIGR 0x0040 +#define MON_OBLITERATE 0x0080 +#define MON_STILL_ARRIVING 0x0100 +#define MON_PARKED 0x0200 #define M_AP_TYPMASK 0x7 #define M_AP_F_DKNOWN 0x8 @@ -212,6 +213,10 @@ struct monst { /* dead monsters stay on the fmon list until dmonsfree() at end of turn */ #define DEADMONSTER(mon) ((mon)->mhp < 1) +/* vault guards intentionally remain on the fmon list at 0,0 until + the temporary corridor is dealt with */ +#define PARKEDMONSTER(mon) ((mon)->isgd && (mon)->mx == 0) +/* eventually, we'll be able to use (((mon)->mstate & MON_PARKED) != 0) */ #define is_starting_pet(mon) ((mon)->m_id == svc.context.startingpet_mid) #define is_vampshifter(mon) \ diff --git a/src/detect.c b/src/detect.c index 11c370a05..ef9348001 100644 --- a/src/detect.c +++ b/src/detect.c @@ -345,7 +345,7 @@ gold_detect(struct obj *sobj) /* look for gold carried by monsters (might be in a container) */ for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)) continue; if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) { if (mtmp == u.usteed) { @@ -433,7 +433,7 @@ gold_detect(struct obj *sobj) ugold = TRUE; } for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)) continue; temp = 0; if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) { @@ -497,7 +497,7 @@ food_detect(struct obj *sobj) ct++; } for (mtmp = fmon; mtmp && (!ct || !ctu); mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)) continue; for (obj = mtmp->minvent; obj; obj = obj->nobj) if (o_in(obj, oclass)) { @@ -561,7 +561,7 @@ food_detect(struct obj *sobj) map_object(temp, 1); } for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)) continue; for (obj = mtmp->minvent; obj; obj = obj->nobj) if ((temp = o_in(obj, oclass)) != 0) { @@ -666,7 +666,7 @@ object_detect(struct obj *detector, /* object doing the detecting */ u.usteed->mx = u.ux, u.usteed->my = u.uy; for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)) continue; for (obj = mtmp->minvent; obj; obj = obj->nobj) { if ((!class && !boulder) || o_in(obj, class) @@ -736,7 +736,7 @@ object_detect(struct obj *detector, /* object doing the detecting */ /* Objects in the monster's inventory override floor objects. */ for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)) continue; for (obj = mtmp->minvent; obj; obj = obj->nobj) if ((!class && !boulder) || (otmp = o_in(obj, class)) != 0 @@ -807,7 +807,7 @@ monster_detect(struct obj *otmp, /* detecting object (if any) */ * with positive hit-points to know for sure. */ for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)) continue; ++mcnt; break; /* no need for full count, just 1 or more vs 0 */ @@ -826,7 +826,7 @@ monster_detect(struct obj *otmp, /* detecting object (if any) */ cls(); unconstrained = unconstrain_map(); for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)) continue; if (!mclass || mtmp->data->mlet == mclass || (mtmp->data == &mons[PM_LONG_WORM] @@ -969,7 +969,7 @@ display_trap_map(int cursed_src) (void) detect_obj_traps(svl.level.buriedobjlist, TRUE, cursed_src, NULL); (void) detect_obj_traps(fobj, TRUE, cursed_src, NULL); for (mon = fmon; mon; mon = mon->nmon) { - if (DEADMONSTER(mon) || (mon->isgd && !mon->mx)) + if (DEADMONSTER(mon) || PARKEDMONSTER(mon)) continue; (void) detect_obj_traps(mon->minvent, TRUE, cursed_src, NULL); } @@ -1046,7 +1046,7 @@ trap_detect( found = TRUE; } for (mon = fmon; mon; mon = mon->nmon) { - if (DEADMONSTER(mon) || (mon->isgd && !mon->mx)) + if (DEADMONSTER(mon) || PARKEDMONSTER(mon)) continue; if ((tr = detect_obj_traps(mon->minvent, FALSE, 0, NULL)) != OTRAP_NONE) { @@ -1643,7 +1643,7 @@ findone(coordxy zx, coordxy zy, genericptr_t whatfound) struct monst *mtmp = m_at(zx, zy); struct found_things *found_p = (struct found_things *) whatfound; - if (mtmp && (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))) + if (mtmp && (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp))) mtmp = (struct monst *) NULL; found_p->ft_cc.x = zx; /* needed by detect_obj_traps() */ found_p->ft_cc.y = zy; diff --git a/src/display.c b/src/display.c index ffb9b2cbc..76daaa30b 100644 --- a/src/display.c +++ b/src/display.c @@ -1544,7 +1544,7 @@ see_monsters(void) /* loop through level.monsters (aka fmon) */ for (mon = fmon; mon; mon = mon->nmon) { - if (DEADMONSTER(mon)) + if (DEADMONSTER(mon) || PARKEDMONSTER(mon)) continue; if ((mon->mstate & MON_STILL_ARRIVING) != 0) continue; diff --git a/src/light.c b/src/light.c index fd41acd73..48f3671b1 100644 --- a/src/light.c +++ b/src/light.c @@ -303,7 +303,7 @@ show_transient_light(struct obj *obj, coordxy x, coordxy y) radius_squared = ls->range * ls->range; for (mon = fmon; mon; mon = mon->nmon) { - if (DEADMONSTER(mon) || (mon->isgd && !mon->mx)) + if (DEADMONSTER(mon) || PARKEDMONSTER(mon)) continue; /* light range is the radius of a circle and we're limiting canseemon() to a square enclosing that circle, but setting @@ -343,7 +343,7 @@ transient_light_cleanup(void) so need to be replaced by "remembered, unseen monster" glyph */ mtempcount = 0; for (mon = fmon; mon; mon = mon->nmon) { - if (DEADMONSTER(mon)) + if (DEADMONSTER(mon) || PARKEDMONSTER(mon)) continue; if (mon->mtemplit) { mon->mtemplit = 0; diff --git a/src/minion.c b/src/minion.c index b161f928d..03a782727 100644 --- a/src/minion.c +++ b/src/minion.c @@ -43,9 +43,7 @@ monster_census(boolean spotted) /* seen|sensed vs all */ int count = 0; for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp)) - continue; - if (mtmp->isgd && mtmp->mx == 0) + if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)) continue; if (spotted && !canspotmon(mtmp)) continue; diff --git a/src/mon.c b/src/mon.c index a69a1aedf..3e86cb730 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1230,7 +1230,7 @@ movemon_singlemon(struct monst *mtmp) off the map too; gd_move() decides whether the temporary corridor can be removed and guard discarded (via clearing mon->isgd flag so that dmonsfree() will get rid of mon) */ - if (mtmp->isgd && !mtmp->mx && !(mtmp->mstate & MON_MIGRATING)) { + if (PARKEDMONSTER(mtmp) && !(mtmp->mstate & MON_MIGRATING)) { /* parked at <0,0>; eventually isgd should get set to false */ if (svm.moves > mtmp->mlstmv) { (void) gd_move(mtmp); diff --git a/src/monmove.c b/src/monmove.c index 340c2f628..10a97675a 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -922,7 +922,7 @@ dochug(struct monst *mtmp) /*FALLTHRU*/ case MMOVE_NOTHING: /* no movement, but it can still attack you */ case MMOVE_DONE: /* absolutely no movement */ - /* vault guard might have vanished */ + /* vault guard might have vanished; PARKEDMONSTER(mtmp) */ if (mtmp->isgd && (DEADMONSTER(mtmp) || mtmp->mx == 0)) return 1; /* behave as if it died */ /* During hallucination, monster appearance should diff --git a/src/restore.c b/src/restore.c index 0cc82f30f..2c9a01a75 100644 --- a/src/restore.c +++ b/src/restore.c @@ -448,6 +448,13 @@ restmonchn(NHFILE *nhfp) restshk(mtmp, ghostly); if (mtmp->ispriest) restpriest(mtmp, ghostly); + if (mtmp->isgd) { + /* fixup for new bit MON_PARKED added post 5.0.0 */ + if (!mtmp->mx + && (mtmp->mstate & MON_PARKED) == 0L + && (mtmp->mstate & MON_MIGRATING) == 0L) + mtmp->mstate |= MON_PARKED; + } if (!ghostly) { if (mtmp->m_id == svc.context.polearm.m_id) diff --git a/src/steed.c b/src/steed.c index a9c1ad7d0..536feec6f 100644 --- a/src/steed.c +++ b/src/steed.c @@ -903,8 +903,10 @@ place_monster(struct monst *mon, coordxy x, coordxy y) buf[0] = '\0'; /* normal map bounds are <1..COLNO-1,0..ROWNO-1> but sometimes - vault guards (either living or dead) are parked at <0,0> */ - if (!isok(x, y) && (x != 0 || y != 0 || !mon->isgd)) { + vault guards (either living or dead) are parked at <0,0>; + their mstate should have the MON_PARKED bit set (post-5.0.0) */ + if (!isok(x, y) + && !(((mon->mstate & MON_PARKED) != 0) || PARKEDMONSTER(mon))) { describe_level(buf, 0); impossible("trying to place %s at <%d,%d> mstate:%lx on %s", minimal_monnam(mon, TRUE), x, y, mon->mstate, buf); @@ -912,7 +914,7 @@ place_monster(struct monst *mon, coordxy x, coordxy y) } if ((mon == u.usteed && !gi.in_steed_dismounting) /* special case is for convoluted vault guard handling */ - || (DEADMONSTER(mon) && !(mon->isgd && x == 0 && y == 0))) { + || (DEADMONSTER(mon) && !PARKEDMONSTER(mon))) { describe_level(buf, 0); impossible("placing %s onto map, mstate:%lx, on %s?", (mon == u.usteed) ? "steed" : "defunct monster", @@ -928,7 +930,17 @@ place_monster(struct monst *mon, coordxy x, coordxy y) } mon->mx = x, mon->my = y; svl.level.monsters[x][y] = mon; - mon->mstate = MON_FLOOR; + /* even though MON_FLOOR is not actually a bit currently + (MON_FLOOR == 0) we want to preserve some of the other + bits that may be set. We'll probably make MON_FLOOR an + actual bit one day */ + + mon->mstate &= ~(MON_OFFMAP | MON_DETACH | MON_LIMBO | MON_MIGRATING); + + /* We don't mess with these bits above: + MON_BUBBLEMOVE | MON_ENDGAME_FREE | MON_ENDGAME_MIGR + | MON_OBLITERATE | MON_STILL_ARRIVING | MON_PARKED + */ } /*steed.c*/ diff --git a/src/vault.c b/src/vault.c index 32d9e84b0..94f50d909 100644 --- a/src/vault.c +++ b/src/vault.c @@ -146,6 +146,7 @@ restfakecorr(struct monst *grd) /* it seems you left the corridor - let the guard disappear */ if (clear_fcorr(grd, FALSE)) { grd->isgd = 0; /* dmonsfree() should delete this mon */ + grd->mstate &= ~MON_PARKED; mongone(grd); } } @@ -162,8 +163,10 @@ parkguard(struct monst *grd) remove_monster(grd->mx, grd->my); newsym(grd->mx, grd->my); } - if (m_at(0, 0) != grd) + if (m_at(0, 0) != grd) { + grd->mstate |= MON_PARKED; place_monster(grd, 0, 0); + } /* [grd->mx,my just got set to 0,0 by place_monster(), so this just sets EGD(grd)->ogx,ogy to 0,0 too; is that what we want?] */ EGD(grd)->ogx = grd->mx; diff --git a/src/wizcmds.c b/src/wizcmds.c index 60b991db9..e7fda43ea 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -98,6 +98,7 @@ makemap_unmakemon(struct monst *mtmp, boolean migratory) mongone() -> m_detach() -> mon_leaving_level() copes with that */ mtmp->mstate |= MON_OFFMAP; mtmp->mstate &= ~(MON_MIGRATING | MON_LIMBO | MON_ENDGAME_MIGR); + /* FIXME: will post-5.0.0 MON_PARKED need to be dealt with here? */ mtmp->nmon = fmon; fmon = mtmp; } From 6d0757fc864f3d92888dc5c1f901097fc92b0471 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 16 Jun 2026 19:56:30 -0400 Subject: [PATCH 480/702] Fix MS-DOS crosscompile on macOS host --- sys/unix/hints/include/cross-pre2.500 | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/unix/hints/include/cross-pre2.500 b/sys/unix/hints/include/cross-pre2.500 index 3a69cbe9f..b5efbb377 100644 --- a/sys/unix/hints/include/cross-pre2.500 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -135,6 +135,7 @@ override TARGET_CXX = $(TOOLTOP1)/i586-pc-msdosdjgpp-g++ override TARGET_AR = $(TOOLTOP1)/i586-pc-msdosdjgpp-gcc-ar override TARGET_STUBEDIT = ../lib/djgpp/i586-pc-msdosdjgpp/bin/stubedit override GENTILEOFILE = $(TARGETPFX)tile.o +override UUIDOBJ = ifdef MAKEFILE_SRC FLDR=../ endif From 118899a5f0dfcce29078ebc41476e5d2e50cac04 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 18 Jun 2026 09:48:34 -0400 Subject: [PATCH 481/702] update tested versions of Visual Studio 2026-06-18 --- sys/windows/Makefile.nmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index 1029b68a9..5a0906c8b 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -8,8 +8,8 @@ # MS Visual Studio Visual C++ compiler # # Visual Studio Compilers Tested: -# - Microsoft Visual Studio Community 2022 v 17.14.33 -# - Microsoft Visual Studio Community 2026 v 18.7.0 +# - Microsoft Visual Studio Community 2022 v 17.14.35 +# - Microsoft Visual Studio Community 2026 v 18.7.1 # #============================================================================== # This is used for building two distinct executables of NetHack: @@ -1204,7 +1204,7 @@ rc=Rc.exe # # Recently tested versions: TESTEDVS2022 = 14.44.35225.0 -TESTEDVS2026 = 14.51.36247.0 +TESTEDVS2026 = 14.51.36248.0 VS20261ST = 1450000000 VS2026CUR = $(TESTEDVS2026:.=) From b54c38c65bce32c1fab174dec4651d1220775396 Mon Sep 17 00:00:00 2001 From: copperwater Date: Fri, 19 Jun 2026 08:40:35 -0400 Subject: [PATCH 482/702] Fix: a shopkeeper msg was printed even when deaf The message in question is '[shopkeeper] says "You be careful with my [item]!"' when you wield a shop-owned item, but it was being printed even when the hero is deaf. Following other examples of shopkeeper dialogue, the correct thing to do here is not to suppress the message if deaf but instead provide some nonverbal feedback, so that is what I did. --- src/wield.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/wield.c b/src/wield.c index 7c75cab31..51920b7d4 100644 --- a/src/wield.c +++ b/src/wield.c @@ -262,8 +262,13 @@ ready_weapon(struct obj *wep) if ((this_shkp = shop_keeper(inside_shop(u.ux, u.uy))) != (struct monst *) 0) { - pline("%s says \"You be careful with my %s!\"", - shkname(this_shkp), xname(wep)); + /* check msound because we don't have access to muteshk() */ + if (!Deaf && this_shkp->data->msound > MS_ANIMAL) + pline("%s says \"You be careful with my %s!\"", + shkname(this_shkp), xname(wep)); + else + pline("%s looks apprehensive about your wielding %s %s.", + shkname(this_shkp), mhis(this_shkp), xname(wep)); } } } From 7a23470c33513fdd6d458f1ea1e328454ca56520 Mon Sep 17 00:00:00 2001 From: copperwater Date: Fri, 19 Jun 2026 09:27:25 -0400 Subject: [PATCH 483/702] Fix: thrown ball travel did not check for regions This is an issue that we discovered in TNNT last year when we added a custom region with effects that trigger upon entry: it was possible to bypass those effects by entering the region via a thrown iron ball. This can be demonstrated by creating a poison gas cloud and then dragging oneself inside the cloud behind a thrown ball: you land in the cloud and are surrounded by poisonous gas, but are unharmed by it. This commit fixes the iron ball code to call in_out_region when appropriate, which handles the side effects of entering and exiting regions in addition to preventing travel into or out of a hypothetical region that blocks entry or exit. --- src/ball.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ball.c b/src/ball.c index b622cb691..1531c3b9e 100644 --- a/src/ball.c +++ b/src/ball.c @@ -808,7 +808,8 @@ drag_ball(coordxy x, coordxy y, int *bc_control, miss(xname(uball), victim); } /* now check again in case mon died */ - if (!m_at(uchain->ox, uchain->oy)) { + if (!m_at(uchain->ox, uchain->oy) + && in_out_region(uchain->ox, uchain->oy)) { u.ux = uchain->ox; u.uy = uchain->oy; newsym(u.ux0, u.uy0); @@ -820,6 +821,9 @@ drag_ball(coordxy x, coordxy y, int *bc_control, *ballx = uchain->ox; *bally = uchain->oy; move_bc(0, *bc_control, *ballx, *bally, *chainx, *chainy); + /* weirdness: you were dragged back on account of the ball falling + * into the pit, but if you escape the pit, the ball is "on top of" + * the pit and does not hinder your movement further */ spoteffects(TRUE); return FALSE; } @@ -932,10 +936,11 @@ drop_ball(coordxy x, coordxy y) && (is_pool(x, y) || ((t = t_at(x, y)) && (is_pit(t->ttyp) - || is_hole(t->ttyp))))) { + || is_hole(t->ttyp)))) + && in_out_region(x, y)) { u.ux = x; u.uy = y; - } else { + } else if (in_out_region(x - u.dx, y - u.dy)) { u.ux = x - u.dx; u.uy = y - u.dy; } From 04963ecf81ac7ff7f4786f3934b429ee208d57fb Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 19 Jun 2026 10:08:42 -0400 Subject: [PATCH 484/702] follow-up: add a general catch for "says" --- include/extern.h | 1 + src/minion.c | 3 ++- src/rumors.c | 5 +++-- src/shk.c | 6 ++++++ src/wield.c | 4 ++-- 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/include/extern.h b/include/extern.h index 194547d2b..5da653c38 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2996,6 +2996,7 @@ extern void credit_report(struct monst *shkp, int idx, boolean silent) NONNULLARG1; extern void use_unpaid_trapobj(struct obj *, coordxy, coordxy) NONNULLARG1; extern void noisy_shop(struct mkroom *); +extern const char *says(void); /* ### shknam.c ### */ diff --git a/src/minion.c b/src/minion.c index 03a782727..86a976908 100644 --- a/src/minion.c +++ b/src/minion.c @@ -299,7 +299,8 @@ demon_talk(struct monst *mtmp) pline("%s says, \"Good hunting, %s.\"", Amonnam(mtmp), flags.female ? "Sister" : "Brother"); else if (canseemon(mtmp)) - pline("%s says something.", Amonnam(mtmp)); + pline("%s %s something.", Amonnam(mtmp), + says()); if (!tele_restrict(mtmp)) (void) rloc(mtmp, RLOC_MSG); return 1; diff --git a/src/rumors.c b/src/rumors.c index 22d3e3077..b78bd2403 100644 --- a/src/rumors.c +++ b/src/rumors.c @@ -554,10 +554,11 @@ outrumor( switch (mechanism) { case BY_ORACLE: /* Oracle delivers the rumor */ - pline("True to her word, the Oracle %ssays: ", + pline("True to her word, the Oracle %s%s: ", (!rn2(4) ? "offhandedly " : (!rn2(3) ? "casually " - : (rn2(2) ? "nonchalantly " : "")))); + : (rn2(2) ? "nonchalantly " : ""))), + says()); SetVoice((struct monst *) 0, 0, 80, voice_oracle); verbalize1(line); /* [WIS exercised by getrumor()] */ diff --git a/src/shk.c b/src/shk.c index 749df40ae..117003f46 100644 --- a/src/shk.c +++ b/src/shk.c @@ -2049,6 +2049,12 @@ dopay(void) return paid ? ECMD_TIME : ECMD_OK; } +const char * +says(void) +{ + return Deaf ? "signs" : "says"; +} + /* for menustyle=Traditional, choose between paying for everything (by declining to itemize), asking item-by-item (by accepting itemization), or switch to selecting via menu (special 'm' answer at "Itemize? [ynq m]" diff --git a/src/wield.c b/src/wield.c index 51920b7d4..515caa938 100644 --- a/src/wield.c +++ b/src/wield.c @@ -264,8 +264,8 @@ ready_weapon(struct obj *wep) != (struct monst *) 0) { /* check msound because we don't have access to muteshk() */ if (!Deaf && this_shkp->data->msound > MS_ANIMAL) - pline("%s says \"You be careful with my %s!\"", - shkname(this_shkp), xname(wep)); + pline("%s %s \"You be careful with my %s!\"", + shkname(this_shkp), says(), xname(wep)); else pline("%s looks apprehensive about your wielding %s %s.", shkname(this_shkp), mhis(this_shkp), xname(wep)); From 43ae611d64ed7167e14da691b6af213550357d1f Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 19 Jun 2026 10:20:50 -0400 Subject: [PATCH 485/702] fixes5-0-1.txt entries following pull request --- doc/fixes5-0-1.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 3fa4b761d..44e86f817 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -61,6 +61,8 @@ fix a bug in which steeds would continuously gain movement points while being ridden when hero's behavior makes erinyes stronger, cap level at 49 rather than 50 with inventory item action for leash, distingluish leash-in-use from empty one +deafness check was missing from a shopkeeper message in ready_weapon() +thrown ball travel did not check for regions (pr #1595 by copperwater) Platform- and/or Interface-Specific Fixes From 24adb1c592a306b67fbb3fa928fbe2fb5497ae79 Mon Sep 17 00:00:00 2001 From: Doktor L Date: Sat, 30 May 2026 18:03:20 +0200 Subject: [PATCH 486/702] curses: use existing background parameter for pile The blue background colour for piles was implemented by changing glyph colour to curses colour pair with the desired background, and then passed to curses_putch which takes character and background colour and makes curses colour pair out of them once again. Pass blue background to curses_putch instead and let it create curses colour pair just once. --- include/wincurs.h | 1 - win/curses/cursmain.c | 6 ++++-- win/curses/curswins.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/wincurs.h b/include/wincurs.h index 0911cf11c..aea0e9ebf 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -145,7 +145,6 @@ extern void curses_puts(winid wid, int attr, const char *text); extern void curses_clear_nhwin(winid wid); extern void curses_alert_win_border(winid wid, boolean onoff); extern void curses_alert_main_borders(boolean onoff); -extern int get_framecolor(int nhcolor, int framecolor); extern void curses_draw_map(int sx, int sy, int ex, int ey); extern boolean curses_map_borders(int *sx, int *sy, int *ex, int *ey, int ux, int uy); diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 448d8c77d..ee45eb059 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -940,6 +940,7 @@ curses_print_glyph( int glyph; int ch; int color; + int framecolor; int nhcolor = 0; unsigned int special; int attr = -1; @@ -948,6 +949,7 @@ curses_print_glyph( special = glyphinfo->gm.glyphflags; ch = glyphinfo->ttychar; color = glyphinfo->gm.sym.color; + framecolor = bkglyphinfo->framecolor; /* Extra color handling * FIQ: The curses library does not support truecolor, only the more limited 256 * color mode. On top of this, the windowport only supports 16 color mode. @@ -981,7 +983,7 @@ curses_print_glyph( */ if ((special & MG_OBJPILE) && iflags.hilite_pile) { if (iflags.wc_color) - color = get_framecolor(color, CLR_BLUE); + framecolor = CLR_BLUE; else /* if (iflags.use_inverse) */ attr = A_REVERSE; } @@ -1007,7 +1009,7 @@ curses_print_glyph( ? glyphinfo->gm.u : NULL, #endif (nhcolor != 0) ? nhcolor : color, - bkglyphinfo->framecolor, attr); + framecolor, attr); } diff --git a/win/curses/curswins.c b/win/curses/curswins.c index 21e1bae09..50f8f171c 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -763,7 +763,7 @@ is_main_window(winid wid) coordinates without a refresh. Currently only used for the map. */ /* convert nhcolor (fg) and framecolor (bg) to curses colorpair */ -int +static int get_framecolor(int nhcolor, int framecolor) { /* curses_toggle_color_attr() adds the +1 and takes care of COLORS < 16 */ From f3d292e111e509a4ad6e426cc0f00da0238d97c6 Mon Sep 17 00:00:00 2001 From: Doktor L Date: Sat, 30 May 2026 18:13:36 +0200 Subject: [PATCH 487/702] Combine three arguments of curses_putch into one It will need another parameter for 256-colour support. To avoid having too many arguments, put glyph colour, background colour and attributes into a struct and, since to curses library all of that is attributes that are handled by same function, call the struct "gryph attributes". curses_putch was also declared in two different headers, remove one of those declarations. --- include/wincurs.h | 8 -------- win/curses/cursmain.c | 27 +++++++++++++-------------- win/curses/curswins.c | 8 ++++---- win/curses/curswins.h | 13 +++++++++---- 4 files changed, 26 insertions(+), 30 deletions(-) diff --git a/include/wincurs.h b/include/wincurs.h index aea0e9ebf..43780e276 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -128,14 +128,6 @@ extern void curses_refresh_nethack_windows(void); extern void curses_del_nhwin(winid wid); extern void curses_del_wid(winid wid); extern void curs_destroy_all_wins(void); -#ifdef ENHANCED_SYMBOLS -extern void curses_putch(winid wid, int x, int y, int ch, - struct unicode_representation *u, int color, - int framecolor, int attrs); -#else -extern void curses_putch(winid wid, int x, int y, int ch, int color, - int framecolor, int attrs); -#endif extern void curses_get_window_size(winid wid, int *height, int *width); extern boolean curses_window_has_border(winid wid); extern boolean curses_window_exists(winid wid); diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index ee45eb059..3966771f6 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -7,6 +7,7 @@ #include "hack.h" #include "color.h" #include "wincurs.h" +#include "curswins.h" #ifdef CURSES_UNICODE #include #endif @@ -939,17 +940,16 @@ curses_print_glyph( { int glyph; int ch; - int color; - int framecolor; + struct glyph_attributes attr; int nhcolor = 0; unsigned int special; - int attr = -1; + attr.attribute_flags = -1; glyph = glyphinfo->glyph; special = glyphinfo->gm.glyphflags; ch = glyphinfo->ttychar; - color = glyphinfo->gm.sym.color; - framecolor = bkglyphinfo->framecolor; + attr.color = glyphinfo->gm.sym.color; + attr.framecolor = bkglyphinfo->framecolor; /* Extra color handling * FIQ: The curses library does not support truecolor, only the more limited 256 * color mode. On top of this, the windowport only supports 16 color mode. @@ -958,7 +958,7 @@ curses_print_glyph( if (glyphinfo->gm.customcolor != 0 && (curses_procs.wincap2 & WC2_EXTRACOLORS) != 0) { if ((glyphinfo->gm.customcolor & NH_BASIC_COLOR) != 0) { - color = COLORVAL(glyphinfo->gm.customcolor); + attr.color = COLORVAL(glyphinfo->gm.customcolor); #if 0 } else { /* 24-bit color, NH_BASIC_COLOR == 0 */ @@ -967,10 +967,10 @@ curses_print_glyph( } } if ((special & MG_PET) && iflags.hilite_pet) { - attr = curses_convert_attr(iflags.wc2_petattr); + attr.attribute_flags = curses_convert_attr(iflags.wc2_petattr); } if ((special & MG_DETECT) && iflags.use_inverse) { - attr = A_REVERSE; + attr.attribute_flags = A_REVERSE; } if (SYMHANDLING(H_DEC)) ch = curses_convert_glyph(ch, glyph); @@ -983,9 +983,9 @@ curses_print_glyph( */ if ((special & MG_OBJPILE) && iflags.hilite_pile) { if (iflags.wc_color) - framecolor = CLR_BLUE; + attr.framecolor = CLR_BLUE; else /* if (iflags.use_inverse) */ - attr = A_REVERSE; + attr.attribute_flags = A_REVERSE; } /* water and lava look the same except for color; when color is off (checked by core), render lava in inverse video so that it looks @@ -994,11 +994,11 @@ curses_print_glyph( if ((special & (MG_BW_LAVA | MG_BW_ICE | MG_BW_SINK | MG_BW_ENGR)) != 0 && iflags.use_inverse) { /* reset_glyphmap() only sets MG_BW_foo if color is off */ - attr = A_REVERSE; + attr.attribute_flags = A_REVERSE; } /* highlight female monsters (wizard mode option) */ if ((special & MG_FEMALE) && wizard && iflags.wizmgender) { - attr = A_REVERSE; + attr.attribute_flags = A_REVERSE; } } @@ -1008,8 +1008,7 @@ curses_print_glyph( && glyphinfo->gm.u && glyphinfo->gm.u->utf8str) ? glyphinfo->gm.u : NULL, #endif - (nhcolor != 0) ? nhcolor : color, - framecolor, attr); + &attr); } diff --git a/win/curses/curswins.c b/win/curses/curswins.c index 50f8f171c..ee28d4508 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -532,7 +532,7 @@ curses_putch(winid wid, int x, int y, int ch, #ifdef ENHANCED_SYMBOLS struct unicode_representation *unicode_representation, #endif - int color, int framecolor, int attr) + const struct glyph_attributes *attr) { static boolean map_initted = FALSE; int sx, sy, ex, ey; @@ -554,9 +554,9 @@ curses_putch(winid wid, int x, int y, int ch, --x; /* map column [0] is not used; draw column [1] in first screen col */ map[y][x].ch = ch; - map[y][x].color = color; - map[y][x].framecolor = framecolor; - map[y][x].attr = attr; + map[y][x].color = attr->color; + map[y][x].framecolor = attr->framecolor; + map[y][x].attr = attr->attribute_flags; #ifdef ENHANCED_SYMBOLS map[y][x].unicode_representation = unicode_representation; #endif diff --git a/win/curses/curswins.h b/win/curses/curswins.h index ebf4c9bb5..992fea55a 100644 --- a/win/curses/curswins.h +++ b/win/curses/curswins.h @@ -6,6 +6,11 @@ #ifndef CURSWIN_H # define CURSWIN_H +struct glyph_attributes { + int color; + int framecolor; + int attribute_flags; +}; /* Global declarations */ @@ -27,11 +32,11 @@ void curses_del_wid(winid wid); void curs_destroy_all_wins(void); #ifdef ENHANCED_SYMBOLS void curses_putch(winid wid, int x, int y, int ch, - struct unicode_representation *ur, int color, - int framecolor, int attrs); + struct unicode_representation *ur, + const struct glyph_attributes *attr); #else -void curses_putch(winid wid, int x, int y, int ch, int color, - int framecolor, int attrs); +void curses_putch(winid wid, int x, int y, int ch, + const struct glyph_attributes *attr); #endif void curses_get_window_xy(winid wid, int *x, int *y); boolean curses_window_has_border(winid wid); From 7036f902d2aabad9d522133509aa9ee59d831398 Mon Sep 17 00:00:00 2001 From: Doktor L Date: Sat, 30 May 2026 18:28:08 +0200 Subject: [PATCH 488/702] Pass base-256 colour index to curses_putch And to its inner function write_char --- src/coloratt.c | 3 ++- win/curses/cursmain.c | 10 ++++------ win/curses/curswins.c | 6 ++++-- win/curses/curswins.h | 3 ++- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/coloratt.c b/src/coloratt.c index 10f216ba6..a5d040fda 100644 --- a/src/coloratt.c +++ b/src/coloratt.c @@ -886,7 +886,8 @@ static struct { int index; uint32 value; } color_256_definitions[] = { - /* color values are from unnethack */ + /* from unnethack - these are the colors used by xterm + when $TERM is set to xterm-256color */ { 16, 0x000000 }, { 17, 0x00005f }, { 18, 0x000087 }, { 19, 0x0000af }, { 20, 0x0000d7 }, { 21, 0x0000ff }, { 22, 0x005f00 }, { 23, 0x005f5f }, { 24, 0x005f87 }, diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 3966771f6..f6b5e3013 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -941,14 +941,14 @@ curses_print_glyph( int glyph; int ch; struct glyph_attributes attr; - int nhcolor = 0; unsigned int special; attr.attribute_flags = -1; glyph = glyphinfo->glyph; special = glyphinfo->gm.glyphflags; ch = glyphinfo->ttychar; - attr.color = glyphinfo->gm.sym.color; + attr.basic_color = glyphinfo->gm.sym.color; + attr.color256 = 0; attr.framecolor = bkglyphinfo->framecolor; /* Extra color handling * FIQ: The curses library does not support truecolor, only the more limited 256 @@ -958,12 +958,10 @@ curses_print_glyph( if (glyphinfo->gm.customcolor != 0 && (curses_procs.wincap2 & WC2_EXTRACOLORS) != 0) { if ((glyphinfo->gm.customcolor & NH_BASIC_COLOR) != 0) { - attr.color = COLORVAL(glyphinfo->gm.customcolor); -#if 0 + attr.basic_color = COLORVAL(glyphinfo->gm.customcolor); } else { /* 24-bit color, NH_BASIC_COLOR == 0 */ - nhcolor = COLORVAL(glyphinfo->gm.customcolor); -#endif + attr.color256 = glyphinfo->gm.color256idx; } } if ((special & MG_PET) && iflags.hilite_pet) { diff --git a/win/curses/curswins.c b/win/curses/curswins.c index ee28d4508..6ce123c34 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -40,7 +40,8 @@ typedef struct nhwd { typedef struct nhchar { int ch; /* character */ - int color; /* color info for character */ + int color; /* basic color info for character */ + int color256; /* extended color for the character, 0 if none */ int framecolor; /* background color info for character */ int attr; /* attributes of character */ struct unicode_representation *unicode_representation; @@ -554,7 +555,8 @@ curses_putch(winid wid, int x, int y, int ch, --x; /* map column [0] is not used; draw column [1] in first screen col */ map[y][x].ch = ch; - map[y][x].color = attr->color; + map[y][x].color = attr->basic_color; + map[y][x].color256 = attr->color256; map[y][x].framecolor = attr->framecolor; map[y][x].attr = attr->attribute_flags; #ifdef ENHANCED_SYMBOLS diff --git a/win/curses/curswins.h b/win/curses/curswins.h index 992fea55a..13985ce1b 100644 --- a/win/curses/curswins.h +++ b/win/curses/curswins.h @@ -7,7 +7,8 @@ # define CURSWIN_H struct glyph_attributes { - int color; + int basic_color; // basic color + int color256; // extended color (0 if not defined), used when supported int framecolor; int attribute_flags; }; From 19c87585fa5cabb8869bc70e2c65c215a66b981b Mon Sep 17 00:00:00 2001 From: Doktor L Date: Sat, 30 May 2026 19:29:11 +0200 Subject: [PATCH 489/702] Create curses colour pairs for 256 colours Keep only 8 background colours but if curses supports 256 colours and 256*8 colours pairs, create colours pairs for 256 foregrounds rather than just 16. --- win/curses/cursinit.c | 12 +++++++----- win/curses/cursmisc.c | 8 +++++++- win/curses/cursmisc.h | 3 +++ win/curses/curswins.c | 6 +++++- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 1135d0eb8..523ae92d3 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -7,6 +7,7 @@ #include "hack.h" #include "wincurs.h" #include "cursinit.h" +#include "cursmisc.h" /* Initialization and startup functions for curses interface */ @@ -334,18 +335,18 @@ curses_init_nhcolors(void) /* COLOR_foo + 8 means COLOR | A_BOLD when COLORS < 16 */ /* otherwise assume the terminal has least 16 different colors */ /* these map to the NetHack CLR_ defines */ - static const int fg_clr[16] = { + static const int basic_fg_clr[16] = { COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE, -1, COLOR_RED + 8, COLOR_GREEN + 8, COLOR_YELLOW + 8, COLOR_BLUE + 8, COLOR_MAGENTA + 8, COLOR_CYAN + 8, COLOR_WHITE + 8 }; - static const int bg_clr[8] = { + static const int bg_clr[CURSES_NUM_BACKGROUND_COLORS] = { -1, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE }; int bg, nhclr; - int maxc = (COLORS >= 16) ? 16 : 8; + int maxc = curses_has_256color() ? 256 : (COLORS >= 16) ? 16 : 8; if (!has_colors()) return; @@ -353,8 +354,9 @@ curses_init_nhcolors(void) use_default_colors(); for (nhclr = CLR_BLACK; nhclr < maxc; nhclr++) { - for (bg = 0; bg < 8; bg++) { - init_pair((maxc * bg) + nhclr + 1, fg_clr[nhclr], bg_clr[bg]); + for (bg = 0; bg < CURSES_NUM_BACKGROUND_COLORS; bg++) { + int fg_color = (nhclr < 16) ? basic_fg_clr[nhclr] : nhclr; + init_pair((maxc * bg) + nhclr + 1, fg_color, bg_clr[bg]); } } diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index efa5da83a..30e782411 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -91,6 +91,12 @@ curses_read_char(void) return ch; } +boolean +curses_has_256color(void) +{ + return (COLORS >= 256) && (COLOR_PAIRS >= 256 * CURSES_NUM_BACKGROUND_COLORS); +} + /* Turn on or off the specified color and / or attribute */ void @@ -147,7 +153,7 @@ curses_toggle_color_attr(WINDOW *win, int color, int attr, int onoff) if (use_bold) { wattron(win, A_BOLD); } - wattron(win, COLOR_PAIR(curses_color)); + wcolor_set(win, curses_color, &curses_color); } if (attr != NONE) { diff --git a/win/curses/cursmisc.h b/win/curses/cursmisc.h index dc79ebfbe..81c34135d 100644 --- a/win/curses/cursmisc.h +++ b/win/curses/cursmisc.h @@ -8,8 +8,11 @@ /* Global declarations */ +#define CURSES_NUM_BACKGROUND_COLORS 8 + int curses_getch(void); int curses_read_char(void); +boolean curses_has_256color(void); void curses_toggle_color_attr(WINDOW *win, int color, int attr, int onoff); void curses_menu_color_attr(WINDOW *win, int color, int attr, int onoff); void curses_bail(const char *mesg); diff --git a/win/curses/curswins.c b/win/curses/curswins.c index 6ce123c34..a09b3f3f0 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -769,7 +769,11 @@ static int get_framecolor(int nhcolor, int framecolor) { /* curses_toggle_color_attr() adds the +1 and takes care of COLORS < 16 */ - return (16 * (framecolor % 8)) + (nhcolor % 16); + if (curses_has_256color()) { + return (256 * (framecolor % 8)) + (nhcolor % 256); + } else + return (16 * (framecolor % 8)) + (nhcolor % 16); + } static void From 08ac68b754c1f22ae6e6b7a33d323e682333c5b6 Mon Sep 17 00:00:00 2001 From: Doktor L Date: Sat, 30 May 2026 19:31:37 +0200 Subject: [PATCH 490/702] Use 256 colours in curses window port Only glyphs that are customised via config can have colours different from the basic 16. For such glyphs, when curses supports 256 colours, use them. --- win/curses/curswins.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/win/curses/curswins.c b/win/curses/curswins.c index a09b3f3f0..1044cd61b 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -766,25 +766,26 @@ coordinates without a refresh. Currently only used for the map. */ /* convert nhcolor (fg) and framecolor (bg) to curses colorpair */ static int -get_framecolor(int nhcolor, int framecolor) +get_framecolor(const nethack_char *nch) { + int bgcolor = (nch->framecolor != NO_COLOR) ? nch->framecolor : 0; /* curses_toggle_color_attr() adds the +1 and takes care of COLORS < 16 */ if (curses_has_256color()) { - return (256 * (framecolor % 8)) + (nhcolor % 256); + int color = nch->color256 ? nch->color256 : nch->color; + return (256 * (bgcolor % CURSES_NUM_BACKGROUND_COLORS)) + (color % 256); } else - return (16 * (framecolor % 8)) + (nhcolor % 16); - + return (16 * (bgcolor % CURSES_NUM_BACKGROUND_COLORS)) + (nch->color % 16); } static void write_char(WINDOW * win, int x, int y, nethack_char nch) { - int curscolor = nch.color, cursattr = nch.attr; + int curscolor; + int cursattr = nch.attr; - if (nch.framecolor != NO_COLOR) { - curscolor = get_framecolor(nch.color, nch.framecolor); - if (nch.attr == A_REVERSE) - cursattr = A_NORMAL; /* hilited pet looks odd otherwise */ + curscolor = get_framecolor(&nch); + if ((nch.framecolor != NO_COLOR) && (nch.attr == A_REVERSE)) { + cursattr = A_NORMAL; /* hilited pet looks odd otherwise */ } curses_toggle_color_attr(win, curscolor, cursattr, ON); #if defined(CURSES_UNICODE) && defined(ENHANCED_SYMBOLS) From 10d87c4b9d229ad1c5d8a593af0e1c51f2217332 Mon Sep 17 00:00:00 2001 From: nhkeni Date: Fri, 19 Jun 2026 20:44:46 -0400 Subject: [PATCH 491/702] nhgitset: Deprecate PRE and POST hooks. nhgitset version 6 prepare for future phases to get rid of those hooks fix some minor bugs --- DEVEL/VERSION | 9 +++++---- DEVEL/hooksdir/NHgithook.pm | 23 ++++++++++++++++++++++- DEVEL/nhgitset.pl | 12 +++++++++++- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/DEVEL/VERSION b/DEVEL/VERSION index 3788cb6d5..382eb85f0 100644 --- a/DEVEL/VERSION +++ b/DEVEL/VERSION @@ -1,4 +1,5 @@ -5 -Please see "git log DEVEL" for previous changes. -Make documentation of nhgitset.pl easier to find and -find out about. +6 +PRE and POST hooks will be dropped at some future date - +see https://www.nethack.org/devel/deprecation.html for details. + +See "git log DEVEL" for previous changes. diff --git a/DEVEL/hooksdir/NHgithook.pm b/DEVEL/hooksdir/NHgithook.pm index 065fcd60a..5b90193aa 100644 --- a/DEVEL/hooksdir/NHgithook.pm +++ b/DEVEL/hooksdir/NHgithook.pm @@ -109,7 +109,7 @@ sub version_in_devel { my $version; my $verfile = "$path${PDS}DEVEL${PDS}VERSION"; - open VERFH,"<",$verfile or die "xCan't open $verfile: $!"; + open VERFH,"<",$verfile or die "Can't open $verfile: $!"; $version = 0+; my $message = join('',); close VERFH; @@ -250,7 +250,17 @@ sub do_hook { my($p) = @_; my $hname = $0; $hname =~ s!^((.*$DS)|())(.*)!$1$p-$4!; + my $vig = version_in_git; if(-x $hname){ + if(`git config --bool nethack.NoDepWarn` ne "true\n"){ + print STDERR <<~E_O_M; + WARNING: $p hooks will be going away. See + https://www.nethack.org/devel/deprecation.html + To stop seeing this message, run + git config --bool nethack.NoDepWarn true + E_O_M + } + print TRACE "START $p: $hname\n" if($trace); open TOHOOK, "|-", $hname or die "open $hname: $!"; @@ -370,6 +380,17 @@ Perl module for infrastructure of NetHack Git hooks. Buffers call information so multiple independent actions may be coded for Git hooks and similar Git callouts. +=over 4 + +=item ==> + +As of Git 2.54, multiple actions may be specified for each hook +event - that makes this redundant for hooks and will be removed at +some future time when Git 2.54 (or later) is better distributed. +This should speed up hook processing. + +=back 4 + Maintains C. Common routines for dealing with nethack.setupversion git config variable. diff --git a/DEVEL/nhgitset.pl b/DEVEL/nhgitset.pl index 2c4977895..d1f587b04 100755 --- a/DEVEL/nhgitset.pl +++ b/DEVEL/nhgitset.pl @@ -93,6 +93,16 @@ if($version_old > 0){ if(length $message_new){ print STDERR "Additional information:\n$message_new\n"; } +# This list and the code below will need to be updated if other changes occur +# before this progression is finished. +# 6 announce eventual deprecation of PRE and POST hooks +# 6->7 unset nethack.NoDepWarn, change message, docs in NHgithook.pm +# 7 deprecation of PRE and POST hooks +# 7->8 unset nethack.NoDepWarn, change message, docs in NHgithook.pm and make fail +# 8 PRE and POST throw errors +# 8->9 unset nethack.NoDepWarn, remove code, docs +# 9 removal of PRE and POST code + system('git','config','--unset','nethack.NoDepWarn') unless($opt_n); } } @@ -358,7 +368,7 @@ sub do_file_nhgitset { open IN, "<", $infile or die "Can't open $infile:$!"; open OUT, ">", $outfile or die "Can't open $outfile:$!"; my $started; - print IN "die \"DO NOT RUN THIS FILE\n\""; + print OUT "=pod\n"; while(){ m/^__END__/ && do {$started =1; next}; print OUT if($started); From f5f87c7ee9c7d3ccf087a7eaa3757fd2c9b67507 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 20 Jun 2026 11:18:14 -0400 Subject: [PATCH 492/702] missed version bit --- sys/unix/README.hints | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/unix/README.hints b/sys/unix/README.hints index a95ae711a..7856a1561 100644 --- a/sys/unix/README.hints +++ b/sys/unix/README.hints @@ -12,7 +12,7 @@ There are two .500 series hints files provided with NetHack: linux.500 for use on Linux macOS.500 for use on macOS -Those will also pull in content from sys/unix/hints/include/*.370, +Those will also pull in content from sys/unix/hints/include/*.500, that is shared between the linux.500 and macOS.500 hints files. From d7ce2410b0b5da7e891b6aff4ec520901d66884a Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Sat, 20 Jun 2026 15:31:53 -0400 Subject: [PATCH 493/702] fixes5-0-1.txt update --- doc/fixes5-0-1.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 44e86f817..bd01b89ca 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -18,7 +18,10 @@ when a vault guard was moved off the map, an impossible about trying to update map location <0,0> was issued doc: use full URL for nethack.org in Guidebook.mn doc: fix a paste error in Guidebook.tex -doc: fix spelling correction in nethack.6 +doc: bring man pages up to date with *nix documentary conventions and ensure + their portable rendering among GNU, Heirloom Doctools, DWB 3.3, + Solaris 10, and Plan 9 troffs, and mandoc(1) +doc: fix spelling error in nethack.6 spelling: "Flanian Pobble Bead" to "Flainian Pobble Bead" obey statue type gender (gnome king statue in minetn-5) fix statue and figurine genders in special levels in general From f5724ff9e6bb250aa614c754c5028d5715ccdf58 Mon Sep 17 00:00:00 2001 From: nhkeni Date: Sat, 20 Jun 2026 17:57:48 -0400 Subject: [PATCH 494/702] fixes entry for my previous commit --- doc/fixes5-0-1.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index bd01b89ca..710a23f69 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -261,4 +261,4 @@ unix hints: the Makefiles distributed by sys/unix/setup.sh will now check make, and use bsd make syntax for bsd make share a single copy of nhuuid generation code between Amiga, Atari, and msdos by way of sys/share/pcmain.c (cherry-pick from pr #1541 by ingpaschke) - +nhgitset.pl: Set up future deprecation of PRE and POST hooks. From 198ac655e5477122e0e388019abda7595e5bd016 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 20 Jun 2026 18:26:43 -0400 Subject: [PATCH 495/702] more 3.7 vestiges A little later than this probably should have been committed. --- include/align.h | 2 +- include/artifact.h | 2 +- include/artilist.h | 2 +- include/attrib.h | 2 +- include/botl.h | 2 +- include/color.h | 2 +- include/config1.h | 2 +- include/context.h | 2 +- include/coord.h | 2 +- include/cstd.h | 2 +- include/decl.h | 2 +- include/defsym.h | 2 +- include/dgn_file.h | 2 +- include/display.h | 2 +- include/dlb.h | 2 +- include/dungeon.h | 2 +- include/engrave.h | 2 +- include/flag.h | 2 +- include/fnamesiz.h | 2 +- include/func_tab.h | 2 +- include/hack.h | 2 +- include/hacklib.h | 2 +- include/integer.h | 2 +- include/lint.h | 2 +- include/mail.h | 2 +- include/mextra.h | 2 +- include/mfndpos.h | 2 +- include/micro.h | 2 +- include/mkroom.h | 2 +- include/monattk.h | 2 +- include/mondata.h | 2 +- include/monflag.h | 2 +- include/monst.h | 2 +- include/monsters.h | 2 +- include/nhmd4.h | 2 +- include/nhregex.h | 2 +- include/obj.h | 2 +- include/objclass.h | 2 +- include/objects.h | 2 +- include/patchlevel.h | 2 +- include/pcconf.h | 2 +- include/permonst.h | 2 +- include/prop.h | 2 +- include/quest.h | 2 +- include/rect.h | 2 +- include/region.h | 2 +- include/rm.h | 2 +- include/savefile.h | 2 +- include/seffects.h | 2 +- include/skills.h | 2 +- include/sndprocs.h | 2 +- include/sp_lev.h | 2 +- include/spell.h | 2 +- include/stairs.h | 2 +- include/tcap.h | 2 +- include/tile2x11.h | 2 +- include/tileset.h | 2 +- include/timeout.h | 2 +- include/tradstdc.h | 2 +- include/trap.h | 2 +- include/vision.h | 2 +- include/vmsconf.h | 2 +- include/warnings.h | 2 +- include/weight.h | 2 +- include/winX.h | 2 +- include/winami.h | 2 +- include/windconf.h | 2 +- include/winprocs.h | 2 +- include/wintty.h | 2 +- include/wintype.h | 2 +- include/xwindow.h | 2 +- include/xwindowp.h | 2 +- include/you.h | 2 +- include/youprop.h | 2 +- src/allmain.c | 2 +- src/alloc.c | 2 +- src/apply.c | 2 +- src/artifact.c | 2 +- src/attrib.c | 2 +- src/ball.c | 2 +- src/bones.c | 2 +- src/botl.c | 2 +- src/calendar.c | 2 +- src/cfgfiles.c | 2 +- src/cmd.c | 2 +- src/coloratt.c | 2 +- src/date.c | 2 +- src/dbridge.c | 2 +- src/decl.c | 2 +- src/detect.c | 2 +- src/dig.c | 2 +- src/display.c | 2 +- src/dlb.c | 2 +- src/do.c | 2 +- src/do_name.c | 2 +- src/do_wear.c | 2 +- src/dog.c | 2 +- src/dogmove.c | 2 +- src/dokick.c | 2 +- src/dothrow.c | 2 +- src/drawing.c | 2 +- src/dungeon.c | 2 +- src/earlyarg.c | 2 +- src/eat.c | 2 +- src/end.c | 2 +- src/engrave.c | 2 +- src/exper.c | 2 +- src/explode.c | 2 +- src/extralev.c | 2 +- src/files.c | 2 +- src/fountain.c | 2 +- src/getpos.c | 2 +- src/hack.c | 2 +- src/hacklib.c | 2 +- src/iactions.c | 2 +- src/insight.c | 2 +- src/invent.c | 2 +- src/light.c | 2 +- src/lock.c | 2 +- src/mail.c | 2 +- src/makemon.c | 2 +- src/mcastu.c | 2 +- src/mdlib.c | 2 +- src/mhitm.c | 2 +- src/mhitu.c | 2 +- src/minion.c | 2 +- src/mklev.c | 2 +- src/mkmap.c | 2 +- src/mkmaze.c | 2 +- src/mkobj.c | 2 +- src/mkroom.c | 2 +- src/mondata.c | 2 +- src/monmove.c | 2 +- src/monst.c | 2 +- src/mplayer.c | 2 +- src/mthrowu.c | 2 +- src/muse.c | 2 +- src/music.c | 2 +- src/nhlobj.c | 2 +- src/nhlsel.c | 2 +- src/nhlua.c | 2 +- src/nhmd4.c | 2 +- src/o_init.c | 2 +- src/objects.c | 2 +- src/objnam.c | 2 +- src/pager.c | 2 +- src/pickup.c | 2 +- src/pline.c | 2 +- src/polyself.c | 2 +- src/potion.c | 2 +- src/pray.c | 2 +- src/priest.c | 2 +- src/quest.c | 2 +- src/read.c | 2 +- src/rect.c | 2 +- src/region.c | 2 +- src/restore.c | 2 +- src/rip.c | 2 +- src/rnd.c | 2 +- src/role.c | 2 +- src/rumors.c | 2 +- src/save.c | 2 +- src/selvar.c | 2 +- src/sfstruct.c | 2 +- src/shk.c | 2 +- src/shknam.c | 2 +- src/sit.c | 2 +- src/sounds.c | 2 +- src/spell.c | 2 +- src/steal.c | 2 +- src/steed.c | 2 +- src/symbols.c | 2 +- src/sys.c | 2 +- src/teleport.c | 2 +- src/timeout.c | 2 +- src/topten.c | 2 +- src/track.c | 2 +- src/trap.c | 2 +- src/u_init.c | 2 +- src/uhitm.c | 2 +- src/vault.c | 2 +- src/version.c | 2 +- src/vision.c | 2 +- src/weapon.c | 2 +- src/were.c | 2 +- src/wield.c | 2 +- src/windows.c | 2 +- src/wizard.c | 2 +- src/wizcmds.c | 2 +- src/worm.c | 2 +- src/worn.c | 2 +- src/write.c | 2 +- src/zap.c | 2 +- util/dlb_main.c | 2 +- util/makedefs.c | 2 +- util/mdgrep.h | 2 +- util/panic.c | 2 +- util/recover.c | 2 +- win/Qt/qt_post.h | 2 +- win/Qt/qt_pre.h | 2 +- win/X11/Window.c | 2 +- win/X11/winX.c | 2 +- win/X11/winmap.c | 2 +- win/X11/winmenu.c | 2 +- win/X11/winmesg.c | 2 +- win/X11/winmisc.c | 2 +- win/X11/winstat.c | 2 +- win/X11/wintext.c | 2 +- win/X11/winval.c | 2 +- win/chain/wc_chainin.c | 2 +- win/chain/wc_chainout.c | 2 +- win/chain/wc_trace.c | 2 +- win/share/bmptiles.c | 2 +- win/share/giftiles.c | 2 +- win/share/ppmwrite.c | 2 +- win/share/thintile.c | 2 +- win/share/tile.h | 2 +- win/share/tile2bmp.c | 2 +- win/share/tilemap.c | 2 +- win/share/tileset.c | 2 +- win/share/tiletext.c | 2 +- win/shim/winshim.c | 2 +- win/tty/getline.c | 2 +- win/tty/termcap.c | 2 +- win/tty/topl.c | 2 +- win/tty/wintty.c | 2 +- win/win32/mhaskyn.c | 2 +- win/win32/mhaskyn.h | 2 +- win/win32/mhdlg.c | 2 +- win/win32/mhdlg.h | 2 +- win/win32/mhfont.c | 2 +- win/win32/mhfont.h | 2 +- win/win32/mhinput.c | 2 +- win/win32/mhinput.h | 2 +- win/win32/mhmain.c | 2 +- win/win32/mhmain.h | 2 +- win/win32/mhmap.c | 2 +- win/win32/mhmap.h | 2 +- win/win32/mhmenu.c | 2 +- win/win32/mhmenu.h | 2 +- win/win32/mhmsg.h | 2 +- win/win32/mhmsgwnd.c | 2 +- win/win32/mhmsgwnd.h | 2 +- win/win32/mhrip.c | 2 +- win/win32/mhrip.h | 2 +- win/win32/mhsplash.c | 2 +- win/win32/mhstatus.c | 2 +- win/win32/mhstatus.h | 2 +- win/win32/mhtext.c | 2 +- win/win32/mhtext.h | 2 +- win/win32/mswproc.c | 2 +- win/win32/winMS.h | 2 +- 252 files changed, 252 insertions(+), 252 deletions(-) diff --git a/include/align.h b/include/align.h index 9890ae41b..36c9d1aff 100644 --- a/include/align.h +++ b/include/align.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 align.h $NHDT-Date: 1604269810 2020/11/01 22:30:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 align.h $NHDT-Date: 1781973076 2026/06/20 16:31:16 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.24 $ */ /* Copyright (c) Mike Stephenson, Izchak Miller 1991. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/artifact.h b/include/artifact.h index fd55ff7a1..021743445 100644 --- a/include/artifact.h +++ b/include/artifact.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 artifact.h $NHDT-Date: 1602692711 2020/10/14 16:25:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 artifact.h $NHDT-Date: 1781973076 2026/06/20 16:31:16 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.23 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/artilist.h b/include/artilist.h index 53caaa7c0..2b7e9ef8d 100644 --- a/include/artilist.h +++ b/include/artilist.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 artilist.h $NHDT-Date: 1710957374 2024/03/20 17:56:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ +/* NetHack 5.0 artilist.h $NHDT-Date: 1781973076 2026/06/20 16:31:16 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.39 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/attrib.h b/include/attrib.h index a5299f423..653c5fe65 100644 --- a/include/attrib.h +++ b/include/attrib.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 attrib.h $NHDT-Date: 1596498527 2020/08/03 23:48:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 attrib.h $NHDT-Date: 1781973077 2026/06/20 16:31:17 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.18 $ */ /* Copyright 1988, Mike Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/botl.h b/include/botl.h index 87fc7cdbd..a097c9eff 100644 --- a/include/botl.h +++ b/include/botl.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 botl.h $NHDT-Date: 1694893330 2023/09/16 19:42:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.37 $ */ +/* NetHack 5.0 botl.h $NHDT-Date: 1781973077 2026/06/20 16:31:17 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.45 $ */ /* Copyright (c) Michael Allison, 2003 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/color.h b/include/color.h index 3ad090346..3d5292a65 100644 --- a/include/color.h +++ b/include/color.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 color.h $NHDT-Date: 1682205020 2023/04/22 23:10:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ */ +/* NetHack 5.0 color.h $NHDT-Date: 1781973077 2026/06/20 16:31:17 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.27 $ */ /* Copyright (c) Steve Linhart, Eric Raymond, 1989. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/config1.h b/include/config1.h index ecf3ce7b0..4e1f6639a 100644 --- a/include/config1.h +++ b/include/config1.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 config1.h $NHDT-Date: 1596498530 2020/08/03 23:48:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.23 $ */ +/* NetHack 5.0 config1.h $NHDT-Date: 1781973077 2026/06/20 16:31:17 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.32 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/context.h b/include/context.h index 1593d23ca..f4f161aae 100644 --- a/include/context.h +++ b/include/context.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 context.h $NHDT-Date: 1753856387 2025/07/29 22:19:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.58 $ */ +/* NetHack 5.0 context.h $NHDT-Date: 1781973077 2026/06/20 16:31:17 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.61 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/coord.h b/include/coord.h index ba8867ccd..13e9c642c 100644 --- a/include/coord.h +++ b/include/coord.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 coord.h $NHDT-Date: 1596498531 2020/08/03 23:48:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 coord.h $NHDT-Date: 1781973078 2026/06/20 16:31:18 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/cstd.h b/include/cstd.h index 7b7a71497..6ecea80a8 100644 --- a/include/cstd.h +++ b/include/cstd.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 cstd.h $NHDT-Date: 1725652996 2024/09/06 20:03:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ */ +/* NetHack 5.0 cstd.h $NHDT-Date: 1781973078 2026/06/20 16:31:18 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/decl.h b/include/decl.h index c6dbe7072..777c25631 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 decl.h $NHDT-Date: 1725653004 2024/09/06 20:03:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.377 $ */ +/* NetHack 5.0 decl.h $NHDT-Date: 1781973078 2026/06/20 16:31:18 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.408 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/defsym.h b/include/defsym.h index 598b2871b..1ad2bb6f2 100644 --- a/include/defsym.h +++ b/include/defsym.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 defsym.h $NHDT-Date: 1725653007 2024/09/06 20:03:27 $ $NHDT-Branch: NetHack-3.7 $ $NHDT-Revision: 1.25 $ */ +/* NetHack 5.0 defsym.h $NHDT-Date: 1781973078 2026/06/20 16:31:18 $ $NHDT-Branch: NetHack-5.0 $ $NHDT-Revision: 1.27 $ */ /* Copyright (c) 2016 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/dgn_file.h b/include/dgn_file.h index 1a214e7c9..e09d098f3 100644 --- a/include/dgn_file.h +++ b/include/dgn_file.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 dgn_file.h $NHDT-Date: 1596498533 2020/08/03 23:48:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 dgn_file.h $NHDT-Date: 1781973079 2026/06/20 16:31:19 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.15 $ */ /* Copyright (c) 1989 by M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/display.h b/include/display.h index 0518a6a2b..d7e8e64b5 100644 --- a/include/display.h +++ b/include/display.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 display.h $NHDT-Date: 1725653008 2024/09/06 20:03:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.106 $ */ +/* NetHack 5.0 display.h $NHDT-Date: 1781973079 2026/06/20 16:31:19 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.118 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */ /* and Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/dlb.h b/include/dlb.h index a94a3aab4..c51c9bace 100644 --- a/include/dlb.h +++ b/include/dlb.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 dlb.h $NHDT-Date: 1596498534 2020/08/03 23:48:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 dlb.h $NHDT-Date: 1781973079 2026/06/20 16:31:19 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.18 $ */ /* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1993. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/dungeon.h b/include/dungeon.h index a19e6e40e..09967adf8 100644 --- a/include/dungeon.h +++ b/include/dungeon.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 dungeon.h $NHDT-Date: 1685863327 2023/06/04 07:22:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ +/* NetHack 5.0 dungeon.h $NHDT-Date: 1781973079 2026/06/20 16:31:19 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.56 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/engrave.h b/include/engrave.h index 2437d4e44..27d152608 100644 --- a/include/engrave.h +++ b/include/engrave.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 engrave.h $NHDT-Date: 1596498535 2020/08/03 23:48:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 engrave.h $NHDT-Date: 1781973079 2026/06/20 16:31:19 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.22 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/flag.h b/include/flag.h index 205de909d..3502354c5 100644 --- a/include/flag.h +++ b/include/flag.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 flag.h $NHDT-Date: 1744860497 2025/04/16 19:28:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.251 $ */ +/* NetHack 5.0 flag.h $NHDT-Date: 1781973080 2026/06/20 16:31:20 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.265 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/fnamesiz.h b/include/fnamesiz.h index 338f55292..ea54f9c0b 100644 --- a/include/fnamesiz.h +++ b/include/fnamesiz.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 fnamesiz.h $NHDT-Date: 1580310580 2020/01/29 15:09:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ */ +/* NetHack 5.0 fnamesiz.h $NHDT-Date: 1781973080 2026/06/20 16:31:20 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ */ /*-Copyright (c) Michael Allison, 2020. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/func_tab.h b/include/func_tab.h index 7992a55c0..605b2f665 100644 --- a/include/func_tab.h +++ b/include/func_tab.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 func_tab.h $NHDT-Date: 1684791775 2023/05/22 21:42:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 5.0 func_tab.h $NHDT-Date: 1781973080 2026/06/20 16:31:20 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.29 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/hack.h b/include/hack.h index c98c8ab8a..4a4b7f9fa 100644 --- a/include/hack.h +++ b/include/hack.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 hack.h $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.266 $ */ +/* NetHack 5.0 hack.h $NHDT-Date: 1781973080 2026/06/20 16:31:20 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.299 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/hacklib.h b/include/hacklib.h index 2e3ac679a..3db368a58 100644 --- a/include/hacklib.h +++ b/include/hacklib.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 hacklib.h $NHDT-Date: 1725653010 2024/09/06 20:03:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 hacklib.h $NHDT-Date: 1781973081 2026/06/20 16:31:21 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/integer.h b/include/integer.h index 64d597030..7fb059887 100644 --- a/include/integer.h +++ b/include/integer.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 integer.h $NHDT-Date: 1720397754 2024/07/08 00:15:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 integer.h $NHDT-Date: 1781973081 2026/06/20 16:31:21 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.20 $ */ /* Copyright (c) 2016 by Michael Allison */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/lint.h b/include/lint.h index 235f05fc2..c92671c6f 100644 --- a/include/lint.h +++ b/include/lint.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 lint.h $NHDT-Date: 1655631029 2022/06/19 09:30:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ */ +/* NetHack 5.0 lint.h $NHDT-Date: 1781973081 2026/06/20 16:31:21 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) 2016 by Robert Patrick Rankin */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/mail.h b/include/mail.h index 3564c020f..835f89d3c 100644 --- a/include/mail.h +++ b/include/mail.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 mail.h $NHDT-Date: 1596498544 2020/08/03 23:49:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 mail.h $NHDT-Date: 1781973081 2026/06/20 16:31:21 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) 2015 by Kenneth Lorber */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/mextra.h b/include/mextra.h index 546c94c71..771696cd6 100644 --- a/include/mextra.h +++ b/include/mextra.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 mextra.h $NHDT-Date: 1720717969 2024/07/11 17:12:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ */ +/* NetHack 5.0 mextra.h $NHDT-Date: 1781973082 2026/06/20 16:31:22 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.50 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/mfndpos.h b/include/mfndpos.h index d4eac8da5..d5efb5495 100644 --- a/include/mfndpos.h +++ b/include/mfndpos.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 mfndpos.h $NHDT-Date: 1596498546 2020/08/03 23:49:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 mfndpos.h $NHDT-Date: 1781973082 2026/06/20 16:31:22 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.19 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2005. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/micro.h b/include/micro.h index 02067b063..ad1e3d25d 100644 --- a/include/micro.h +++ b/include/micro.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 micro.h $NHDT-Date: 1596498546 2020/08/03 23:49:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 micro.h $NHDT-Date: 1781973082 2026/06/20 16:31:22 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) 2015 by Kenneth Lorber */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/mkroom.h b/include/mkroom.h index 9b82807e8..81c0de6c7 100644 --- a/include/mkroom.h +++ b/include/mkroom.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 mkroom.h $NHDT-Date: 1725653011 2024/09/06 20:03:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.33 $ */ +/* NetHack 5.0 mkroom.h $NHDT-Date: 1781973082 2026/06/20 16:31:22 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.35 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/monattk.h b/include/monattk.h index 3e2d65690..7cddd1dee 100644 --- a/include/monattk.h +++ b/include/monattk.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 monattk.h $NHDT-Date: 1596498548 2020/08/03 23:49:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 monattk.h $NHDT-Date: 1781973083 2026/06/20 16:31:23 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.23 $ */ /* NetHack may be freely redistributed. See license for details. */ /* Copyright 1988, M. Stephenson */ diff --git a/include/mondata.h b/include/mondata.h index 05f276fa8..4cd388d66 100644 --- a/include/mondata.h +++ b/include/mondata.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 mondata.h $NHDT-Date: 1703845738 2023/12/29 10:28:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.63 $ */ +/* NetHack 5.0 mondata.h $NHDT-Date: 1781973083 2026/06/20 16:31:23 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.70 $ */ /* Copyright (c) 1989 Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/monflag.h b/include/monflag.h index 602588b54..2e8234bc4 100644 --- a/include/monflag.h +++ b/include/monflag.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 monflag.h $NHDT-Date: 1596498549 2020/08/03 23:49:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ +/* NetHack 5.0 monflag.h $NHDT-Date: 1781973083 2026/06/20 16:31:23 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.33 $ */ /* Copyright (c) 1989 Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/monst.h b/include/monst.h index 3a9bf151a..8e29c40b8 100644 --- a/include/monst.h +++ b/include/monst.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 monst.h $NHDT-Date: 1738640524 2025/02/03 19:42:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.67 $ */ +/* NetHack 5.0 monst.h $NHDT-Date: 1781973083 2026/06/20 16:31:23 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.78 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/monsters.h b/include/monsters.h index 202411128..4677a3740 100644 --- a/include/monsters.h +++ b/include/monsters.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 monsters.h $NHDT-Date: 1723945838 2024/08/18 01:50:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.124 $ */ +/* NetHack 5.0 monsters.h $NHDT-Date: 1781973083 2026/06/20 16:31:23 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.134 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/nhmd4.h b/include/nhmd4.h index d9751b56d..658ec0117 100644 --- a/include/nhmd4.h +++ b/include/nhmd4.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 nhmd4.h $NHDT-Date: 1708811386 2024/02/24 21:49:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 nhmd4.h $NHDT-Date: 1781973084 2026/06/20 16:31:24 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ */ /*- Copyright (c) Kenneth Lorber, Kensington, Maryland, 2024 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/nhregex.h b/include/nhregex.h index 5f6c4c2ca..e85fe2f23 100644 --- a/include/nhregex.h +++ b/include/nhregex.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 nhregex.h $NHDT-Date: $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: $ */ +/* NetHack 5.0 nhregex.h $NHDT-Date: $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: $ */ /* NetHack may be freely redistributed. See license for details. */ #ifndef NHREGEX_H diff --git a/include/obj.h b/include/obj.h index 8d95bb007..ba5e26d5d 100644 --- a/include/obj.h +++ b/include/obj.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 obj.h $NHDT-Date: 1718999845 2024/06/21 19:57:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ +/* NetHack 5.0 obj.h $NHDT-Date: 1781973084 2026/06/20 16:31:24 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.131 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/objclass.h b/include/objclass.h index 96468187a..4e006fb59 100644 --- a/include/objclass.h +++ b/include/objclass.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 objclass.h $NHDT-Date: 1596498553 2020/08/03 23:49:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.22 $ */ +/* NetHack 5.0 objclass.h $NHDT-Date: 1781973084 2026/06/20 16:31:24 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.43 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/objects.h b/include/objects.h index f5d42510e..f1f410606 100644 --- a/include/objects.h +++ b/include/objects.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 objects.h $NHDT-Date: 1749097644 2025/06/04 20:27:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ +/* NetHack 5.0 objects.h $NHDT-Date: 1781973085 2026/06/20 16:31:25 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.39 $ */ /* Copyright (c) Mike Threepoint, 1989. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/patchlevel.h b/include/patchlevel.h index 4c66c7fd2..7bf713ff5 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 patchlevel.h $NHDT-Date: 1753856387 2025/07/29 22:19:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.288 $ */ +/* NetHack 5.0 patchlevel.h $NHDT-Date: 1781973085 2026/06/20 16:31:25 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.310 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/pcconf.h b/include/pcconf.h index e1fd14cfe..a4adbbd9f 100644 --- a/include/pcconf.h +++ b/include/pcconf.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 pcconf.h $NHDT-Date: 1596498554 2020/08/03 23:49:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.28 $ */ +/* NetHack 5.0 pcconf.h $NHDT-Date: 1781973085 2026/06/20 16:31:25 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.40 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/permonst.h b/include/permonst.h index 895e4f964..24b7c0cbe 100644 --- a/include/permonst.h +++ b/include/permonst.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 permonst.h $NHDT-Date: 1725653014 2024/09/06 20:03:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ */ +/* NetHack 5.0 permonst.h $NHDT-Date: 1781973085 2026/06/20 16:31:25 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.31 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/prop.h b/include/prop.h index 5b846698e..e7a108e01 100644 --- a/include/prop.h +++ b/include/prop.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 prop.h $NHDT-Date: 1702274027 2023/12/11 05:53:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 5.0 prop.h $NHDT-Date: 1781973086 2026/06/20 16:31:26 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.28 $ */ /* Copyright (c) 1989 Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/quest.h b/include/quest.h index 5ab48a756..d91dd8f93 100644 --- a/include/quest.h +++ b/include/quest.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 quest.h $NHDT-Date: 1596498556 2020/08/03 23:49:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 quest.h $NHDT-Date: 1781973086 2026/06/20 16:31:26 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.16 $ */ /* Copyright (c) Mike Stephenson 1991. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/rect.h b/include/rect.h index b8395c5f4..ef444a223 100644 --- a/include/rect.h +++ b/include/rect.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 rect.h $NHDT-Date: 1596498557 2020/08/03 23:49:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 rect.h $NHDT-Date: 1781973086 2026/06/20 16:31:26 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) 1990 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/region.h b/include/region.h index ba82dd710..87cda9f0e 100644 --- a/include/region.h +++ b/include/region.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 region.h $NHDT-Date: 1596498557 2020/08/03 23:49:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 region.h $NHDT-Date: 1781973086 2026/06/20 16:31:26 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.21 $ */ /* Copyright (c) 1996 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/rm.h b/include/rm.h index e97822b4c..729997efa 100644 --- a/include/rm.h +++ b/include/rm.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 rm.h $NHDT-Date: 1745114235 2025/04/19 17:57:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.120 $ */ +/* NetHack 5.0 rm.h $NHDT-Date: 1781973087 2026/06/20 16:31:27 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.126 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/savefile.h b/include/savefile.h index 3307de1ca..22eb5ac6e 100644 --- a/include/savefile.h +++ b/include/savefile.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 savefile.h $NHDT-Date: 1738638877 2025/02/03 19:14:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1476 $ */ +/* NetHack 5.0 savefile.h $NHDT-Date: 1781973087 2026/06/20 16:31:27 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ */ /* Copyright (c) Michael Allison, 2025. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/seffects.h b/include/seffects.h index bd62c9543..9ad03b0d5 100644 --- a/include/seffects.h +++ b/include/seffects.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 seffects.h $NHDT-Date: 1693253118 2023/08/28 20:05:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ */ +/* NetHack 5.0 seffects.h $NHDT-Date: 1781973087 2026/06/20 16:31:27 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.7 $ */ /* Copyright (c) Michael Allison, 2023 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/skills.h b/include/skills.h index 40204aa4f..7ddb4a5cd 100644 --- a/include/skills.h +++ b/include/skills.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 skills.h $NHDT-Date: 1596498559 2020/08/03 23:49:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.16 $ */ +/* NetHack 5.0 skills.h $NHDT-Date: 1781973087 2026/06/20 16:31:27 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.21 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985-1999. */ /*-Copyright (c) Pasi Kallinen, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/sndprocs.h b/include/sndprocs.h index d09e4e1e7..0a5f879d4 100755 --- a/include/sndprocs.h +++ b/include/sndprocs.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 sndprocs.h $NHDT-Date: 1725653015 2024/09/06 20:03:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ */ +/* NetHack 5.0 sndprocs.h $NHDT-Date: 1781973088 2026/06/20 16:31:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.28 $ */ /* Copyright (c) Michael Allison, 2022 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/sp_lev.h b/include/sp_lev.h index 3aec7c2cf..3b00335d5 100644 --- a/include/sp_lev.h +++ b/include/sp_lev.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 sp_lev.h $NHDT-Date: 1622361649 2021/05/30 08:00:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ +/* NetHack 5.0 sp_lev.h $NHDT-Date: 1781973088 2026/06/20 16:31:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.62 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/spell.h b/include/spell.h index 8f68f5c94..5d42ab733 100644 --- a/include/spell.h +++ b/include/spell.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 spell.h $NHDT-Date: 1646838388 2022/03/09 15:06:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 spell.h $NHDT-Date: 1781973088 2026/06/20 16:31:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.21 $ */ /* Copyright 1986, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/stairs.h b/include/stairs.h index e52ad7075..8d2371fda 100644 --- a/include/stairs.h +++ b/include/stairs.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 stairs.h $NHDT-Date: 1685863327 2023/06/04 07:22:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ +/* NetHack 5.0 stairs.h $NHDT-Date: 1781973088 2026/06/20 16:31:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.1 $ */ /* Copyright (c) 2024 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/tcap.h b/include/tcap.h index 785458ed1..ddab92ec8 100644 --- a/include/tcap.h +++ b/include/tcap.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 tcap.h $NHDT-Date: 1596498562 2020/08/03 23:49:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 tcap.h $NHDT-Date: 1781973089 2026/06/20 16:31:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.17 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1989. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/tile2x11.h b/include/tile2x11.h index ffdfda291..d801c5a87 100644 --- a/include/tile2x11.h +++ b/include/tile2x11.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 tile2x11.h $NHDT-Date: 1597274123 2020/08/12 23:15:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 tile2x11.h $NHDT-Date: 1781973089 2026/06/20 16:31:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) 2002 by David Cohrs */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/tileset.h b/include/tileset.h index ef432732f..20c5fe6a7 100644 --- a/include/tileset.h +++ b/include/tileset.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 tileset.h $NHDT-Date: 1596498564 2020/08/03 23:49:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ */ +/* NetHack 5.0 tileset.h $NHDT-Date: 1781973089 2026/06/20 16:31:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ */ /* Copyright (c) Ray Chason, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/timeout.h b/include/timeout.h index 946959ae9..4fa967488 100644 --- a/include/timeout.h +++ b/include/timeout.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 timeout.h $NHDT-Date: 1705087443 2024/01/12 19:24:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.23 $ */ +/* NetHack 5.0 timeout.h $NHDT-Date: 1781973089 2026/06/20 16:31:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.27 $ */ /* Copyright 1994, Dean Luick */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/tradstdc.h b/include/tradstdc.h index a202c0c7b..f42eba1a9 100644 --- a/include/tradstdc.h +++ b/include/tradstdc.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 tradstdc.h $NHDT-Date: 1744938651 2025/04/17 17:10:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.67 $ */ +/* NetHack 5.0 tradstdc.h $NHDT-Date: 1781973090 2026/06/20 16:31:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.71 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/trap.h b/include/trap.h index d756cde03..d8ae807ab 100644 --- a/include/trap.h +++ b/include/trap.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 trap.h $NHDT-Date: 1670316586 2022/12/06 08:49:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.31 $ */ +/* NetHack 5.0 trap.h $NHDT-Date: 1781973090 2026/06/20 16:31:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.38 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/vision.h b/include/vision.h index b0728f763..c519718e1 100644 --- a/include/vision.h +++ b/include/vision.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 vision.h $NHDT-Date: 1666478832 2022/10/22 22:47:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 vision.h $NHDT-Date: 1781973090 2026/06/20 16:31:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.20 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/vmsconf.h b/include/vmsconf.h index a4d1eb724..bafb9ed65 100644 --- a/include/vmsconf.h +++ b/include/vmsconf.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 vmsconf.h $NHDT-Date: 1596498569 2020/08/03 23:49:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.33 $ */ +/* NetHack 5.0 vmsconf.h $NHDT-Date: 1781973090 2026/06/20 16:31:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.48 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/warnings.h b/include/warnings.h index 9f2858a3d..96d104c23 100644 --- a/include/warnings.h +++ b/include/warnings.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 warnings.h $NHDT-Date: 1596498562 2020/08/03 23:49:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 5.0 warnings.h $NHDT-Date: 1781973090 2026/06/20 16:31:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) Michael Allison, 2021. */ #ifndef WARNINGS_H diff --git a/include/weight.h b/include/weight.h index 967ba0f0e..38a82e149 100644 --- a/include/weight.h +++ b/include/weight.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 weight.h $NHDT-Date: 1742427965 2025/03/19 23:46:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ */ +/* NetHack 5.0 weight.h $NHDT-Date: 1781973091 2026/06/20 16:31:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ */ /* Copyright (c) Michael Allison, 2025. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/winX.h b/include/winX.h index e26faf5b8..f408aee04 100644 --- a/include/winX.h +++ b/include/winX.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 winX.h $NHDT-Date: 1740795096 2025/02/28 18:11:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.65 $ */ +/* NetHack 5.0 winX.h $NHDT-Date: 1781973092 2026/06/20 16:31:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.69 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/winami.h b/include/winami.h index 2b084a68c..16732101b 100644 --- a/include/winami.h +++ b/include/winami.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 winami.h $NHDT-Date: 1596498569 2020/08/03 23:49:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 winami.h $NHDT-Date: 1781973091 2026/06/20 16:31:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.16 $ */ /* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1991. */ /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1992, 1993. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/windconf.h b/include/windconf.h index cf113aee1..2ba5b182e 100644 --- a/include/windconf.h +++ b/include/windconf.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 windconf.h $NHDT-Date: 1596498552 2020/08/03 23:49:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.89 $ */ +/* NetHack 5.0 windconf.h $NHDT-Date: 1781973091 2026/06/20 16:31:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.133 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/winprocs.h b/include/winprocs.h index fea60cf0b..5ae1d2606 100644 --- a/include/winprocs.h +++ b/include/winprocs.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 winprocs.h $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.83 $ */ +/* NetHack 5.0 winprocs.h $NHDT-Date: 1781973091 2026/06/20 16:31:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.95 $ */ /* Copyright (c) David Cohrs, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/wintty.h b/include/wintty.h index f59b87229..54861e82b 100644 --- a/include/wintty.h +++ b/include/wintty.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 wintty.h $NHDT-Date: 1656014599 2022/06/23 20:03:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.55 $ */ +/* NetHack 5.0 wintty.h $NHDT-Date: 1781973092 2026/06/20 16:31:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.84 $ */ /* Copyright (c) David Cohrs, 1991,1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/wintype.h b/include/wintype.h index 08da476f8..4df54c16f 100644 --- a/include/wintype.h +++ b/include/wintype.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 wintype.h $NHDT-Date: 1717880364 2024/06/08 20:59:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.52 $ */ +/* NetHack 5.0 wintype.h $NHDT-Date: 1781973092 2026/06/20 16:31:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.60 $ */ /* Copyright (c) David Cohrs, 1991 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/xwindow.h b/include/xwindow.h index 72edd084f..7f363393e 100644 --- a/include/xwindow.h +++ b/include/xwindow.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 xwindow.h $NHDT-Date: 1596498574 2020/08/03 23:49:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 xwindow.h $NHDT-Date: 1781973092 2026/06/20 16:31:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/xwindowp.h b/include/xwindowp.h index 6eb8bfdda..ca6038ffe 100644 --- a/include/xwindowp.h +++ b/include/xwindowp.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 xwindowp.h $NHDT-Date: 1596498575 2020/08/03 23:49:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 xwindowp.h $NHDT-Date: 1781973093 2026/06/20 16:31:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/you.h b/include/you.h index d788046bf..33e2f840f 100644 --- a/include/you.h +++ b/include/you.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 you.h $NHDT-Date: 1702349061 2023/12/12 02:44:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.75 $ */ +/* NetHack 5.0 you.h $NHDT-Date: 1781973093 2026/06/20 16:31:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.89 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/youprop.h b/include/youprop.h index 4aa6557fa..468dd684b 100644 --- a/include/youprop.h +++ b/include/youprop.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 youprop.h $NHDT-Date: 1725653018 2024/09/06 20:03:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.45 $ */ +/* NetHack 5.0 youprop.h $NHDT-Date: 1781973093 2026/06/20 16:31:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.50 $ */ /* Copyright (c) 1989 Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/allmain.c b/src/allmain.c index 75e54027a..8f747564a 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 allmain.c $NHDT-Date: 1771213100 2026/02/15 19:38:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.286 $ */ +/* NetHack 5.0 allmain.c $NHDT-Date: 1781973040 2026/06/20 16:30:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.304 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/alloc.c b/src/alloc.c index 84ee660f9..1861a04d6 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 alloc.c $NHDT-Date: 1737281026 2025/01/19 02:03:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.38 $ */ +/* NetHack 5.0 alloc.c $NHDT-Date: 1781973040 2026/06/20 16:30:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.42 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/apply.c b/src/apply.c index 2f4db65c5..45cae0660 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 apply.c $NHDT-Date: 1769342601 2026/01/25 04:03:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.475 $ */ +/* NetHack 5.0 apply.c $NHDT-Date: 1781973040 2026/06/20 16:30:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.482 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/artifact.c b/src/artifact.c index 8abe196d7..348f2108d 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 artifact.c $NHDT-Date: 1715889721 2024/05/16 20:02:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.236 $ */ +/* NetHack 5.0 artifact.c $NHDT-Date: 1781973041 2026/06/20 16:30:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.264 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/attrib.c b/src/attrib.c index aaad2dbd0..16469fbcf 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 attrib.c $NHDT-Date: 1777000050 2026/04/23 19:07:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.137 $ */ +/* NetHack 5.0 attrib.c $NHDT-Date: 1781973041 2026/06/20 16:30:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.142 $ */ /* Copyright 1988, 1989, 1990, 1992, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/ball.c b/src/ball.c index 1531c3b9e..1ed458319 100644 --- a/src/ball.c +++ b/src/ball.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 ball.c $NHDT-Date: 1596498150 2020/08/03 23:42:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.51 $ */ +/* NetHack 5.0 ball.c $NHDT-Date: 1781973041 2026/06/20 16:30:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.78 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) David Cohrs, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/bones.c b/src/bones.c index e55857d4b..715580f98 100644 --- a/src/bones.c +++ b/src/bones.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 bones.c $NHDT-Date: 1701500709 2023/12/02 07:05:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.129 $ */ +/* NetHack 5.0 bones.c $NHDT-Date: 1781973041 2026/06/20 16:30:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.159 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/botl.c b/src/botl.c index dea5c2e42..4447cbb5e 100644 --- a/src/botl.c +++ b/src/botl.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 botl.c $NHDT-Date: 1769839231 2026/01/30 22:00:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.277 $ */ +/* NetHack 5.0 botl.c $NHDT-Date: 1781973042 2026/06/20 16:30:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.286 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/calendar.c b/src/calendar.c index deea28daf..61f984cfc 100644 --- a/src/calendar.c +++ b/src/calendar.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 calendar.c $NHDT-Date: 1706213796 2024/01/25 20:16:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ +/* NetHack 5.0 calendar.c $NHDT-Date: 1781973042 2026/06/20 16:30:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* Copyright (c) Robert Patrick Rankin, 1991 */ diff --git a/src/cfgfiles.c b/src/cfgfiles.c index f3138920c..08db400d6 100644 --- a/src/cfgfiles.c +++ b/src/cfgfiles.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 cfgfiles.c $NHDT-Date: 1740532826 2025/02/25 17:20:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.417 $ */ +/* NetHack 5.0 cfgfiles.c $NHDT-Date: 1781973042 2026/06/20 16:30:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.23 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/cmd.c b/src/cmd.c index 73b6c4c63..882a371ca 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 cmd.c $NHDT-Date: 1762680996 2025/11/09 01:36:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.755 $ */ +/* NetHack 5.0 cmd.c $NHDT-Date: 1781973043 2026/06/20 16:30:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.772 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/coloratt.c b/src/coloratt.c index a5d040fda..d8685b919 100644 --- a/src/coloratt.c +++ b/src/coloratt.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 coloratt.c $NHDT-Date: 1737286550 2025/01/19 03:35:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 coloratt.c $NHDT-Date: 1781973043 2026/06/20 16:30:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.20 $ */ /* Copyright (c) Pasi Kallinen, 2024 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/date.c b/src/date.c index a1c80a385..8ec8f4061 100644 --- a/src/date.c +++ b/src/date.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 date.c $NHDT-Date: 1655402414 2022/06/16 18:00:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ */ +/* NetHack 5.0 date.c $NHDT-Date: 1781973043 2026/06/20 16:30:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) Michael Allison, 2021. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/dbridge.c b/src/dbridge.c index 52fd4aa56..0c9352432 100644 --- a/src/dbridge.c +++ b/src/dbridge.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 dbridge.c $NHDT-Date: 1772771734 2026/03/05 20:35:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ */ +/* NetHack 5.0 dbridge.c $NHDT-Date: 1781973044 2026/06/20 16:30:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.74 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/decl.c b/src/decl.c index 8b04a05ac..365500a72 100644 --- a/src/decl.c +++ b/src/decl.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 decl.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.341 $ */ +/* NetHack 5.0 decl.c $NHDT-Date: 1781973044 2026/06/20 16:30:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.368 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/detect.c b/src/detect.c index ef9348001..8f93df374 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 detect.c $NHDT-Date: 1763708572 2025/11/20 23:02:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.191 $ */ +/* NetHack 5.0 detect.c $NHDT-Date: 1781973044 2026/06/20 16:30:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.197 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/dig.c b/src/dig.c index 29a242fa8..fa9ea2108 100644 --- a/src/dig.c +++ b/src/dig.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 dig.c $NHDT-Date: 1740629713 2025/02/26 20:15:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.227 $ */ +/* NetHack 5.0 dig.c $NHDT-Date: 1781973044 2026/06/20 16:30:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.236 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/display.c b/src/display.c index 76daaa30b..3e74ea42e 100644 --- a/src/display.c +++ b/src/display.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 display.c $NHDT-Date: 1777000050 2026/04/23 19:07:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.263 $ */ +/* NetHack 5.0 display.c $NHDT-Date: 1781973045 2026/06/20 16:30:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.270 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */ /* and Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/dlb.c b/src/dlb.c index a68126dca..1a39cc3dd 100644 --- a/src/dlb.c +++ b/src/dlb.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 dlb.c $NHDT-Date: 1596498157 2020/08/03 23:42:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.20 $ */ +/* NetHack 5.0 dlb.c $NHDT-Date: 1781973045 2026/06/20 16:30:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.30 $ */ /* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1993. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/do.c b/src/do.c index ea55197d7..5de166814 100644 --- a/src/do.c +++ b/src/do.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 do.c $NHDT-Date: 1774269965 2026/03/23 04:46:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.404 $ */ +/* NetHack 5.0 do.c $NHDT-Date: 1781973045 2026/06/20 16:30:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.411 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/do_name.c b/src/do_name.c index 75f33815f..d3943b7cf 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 do_name.c $NHDT-Date: 1737013431 2025/01/15 23:43:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.326 $ */ +/* NetHack 5.0 do_name.c $NHDT-Date: 1781973046 2026/06/20 16:30:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.339 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/do_wear.c b/src/do_wear.c index b5593ab36..c75e4b2f8 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 do_wear.c $NHDT-Date: 1737343372 2025/01/19 19:22:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.201 $ */ +/* NetHack 5.0 do_wear.c $NHDT-Date: 1781973047 2026/06/20 16:30:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.212 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/dog.c b/src/dog.c index 05e7e9e88..1bbee167e 100644 --- a/src/dog.c +++ b/src/dog.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 dog.c $NHDT-Date: 1753856387 2025/07/29 22:19:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.190 $ */ +/* NetHack 5.0 dog.c $NHDT-Date: 1781973045 2026/06/20 16:30:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.197 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/dogmove.c b/src/dogmove.c index 6f2882100..ad499b7f4 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 dogmove.c $NHDT-Date: 1725733007 2024/09/07 18:16:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.156 $ */ +/* NetHack 5.0 dogmove.c $NHDT-Date: 1781973046 2026/06/20 16:30:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.177 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/dokick.c b/src/dokick.c index 45cc67798..a37e39fd9 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 dokick.c $NHDT-Date: 1712453347 2024/04/07 01:29:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.223 $ */ +/* NetHack 5.0 dokick.c $NHDT-Date: 1781973046 2026/06/20 16:30:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.237 $ */ /* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/dothrow.c b/src/dothrow.c index 4d61959eb..5c8997bcf 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 dothrow.c $NHDT-Date: 1737343372 2025/01/19 19:22:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.300 $ */ +/* NetHack 5.0 dothrow.c $NHDT-Date: 1781973046 2026/06/20 16:30:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.318 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/drawing.c b/src/drawing.c index 375db072b..ec3a38668 100644 --- a/src/drawing.c +++ b/src/drawing.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 drawing.c $NHDT-Date: 1596498163 2020/08/03 23:42:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.78 $ */ +/* NetHack 5.0 drawing.c $NHDT-Date: 1781973047 2026/06/20 16:30:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.97 $ */ /* Copyright (c) NetHack Development Team 1992. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/dungeon.c b/src/dungeon.c index f299632a6..b88ee0fa3 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 dungeon.c $NHDT-Date: 1737343478 2025/01/19 19:24:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.228 $ */ +/* NetHack 5.0 dungeon.c $NHDT-Date: 1781973047 2026/06/20 16:30:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.239 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/earlyarg.c b/src/earlyarg.c index 8c03c0e19..2d3315fdf 100755 --- a/src/earlyarg.c +++ b/src/earlyarg.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 earlyarg.c $NHDT-Date: 1771213100 2026/02/15 19:38:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.286 $ */ +/* NetHack 5.0 earlyarg.c $NHDT-Date: 1781973047 2026/06/20 16:30:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/eat.c b/src/eat.c index c7f0bd58c..242429552 100644 --- a/src/eat.c +++ b/src/eat.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 eat.c $NHDT-Date: 1740534854 2025/02/25 17:54:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.344 $ */ +/* NetHack 5.0 eat.c $NHDT-Date: 1781973048 2026/06/20 16:30:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.354 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/end.c b/src/end.c index 9bee60b87..ef26d317d 100644 --- a/src/end.c +++ b/src/end.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 end.c $NHDT-Date: 1720397752 2024/07/08 00:15:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.315 $ */ +/* NetHack 5.0 end.c $NHDT-Date: 1781973048 2026/06/20 16:30:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.349 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/engrave.c b/src/engrave.c index c16db8150..76b95716d 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 engrave.c $NHDT-Date: 1737345573 2025/01/19 19:59:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.165 $ */ +/* NetHack 5.0 engrave.c $NHDT-Date: 1781973048 2026/06/20 16:30:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.179 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/exper.c b/src/exper.c index 003a5035b..9b65e79da 100644 --- a/src/exper.c +++ b/src/exper.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 exper.c $NHDT-Date: 1706133782 2024/01/24 22:03:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.62 $ */ +/* NetHack 5.0 exper.c $NHDT-Date: 1781973049 2026/06/20 16:30:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.71 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2007. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/explode.c b/src/explode.c index eae1cbb28..e2e5fa90b 100644 --- a/src/explode.c +++ b/src/explode.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 explode.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.122 $ */ +/* NetHack 5.0 explode.c $NHDT-Date: 1781973049 2026/06/20 16:30:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.128 $ */ /* Copyright (C) 1990 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/extralev.c b/src/extralev.c index a7cdccaa9..740f01fa4 100644 --- a/src/extralev.c +++ b/src/extralev.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 extralev.c $NHDT-Date: 1737345573 2025/01/19 19:59:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.28 $ */ +/* NetHack 5.0 extralev.c $NHDT-Date: 1781973049 2026/06/20 16:30:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.30 $ */ /* Copyright 1988, 1989 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/files.c b/src/files.c index 88e5adfa2..d03ad1071 100644 --- a/src/files.c +++ b/src/files.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 files.c $NHDT-Date: 1740532826 2025/02/25 17:20:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.417 $ */ +/* NetHack 5.0 files.c $NHDT-Date: 1781973049 2026/06/20 16:30:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.448 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/fountain.c b/src/fountain.c index c4702782a..8cafaf2a2 100644 --- a/src/fountain.c +++ b/src/fountain.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 fountain.c $NHDT-Date: 1699582923 2023/11/10 02:22:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.100 $ */ +/* NetHack 5.0 fountain.c $NHDT-Date: 1781973050 2026/06/20 16:30:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.121 $ */ /* Copyright Scott R. Turner, srt@ucla, 10/27/86 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/getpos.c b/src/getpos.c index 25813d6a4..643d12bd6 100644 --- a/src/getpos.c +++ b/src/getpos.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 getpos.c $NHDT-Date: 1763708572 2025/11/20 23:02:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ */ +/* NetHack 5.0 getpos.c $NHDT-Date: 1781973050 2026/06/20 16:30:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ */ /*-Copyright (c) Pasi Kallinen, 2023. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/hack.c b/src/hack.c index 4dfca4006..6175d46e2 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 hack.c $NHDT-Date: 1763708572 2025/11/20 23:02:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.494 $ */ +/* NetHack 5.0 hack.c $NHDT-Date: 1781973050 2026/06/20 16:30:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.508 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/hacklib.c b/src/hacklib.c index 35757e4ed..32e3af3b6 100644 --- a/src/hacklib.c +++ b/src/hacklib.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 hacklib.c $NHDT-Date: 1706213796 2024/01/25 20:16:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ +/* NetHack 5.0 hacklib.c $NHDT-Date: 1781973051 2026/06/20 16:30:51 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.133 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* Copyright (c) Robert Patrick Rankin, 1991 */ diff --git a/src/iactions.c b/src/iactions.c index 62566569c..01c956e70 100644 --- a/src/iactions.c +++ b/src/iactions.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 iactions.c $NHDT-Date: 1762680996 2025/11/09 01:36:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.543 $ */ +/* NetHack 5.0 iactions.c $NHDT-Date: 1781973051 2026/06/20 16:30:51 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2026. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/insight.c b/src/insight.c index b6e56cd19..f3a1aca4b 100644 --- a/src/insight.c +++ b/src/insight.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 insight.c $NHDT-Date: 1777004419 2026/04/23 20:20:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.134 $ */ +/* NetHack 5.0 insight.c $NHDT-Date: 1781973051 2026/06/20 16:30:51 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.139 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/invent.c b/src/invent.c index 4c7f61bff..347d915cf 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 invent.c $NHDT-Date: 1762680996 2025/11/09 01:36:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.543 $ */ +/* NetHack 5.0 invent.c $NHDT-Date: 1781973052 2026/06/20 16:30:52 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.563 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/light.c b/src/light.c index 48f3671b1..02fa686ac 100644 --- a/src/light.c +++ b/src/light.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 light.c $NHDT-Date: 1773375430 2026/03/12 20:17:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.82 $ */ +/* NetHack 5.0 light.c $NHDT-Date: 1781973052 2026/06/20 16:30:52 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.88 $ */ /* Copyright (c) Dean Luick, 1994 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/lock.c b/src/lock.c index 7f62eb890..89378d088 100644 --- a/src/lock.c +++ b/src/lock.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 lock.c $NHDT-Date: 1741793439 2025/03/12 07:30:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.145 $ */ +/* NetHack 5.0 lock.c $NHDT-Date: 1781973052 2026/06/20 16:30:52 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.150 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mail.c b/src/mail.c index 2f9528188..91706b80a 100644 --- a/src/mail.c +++ b/src/mail.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mail.c $NHDT-Date: 1762750699 2025/11/09 20:58:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.77 $ */ +/* NetHack 5.0 mail.c $NHDT-Date: 1781973052 2026/06/20 16:30:52 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.80 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/makemon.c b/src/makemon.c index 9af36be2f..18fb3bff1 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 makemon.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.271 $ */ +/* NetHack 5.0 makemon.c $NHDT-Date: 1781973053 2026/06/20 16:30:53 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.277 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mcastu.c b/src/mcastu.c index 655a3826e..a7873c656 100644 --- a/src/mcastu.c +++ b/src/mcastu.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mcastu.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.111 $ */ +/* NetHack 5.0 mcastu.c $NHDT-Date: 1781973053 2026/06/20 16:30:53 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.122 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mdlib.c b/src/mdlib.c index dfa3fb72b..6648717d4 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mdlib.c $NHDT-Date: 1701499945 2023/12/02 06:52:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.51 $ */ +/* NetHack 5.0 mdlib.c $NHDT-Date: 1781973053 2026/06/20 16:30:53 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.74 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* Copyright (c) M. Stephenson, 1990, 1991. */ diff --git a/src/mhitm.c b/src/mhitm.c index ff59ef470..4e7f0f078 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhitm.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.253 $ */ +/* NetHack 5.0 mhitm.c $NHDT-Date: 1781973054 2026/06/20 16:30:54 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.269 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mhitu.c b/src/mhitu.c index 178f43eb3..fe5fcc65c 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhitu.c $NHDT-Date: 1775259433 2026/04/03 15:37:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.341 $ */ +/* NetHack 5.0 mhitu.c $NHDT-Date: 1781973054 2026/06/20 16:30:54 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.347 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/minion.c b/src/minion.c index 86a976908..0a588989f 100644 --- a/src/minion.c +++ b/src/minion.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 minion.c $NHDT-Date: 1762727599 2025/11/09 14:33:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.81 $ */ +/* NetHack 5.0 minion.c $NHDT-Date: 1781973054 2026/06/20 16:30:54 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.88 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2008. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mklev.c b/src/mklev.c index 2c48af09a..c3d7a8a54 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mklev.c $NHDT-Date: 1737387068 2025/01/20 07:31:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.194 $ */ +/* NetHack 5.0 mklev.c $NHDT-Date: 1781973055 2026/06/20 16:30:55 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.207 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Alex Smith, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mkmap.c b/src/mkmap.c index 3ed81f14f..a84304ad1 100644 --- a/src/mkmap.c +++ b/src/mkmap.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mkmap.c $NHDT-Date: 1717432093 2024/06/03 16:28:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ */ +/* NetHack 5.0 mkmap.c $NHDT-Date: 1781973055 2026/06/20 16:30:55 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.47 $ */ /* Copyright (c) J. C. Collet, M. Stephenson and D. Cohrs, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mkmaze.c b/src/mkmaze.c index bba58e294..5f612aa24 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mkmaze.c $NHDT-Date: 1745114235 2025/04/19 17:57:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.179 $ */ +/* NetHack 5.0 mkmaze.c $NHDT-Date: 1781973055 2026/06/20 16:30:55 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.185 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mkobj.c b/src/mkobj.c index 735c88d34..47bfc4108 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mkobj.c $NHDT-Date: 1764044196 2025/11/24 20:16:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.326 $ */ +/* NetHack 5.0 mkobj.c $NHDT-Date: 1781973055 2026/06/20 16:30:55 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.335 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mkroom.c b/src/mkroom.c index 68ce1e1d6..a1def04cc 100644 --- a/src/mkroom.c +++ b/src/mkroom.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mkroom.c $NHDT-Date: 1613086701 2021/02/11 23:38:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.52 $ */ +/* NetHack 5.0 mkroom.c $NHDT-Date: 1781973056 2026/06/20 16:30:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.81 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mondata.c b/src/mondata.c index d7be05a18..e9d25095c 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mondata.c $NHDT-Date: 1738638877 2025/02/03 19:14:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.140 $ */ +/* NetHack 5.0 mondata.c $NHDT-Date: 1781973056 2026/06/20 16:30:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.148 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/monmove.c b/src/monmove.c index 10a97675a..7752b340a 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 monmove.c $NHDT-Date: 1737392015 2025/01/20 08:53:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.266 $ */ +/* NetHack 5.0 monmove.c $NHDT-Date: 1781973056 2026/06/20 16:30:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.284 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/monst.c b/src/monst.c index ef794c4c3..2a0e1fb11 100644 --- a/src/monst.c +++ b/src/monst.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 monst.c $NHDT-Date: 1705092160 2024/01/12 20:42:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.100 $ */ +/* NetHack 5.0 monst.c $NHDT-Date: 1781973056 2026/06/20 16:30:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.106 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mplayer.c b/src/mplayer.c index 267ab0d39..480f59619 100644 --- a/src/mplayer.c +++ b/src/mplayer.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mplayer.c $NHDT-Date: 1596498188 2020/08/03 23:43:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ +/* NetHack 5.0 mplayer.c $NHDT-Date: 1781973057 2026/06/20 16:30:57 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.54 $ */ /* Copyright (c) Izchak Miller, 1992. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mthrowu.c b/src/mthrowu.c index c292fd7e6..aea7a29ec 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mthrowu.c $NHDT-Date: 1737392015 2025/01/20 08:53:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.173 $ */ +/* NetHack 5.0 mthrowu.c $NHDT-Date: 1781973057 2026/06/20 16:30:57 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.192 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/muse.c b/src/muse.c index 1a8e6ea0c..0e4770d4e 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 muse.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.241 $ */ +/* NetHack 5.0 muse.c $NHDT-Date: 1781973057 2026/06/20 16:30:57 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.248 $ */ /* Copyright (C) 1990 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/music.c b/src/music.c index ce06dc954..b2e71e790 100644 --- a/src/music.c +++ b/src/music.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 music.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.120 $ */ +/* NetHack 5.0 music.c $NHDT-Date: 1781973058 2026/06/20 16:30:58 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.126 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/nhlobj.c b/src/nhlobj.c index f4fa7dcf1..36ea624e5 100644 --- a/src/nhlobj.c +++ b/src/nhlobj.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 nhlobj.c $NHDT-Date: 1576097301 2019/12/11 20:48:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 nhlobj.c $NHDT-Date: 1781973058 2026/06/20 16:30:58 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.42 $ */ /* Copyright (c) 2019 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/nhlsel.c b/src/nhlsel.c index cbaf6f9b8..817cb775a 100644 --- a/src/nhlsel.c +++ b/src/nhlsel.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 nhlua.c $NHDT-Date: 1769840272 2026/01/30 22:17:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.69 $ */ +/* NetHack 5.0 nhlua.c $NHDT-Date: 1781973058 2026/06/20 16:30:58 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.71 $ */ /* Copyright (c) 2018 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/nhlua.c b/src/nhlua.c index d4ec44cd9..7cd1b9cd3 100644 --- a/src/nhlua.c +++ b/src/nhlua.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 nhlua.c $NHDT-Date: 1744963460 2025/04/18 00:04:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.153 $ */ +/* NetHack 5.0 nhlua.c $NHDT-Date: 1781973059 2026/06/20 16:30:59 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.168 $ */ /* Copyright (c) 2018 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/nhmd4.c b/src/nhmd4.c index 580d8e49f..043166397 100644 --- a/src/nhmd4.c +++ b/src/nhmd4.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 nhmd4.c $NHDT-Date: 1708811387 2024/02/24 21:49:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 nhmd4.c $NHDT-Date: 1781973059 2026/06/20 16:30:59 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2024 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/o_init.c b/src/o_init.c index f6ede4dab..ead30d1d9 100644 --- a/src/o_init.c +++ b/src/o_init.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 o_init.c $NHDT-Date: 1771216675 2026/02/15 20:37:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.101 $ */ +/* NetHack 5.0 o_init.c $NHDT-Date: 1781973060 2026/06/20 16:31:00 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.106 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/objects.c b/src/objects.c index b6bbaa3dd..51e93aa84 100644 --- a/src/objects.c +++ b/src/objects.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 objects.c $NHDT-Date: 1596498192 2020/08/03 23:43:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.66 $ */ +/* NetHack 5.0 objects.c $NHDT-Date: 1781973059 2026/06/20 16:30:59 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.76 $ */ /* Copyright (c) Mike Threepoint, 1989. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/objnam.c b/src/objnam.c index f9bc1749f..d9efc1521 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 objnam.c $NHDT-Date: 1745114235 2025/04/19 17:57:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.453 $ */ +/* NetHack 5.0 objnam.c $NHDT-Date: 1781973060 2026/06/20 16:31:00 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.464 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/pager.c b/src/pager.c index 6f9cd22e8..9cc16fb85 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 pager.c $NHDT-Date: 1774846177 2026/03/29 20:49:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.296 $ */ +/* NetHack 5.0 pager.c $NHDT-Date: 1781973061 2026/06/20 16:31:01 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.302 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/pickup.c b/src/pickup.c index 5de4c3c98..7cb487b4c 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 pickup.c $NHDT-Date: 1773373633 2026/03/12 19:47:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.386 $ */ +/* NetHack 5.0 pickup.c $NHDT-Date: 1781973061 2026/06/20 16:31:01 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.397 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/pline.c b/src/pline.c index 49c293195..83a42e8df 100644 --- a/src/pline.c +++ b/src/pline.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 pline.c $NHDT-Date: 1719819280 2024/07/01 07:34:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.130 $ */ +/* NetHack 5.0 pline.c $NHDT-Date: 1781973061 2026/06/20 16:31:01 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.150 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/polyself.c b/src/polyself.c index a3f31a0ab..6e380ad96 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 polyself.c $NHDT-Date: 1772101811 2026/02/26 02:30:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.227 $ */ +/* NetHack 5.0 polyself.c $NHDT-Date: 1781973061 2026/06/20 16:31:01 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.233 $ */ /* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/potion.c b/src/potion.c index cda436427..c259e308f 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 potion.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.279 $ */ +/* NetHack 5.0 potion.c $NHDT-Date: 1781973062 2026/06/20 16:31:02 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.288 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/pray.c b/src/pray.c index a00f81a9f..ffea72530 100644 --- a/src/pray.c +++ b/src/pray.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 pray.c $NHDT-Date: 1762680996 2025/11/09 01:36:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.244 $ */ +/* NetHack 5.0 pray.c $NHDT-Date: 1781973062 2026/06/20 16:31:02 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.253 $ */ /* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/priest.c b/src/priest.c index 643fe425d..d679893ee 100644 --- a/src/priest.c +++ b/src/priest.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 priest.c $NHDT-Date: 1764567778 2025/11/30 21:42:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.106 $ */ +/* NetHack 5.0 priest.c $NHDT-Date: 1781973062 2026/06/20 16:31:02 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.110 $ */ /* Copyright (c) Izchak Miller, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/quest.c b/src/quest.c index d57f1712b..c5ed1642c 100644 --- a/src/quest.c +++ b/src/quest.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 quest.c $NHDT-Date: 1774269965 2026/03/23 04:46:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.46 $ */ +/* NetHack 5.0 quest.c $NHDT-Date: 1781973063 2026/06/20 16:31:03 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.48 $ */ /* Copyright 1991, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/read.c b/src/read.c index d08a9acb2..f6aa5744a 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 read.c $NHDT-Date: 1762577372 2025/11/07 20:49:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.323 $ */ +/* NetHack 5.0 read.c $NHDT-Date: 1781973063 2026/06/20 16:31:03 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.333 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/rect.c b/src/rect.c index aebd8216b..e63c2eac0 100644 --- a/src/rect.c +++ b/src/rect.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 rect.c $NHDT-Date: 1596498203 2020/08/03 23:43:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 rect.c $NHDT-Date: 1781973063 2026/06/20 16:31:03 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.26 $ */ /* Copyright (c) 1990 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/region.c b/src/region.c index 9fa2530e4..6980e06b5 100644 --- a/src/region.c +++ b/src/region.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 region.c $NHDT-Date: 1727251269 2024/09/25 08:01:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.104 $ */ +/* NetHack 5.0 region.c $NHDT-Date: 1781973064 2026/06/20 16:31:04 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.112 $ */ /* Copyright (c) 1996 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/restore.c b/src/restore.c index 2c9a01a75..dcd4d8164 100644 --- a/src/restore.c +++ b/src/restore.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 restore.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.234 $ */ +/* NetHack 5.0 restore.c $NHDT-Date: 1781973064 2026/06/20 16:31:04 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.265 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/rip.c b/src/rip.c index b7c7fbd72..fa8a425f9 100644 --- a/src/rip.c +++ b/src/rip.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 rip.c $NHDT-Date: 1597967808 2020/08/20 23:56:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.33 $ */ +/* NetHack 5.0 rip.c $NHDT-Date: 1781973064 2026/06/20 16:31:04 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.49 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/rnd.c b/src/rnd.c index 1994120af..3551b57a0 100644 --- a/src/rnd.c +++ b/src/rnd.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 rnd.c $NHDT-Date: 1596498205 2020/08/03 23:43:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ +/* NetHack 5.0 rnd.c $NHDT-Date: 1781973065 2026/06/20 16:31:05 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.41 $ */ /* Copyright (c) 2004 by Robert Patrick Rankin */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/role.c b/src/role.c index ee3e9a836..ead4345cf 100644 --- a/src/role.c +++ b/src/role.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 role.c $NHDT-Date: 1737607158 2025/01/22 20:39:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.107 $ */ +/* NetHack 5.0 role.c $NHDT-Date: 1781973065 2026/06/20 16:31:05 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.111 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985-1999. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/rumors.c b/src/rumors.c index b78bd2403..fb5d2faa6 100644 --- a/src/rumors.c +++ b/src/rumors.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 rumors.c $NHDT-Date: 1594370241 2020/07/10 08:37:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.56 $ */ +/* NetHack 5.0 rumors.c $NHDT-Date: 1781973065 2026/06/20 16:31:05 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.93 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/save.c b/src/save.c index d31e23148..72ff9f859 100644 --- a/src/save.c +++ b/src/save.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 save.c $NHDT-Date: 1737610109 2025/01/22 21:28:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.232 $ */ +/* NetHack 5.0 save.c $NHDT-Date: 1781973065 2026/06/20 16:31:05 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.263 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/selvar.c b/src/selvar.c index e1dad31af..1b9296415 100644 --- a/src/selvar.c +++ b/src/selvar.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 selvar.c $NHDT-Date: 1769840272 2026/01/30 22:17:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ */ +/* NetHack 5.0 selvar.c $NHDT-Date: 1781973066 2026/06/20 16:31:06 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ */ /* Copyright (c) 2024 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/sfstruct.c b/src/sfstruct.c index 424d57c88..00888d8d8 100644 --- a/src/sfstruct.c +++ b/src/sfstruct.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 sfstruct.c $NHDT-Date: 1606765215 2020/11/30 19:40:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ */ +/* NetHack 5.0 sfstruct.c $NHDT-Date: 1781973066 2026/06/20 16:31:06 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.28 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2025. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/shk.c b/src/shk.c index 117003f46..37e7b9422 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 shk.c $NHDT-Date: 1736516428 2025/01/10 05:40:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.306 $ */ +/* NetHack 5.0 shk.c $NHDT-Date: 1781973066 2026/06/20 16:31:06 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.323 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/shknam.c b/src/shknam.c index 393204ca5..54e76d0ec 100644 --- a/src/shknam.c +++ b/src/shknam.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 shknam.c $NHDT-Date: 1764109114 2025/11/25 22:18:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.86 $ */ +/* NetHack 5.0 shknam.c $NHDT-Date: 1781973067 2026/06/20 16:31:07 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.90 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/sit.c b/src/sit.c index 15c772cfd..2fc32471c 100644 --- a/src/sit.c +++ b/src/sit.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 sit.c $NHDT-Date: 1718136168 2024/06/11 20:02:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.95 $ */ +/* NetHack 5.0 sit.c $NHDT-Date: 1781973067 2026/06/20 16:31:07 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.112 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/sounds.c b/src/sounds.c index be48f9e30..aedf619d7 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 sounds.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.165 $ */ +/* NetHack 5.0 sounds.c $NHDT-Date: 1781973067 2026/06/20 16:31:07 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.172 $ */ /* Copyright (c) 1989 Janet Walz, Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/spell.c b/src/spell.c index 247997f43..e60c2e0d8 100644 --- a/src/spell.c +++ b/src/spell.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 spell.c $NHDT-Date: 1769498874 2026/01/26 23:27:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.185 $ */ +/* NetHack 5.0 spell.c $NHDT-Date: 1781973068 2026/06/20 16:31:08 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.189 $ */ /* Copyright (c) M. Stephenson 1988 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/steal.c b/src/steal.c index 524b2dd00..ded8c1749 100644 --- a/src/steal.c +++ b/src/steal.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 steal.c $NHDT-Date: 1720895742 2024/07/13 18:35:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.132 $ */ +/* NetHack 5.0 steal.c $NHDT-Date: 1781973068 2026/06/20 16:31:08 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.142 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/steed.c b/src/steed.c index 536feec6f..c76c61696 100644 --- a/src/steed.c +++ b/src/steed.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 steed.c $NHDT-Date: 1720128167 2024/07/04 21:22:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.121 $ */ +/* NetHack 5.0 steed.c $NHDT-Date: 1781973068 2026/06/20 16:31:08 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.132 $ */ /* Copyright (c) Kevin Hugo, 1998-1999. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/symbols.c b/src/symbols.c index 7b484505f..1512ed7c5 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 symbols.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.123 $ */ +/* NetHack 5.0 symbols.c $NHDT-Date: 1781973069 2026/06/20 16:31:09 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.128 $ */ /* Copyright (c) NetHack Development Team 2020. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/sys.c b/src/sys.c index 55e93eb02..6661b74a3 100644 --- a/src/sys.c +++ b/src/sys.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 sys.c $NHDT-Date: 1717449153 2024/06/03 21:12:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.64 $ */ +/* NetHack 5.0 sys.c $NHDT-Date: 1781973069 2026/06/20 16:31:09 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.74 $ */ /* Copyright (c) Kenneth Lorber, Kensington, Maryland, 2008. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/teleport.c b/src/teleport.c index 3792e02f6..649a58c4d 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 teleport.c $NHDT-Date: 1769342601 2026/01/25 04:03:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.239 $ */ +/* NetHack 5.0 teleport.c $NHDT-Date: 1781973069 2026/06/20 16:31:09 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.246 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/timeout.c b/src/timeout.c index 03f2bdcc3..9b83e33b5 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 timeout.c $NHDT-Date: 1776080125 2026/04/13 03:35:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.207 $ */ +/* NetHack 5.0 timeout.c $NHDT-Date: 1781973070 2026/06/20 16:31:10 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.212 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/topten.c b/src/topten.c index 97391b091..76869599d 100644 --- a/src/topten.c +++ b/src/topten.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 topten.c $NHDT-Date: 1606009004 2020/11/22 01:36:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.74 $ */ +/* NetHack 5.0 topten.c $NHDT-Date: 1781973070 2026/06/20 16:31:10 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.111 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/track.c b/src/track.c index 660e900c7..af0ee8b03 100644 --- a/src/track.c +++ b/src/track.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 track.c $NHDT-Date: 1596498219 2020/08/03 23:43:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 track.c $NHDT-Date: 1781973070 2026/06/20 16:31:10 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.24 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/trap.c b/src/trap.c index c9ab97563..3dae5590a 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 trap.c $NHDT-Date: 1741926700 2025/03/13 20:31:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.621 $ */ +/* NetHack 5.0 trap.c $NHDT-Date: 1781973071 2026/06/20 16:31:11 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.645 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/u_init.c b/src/u_init.c index ac41da92c..cca46f17d 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 u_init.c $NHDT-Date: 1769398807 2026/01/25 19:40:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.121 $ */ +/* NetHack 5.0 u_init.c $NHDT-Date: 1781973071 2026/06/20 16:31:11 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.127 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/uhitm.c b/src/uhitm.c index ada2fc1bd..8cd7403f7 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 uhitm.c $NHDT-Date: 1752823766 2025/07/17 23:29:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.477 $ */ +/* NetHack 5.0 uhitm.c $NHDT-Date: 1781973071 2026/06/20 16:31:11 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.503 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/vault.c b/src/vault.c index 94f50d909..6de691f73 100644 --- a/src/vault.c +++ b/src/vault.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 vault.c $NHDT-Date: 1737622664 2025/01/23 00:57:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.113 $ */ +/* NetHack 5.0 vault.c $NHDT-Date: 1781973072 2026/06/20 16:31:12 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.121 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/version.c b/src/version.c index 8fa0e0398..32da5c6d9 100644 --- a/src/version.c +++ b/src/version.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 version.c $NHDT-Date: 1737622664 2025/01/23 00:57:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.105 $ */ +/* NetHack 5.0 version.c $NHDT-Date: 1781973072 2026/06/20 16:31:12 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.118 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/vision.c b/src/vision.c index b640c6d3b..4b41f325c 100644 --- a/src/vision.c +++ b/src/vision.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 vision.c $NHDT-Date: 1777205478 2026/04/26 04:11:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.75 $ */ +/* NetHack 5.0 vision.c $NHDT-Date: 1781973072 2026/06/20 16:31:12 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.78 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/weapon.c b/src/weapon.c index 4dfa4a112..39b186812 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 weapon.c $NHDT-Date: 1725227810 2024/09/01 21:56:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.128 $ */ +/* NetHack 5.0 weapon.c $NHDT-Date: 1781973073 2026/06/20 16:31:13 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.147 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/were.c b/src/were.c index 4f1b81255..b8969ceb5 100644 --- a/src/were.c +++ b/src/were.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 were.c $NHDT-Date: 1766588485 2025/12/24 07:01:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.41 $ */ +/* NetHack 5.0 were.c $NHDT-Date: 1781973073 2026/06/20 16:31:13 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.46 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/wield.c b/src/wield.c index 515caa938..f0abd801f 100644 --- a/src/wield.c +++ b/src/wield.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 wield.c $NHDT-Date: 1707525193 2024/02/10 00:33:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.110 $ */ +/* NetHack 5.0 wield.c $NHDT-Date: 1781973073 2026/06/20 16:31:13 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.124 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2009. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/windows.c b/src/windows.c index 8337d9bbe..3169ade76 100644 --- a/src/windows.c +++ b/src/windows.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 windows.c $NHDT-Date: 1737345149 2025/01/19 19:52:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.138 $ */ +/* NetHack 5.0 windows.c $NHDT-Date: 1781973074 2026/06/20 16:31:14 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.147 $ */ /* Copyright (c) D. Cohrs, 1993. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/wizard.c b/src/wizard.c index b09e3a150..a7f6af3a5 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 wizard.c $NHDT-Date: 1741407262 2025/03/07 20:14:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ +/* NetHack 5.0 wizard.c $NHDT-Date: 1781973074 2026/06/20 16:31:14 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.121 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/wizcmds.c b/src/wizcmds.c index e7fda43ea..149607228 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 wizcmds.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ +/* NetHack 5.0 wizcmds.c $NHDT-Date: 1781973074 2026/06/20 16:31:14 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.36 $ */ /*-Copyright (c) Robert Patrick Rankin, 2024. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/worm.c b/src/worm.c index c5a12fd12..54c82300f 100644 --- a/src/worm.c +++ b/src/worm.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 worm.c $NHDT-Date: 1652689653 2022/05/16 08:27:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.56 $ */ +/* NetHack 5.0 worm.c $NHDT-Date: 1781973075 2026/06/20 16:31:15 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.73 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2009. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/worn.c b/src/worn.c index 14bb8fdbc..5efd376c6 100644 --- a/src/worn.c +++ b/src/worn.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 worn.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.119 $ */ +/* NetHack 5.0 worn.c $NHDT-Date: 1781973075 2026/06/20 16:31:15 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.124 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/write.c b/src/write.c index ba90c7d4c..2a2390cfe 100644 --- a/src/write.c +++ b/src/write.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 write.c $NHDT-Date: 1702023275 2023/12/08 08:14:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.41 $ */ +/* NetHack 5.0 write.c $NHDT-Date: 1781973075 2026/06/20 16:31:15 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.54 $ */ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" diff --git a/src/zap.c b/src/zap.c index 8aefcb1ea..3e578fbee 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 zap.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.584 $ */ +/* NetHack 5.0 zap.c $NHDT-Date: 1781973075 2026/06/20 16:31:15 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.596 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/util/dlb_main.c b/util/dlb_main.c index 3b0aaf421..238734980 100644 --- a/util/dlb_main.c +++ b/util/dlb_main.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 dlb_main.c $NHDT-Date: 1706213798 2024/01/25 20:16:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.27 $ */ +/* NetHack 5.0 dlb_main.c $NHDT-Date: 1706213798 2024/01/25 20:16:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.27 $ */ /* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1993. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/util/makedefs.c b/util/makedefs.c index 21dbb1089..f18623e2e 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 makedefs.c $NHDT-Date: 1702948590 2023/12/19 01:16:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.233 $ */ +/* NetHack 5.0 makedefs.c $NHDT-Date: 1702948590 2023/12/19 01:16:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.233 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* Copyright (c) M. Stephenson, 1990, 1991. */ diff --git a/util/mdgrep.h b/util/mdgrep.h index 1b64de3db..2de58266a 100644 --- a/util/mdgrep.h +++ b/util/mdgrep.h @@ -1,5 +1,5 @@ /* - * NetHack 5.0 mdgrep.h $NHDT-Date: 1710949914 2024/03/20 15:51:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.20 $ + * NetHack 5.0 mdgrep.h $NHDT-Date: 1710949914 2024/03/20 15:51:54 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.20 $ * Copyright (c) Kenneth Lorber, Kensington, Maryland, 2008 * NetHack may be freely redistributed. See license for details. * diff --git a/util/panic.c b/util/panic.c index 92c921ddb..581f15c0d 100644 --- a/util/panic.c +++ b/util/panic.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 panic.c $NHDT-Date: 1596498262 2020/08/03 23:44:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 panic.c $NHDT-Date: 1596498262 2020/08/03 23:44:22 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/util/recover.c b/util/recover.c index a1a7ed70b..e4f799ce0 100644 --- a/util/recover.c +++ b/util/recover.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 recover.c $NHDT-Date: 1687547437 2023/06/23 19:10:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.33 $ */ +/* NetHack 5.0 recover.c $NHDT-Date: 1687547437 2023/06/23 19:10:37 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.33 $ */ /* Copyright (c) Janet Walz, 1992. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/Qt/qt_post.h b/win/Qt/qt_post.h index 6c783cf00..a73f9f3a3 100644 --- a/win/Qt/qt_post.h +++ b/win/Qt/qt_post.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 qt_post.h $NHDT-Date: 1597276832 2020/08/13 00:00:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 qt_post.h $NHDT-Date: 1781973096 2026/06/20 16:31:36 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ */ /* * qt_post.h -- reverse part of qt_pre.h. diff --git a/win/Qt/qt_pre.h b/win/Qt/qt_pre.h index 1dddde25b..dc5cdfbdf 100644 --- a/win/Qt/qt_pre.h +++ b/win/Qt/qt_pre.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 qt_pre.h $NHDT-Date: 1597276835 2020/08/13 00:00:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 qt_pre.h $NHDT-Date: 1781973096 2026/06/20 16:31:36 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /* * qt_pre.h -- undefine some nethack macros which conflict with Qt headers. diff --git a/win/X11/Window.c b/win/X11/Window.c index 645193a77..d9b4f3edb 100644 --- a/win/X11/Window.c +++ b/win/X11/Window.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 Window.c $NHDT-Date: 1596498371 2020/08/03 23:46:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 Window.c $NHDT-Date: 1781973108 2026/06/20 16:31:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.17 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/winX.c b/win/X11/winX.c index f4725399b..59cbb933e 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 winX.c $NHDT-Date: 1717967337 2024/06/09 21:08:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.136 $ */ +/* NetHack 5.0 winX.c $NHDT-Date: 1781973110 2026/06/20 16:31:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.150 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/winmap.c b/win/X11/winmap.c index 97e17eaee..1ee30626e 100644 --- a/win/X11/winmap.c +++ b/win/X11/winmap.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 winmap.c $NHDT-Date: 1682206649 2023/04/22 23:37:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.59 $ */ +/* NetHack 5.0 winmap.c $NHDT-Date: 1781973109 2026/06/20 16:31:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.77 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index 85deaf56f..1c6885648 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 winmenu.c $NHDT-Date: 1644531504 2022/02/10 22:18:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.50 $ */ +/* NetHack 5.0 winmenu.c $NHDT-Date: 1781973109 2026/06/20 16:31:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.64 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/winmesg.c b/win/X11/winmesg.c index 107c37d58..1e3539c8d 100644 --- a/win/X11/winmesg.c +++ b/win/X11/winmesg.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 winmesg.c $NHDT-Date: 1596498373 2020/08/03 23:46:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 winmesg.c $NHDT-Date: 1781973109 2026/06/20 16:31:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.19 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/winmisc.c b/win/X11/winmisc.c index 4baae3f49..af1f64d4a 100644 --- a/win/X11/winmisc.c +++ b/win/X11/winmisc.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 winmisc.c $NHDT-Date: 1596498374 2020/08/03 23:46:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.49 $ */ +/* NetHack 5.0 winmisc.c $NHDT-Date: 1781973109 2026/06/20 16:31:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.68 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 0e6f79f94..1028ec2ad 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 winstat.c $NHDT-Date: 1649269127 2022/04/06 18:18:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.37 $ */ +/* NetHack 5.0 winstat.c $NHDT-Date: 1781973110 2026/06/20 16:31:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.50 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/wintext.c b/win/X11/wintext.c index cf2a1d7eb..9c7b98a2b 100644 --- a/win/X11/wintext.c +++ b/win/X11/wintext.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 wintext.c $NHDT-Date: 1597967808 2020/08/20 23:56:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.22 $ */ +/* NetHack 5.0 wintext.c $NHDT-Date: 1781973110 2026/06/20 16:31:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.35 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/winval.c b/win/X11/winval.c index 62e3b9937..9abd40f72 100644 --- a/win/X11/winval.c +++ b/win/X11/winval.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 winval.c $NHDT-Date: 1611697183 2021/01/26 21:39:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 winval.c $NHDT-Date: 1781973110 2026/06/20 16:31:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.16 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/chain/wc_chainin.c b/win/chain/wc_chainin.c index 4e05d3933..7b83ffd17 100644 --- a/win/chain/wc_chainin.c +++ b/win/chain/wc_chainin.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 wc_chainin.c $NHDT-Date: 1596498323 2020/08/03 23:45:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 wc_chainin.c $NHDT-Date: 1781973093 2026/06/20 16:31:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.28 $ */ /* Copyright (c) Kenneth Lorber, 2012 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/chain/wc_chainout.c b/win/chain/wc_chainout.c index a330e0efb..a1d4d511c 100644 --- a/win/chain/wc_chainout.c +++ b/win/chain/wc_chainout.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 wc_chainout.c $NHDT-Date: 1596498324 2020/08/03 23:45:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 wc_chainout.c $NHDT-Date: 1781973094 2026/06/20 16:31:34 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.29 $ */ /* Copyright (c) Kenneth Lorber, 2012 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/chain/wc_trace.c b/win/chain/wc_trace.c index 936bcf26f..fffbc3961 100644 --- a/win/chain/wc_trace.c +++ b/win/chain/wc_trace.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 wc_trace.c $NHDT-Date: 1596498324 2020/08/03 23:45:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 wc_trace.c $NHDT-Date: 1781973094 2026/06/20 16:31:34 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.29 $ */ /* Copyright (c) Kenneth Lorber, 2012 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/share/bmptiles.c b/win/share/bmptiles.c index 5c6bd09c8..a82ea651a 100644 --- a/win/share/bmptiles.c +++ b/win/share/bmptiles.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 bmptiles.c $NHDT-Date: 1596498334 2020/08/03 23:45:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ */ +/* NetHack 5.0 bmptiles.c $NHDT-Date: 1781973097 2026/06/20 16:31:37 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ */ /* Copyright (c) Ray Chason, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/share/giftiles.c b/win/share/giftiles.c index 1fdf1a0bc..cb026cc05 100644 --- a/win/share/giftiles.c +++ b/win/share/giftiles.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 giftiles.c $NHDT-Date: 1596498335 2020/08/03 23:45:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ */ +/* NetHack 5.0 giftiles.c $NHDT-Date: 1781973097 2026/06/20 16:31:37 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ */ /* Copyright (c) Ray Chason, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/share/ppmwrite.c b/win/share/ppmwrite.c index b9f5848e3..44d181f7e 100644 --- a/win/share/ppmwrite.c +++ b/win/share/ppmwrite.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 ppmwrite.c $NHDT-Date: 1596498336 2020/08/03 23:45:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ */ +/* NetHack 5.0 ppmwrite.c $NHDT-Date: 1781973098 2026/06/20 16:31:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /* this produces a raw ppm file, with a 15-character header of * "P6 3-digit-width 3-digit-height 255\n" */ diff --git a/win/share/thintile.c b/win/share/thintile.c index b975c37cf..f9d85aaea 100644 --- a/win/share/thintile.c +++ b/win/share/thintile.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 thintile.c $NHDT-Date: 1596498337 2020/08/03 23:45:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 thintile.c $NHDT-Date: 1781973098 2026/06/20 16:31:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) NetHack Development Team 1995 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/share/tile.h b/win/share/tile.h index fcb01ece0..c348a72dc 100644 --- a/win/share/tile.h +++ b/win/share/tile.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 tile.h $NHDT-Date: 1596498339 2020/08/03 23:45:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 tile.h $NHDT-Date: 1781973098 2026/06/20 16:31:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.17 $ */ /* Copyright (c) 2016 by Michael Allison */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/share/tile2bmp.c b/win/share/tile2bmp.c index e875763f9..f25950c84 100644 --- a/win/share/tile2bmp.c +++ b/win/share/tile2bmp.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 tile2bmp.c $NHDT-Date: 1737281026 2025/01/19 02:03:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.51 $ */ +/* NetHack 5.0 tile2bmp.c $NHDT-Date: 1781973098 2026/06/20 16:31:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.53 $ */ /* Copyright (c) NetHack PC Development Team 1995 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/share/tilemap.c b/win/share/tilemap.c index 90bb6b85a..11b067471 100644 --- a/win/share/tilemap.c +++ b/win/share/tilemap.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 tilemap.c $NHDT-Date: 1737720923 2025/01/24 04:15:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.87 $ */ +/* NetHack 5.0 tilemap.c $NHDT-Date: 1781973099 2026/06/20 16:31:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.93 $ */ /* Copyright (c) 2016 by Michael Allison */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/share/tileset.c b/win/share/tileset.c index 6a1280fb4..2fff3affa 100644 --- a/win/share/tileset.c +++ b/win/share/tileset.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 tileset.c $NHDT-Date: 1596498341 2020/08/03 23:45:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ */ +/* NetHack 5.0 tileset.c $NHDT-Date: 1781973099 2026/06/20 16:31:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ */ /* Copyright (c) Ray Chason, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/share/tiletext.c b/win/share/tiletext.c index 80f630f94..09cab5935 100644 --- a/win/share/tiletext.c +++ b/win/share/tiletext.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 tiletext.c $NHDT-Date: 1596498342 2020/08/03 23:45:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.17 $ */ +/* NetHack 5.0 tiletext.c $NHDT-Date: 1781973099 2026/06/20 16:31:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.31 $ */ /* Copyright (c) 2016 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/shim/winshim.c b/win/shim/winshim.c index a18534d35..6ec7c0266 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 winshim.c $NHDT-Date: 1596498345 2020/08/03 23:45:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.259 $ */ +/* NetHack 5.0 winshim.c $NHDT-Date: 1781973099 2026/06/20 16:31:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.34 $ */ /* Copyright (c) Adam Powers, 2020 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/tty/getline.c b/win/tty/getline.c index 8dbd43f67..459491864 100644 --- a/win/tty/getline.c +++ b/win/tty/getline.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 getline.c $NHDT-Date: 1701285885 2023/11/29 19:24:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.59 $ */ +/* NetHack 5.0 getline.c $NHDT-Date: 1781973100 2026/06/20 16:31:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.71 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/tty/termcap.c b/win/tty/termcap.c index a44e84ca5..037f1bf0f 100644 --- a/win/tty/termcap.c +++ b/win/tty/termcap.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 termcap.c $NHDT-Date: 1701946349 2023/12/07 10:52:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.60 $ */ +/* NetHack 5.0 termcap.c $NHDT-Date: 1781973100 2026/06/20 16:31:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.81 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/tty/topl.c b/win/tty/topl.c index b9f9936a8..e3b154c86 100644 --- a/win/tty/topl.c +++ b/win/tty/topl.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 topl.c $NHDT-Date: 1717967339 2024/06/09 21:08:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.89 $ */ +/* NetHack 5.0 topl.c $NHDT-Date: 1781973100 2026/06/20 16:31:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.94 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/tty/wintty.c b/win/tty/wintty.c index a018d3bc0..c4aa816bd 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 wintty.c $NHDT-Date: 1737691300 2025/01/23 20:01:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.420 $ */ +/* NetHack 5.0 wintty.c $NHDT-Date: 1781973100 2026/06/20 16:31:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.438 $ */ /* Copyright (c) David Cohrs, 1991 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhaskyn.c b/win/win32/mhaskyn.c index 9ed889b9a..d958f3ff8 100644 --- a/win/win32/mhaskyn.c +++ b/win/win32/mhaskyn.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhaskyn.c $NHDT-Date: 1596498346 2020/08/03 23:45:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 mhaskyn.c $NHDT-Date: 1781973101 2026/06/20 16:31:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhaskyn.h b/win/win32/mhaskyn.h index d81a33698..9790fc3bd 100644 --- a/win/win32/mhaskyn.h +++ b/win/win32/mhaskyn.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhaskyn.h $NHDT-Date: 1596498347 2020/08/03 23:45:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 mhaskyn.h $NHDT-Date: 1781973101 2026/06/20 16:31:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhdlg.c b/win/win32/mhdlg.c index 0d48f2531..4650a25a5 100644 --- a/win/win32/mhdlg.c +++ b/win/win32/mhdlg.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhdlg.c $NHDT-Date: 1596498347 2020/08/03 23:45:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.36 $ */ +/* NetHack 5.0 mhdlg.c $NHDT-Date: 1781973101 2026/06/20 16:31:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.48 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhdlg.h b/win/win32/mhdlg.h index 9c3414da4..a83d0680f 100644 --- a/win/win32/mhdlg.h +++ b/win/win32/mhdlg.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhdlg.h $NHDT-Date: 1596498348 2020/08/03 23:45:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 mhdlg.h $NHDT-Date: 1781973102 2026/06/20 16:31:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.15 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhfont.c b/win/win32/mhfont.c index 5b39bcbf0..9230accde 100644 --- a/win/win32/mhfont.c +++ b/win/win32/mhfont.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhfont.c $NHDT-Date: 1596498349 2020/08/03 23:45:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.29 $ */ +/* NetHack 5.0 mhfont.c $NHDT-Date: 1781973102 2026/06/20 16:31:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.34 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhfont.h b/win/win32/mhfont.h index c4f10826f..53a5f4337 100644 --- a/win/win32/mhfont.h +++ b/win/win32/mhfont.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhfont.h $NHDT-Date: 1596498350 2020/08/03 23:45:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.17 $ */ +/* NetHack 5.0 mhfont.h $NHDT-Date: 1781973102 2026/06/20 16:31:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.19 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhinput.c b/win/win32/mhinput.c index 7f209ea20..64a3bc213 100644 --- a/win/win32/mhinput.c +++ b/win/win32/mhinput.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhinput.c $NHDT-Date: 1596498350 2020/08/03 23:45:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 mhinput.c $NHDT-Date: 1781973102 2026/06/20 16:31:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.21 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhinput.h b/win/win32/mhinput.h index 20c7af695..4ab0d4f9a 100644 --- a/win/win32/mhinput.h +++ b/win/win32/mhinput.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhinput.h $NHDT-Date: 1596498351 2020/08/03 23:45:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 mhinput.h $NHDT-Date: 1781973102 2026/06/20 16:31:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmain.c b/win/win32/mhmain.c index d543def7b..83ce94b4d 100644 --- a/win/win32/mhmain.c +++ b/win/win32/mhmain.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhmain.c $NHDT-Date: 1596498352 2020/08/03 23:45:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.76 $ */ +/* NetHack 5.0 mhmain.c $NHDT-Date: 1781973103 2026/06/20 16:31:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.101 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmain.h b/win/win32/mhmain.h index 89c0724b3..a50fac0bb 100644 --- a/win/win32/mhmain.h +++ b/win/win32/mhmain.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhmain.h $NHDT-Date: 1596498352 2020/08/03 23:45:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 mhmain.h $NHDT-Date: 1781973103 2026/06/20 16:31:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.18 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmap.c b/win/win32/mhmap.c index a24e99f0e..390185674 100644 --- a/win/win32/mhmap.c +++ b/win/win32/mhmap.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhmap.c $NHDT-Date: 1596498353 2020/08/03 23:45:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.85 $ */ +/* NetHack 5.0 mhmap.c $NHDT-Date: 1781973103 2026/06/20 16:31:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.115 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmap.h b/win/win32/mhmap.h index a66041fd1..4ca2fadf9 100644 --- a/win/win32/mhmap.h +++ b/win/win32/mhmap.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhmap.h $NHDT-Date: 1596498354 2020/08/03 23:45:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.17 $ */ +/* NetHack 5.0 mhmap.h $NHDT-Date: 1781973103 2026/06/20 16:31:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.20 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmenu.c b/win/win32/mhmenu.c index 3f9b7dfe8..908284e16 100644 --- a/win/win32/mhmenu.c +++ b/win/win32/mhmenu.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhmenu.c $NHDT-Date: 1596498354 2020/08/03 23:45:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.74 $ */ +/* NetHack 5.0 mhmenu.c $NHDT-Date: 1781973104 2026/06/20 16:31:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.96 $ */ /* Copyright (c) Alex Kompel, 2002 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmenu.h b/win/win32/mhmenu.h index a2ca7a8c4..c12aa87d2 100644 --- a/win/win32/mhmenu.h +++ b/win/win32/mhmenu.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhmenu.h $NHDT-Date: 1596498355 2020/08/03 23:45:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 mhmenu.h $NHDT-Date: 1781973104 2026/06/20 16:31:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmsg.h b/win/win32/mhmsg.h index 2f7eff193..a80630143 100644 --- a/win/win32/mhmsg.h +++ b/win/win32/mhmsg.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhmsg.h $NHDT-Date: 1596498356 2020/08/03 23:45:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ +/* NetHack 5.0 mhmsg.h $NHDT-Date: 1781973104 2026/06/20 16:31:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.31 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmsgwnd.c b/win/win32/mhmsgwnd.c index 8dc795fba..c5ee2841f 100644 --- a/win/win32/mhmsgwnd.c +++ b/win/win32/mhmsgwnd.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhmsgwnd.c $NHDT-Date: 1596498357 2020/08/03 23:45:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ */ +/* NetHack 5.0 mhmsgwnd.c $NHDT-Date: 1781973104 2026/06/20 16:31:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.52 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmsgwnd.h b/win/win32/mhmsgwnd.h index 614e0e8a2..d9ff67ae9 100644 --- a/win/win32/mhmsgwnd.h +++ b/win/win32/mhmsgwnd.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhmsgwnd.h $NHDT-Date: 1596498358 2020/08/03 23:45:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 mhmsgwnd.h $NHDT-Date: 1781973105 2026/06/20 16:31:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhrip.c b/win/win32/mhrip.c index 45188ac31..f80736707 100644 --- a/win/win32/mhrip.c +++ b/win/win32/mhrip.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhrip.c $NHDT-Date: 1596498358 2020/08/03 23:45:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 5.0 mhrip.c $NHDT-Date: 1781973105 2026/06/20 16:31:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.35 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhrip.h b/win/win32/mhrip.h index 7435294ef..7b4bdfaa0 100644 --- a/win/win32/mhrip.h +++ b/win/win32/mhrip.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhrip.h $NHDT-Date: 1596498359 2020/08/03 23:45:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 mhrip.h $NHDT-Date: 1781973105 2026/06/20 16:31:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhsplash.c b/win/win32/mhsplash.c index da5897978..f6af47ed5 100644 --- a/win/win32/mhsplash.c +++ b/win/win32/mhsplash.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhsplash.c $NHDT-Date: 1596498360 2020/08/03 23:46:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.36 $ */ +/* NetHack 5.0 mhsplash.c $NHDT-Date: 1781973105 2026/06/20 16:31:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.45 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhstatus.c b/win/win32/mhstatus.c index d7e66505d..f4eb8578d 100644 --- a/win/win32/mhstatus.c +++ b/win/win32/mhstatus.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhstatus.c $NHDT-Date: 1596498360 2020/08/03 23:46:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.35 $ */ +/* NetHack 5.0 mhstatus.c $NHDT-Date: 1781973106 2026/06/20 16:31:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.45 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhstatus.h b/win/win32/mhstatus.h index f4b3d844e..2197a8f31 100644 --- a/win/win32/mhstatus.h +++ b/win/win32/mhstatus.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhstatus.h $NHDT-Date: 1596498361 2020/08/03 23:46:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 mhstatus.h $NHDT-Date: 1781973106 2026/06/20 16:31:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.18 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhtext.c b/win/win32/mhtext.c index 72ab526e6..e84ee3af1 100644 --- a/win/win32/mhtext.c +++ b/win/win32/mhtext.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhtext.c $NHDT-Date: 1596498362 2020/08/03 23:46:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.31 $ */ +/* NetHack 5.0 mhtext.c $NHDT-Date: 1781973106 2026/06/20 16:31:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.39 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhtext.h b/win/win32/mhtext.h index eee831041..d3c34a399 100644 --- a/win/win32/mhtext.h +++ b/win/win32/mhtext.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 mhtext.h $NHDT-Date: 1596498363 2020/08/03 23:46:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 mhtext.h $NHDT-Date: 1781973106 2026/06/20 16:31:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index de996828d..09c8cb4ad 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 mswproc.c $NHDT-Date: 1717967341 2024/06/09 21:09:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.193 $ */ +/* NetHack 5.0 mswproc.c $NHDT-Date: 1781973107 2026/06/20 16:31:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.208 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/winMS.h b/win/win32/winMS.h index 2d4deb058..080cdb10a 100644 --- a/win/win32/winMS.h +++ b/win/win32/winMS.h @@ -1,4 +1,4 @@ -/* NetHack 5.0 winMS.h $NHDT-Date: 1596498367 2020/08/03 23:46:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.53 $ */ +/* NetHack 5.0 winMS.h $NHDT-Date: 1781973108 2026/06/20 16:31:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.71 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ From 6399e0070b132ac9786924465e74e099c4e3c8c5 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 20 Jun 2026 18:35:38 -0400 Subject: [PATCH 496/702] dat/*.lua 3.7 vestiges --- dat/Arc-fila.lua | 2 +- dat/Arc-filb.lua | 2 +- dat/Arc-goal.lua | 2 +- dat/Arc-loca.lua | 2 +- dat/Arc-strt.lua | 2 +- dat/Bar-fila.lua | 2 +- dat/Bar-filb.lua | 2 +- dat/Bar-goal.lua | 2 +- dat/Bar-loca.lua | 2 +- dat/Bar-strt.lua | 2 +- dat/Cav-fila.lua | 2 +- dat/Cav-filb.lua | 2 +- dat/Cav-goal.lua | 2 +- dat/Cav-loca.lua | 2 +- dat/Cav-strt.lua | 2 +- dat/Hea-fila.lua | 2 +- dat/Hea-filb.lua | 2 +- dat/Hea-goal.lua | 2 +- dat/Hea-loca.lua | 2 +- dat/Hea-strt.lua | 2 +- dat/Kni-fila.lua | 2 +- dat/Kni-filb.lua | 2 +- dat/Kni-goal.lua | 2 +- dat/Kni-loca.lua | 2 +- dat/Kni-strt.lua | 2 +- dat/Mon-fila.lua | 2 +- dat/Mon-filb.lua | 2 +- dat/Mon-goal.lua | 2 +- dat/Mon-loca.lua | 2 +- dat/Mon-strt.lua | 2 +- dat/Pri-fila.lua | 2 +- dat/Pri-filb.lua | 2 +- dat/Pri-goal.lua | 2 +- dat/Pri-loca.lua | 2 +- dat/Pri-strt.lua | 2 +- dat/Ran-fila.lua | 2 +- dat/Ran-filb.lua | 2 +- dat/Ran-goal.lua | 2 +- dat/Ran-loca.lua | 2 +- dat/Ran-strt.lua | 2 +- dat/Rog-fila.lua | 2 +- dat/Rog-filb.lua | 2 +- dat/Rog-goal.lua | 2 +- dat/Rog-loca.lua | 2 +- dat/Rog-strt.lua | 2 +- dat/Sam-fila.lua | 2 +- dat/Sam-filb.lua | 2 +- dat/Sam-goal.lua | 2 +- dat/Sam-loca.lua | 2 +- dat/Sam-strt.lua | 2 +- dat/Tou-fila.lua | 2 +- dat/Tou-filb.lua | 2 +- dat/Tou-goal.lua | 2 +- dat/Tou-loca.lua | 2 +- dat/Tou-strt.lua | 2 +- dat/Val-fila.lua | 2 +- dat/Val-filb.lua | 2 +- dat/Val-goal.lua | 2 +- dat/Val-loca.lua | 2 +- dat/Val-strt.lua | 2 +- dat/Wiz-fila.lua | 2 +- dat/Wiz-filb.lua | 2 +- dat/Wiz-goal.lua | 2 +- dat/Wiz-loca.lua | 2 +- dat/Wiz-strt.lua | 2 +- dat/air.lua | 2 +- dat/asmodeus.lua | 2 +- dat/astral.lua | 2 +- dat/baalz.lua | 2 +- dat/bigrm-1.lua | 2 +- dat/bigrm-10.lua | 2 +- dat/bigrm-11.lua | 2 +- dat/bigrm-12.lua | 2 +- dat/bigrm-13.lua | 2 +- dat/bigrm-2.lua | 2 +- dat/bigrm-3.lua | 2 +- dat/bigrm-4.lua | 2 +- dat/bigrm-5.lua | 2 +- dat/bigrm-6.lua | 2 +- dat/bigrm-7.lua | 2 +- dat/bigrm-8.lua | 2 +- dat/bigrm-9.lua | 2 +- dat/castle.lua | 2 +- dat/dungeon.lua | 2 +- dat/earth.lua | 2 +- dat/fakewiz1.lua | 2 +- dat/fakewiz2.lua | 2 +- dat/fire.lua | 2 +- dat/juiblex.lua | 2 +- dat/knox.lua | 2 +- dat/medusa-1.lua | 2 +- dat/medusa-2.lua | 2 +- dat/medusa-3.lua | 2 +- dat/medusa-4.lua | 2 +- dat/minefill.lua | 2 +- dat/minend-1.lua | 2 +- dat/minend-2.lua | 2 +- dat/minend-3.lua | 2 +- dat/minetn-1.lua | 2 +- dat/minetn-2.lua | 2 +- dat/minetn-3.lua | 2 +- dat/minetn-4.lua | 2 +- dat/minetn-5.lua | 2 +- dat/minetn-6.lua | 2 +- dat/minetn-7.lua | 2 +- dat/nhcore.lua | 2 +- dat/nhlib.lua | 2 +- dat/oracle.lua | 2 +- dat/orcus.lua | 2 +- dat/quest.lua | 2 +- dat/sanctum.lua | 2 +- dat/soko1-1.lua | 2 +- dat/soko1-2.lua | 2 +- dat/soko2-1.lua | 2 +- dat/soko2-2.lua | 2 +- dat/soko3-1.lua | 2 +- dat/soko3-2.lua | 2 +- dat/soko4-1.lua | 2 +- dat/soko4-2.lua | 2 +- dat/themerms.lua | 2 +- dat/tower1.lua | 2 +- dat/tower2.lua | 2 +- dat/tower3.lua | 2 +- dat/valley.lua | 2 +- dat/water.lua | 2 +- dat/wizard1.lua | 2 +- dat/wizard2.lua | 2 +- dat/wizard3.lua | 2 +- 128 files changed, 128 insertions(+), 128 deletions(-) diff --git a/dat/Arc-fila.lua b/dat/Arc-fila.lua index 1a869dd0f..94c94c624 100644 --- a/dat/Arc-fila.lua +++ b/dat/Arc-fila.lua @@ -1,4 +1,4 @@ --- NetHack Archeologist Arc-fila.lua $NHDT-Date: 1652195998 2022/05/10 15:19:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Archeologist Arc-fila.lua $NHDT-Date: 1781994863 2026/06/20 22:34:23 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Arc-filb.lua b/dat/Arc-filb.lua index a5334874b..37df5acc1 100644 --- a/dat/Arc-filb.lua +++ b/dat/Arc-filb.lua @@ -1,4 +1,4 @@ --- NetHack Archeologist Arc-filb.lua $NHDT-Date: 1652195998 2022/05/10 15:19:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Archeologist Arc-filb.lua $NHDT-Date: 1781994863 2026/06/20 22:34:23 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Arc-goal.lua b/dat/Arc-goal.lua index 0561d1a85..4fadb5b15 100644 --- a/dat/Arc-goal.lua +++ b/dat/Arc-goal.lua @@ -1,4 +1,4 @@ --- NetHack Archeologist Arc-goal.lua $NHDT-Date: 1652195998 2022/05/10 15:19:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Archeologist Arc-goal.lua $NHDT-Date: 1781994864 2026/06/20 22:34:24 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Arc-loca.lua b/dat/Arc-loca.lua index ec08e9849..f436c2d46 100644 --- a/dat/Arc-loca.lua +++ b/dat/Arc-loca.lua @@ -1,4 +1,4 @@ --- NetHack Archeologist Arc-loca.lua $NHDT-Date: 1652195999 2022/05/10 15:19:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Archeologist Arc-loca.lua $NHDT-Date: 1781994864 2026/06/20 22:34:24 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Arc-strt.lua b/dat/Arc-strt.lua index cad40375b..b36c5d707 100644 --- a/dat/Arc-strt.lua +++ b/dat/Arc-strt.lua @@ -1,4 +1,4 @@ --- NetHack Archeologist Arc-strt.lua $NHDT-Date: 1652195999 2022/05/10 15:19:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Archeologist Arc-strt.lua $NHDT-Date: 1781994864 2026/06/20 22:34:24 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Bar-fila.lua b/dat/Bar-fila.lua index 64ea97e54..9488b43a1 100644 --- a/dat/Bar-fila.lua +++ b/dat/Bar-fila.lua @@ -1,4 +1,4 @@ --- NetHack Barbarian Bar-fila.lua $NHDT-Date: 1652195999 2022/05/10 15:19:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Barbarian Bar-fila.lua $NHDT-Date: 1781994864 2026/06/20 22:34:24 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Bar-filb.lua b/dat/Bar-filb.lua index 9764c3128..8af6ea40c 100644 --- a/dat/Bar-filb.lua +++ b/dat/Bar-filb.lua @@ -1,4 +1,4 @@ --- NetHack Barbarian Bar-filb.lua $NHDT-Date: 1652196000 2022/05/10 15:20:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Barbarian Bar-filb.lua $NHDT-Date: 1781994864 2026/06/20 22:34:24 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Bar-goal.lua b/dat/Bar-goal.lua index 760f36ad9..e065156ff 100644 --- a/dat/Bar-goal.lua +++ b/dat/Bar-goal.lua @@ -1,4 +1,4 @@ --- NetHack Barbarian Bar-goal.lua $NHDT-Date: 1652196000 2022/05/10 15:20:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Barbarian Bar-goal.lua $NHDT-Date: 1781994865 2026/06/20 22:34:25 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Bar-loca.lua b/dat/Bar-loca.lua index a11a896e5..04d95ba10 100644 --- a/dat/Bar-loca.lua +++ b/dat/Bar-loca.lua @@ -1,4 +1,4 @@ --- NetHack Barbarian Bar-loca.lua $NHDT-Date: 1652196000 2022/05/10 15:20:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Barbarian Bar-loca.lua $NHDT-Date: 1781994865 2026/06/20 22:34:25 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Bar-strt.lua b/dat/Bar-strt.lua index 28cacf028..e165cd34f 100644 --- a/dat/Bar-strt.lua +++ b/dat/Bar-strt.lua @@ -1,4 +1,4 @@ --- NetHack Barbarian Bar-strt.lua $NHDT-Date: 1652196001 2022/05/10 15:20:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack Barbarian Bar-strt.lua $NHDT-Date: 1781994865 2026/06/20 22:34:25 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Cav-fila.lua b/dat/Cav-fila.lua index d1b0b2000..a914d937c 100644 --- a/dat/Cav-fila.lua +++ b/dat/Cav-fila.lua @@ -1,4 +1,4 @@ --- NetHack Caveman Cav-fila.lua $NHDT-Date: 1652196001 2022/05/10 15:20:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Caveman Cav-fila.lua $NHDT-Date: 1781994865 2026/06/20 22:34:25 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Cav-filb.lua b/dat/Cav-filb.lua index a18fed77c..991740221 100644 --- a/dat/Cav-filb.lua +++ b/dat/Cav-filb.lua @@ -1,4 +1,4 @@ --- NetHack Caveman Cav-filb.lua $NHDT-Date: 1652196001 2022/05/10 15:20:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Caveman Cav-filb.lua $NHDT-Date: 1781994866 2026/06/20 22:34:26 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Cav-goal.lua b/dat/Cav-goal.lua index 871579f9d..134fa6c78 100644 --- a/dat/Cav-goal.lua +++ b/dat/Cav-goal.lua @@ -1,4 +1,4 @@ --- NetHack Caveman Cav-goal.lua $NHDT-Date: 1652196002 2022/05/10 15:20:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Caveman Cav-goal.lua $NHDT-Date: 1781994866 2026/06/20 22:34:26 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Cav-loca.lua b/dat/Cav-loca.lua index d779d601a..3089663f1 100644 --- a/dat/Cav-loca.lua +++ b/dat/Cav-loca.lua @@ -1,4 +1,4 @@ --- NetHack Caveman Cav-loca.lua $NHDT-Date: 1652196002 2022/05/10 15:20:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Caveman Cav-loca.lua $NHDT-Date: 1781994866 2026/06/20 22:34:26 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Cav-strt.lua b/dat/Cav-strt.lua index 224ed7455..ba3cb5685 100644 --- a/dat/Cav-strt.lua +++ b/dat/Cav-strt.lua @@ -1,4 +1,4 @@ --- NetHack Caveman Cav-strt.lua $NHDT-Date: 1652196002 2022/05/10 15:20:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack Caveman Cav-strt.lua $NHDT-Date: 1781994866 2026/06/20 22:34:26 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Hea-fila.lua b/dat/Hea-fila.lua index 7fa038ddc..8dd58756f 100644 --- a/dat/Hea-fila.lua +++ b/dat/Hea-fila.lua @@ -1,4 +1,4 @@ --- NetHack Healer Hea-fila.lua $NHDT-Date: 1652196003 2022/05/10 15:20:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Healer Hea-fila.lua $NHDT-Date: 1781994866 2026/06/20 22:34:26 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991, 1993 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Hea-filb.lua b/dat/Hea-filb.lua index 778402363..55cb12cb4 100644 --- a/dat/Hea-filb.lua +++ b/dat/Hea-filb.lua @@ -1,4 +1,4 @@ --- NetHack Healer Hea-filb.lua $NHDT-Date: 1652196003 2022/05/10 15:20:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Healer Hea-filb.lua $NHDT-Date: 1781994867 2026/06/20 22:34:27 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991, 1993 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Hea-goal.lua b/dat/Hea-goal.lua index 0499a1248..f2183efeb 100644 --- a/dat/Hea-goal.lua +++ b/dat/Hea-goal.lua @@ -1,4 +1,4 @@ --- NetHack Healer Hea-goal.lua $NHDT-Date: 1652196003 2022/05/10 15:20:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Healer Hea-goal.lua $NHDT-Date: 1781994867 2026/06/20 22:34:27 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991, 1993 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Hea-loca.lua b/dat/Hea-loca.lua index a05020f17..950ae0f0a 100644 --- a/dat/Hea-loca.lua +++ b/dat/Hea-loca.lua @@ -1,4 +1,4 @@ --- NetHack Healer Hea-loca.lua $NHDT-Date: 1652196004 2022/05/10 15:20:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Healer Hea-loca.lua $NHDT-Date: 1781994867 2026/06/20 22:34:27 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991, 1993 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Hea-strt.lua b/dat/Hea-strt.lua index 9e9e35247..fc2f11248 100644 --- a/dat/Hea-strt.lua +++ b/dat/Hea-strt.lua @@ -1,4 +1,4 @@ --- NetHack Healer Hea-strt.lua $NHDT-Date: 1652196004 2022/05/10 15:20:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Healer Hea-strt.lua $NHDT-Date: 1781994867 2026/06/20 22:34:27 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991, 1993 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Kni-fila.lua b/dat/Kni-fila.lua index 362d0674b..d24ef18a4 100644 --- a/dat/Kni-fila.lua +++ b/dat/Kni-fila.lua @@ -1,4 +1,4 @@ --- NetHack Knight Kni-fila.lua $NHDT-Date: 1652196004 2022/05/10 15:20:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Knight Kni-fila.lua $NHDT-Date: 1781994867 2026/06/20 22:34:27 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Kni-filb.lua b/dat/Kni-filb.lua index 14a414f4e..4d6c7279a 100644 --- a/dat/Kni-filb.lua +++ b/dat/Kni-filb.lua @@ -1,4 +1,4 @@ --- NetHack Knight Kni-filb.lua $NHDT-Date: 1652196005 2022/05/10 15:20:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Knight Kni-filb.lua $NHDT-Date: 1781994868 2026/06/20 22:34:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Kni-goal.lua b/dat/Kni-goal.lua index 08a8dff78..fe42e601d 100644 --- a/dat/Kni-goal.lua +++ b/dat/Kni-goal.lua @@ -1,4 +1,4 @@ --- NetHack Knight Kni-goal.lua $NHDT-Date: 1652196005 2022/05/10 15:20:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Knight Kni-goal.lua $NHDT-Date: 1781994868 2026/06/20 22:34:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Kni-loca.lua b/dat/Kni-loca.lua index 91d557a70..cd11949c6 100644 --- a/dat/Kni-loca.lua +++ b/dat/Kni-loca.lua @@ -1,4 +1,4 @@ --- NetHack Knight Kni-loca.lua $NHDT-Date: 1652196005 2022/05/10 15:20:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Knight Kni-loca.lua $NHDT-Date: 1781994868 2026/06/20 22:34:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Kni-strt.lua b/dat/Kni-strt.lua index 9873fb42e..ba199bd01 100644 --- a/dat/Kni-strt.lua +++ b/dat/Kni-strt.lua @@ -1,4 +1,4 @@ --- NetHack Knight Kni-strt.lua $NHDT-Date: 1652196006 2022/05/10 15:20:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack Knight Kni-strt.lua $NHDT-Date: 1781994868 2026/06/20 22:34:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Mon-fila.lua b/dat/Mon-fila.lua index c62801a83..ba0f2c8d7 100644 --- a/dat/Mon-fila.lua +++ b/dat/Mon-fila.lua @@ -1,4 +1,4 @@ --- NetHack Monk Mon-fila.lua $NHDT-Date: 1652196006 2022/05/10 15:20:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Monk Mon-fila.lua $NHDT-Date: 1781994868 2026/06/20 22:34:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Mon-filb.lua b/dat/Mon-filb.lua index 98e98f12d..aff195eb3 100644 --- a/dat/Mon-filb.lua +++ b/dat/Mon-filb.lua @@ -1,4 +1,4 @@ --- NetHack Monk Mon-filb.lua $NHDT-Date: 1652196006 2022/05/10 15:20:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Monk Mon-filb.lua $NHDT-Date: 1781994869 2026/06/20 22:34:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Mon-goal.lua b/dat/Mon-goal.lua index c19bfef54..e2ca412e0 100644 --- a/dat/Mon-goal.lua +++ b/dat/Mon-goal.lua @@ -1,4 +1,4 @@ --- NetHack Monk Mon-goal.lua $NHDT-Date: 1652196007 2022/05/10 15:20:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Monk Mon-goal.lua $NHDT-Date: 1781994869 2026/06/20 22:34:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Mon-loca.lua b/dat/Mon-loca.lua index 598b364eb..67b971412 100644 --- a/dat/Mon-loca.lua +++ b/dat/Mon-loca.lua @@ -1,4 +1,4 @@ --- NetHack Monk Mon-loca.lua $NHDT-Date: 1652196007 2022/05/10 15:20:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Monk Mon-loca.lua $NHDT-Date: 1781994869 2026/06/20 22:34:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Mon-strt.lua b/dat/Mon-strt.lua index 0396c56f7..d027fa4de 100644 --- a/dat/Mon-strt.lua +++ b/dat/Mon-strt.lua @@ -1,4 +1,4 @@ --- NetHack Monk Mon-strt.lua $NHDT-Date: 1652196007 2022/05/10 15:20:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack Monk Mon-strt.lua $NHDT-Date: 1781994869 2026/06/20 22:34:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.9 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Pri-fila.lua b/dat/Pri-fila.lua index c65683cf1..bd2d5f117 100644 --- a/dat/Pri-fila.lua +++ b/dat/Pri-fila.lua @@ -1,4 +1,4 @@ --- NetHack Priest Pri-fila.lua $NHDT-Date: 1652196008 2022/05/10 15:20:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Priest Pri-fila.lua $NHDT-Date: 1781994870 2026/06/20 22:34:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Pri-filb.lua b/dat/Pri-filb.lua index ad0a84ec9..ce04e70c2 100644 --- a/dat/Pri-filb.lua +++ b/dat/Pri-filb.lua @@ -1,4 +1,4 @@ --- NetHack Priest Pri-filb.lua $NHDT-Date: 1652196008 2022/05/10 15:20:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Priest Pri-filb.lua $NHDT-Date: 1781994870 2026/06/20 22:34:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Pri-goal.lua b/dat/Pri-goal.lua index 1e29d9713..d9a5a3515 100644 --- a/dat/Pri-goal.lua +++ b/dat/Pri-goal.lua @@ -1,4 +1,4 @@ --- NetHack Priest Pri-goal.lua $NHDT-Date: 1687033651 2023/06/17 20:27:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Priest Pri-goal.lua $NHDT-Date: 1781994870 2026/06/20 22:34:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Pri-loca.lua b/dat/Pri-loca.lua index 6c8909721..080db9647 100644 --- a/dat/Pri-loca.lua +++ b/dat/Pri-loca.lua @@ -1,4 +1,4 @@ --- NetHack Priest Pri-loca.lua $NHDT-Date: 1652196009 2022/05/10 15:20:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack Priest Pri-loca.lua $NHDT-Date: 1781994870 2026/06/20 22:34:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Pri-strt.lua b/dat/Pri-strt.lua index 29edb6d15..cbbd8543c 100644 --- a/dat/Pri-strt.lua +++ b/dat/Pri-strt.lua @@ -1,4 +1,4 @@ --- NetHack Priest Pri-strt.lua $NHDT-Date: 1652196009 2022/05/10 15:20:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ +-- NetHack Priest Pri-strt.lua $NHDT-Date: 1781994870 2026/06/20 22:34:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Ran-fila.lua b/dat/Ran-fila.lua index c9c02cfdd..a6b2417bd 100644 --- a/dat/Ran-fila.lua +++ b/dat/Ran-fila.lua @@ -1,4 +1,4 @@ --- NetHack Ranger Ran-fila.lua $NHDT-Date: 1652196009 2022/05/10 15:20:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Ranger Ran-fila.lua $NHDT-Date: 1781994871 2026/06/20 22:34:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Ran-filb.lua b/dat/Ran-filb.lua index 48275fa95..7813cb5a5 100644 --- a/dat/Ran-filb.lua +++ b/dat/Ran-filb.lua @@ -1,4 +1,4 @@ --- NetHack Ranger Ran-filb.lua $NHDT-Date: 1652196010 2022/05/10 15:20:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Ranger Ran-filb.lua $NHDT-Date: 1781994871 2026/06/20 22:34:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Ran-goal.lua b/dat/Ran-goal.lua index a28b0c10b..8d543539b 100644 --- a/dat/Ran-goal.lua +++ b/dat/Ran-goal.lua @@ -1,4 +1,4 @@ --- NetHack Ranger Ran-goal.lua $NHDT-Date: 1652196010 2022/05/10 15:20:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Ranger Ran-goal.lua $NHDT-Date: 1781994871 2026/06/20 22:34:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Ran-loca.lua b/dat/Ran-loca.lua index 386c3e785..1c62e0193 100644 --- a/dat/Ran-loca.lua +++ b/dat/Ran-loca.lua @@ -1,4 +1,4 @@ --- NetHack Ranger Ran-loca.lua $NHDT-Date: 1652196010 2022/05/10 15:20:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Ranger Ran-loca.lua $NHDT-Date: 1781994871 2026/06/20 22:34:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Ran-strt.lua b/dat/Ran-strt.lua index 8628bcc39..7827fb130 100644 --- a/dat/Ran-strt.lua +++ b/dat/Ran-strt.lua @@ -1,4 +1,4 @@ --- NetHack Ranger Ran-strt.lua $NHDT-Date: 1652196011 2022/05/10 15:20:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Ranger Ran-strt.lua $NHDT-Date: 1781994871 2026/06/20 22:34:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Rog-fila.lua b/dat/Rog-fila.lua index 6b4a80fa2..0c31e7f69 100644 --- a/dat/Rog-fila.lua +++ b/dat/Rog-fila.lua @@ -1,4 +1,4 @@ --- NetHack Rogue Rog-fila.lua $NHDT-Date: 1652196011 2022/05/10 15:20:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Rogue Rog-fila.lua $NHDT-Date: 1781994872 2026/06/20 22:34:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1992 by Dean Luick -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/Rog-filb.lua b/dat/Rog-filb.lua index 83b5969f1..5af7735d4 100644 --- a/dat/Rog-filb.lua +++ b/dat/Rog-filb.lua @@ -1,4 +1,4 @@ --- NetHack Rogue Rog-filb.lua $NHDT-Date: 1652196011 2022/05/10 15:20:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Rogue Rog-filb.lua $NHDT-Date: 1781994872 2026/06/20 22:34:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1992 by Dean Luick -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/Rog-goal.lua b/dat/Rog-goal.lua index 4eb58f30b..23e839260 100644 --- a/dat/Rog-goal.lua +++ b/dat/Rog-goal.lua @@ -1,4 +1,4 @@ --- NetHack Rogue Rog-goal.lua $NHDT-Date: 1652196012 2022/05/10 15:20:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Rogue Rog-goal.lua $NHDT-Date: 1781994872 2026/06/20 22:34:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1992 by Dean Luick -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/Rog-loca.lua b/dat/Rog-loca.lua index 3a88e11fe..4020f33d4 100644 --- a/dat/Rog-loca.lua +++ b/dat/Rog-loca.lua @@ -1,4 +1,4 @@ --- NetHack Rogue Rog-loca.lua $NHDT-Date: 1652196012 2022/05/10 15:20:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Rogue Rog-loca.lua $NHDT-Date: 1781994872 2026/06/20 22:34:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1992 by Dean Luick -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/Rog-strt.lua b/dat/Rog-strt.lua index 1e4700d49..7c3c60dc3 100644 --- a/dat/Rog-strt.lua +++ b/dat/Rog-strt.lua @@ -1,4 +1,4 @@ --- NetHack Rogue Rog-strt.lua $NHDT-Date: 1652196012 2022/05/10 15:20:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack Rogue Rog-strt.lua $NHDT-Date: 1781994872 2026/06/20 22:34:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.7 $ -- Copyright (c) 1992 by Dean Luick -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/Sam-fila.lua b/dat/Sam-fila.lua index 53d23d5f6..c3f60e91f 100644 --- a/dat/Sam-fila.lua +++ b/dat/Sam-fila.lua @@ -1,4 +1,4 @@ --- NetHack Samurai Sam-fila.lua $NHDT-Date: 1652196013 2022/05/10 15:20:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Samurai Sam-fila.lua $NHDT-Date: 1781994873 2026/06/20 22:34:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Sam-filb.lua b/dat/Sam-filb.lua index 69e61032d..7646149ac 100644 --- a/dat/Sam-filb.lua +++ b/dat/Sam-filb.lua @@ -1,4 +1,4 @@ --- NetHack Samurai Sam-filb.lua $NHDT-Date: 1652196013 2022/05/10 15:20:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Samurai Sam-filb.lua $NHDT-Date: 1781994873 2026/06/20 22:34:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Sam-goal.lua b/dat/Sam-goal.lua index eb3f95608..e875e9e65 100644 --- a/dat/Sam-goal.lua +++ b/dat/Sam-goal.lua @@ -1,4 +1,4 @@ --- NetHack Samurai Sam-goal.lua $NHDT-Date: 1652196013 2022/05/10 15:20:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Samurai Sam-goal.lua $NHDT-Date: 1781994873 2026/06/20 22:34:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Sam-loca.lua b/dat/Sam-loca.lua index 95bf247f2..248f29ca3 100644 --- a/dat/Sam-loca.lua +++ b/dat/Sam-loca.lua @@ -1,4 +1,4 @@ --- NetHack Samurai Sam-loca.lua $NHDT-Date: 1652196014 2022/05/10 15:20:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Samurai Sam-loca.lua $NHDT-Date: 1781994873 2026/06/20 22:34:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Sam-strt.lua b/dat/Sam-strt.lua index e6cac093c..221ae4a21 100644 --- a/dat/Sam-strt.lua +++ b/dat/Sam-strt.lua @@ -1,4 +1,4 @@ --- NetHack Samurai Sam-strt.lua $NHDT-Date: 1695932714 2023/09/28 20:25:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack Samurai Sam-strt.lua $NHDT-Date: 1781994874 2026/06/20 22:34:34 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Tou-fila.lua b/dat/Tou-fila.lua index 6465b5d78..d77e3f154 100644 --- a/dat/Tou-fila.lua +++ b/dat/Tou-fila.lua @@ -1,4 +1,4 @@ --- NetHack Tourist Tou-fila.lua $NHDT-Date: 1652196014 2022/05/10 15:20:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Tourist Tou-fila.lua $NHDT-Date: 1781994874 2026/06/20 22:34:34 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Tou-filb.lua b/dat/Tou-filb.lua index 54855015c..7c4d05d3d 100644 --- a/dat/Tou-filb.lua +++ b/dat/Tou-filb.lua @@ -1,4 +1,4 @@ --- NetHack Tourist Tou-filb.lua $NHDT-Date: 1652196015 2022/05/10 15:20:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Tourist Tou-filb.lua $NHDT-Date: 1781994874 2026/06/20 22:34:34 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Tou-goal.lua b/dat/Tou-goal.lua index f0f3ca8ef..8dccaa01d 100644 --- a/dat/Tou-goal.lua +++ b/dat/Tou-goal.lua @@ -1,4 +1,4 @@ --- NetHack Tourist Tou-goal.lua $NHDT-Date: 1652196015 2022/05/10 15:20:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack Tourist Tou-goal.lua $NHDT-Date: 1781994874 2026/06/20 22:34:34 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Tou-loca.lua b/dat/Tou-loca.lua index 68885a91e..f53f15f32 100644 --- a/dat/Tou-loca.lua +++ b/dat/Tou-loca.lua @@ -1,4 +1,4 @@ --- NetHack Tourist Tou-loca.lua $NHDT-Date: 1652196015 2022/05/10 15:20:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Tourist Tou-loca.lua $NHDT-Date: 1781994874 2026/06/20 22:34:34 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Tou-strt.lua b/dat/Tou-strt.lua index 5c3a0bc32..7f7304162 100644 --- a/dat/Tou-strt.lua +++ b/dat/Tou-strt.lua @@ -1,4 +1,4 @@ --- NetHack Tourist Tou-strt.lua $NHDT-Date: 1652196016 2022/05/10 15:20:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack Tourist Tou-strt.lua $NHDT-Date: 1781994875 2026/06/20 22:34:35 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Val-fila.lua b/dat/Val-fila.lua index 8047f7957..52f7b138c 100644 --- a/dat/Val-fila.lua +++ b/dat/Val-fila.lua @@ -1,4 +1,4 @@ --- NetHack Valkyrie Val-fila.lua $NHDT-Date: 1652196016 2022/05/10 15:20:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Valkyrie Val-fila.lua $NHDT-Date: 1781994875 2026/06/20 22:34:35 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Val-filb.lua b/dat/Val-filb.lua index ede6f1e52..321b5ad6c 100644 --- a/dat/Val-filb.lua +++ b/dat/Val-filb.lua @@ -1,4 +1,4 @@ --- NetHack Valkyrie Val-filb.lua $NHDT-Date: 1652196016 2022/05/10 15:20:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Valkyrie Val-filb.lua $NHDT-Date: 1781994875 2026/06/20 22:34:35 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Val-goal.lua b/dat/Val-goal.lua index 43179a390..9dacbe095 100644 --- a/dat/Val-goal.lua +++ b/dat/Val-goal.lua @@ -1,4 +1,4 @@ --- NetHack Valkyrie Val-goal.lua $NHDT-Date: 1652196017 2022/05/10 15:20:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ +-- NetHack Valkyrie Val-goal.lua $NHDT-Date: 1781994875 2026/06/20 22:34:35 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Val-loca.lua b/dat/Val-loca.lua index a2875839a..44ff6bd38 100644 --- a/dat/Val-loca.lua +++ b/dat/Val-loca.lua @@ -1,4 +1,4 @@ --- NetHack Valkyrie Val-loca.lua $NHDT-Date: 1652196017 2022/05/10 15:20:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Valkyrie Val-loca.lua $NHDT-Date: 1781994875 2026/06/20 22:34:35 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Val-strt.lua b/dat/Val-strt.lua index 906500fcf..3e0b0f43e 100644 --- a/dat/Val-strt.lua +++ b/dat/Val-strt.lua @@ -1,4 +1,4 @@ --- NetHack Valkyrie Val-strt.lua $NHDT-Date: 1652196017 2022/05/10 15:20:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Valkyrie Val-strt.lua $NHDT-Date: 1781994876 2026/06/20 22:34:36 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Wiz-fila.lua b/dat/Wiz-fila.lua index 401067e74..9371a77f4 100644 --- a/dat/Wiz-fila.lua +++ b/dat/Wiz-fila.lua @@ -1,4 +1,4 @@ --- NetHack Wizard Wiz-fila.lua $NHDT-Date: 1652196018 2022/05/10 15:20:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Wizard Wiz-fila.lua $NHDT-Date: 1781994876 2026/06/20 22:34:36 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1992 by David Cohrs -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/Wiz-filb.lua b/dat/Wiz-filb.lua index 28dc5e366..fbc28a771 100644 --- a/dat/Wiz-filb.lua +++ b/dat/Wiz-filb.lua @@ -1,4 +1,4 @@ --- NetHack Wizard Wiz-filb.lua $NHDT-Date: 1652196018 2022/05/10 15:20:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Wizard Wiz-filb.lua $NHDT-Date: 1781994876 2026/06/20 22:34:36 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1992 by David Cohrs -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/Wiz-goal.lua b/dat/Wiz-goal.lua index 8bf86626f..e5a92e92f 100644 --- a/dat/Wiz-goal.lua +++ b/dat/Wiz-goal.lua @@ -1,4 +1,4 @@ --- NetHack Wizard Wiz-goal.lua $NHDT-Date: 1652196018 2022/05/10 15:20:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Wizard Wiz-goal.lua $NHDT-Date: 1781994876 2026/06/20 22:34:36 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1992 by David Cohrs -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/Wiz-loca.lua b/dat/Wiz-loca.lua index 4522d61c2..5f8eb3080 100644 --- a/dat/Wiz-loca.lua +++ b/dat/Wiz-loca.lua @@ -1,4 +1,4 @@ --- NetHack Wizard Wiz-loca.lua $NHDT-Date: 1652196019 2022/05/10 15:20:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Wizard Wiz-loca.lua $NHDT-Date: 1781994876 2026/06/20 22:34:36 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1992 by David Cohrs -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/Wiz-strt.lua b/dat/Wiz-strt.lua index 96a04bae1..f03176afb 100644 --- a/dat/Wiz-strt.lua +++ b/dat/Wiz-strt.lua @@ -1,4 +1,4 @@ --- NetHack Wizard Wiz-strt.lua $NHDT-Date: 1652196019 2022/05/10 15:20:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack Wizard Wiz-strt.lua $NHDT-Date: 1781994877 2026/06/20 22:34:37 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1992 by David Cohrs -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/air.lua b/dat/air.lua index af27b86ac..93ba58d59 100644 --- a/dat/air.lua +++ b/dat/air.lua @@ -1,4 +1,4 @@ --- NetHack endgame air.lua $NHDT-Date: 1652196019 2022/05/10 15:20:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack endgame air.lua $NHDT-Date: 1781994877 2026/06/20 22:34:37 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992,1993 by Izchak Miller, David Cohrs, -- and Timo Hakulinen diff --git a/dat/asmodeus.lua b/dat/asmodeus.lua index c860e3cbc..72fd97a30 100644 --- a/dat/asmodeus.lua +++ b/dat/asmodeus.lua @@ -1,4 +1,4 @@ --- NetHack gehennom asmodeus.lua $NHDT-Date: 1652196020 2022/05/10 15:20:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack gehennom asmodeus.lua $NHDT-Date: 1781994877 2026/06/20 22:34:37 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/astral.lua b/dat/astral.lua index 6d6f0808b..0f6498b31 100644 --- a/dat/astral.lua +++ b/dat/astral.lua @@ -1,4 +1,4 @@ --- NetHack endgame astral.lua $NHDT-Date: 1652196020 2022/05/10 15:20:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ +-- NetHack endgame astral.lua $NHDT-Date: 1781994877 2026/06/20 22:34:37 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.9 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992,1993 by Izchak Miller, David Cohrs, -- and Timo Hakulinen diff --git a/dat/baalz.lua b/dat/baalz.lua index 233c26c5c..360449a85 100644 --- a/dat/baalz.lua +++ b/dat/baalz.lua @@ -1,4 +1,4 @@ --- NetHack gehennom baalz.lua $NHDT-Date: 1652196020 2022/05/10 15:20:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack gehennom baalz.lua $NHDT-Date: 1781994878 2026/06/20 22:34:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-1.lua b/dat/bigrm-1.lua index 2c734a5ac..2d048b786 100644 --- a/dat/bigrm-1.lua +++ b/dat/bigrm-1.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-1.lua $NHDT-Date: 1652196021 2022/05/10 15:20:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack bigroom bigrm-1.lua $NHDT-Date: 1781994878 2026/06/20 22:34:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-10.lua b/dat/bigrm-10.lua index dc51c1e02..90626100e 100644 --- a/dat/bigrm-10.lua +++ b/dat/bigrm-10.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-10.lua $NHDT-Date: 1652196024 2022/05/10 15:20:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack bigroom bigrm-10.lua $NHDT-Date: 1781994878 2026/06/20 22:34:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-11.lua b/dat/bigrm-11.lua index db9bcdccd..67df8d063 100644 --- a/dat/bigrm-11.lua +++ b/dat/bigrm-11.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-11.lua $NHDT-Date: 1652196024 2022/05/10 15:20:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ +-- NetHack bigroom bigrm-11.lua $NHDT-Date: 1781994878 2026/06/20 22:34:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.1 $ -- Copyright (c) 2021 by Pasi Kallinen -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/bigrm-12.lua b/dat/bigrm-12.lua index 0e41bd9e4..cb9a6e100 100644 --- a/dat/bigrm-12.lua +++ b/dat/bigrm-12.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-12.lua $NHDT-Date: $ $NHDT-Branch: NetHack-3.7 $ +-- NetHack bigroom bigrm-12.lua $NHDT-Date: $ $NHDT-Branch: NetHack-5.0 $ -- Copyright (c) 2024 by Pasi Kallinen -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/bigrm-13.lua b/dat/bigrm-13.lua index ff834a666..94b473eed 100644 --- a/dat/bigrm-13.lua +++ b/dat/bigrm-13.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-13.lua $NHDT-Date: 1652196024 2022/05/10 15:20:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ +-- NetHack bigroom bigrm-13.lua $NHDT-Date: 1781994879 2026/06/20 22:34:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 2026 by Pasi Kallinen -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/bigrm-2.lua b/dat/bigrm-2.lua index 53c3e100a..fc99ec540 100644 --- a/dat/bigrm-2.lua +++ b/dat/bigrm-2.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-2.lua $NHDT-Date: 1652196021 2022/05/10 15:20:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack bigroom bigrm-2.lua $NHDT-Date: 1781994879 2026/06/20 22:34:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-3.lua b/dat/bigrm-3.lua index ee7e0f310..315a0aa30 100644 --- a/dat/bigrm-3.lua +++ b/dat/bigrm-3.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-3.lua $NHDT-Date: 1652196021 2022/05/10 15:20:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack bigroom bigrm-3.lua $NHDT-Date: 1781994879 2026/06/20 22:34:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-4.lua b/dat/bigrm-4.lua index a6b9340d1..b38b31047 100644 --- a/dat/bigrm-4.lua +++ b/dat/bigrm-4.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-4.lua $NHDT-Date: 1652196022 2022/05/10 15:20:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack bigroom bigrm-4.lua $NHDT-Date: 1781994879 2026/06/20 22:34:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-5.lua b/dat/bigrm-5.lua index 3e40812e6..1e63e7851 100644 --- a/dat/bigrm-5.lua +++ b/dat/bigrm-5.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-5.lua $NHDT-Date: 1652196022 2022/05/10 15:20:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack bigroom bigrm-5.lua $NHDT-Date: 1781994879 2026/06/20 22:34:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-6.lua b/dat/bigrm-6.lua index c6063a818..e4d9a2b6d 100644 --- a/dat/bigrm-6.lua +++ b/dat/bigrm-6.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-6.lua $NHDT-Date: 1652196022 2022/05/10 15:20:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack bigroom bigrm-6.lua $NHDT-Date: 1781994880 2026/06/20 22:34:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-7.lua b/dat/bigrm-7.lua index 07038d8d6..58154a466 100644 --- a/dat/bigrm-7.lua +++ b/dat/bigrm-7.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-7.lua $NHDT-Date: 1652196023 2022/05/10 15:20:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ +-- NetHack bigroom bigrm-7.lua $NHDT-Date: 1781994880 2026/06/20 22:34:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-8.lua b/dat/bigrm-8.lua index f851411a8..fa6a7e181 100644 --- a/dat/bigrm-8.lua +++ b/dat/bigrm-8.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-8.lua $NHDT-Date: 1652196023 2022/05/10 15:20:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack bigroom bigrm-8.lua $NHDT-Date: 1781994880 2026/06/20 22:34:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-9.lua b/dat/bigrm-9.lua index e46543619..f7c33e879 100644 --- a/dat/bigrm-9.lua +++ b/dat/bigrm-9.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-9.lua $NHDT-Date: 1652196023 2022/05/10 15:20:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack bigroom bigrm-9.lua $NHDT-Date: 1781994880 2026/06/20 22:34:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/castle.lua b/dat/castle.lua index 0a2b7f243..9d4fa355a 100644 --- a/dat/castle.lua +++ b/dat/castle.lua @@ -1,4 +1,4 @@ --- NetHack castle castle.lua $NHDT-Date: 1652196024 2022/05/10 15:20:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ +-- NetHack castle castle.lua $NHDT-Date: 1781994880 2026/06/20 22:34:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.9 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/dungeon.lua b/dat/dungeon.lua index 7550d1317..5b1d23d2e 100644 --- a/dat/dungeon.lua +++ b/dat/dungeon.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 dungeon dungeon.lua $NHDT-Date: 1652196135 2022/05/10 15:22:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack 3.6 dungeon dungeon.lua $NHDT-Date: 1781994881 2026/06/20 22:34:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ -- Copyright (c) 1990-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/earth.lua b/dat/earth.lua index 4d7527e07..f052b4b08 100644 --- a/dat/earth.lua +++ b/dat/earth.lua @@ -1,4 +1,4 @@ --- NetHack endgame earth.lua $NHDT-Date: 1652196025 2022/05/10 15:20:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack endgame earth.lua $NHDT-Date: 1781994881 2026/06/20 22:34:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992,1993 by Izchak Miller, David Cohrs, -- and Timo Hakulinen diff --git a/dat/fakewiz1.lua b/dat/fakewiz1.lua index abee299d7..1ab3bd05f 100644 --- a/dat/fakewiz1.lua +++ b/dat/fakewiz1.lua @@ -1,4 +1,4 @@ --- NetHack yendor fakewiz1.lua $NHDT-Date: 1652196025 2022/05/10 15:20:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack yendor fakewiz1.lua $NHDT-Date: 1781994881 2026/06/20 22:34:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/fakewiz2.lua b/dat/fakewiz2.lua index 4b81ae338..731b84813 100644 --- a/dat/fakewiz2.lua +++ b/dat/fakewiz2.lua @@ -1,4 +1,4 @@ --- NetHack yendor fakewiz2.lua $NHDT-Date: 1652196026 2022/05/10 15:20:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack yendor fakewiz2.lua $NHDT-Date: 1781994881 2026/06/20 22:34:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/fire.lua b/dat/fire.lua index 1cd3db7a2..01fc3c93a 100644 --- a/dat/fire.lua +++ b/dat/fire.lua @@ -1,4 +1,4 @@ --- NetHack endgame fire.lua $NHDT-Date: 1700398454 2023/11/19 12:54:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack endgame fire.lua $NHDT-Date: 1781994882 2026/06/20 22:34:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992,1993 by Izchak Miller, David Cohrs, -- and Timo Hakulinen diff --git a/dat/juiblex.lua b/dat/juiblex.lua index 56c02f9a5..cbf8620cd 100644 --- a/dat/juiblex.lua +++ b/dat/juiblex.lua @@ -1,4 +1,4 @@ --- NetHack gehennom juiblex.lua $NHDT-Date: 1652196026 2022/05/10 15:20:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ +-- NetHack gehennom juiblex.lua $NHDT-Date: 1781994882 2026/06/20 22:34:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.7 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/knox.lua b/dat/knox.lua index 2b58f2ae4..ed947743f 100644 --- a/dat/knox.lua +++ b/dat/knox.lua @@ -1,4 +1,4 @@ --- NetHack knox knox.lua $NHDT-Date: 1652196027 2022/05/10 15:20:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ +-- NetHack knox knox.lua $NHDT-Date: 1781994882 2026/06/20 22:34:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/medusa-1.lua b/dat/medusa-1.lua index 3c5e50c66..6763abb4c 100644 --- a/dat/medusa-1.lua +++ b/dat/medusa-1.lua @@ -1,4 +1,4 @@ --- NetHack medusa medusa-1.lua $NHDT-Date: 1652196027 2022/05/10 15:20:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack medusa medusa-1.lua $NHDT-Date: 1781994882 2026/06/20 22:34:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990, 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/medusa-2.lua b/dat/medusa-2.lua index d270616ae..d3adcbfb7 100644 --- a/dat/medusa-2.lua +++ b/dat/medusa-2.lua @@ -1,4 +1,4 @@ --- NetHack medusa medusa-2.lua $NHDT-Date: 1652196027 2022/05/10 15:20:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack medusa medusa-2.lua $NHDT-Date: 1781994882 2026/06/20 22:34:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990, 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/medusa-3.lua b/dat/medusa-3.lua index 282d3668b..84da3dee0 100644 --- a/dat/medusa-3.lua +++ b/dat/medusa-3.lua @@ -1,4 +1,4 @@ --- NetHack medusa medusa-3.lua $NHDT-Date: 1716152250 2024/05/19 20:57:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ +-- NetHack medusa medusa-3.lua $NHDT-Date: 1781994883 2026/06/20 22:34:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990, 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/medusa-4.lua b/dat/medusa-4.lua index acf6c6d3f..22fbd91f6 100644 --- a/dat/medusa-4.lua +++ b/dat/medusa-4.lua @@ -1,4 +1,4 @@ --- NetHack medusa medusa-4.lua $NHDT-Date: 1716152274 2024/05/19 20:57:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ +-- NetHack medusa medusa-4.lua $NHDT-Date: 1781994883 2026/06/20 22:34:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.9 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990, 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minefill.lua b/dat/minefill.lua index 2992690e6..eab601b23 100644 --- a/dat/minefill.lua +++ b/dat/minefill.lua @@ -1,4 +1,4 @@ --- NetHack mines minefill.lua $NHDT-Date: 1652196028 2022/05/10 15:20:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack mines minefill.lua $NHDT-Date: 1781994883 2026/06/20 22:34:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minend-1.lua b/dat/minend-1.lua index 5d690c32c..f32f27c62 100644 --- a/dat/minend-1.lua +++ b/dat/minend-1.lua @@ -1,4 +1,4 @@ --- NetHack mines minend-1.lua $NHDT-Date: 1652196029 2022/05/10 15:20:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack mines minend-1.lua $NHDT-Date: 1781994883 2026/06/20 22:34:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minend-2.lua b/dat/minend-2.lua index e85e45870..061e00aa6 100644 --- a/dat/minend-2.lua +++ b/dat/minend-2.lua @@ -1,4 +1,4 @@ --- NetHack mines minend-2.lua $NHDT-Date: 1652196029 2022/05/10 15:20:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack mines minend-2.lua $NHDT-Date: 1781994884 2026/06/20 22:34:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.7 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minend-3.lua b/dat/minend-3.lua index 411e1ac67..21f25a6a0 100644 --- a/dat/minend-3.lua +++ b/dat/minend-3.lua @@ -1,4 +1,4 @@ --- NetHack mines minend-3.lua $NHDT-Date: 1652196029 2022/05/10 15:20:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack mines minend-3.lua $NHDT-Date: 1781994884 2026/06/20 22:34:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minetn-1.lua b/dat/minetn-1.lua index 87544b1c9..c0bf0f68d 100644 --- a/dat/minetn-1.lua +++ b/dat/minetn-1.lua @@ -1,4 +1,4 @@ --- NetHack 5.0 mines minetn-1.lua $NHDT-Date: 1652196030 2022/05/10 15:20:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ +-- NetHack 5.0 mines minetn-1.lua $NHDT-Date: 1781994884 2026/06/20 22:34:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minetn-2.lua b/dat/minetn-2.lua index 133285f93..60784f7a4 100644 --- a/dat/minetn-2.lua +++ b/dat/minetn-2.lua @@ -1,4 +1,4 @@ --- NetHack mines minetn-2.lua $NHDT-Date: 1652196030 2022/05/10 15:20:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack mines minetn-2.lua $NHDT-Date: 1781994884 2026/06/20 22:34:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minetn-3.lua b/dat/minetn-3.lua index 910293868..e8b308ef9 100644 --- a/dat/minetn-3.lua +++ b/dat/minetn-3.lua @@ -1,4 +1,4 @@ --- NetHack mines minetn-3.lua $NHDT-Date: 1652196030 2022/05/10 15:20:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack mines minetn-3.lua $NHDT-Date: 1781994885 2026/06/20 22:34:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minetn-4.lua b/dat/minetn-4.lua index 6d5804133..57625fdf4 100644 --- a/dat/minetn-4.lua +++ b/dat/minetn-4.lua @@ -1,4 +1,4 @@ --- NetHack mines minetn-4.lua $NHDT-Date: 1652196031 2022/05/10 15:20:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack mines minetn-4.lua $NHDT-Date: 1781994885 2026/06/20 22:34:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minetn-5.lua b/dat/minetn-5.lua index a0d16ea0a..c995d2f55 100644 --- a/dat/minetn-5.lua +++ b/dat/minetn-5.lua @@ -1,4 +1,4 @@ --- NetHack mines minetn-5.lua $NHDT-Date: 1652196031 2022/05/10 15:20:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ +-- NetHack mines minetn-5.lua $NHDT-Date: 1781994885 2026/06/20 22:34:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minetn-6.lua b/dat/minetn-6.lua index 2827d1947..9f37d76e3 100644 --- a/dat/minetn-6.lua +++ b/dat/minetn-6.lua @@ -1,4 +1,4 @@ --- NetHack mines minetn-6.lua $NHDT-Date: 1652196031 2022/05/10 15:20:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack mines minetn-6.lua $NHDT-Date: 1781994885 2026/06/20 22:34:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.7 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minetn-7.lua b/dat/minetn-7.lua index 31a1d3d80..024c3389d 100644 --- a/dat/minetn-7.lua +++ b/dat/minetn-7.lua @@ -1,4 +1,4 @@ --- NetHack mines minetn-7.lua $NHDT-Date: 1652196032 2022/05/10 15:20:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack mines minetn-7.lua $NHDT-Date: 1781994885 2026/06/20 22:34:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/nhcore.lua b/dat/nhcore.lua index 0fc778f6c..41c718dc0 100644 --- a/dat/nhcore.lua +++ b/dat/nhcore.lua @@ -1,4 +1,4 @@ --- NetHack core nhcore.lua $NHDT-Date: 1652196284 2022/05/10 15:24:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ +-- NetHack core nhcore.lua $NHDT-Date: 1781994886 2026/06/20 22:34:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 2021 by Pasi Kallinen -- NetHack may be freely redistributed. See license for details. -- This file contains lua code used by NetHack core. diff --git a/dat/nhlib.lua b/dat/nhlib.lua index f4fab68fb..f8fc93072 100644 --- a/dat/nhlib.lua +++ b/dat/nhlib.lua @@ -1,4 +1,4 @@ --- NetHack nhlib.lua $NHDT-Date: 1652196140 2022/05/10 15:22:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack nhlib.lua $NHDT-Date: 1781994886 2026/06/20 22:34:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.20 $ -- Copyright (c) 2021 by Pasi Kallinen -- NetHack may be freely redistributed. See license for details. -- compatibility shim diff --git a/dat/oracle.lua b/dat/oracle.lua index 16ee2ff4e..b77562ce3 100644 --- a/dat/oracle.lua +++ b/dat/oracle.lua @@ -1,4 +1,4 @@ --- NetHack oracle oracle.lua $NHDT-Date: 1652196033 2022/05/10 15:20:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack oracle oracle.lua $NHDT-Date: 1781994886 2026/06/20 22:34:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 2015 by Pasi Kallinen -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/orcus.lua b/dat/orcus.lua index 67406d8e2..b3d286c2c 100644 --- a/dat/orcus.lua +++ b/dat/orcus.lua @@ -1,4 +1,4 @@ --- NetHack gehennom orcus.lua $NHDT-Date: 1652196033 2022/05/10 15:20:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack gehennom orcus.lua $NHDT-Date: 1781994886 2026/06/20 22:34:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/quest.lua b/dat/quest.lua index c3bad692d..298b6bb60 100644 --- a/dat/quest.lua +++ b/dat/quest.lua @@ -1,4 +1,4 @@ --- NetHack quest.lua $NHDT-Date: 1726894904 2024/09/21 05:01:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ +-- NetHack quest.lua $NHDT-Date: 1781994887 2026/06/20 22:34:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ -- Copyright (c) 2021 by Pasi Kallinen -- NetHack may be freely redistributed. See license for details. -- TODO: diff --git a/dat/sanctum.lua b/dat/sanctum.lua index fe5a85eb0..803ce73c2 100644 --- a/dat/sanctum.lua +++ b/dat/sanctum.lua @@ -1,4 +1,4 @@ --- NetHack gehennom sanctum.lua $NHDT-Date: 1652196034 2022/05/10 15:20:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ +-- NetHack gehennom sanctum.lua $NHDT-Date: 1781994887 2026/06/20 22:34:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/soko1-1.lua b/dat/soko1-1.lua index ac9bcdf31..4d9886b3a 100644 --- a/dat/soko1-1.lua +++ b/dat/soko1-1.lua @@ -1,4 +1,4 @@ --- NetHack sokoban soko1-1.lua $NHDT-Date: 1652196034 2022/05/10 15:20:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ +-- NetHack sokoban soko1-1.lua $NHDT-Date: 1781994887 2026/06/20 22:34:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ -- Copyright (c) 1998-1999 by Kevin Hugo -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/soko1-2.lua b/dat/soko1-2.lua index 36ab90721..34bffdb96 100644 --- a/dat/soko1-2.lua +++ b/dat/soko1-2.lua @@ -1,4 +1,4 @@ --- NetHack sokoban soko1-2.lua $NHDT-Date: 1652196034 2022/05/10 15:20:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ +-- NetHack sokoban soko1-2.lua $NHDT-Date: 1781994887 2026/06/20 22:34:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ -- Copyright (c) 1998-1999 by Kevin Hugo -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/soko2-1.lua b/dat/soko2-1.lua index e8b56efef..475323984 100644 --- a/dat/soko2-1.lua +++ b/dat/soko2-1.lua @@ -1,4 +1,4 @@ --- NetHack sokoban soko2-1.lua $NHDT-Date: 1652196035 2022/05/10 15:20:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack sokoban soko2-1.lua $NHDT-Date: 1781994888 2026/06/20 22:34:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1998-1999 by Kevin Hugo -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/soko2-2.lua b/dat/soko2-2.lua index f11702c1e..18c07c1e9 100644 --- a/dat/soko2-2.lua +++ b/dat/soko2-2.lua @@ -1,4 +1,4 @@ --- NetHack sokoban soko2-2.lua $NHDT-Date: 1652196035 2022/05/10 15:20:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack sokoban soko2-2.lua $NHDT-Date: 1781994888 2026/06/20 22:34:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1998-1999 by Kevin Hugo -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/soko3-1.lua b/dat/soko3-1.lua index 1c7715858..1675ed09c 100644 --- a/dat/soko3-1.lua +++ b/dat/soko3-1.lua @@ -1,4 +1,4 @@ --- NetHack sokoban soko3-1.lua $NHDT-Date: 1652196035 2022/05/10 15:20:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack sokoban soko3-1.lua $NHDT-Date: 1781994888 2026/06/20 22:34:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1998-1999 by Kevin Hugo -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/soko3-2.lua b/dat/soko3-2.lua index 24236efe2..e445fffa9 100644 --- a/dat/soko3-2.lua +++ b/dat/soko3-2.lua @@ -1,4 +1,4 @@ --- NetHack sokoban soko3-2.lua $NHDT-Date: 1652196036 2022/05/10 15:20:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack sokoban soko3-2.lua $NHDT-Date: 1781994888 2026/06/20 22:34:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1998-1999 by Kevin Hugo -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/soko4-1.lua b/dat/soko4-1.lua index 3768c1cf7..39b35e30a 100644 --- a/dat/soko4-1.lua +++ b/dat/soko4-1.lua @@ -1,4 +1,4 @@ --- NetHack sokoban soko4-1.lua $NHDT-Date: 1652196036 2022/05/10 15:20:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack sokoban soko4-1.lua $NHDT-Date: 1781994888 2026/06/20 22:34:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1998-1999 by Kevin Hugo -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/soko4-2.lua b/dat/soko4-2.lua index d0606dc6a..df830b32d 100644 --- a/dat/soko4-2.lua +++ b/dat/soko4-2.lua @@ -1,4 +1,4 @@ --- NetHack sokoban soko4-2.lua $NHDT-Date: 1652196036 2022/05/10 15:20:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack sokoban soko4-2.lua $NHDT-Date: 1781994889 2026/06/20 22:34:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1998-1999 by Kevin Hugo -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/themerms.lua b/dat/themerms.lua index 6aff95286..c29d66ce0 100644 --- a/dat/themerms.lua +++ b/dat/themerms.lua @@ -1,4 +1,4 @@ --- NetHack themerms.lua $NHDT-Date: 1744445274 2025/04/12 00:07:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ +-- NetHack themerms.lua $NHDT-Date: 1781994889 2026/06/20 22:34:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.43 $ -- Copyright (c) 2020 by Pasi Kallinen -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/tower1.lua b/dat/tower1.lua index eae3016b3..2a7c98e23 100644 --- a/dat/tower1.lua +++ b/dat/tower1.lua @@ -1,4 +1,4 @@ --- NetHack tower tower1.lua $NHDT-Date: 1717178759 2024/05/31 18:05:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack tower tower1.lua $NHDT-Date: 1781994889 2026/06/20 22:34:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.7 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/tower2.lua b/dat/tower2.lua index 57b5d6003..958f8c104 100644 --- a/dat/tower2.lua +++ b/dat/tower2.lua @@ -1,4 +1,4 @@ --- NetHack tower tower2.lua $NHDT-Date: 1652196037 2022/05/10 15:20:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack tower tower2.lua $NHDT-Date: 1781994889 2026/06/20 22:34:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/tower3.lua b/dat/tower3.lua index fe1484db2..dc9623917 100644 --- a/dat/tower3.lua +++ b/dat/tower3.lua @@ -1,4 +1,4 @@ --- NetHack tower tower3.lua $NHDT-Date: 1652196038 2022/05/10 15:20:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack tower tower3.lua $NHDT-Date: 1781994889 2026/06/20 22:34:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/valley.lua b/dat/valley.lua index 96bceb997..56c339537 100644 --- a/dat/valley.lua +++ b/dat/valley.lua @@ -1,4 +1,4 @@ --- NetHack gehennom valley.lua $NHDT-Date: 1652196038 2022/05/10 15:20:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack gehennom valley.lua $NHDT-Date: 1781994890 2026/06/20 22:34:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/water.lua b/dat/water.lua index 760c83eb5..fc3678e7f 100644 --- a/dat/water.lua +++ b/dat/water.lua @@ -1,4 +1,4 @@ --- NetHack endgame water.lua $NHDT-Date: 1652196038 2022/05/10 15:20:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack endgame water.lua $NHDT-Date: 1781994890 2026/06/20 22:34:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992,1993 by Izchak Miller, David Cohrs, -- and Timo Hakulinen diff --git a/dat/wizard1.lua b/dat/wizard1.lua index f1d4be198..612f67be8 100644 --- a/dat/wizard1.lua +++ b/dat/wizard1.lua @@ -1,4 +1,4 @@ --- NetHack yendor wizard1.lua $NHDT-Date: 1652196039 2022/05/10 15:20:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack yendor wizard1.lua $NHDT-Date: 1781994890 2026/06/20 22:34:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/wizard2.lua b/dat/wizard2.lua index 34f48005d..75ce9f92a 100644 --- a/dat/wizard2.lua +++ b/dat/wizard2.lua @@ -1,4 +1,4 @@ --- NetHack yendor wizard2.lua $NHDT-Date: 1652196039 2022/05/10 15:20:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack yendor wizard2.lua $NHDT-Date: 1781994890 2026/06/20 22:34:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/wizard3.lua b/dat/wizard3.lua index 3166d799c..c302b1ac3 100644 --- a/dat/wizard3.lua +++ b/dat/wizard3.lua @@ -1,4 +1,4 @@ --- NetHack yendor wizard3.lua $NHDT-Date: 1652196040 2022/05/10 15:20:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack yendor wizard3.lua $NHDT-Date: 1781994891 2026/06/20 22:34:51 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. From 6808e87869c089dcc991e5fb556559105d6c2e58 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 20 Jun 2026 18:55:28 -0400 Subject: [PATCH 497/702] yet more 3.7 cleanup --- dat/bogusmon.txt | 2 +- dat/engrave.txt | 2 +- dat/epitaph.txt | 2 +- dat/symbols | 2 +- dat/tribute | 2 +- doc/Guidebook.mn | 2 +- doc/Guidebook.tex | 2 +- doc/config.nh | 2 +- doc/sound.txt | 2 +- doc/window.txt | 2 +- outdated/include/mac-carbon.h | 2 +- outdated/include/mac-qt.h | 2 +- outdated/include/mac-term.h | 2 +- outdated/include/macpopup.h | 2 +- outdated/include/mactty.h | 2 +- outdated/include/macwin.h | 2 +- outdated/include/mttypriv.h | 2 +- outdated/include/system.h | 2 +- outdated/include/trampoli.h | 2 +- outdated/include/winGnome.h | 2 +- outdated/include/wingem.h | 2 +- outdated/sys/vms/lev_lex.h | 2 +- outdated/win/Qt3/qt3_win.h | 2 +- win/X11/NetHack.ad | 2 +- win/X11/nh32icon | 2 +- win/X11/nh56icon | 2 +- win/X11/nh72icon | 2 +- win/macosx/NetHackGuidebook.applescript | 2 +- win/macosx/NetHackRecover.applescript | 2 +- win/macosx/recover.pl | 2 +- win/share/tile.doc | 2 +- 31 files changed, 31 insertions(+), 31 deletions(-) diff --git a/dat/bogusmon.txt b/dat/bogusmon.txt index b7474231c..8a418ff50 100644 --- a/dat/bogusmon.txt +++ b/dat/bogusmon.txt @@ -1,4 +1,4 @@ -# NetHack 5.0 bogusmon.txt $NHDT-Date: 1596498237 2020/08/03 23:43:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ +# NetHack 5.0 bogusmon.txt $NHDT-Date: 1596498237 2020/08/03 23:43:57 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ # Copyright (c) 2016 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. # diff --git a/dat/engrave.txt b/dat/engrave.txt index 1d199a3e7..cd62963a8 100644 --- a/dat/engrave.txt +++ b/dat/engrave.txt @@ -1,4 +1,4 @@ -# NetHack 5.0 engrave.txt $NHDT-Date: 1596498240 2020/08/03 23:44:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ +# NetHack 5.0 engrave.txt $NHDT-Date: 1596498240 2020/08/03 23:44:00 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ # Copyright (c) 2015 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. # Random engravings on the floor diff --git a/dat/epitaph.txt b/dat/epitaph.txt index 1c1a85f6a..2d80d1741 100644 --- a/dat/epitaph.txt +++ b/dat/epitaph.txt @@ -1,4 +1,4 @@ -# NetHack 5.0 epitaph.txt $NHDT-Date: 1596498241 2020/08/03 23:44:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +# NetHack 5.0 epitaph.txt $NHDT-Date: 1596498241 2020/08/03 23:44:01 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ # Copyright (c) 2015 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. # Epitaphs for random headstones diff --git a/dat/symbols b/dat/symbols index cb46ec197..39ea0ce6a 100644 --- a/dat/symbols +++ b/dat/symbols @@ -1,4 +1,4 @@ -# NetHack 5.0 symbols $NHDT-Date: 1725052751 2024/08/30 21:19:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.36 $ +# NetHack 5.0 symbols $NHDT-Date: 1725052751 2024/08/30 21:19:11 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.36 $ # Copyright (c) 2006 by Michael Allison # NetHack may be freely redistributed. See license for details. # diff --git a/dat/tribute b/dat/tribute index a2944d7d6..097bdc3b5 100644 --- a/dat/tribute +++ b/dat/tribute @@ -1,4 +1,4 @@ -# NetHack 5.0 tribute $NHDT-Date: 1726809275 2024/09/20 05:14:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.118 $ +# NetHack 5.0 tribute $NHDT-Date: 1726809275 2024/09/20 05:14:35 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.118 $ # Copyright (c) 2017 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. # A tribute introduced in NetHack 3.6.0 to: diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index eae8626c7..28e9e7fad 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.614 $ $NHDT-Date: 1770881338 2026/02/11 23:28:58 $ +.\" $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.614 $ $NHDT-Date: 1770881338 2026/02/11 23:28:58 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\"+-- diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 8ba048b5e..e6d0aa2ca 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -1,4 +1,4 @@ -% NetHack 5.0 Guidebook.tex $NHDT-Date: 1770881338 2026/02/11 23:28:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.596 $ */ +% NetHack 5.0 Guidebook.tex $NHDT-Date: 1770881338 2026/02/11 23:28:58 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.596 $ */ \documentclass[titlepage]{article} \usepackage[hidelinks]{hyperref} \usepackage{longtable} diff --git a/doc/config.nh b/doc/config.nh index 69c722135..625eb3648 100644 --- a/doc/config.nh +++ b/doc/config.nh @@ -1,4 +1,4 @@ -# NetHack 3.7 config.nh $NHDT-Date: 1745978702 2025/04/29 18:05:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ +# NetHack 3.7 config.nh $NHDT-Date: 1745978702 2025/04/29 18:05:02 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ # Copyright (c) 2016 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. # diff --git a/doc/sound.txt b/doc/sound.txt index 608237c68..ee4c34893 100644 --- a/doc/sound.txt +++ b/doc/sound.txt @@ -1,4 +1,4 @@ -NetHack 5.0 sound.txt $NHDT-Date: 1693253363 2023/08/28 20:09:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ +NetHack 5.0 sound.txt $NHDT-Date: 1693253363 2023/08/28 20:09:23 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.7 $ Introduction diff --git a/doc/window.txt b/doc/window.txt index ae69d4f00..f45db607b 100644 --- a/doc/window.txt +++ b/doc/window.txt @@ -1,4 +1,4 @@ -NetHack 5.0 window.txt $NHDT-Date: 1666390558 2022/10/21 22:15:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ +NetHack 5.0 window.txt $NHDT-Date: 1666390558 2022/10/21 22:15:58 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.70 $ Introduction diff --git a/outdated/include/mac-carbon.h b/outdated/include/mac-carbon.h index e77e2223f..fb270054f 100644 --- a/outdated/include/mac-carbon.h +++ b/outdated/include/mac-carbon.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 mac-carbon.h $NHDT-Date: 1596498540 2020/08/03 23:49:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.6 mac-carbon.h $NHDT-Date: 1596498540 2020/08/03 23:49:00 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 2003. */ /*-Copyright (c) Kevin Hugo, 2003. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/mac-qt.h b/outdated/include/mac-qt.h index 41f61d9f9..b284142d3 100644 --- a/outdated/include/mac-qt.h +++ b/outdated/include/mac-qt.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 mac-qt.h $NHDT-Date: 1596498541 2020/08/03 23:49:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.6 mac-qt.h $NHDT-Date: 1596498541 2020/08/03 23:49:01 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 2003. */ /*-Copyright (c) Kevin Hugo, 2003. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/mac-term.h b/outdated/include/mac-term.h index 3aa0c3aa5..50c0e2301 100644 --- a/outdated/include/mac-term.h +++ b/outdated/include/mac-term.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 mac-term.h $NHDT-Date: 1596498541 2020/08/03 23:49:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.6 mac-term.h $NHDT-Date: 1596498541 2020/08/03 23:49:01 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 2003. */ /*-Copyright (c) Kevin Hugo, 2003. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/macpopup.h b/outdated/include/macpopup.h index 0e1e72eb4..79c67d73a 100644 --- a/outdated/include/macpopup.h +++ b/outdated/include/macpopup.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 macpopup.h $NHDT-Date: 1596498542 2020/08/03 23:49:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 3.6 macpopup.h $NHDT-Date: 1596498542 2020/08/03 23:49:02 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) Nethack Development Team, 1999. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/mactty.h b/outdated/include/mactty.h index fb64887b7..a620b5b9e 100644 --- a/outdated/include/mactty.h +++ b/outdated/include/mactty.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 mactty.h $NHDT-Date: 1596498543 2020/08/03 23:49:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 3.6 mactty.h $NHDT-Date: 1596498543 2020/08/03 23:49:03 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Jon W{tte 1993. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/macwin.h b/outdated/include/macwin.h index ddf20170f..ef89fceb2 100644 --- a/outdated/include/macwin.h +++ b/outdated/include/macwin.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 macwin.h $NHDT-Date: 1596498543 2020/08/03 23:49:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 3.6 macwin.h $NHDT-Date: 1596498543 2020/08/03 23:49:03 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kevin Hugo, 2003. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/mttypriv.h b/outdated/include/mttypriv.h index 5720dad94..a1b4e0f62 100644 --- a/outdated/include/mttypriv.h +++ b/outdated/include/mttypriv.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 mttypriv.h $NHDT-Date: 1596498551 2020/08/03 23:49:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.6 mttypriv.h $NHDT-Date: 1596498551 2020/08/03 23:49:11 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) Jon W{tte 1993. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/system.h b/outdated/include/system.h index bd7045620..a3571ad44 100644 --- a/outdated/include/system.h +++ b/outdated/include/system.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 system.h $NHDT-Date: 1596498562 2020/08/03 23:49:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 3.6 system.h $NHDT-Date: 1596498562 2020/08/03 23:49:22 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.24 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/trampoli.h b/outdated/include/trampoli.h index 5a4af9fcb..7fa42779d 100644 --- a/outdated/include/trampoli.h +++ b/outdated/include/trampoli.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 trampoli.h $NHDT-Date: 1596498566 2020/08/03 23:49:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 3.6 trampoli.h $NHDT-Date: 1596498566 2020/08/03 23:49:26 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) 1989, by Norm Meluch and Stephen Spackman */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/winGnome.h b/outdated/include/winGnome.h index 96950fc1e..4714c17d2 100644 --- a/outdated/include/winGnome.h +++ b/outdated/include/winGnome.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 winGnome.h $NHDT-Date: 1596498571 2020/08/03 23:49:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.6 winGnome.h $NHDT-Date: 1596498571 2020/08/03 23:49:31 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.9 $ */ /* Copyright (C) 1998 by Erik Andersen */ /* Copyright (C) 1998 by Anthony Taylor */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/wingem.h b/outdated/include/wingem.h index 21be09ce5..017f718f5 100644 --- a/outdated/include/wingem.h +++ b/outdated/include/wingem.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 wingem.h $NHDT-Date: 1596498570 2020/08/03 23:49:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 3.6 wingem.h $NHDT-Date: 1596498570 2020/08/03 23:49:30 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.15 $ */ /* Copyright (c) Christian Bressler, 1999 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/sys/vms/lev_lex.h b/outdated/sys/vms/lev_lex.h index 97e688540..a6d8a62cf 100644 --- a/outdated/sys/vms/lev_lex.h +++ b/outdated/sys/vms/lev_lex.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 lev_lex.h $NHDT-Date: 1596498300 2020/08/03 23:45:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.6 lev_lex.h $NHDT-Date: 1596498300 2020/08/03 23:45:00 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.9 $ */ /* "vms/lev_lex.h" copied into "util/stdio.h" for use in *_lex.c only! * This is an awful kludge to allow util/*_lex.c made by SunOS's `lex' * to be compiled as is. (It isn't needed with `flex' or VMS POSIX diff --git a/outdated/win/Qt3/qt3_win.h b/outdated/win/Qt3/qt3_win.h index c5548e37c..e3a2076c1 100644 --- a/outdated/win/Qt3/qt3_win.h +++ b/outdated/win/Qt3/qt3_win.h @@ -1,4 +1,4 @@ -// NetHack 3.6 qt_win.h $NHDT-Date: 1575917700 2019/12/09 18:55:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ +// NetHack 3.6 qt_win.h $NHDT-Date: 1575917700 2019/12/09 18:55:00 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.0 $ // Copyright (c) Warwick Allison, 1999. // NetHack may be freely redistributed. See license for details. // diff --git a/win/X11/NetHack.ad b/win/X11/NetHack.ad index c10d1360f..ecd654034 100644 --- a/win/X11/NetHack.ad +++ b/win/X11/NetHack.ad @@ -1,4 +1,4 @@ -! $NHDT-Date: 1750598195 2025/06/22 05:16:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.27 $ +! $NHDT-Date: 1750598195 2025/06/22 05:16:35 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.27 $ ! Copyright (c) 2017 by Pasi Kallinen ! NetHack may be freely redistributed. See license for details. diff --git a/win/X11/nh32icon b/win/X11/nh32icon index 553ea2d92..adc4f24f5 100644 --- a/win/X11/nh32icon +++ b/win/X11/nh32icon @@ -1,4 +1,4 @@ -/* NetHack 5.0 nh32icon $NHDT-Date: 1597001766 2020/08/09 19:36:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 nh32icon $NHDT-Date: 1597001766 2020/08/09 19:36:06 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ */ /* Copyright (C) 1993,1995,2015 by Robert Patrick Rankin */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/nh56icon b/win/X11/nh56icon index 6d6156672..d845ddbe7 100644 --- a/win/X11/nh56icon +++ b/win/X11/nh56icon @@ -1,4 +1,4 @@ -/* NetHack 5.0 nh56icon $NHDT-Date: 1597001767 2020/08/09 19:36:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 nh56icon $NHDT-Date: 1597001767 2020/08/09 19:36:07 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) 1993,1995,2015 by M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/nh72icon b/win/X11/nh72icon index 55ac15767..3f1e28da7 100644 --- a/win/X11/nh72icon +++ b/win/X11/nh72icon @@ -1,4 +1,4 @@ -/* NetHack 5.0 nh72icon $NHDT-Date: 1596498370 2020/08/03 23:46:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 nh72icon $NHDT-Date: 1596498370 2020/08/03 23:46:10 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) 1993 by M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/macosx/NetHackGuidebook.applescript b/win/macosx/NetHackGuidebook.applescript index 81281a397..6006623fe 100644 --- a/win/macosx/NetHackGuidebook.applescript +++ b/win/macosx/NetHackGuidebook.applescript @@ -1,5 +1,5 @@ #!/usr/bin/osascript -# NetHack 5.0 NetHackGuidebook.applescript $NHDT-Date: 1596498328 2020/08/03 23:45:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ +# NetHack 5.0 NetHackGuidebook.applescript $NHDT-Date: 1596498328 2020/08/03 23:45:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2011 # NetHack may be freely redistributed. See license for details. diff --git a/win/macosx/NetHackRecover.applescript b/win/macosx/NetHackRecover.applescript index c6e81ae0a..72544864b 100644 --- a/win/macosx/NetHackRecover.applescript +++ b/win/macosx/NetHackRecover.applescript @@ -1,5 +1,5 @@ #!/usr/bin/osascript -# NetHack 5.0 NetHackRecover.applescript $NHDT-Date: 1596498329 2020/08/03 23:45:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ +# NetHack 5.0 NetHackRecover.applescript $NHDT-Date: 1596498329 2020/08/03 23:45:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2009 # NetHack may be freely redistributed. See license for details. diff --git a/win/macosx/recover.pl b/win/macosx/recover.pl index 7fb9411aa..5fb4535f2 100755 --- a/win/macosx/recover.pl +++ b/win/macosx/recover.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl -# NetHack 5.0 recover.pl $NHDT-Date: 1596498329 2020/08/03 23:45:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ +# NetHack 5.0 recover.pl $NHDT-Date: 1596498329 2020/08/03 23:45:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2009 # NetHack may be freely redistributed. See license for details. diff --git a/win/share/tile.doc b/win/share/tile.doc index d701d33df..4e70c960b 100644 --- a/win/share/tile.doc +++ b/win/share/tile.doc @@ -1,4 +1,4 @@ -NetHack 5.0 tile.doc $NHDT-Date: 1596498338 2020/08/03 23:45:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ +NetHack 5.0 tile.doc $NHDT-Date: 1596498338 2020/08/03 23:45:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.8 $ Window ports can optionally make use of the tiles (pictures for NetHack symbols) found in this directory. They are distributed in a text format From 7c694ad785a8cc81b8207f610cd4e5ccd4d662a1 Mon Sep 17 00:00:00 2001 From: nhkeni Date: Sat, 20 Jun 2026 19:43:26 -0400 Subject: [PATCH 498/702] Remove deprecated option --version:paste This should have been deleted before the 5.0.0 release. --- doc/fixes5-0-1.txt | 1 + src/earlyarg.c | 8 ++------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 710a23f69..7b3746481 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -66,6 +66,7 @@ when hero's behavior makes erinyes stronger, cap level at 49 rather than 50 with inventory item action for leash, distingluish leash-in-use from empty one deafness check was missing from a shopkeeper message in ready_weapon() thrown ball travel did not check for regions (pr #1595 by copperwater) +remove deprecated option --version:paste Platform- and/or Interface-Specific Fixes diff --git a/src/earlyarg.c b/src/earlyarg.c index 2d3315fdf..952defaaa 100755 --- a/src/earlyarg.c +++ b/src/earlyarg.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 earlyarg.c $NHDT-Date: 1781973047 2026/06/20 16:30:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 earlyarg.c $NHDT-Date: 1782016695 2026/06/20 23:38:15 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -498,11 +498,7 @@ argcheck(int argc, char *argv[], enum earlyarg e_arg) if (extended_opt) { extended_opt++; - /* Deprecated in favor of "copy" - remove no later - than next major version */ - if (match_optname(extended_opt, "paste", 5, FALSE)) { - insert_into_pastebuf = TRUE; - } else if (match_optname(extended_opt, "copy", 4, FALSE)) { + if (match_optname(extended_opt, "copy", 4, FALSE)) { insert_into_pastebuf = TRUE; } else if (match_optname(extended_opt, "dump", 4, FALSE)) { /* version number plus enabled features and sanity From 186d9524de4c7bae696f6fcd8cfed44933d7b33e Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 20 Jun 2026 20:02:31 -0400 Subject: [PATCH 499/702] missed a line in this file --- doc/config.nh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/config.nh b/doc/config.nh index 625eb3648..00b8a8a08 100644 --- a/doc/config.nh +++ b/doc/config.nh @@ -1,4 +1,4 @@ -# NetHack 3.7 config.nh $NHDT-Date: 1745978702 2025/04/29 18:05:02 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ +# NetHack 5.0 config.nh $NHDT-Date: 1745978702 2025/04/29 18:05:02 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ # Copyright (c) 2016 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. # From 43c302d9274578d1ad727db0c0a688d1a898306f Mon Sep 17 00:00:00 2001 From: copperwater Date: Sun, 21 Jun 2026 06:02:20 -0400 Subject: [PATCH 500/702] Copy bones monster info to recorporealized ghost This is a reimplementation of commit ec32748 in TNNT by entrez: If you use undead turning on a dead hero's corpse from a bones file, its ghost will get sucked back into its body when it comes back to life. In such cases, treat the newly revived corpse/recorporealized ghost as a "former hero" for the purposes of livelogging bones monster kills. Part of this change was to remove a bit of weirdness in the game - the odd situation where you revive a corpse-ghost combo on a bones pile, and get the messages: The human corpse glows iridescently. Foo's ghost is suddenly drawn into its former body! The human is resurrected! and subsequently the monster is just a generic human (or elf, etc) without anything indicating it used to be a player. With this change, the monster will retain the name that the ghost had, and its struct ebones prevents the player from renaming it. This commit also adjusts the "resurrected" message to explicitly use the monster's name if it has one, and to use YMonnam in the unrelated case where the monster was a pet (so reviving an unnamed tame kitten will print as "Your kitten is resurrected!") --- src/zap.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/zap.c b/src/zap.c index 3e578fbee..dca9a97c0 100644 --- a/src/zap.c +++ b/src/zap.c @@ -892,6 +892,10 @@ revive(struct obj *corpse, boolean by_hero) mmflags_nht mmflags = NO_MINVENT | MM_NOWAIT | MM_NOMSG; int montype, cgend, container_nesting = 0; boolean is_zomb; + /* normally use the name on the corpse object, but don't if drawing a + * player's ghost back into its body, in which case use the ghost's + * (player's) name */ + boolean use_corpse_name = TRUE; if (corpse->otyp != CORPSE) { impossible("Attempting to revive %s?", xname(corpse)); @@ -1085,6 +1089,16 @@ revive(struct obj *corpse, boolean by_hero) mtmp->mtame = ghost->mtame; } } + /* copy over ghost's name and struct ebones to newly revived "hero"; + * has_mgivenname should always be true because there are guards + * against renaming a ghost, but check it just to be sure */ + if (has_mgivenname(ghost)) { + mtmp = christen_monst(mtmp, MGIVENNAME(ghost)); + /* don't let player-provided name of corpse override actual + * name of ex-hero */ + use_corpse_name = FALSE; + } + copy_mextra(mtmp, ghost); /* pass on struct ebones */ /* was ghost, now alive, it's all very confusing */ mtmp->mconf = 1; /* separate ghost monster no longer exists */ @@ -1094,7 +1108,7 @@ revive(struct obj *corpse, boolean by_hero) } /* monster retains its name */ - if (has_oname(corpse) && !unique_corpstat(mtmp->data)) + if (use_corpse_name && has_oname(corpse) && !unique_corpstat(mtmp->data)) mtmp = christen_monst(mtmp, ONAME(corpse)); /* partially eaten corpse yields wounded monster */ if (corpse->oeaten) @@ -2357,7 +2371,7 @@ bhito(struct obj *obj, struct obj *otmp) if (cansee(ox, oy)) { if (canspotmon(mtmp)) { pline("%s is resurrected!", - upstart(noname_monnam(mtmp, ARTICLE_THE))); + mtmp->mtame ? YMonnam(mtmp) : Monnam(mtmp)); learn_it = by_u ? TRUE : gz.zap_oseen; } else { /* saw corpse but don't see monster: maybe From 1fa60f75368f7866ebd934e99ee0ea31b0ca7c3a Mon Sep 17 00:00:00 2001 From: nhkeni Date: Sun, 21 Jun 2026 14:10:51 -0400 Subject: [PATCH 501/702] Add a new T-shift slogan. --- src/read.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/read.c b/src/read.c index f6aa5744a..27b2ab588 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 5.0 read.c $NHDT-Date: 1781973063 2026/06/20 16:31:03 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.333 $ */ +/* NetHack 5.0 read.c $NHDT-Date: 1782083451 2026/06/21 18:10:51 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.334 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -180,6 +180,7 @@ tshirt_text(struct obj *tshirt, char *buf) from book series _A_Song_of_Ice_and_Fire_ by George R.R. Martin, TV show "Game of Thrones" (probably an actual T-shirt too...) */ "/Valar morghulis/ -- /Valar dohaeris/", + "Asidonhopo once said: the namesake of my enemy is my enemy", }; Strcpy(buf, shirt_msgs[tshirt->o_id % SIZE(shirt_msgs)]); From e6b5338441530f63d65ab8e93904f057cc67edee Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 21 Jun 2026 14:18:00 -0400 Subject: [PATCH 502/702] some windows build updates --- sys/windows/Install.windows | 7 +++--- sys/windows/build-nmake.txt | 45 +++++++++++++++++-------------------- sys/windows/fetch.cmd | 45 +++++++++++++++++++++++-------------- 3 files changed, 53 insertions(+), 44 deletions(-) diff --git a/sys/windows/Install.windows b/sys/windows/Install.windows index 207ec5f5d..cff81c687 100644 --- a/sys/windows/Install.windows +++ b/sys/windows/Install.windows @@ -4,7 +4,7 @@ NetHack may be freely redistributed. See license for details. Instructions for compiling NetHack 5.0 on a Windows system (only tested on Windows 10/11 or later) ============================================================== -Last revision: $NHDT-Date: 1594155895 2020/07/07 21:04:55 $ +Last revision: $NHDT-Date: 1782065703 2026/06/21 18:15:03 $ See file dat\History for credits and history of NetHack for Windows. @@ -12,8 +12,9 @@ See file dat\History for credits and history of NetHack for Windows. | Download a prebuilt package of NetHack for Windows from NetHack.org | \----------------------------------------------------------- -----------/ - FIXME: - + In your web browser, navigate to + https://www.nethack.org/v500/ports/download-win.html + and follow the instructions there. /-----------------------------------------------------------------------\ | Build and package NetHack for Windows yourself | diff --git a/sys/windows/build-nmake.txt b/sys/windows/build-nmake.txt index b564d20fb..f96dd769e 100644 --- a/sys/windows/build-nmake.txt +++ b/sys/windows/build-nmake.txt @@ -6,23 +6,7 @@ Prerequisite Requirements: A copy of Microsoft Visual Studio Community needs to be installed on your machine. See: https://visualstudio.microsoft.com/vs/community/ - o Lua - NetHack 5.0 for Windows requires 3rd party Lua source that is not part - of the NetHack distribution or repository. - A windows cmd command procedure for fetching prerequisite sources - is available, and can be run as follows from the top of the - NetHack source tree to obtain lua: - sys\windows\fetch.cmd lua - o pdcursesmod (Only required if curses interface support is desired) - If you want to include curses interface support in NetHack 5.0 for - 3rd part pdcursesmod source code is required and is not part of the - NetHack distribution or repository. - - A windows cmd command procedure for fetching prerequisite - sources is available, and can be run as follows from the top of - the NetHack source tree to obtain pdcursesmod: - sys\windows\fetch.cmd pdcursesmod The build Makefiles and procedures produce two executables: a. A TTY and curses version of NetHack in nethack.exe @@ -44,9 +28,9 @@ You can use one of the following build environments: | | | | | | | | | | | | | | | | lua-5.4.8 pdcursesmod share windows tty win32 lua pdcursesmod - | - vs - | + | + vs + | +----------+-------+--------+--------+-----------+-------+-----+------+ | | | | | | | | | makedefs NetHack NetHackW PDCurses PDCursesGui tile2bmp tilemap tiles uudecode @@ -99,19 +83,32 @@ Setting Up source tree, if you are at the top of the NetHack source tree. cd sys\windows. -2. Execute .\nhsetup.bat to place copies of the Makefiles in +2. Execute + .\nhsetup.bat + to place copies of the Makefiles in the src subfolder. The file sys\windows\Makefile.nmake will copied to a file src\Makefile. .\nhsetup.bat +3. Execute + .\fetch.bat lua + to place a copy of Lua into the lib subfolder of the NetHack source + tree. NetHack 5.0 for Windows requires 3rd party Lua source that is not part + of the NetHack distribution or repository. -3. Change your current directory to the src subfolder of the nethack +4. If you want to include support of the optional curses interface in your + build, execute + .\fetch.cmd pdcursesmod + to place a copy pdcursesmod into the lib subfolder of the NetHack + tree. + +5. Change your current directory to the src subfolder of the nethack source tree. The following command assumes you are still in the sys\windows folder from steps #1 and #2 above: cd ..\..\src Compiling -4. Now that everything is set up, you should be ready to start the +6. Now that everything is set up, you should be ready to start the process. Your current directory should be the NetHack src directory. @@ -125,13 +122,13 @@ Compiling Notes: -1. To rebuild NetHack after changing something, change your current directory +N1. To rebuild NetHack after changing something, change your current directory to src and issue the appropriate command for your compiler: For Microsoft compiler: nmake package -2. Depending on the build and compiler and tools used above, the +N2. Depending on the build and compiler and tools used above, the package produced by the build will be either contain: - a 32-bit (x86) .exe file, which should run on any recent Win32 environment. diff --git a/sys/windows/fetch.cmd b/sys/windows/fetch.cmd index a508ad8dc..4df517a24 100644 --- a/sys/windows/fetch.cmd +++ b/sys/windows/fetch.cmd @@ -1,30 +1,41 @@ -@echo off -if not exist lib\* mkdir lib +@echo on + +if exist %cd%\..\sys\windows\Makefile.nmake set LIBDIR=..\lib +if exist %cd%\Makefile.nmake set LIBDIR=..\..\lib +if exist %cd%\sys\windows\Makefile.nmake set LIBDIR=lib + +set LUA_VERSION=5.4.8 +set LUASRC=%LIBDIR%/lua +set CURLLUASRC=http://www.lua.org/ftp/lua-%LUA_VERSION%.tar.gz +set CURLLUADST=lua-%LUA_VERSION%.tar.gz + +set PDCVERSION=4.5.4 +set CURLPDCSRC=https://github.com/Bill-Gray/PDCursesMod/archive/refs/tags/v%PDCVERSION%.zip +set CURLPDCDST=pdcursesmod.zip + +:proceed + +if not exist %LIBDIR%\* mkdir lib if [%1] == [lua] ( - set LUA_VERSION=5.4.8 - set LUASRC=../lib/lua - set CURLLUASRC=http://www.lua.org/ftp/lua-%LUA_VERSION%.tar.gz - set CURLLUADST=lua-%LUA_VERSION%.tar.gz - if NOT exist lib/lua.h ( - cd lib + if NOT exist %LIBDIR%\lua.h ( + pushd %LIBDIR% curl -L %CURLLUASRC% -o %CURLLUADST% tar -xvf %CURLLUADST% - cd .. + popd ) - echo Lua placed in lib/lua-%LUA_VERSION%.tar.gz + echo Lua placed in %LIBDIR%\lua-%LUA_VERSION%.tar.gz ) if [%1] == [pdcursesmod] ( - set PDCVERSION=4.4.0 - set CURLPDCSRC=https://github.com/Bill-Gray/PDCursesMod/archive/refs/tags/v%PDCVERSION%.zip - set CURLPDCDST=pdcursesmod.zip - if NOT exist lib/pdcursesmod/curses.h ( - cd lib + if NOT exist %LIBDIR%\pdcursesmod\curses.h ( + pushd %LIBDIR% curl -L %CURLPDCSRC% -o %CURLPDCDST% - tar -xvf %CURLPDCDST% mkdir pdcursesmod tar -C pdcursesmod --strip-components=1 -xvf %CURLPDCDST% - cd .. + popd ) + echo pdcursesmod placed in %LIBDIR%\pdcursesmod ) + +:done From f119ab3dcf8559db9af496bcc9fad65393088748 Mon Sep 17 00:00:00 2001 From: JodiJodington <193165323+JodiJodington@users.noreply.github.com> Date: Tue, 23 Jun 2026 11:44:31 -0500 Subject: [PATCH 503/702] made it so the drop button in herecmdmenu does a multi-drop --- src/cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd.c b/src/cmd.c index 882a371ca..e51bf159f 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -4805,7 +4805,7 @@ act_on_act( cmdq_add_key(CQ_CANNED, 'y'); /* "There is foo here; eat it?" */ break; case MCMD_DROP: - cmdq_add_ec(CQ_CANNED, dodrop); + cmdq_add_ec(CQ_CANNED, doddrop); break; case MCMD_INVENTORY: cmdq_add_ec(CQ_CANNED, ddoinv); From 2c58864b1c8c7f20df0863c24178019bd7b8e5f4 Mon Sep 17 00:00:00 2001 From: nhkeni Date: Tue, 23 Jun 2026 19:14:54 -0400 Subject: [PATCH 504/702] CRASHREPORTURL should have been updated at 5.0.0 release --- doc/Guidebook.mn | 6 +++--- doc/Guidebook.tex | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 28e9e7fad..88600fef7 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.614 $ $NHDT-Date: 1770881338 2026/02/11 23:28:58 $ +.\" $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.652 $ $NHDT-Date: 1782274458 2026/06/23 23:14:18 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\"+-- @@ -60,7 +60,7 @@ .ds f0 \*(vr .ds f1 \" empty .\"DO NOT REMOVE NH_DATESUB .ds f2 Date(%B %-d, %Y) -.ds f2 May 29, 2026 +.ds f2 June 23, 2026 . .\" A note on some special characters: .\" \(lq = left double quote @@ -6387,7 +6387,7 @@ large unless it is actively maintained. . .lp CRASHREPORTURL\ =\ If set to -\f(CRhttps://www.nethack.org/links/cr-37BETA.html\fP +\f(CRhttps://www.nethack.org/links/cr-5.0.0.html\fP and support is compiled in, brings up a browser window pre-populated with the information needed to report a problem if the game panics or ends up in an internally inconsistent state, or if the #bugreport command is diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index e6d0aa2ca..97cbb1bdf 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -1,4 +1,4 @@ -% NetHack 5.0 Guidebook.tex $NHDT-Date: 1770881338 2026/02/11 23:28:58 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.596 $ */ +% NetHack 5.0 Guidebook.tex $NHDT-Date: 1782274458 2026/06/23 23:14:18 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.630 $ */ \documentclass[titlepage]{article} \usepackage[hidelinks]{hyperref} \usepackage{longtable} @@ -25,7 +25,7 @@ \author{Original version - Eric S. Raymond\\ (Edited and expanded for 5.0.0 by Mike Stephenson and others)} %DO NOT REMOVE NH_DATESUB \date{Date(%B %-d, %Y)} -\date{May 29, 2026} +\date{June 23, 2026} \maketitle @@ -7010,7 +7010,7 @@ large unless it is actively maintained. %.lp \item[CRASHREPORTURL] If set to -\url{https://www.nethack.org/links/cr-37BETA.html} +\url{https://www.nethack.org/links/cr-5.0.0.html} and support is compiled in, brings up a browser window populated with the information needed to report a problem if the game panics or ends up in an internally inconsistent state, or if the \#bugreport command is From e381605bbaf7342860324bf5196016a6140e1a65 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Tue, 23 Jun 2026 14:52:16 -0400 Subject: [PATCH 505/702] Remove wintype.h include from hack.h Removed unnecessary second include for wintype.h --- include/hack.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/hack.h b/include/hack.h index 4a4b7f9fa..58bedc19a 100644 --- a/include/hack.h +++ b/include/hack.h @@ -38,7 +38,6 @@ #include "sys.h" #include "timeout.h" #include "winprocs.h" -#include "wintype.h" #include "vision.h" #include "you.h" From 5911ee19d02662e53f68b4aac935a08cd870d488 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Tue, 23 Jun 2026 19:16:08 -0400 Subject: [PATCH 506/702] This is cron-daily v1-May-7-2026. 005guidebook updated: doc/Guidebook.txt --- doc/Guidebook.txt | 240 +++++++++++++++++++++++----------------------- 1 file changed, 120 insertions(+), 120 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index de1b25558..96803add8 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for NetHack 5.0.0 by Mike Stephenson and others) - May 29, 2026 + June 23, 2026 @@ -126,7 +126,7 @@ employ to great advantage. - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -192,7 +192,7 @@ NetHack continues this fine tradition. Unlike text adventure games - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -258,7 +258,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -324,7 +324,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -390,7 +390,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -456,7 +456,7 @@ The number of turns elapsed so far, displayed if you have the - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -522,7 +522,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -588,7 +588,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -654,7 +654,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -720,7 +720,7 @@ instead. Only these one-step movement commands cause you to - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -786,7 +786,7 @@ ing . ^ is used as shorthand elsewhere in the - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -852,7 +852,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -918,7 +918,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -984,7 +984,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -1050,7 +1050,7 @@ at an adjacent "remembered, unseen monster" marker. - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -1116,7 +1116,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -1182,7 +1182,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -1248,7 +1248,7 @@ (R)UNIX is a registered trademark of The Open Group. - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -1314,7 +1314,7 @@ inventory slot. If it has a name assigned, other stacks with the - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -1380,7 +1380,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -1446,7 +1446,7 @@ fight there. Default key is `F', or `-' with number_pad - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -1512,7 +1512,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -1578,7 +1578,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -1644,7 +1644,7 @@ Pick up things at the current location. Default key is `,'. The - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -1710,7 +1710,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -1776,7 +1776,7 @@ worn. - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -1842,7 +1842,7 @@ Suspend the game, switching from NetHack to the terminal it was - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -1908,7 +1908,7 @@ pick one from inventory, except for the special case of - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -1974,7 +1974,7 @@ menu of sorting orders available (provided that the vanquished - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -2040,7 +2040,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -2106,7 +2106,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -2172,7 +2172,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -2238,7 +2238,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -2304,7 +2304,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -2370,7 +2370,7 @@ them). Some monsters who can open doors can also use unlocking tools. - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -2436,7 +2436,7 @@ been nullified, giving access to whatever is beyond them. In the - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -2502,7 +2502,7 @@ play. - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -2568,7 +2568,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -2634,7 +2634,7 @@ attack, when guessing where an unseen monster is or when deliberately - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -2700,7 +2700,7 @@ noid_confirmation:attack option to require a response of "yes" - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -2766,7 +2766,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -2832,7 +2832,7 @@ are encumbered, one of the conditions Burdened, Stressed, Strained, - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -2898,7 +2898,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -2964,7 +2964,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -3030,7 +3030,7 @@ aklys, lucern hammer, and bec-de-corbin) are defined in an appendix to - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -3096,7 +3096,7 @@ shots by using a numeric prefix before the `t' or `f' command. For - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -3162,7 +3162,7 @@ first you need to have a weapon in each hand. (Note that your two - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -3228,7 +3228,7 @@ even further. Most of these provide a one or two point improvement to - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -3294,7 +3294,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -3360,7 +3360,7 @@ yourself (just give a `.' or `s' for the direction). Be warned, how- - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -3426,7 +3426,7 @@ your ken can be harmful to your health! - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -3492,7 +3492,7 @@ play the entire game without being able to see (a self-imposed chal- - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -3558,7 +3558,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -3624,7 +3624,7 @@ set the goldX option if you prefer to have gold pieces be treated as - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -3690,7 +3690,7 @@ eating such items still counts against foodless conduct. - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -3756,7 +3756,7 @@ monster (i.e. if you would get experience for the death). This is a - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -3822,7 +3822,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -3888,7 +3888,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -3954,7 +3954,7 @@ ning NetHack for the first time, you should find a default template - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -4020,7 +4020,7 @@ [not available on Unix] - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -4086,7 +4086,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -4152,7 +4152,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -4218,7 +4218,7 @@ be set to the full name of a configuration file you want to use. If - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -4284,7 +4284,7 @@ Automatically dig if you are wielding a digging tool and moving into - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -4350,7 +4350,7 @@ nearby monsters. Successfully forcing a container open will break - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -4416,7 +4416,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -4482,7 +4482,7 @@ extended command, it controls whether the menu shows all available - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -4548,7 +4548,7 @@ might miss some interesting and/or important information. Persis- - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -4614,7 +4614,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -4680,7 +4680,7 @@ class(es). Combination starts with a prompt for object class(es) of - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -4746,7 +4746,7 @@ 5 - One-or-other - show symbols on headers, or on entries if no - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -4812,7 +4812,7 @@ port is the same as specifying 0. - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -4878,7 +4878,7 @@ ing 1 and negating number_pad is the same as specifying 0. (Set- - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -4944,7 +4944,7 @@ `y', set Confirm too); - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -5010,7 +5010,7 @@ ing pets on the map. Effectively a superset of the hilite_pet bool- - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -5076,7 +5076,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -5142,7 +5142,7 @@ game). This option exists partly as an acknowledgement that some - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -5208,7 +5208,7 @@ sistent. - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -5274,7 +5274,7 @@ Controls the sorting behavior for the output of the `\' and ``' com- - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -5340,7 +5340,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -5406,7 +5406,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -5472,7 +5472,7 @@ targets. - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -5538,7 +5538,7 @@ currently using by checking to see if it shows up in the Options list. - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -5604,7 +5604,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -5670,7 +5670,7 @@ this option. - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -5736,7 +5736,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -5802,7 +5802,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -5868,7 +5868,7 @@ hang if this is turned on. Cannot be set with the `O' command. - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -5934,7 +5934,7 @@ you can define patterns to be checked when the game is about to - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -6000,7 +6000,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -6066,7 +6066,7 @@ When asked for a location, the key to go to next closest door or - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -6132,7 +6132,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -6198,7 +6198,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -6264,7 +6264,7 @@ ple MENUCOLOR entries in your configuration file, and the last MENU- - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -6330,7 +6330,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -6396,7 +6396,7 @@ depending upon your other option settings. - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -6462,7 +6462,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -6528,7 +6528,7 @@ value, and the ^ prefix causes the following character to be treated - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -6594,7 +6594,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -6660,7 +6660,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -6726,7 +6726,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -6792,7 +6792,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -6858,7 +6858,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -6924,7 +6924,7 @@ seen via the "#attributes" command. - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -6990,7 +6990,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -7047,7 +7047,7 @@ extremely large unless it is actively maintained. CRASHREPORTURL = If set to - https://www.nethack.org/links/cr-37BETA.html and support is compiled + https://www.nethack.org/links/cr-5.0.0.html and support is compiled in, brings up a browser window pre-populated with the information needed to report a problem if the game panics or ends up in an internally inconsistent state, or if the #bugreport command is @@ -7056,7 +7056,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -7122,7 +7122,7 @@ connection between "wizard mode" and the Wizard role). Attempting to - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -7188,7 +7188,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -7254,7 +7254,7 @@ were distinct for specific types of monsters and objects rather than - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -7320,7 +7320,7 @@ file layout which prevented score entries from being read back in cor- - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -7386,7 +7386,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -7452,7 +7452,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -7518,7 +7518,7 @@ changes and new features almost immediately, and they often did. The - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -7584,7 +7584,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -7650,7 +7650,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -7716,7 +7716,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -7782,7 +7782,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 @@ -7848,7 +7848,7 @@ - NetHack 5.0.0 May 29, 2026 + NetHack 5.0.0 June 23, 2026 From 164c057d5fcfcceda3c1bfa509b0b5d866482619 Mon Sep 17 00:00:00 2001 From: JodiJodington <193165323+JodiJodington@users.noreply.github.com> Date: Wed, 24 Jun 2026 12:16:37 -0500 Subject: [PATCH 507/702] added a pray button to herecmdmenu --- src/cmd.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cmd.c b/src/cmd.c index e51bf159f..d29e16fb0 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -4407,6 +4407,7 @@ enum menucmd { MCMD_REST, MCMD_LOOK_HERE, MCMD_LOOK_AT, + MCMD_PRAY, MCMD_ATTACK_NEXT2U, MCMD_UNTRAP_HERE, MCMD_OFFER, @@ -4507,6 +4508,7 @@ there_cmd_menu_self(winid win, coordxy x, coordxy y, int *act UNUSED) mcmd_addmenu(win, MCMD_REST, "Rest one turn"), ++K; mcmd_addmenu(win, MCMD_SEARCH, "Search around you"), ++K; mcmd_addmenu(win, MCMD_LOOK_HERE, "Look at what is here"), ++K; + mcmd_addmenu(win, MCMD_PRAY, "Pray here"), ++K; if (num_spells() > 0) mcmd_addmenu(win, MCMD_CAST_SPELL, "Cast a spell"), ++K; @@ -4821,6 +4823,9 @@ act_on_act( gc.clicklook_cc.y = u.uy + dy; cmdq_add_ec(CQ_CANNED, doclicklook); break; + case MCMD_PRAY: + cmdq_add_ec(CQ_CANNED, dopray); + break; case MCMD_UNTRAP_HERE: cmdq_add_ec(CQ_CANNED, dountrap); cmdq_add_dir(CQ_CANNED, 0, 0, 1); From 06436b69d3b331fa201158b4935f334e94f8d524 Mon Sep 17 00:00:00 2001 From: JodiJodington <193165323+JodiJodington@users.noreply.github.com> Date: Wed, 24 Jun 2026 12:17:00 -0500 Subject: [PATCH 508/702] added an engrave button to herecmdmenu --- src/cmd.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cmd.c b/src/cmd.c index d29e16fb0..24ed07c65 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -4408,6 +4408,7 @@ enum menucmd { MCMD_LOOK_HERE, MCMD_LOOK_AT, MCMD_PRAY, + MCMD_ENGRAVE, MCMD_ATTACK_NEXT2U, MCMD_UNTRAP_HERE, MCMD_OFFER, @@ -4509,6 +4510,7 @@ there_cmd_menu_self(winid win, coordxy x, coordxy y, int *act UNUSED) mcmd_addmenu(win, MCMD_SEARCH, "Search around you"), ++K; mcmd_addmenu(win, MCMD_LOOK_HERE, "Look at what is here"), ++K; mcmd_addmenu(win, MCMD_PRAY, "Pray here"), ++K; + mcmd_addmenu(win, MCMD_ENGRAVE, "Engrave here"), ++K; if (num_spells() > 0) mcmd_addmenu(win, MCMD_CAST_SPELL, "Cast a spell"), ++K; @@ -4826,6 +4828,9 @@ act_on_act( case MCMD_PRAY: cmdq_add_ec(CQ_CANNED, dopray); break; + case MCMD_ENGRAVE: + cmdq_add_ec(CQ_CANNED, doengrave); + break; case MCMD_UNTRAP_HERE: cmdq_add_ec(CQ_CANNED, dountrap); cmdq_add_dir(CQ_CANNED, 0, 0, 1); From 3574a99d3583c929119a0f85c205617e2b643da5 Mon Sep 17 00:00:00 2001 From: JodiJodington <193165323+JodiJodington@users.noreply.github.com> Date: Wed, 24 Jun 2026 10:03:53 -0500 Subject: [PATCH 509/702] added a jump button to herecmdmenu --- src/cmd.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cmd.c b/src/cmd.c index 24ed07c65..84cf9a263 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -4414,6 +4414,7 @@ enum menucmd { MCMD_OFFER, MCMD_INVENTORY, MCMD_CAST_SPELL, + MCMD_JUMP, MCMD_THROW_OBJ, MCMD_TRAVEL, @@ -4520,6 +4521,9 @@ there_cmd_menu_self(winid win, coordxy x, coordxy y, int *act UNUSED) mcmd_addmenu(win, MCMD_UNTRAP_HERE, "Attempt to disarm trap"), ++K; } + if (Jumping) { + mcmd_addmenu(win, MCMD_JUMP, "Jump"), ++K; + } return K; } @@ -4842,6 +4846,8 @@ act_on_act( case MCMD_CAST_SPELL: cmdq_add_ec(CQ_CANNED, docast); break; + case MCMD_JUMP: + cmdq_add_ec(CQ_CANNED, dojump); default: break; } From 8c3a553f4bb5de9eb6235f9317d001ad0d091d0a Mon Sep 17 00:00:00 2001 From: JodiJodington <193165323+JodiJodington@users.noreply.github.com> Date: Wed, 24 Jun 2026 10:04:27 -0500 Subject: [PATCH 510/702] added an attributes button to herecmdmenu --- src/cmd.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cmd.c b/src/cmd.c index 84cf9a263..8f9459b3f 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -4409,6 +4409,7 @@ enum menucmd { MCMD_LOOK_AT, MCMD_PRAY, MCMD_ENGRAVE, + MCMD_ATTRIBUTES, MCMD_ATTACK_NEXT2U, MCMD_UNTRAP_HERE, MCMD_OFFER, @@ -4512,6 +4513,7 @@ there_cmd_menu_self(winid win, coordxy x, coordxy y, int *act UNUSED) mcmd_addmenu(win, MCMD_LOOK_HERE, "Look at what is here"), ++K; mcmd_addmenu(win, MCMD_PRAY, "Pray here"), ++K; mcmd_addmenu(win, MCMD_ENGRAVE, "Engrave here"), ++K; + mcmd_addmenu(win, MCMD_ATTRIBUTES, "View attributes"), ++K; if (num_spells() > 0) mcmd_addmenu(win, MCMD_CAST_SPELL, "Cast a spell"), ++K; @@ -4835,6 +4837,9 @@ act_on_act( case MCMD_ENGRAVE: cmdq_add_ec(CQ_CANNED, doengrave); break; + case MCMD_ATTRIBUTES: + cmdq_add_ec(CQ_CANNED, doattributes); + break; case MCMD_UNTRAP_HERE: cmdq_add_ec(CQ_CANNED, dountrap); cmdq_add_dir(CQ_CANNED, 0, 0, 1); From ae011af0265f35967efc39933e8ce4d8d0a4dce6 Mon Sep 17 00:00:00 2001 From: JodiJodington <193165323+JodiJodington@users.noreply.github.com> Date: Wed, 24 Jun 2026 13:11:20 -0500 Subject: [PATCH 511/702] added a button that shows previous messages to herecmdmenu --- src/cmd.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cmd.c b/src/cmd.c index 8f9459b3f..5eda97b99 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -4410,6 +4410,7 @@ enum menucmd { MCMD_PRAY, MCMD_ENGRAVE, MCMD_ATTRIBUTES, + MCMD_PREVIOUS_MESSAGES, MCMD_ATTACK_NEXT2U, MCMD_UNTRAP_HERE, MCMD_OFFER, @@ -4514,6 +4515,7 @@ there_cmd_menu_self(winid win, coordxy x, coordxy y, int *act UNUSED) mcmd_addmenu(win, MCMD_PRAY, "Pray here"), ++K; mcmd_addmenu(win, MCMD_ENGRAVE, "Engrave here"), ++K; mcmd_addmenu(win, MCMD_ATTRIBUTES, "View attributes"), ++K; + mcmd_addmenu(win, MCMD_PREVIOUS_MESSAGES, "Access memories"), ++K; if (num_spells() > 0) mcmd_addmenu(win, MCMD_CAST_SPELL, "Cast a spell"), ++K; @@ -4840,6 +4842,9 @@ act_on_act( case MCMD_ATTRIBUTES: cmdq_add_ec(CQ_CANNED, doattributes); break; + case MCMD_PREVIOUS_MESSAGES: + cmdq_add_key(CQ_CANNED, C('p')); + break; case MCMD_UNTRAP_HERE: cmdq_add_ec(CQ_CANNED, dountrap); cmdq_add_dir(CQ_CANNED, 0, 0, 1); From e3407a923f171ab884651c233d33035b64a64a78 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 26 Jun 2026 12:30:36 -0400 Subject: [PATCH 512/702] address some compiler complaints --- include/optlist.h | 4 ++++ src/cmd.c | 3 ++- src/makemon.c | 2 +- src/mon.c | 6 +++--- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/include/optlist.h b/include/optlist.h index 67ace7b32..a8c93ecd1 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -363,11 +363,15 @@ static int optfn_##a(int, int, boolean, char *, char *); NHOPTB(herecmd_menu, Advanced, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &iflags.herecmd_menu, Term_False, "show commands available in this location") +#if 0 +/* there is no optfn_hicolor() defined in options.c presently + and that is required for NHOPTC */ #if defined(MAC68K) NHOPTC(hicolor, Advanced, 15, opt_in, set_in_config, No, Yes, No, No, NoAlias, "same as palette, only order is reversed") #endif +#endif /* 0 */ NHOPTB(hilite_pet, Map, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &iflags.wc_hilite_pet, Term_False, "use highlight for pets") diff --git a/src/cmd.c b/src/cmd.c index 882a371ca..77fcdc6b8 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -2493,7 +2493,8 @@ handler_change_autocompletions(void) if (strlen(ec->ef_txt) < 2) continue; - Sprintf(buf, "%s", ec->ef_txt); + /* switched to Snprintf to eliminate -Wformat-overflow warning */ + Snprintf(buf, sizeof buf, "%s", ec->ef_txt); for (j = 0; j < n; ++j) { if (ec == &extcmdlist[(picks[j].item.a_int - 1)]) { diff --git a/src/makemon.c b/src/makemon.c index 18fb3bff1..d0c540e92 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1681,7 +1681,7 @@ rndmonst_adj(int minadj, int maxadj) if (montooweak(mndx, minmlev) || montoostrong(mndx, maxmlev)) continue; - if (upper && !isupper(monsym(ptr))) + if (upper && !isupper((int) monsym(ptr))) continue; if (elemlevel && wrong_elem_type(ptr)) continue; diff --git a/src/mon.c b/src/mon.c index 3e86cb730..f04e2418c 100644 --- a/src/mon.c +++ b/src/mon.c @@ -4868,7 +4868,7 @@ pick_animal(void) /* rogue level should use monsters represented by uppercase letters only, but since chameleons aren't generated there (not uppercase!) we don't perform a lot of retries */ - if (Is_rogue_level(&u.uz) && !isupper(monsym(&mons[res]))) + if (Is_rogue_level(&u.uz) && !isupper((int) monsym(&mons[res]))) res = ga.animal_list[rn2(ga.animal_list_count)]; return res; } @@ -5224,7 +5224,7 @@ select_newcham_form(struct monst *mon) } while (--tryct > 0 && !validspecmon(mon, mndx) /* try harder to select uppercase monster on rogue level */ && (tryct > 40 && Is_rogue_level(&u.uz) - && !isupper(monsym(&mons[mndx])))); + && !isupper((int) monsym(&mons[mndx])))); } return mndx; } @@ -5334,7 +5334,7 @@ newcham( /* for the first several tries we require upper-case on the rogue level (after that, we take whatever we get) */ if (tryct > 15 && Is_rogue_level(&u.uz) - && mdat && !isupper(monsym(mdat))) + && mdat && !isupper((int) monsym(mdat))) mdat = 0; if (mdat) break; From c40bf4658dbece58e1fecd9c7b88890da079f676 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 26 Jun 2026 14:56:26 -0400 Subject: [PATCH 513/702] more warning cleanup The use of strncat and eos(buf) together was odd anyway. --- src/options.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/options.c b/src/options.c index e9c576399..f3e7c3fdd 100644 --- a/src/options.c +++ b/src/options.c @@ -3033,8 +3033,8 @@ optfn_paranoid_confirmation( " %s", paranoia[i].argname); } /* note: always leaves enough room for caller to tack on '\n' */ - opts[0] = '\0'; - (void) strncat(opts, tmpbuf[0] ? &tmpbuf[1] : "none", BUFSZ - 1); + Snprintf(opts, BUFSZ - 1, "%s", + tmpbuf[0] ? &tmpbuf[1] : "none"); return optn_ok; } if (req == do_handler) { @@ -8965,9 +8965,10 @@ doset(void) /* changing options via menu by Per Liboriussen */ getlin(buf, abuf); if (abuf[0] == '\033') continue; - Sprintf(buf, "%s:", allopt[opt_indx].name); - (void) strncat(eos(buf), abuf, - (sizeof buf - 1 - strlen(buf))); + Snprintf(buf, sizeof buf, + "%s:%s", + allopt[opt_indx].name, + abuf); /* pass the buck */ (void) parseoptions(buf, FALSE, FALSE); } From 2b2f949484a82bec0c0af0e4a0e080b0ac64d6e1 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 26 Jun 2026 15:11:42 -0400 Subject: [PATCH 514/702] address another warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sounds.c: In function ‘domonnoise’: sounds.c:818:40: warning: array subscript [0, 1] is outside array bounds of ‘const char * const[2]’ [-Warray-bounds=] 818 | verbl_msg = vampmsg[vampindex]; | ~~~~~~~^~~~~~~~~~~ sounds.c:786:38: note: while referencing ‘vampmsg’ 786 | static const char *const vampmsg[] = { | ^~~~~~~ --- src/sounds.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sounds.c b/src/sounds.c index aedf619d7..4fcd1c9de 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -814,8 +814,10 @@ domonnoise(struct monst *mtmp) flags.female ? FEMALE : MALE)) : an(racenoun)); verbl_msg = verbuf; - } else - verbl_msg = vampmsg[vampindex]; + } else if (vampindex > 1) { + if (vampindex >= 0 && vampindex < SIZE(vampmsg)) + verbl_msg = vampmsg[vampindex]; + } } } break; From 6fee8a4e789ed54ba805aaf09d4450f05a80a91f Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 26 Jun 2026 15:21:19 -0400 Subject: [PATCH 515/702] yet another warning bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In file included from ../include/hack.h:34, from sp_lev.c:14: In function ‘create_monster’, inlined from ‘lspo_monster’ at sp_lev.c:3386:5: ../include/rm.h:528:32: warning: array subscript -1 is below array bounds of ‘struct monst *[80][21]’ [-Warray-bounds=] 528 | if (!svl.level.monsters[x][y]) \ | ~~~~~~~~~~~~~~~~~~^~~ sp_lev.c:2045:25: note: in expansion of macro ‘remove_monster’ 2045 | remove_monster(x, y); | ^~~~~~~~~~~~~~ ../include/rm.h: In function ‘lspo_monster’: ../include/rm.h:476:19: note: while referencing ‘monsters’ 476 | struct monst *monsters[COLNO][ROWNO]; | ^~~~~~~~ In function ‘create_monster’, inlined from ‘lspo_monster’ at sp_lev.c:3386:5: ../include/rm.h:530:27: warning: array subscript -1 is below array bounds of ‘struct monst *[80][21]’ [-Warray-bounds=] 530 | svl.level.monsters[x][y] = (struct monst *) 0; \ | ~~~~~~~~~~~~~~~~~~^~~ sp_lev.c:2045:25: note: in expansion of macro ‘remove_monster’ 2045 | remove_monster(x, y); | ^~~~~~~~~~~~~~ ../include/rm.h: In function ‘lspo_monster’: ../include/rm.h:476:19: note: while referencing ‘monsters’ 476 | struct monst *monsters[COLNO][ROWNO]; | ^~~~~~~~ --- src/sp_lev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sp_lev.c b/src/sp_lev.c index 496962ae2..163a68925 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -2042,7 +2042,8 @@ create_monster(monster *m, struct mkroom *croom) && m_bad_boulder_spot(x, y)) { int retrylimit = 10; - remove_monster(x, y); + if (x >= 0) + remove_monster(x, y); do { x = m->x; y = m->y; From ac3d71a82a8a6e006eb1338aad85090ebf5514e3 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 27 Jun 2026 11:18:44 -0400 Subject: [PATCH 516/702] give player an inkling of why corpses didn't stack When corpses haven't stacked, and there is no player-discernable reason why, provide some additional information in some cases, but only when it is required. Gender variance is the supported case in this commit. Related to GitHub issue #1607. This commit doesn't change the underlying mechanics to allow the corpses to stack, but it does help the player understand why that's the case in this instance. --- include/decl.h | 3 +++ include/extern.h | 3 +++ include/hack.h | 1 + src/decl.c | 7 ++++++ src/invent.c | 64 +++++++++++++++++++++++++++++++++++++++++++++--- src/objnam.c | 43 ++++++++++++++++++++++++++------ src/pickup.c | 8 ++++-- 7 files changed, 116 insertions(+), 13 deletions(-) diff --git a/include/decl.h b/include/decl.h index 777c25631..70e454f95 100644 --- a/include/decl.h +++ b/include/decl.h @@ -803,6 +803,9 @@ struct instance_globals_p { int poly_zapped; /* new stuff */ + int puzzling_critera; + char puzzling_ilets[invlet_basic + 1]; + boolean havestate; }; diff --git a/include/extern.h b/include/extern.h index 5da653c38..a6043a94e 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1404,6 +1404,7 @@ extern void perm_invent_toggled(boolean negated); extern void prepare_perminvent(winid window); extern struct obj *carrying_stoning_corpse(void); extern void repopulate_perminvent(void); +extern int check_for_puzzling_nonmerge(struct obj *); /* ### ioctl.c ### */ @@ -2236,6 +2237,8 @@ extern boolean the_unique_pm(struct permonst *) NONNULLARG1; extern boolean erosion_matters(struct obj *) NONNULLARG1; extern char *doname(struct obj *) NONNULLARG1; extern char *doname_with_price(struct obj *) NONNULLARG1; +extern char *doname_with_cgender(struct obj *) NONNULLARG1; +extern char *doname_with_price_and_cgender(struct obj *) NONNULLARG1; extern char *doname_vague_quan(struct obj *) NONNULLARG1; extern boolean not_fully_identified(struct obj *) NONNULLARG1; extern char *corpse_xname(struct obj *, const char *, unsigned) NONNULLARG1; diff --git a/include/hack.h b/include/hack.h index 58bedc19a..0d140e8b1 100644 --- a/include/hack.h +++ b/include/hack.h @@ -63,6 +63,7 @@ #define CXN_PFX_THE 4 /* prefix with "the " (unless pname) */ #define CXN_ARTICLE 8 /* include a/an/the prefix */ #define CXN_NOCORPSE 16 /* suppress " corpse" suffix */ +#define CXN_ADDGNDR 32 /* include a gender */ /* number of turns it takes for vault guard to show up */ #define VAULT_GUARD_TIME 30 diff --git a/src/decl.c b/src/decl.c index 365500a72..6263eb708 100644 --- a/src/decl.c +++ b/src/decl.c @@ -648,6 +648,13 @@ static const struct instance_globals_p g_init_p = { UNDEFINED_PTR, /* propellor */ /* zap.c */ UNDEFINED_VALUE, /* poly_zap */ + 0, /* puzzling_criteria */ + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, /* puzzling_ilets[] */ + TRUE, /* havestate*/ }; diff --git a/src/invent.c b/src/invent.c index 347d915cf..b84e05279 100644 --- a/src/invent.c +++ b/src/invent.c @@ -2701,6 +2701,51 @@ count_unidentified(struct obj *objchn) return unid_cnt; } +/* mark the puzzling items */ +int +check_for_puzzling_nonmerge(struct obj *objchn) +{ + int i, k, idx, puzzling_cnt = 0, ilet, mnums[invlet_basic + 1], + gndr[invlet_basic + 1]; + struct obj *obj; + boolean at_least_one = FALSE; + + for (i = 0; i < invlet_basic + 1; ++i) + gp.puzzling_ilets[i] = mnums[i] = gndr[i] = 0; + + + for (obj = objchn; obj; obj = obj->nobj) { + if (obj->otyp == CORPSE + && obj->corpsenm >= 0 && obj->corpsenm < NUMMONS) { + ilet = obj->invlet; + idx = (ilet >= 'A' && ilet <= 'Z') ? ilet - 'A' + : (ilet >= 'a' && ilet <= 'z') ? ilet - 'a' + 26 + : 53; + if (idx < 53) { + mnums[idx] = obj->corpsenm; + gndr[idx] = (obj->spe & CORPSTAT_MALE) ? CORPSTAT_MALE + : CORPSTAT_FEMALE; + at_least_one = TRUE; + } + } + } + if (at_least_one) { + for (i = 0; i < invlet_basic; ++i) { + for (k = i + 1; k < invlet_basic; ++k) { + if (k == i) + continue; + if (mnums[k] == mnums[i] && gndr[k] != gndr[i]) { + ++puzzling_cnt; + gp.puzzling_ilets[i] = gp.puzzling_ilets[k] = 1; + } + } + } + if (puzzling_cnt) + gp.puzzling_critera = 411; + } + return puzzling_cnt; +} + /* dialog with user to identify a given number of items; 0 means all */ void identify_pack( @@ -3064,7 +3109,7 @@ display_pickinv( struct obj *otmp, wizid_fakeobj, inuse_fakeobj; char ilet, ret, *formattedobj; const char *invlet = flags.inv_order; - int n, classcount, inusecount = 0; + int n, classcount, inusecount = 0, puzzling_count = 0; winid win; /* windows being used */ anything any; menu_item *selected; @@ -3212,6 +3257,9 @@ display_pickinv( sortedinvent[0].obj = (struct obj *) 0; } + + puzzling_count = check_for_puzzling_nonmerge(gi.invent); + start_menu(win, menu_behavior); any = cg.zeroany; if (wizid) { @@ -3314,7 +3362,9 @@ display_pickinv( /* normal inventory item */ tmpglyph = obj_to_glyph(otmp, rn2_on_display_rng); map_glyphinfo(0, 0, tmpglyph, 0U, &tmpglyphinfo); - formattedobj = doname(otmp); + formattedobj = !puzzling_count + ? doname(otmp) + : doname_with_cgender(otmp); add_menu(win, &tmpglyphinfo, &any, ilet, wizid ? def_oc_syms[(int) otmp->oclass].sym : 0, ATR_NONE, clr, formattedobj, MENU_ITEMFLAGS_NONE); @@ -4110,6 +4160,7 @@ look_here( picked_some = (lookhere_flags & LOOKHERE_PICKED_SOME) != 0, /* skip 'dfeature' if caller used describe_decor() to show it */ skip_dfeature = (lookhere_flags & LOOKHERE_SKIP_DFEATURE) != 0; + int puzzling_count = 0; /* default pile_limit is 5; a value of 0 means "never skip" (and 1 effectively forces "always skip") */ @@ -4173,6 +4224,7 @@ look_here( } otmp = svl.level.objects[u.ux][u.uy]; + puzzling_count = check_for_puzzling_nonmerge(otmp); dfeature = dfeature_at(u.ux, u.uy, fbuf2); if (dfeature && !strcmp(dfeature, "pool of water") && Underwater) dfeature = 0; @@ -4294,11 +4346,15 @@ look_here( for (; otmp; otmp = otmp->nexthere) { if (otmp->otyp == CORPSE && will_feel_cockatrice(otmp, FALSE)) { felt_cockatrice = TRUE; - Sprintf(buf, "%s...", doname(otmp)); + Sprintf(buf, "%s...", + (puzzling_count) ? doname_with_cgender(otmp) + : doname(otmp)); putstr(tmpwin, 0, buf); break; } - putstr(tmpwin, 0, doname_with_price(otmp)); + putstr(tmpwin, 0, + (puzzling_count) ? doname_with_price_and_cgender(otmp) + : doname_with_price(otmp)); } display_nhwindow(tmpwin, TRUE); destroy_nhwindow(tmpwin); diff --git a/src/objnam.c b/src/objnam.c index d9efc1521..233a84b31 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1214,9 +1214,10 @@ erosion_matters(struct obj *obj) return FALSE; } -#define DONAME_WITH_PRICE 1 -#define DONAME_VAGUE_QUAN 2 -#define DONAME_FOR_MENU 4 /* [not used anywhere yet] */ +#define DONAME_WITH_PRICE 1 +#define DONAME_VAGUE_QUAN 2 +#define DONAME_FOR_MENU 4 /* [not used anywhere yet] */ +#define DONAME_FORCE_GENDER 8 /* always add male or female */ /* core of doname() */ staticfn char * @@ -1227,7 +1228,8 @@ doname_base( boolean ispoisoned = FALSE, with_price = (doname_flags & DONAME_WITH_PRICE) != 0, vague_quan = (doname_flags & DONAME_VAGUE_QUAN) != 0, - for_menu = (doname_flags & DONAME_FOR_MENU) != 0; + for_menu = (doname_flags & DONAME_FOR_MENU) != 0, + with_corpse_genders = (doname_flags & DONAME_FORCE_GENDER) != 0; boolean known, dknown, cknown, bknown, lknown, fake_arti, force_the; char prefix[PREFIX]; @@ -1511,7 +1513,15 @@ doname_base( unsigned cxarg = (((obj->quan != 1L) ? 0 : CXN_ARTICLE) | CXN_NOCORPSE); char *cxstr, *save_xnamep; + int puzzidx = (obj->invlet >= 'A' && obj->invlet <= 'Z') + ? obj->invlet - 'A' + : (obj->invlet >= 'a' && obj->invlet <= 'z') + ? obj->invlet - 'a' + 26 + : 53; /* valid index, but always holds zero */ + if (with_corpse_genders && puzzidx < 53 + && gp.puzzling_critera == 411 && gp.puzzling_ilets[puzzidx]) + cxarg |= CXN_ADDGNDR; /* corpse_xname() sets xnamep; callers other than doname_base() itself shouldn't care about xnamep (pointer to start of current obuf[]) but keep it accurate anyway */ @@ -1763,6 +1773,20 @@ doname_with_price(struct obj *obj) return doname_base(obj, DONAME_WITH_PRICE); } +/* Name of object including corpse genders. */ +char * +doname_with_cgender(struct obj *obj) +{ + return doname_base(obj, DONAME_FORCE_GENDER); +} + +/* doname with both price and corpse gender */ +char * +doname_with_price_and_cgender(struct obj *obj) +{ + return doname_base(obj, DONAME_WITH_PRICE | DONAME_FORCE_GENDER); +} + /* "some" instead of precise quantity if obj->dknown not set */ char * doname_vague_quan(struct obj *obj) @@ -1837,9 +1861,10 @@ corpse_xname( any_prefix = (cxn_flags & CXN_ARTICLE) != 0, /* leave off suffix (do_name() appends "corpse" itself) */ omit_corpse = (cxn_flags & CXN_NOCORPSE) != 0, + gndr_prefix = (cxn_flags & CXN_ADDGNDR) != 0, possessive = FALSE, glob = (otmp->otyp != CORPSE && otmp->globby); - const char *mnam; + const char *mnam, *gndr; /* some callers [aobjnam()] rely on prefix area that xname() sets aside */ gx.xnamep = nextobuf(); @@ -1879,15 +1904,19 @@ corpse_xname( into the code, so the() has been modified to deal with capitalized monster names; we could switch to using it below like an() */ + gndr = (gndr_prefix && otmp->spe & CORPSTAT_MALE) != 0 ? "male " + : (gndr_prefix && otmp->spe & CORPSTAT_FEMALE) != 0 ? "female " + : ""; if (!adjective || !*adjective) { + Strcat(nambuf, gndr); /* normal case: newt corpse */ Strcat(nambuf, mnam); } else { /* adjective positioning depends upon format of monster name */ if (possessive) /* Medusa's cursed partly eaten corpse */ - Sprintf(eos(nambuf), "%s %s", mnam, adjective); + Sprintf(eos(nambuf), "%s %s%s", mnam, gndr, adjective); else /* cursed partly eaten troll corpse */ - Sprintf(eos(nambuf), "%s %s", adjective, mnam); + Sprintf(eos(nambuf), "%s %s%s", adjective, gndr, mnam); /* in case adjective has a trailing space, squeeze it out */ mungspaces(nambuf); /* doname() might include a count in the adjective argument; diff --git a/src/pickup.c b/src/pickup.c index 7cb487b4c..6e1f788a8 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1041,7 +1041,7 @@ query_objlist(const char *qstr, /* query string */ unsigned sortflags; glyph_info tmpglyphinfo = nul_glyphinfo; Loot *sortedolist, *srtoli; - int clr = NO_COLOR; + int clr = NO_COLOR, puzzling_count = 0; *pick_list = (menu_item *) 0; if (!olist && !engulfer) @@ -1076,6 +1076,8 @@ query_objlist(const char *qstr, /* query string */ return 1; } + puzzling_count = check_for_puzzling_nonmerge(olist); + sortflags = (((flags.sortloot == 'f' || (flags.sortloot == 'l' && !(qflags & USE_INVLET))) ? SORTLOOT_LOOT @@ -1134,7 +1136,9 @@ query_objlist(const char *qstr, /* query string */ (qflags & USE_INVLET) ? curr->invlet : (first && curr->oclass == COIN_CLASS) ? '$' : 0, def_oc_syms[(int) objects[curr->otyp].oc_class].sym, - ATR_NONE, clr, doname_with_price(curr), + ATR_NONE, clr, + (puzzling_count) ? doname_with_price_and_cgender(curr) + : doname_with_price(curr), MENU_ITEMFLAGS_NONE); first = FALSE; } From 90aaeb53cdd1c2fb208ec60d48c5cba2638a37bd Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 27 Jun 2026 11:41:54 -0400 Subject: [PATCH 517/702] follow-up: zero out puzzling_criteria --- src/invent.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/invent.c b/src/invent.c index b84e05279..e885b7ae0 100644 --- a/src/invent.c +++ b/src/invent.c @@ -2710,6 +2710,7 @@ check_for_puzzling_nonmerge(struct obj *objchn) struct obj *obj; boolean at_least_one = FALSE; + gp.puzzling_criteria = 0; for (i = 0; i < invlet_basic + 1; ++i) gp.puzzling_ilets[i] = mnums[i] = gndr[i] = 0; From c9188782998629bb0b317ee2eb65c38eb53f9f6e Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 27 Jun 2026 11:45:36 -0400 Subject: [PATCH 518/702] follow-up: field name typo --- include/decl.h | 2 +- src/invent.c | 2 +- src/objnam.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/decl.h b/include/decl.h index 70e454f95..86ec5b977 100644 --- a/include/decl.h +++ b/include/decl.h @@ -803,7 +803,7 @@ struct instance_globals_p { int poly_zapped; /* new stuff */ - int puzzling_critera; + int puzzling_criteria; char puzzling_ilets[invlet_basic + 1]; boolean havestate; diff --git a/src/invent.c b/src/invent.c index e885b7ae0..725b78a62 100644 --- a/src/invent.c +++ b/src/invent.c @@ -2742,7 +2742,7 @@ check_for_puzzling_nonmerge(struct obj *objchn) } } if (puzzling_cnt) - gp.puzzling_critera = 411; + gp.puzzling_criteria = 411; } return puzzling_cnt; } diff --git a/src/objnam.c b/src/objnam.c index 233a84b31..160f35091 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1520,7 +1520,7 @@ doname_base( : 53; /* valid index, but always holds zero */ if (with_corpse_genders && puzzidx < 53 - && gp.puzzling_critera == 411 && gp.puzzling_ilets[puzzidx]) + && gp.puzzling_criteria == 411 && gp.puzzling_ilets[puzzidx]) cxarg |= CXN_ADDGNDR; /* corpse_xname() sets xnamep; callers other than doname_base() itself shouldn't care about xnamep (pointer to start of From bfa924bb0ed29522da7c83b9c82f3939e4d7a537 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 28 Jun 2026 17:46:17 -0400 Subject: [PATCH 519/702] replace hardcoded number with correct enum value --- src/objnam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objnam.c b/src/objnam.c index 160f35091..def054c37 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1517,7 +1517,7 @@ doname_base( ? obj->invlet - 'A' : (obj->invlet >= 'a' && obj->invlet <= 'z') ? obj->invlet - 'a' + 26 - : 53; /* valid index, but always holds zero */ + : invlet_basic; /* valid index, but always holds zero */ if (with_corpse_genders && puzzidx < 53 && gp.puzzling_criteria == 411 && gp.puzzling_ilets[puzzidx]) From aaf601ffc803d5a2dfd91db17d412146ee756175 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 28 Jun 2026 17:49:00 -0400 Subject: [PATCH 520/702] follow-up bit --- src/objnam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objnam.c b/src/objnam.c index def054c37..35bb6bc7d 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1519,7 +1519,7 @@ doname_base( ? obj->invlet - 'a' + 26 : invlet_basic; /* valid index, but always holds zero */ - if (with_corpse_genders && puzzidx < 53 + if (with_corpse_genders && puzzidx < invlet_basic && gp.puzzling_criteria == 411 && gp.puzzling_ilets[puzzidx]) cxarg |= CXN_ADDGNDR; /* corpse_xname() sets xnamep; callers other than doname_base() From 5e80fd3b93e888876f60162e519d4079a65c427c Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 2 Jul 2026 17:48:29 -0400 Subject: [PATCH 521/702] wand of stasis when off level Account for the time spent on other levels for wand of stasis Resolves #1608 --- include/extern.h | 2 +- src/restore.c | 6 ++++-- src/save.c | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/extern.h b/include/extern.h index a6043a94e..5edd7ac7b 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2755,7 +2755,7 @@ void restore_gamelog(NHFILE *); boolean restgamestate(NHFILE *); void restore_msghistory(NHFILE *); #endif -extern void rest_adjust_levelflags(void); +extern void rest_adjust_levelflags(long); extern void moves_to_relative_time(long *); extern void relative_time_to_moves(long *); extern boolean revision_increment(int, int, uchar *); diff --git a/src/restore.c b/src/restore.c index dcd4d8164..5ab2342c7 100644 --- a/src/restore.c +++ b/src/restore.c @@ -1140,7 +1140,7 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) Sfi_dest_area(nhfp, &svu.updest, "lev-updest"); Sfi_dest_area(nhfp, &svd.dndest, "lev-dndest"); Sfi_levelflags(nhfp, &svl.level.flags, "lev-level_flags"); - rest_adjust_levelflags(); + rest_adjust_levelflags(elapsed); if (svd.doors) { free(svd.doors); svd.doors = 0; @@ -1348,11 +1348,13 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) } void -rest_adjust_levelflags(void) +rest_adjust_levelflags(long elapsed) { /* adjust timestamps */ relative_time_to_moves(&svl.level.flags.stasis_until); + svl.level.flags.stasis_until -= elapsed; } + void moves_to_relative_time(long *timestamp) { diff --git a/src/save.c b/src/save.c index 72ff9f859..d03000408 100644 --- a/src/save.c +++ b/src/save.c @@ -529,7 +529,7 @@ savelev_core(NHFILE *nhfp, xint8 lev) Sfo_dest_area(nhfp, &svd.dndest, "lev-dndest"); save_adjust_levelflags(); Sfo_levelflags(nhfp, &svl.level.flags, "lev-level_flags"); - rest_adjust_levelflags(); + rest_adjust_levelflags(0L); Sfo_int(nhfp, &svd.doors_alloc, "lev-doors_alloc"); /* don't rely on underlying write() behavior to write From 338461943197e9e5e206d72c2099e248cbda07b7 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Thu, 2 Jul 2026 21:22:30 -0400 Subject: [PATCH 522/702] MS-DOS: Add Extended2 symbols to the bundled fonts This change adds U+2299, U+2601 and U+2980 to the bundled fonts, so that all symbols specified in the Extended2 symbol set are available. Also, a few more directives are added to the files, so that FontForge can load them and display their contents. --- sys/msdos/fonts/nh-u16b.bdf | 88 ++++++++++++++++++++++- sys/msdos/fonts/nh-u16v.bdf | 88 ++++++++++++++++++++++- sys/msdos/fonts/nh-u18b.bdf | 94 ++++++++++++++++++++++++- sys/msdos/fonts/nh-u20b.bdf | 100 +++++++++++++++++++++++++- sys/msdos/fonts/nh-u22b.bdf | 106 +++++++++++++++++++++++++++- sys/msdos/fonts/nh-u24b.bdf | 112 ++++++++++++++++++++++++++++- sys/msdos/fonts/nh-u28b.bdf | 124 +++++++++++++++++++++++++++++++- sys/msdos/fonts/nh-u32b.bdf | 136 +++++++++++++++++++++++++++++++++++- 8 files changed, 832 insertions(+), 16 deletions(-) diff --git a/sys/msdos/fonts/nh-u16b.bdf b/sys/msdos/fonts/nh-u16b.bdf index a4b9cb633..d2eb8f9e3 100644 --- a/sys/msdos/fonts/nh-u16b.bdf +++ b/sys/msdos/fonts/nh-u16b.bdf @@ -1,12 +1,21 @@ STARTFONT 2.1 FONTBOUNDINGBOX 8 16 -STARTPROPERTIES 3 +STARTPROPERTIES 8 NOTICE "Additional characters to use with ter-u16b.bdf" -COPYRIGHT "Copyright 2022 Ray Chason." +COPYRIGHT "Copyright 2022, 2026 Ray Chason." +NOTICE "Cloud glyph adapted from the uw-ptty0 font at" +NOTICE "https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/" NOTICE "NetHack may be freely redistributed. See license for details." +PIXEL_SIZE 16 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" ENDPROPERTIES +CHARS 6 STARTCHAR tripletilde ENCODING 8779 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 BITMAP 00 00 @@ -25,8 +34,34 @@ BITMAP 00 00 ENDCHAR +STARTCHAR uni2299 +ENCODING 8857 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 +BITMAP +00 +00 +00 +00 +3C +7E +C3 +DB +DB +C3 +7E +3C +00 +00 +00 +00 +ENDCHAR STARTCHAR uppereighth ENCODING 9620 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 BITMAP FF FF @@ -47,6 +82,9 @@ FF ENDCHAR STARTCHAR righteighth ENCODING 9621 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 BITMAP 01 01 @@ -65,4 +103,50 @@ BITMAP 01 01 ENDCHAR +STARTCHAR uni2601 +ENCODING 9729 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 +BITMAP +00 +00 +00 +00 +00 +0E +13 +61 +81 +C3 +7E +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2980 +ENCODING 10624 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 +BITMAP +00 +00 +54 +54 +54 +54 +54 +54 +54 +54 +54 +54 +00 +00 +00 +00 +ENDCHAR ENDFONT diff --git a/sys/msdos/fonts/nh-u16v.bdf b/sys/msdos/fonts/nh-u16v.bdf index 7bd2669e0..33e7af5d6 100644 --- a/sys/msdos/fonts/nh-u16v.bdf +++ b/sys/msdos/fonts/nh-u16v.bdf @@ -1,12 +1,21 @@ STARTFONT 2.1 FONTBOUNDINGBOX 8 16 -STARTPROPERTIES 3 +STARTPROPERTIES 8 NOTICE "Additional characters to use with ter-u16v.bdf" -COPYRIGHT "Copyright 2022 Ray Chason." +COPYRIGHT "Copyright 2022, 2026 Ray Chason." +NOTICE "Cloud glyph adapted from the uw-ptty0 font at" +NOTICE "https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/" NOTICE "NetHack may be freely redistributed. See license for details." +PIXEL_SIZE 16 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" ENDPROPERTIES +CHARS 6 STARTCHAR tripletilde ENCODING 8779 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 BITMAP 00 00 @@ -25,8 +34,34 @@ BITMAP 00 00 ENDCHAR +STARTCHAR uni2299 +ENCODING 8857 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 +BITMAP +00 +00 +00 +00 +3C +7E +C3 +DB +DB +C3 +7E +3C +00 +00 +00 +00 +ENDCHAR STARTCHAR uppereighth ENCODING 9620 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 BITMAP FF FF @@ -47,6 +82,9 @@ FF ENDCHAR STARTCHAR righteighth ENCODING 9621 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 BITMAP 01 01 @@ -65,4 +103,50 @@ BITMAP 01 01 ENDCHAR +STARTCHAR uni2601 +ENCODING 9729 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 +BITMAP +00 +00 +00 +00 +00 +0E +13 +61 +81 +C3 +7E +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2980 +ENCODING 10624 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 +BITMAP +00 +00 +54 +54 +54 +54 +54 +54 +54 +54 +54 +54 +00 +00 +00 +00 +ENDCHAR ENDFONT diff --git a/sys/msdos/fonts/nh-u18b.bdf b/sys/msdos/fonts/nh-u18b.bdf index 11a4b1176..ff9196e40 100644 --- a/sys/msdos/fonts/nh-u18b.bdf +++ b/sys/msdos/fonts/nh-u18b.bdf @@ -1,12 +1,21 @@ STARTFONT 2.1 FONTBOUNDINGBOX 10 18 -STARTPROPERTIES 3 +STARTPROPERTIES 8 NOTICE "Additional characters to use with ter-u18b.bdf" -COPYRIGHT "Copyright 2022 Ray Chason." +COPYRIGHT "Copyright 2022, 2026 Ray Chason." +NOTICE "Cloud glyph adapted from the uw-ptty0 font at" +NOTICE "https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/" NOTICE "NetHack may be freely redistributed. See license for details." +PIXEL_SIZE 18 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" ENDPROPERTIES +CHARS 6 STARTCHAR tripletilde ENCODING 8779 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 BITMAP 0000 0000 @@ -27,8 +36,36 @@ BITMAP 0000 0000 ENDCHAR +STARTCHAR uni2299 +ENCODING 8857 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 +BITMAP +0000 +0000 +0000 +0000 +0000 +3C00 +7E00 +C300 +DB00 +DB00 +C300 +7E00 +3C00 +0000 +0000 +0000 +0000 +0000 +ENDCHAR STARTCHAR uppereighth ENCODING 9620 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 BITMAP FFC0 FFC0 @@ -51,6 +88,9 @@ FFC0 ENDCHAR STARTCHAR righteighth ENCODING 9621 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 BITMAP 0040 0040 @@ -71,4 +111,54 @@ BITMAP 0040 0040 ENDCHAR +STARTCHAR uni2601 +ENCODING 9729 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0F00 +1980 +7080 +C080 +8080 +C180 +7F00 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR uni2980 +ENCODING 10624 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 +BITMAP +0000 +0000 +0000 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +0000 +0000 +0000 +ENDCHAR ENDFONT diff --git a/sys/msdos/fonts/nh-u20b.bdf b/sys/msdos/fonts/nh-u20b.bdf index 702269414..b510e7cf6 100644 --- a/sys/msdos/fonts/nh-u20b.bdf +++ b/sys/msdos/fonts/nh-u20b.bdf @@ -1,12 +1,21 @@ STARTFONT 2.1 FONTBOUNDINGBOX 10 20 -STARTPROPERTIES 3 +STARTPROPERTIES 8 NOTICE "Additional characters to use with ter-u20b.bdf" -COPYRIGHT "Copyright 2022 Ray Chason." +COPYRIGHT "Copyright 2022, 2026 Ray Chason." +NOTICE "Cloud glyph adapted from the uw-ptty0 font at" +NOTICE "https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/" NOTICE "NetHack may be freely redistributed. See license for details." +PIXEL_SIZE 20 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" ENDPROPERTIES +CHARS 6 STARTCHAR tripletilde ENCODING 8779 +SWIDTH 500 0 +DWIDTH 10 0 +BBX 10 20 0 -4 BITMAP 0000 0000 @@ -29,8 +38,38 @@ BITMAP 0000 0000 ENDCHAR +STARTCHAR uni2299 +ENCODING 8857 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 +BITMAP +0000 +0000 +0000 +0000 +0000 +0C00 +3F00 +6180 +4080 +CCC0 +CCC0 +4080 +6180 +3F00 +0C00 +0000 +0000 +0000 +0000 +0000 +ENDCHAR STARTCHAR uppereighth ENCODING 9620 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 BITMAP FFC0 FFC0 @@ -55,6 +94,9 @@ FFC0 ENDCHAR STARTCHAR righteighth ENCODING 9621 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 BITMAP 0040 0040 @@ -77,4 +119,58 @@ BITMAP 0040 0040 ENDCHAR +STARTCHAR uni2601 +ENCODING 9729 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0780 +0FC0 +1CC0 +78C0 +E0C0 +C0C0 +FF80 +7F00 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR uni2980 +ENCODING 10624 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 +BITMAP +0000 +0000 +0000 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +0000 +0000 +0000 +0000 +ENDCHAR ENDFONT diff --git a/sys/msdos/fonts/nh-u22b.bdf b/sys/msdos/fonts/nh-u22b.bdf index 15de8d761..b4a87bd31 100644 --- a/sys/msdos/fonts/nh-u22b.bdf +++ b/sys/msdos/fonts/nh-u22b.bdf @@ -1,12 +1,21 @@ STARTFONT 2.1 FONTBOUNDINGBOX 11 22 -STARTPROPERTIES 3 +STARTPROPERTIES 8 NOTICE "Additional characters to use with ter-u22b.bdf" -COPYRIGHT "Copyright 2022 Ray Chason." +COPYRIGHT "Copyright 2022, 2026 Ray Chason." +NOTICE "Cloud glyph adapted from the uw-ptty0 font at" +NOTICE "https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/" NOTICE "NetHack may be freely redistributed. See license for details." +PIXEL_SIZE 22 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" ENDPROPERTIES +CHARS 6 STARTCHAR tripletilde ENCODING 8779 +SWIDTH 500 0 +DWIDTH 11 0 +BBX 11 22 0 -5 BITMAP 0000 0000 @@ -31,8 +40,40 @@ BITMAP 0000 0000 ENDCHAR +STARTCHAR uni2299 +ENCODING 8857 +SWIDTH 500 0 +DWIDTH 11 0 +BBX 11 22 0 -5 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0C00 +3F00 +6180 +4080 +CCC0 +CCC0 +4080 +6180 +3F00 +0C00 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR STARTCHAR uppereighth ENCODING 9620 +SWIDTH 500 0 +DWIDTH 11 0 +BBX 11 22 0 -5 BITMAP FFE0 FFE0 @@ -59,6 +100,9 @@ FFE0 ENDCHAR STARTCHAR righteighth ENCODING 9621 +SWIDTH 500 0 +DWIDTH 11 0 +BBX 11 22 0 -5 BITMAP 0060 0060 @@ -83,4 +127,62 @@ BITMAP 0060 0060 ENDCHAR +STARTCHAR uni2601 +ENCODING 9729 +SWIDTH 500 0 +DWIDTH 11 0 +BBX 11 22 0 -5 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0780 +0FC0 +1CC0 +78C0 +E0C0 +C0C0 +FF80 +7F00 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR uni2980 +ENCODING 10624 +SWIDTH 500 0 +DWIDTH 11 0 +BBX 11 22 0 -5 +BITMAP +0000 +0000 +0000 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +0000 +0000 +0000 +0000 +0000 +ENDCHAR ENDFONT diff --git a/sys/msdos/fonts/nh-u24b.bdf b/sys/msdos/fonts/nh-u24b.bdf index bea34cc68..90b6278cd 100644 --- a/sys/msdos/fonts/nh-u24b.bdf +++ b/sys/msdos/fonts/nh-u24b.bdf @@ -1,12 +1,21 @@ STARTFONT 2.1 FONTBOUNDINGBOX 12 24 -STARTPROPERTIES 3 +STARTPROPERTIES 8 NOTICE "Additional characters to use with ter-u24b.bdf" -COPYRIGHT "Copyright 2022 Ray Chason." +COPYRIGHT "Copyright 2022, 2026 Ray Chason." +NOTICE "Cloud glyph adapted from the uw-ptty0 font at" +NOTICE "https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/" NOTICE "NetHack may be freely redistributed. See license for details." +PIXEL_SIZE 24 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" ENDPROPERTIES +CHARS 6 STARTCHAR tripletilde ENCODING 8779 +SWIDTH 500 0 +DWIDTH 12 0 +BBX 12 24 0 -5 BITMAP 0000 0000 @@ -33,8 +42,42 @@ BITMAP 0000 0000 ENDCHAR +STARTCHAR uni2299 +ENCODING 8857 +SWIDTH 500 0 +DWIDTH 12 0 +BBX 12 24 0 -5 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0F00 +3FC0 +70E0 +6060 +C030 +C630 +C630 +C030 +6060 +70E0 +3FC0 +0F00 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR STARTCHAR uppereighth ENCODING 9620 +SWIDTH 500 0 +DWIDTH 12 0 +BBX 12 24 0 -5 BITMAP FFF0 FFF0 @@ -63,6 +106,9 @@ FFF0 ENDCHAR STARTCHAR righteighth ENCODING 9621 +SWIDTH 500 0 +DWIDTH 12 0 +BBX 12 24 0 -5 BITMAP 0030 0030 @@ -89,4 +135,66 @@ BITMAP 0030 0030 ENDCHAR +STARTCHAR uni2601 +ENCODING 9729 +SWIDTH 500 0 +DWIDTH 12 0 +BBX 12 24 0 -5 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +03C0 +07E0 +0E60 +3C60 +7060 +6060 +7FC0 +3F80 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR uni2980 +ENCODING 10624 +SWIDTH 500 0 +DWIDTH 12 0 +BBX 12 24 0 -5 +BITMAP +0000 +0000 +0000 +0000 +6660 +6660 +6660 +6660 +6660 +6660 +6660 +6660 +6660 +6660 +6660 +6660 +6660 +6660 +6660 +0000 +0000 +0000 +0000 +0000 +ENDCHAR ENDFONT diff --git a/sys/msdos/fonts/nh-u28b.bdf b/sys/msdos/fonts/nh-u28b.bdf index 2b3954771..78aa22ced 100644 --- a/sys/msdos/fonts/nh-u28b.bdf +++ b/sys/msdos/fonts/nh-u28b.bdf @@ -1,12 +1,21 @@ STARTFONT 2.1 FONTBOUNDINGBOX 14 28 -STARTPROPERTIES 3 +STARTPROPERTIES 8 NOTICE "Additional characters to use with ter-u28b.bdf" -COPYRIGHT "Copyright 2022 Ray Chason." +COPYRIGHT "Copyright 2022, 2026 Ray Chason." +NOTICE "Cloud glyph adapted from the uw-ptty0 font at" +NOTICE "https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/" NOTICE "NetHack may be freely redistributed. See license for details." +PIXEL_SIZE 28 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" ENDPROPERTIES +CHARS 6 STARTCHAR tripletilde ENCODING 8779 +SWIDTH 500 0 +DWIDTH 14 0 +BBX 14 28 0 -6 BITMAP 0000 0000 @@ -37,8 +46,46 @@ BITMAP 0000 0000 ENDCHAR +STARTCHAR uni2299 +ENCODING 8857 +SWIDTH 500 0 +DWIDTH 14 0 +BBX 14 28 0 -6 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0780 +1FE0 +3870 +6018 +6018 +C30C +C78C +C78C +C30C +6018 +6018 +3870 +1FE0 +0780 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR STARTCHAR uppereighth ENCODING 9620 +SWIDTH 500 0 +DWIDTH 14 0 +BBX 14 28 0 -6 BITMAP FFFC FFFC @@ -71,6 +118,9 @@ FFFC ENDCHAR STARTCHAR righteighth ENCODING 9621 +SWIDTH 500 0 +DWIDTH 14 0 +BBX 14 28 0 -6 BITMAP 000C 000C @@ -101,4 +151,74 @@ BITMAP 000C 000C ENDCHAR +STARTCHAR uni2601 +ENCODING 9729 +SWIDTH 500 0 +DWIDTH 14 0 +BBX 14 28 0 -6 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +01E0 +03F8 +07F8 +3F1C +7E0C +F00C +C00C +C00C +C01C +FFF8 +7FF8 +3FE0 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR uni2980 +ENCODING 10624 +SWIDTH 500 0 +DWIDTH 14 0 +BBX 14 28 0 -6 +BITMAP +0000 +0000 +0000 +0000 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR ENDFONT diff --git a/sys/msdos/fonts/nh-u32b.bdf b/sys/msdos/fonts/nh-u32b.bdf index e5cf7f2a8..356fa3765 100644 --- a/sys/msdos/fonts/nh-u32b.bdf +++ b/sys/msdos/fonts/nh-u32b.bdf @@ -1,12 +1,21 @@ STARTFONT 2.1 FONTBOUNDINGBOX 16 32 -STARTPROPERTIES 3 +STARTPROPERTIES 8 NOTICE "Additional characters to use with ter-u32b.bdf" -COPYRIGHT "Copyright 2022 Ray Chason." +COPYRIGHT "Copyright 2022, 2026 Ray Chason." +NOTICE "Cloud glyph adapted from the uw-ptty0 font at" +NOTICE "https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/" NOTICE "NetHack may be freely redistributed. See license for details." +PIXEL_SIZE 32 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" ENDPROPERTIES +CHARS 6 STARTCHAR tripletilde ENCODING 8779 +SWIDTH 500 0 +DWIDTH 16 0 +BBX 16 32 0 -6 BITMAP 0000 0000 @@ -41,8 +50,50 @@ BITMAP 0000 0000 ENDCHAR +STARTCHAR uni2299 +ENCODING 8857 +SWIDTH 500 0 +DWIDTH 16 0 +BBX 16 32 0 -6 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +07E0 +1FF8 +381C +6006 +6006 +C003 +C183 +C3C3 +C3C3 +C183 +C003 +6006 +6006 +381C +1FF8 +07E0 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR STARTCHAR uppereighth ENCODING 9620 +SWIDTH 500 0 +DWIDTH 16 0 +BBX 16 32 0 -6 BITMAP FFFF FFFF @@ -79,6 +130,9 @@ FFFF ENDCHAR STARTCHAR righteighth ENCODING 9621 +SWIDTH 500 0 +DWIDTH 16 0 +BBX 16 32 0 -6 BITMAP 0002 0002 @@ -113,4 +167,82 @@ BITMAP 0002 0002 ENDCHAR +STARTCHAR uni2601 +ENCODING 9729 +SWIDTH 500 0 +DWIDTH 16 0 +BBX 16 32 0 -6 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +00F0 +01FC +03FC +1F8E +3F06 +7806 +6006 +6006 +600E +7FFC +3FFC +1FF0 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR uni2980 +ENCODING 10624 +SWIDTH 500 0 +DWIDTH 16 0 +BBX 16 32 0 -6 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR ENDFONT From ae8982fe3e71acefb12fe248b4ffd4137b29e8b9 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Thu, 2 Jul 2026 21:34:35 -0400 Subject: [PATCH 523/702] MS-DOS: Check font pointer for null The 16 color mode loads the font specified in font_map, and accepts it only if its size is 8 by 16 pixels. This change avoids a null dereference if the font is not found. --- sys/msdos/vidvga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index c69823d74..fb5de8db7 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -811,7 +811,7 @@ vga_Init(void) } free_font(psf_font); psf_font = load_font(font_name); - if (psf_font->width != 8 || psf_font->height != 16) { + if (psf_font != NULL && psf_font->width != 8 || psf_font->height != 16) { raw_printf("VGA mode only supports 8x16 fonts"); free_font(psf_font); psf_font = NULL; From 1de1b531b34ff8ae8e40db6b1e5daf8b06001754 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Thu, 2 Jul 2026 23:08:42 -0400 Subject: [PATCH 524/702] Some optimizations of the glyph lookup * src/glyphs.c: Don't produce names for swallow glyphs that can never appear. This speeds up the building of the glyph index in populate_glyphname_hash_indices. * src/symbols.c: Build a sorted index for loadsyms so that it can be searched with bsearch. Benchmarking results, using the MS-DOS port on an emulated 386SX at 16 MHz; times are as measured with clock() from the entry to main() to the appearance of the "Who are you?" prompt: * Unmodified: 48.5 seconds * With the loadsyms index: 40.4 seconds * With impossible swallow glyphs left unnamed: 34.5 seconds These changes should also be helpful for the Amiga and Atari ST ports. --- src/glyphs.c | 4 +- src/symbols.c | 125 ++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 105 insertions(+), 24 deletions(-) diff --git a/src/glyphs.c b/src/glyphs.c index 226a7f208..8e12da56d 100644 --- a/src/glyphs.c +++ b/src/glyphs.c @@ -373,8 +373,10 @@ compose_glyph_name(int glyph, char *buf, size_t bufsz) }; j = glyph - GLYPH_SWALLOW_OFF; - cmap = glyph_to_swallow(glyph); mnum = j / ((S_sw_br - S_sw_tl) + 1); + if (!attacktype(&mons[mnum], AT_ENGL)) + return 0; + cmap = glyph_to_swallow(glyph); Snprintf(tmpbuf[3], sizeof tmpbuf[3], "swallow %s %s", monsdump[mnum].nm, swallow_texts[cmap]); buf3 = tmpbuf[3]; diff --git a/src/symbols.c b/src/symbols.c index 1512ed7c5..b1f459341 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -7,6 +7,9 @@ staticfn void savedsym_add(const char *, const char *, int); staticfn struct _savedsym *savedsym_find(const char *, int); +staticfn const struct symparse *search_loadsyms(const char *buf, size_t len); +staticfn int symparse_compare(const void *s1_, const void *s2_); +staticfn int symparse_find(const void *bstr_, const void *rec_); extern const uchar def_r_oc_syms[MAXOCLASSES]; /* drawing.c */ @@ -29,6 +32,11 @@ void (*utf8graphics_mode_callback)(void) = 0; /* set in term_start_screen and * found in unixtty,windtty,&c */ #endif +struct bounded_string { + const char *str; + size_t len; +}; + /* * Explanations of the functions found below: * @@ -864,42 +872,113 @@ match_sym(char *buf) { "S_explode8", "S_expl_bc" }, { "S_explode9", "S_expl_br" }, }; int i; - size_t len = strlen(buf); - const char *p = strchr(buf, ':'), *q = strchr(buf, '='); - const struct symparse *sp = loadsyms; + size_t len; + const struct symparse *sp; /* G_ lines will never match here */ if ((buf[0] == 'G' || buf[0] == 'g') && buf[1] == '_') return (struct symparse *) 0; - if (!p || (q && q < p)) - p = q; - if (p) { - /* note: there will be at most one space before the '=' - because caller has condensed buf[] with mungspaces() */ - if (p > buf && p[-1] == ' ') - p--; - len = (int) (p - buf); - } - while (sp->range) { - if ((len >= strlen(sp->name)) && !strncmpi(buf, sp->name, len)) - return sp; - sp++; - } + len = strcspn(buf, "=:"); + /* note: there will be at most one space before the '=' + because caller has condensed buf[] with mungspaces() */ + if (len != 0 && buf[len-1] == ' ') + len--; + sp = search_loadsyms(buf, len); + if (sp != NULL) + return sp; for (i = 0; i < SIZE(alternates); ++i) { if ((len >= strlen(alternates[i].altnm)) && !strncmpi(buf, alternates[i].altnm, len)) { - sp = loadsyms; - while (sp->range) { - if (!strcmp(alternates[i].nm, sp->name)) - return sp; - sp++; - } + sp = search_loadsyms(alternates[i].nm, strlen(alternates[i].nm)); + if (sp != NULL) + return sp; } } return (struct symparse *) 0; } +staticfn const struct symparse * +search_loadsyms(const char *buf, size_t len) +{ + struct bounded_string bstr; + + /* Sorted index to loadsyms */ + static boolean first_time = TRUE; + static const struct symparse *loadsyms_sorted[SIZE(loadsyms) - 1]; + if (first_time) { + const struct symparse *sp = loadsyms; + size_t i = 0; + while (sp->range) { + loadsyms_sorted[i] = sp; + ++sp; + ++i; + } + qsort(loadsyms_sorted, SIZE(loadsyms_sorted), sizeof(loadsyms_sorted[0]), + symparse_compare); + first_time = FALSE; + } + + bstr.str = buf; + bstr.len = len; + const struct symparse **sp = bsearch(&bstr, loadsyms_sorted, + SIZE(loadsyms_sorted), sizeof(loadsyms_sorted[0]), + symparse_find); + return sp ? *sp : NULL; +} + +staticfn int +symparse_compare(const void *s1_, const void *s2_) +{ + const struct symparse **s1 = (const struct symparse **)s1_; + const struct symparse **s2 = (const struct symparse **)s2_; + const char *n1 = (*s1)->name; + const char *n2 = (*s2)->name; + size_t i; + + /* Can we count on strcmpi to say less than or greater than consistently? */ + for (i = 0; n1[i] != 0 && n2[i] != 0; ++i) { + char c1 = n1[i]; + char c2 = n2[i]; + if ('A' <= c1 && c1 <= 'Z') { + c1 += 'a' - 'A'; + } + if ('A' <= c2 && c2 <= 'Z') { + c2 += 'a' - 'A'; + } + if (c1 != c2) { + return c1 - c2; + } + } + + return n1[i] - n2[i]; +} + +staticfn int +symparse_find(const void *bstr_, const void *rec_) +{ + const struct bounded_string *bstr = (const struct bounded_string *)bstr_; + const struct symparse **rec = (const struct symparse **)rec_; + size_t i; + + /* Can we count on strcmpi to say less than or greater than consistently? */ + for (i = 0; i < bstr->len; ++i) { + char c1 = bstr->str[i]; + char c2 = (*rec)->name[i]; + if ('A' <= c1 && c1 <= 'Z') { + c1 += 'a' - 'A'; + } + if ('A' <= c2 && c2 <= 'Z') { + c2 += 'a' - 'A'; + } + if (c1 != c2) { + return c1 - c2; + } + } + + return 0; +} + DISABLE_WARNING_FORMAT_NONLITERAL /* From b3fd7330efd8872945576cd1481709c078f1b5f8 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Fri, 3 Jul 2026 00:24:17 -0400 Subject: [PATCH 525/702] Fix operator precedence --- sys/msdos/vidvga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index fb5de8db7..792a32e2b 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -811,7 +811,7 @@ vga_Init(void) } free_font(psf_font); psf_font = load_font(font_name); - if (psf_font != NULL && psf_font->width != 8 || psf_font->height != 16) { + if (psf_font != NULL && (psf_font->width != 8 || psf_font->height != 16)) { raw_printf("VGA mode only supports 8x16 fonts"); free_font(psf_font); psf_font = NULL; From edb99dcf8fb62c9e5cd4de0710ceb23e59186b93 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 3 Jul 2026 08:30:40 -0400 Subject: [PATCH 526/702] fixes5-0-1.txt catch-up; also fix some whitespace --- doc/fixes5-0-1.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 7b3746481..077f75971 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -61,12 +61,14 @@ keep the player better-informed about status of the tether on their weapon don't overflow svp.plname on restore (pr #1570 by chasonr) monsters (including pets) aren't scared of the Sokoban rolling boulder traps fix a bug in which steeds would continuously gain movement points while - being ridden + being ridden when hero's behavior makes erinyes stronger, cap level at 49 rather than 50 with inventory item action for leash, distingluish leash-in-use from empty one deafness check was missing from a shopkeeper message in ready_weapon() thrown ball travel did not check for regions (pr #1595 by copperwater) remove deprecated option --version:paste +the timeout for stasis wasn't decrementing while off-level; ensure the elapsed + time is taken into consideration upon return to the level Platform- and/or Interface-Specific Fixes @@ -156,7 +158,7 @@ libnh: rewrote sys/unix/hints/macOS.500: rewrote the libnh.a rule. The (the tty windowport), which duplicated symbols from libnhmain.o / winshim.o. libnh: sys/libnh/libnhmain.c: gate the emscripten-only code in get_nhuuid - with `#ifdef __EMSCRIPTEN__` instead of `#ifdef NHUUID` + with `#ifdef __EMSCRIPTEN__` instead of `#ifdef NHUUID` libnh: sys/unix/hints/macOS.500 in the WANT_LIBNH block, add an explicit `recover: lua_support` dependency (gated by MAKEFILE_TOP). When $(GAME) is overridden to empty, the regular `recover: $(GAME)` chain From ece0c3ce3c68f3c23400d29eefb427de2d4eb876 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 3 Jul 2026 08:45:04 -0400 Subject: [PATCH 527/702] fixes5-0-1.txt entries for three pull requests --- doc/fixes5-0-1.txt | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 077f75971..77f7264a4 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -69,6 +69,11 @@ thrown ball travel did not check for regions (pr #1595 by copperwater) remove deprecated option --version:paste the timeout for stasis wasn't decrementing while off-level; ensure the elapsed time is taken into consideration upon return to the level +Some optimizations of the glyph lookup - don't produce names for swallow + glyphs that can never appear to speed up the building of the + glyph index in populate_glyphname_hash_indices; build a sorted + index for loadsyms so that it can be searched with bsearch + (pr #1612 by chasonr) Platform- and/or Interface-Specific Fixes @@ -184,7 +189,15 @@ MS-DOS: 16 color mode: Set the panning direction so CTRL-left and CTRL-right MS-DOS: makefont.lua was generating incorrect PSF fonts; there can be multiple characters mapped to a single glyph, but the mappings should be separated by FE bytes (pr #1581 by chasonr) -MS-DOS: accept only single character font mappings (pr #1581 by chasonr) +MS-DOS: accept only single character font mappings (pr #1581 by chasonr) +MS-DOS: add U+2299, U+2601 and U+2980 to the bundled fonts, so that all + symbols specified in the Extended2 symbol set are available; + also,a few more directives are added to the files, so that + FontForge can load them and display their contents + (pr #1610 by chasonr) +MS-DOS: The 16 color mode loads the font specified in font_map, and accepts + it only if its size is 8 by 16 pixels; avoid a null dereference + if the font is not found (pr #1611 by chasonr) musl: musl libc does not have __sighandler_t so don't use it in the macro definition for SIG_RET_TYPE with musl WASM: resolve some build failures in 'make CROSS_TO_WASM=1' From 7c418cff6aa5f31b48f17dee6cd10eab410f7076 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 3 Jul 2026 09:39:02 -0400 Subject: [PATCH 528/702] follow-up: a compiler warning fix --- src/symbols.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/symbols.c b/src/symbols.c index b1f459341..bd9596a1c 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -914,8 +914,8 @@ search_loadsyms(const char *buf, size_t len) ++sp; ++i; } - qsort(loadsyms_sorted, SIZE(loadsyms_sorted), sizeof(loadsyms_sorted[0]), - symparse_compare); + qsort((struct symparse **)loadsyms_sorted, SIZE(loadsyms_sorted), + sizeof(loadsyms_sorted[0]), symparse_compare); first_time = FALSE; } From 228576628cd09b39d2dedbf781dfef121e9afc28 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 4 Jul 2026 12:53:33 -0400 Subject: [PATCH 529/702] fix spot_monsters give-away Resolves #1603 --- src/hack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hack.c b/src/hack.c index 6175d46e2..eaeb8c365 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1719,7 +1719,7 @@ notice_mon(struct monst *mtmp) set_msg_xy(mtmp->mx, mtmp->my); You("%s %s.", canseemon(mtmp) ? "see" : "notice", x_monnam(mtmp, - mtmp->mtame ? ARTICLE_YOUR + (mtmp->mtame && !Hallucination) ? ARTICLE_YOUR : (!has_mgivenname(mtmp) && !type_is_pname(mtmp->data)) ? ARTICLE_A : ARTICLE_NONE, From 2afd03e01561ad0b88f91dfdc7115b5f40d9ea43 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 4 Jul 2026 13:16:31 -0400 Subject: [PATCH 530/702] Guidebook update - July 4, 2026 --- doc/Guidebook.mn | 5 +++-- doc/Guidebook.tex | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 88600fef7..5e64b337c 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -60,7 +60,7 @@ .ds f0 \*(vr .ds f1 \" empty .\"DO NOT REMOVE NH_DATESUB .ds f2 Date(%B %-d, %Y) -.ds f2 June 23, 2026 +.ds f2 July 4, 2026 . .\" A note on some special characters: .\" \(lq = left double quote @@ -4427,7 +4427,8 @@ is used for the role, then a random one will be automatically chosen. On some systems, the default is the player's user name; on others, there is no default and the player will be prompted. The former can made to behave like the latter by specifying a generic name -such as ``player''. +such as ``player''. The GENERICUSERS= setting in sysconf controls wich +names are considered generic. Cannot be set with the \(oq\f(CRO\fP\(cq command. .lp "news " Read the NetHack news file, if present (default on). diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 97cbb1bdf..c52050197 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -25,7 +25,7 @@ \author{Original version - Eric S. Raymond\\ (Edited and expanded for 5.0.0 by Mike Stephenson and others)} %DO NOT REMOVE NH_DATESUB \date{Date(%B %-d, %Y)} -\date{June 23, 2026} +\date{July 4, 2026} \maketitle @@ -4823,7 +4823,8 @@ automatically chosen. On some systems, the default is the player's user name; on others, there is no default and the player will be prompted. The former can made to behave like the latter by specifying a generic name -such as ``player''. +such as ``player''. The GENERICUSERS= setting in sysconf controls wich +names are considered generic. Cannot be set with the `\texttt{O}' command. %.lp \item[news] From af79ad629cc6dd5f1c965266dabd6b064266c920 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 4 Jul 2026 13:43:23 -0400 Subject: [PATCH 531/702] MS-DOS: some optimizations for tile handling * In both the 16 color and the VESA mode, the tileset image is loaded and split into individual tiles; the tiles are then processed into a form that is compatible with the video mode in use. For 16 color mode, a tile is processed each time it is displayed, leading to slow redrawing. For VESA mode, each tile is processed at startup, leading to long startup times. Both modes are changed so that the tile is processed once, when it is first displayed, and the result is cached. * Use memcpy when splitting the image into tiles. * Only load the tileset once. In 16 color mode, for reasons I do not understand, the gr_init function is called twice, leading to delay in startup. This does not happen in VESA mode. --- sys/msdos/vidvesa.c | 83 +++++++++++++++++++++++++++------------ sys/msdos/vidvga.c | 96 +++++++++++++++++++++++++++++++++------------ win/share/tileset.c | 24 ++++++------ 3 files changed, 143 insertions(+), 60 deletions(-) diff --git a/sys/msdos/vidvesa.c b/sys/msdos/vidvesa.c index bb66379ad..147e21da3 100644 --- a/sys/msdos/vidvesa.c +++ b/sys/msdos/vidvesa.c @@ -60,6 +60,8 @@ static unsigned long vesa_DoublePixels(unsigned long); static unsigned long vesa_TriplePixels(unsigned long); static void vesa_WriteStr(const char *, int, int, int, int); static unsigned char __far *vesa_FontPtrs(void); +static unsigned char *vesa_tile(unsigned); +static unsigned char *vesa_oview_tile(unsigned); /* static void vesa_process_tile(struct TileImage *tile); */ #ifdef POSITIONBAR @@ -849,7 +851,7 @@ vesa_redrawmap(void) for (cy = 0; cy < ROWNO; ++cy) { for (py = 0; py < vesa_oview_height; ++py) { for (cx = 0; cx < COLNO; ++cx) { - tile = vesa_oview_tiles[map[cy][cx].tileidx]; + tile = vesa_oview_tile(map[cy][cx].tileidx); vesa_WritePixelRow(offset + p_row_width * cx, tile + p_row_width * py, p_row_width); } x = COLNO * vesa_oview_width; @@ -869,7 +871,7 @@ vesa_redrawmap(void) for (cy = clipy; cy <= (unsigned) clipymax && cy < ROWNO; ++cy) { for (py = 0; py < (unsigned) iflags.wc_tile_height; ++py) { for (cx = clipx; cx <= (unsigned) clipxmax && cx < COLNO; ++cx) { - tile = vesa_tiles[map[cy][cx].tileidx]; + tile = vesa_tile(map[cy][cx].tileidx); vesa_WritePixelRow(offset + p_row_width * (cx - clipx), tile + p_row_width * py, p_row_width); } x = (cx - clipx) * iflags.wc_tile_width; @@ -1053,8 +1055,6 @@ vesa_Init(void) { static boolean inited = FALSE; const struct Pixel *paletteptr; - unsigned i; - unsigned num_pixels, num_oview_pixels; const char *tile_file; const char *font_name; int tilefailure = 0; @@ -1186,31 +1186,33 @@ vesa_Init(void) /* Process tiles for the current video mode */ vesa_tiles = (unsigned char **) alloc(total_tiles_used * sizeof(void *)); + memset(vesa_tiles, 0, total_tiles_used * sizeof(void *)); vesa_oview_tiles = (unsigned char **) alloc(total_tiles_used * sizeof(void *)); - num_pixels = iflags.wc_tile_width * iflags.wc_tile_height; - num_oview_pixels = vesa_oview_width * vesa_oview_height; + memset(vesa_oview_tiles, 0, total_tiles_used * sizeof(void *)); set_tile_type(vesa_pixel_size > 8); - for (i = 0; i < (unsigned) total_tiles_used; ++i) { - const struct TileImage *tile = get_tile(i); - struct TileImage *ov_tile = stretch_tile(tile, vesa_oview_width, vesa_oview_height); +} + +RESTORE_WARNING_FORMAT_NONLITERAL + +/* Return processed pixels for a normal tile */ +static unsigned char * +vesa_tile(unsigned index) +{ + if (vesa_tiles[index] == NULL) { + unsigned num_pixels = iflags.wc_tile_width * iflags.wc_tile_height; + const struct TileImage *tile = get_tile(index); unsigned j; unsigned char *t_img = (unsigned char *) alloc(num_pixels * vesa_pixel_bytes); - unsigned char *ot_img = (unsigned char *) alloc(num_oview_pixels * vesa_pixel_bytes); - vesa_tiles[i] = t_img; - vesa_oview_tiles[i] = ot_img; + vesa_tiles[index] = t_img; switch (vesa_pixel_bytes) { case 1: memcpy(t_img, tile->indexes, num_pixels); - memcpy(ot_img, ov_tile->indexes, num_oview_pixels); break; case 2: for (j = 0; j < num_pixels; ++j) { ((uint16_t *)t_img)[j] = vesa_MakeColor(tile->pixels[j]); } - for (j = 0; j < num_oview_pixels; ++j) { - ((uint16_t *)ot_img)[j] = vesa_MakeColor(ov_tile->pixels[j]); - } break; case 3: @@ -1220,6 +1222,42 @@ vesa_Init(void) t_img[3*j + 1] = (color >> 8) & 0xFF; t_img[3*j + 2] = (color >> 16) & 0xFF; } + break; + + case 4: + for (j = 0; j < num_pixels; ++j) { + ((uint32_t *)t_img)[j] = vesa_MakeColor(tile->pixels[j]); + } + break; + } + } + + return vesa_tiles[index]; +} + +/* Return processed pixels for an overview tile */ +static unsigned char * +vesa_oview_tile(unsigned index) +{ + if (vesa_oview_tiles[index] == NULL) { + unsigned num_oview_pixels = vesa_oview_width * vesa_oview_height; + const struct TileImage *tile = get_tile(index); + struct TileImage *ov_tile = stretch_tile(tile, vesa_oview_width, vesa_oview_height); + unsigned j; + unsigned char *ot_img = (unsigned char *) alloc(num_oview_pixels * vesa_pixel_bytes); + vesa_oview_tiles[index] = ot_img; + switch (vesa_pixel_bytes) { + case 1: + memcpy(ot_img, ov_tile->indexes, num_oview_pixels); + break; + + case 2: + for (j = 0; j < num_oview_pixels; ++j) { + ((uint16_t *)ot_img)[j] = vesa_MakeColor(ov_tile->pixels[j]); + } + break; + + case 3: for (j = 0; j < num_oview_pixels; ++j) { unsigned long color = vesa_MakeColor(ov_tile->pixels[j]); ot_img[3*j + 0] = color & 0xFF; @@ -1229,9 +1267,6 @@ vesa_Init(void) break; case 4: - for (j = 0; j < num_pixels; ++j) { - ((uint32_t *)t_img)[j] = vesa_MakeColor(tile->pixels[j]); - } for (j = 0; j < num_oview_pixels; ++j) { ((uint32_t *)ot_img)[j] = vesa_MakeColor(ov_tile->pixels[j]); } @@ -1239,10 +1274,9 @@ vesa_Init(void) } free_tile(ov_tile); } - free_tiles(); -} -RESTORE_WARNING_FORMAT_NONLITERAL + return vesa_oview_tiles[index]; +} /* Set the size of the map viewport */ static void @@ -1314,6 +1348,7 @@ vesa_Finish(void) } free(vesa_tiles); free(vesa_oview_tiles); + free_tiles(); vesa_SwitchMode(MODETEXT); windowprocs.win_cliparound = tty_cliparound; g_attribute = attrib_text_normal; @@ -1873,11 +1908,11 @@ vesa_DisplayCell(int tilenum, int col, int row) unsigned p_row_width; if (iflags.over_view) { - tile = vesa_oview_tiles[tilenum]; + tile = vesa_oview_tile(tilenum); t_width = vesa_oview_width; t_height = vesa_oview_height; } else { - tile = vesa_tiles[tilenum]; + tile = vesa_tile(tilenum); t_width = iflags.wc_tile_width; t_height = iflags.wc_tile_height; } diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index 792a32e2b..a546d67c1 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -213,8 +213,8 @@ int vp[SCREENPLANES] = { 8, 4, 2, 1 }; #endif int vp2[SCREENPLANES] = { 1, 2, 4, 8 }; -static struct planar_cell_struct planecell; -static struct overview_planar_cell_struct planecell_O; +static struct planar_cell_struct **cell_cache; +static struct overview_planar_cell_struct **cell_cache_O; /* static int g_attribute; */ /* Current attribute to use */ @@ -410,6 +410,7 @@ vga_xputg(const glyph_info *glyphinfo, vga_WriteChar(ch, col, row, attr); } else if (!iflags.over_view) { if ((col >= clipx) && (col <= clipxmax)) { + struct planar_cell_struct planecell; read_planar_tile(glyphnum, &planecell); if (map[ry][col].special) decal_planar(&planecell, special); @@ -426,6 +427,7 @@ vga_xputg(const glyph_info *glyphinfo, } } } else { + struct overview_planar_cell_struct planecell_O; read_planar_tile_O(glyphnum, &planecell_O); vga_DisplayCell_O(&planecell_O, col, row); } @@ -512,11 +514,13 @@ vga_redrawmap(boolean clearfirst) } else { t = map[y][x].glyph; if (!iflags.over_view) { + struct planar_cell_struct planecell; read_planar_tile(t, &planecell); if (map[y][x].special) decal_planar(&planecell, map[y][x].special); vga_DisplayCell(&planecell, x - clipx, y + TOP_MAP_ROW); } else { + struct overview_planar_cell_struct planecell_O; read_planar_tile_O(t, &planecell_O); vga_DisplayCell_O(&planecell_O, x, y + TOP_MAP_ROW); } @@ -643,6 +647,7 @@ boolean left; } for (y = 0; y < ROWNO; ++y) { for (x = i; x < j; x += 2) { + struct planar_cell_struct planecell; t = map[y][x].glyph; read_planar_tile(t, &planecell); if (map[y][x].special) @@ -656,47 +661,69 @@ boolean left; static void read_planar_tile(unsigned glyph, struct planar_cell_struct *cell) { + struct planar_cell_struct *pcell; unsigned char indexes[TILE_Y][TILE_X]; unsigned plane, y, byte, bit; + int tilenum = glyphmap[glyph].tileidx; - read_tile_indexes(glyph, indexes); - /* cell->plane[0..3].image[0..15][0..1] */ - for (plane = 0; plane < SCREENPLANES; ++plane) { - for (y = 0; y < TILE_Y; ++y) { - for (byte = 0; byte < MAX_BYTES_PER_CELL; ++byte) { - unsigned char b = 0; - for (bit = 0; bit < 8; ++bit) { - unsigned char x = byte * 8 + bit; - unsigned char i = indexes[y][x]; - b <<= 1; - if (i & (0x8 >> plane)) b |= 1; + /* Get the processed tile from the cache if we can */ + pcell = cell_cache[tilenum]; + if (pcell == NULL) { + /* Process the tile */ + pcell = (struct planar_cell_struct *) alloc(sizeof(*pcell)); + cell_cache[tilenum] = pcell; + read_tile_indexes(glyph, indexes); + /* pcell->plane[0..3].image[0..15][0..1] */ + for (plane = 0; plane < SCREENPLANES; ++plane) { + for (y = 0; y < TILE_Y; ++y) { + for (byte = 0; byte < MAX_BYTES_PER_CELL; ++byte) { + unsigned char b = 0; + for (bit = 0; bit < 8; ++bit) { + unsigned char x = byte * 8 + bit; + unsigned char i = indexes[y][x]; + b <<= 1; + if (i & (0x8 >> plane)) b |= 1; + } + pcell->plane[plane].image[y][byte] = b; } - cell->plane[plane].image[y][byte] = b; } } } + + *cell = *pcell; } static void read_planar_tile_O(unsigned glyph, struct overview_planar_cell_struct *cell) { + struct overview_planar_cell_struct *pcell; unsigned char indexes[TILE_Y][TILE_X]; unsigned plane, y, bit; + int tilenum = glyphmap[glyph].tileidx; - read_tile_indexes(glyph, indexes); - /* cell->plane[0..3].image[0..15][0..0] */ - for (plane = 0; plane < SCREENPLANES; ++plane) { - for (y = 0; y < TILE_Y; ++y) { - unsigned char b = 0; - for (bit = 0; bit < 8; ++bit) { - unsigned char x = bit * 2; - unsigned char i = indexes[y][x]; - b <<= 1; - if (i & (0x8 >> plane)) b |= 1; + /* Get the processed tile from the cache if we can */ + pcell = cell_cache_O[tilenum]; + if (pcell == NULL) { + /* Process the tile */ + pcell = (struct overview_planar_cell_struct *) alloc(sizeof(*pcell)); + cell_cache_O[tilenum] = pcell; + read_tile_indexes(glyph, indexes); + /* pcell->plane[0..3].image[0..15][0..0] */ + for (plane = 0; plane < SCREENPLANES; ++plane) { + for (y = 0; y < TILE_Y; ++y) { + unsigned char b = 0; + for (bit = 0; bit < 8; ++bit) { + unsigned char x = bit * 2; + unsigned char i = indexes[y][x]; + b <<= 1; + if (i & (0x8 >> plane)) b |= 1; + } + pcell->plane[plane].image[y][0] = b; } - cell->plane[plane].image[y][0] = b; } } + + *cell = *pcell; } static void @@ -782,6 +809,15 @@ vga_Init(void) /* term_clear_screen() */ /* not vga_clear_screen() */ return; } + + if (cell_cache == NULL) { + cell_cache = (struct planar_cell_struct **) alloc( + total_tiles_used * sizeof(cell_cache[0])); + memset(cell_cache, 0, total_tiles_used * sizeof(cell_cache[0])); + cell_cache_O = (struct overview_planar_cell_struct **) alloc( + total_tiles_used * sizeof(cell_cache_O[0])); + memset(cell_cache_O, 0, total_tiles_used * sizeof(cell_cache_O[0])); + } #endif if (iflags.usevga) { @@ -860,7 +896,17 @@ vga_SwitchMode(unsigned int mode) void vga_Finish(void) { + int i; + free_tiles(); + for (i = 0; i < total_tiles_used; ++i) { + free(cell_cache[i]); + free(cell_cache_O[i]); + } + free(cell_cache); + cell_cache = NULL; + free(cell_cache_O); + cell_cache_O = NULL; vga_SwitchMode(MODETEXT); windowprocs.win_cliparound = tty_cliparound; g_attribute = attrib_text_normal; diff --git a/win/share/tileset.c b/win/share/tileset.c index 2fff3affa..385d26580 100644 --- a/win/share/tileset.c +++ b/win/share/tileset.c @@ -30,6 +30,9 @@ read_tiles(const char *filename, boolean true_color) char header[16]; boolean ok; + if (tiles != NULL) + return; + /* Fill the image structure with known values */ image.width = 0; image.height = 0; @@ -283,7 +286,7 @@ split_tiles(const struct TileSetImage *image) { unsigned tile_rows, tile_cols; size_t tile_size, i, j; - unsigned x1, y1, x2, y2; + unsigned x1, y1, y2; /* Get the number of tiles */ tile_rows = image->height / iflags.wc_tile_height; @@ -308,16 +311,15 @@ split_tiles(const struct TileSetImage *image) tile->indexes = (unsigned char *) alloc(tile_size); } for (y2 = 0; y2 < (unsigned) iflags.wc_tile_height; ++y2) { - for (x2 = 0; x2 < (unsigned) iflags.wc_tile_width; ++x2) { - unsigned x = x1 * iflags.wc_tile_width + x2; - unsigned y = y1 * iflags.wc_tile_height + y2; - - i = y * image->width + x; - j = y2 * tile->width + x2; - tile->pixels[j] = image->pixels[i]; - if (image->indexes != NULL) { - tile->indexes[j] = image->indexes[i]; - } + unsigned y = y1 * iflags.wc_tile_height + y2; + unsigned x = x1 * iflags.wc_tile_width; + i = y * image->width; + j = y2 * tile->width; + memcpy(tile->pixels + j, image->pixels + i + x, + sizeof(tile->pixels[0]) * iflags.wc_tile_width); + if (image->indexes != NULL) { + memcpy(tile->indexes + j, image->indexes + i + x, + iflags.wc_tile_width); } } } From adbab7f767cd60758c5556ccedce9a02fd1640e0 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 4 Jul 2026 14:17:43 -0400 Subject: [PATCH 532/702] periodic style check: whitespace cleanup leading tabs and trailing blanks --- src/earlyarg.c | 2 +- src/read.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/earlyarg.c b/src/earlyarg.c index 952defaaa..2209e9323 100755 --- a/src/earlyarg.c +++ b/src/earlyarg.c @@ -498,7 +498,7 @@ argcheck(int argc, char *argv[], enum earlyarg e_arg) if (extended_opt) { extended_opt++; - if (match_optname(extended_opt, "copy", 4, FALSE)) { + if (match_optname(extended_opt, "copy", 4, FALSE)) { insert_into_pastebuf = TRUE; } else if (match_optname(extended_opt, "dump", 4, FALSE)) { /* version number plus enabled features and sanity diff --git a/src/read.c b/src/read.c index 27b2ab588..a8437bc16 100644 --- a/src/read.c +++ b/src/read.c @@ -180,7 +180,7 @@ tshirt_text(struct obj *tshirt, char *buf) from book series _A_Song_of_Ice_and_Fire_ by George R.R. Martin, TV show "Game of Thrones" (probably an actual T-shirt too...) */ "/Valar morghulis/ -- /Valar dohaeris/", - "Asidonhopo once said: the namesake of my enemy is my enemy", + "Asidonhopo once said: the namesake of my enemy is my enemy", }; Strcpy(buf, shirt_msgs[tshirt->o_id % SIZE(shirt_msgs)]); From 25be6848306c7dea81a5ad763c3754e708eb6b49 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 4 Jul 2026 14:29:54 -0400 Subject: [PATCH 533/702] trailing spaces removed from generated nhlua.h --- sys/windows/vs/nhlua_h/nhlua_h.vcxproj | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sys/windows/vs/nhlua_h/nhlua_h.vcxproj b/sys/windows/vs/nhlua_h/nhlua_h.vcxproj index 2f8f14f28..1a516d3fb 100644 --- a/sys/windows/vs/nhlua_h/nhlua_h.vcxproj +++ b/sys/windows/vs/nhlua_h/nhlua_h.vcxproj @@ -47,12 +47,12 @@ - - - - - - + + + + + + @@ -60,4 +60,4 @@ - \ No newline at end of file + From 9004f49b014185e34e9c69176c8f05cd2e6ddd5f Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 4 Jul 2026 19:12:00 -0700 Subject: [PATCH 534/702] GENERICUSERS in Guidebook --- doc/Guidebook.mn | 8 ++++++-- doc/Guidebook.tex | 6 +++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 5e64b337c..1494ad7cf 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -4426,8 +4426,9 @@ is used for the role, then a random one will be automatically chosen. .lp "" On some systems, the default is the player's user name; on others, there is no default and the player will be prompted. -The former can made to behave like the latter by specifying a generic name -such as ``player''. The GENERICUSERS= setting in sysconf controls wich +The former can be made to behave like the latter by specifying a generic name +such as ``player''. +The GENERICUSERS= setting in sysconf controls which names are considered generic. Cannot be set with the \(oq\f(CRO\fP\(cq command. .lp "news " @@ -6297,6 +6298,9 @@ escape command (!). The syntax is the same as WIZARDS. EXPLORERS\ =\ A list of users who are allowed to use the explore mode. The syntax is the same as WIZARDS. .lp +GENERICUSERS\ =\ A list of user names that should prompt ``Who are you?'' +rather than become a character's name. +.lp MSGHANDLER\ =\ A path and filename of executable. Whenever a message-window message is shown, NetHack runs this program. The program will get the message as the only parameter. diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index c52050197..804df47ec 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -4823,7 +4823,7 @@ automatically chosen. On some systems, the default is the player's user name; on others, there is no default and the player will be prompted. The former can made to behave like the latter by specifying a generic name -such as ``player''. The GENERICUSERS= setting in sysconf controls wich +such as ``player''. The GENERICUSERS= setting in sysconf controls which names are considered generic. Cannot be set with the `\texttt{O}' command. %.lp @@ -6916,6 +6916,10 @@ The syntax is the same as WIZARDS. A list of users who are allowed to use the explore mode. The syntax is the same as WIZARDS. %.lp +\item[GENERICUSERS] +A list of user names that should prompt ``Who are you?'' +rather than become a character's name. +%.lp \item[MSGHANDLER] A path and filename of executable. Whenever a message-window message is shown, \textit{NetHack} runs this program. The program will get From 4761d45debc99325896f72851b7b7cd160009329 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 4 Jul 2026 23:43:41 -0400 Subject: [PATCH 535/702] Guidebook.txt update - July 4, 2026 --- doc/Guidebook.txt | 1360 ++++++++++++++++++++++----------------------- 1 file changed, 680 insertions(+), 680 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 96803add8..618fdac8f 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for NetHack 5.0.0 by Mike Stephenson and others) - June 23, 2026 + July 4, 2026 @@ -126,7 +126,7 @@ employ to great advantage. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -192,7 +192,7 @@ NetHack continues this fine tradition. Unlike text adventure games - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -258,7 +258,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -324,7 +324,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -390,7 +390,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -456,7 +456,7 @@ The number of turns elapsed so far, displayed if you have the - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -522,7 +522,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -588,7 +588,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -654,7 +654,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -720,7 +720,7 @@ instead. Only these one-step movement commands cause you to - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -786,7 +786,7 @@ ing . ^ is used as shorthand elsewhere in the - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -852,7 +852,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -918,7 +918,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -984,7 +984,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1050,7 +1050,7 @@ at an adjacent "remembered, unseen monster" marker. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1116,7 +1116,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1182,7 +1182,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1248,7 +1248,7 @@ (R)UNIX is a registered trademark of The Open Group. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1314,7 +1314,7 @@ inventory slot. If it has a name assigned, other stacks with the - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1380,7 +1380,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1446,7 +1446,7 @@ fight there. Default key is `F', or `-' with number_pad - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1512,7 +1512,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1578,7 +1578,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1644,7 +1644,7 @@ Pick up things at the current location. Default key is `,'. The - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1710,7 +1710,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1776,7 +1776,7 @@ worn. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1842,7 +1842,7 @@ Suspend the game, switching from NetHack to the terminal it was - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1908,7 +1908,7 @@ pick one from inventory, except for the special case of - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1974,7 +1974,7 @@ menu of sorting orders available (provided that the vanquished - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2040,7 +2040,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2106,7 +2106,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2172,7 +2172,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2238,7 +2238,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2304,7 +2304,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2370,7 +2370,7 @@ them). Some monsters who can open doors can also use unlocking tools. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2436,7 +2436,7 @@ been nullified, giving access to whatever is beyond them. In the - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2502,7 +2502,7 @@ play. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2568,7 +2568,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2634,7 +2634,7 @@ attack, when guessing where an unseen monster is or when deliberately - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2700,7 +2700,7 @@ noid_confirmation:attack option to require a response of "yes" - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2766,7 +2766,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2832,7 +2832,7 @@ are encumbered, one of the conditions Burdened, Stressed, Strained, - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2898,7 +2898,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2964,7 +2964,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3030,7 +3030,7 @@ aklys, lucern hammer, and bec-de-corbin) are defined in an appendix to - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3096,7 +3096,7 @@ shots by using a numeric prefix before the `t' or `f' command. For - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3162,7 +3162,7 @@ first you need to have a weapon in each hand. (Note that your two - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3228,7 +3228,7 @@ even further. Most of these provide a one or two point improvement to - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3294,7 +3294,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3360,7 +3360,7 @@ yourself (just give a `.' or `s' for the direction). Be warned, how- - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3426,7 +3426,7 @@ your ken can be harmful to your health! - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3492,7 +3492,7 @@ play the entire game without being able to see (a self-imposed chal- - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3558,7 +3558,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3624,7 +3624,7 @@ set the goldX option if you prefer to have gold pieces be treated as - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3690,7 +3690,7 @@ eating such items still counts against foodless conduct. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3756,7 +3756,7 @@ monster (i.e. if you would get experience for the death). This is a - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3822,7 +3822,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3888,7 +3888,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3954,7 +3954,7 @@ ning NetHack for the first time, you should find a default template - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4020,7 +4020,7 @@ [not available on Unix] - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4086,7 +4086,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4152,7 +4152,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4218,7 +4218,7 @@ be set to the full name of a configuration file you want to use. If - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4284,7 +4284,7 @@ Automatically dig if you are wielding a digging tool and moving into - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4350,7 +4350,7 @@ nearby monsters. Successfully forcing a container open will break - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4416,7 +4416,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4482,7 +4482,7 @@ extended command, it controls whether the menu shows all available - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4548,7 +4548,7 @@ might miss some interesting and/or important information. Persis- - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4614,7 +4614,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4680,7 +4680,7 @@ class(es). Combination starts with a prompt for object class(es) of - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4746,7 +4746,7 @@ 5 - One-or-other - show symbols on headers, or on entries if no - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4812,7 +4812,7 @@ port is the same as specifying 0. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4849,12 +4849,13 @@ On some systems, the default is the player's user name; on others, there is no default and the player will be prompted. The former can - made to behave like the latter by specifying a generic name such as - ``player''. Cannot be set with the `O' command. + be made to behave like the latter by specifying a generic name such + as ``player''. The GENERICUSERS= setting in sysconf controls which + names are considered generic. Cannot be set with the `O' command. news Read the NetHack news file, if present (default on). Since the news - is shown at the beginning of the game, there's no point in setting + is shown at the beginning of the game, there's no point in setting this with the `O' command. nudist @@ -4875,10 +4876,9 @@ -1 - by letters but use `z' to go northwest, `y' to zap wands For backward compatibility, omitting a value is the same as specify- - ing 1 and negating number_pad is the same as specifying 0. (Set- - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4888,63 +4888,63 @@ - tings 2 and 4 are for compatibility with MS-DOS or old PC Hack; in - addition to the different behavior for `5', `Alt-5' acts as `G' and - `Alt-0' acts as `I'. Setting -1 is to accommodate some QWERTZ key- - boards which have the location of the `y' and `z' keys swapped.) - When moving by numbers, to enter a count prefix for those commands - which accept one (such as "12s" to search twelve times), precede it + ing 1 and negating number_pad is the same as specifying 0. (Set- + tings 2 and 4 are for compatibility with MS-DOS or old PC Hack; in + addition to the different behavior for `5', `Alt-5' acts as `G' and + `Alt-0' acts as `I'. Setting -1 is to accommodate some QWERTZ key- + boards which have the location of the `y' and `z' keys swapped.) + When moving by numbers, to enter a count prefix for those commands + which accept one (such as "12s" to search twelve times), precede it with the letter `n' ("n12s"). packorder - Specify the order to list object types in (default + Specify the order to list object types in (default "")[%?+!=/(*`0_"). The value of this option should be a string con- taining the symbols for the various object types. Any omitted types are filled in at the end from the previous order. paranoid_confirmation - A space separated list of specific situations where alternate - prompting is desired. The default is "paranoid_confirmation:pray + A space separated list of specific situations where alternate + prompting is desired. The default is "paranoid_confirmation:pray swim trap". - Confirm - for any prompts which are set to require "yes" rather - than `y', also require "no" to reject instead of + Confirm - for any prompts which are set to require "yes" rather + than `y', also require "no" to reject instead of accepting any non-yes response as no; changes pray and AutoAll to require "yes" or `no' too; - quit - require "yes" rather than `y' to confirm quitting the + quit - require "yes" rather than `y' to confirm quitting the game or switching into non-scoring explore mode; - die - require "yes" rather than `y' to confirm dying (not + die - require "yes" rather than `y' to confirm dying (not useful in normal play; applies to explore mode); - bones - require "yes" rather than `y' to confirm saving bones + bones - require "yes" rather than `y' to confirm saving bones data when dying in debug mode; - attack - require "yes" rather than `y' to confirm attacking a + attack - require "yes" rather than `y' to confirm attacking a peaceful monster; - wand-break - require "yes" rather than `y' to confirm breaking a + wand-break - require "yes" rather than `y' to confirm breaking a wand with the apply command; - eating - require "yes" rather than `y' to confirm whether to + eating - require "yes" rather than `y' to confirm whether to continue eating; Were-change - require "yes" rather than `y' to confirm changing form due to lycanthropy when hero has polymorph control; - pray - require `y' to confirm an attempt to pray rather than - immediately praying; on by default; (to require "yes" + pray - require `y' to confirm an attempt to pray rather than + immediately praying; on by default; (to require "yes" rather than just `y', set Confirm too); trap - require `y' to confirm an attempt to move into or onto - a known trap, unless doing so is considered to be + a known trap, unless doing so is considered to be harmless; when enabled, this confirmation is also used for moving into visible gas cloud regions; (to require - "yes" rather than just `y', set Confirm too); confir- - mation can be skipped by using the `m' movement pre- + "yes" rather than just `y', set Confirm too); confir- + mation can be skipped by using the `m' movement pre- fix; swim - prevent walking into water or lava; on by default; (to - deliberately step onto/into such terrain when this is + deliberately step onto/into such terrain when this is set, use the `m' movement prefix when adjacent); - AutoAll - require confirmation when the `A' (Autoselect-All) + AutoAll - require confirmation when the `A' (Autoselect-All) choice is selected in object class filtering menus for - menustyle:Full; (to require "yes" rather than just - `y', set Confirm too); + menustyle:Full; (to require "yes" rather than just - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4954,39 +4954,40 @@ - Remove - require selection from inventory for `R' and `T' com- + `y', set Confirm too); + Remove - require selection from inventory for `R' and `T' com- mands even when wearing just one applicable item; all - turn on all of the above. By default, the pray, swim, and trap choices are enabled, the others disabled. To disable them without setting any of the other choices, - use paranoid_confirmation:none. To keep them enabled while setting - any of the others, you can include them in the new list, such as + use paranoid_confirmation:none. To keep them enabled while setting + any of the others, you can include them in the new list, such as paranoid_confirmation:attack pray swim Remove or you can precede the - first entry in the list with a plus sign, paranoid_confirma- - tion:+attack Remove. To remove an entry that has been previously - set without removing others, precede the first entry in the list - with a minus sign, paranoid_confirmation:-swim. To both add some - new entries and remove some old ones, you can use multiple para- - noid_confirmation option settings, or you can use the `+' form and - list entries to be added by their name and entries to be removed by + first entry in the list with a plus sign, paranoid_confirma- + tion:+attack Remove. To remove an entry that has been previously + set without removing others, precede the first entry in the list + with a minus sign, paranoid_confirmation:-swim. To both add some + new entries and remove some old ones, you can use multiple para- + noid_confirmation option settings, or you can use the `+' form and + list entries to be added by their name and entries to be removed by `!' and name. The positive (no `!') and negative (with `!') entries can be intermixed. pauper - Start the character with no possessions (default false). Persis- + Start the character with no possessions (default false). Persis- tent. - Also start with no spells or skills, which are tied to starting - equipment. Does not inhibit acquiring and using items, spells, and + Also start with no spells or skills, which are tied to starting + equipment. Does not inhibit acquiring and using items, spells, and skills once play has started. perm_invent - If true, always display your current inventory in a window (default + If true, always display your current inventory in a window (default false). This only makes sense for windowing system interfaces that implement - this feature. For those that do, the perminv_mode option can be + this feature. For those that do, the perminv_mode option can be used to refine what gets displayed for perm_invent. Setting that to a value other than none while perm_invent is false will change it to true. @@ -5007,10 +5008,9 @@ petattr Specifies one or more text highlighting attributes to use when show- - ing pets on the map. Effectively a superset of the hilite_pet bool- - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5020,63 +5020,63 @@ - ean option. Curses or tty interface only; value is one of none, - bold, dim, underline, italic, blink, and inverse. Some of those + ing pets on the map. Effectively a superset of the hilite_pet bool- + ean option. Curses or tty interface only; value is one of none, + bold, dim, underline, italic, blink, and inverse. Some of those choices might not work, depending upon terminal hardware or terminal emulation software. pettype Specify the type of your initial pet, if you are playing a character class that uses multiple types of pets; or choose to have no initial - pet at all. Possible values are "cat", "dog", "horse", and "none". + pet at all. Possible values are "cat", "dog", "horse", and "none". If the choice is not allowed for the role you are currently playing, it will be silently ignored. For example, "horse" will only be hon- ored when playing a knight. Cannot be set with the `O' command. pickup_burden - When you pick up an item that would exceed this encumbrance level - (Unencumbered, Burdened, streSsed, straiNed, overTaxed, or over- - Loaded), you will be asked if you want to continue. (Default `S'). + When you pick up an item that would exceed this encumbrance level + (Unencumbered, Burdened, streSsed, straiNed, overTaxed, or over- + Loaded), you will be asked if you want to continue. (Default `S'). Persistent. pickup_stolen - If this option is on and autopickup is also on, try to pick up - things that a monster stole from you, even if they aren't in + If this option is on and autopickup is also on, try to pick up + things that a monster stole from you, even if they aren't in pickup_types or match an autopickup exception. Default is on. Per- sistent. pickup_thrown - If this option is on and autopickup is also on, try to pick up - things that you threw, even if they aren't in pickup_types or match + If this option is on and autopickup is also on, try to pick up + things that you threw, even if they aren't in pickup_types or match an autopickup exception. Default is on. Persistent. pickup_types - Specify the object types to be picked up when autopickup is on. + Specify the object types to be picked up when autopickup is on. Default is all types. Persistent. - The value is a list of object symbols, such as pickup_types:$?! to - pick up gold, scrolls, and potions. You can use autopickup_excep- + The value is a list of object symbols, such as pickup_types:$?! to + pick up gold, scrolls, and potions. You can use autopickup_excep- tion configuration file lines to further refine autopickup behavior. - There is no way to set pickup_types to "none". (Setting it to an - empty value reverts to "all".) If you want to avoid automatically - picking up any types of items but do want to have autopickup on in - order to have autopickup_exception settings control what you do and - don't pick up, you can set pickup_types to `.'. That is the type - symbol for venom and you won't come across any venom items so won't + There is no way to set pickup_types to "none". (Setting it to an + empty value reverts to "all".) If you want to avoid automatically + picking up any types of items but do want to have autopickup on in + order to have autopickup_exception settings control what you do and + don't pick up, you can set pickup_types to `.'. That is the type + symbol for venom and you won't come across any venom items so won't unintentionally pick such up. pile_limit - When walking across a pile of objects on the floor, threshold at + When walking across a pile of objects on the floor, threshold at which the message "there are few/several/many objects here" is given - instead of showing a popup list of those objects. A value of 0 + instead of showing a popup list of those objects. A value of 0 means "no limit" (always list the objects); a value of 1 effectively means "never show the objects" since the pile size will always be at least that big; default value is 5. Persistent. - - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5087,28 +5087,28 @@ playmode - Values are "normal", "explore", or "debug". Allows selection of - explore mode (also known as discovery mode) or debug mode (also + Values are "normal", "explore", or "debug". Allows selection of + explore mode (also known as discovery mode) or debug mode (also known as wizard mode) instead of normal play. Debug mode might only - be allowed for someone logged in under a particular user name (on - multi-user systems) or specifying a particular character name (on - single-user systems) or it might be disabled entirely. Requesting + be allowed for someone logged in under a particular user name (on + multi-user systems) or specifying a particular character name (on + single-user systems) or it might be disabled entirely. Requesting it when not allowed or not possible results in explore mode instead. Default is normal play. price_quotes Whenever the game mentions the name of an object you haven't identi- fied yet, it also mentions the range of buy and sell prices you have - seen for that item (to help narrow down what it could be). The - price shown is the unit price for one item (even when you are look- - ing at a stack of multiple items). Many players may want to turn - this on while identifying objects, and then turn it back off again + seen for that item (to help narrow down what it could be). The + price shown is the unit price for one item (even when you are look- + ing at a stack of multiple items). Many players may want to turn + this on while identifying objects, and then turn it back off again for general play. Default is off. pushweapon Using the `w' (wield) command when already wielding something pushes - the old item into your alternate weapon slot (default off). Like- - wise for the `a' (apply) command if it causes the applied item to + the old item into your alternate weapon slot (default off). Like- + wise for the `a' (apply) command if it causes the applied item to become wielded. Persistent. query_menu @@ -5116,33 +5116,33 @@ quick_farsight When set, usually prevents the "you sense your surroundings" message - where play pauses to allow you to browse the map whenever clairvoy- - ance randomly activates. Some situations, such as being underwater - or engulfed, ignore this option. It does not affect the clairvoy- - ance spell where pausing to examine revealed objects or monsters is + where play pauses to allow you to browse the map whenever clairvoy- + ance randomly activates. Some situations, such as being underwater + or engulfed, ignore this option. It does not affect the clairvoy- + ance spell where pausing to examine revealed objects or monsters is less intrusive. Default is off. Persistent. race - Selects your race (for example, race:human). Choices are human, + Selects your race (for example, race:human). Choices are human, dwarf, elf, gnome, and orc but most roles restrict which of the non- - human races are allowed. See role for a description of how to use + human races are allowed. See role for a description of how to use negation to exclude choices. - If race is not specified, there is no default value; player will be - prompted unless role forces a choice for race. Cannot be set with + If race is not specified, there is no default value; player will be + prompted unless role forces a choice for race. Cannot be set with the `O' command. Persistent. reroll - Allows rerolling your character's starting inventory and attributes + Allows rerolling your character's starting inventory and attributes (default false). Persistent. - Note that rerolling your character is not a recommended way to play - if aiming merely to win (a lucky start has a much smaller influence - on whether or not you win the game than your actions later in the - game). This option exists partly as an acknowledgement that some + Note that rerolling your character is not a recommended way to play + if aiming merely to win (a lucky start has a much smaller influence + on whether or not you win the game than your actions later in the + game). This option exists partly as an acknowledgement that some - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5156,17 +5156,17 @@ may be necessary for certain types of challenge games. rest_on_space - Make the space bar a synonym for the `.' (#wait) command (default + Make the space bar a synonym for the `.' (#wait) command (default off). Persistent. role Pick your type of character (for example, role:Samurai); synonym for - character. See name for an alternate method of specifying your + character. See name for an alternate method of specifying your role. - This option can also be used to limit selection when role is chosen - randomly. Use a space-separated list of roles and either negate - each one or negate the option itself instead. Negation is accom- + This option can also be used to limit selection when role is chosen + randomly. Use a space-separated list of roles and either negate + each one or negate the option itself instead. Negation is accom- plished in the same manner as with boolean options, by prefixing the option or its value(s) with `!' or "no". Examples: @@ -5174,10 +5174,10 @@ OPTIONS=role:!arc !bar !kni OPTIONS=!role:arc bar kni - There can be multiple instances of the role option if they're all + There can be multiple instances of the role option if they're all negations. - If role is not specified, there is no default value; player will be + If role is not specified, there is no default value; player will be prompted. Cannot be set with the `O' command. Persistent. roguesymset @@ -5186,14 +5186,14 @@ rogue level. rlecomp - When writing out a save file, perform run length compression of the + When writing out a save file, perform run length compression of the map. Not all ports support run length compression. It has no effect on reading an existing save file. runmode - Controls the amount of screen updating for the map window when - engaged in multi-turn movement (running via shift+direction or con- - trol+direction and so forth, or via the travel command or mouse + Controls the amount of screen updating for the map window when + engaged in multi-turn movement (running via shift+direction or con- + trol+direction and so forth, or via the travel command or mouse click). The possible values are: teleport - update the map after movement has finished; @@ -5201,14 +5201,14 @@ walk - update the map after each step; crawl - like walk, but pause briefly after each step. - This option only affects the game's screen display, not the actual - results of moving. The default is "run"; versions prior to 3.4.1 - used "teleport" only. Whether or not the effect is noticeable will - depend upon the window port used or on the type of terminal. Per- + This option only affects the game's screen display, not the actual + results of moving. The default is "run"; versions prior to 3.4.1 + used "teleport" only. Whether or not the effect is noticeable will + depend upon the window port used or on the type of terminal. Per- sistent. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5223,48 +5223,48 @@ sistent. safe_wait - Prevents you from waiting or searching when next to a hostile mon- + Prevents you from waiting or searching when next to a hostile mon- ster (default on). Persistent. sanity_check - Evaluate monsters, objects, and map prior to each turn (default + Evaluate monsters, objects, and map prior to each turn (default off). Debug mode only. scores - Control what parts of the score list you are shown at the end (for - example "scores:5 top scores/4 around my score/own scores"). Only - the first letter of each category (`t', `a', or `o') is necessary. + Control what parts of the score list you are shown at the end (for + example "scores:5 top scores/4 around my score/own scores"). Only + the first letter of each category (`t', `a', or `o') is necessary. Persistent. showdamage - Whenever your character takes damage, show a message of the damage + Whenever your character takes damage, show a message of the damage taken, and the amount of hit points left. showexp - Show your accumulated experience points on bottom line (default + Show your accumulated experience points on bottom line (default off). Persistent. showrace - Display yourself as the glyph for your race, rather than the glyph - for your role (default off). Note that this setting affects only - the appearance of the display, not the way the game treats you. + Display yourself as the glyph for your race, rather than the glyph + for your role (default off). Note that this setting affects only + the appearance of the display, not the way the game treats you. Persistent. showscore - Show your approximate accumulated score on bottom line (default + Show your approximate accumulated score on bottom line (default off). By default, this feature is suppressed when building the pro- gram. Persistent. showvers Include the game's version number on the status lines (default off). Potentially useful if you switch between different versions or vari- - ants, or you are making screenshots or streaming video. Using the - statuslines:3 option is recommended so that there will be more room - available for status information, unless you're using NetHack's Qt - interface or your terminal emulator window displays fewer than 25 + ants, or you are making screenshots or streaming video. Using the + statuslines:3 option is recommended so that there will be more room + available for status information, unless you're using NetHack's Qt + interface or your terminal emulator window displays fewer than 25 lines. Persistent. - The versinfo option provides limited control over what information + The versinfo option provides limited control over what information showvers displays. silent @@ -5274,7 +5274,7 @@ Controls the sorting behavior for the output of the `\' and ``' com- - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5288,32 +5288,32 @@ The possible values are: - o - list object types by class, in discovery order within each + o - list object types by class, in discovery order within each class; default; - s - list object types by sortloot classification: by class, by sub- - class within class for classes which have substantial groupings - (like helmets, boots, gloves, and so forth for armor), with - object types partly-discovered via assigned name coming before + s - list object types by sortloot classification: by class, by sub- + class within class for classes which have substantial groupings + (like helmets, boots, gloves, and so forth for armor), with + object types partly-discovered via assigned name coming before fully identified types; c - list by class, alphabetically within each class; a - list alphabetically across all classes. - Can be interactively set via the `O' command or via using the `m' + Can be interactively set via the `O' command or via using the `m' prefix before the `\' or ``' command. sortloot - Controls the sorting behavior of the pickup lists for inventory and + Controls the sorting behavior of the pickup lists for inventory and #loot commands and some others. Persistent. The possible values are: full - always sort the lists; - loot - only sort the lists that don't use inventory letters, like + loot - only sort the lists that don't use inventory letters, like with the #loot and pickup commands; none - show lists the traditional way without sorting; default. sortpack - Sort the pack contents by type when displaying inventory (default + Sort the pack contents by type when displaying inventory (default on). Persistent. sortvanquished @@ -5324,23 +5324,23 @@ t - traditional--order by monster level; ties are broken by internal monster index; default; - d - order by monster difficulty rating; ties broken by internal + d - order by monster difficulty rating; ties broken by internal index; - a - order alphabetically, first any unique monsters then all the + a - order alphabetically, first any unique monsters then all the others; c - order by monster class, by low to high level within each class; n - order by count, high to low; ties are broken by internal monster index; z - order by count, low to high; ties broken by internal index. - Can be interactively set via the `m O' command or via using the `m' - prefix before either the #vanquished command or the #genocided com- + Can be interactively set via the `m O' command or via using the `m' + prefix before either the #vanquished command or the #genocided com- mand. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5355,7 +5355,7 @@ on). sparkle - Display a sparkly effect when a monster (including yourself) is hit + Display a sparkly effect when a monster (including yourself) is hit by an attack to which it is resistant (default on). Persistent. spot_monsters @@ -5370,32 +5370,32 @@ ing Status Hilites" for further information. status_updates - Allow updates to the status lines at the bottom of the screen + Allow updates to the status lines at the bottom of the screen (default true). suppress_alert - This option may be set to a NetHack version level to suppress alert - notification messages about feature changes for that and prior ver- + This option may be set to a NetHack version level to suppress alert + notification messages about feature changes for that and prior ver- sions (for example "suppress_alert:3.3.1"). symset This option may be used to select one of the named symbol sets found - within "symbols" to alter the symbols displayed on the screen. Use + within "symbols" to alter the symbols displayed on the screen. Use "symset:default" to explicitly select the default symbols. terrainstatus - Display an extra status condition describing the spot beneath the + Display an extra status condition describing the spot beneath the hero's feet (default off, not supported by all interfaces). time - Show the elapsed game time in turns on bottom line (default off). + Show the elapsed game time in turns on bottom line (default off). Persistent. timed_delay When pausing momentarily for display effect, such as with explosions and moving objects, use a timer rather than sending extra characters - to the screen. (Applies to "tty" and "curses" interfaces only; - "X11" interface always uses a timer-based delay. The default is on + to the screen. (Applies to "tty" and "curses" interfaces only; + "X11" interface always uses a timer-based delay. The default is on if configured into the program.) Persistent. tips @@ -5406,7 +5406,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5417,8 +5417,8 @@ toptenwin - Put the ending display in a NetHack window instead of on stdout - (default off). Setting this option makes the score list visible + Put the ending display in a NetHack window instead of on stdout + (default off). Setting this option makes the score list visible when a windowing version of NetHack is started without a parent win- dow, but it no longer leaves the score list around after game end on a terminal or emulating window. @@ -5426,7 +5426,7 @@ travel Allow the travel command via mouse click (default on). Turning this option off will prevent the game from attempting unintended moves if - you make inadvertent mouse clicks on the map window. Does not + you make inadvertent mouse clicks on the map window. Does not affect traveling via the `_' ("#travel") command. Persistent. tutorial @@ -5440,7 +5440,7 @@ Controls what the showvers option displays on the status lines. weaponstatus - Display an extra status condition which describes currently wielded + Display an extra status condition which describes currently wielded weapon (default off, not supported by all interfaces). Some possible displayed values are: @@ -5450,8 +5450,8 @@ dual-weps - wielding two weapons. whatis_coord - When using the `/' or `;' commands to look around on the map with - autodescribe on, display coordinates after the description. Also + When using the `/' or `;' commands to look around on the map with + autodescribe on, display coordinates after the description. Also works in other situations where you are asked to pick a location. The possible settings are: @@ -5462,17 +5462,17 @@ s - screen [row,column] (row is offset to match tty usage); n - none (no coordinates shown) [default]. - The whatis_coord option is also used with the "/m", "/M", "/o", and - "/O" sub-commands of `/', where the "none" setting is overridden + The whatis_coord option is also used with the "/m", "/M", "/o", and + "/O" sub-commands of `/', where the "none" setting is overridden with "map". whatis_filter - When getting a location on the map, and using the keys to cycle - through next and previous targets, allows filtering the possible + When getting a location on the map, and using the keys to cycle + through next and previous targets, allows filtering the possible targets. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5486,8 +5486,8 @@ v - in view only a - in same area only - The area-filter tries to be slightly predictive--if you're standing - on a doorway, it will consider the area on the side of the door you + The area-filter tries to be slightly predictive--if you're standing + on a doorway, it will consider the area on the side of the door you were last moving towards. Filtering can also be changed when getting a location with the "get- @@ -5495,50 +5495,50 @@ whatis_menu When getting a location on the map, and using a key to cycle through - next and previous targets, use a menu instead to pick a target. + next and previous targets, use a menu instead to pick a target. (default off) whatis_moveskip - When getting a location on the map, and using shifted movement keys - or meta-digit keys to fast-move, instead of moving 8 units at a + When getting a location on the map, and using shifted movement keys + or meta-digit keys to fast-move, instead of moving 8 units at a time, move by skipping the same glyphs. (default off) windowtype - When the program has been built to support multiple interfaces, - select which one to use, such as "tty" or "X11" (default depends on - build-time settings; use "#version" to check). Cannot be set with + When the program has been built to support multiple interfaces, + select which one to use, such as "tty" or "X11" (default depends on + build-time settings; use "#version" to check). Cannot be set with the `O' command. - When used, it should be the first option set since its value might - enable or disable the availability of various other options. For + When used, it should be the first option set since its value might + enable or disable the availability of various other options. For multiple lines in a configuration file, that would be the first non- - comment line. For a comma-separated list in NETHACKOPTIONS or an - OPTIONS line in a configuration file, that would be the rightmost + comment line. For a comma-separated list in NETHACKOPTIONS or an + OPTIONS line in a configuration file, that would be the rightmost option in the list. wizweight - Augment object descriptions with their objects' weight (default + Augment object descriptions with their objects' weight (default off). Debug mode only. zerocomp - When writing out a save file, perform zero-comp compression of the - contents. Not all ports support zero-comp compression. It has no + When writing out a save file, perform zero-comp compression of the + contents. Not all ports support zero-comp compression. It has no effect on reading an existing save file. 9.5. Window Port Customization options - Here are explanations of the various options that are used to - customize and change the characteristics of the windowtype that you - have chosen. Character strings that are too long may be truncated. - Not all window ports will adjust for all settings listed here. You + Here are explanations of the various options that are used to + customize and change the characteristics of the windowtype that you + have chosen. Character strings that are too long may be truncated. + Not all window ports will adjust for all settings listed here. You can safely add any of these options to your configuration file, and if - the window port is capable of adjusting to suit your preferences, it - will attempt to do so. If it can't it will silently ignore it. You + the window port is capable of adjusting to suit your preferences, it + will attempt to do so. If it can't it will silently ignore it. You can find out if an option is supported by the window port that you are currently using by checking to see if it shows up in the Options list. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5552,19 +5552,19 @@ `O' command. align_message - Where to align or place the message window (top, bottom, left, or + Where to align or place the message window (top, bottom, left, or right) align_status - Where to align or place the status window (top, bottom, left, or + Where to align or place the status window (top, bottom, left, or right). ascii_map - If NetHack can, it should display the map using simple characters - (letters and punctuation) rather than tiles graphics. In some - cases, characters can be augmented with line-drawing symbols; use - the symset option to select a symbol set such as DECgraphics or - IBMgraphics if your display supports them. Setting ascii_map to + If NetHack can, it should display the map using simple characters + (letters and punctuation) rather than tiles graphics. In some + cases, characters can be augmented with line-drawing symbols; use + the symset option to select a symbol set such as DECgraphics or + IBMgraphics if your display supports them. Setting ascii_map to True forces tiled_map to be False. color @@ -5573,15 +5573,15 @@ eight_bit_tty If NetHack can, it should pass eight-bit character values (for exam- - ple, specified with the traps option) straight through to your ter- + ple, specified with the traps option) straight through to your ter- minal (default off). font_map - if NetHack can, it should use a font by the chosen name for the map + if NetHack can, it should use a font by the chosen name for the map window. font_menu - If NetHack can, it should use a font by the chosen name for menu + If NetHack can, it should use a font by the chosen name for menu windows. font_message @@ -5593,7 +5593,7 @@ tus window. font_text - If NetHack can, it should use a font by the chosen name for text + If NetHack can, it should use a font by the chosen name for text windows. font_size_map @@ -5604,7 +5604,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5628,8 +5628,8 @@ than in a window. guicolor - Use color text and/or highlighting attributes when displaying some - non-map data (such as menu selector letters). Curses interface + Use color text and/or highlighting attributes when displaying some + non-map data (such as menu selector letters). Curses interface only; default is on. large_font @@ -5639,17 +5639,17 @@ If NetHack can, it should display the map in the manner specified. player_selection - If NetHack can, it should pop up dialog boxes, or use prompts for + If NetHack can, it should pop up dialog boxes, or use prompts for character selection. popup_dialog If NetHack can, it should pop up dialog boxes for input. preload_tiles - If NetHack can, it should preload tiles into memory. For example, + If NetHack can, it should preload tiles into memory. For example, in the protected mode MS-DOS version, control whether tiles get pre- loaded into RAM at the start of the game. Doing so enhances perfor- - mance of the tile graphics, but uses more memory. (default on). + mance of the tile graphics, but uses more memory. (default on). Cannot be set with the `O' command. scroll_amount @@ -5666,11 +5666,11 @@ support this option. softkeyboard - Display an onscreen keyboard. Handhelds are most likely to support + Display an onscreen keyboard. Handhelds are most likely to support this option. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5681,7 +5681,7 @@ splash_screen - If NetHack can, it should display an opening splash screen when it + If NetHack can, it should display an opening splash screen when it starts up (default yes). statuslines @@ -5689,37 +5689,37 @@ Acceptable values are 2 and 3 (default is 2). When set to 3, the tty interface moves some fields around and mainly - shows status conditions on their own line. A display capable of - showing at least 25 lines is recommended. The value can be toggled + shows status conditions on their own line. A display capable of + showing at least 25 lines is recommended. The value can be toggled back and forth during the game with the `O' command. The curses interface does likewise if the align_status option is set to top or bottom but ignores statuslines when set to left or right. - The Qt interface already displays more than 3 lines for status so + The Qt interface already displays more than 3 lines for status so uses the statuslines value differently. A value of 3 renders status in the Qt interface's original format, with the status window spread - out vertically. A value of 2 makes status be slightly condensed, - moving some fields to different lines to eliminate one whole line, + out vertically. A value of 2 makes status be slightly condensed, + moving some fields to different lines to eliminate one whole line, reducing the height needed. (If NetHack has been built using a ver- - sion of Qt older than qt-5.9, statuslines can only be set in the - run-time configuration file or via NETHACKOPTIONS, not during play + sion of Qt older than qt-5.9, statuslines can only be set in the + run-time configuration file or via NETHACKOPTIONS, not during play with the `O' command.) term_cols and term_rows - Curses interface only. Number of columns and rows to use for the - display. Curses will attempt to resize to the values specified but - will settle for smaller sizes if they are too big. Default is the + Curses interface only. Number of columns and rows to use for the + display. Curses will attempt to resize to the values specified but + will settle for smaller sizes if they are too big. Default is the current window size. tile_file - Specify the name of an alternative tile file to override the + Specify the name of an alternative tile file to override the default. - Note: the X11 interface uses X resources rather than NetHack's - options to select an alternate tile file. See NetHack.ad, the sam- + Note: the X11 interface uses X resources rather than NetHack's + options to select an alternate tile file. See NetHack.ad, the sam- ple X "application defaults" file. tile_height @@ -5729,14 +5729,14 @@ Specify the preferred width of each tile in a tile capable port tiled_map - If NetHack can, it should display the map using tiles graphics - rather than simple characters (letters and punctuation, possibly - augmented by line-drawing symbols). Setting tiled_map to True + If NetHack can, it should display the map using tiles graphics + rather than simple characters (letters and punctuation, possibly + augmented by line-drawing symbols). Setting tiled_map to True forces ascii_map to be False. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5750,16 +5750,16 @@ Use bold black instead of blue for black glyphs (TTY only). use_inverse - If NetHack can, it should display inverse when the game specifies + If NetHack can, it should display inverse when the game specifies it. vary_msgcount - If NetHack can, it should display this number of messages at a time + If NetHack can, it should display this number of messages at a time in the message window. windowborders Whether to draw boxes around the map, status area, message area, and - persistent inventory window if enabled. Curses interface only. + persistent inventory window if enabled. Curses interface only. Acceptable values are 0 - off, never show borders @@ -5768,11 +5768,11 @@ 3 - on, except forced off for perm_invent 4 - auto, except forced off for perm_invent - (The 26x82 size threshold for `2' refers to number of rows and col- + (The 26x82 size threshold for `2' refers to number of rows and col- umns of the display. A width of at least 110 columns (80+2+26+2) is needed to show borders if align_status is set to left or right.) - The persistent inventory window, when enabled, can grow until it is + The persistent inventory window, when enabled, can grow until it is too big to fit on most displays, resulting in truncation of its con- tents. If borders are forced on (1) or the display is big enough to show them (2), setting the value to 3 or 4 instead will keep borders @@ -5781,28 +5781,28 @@ umns. windowcolors - If NetHack can, it should display all windows of a particular style - with the specified foreground and background colors. Windows GUI + If NetHack can, it should display all windows of a particular style + with the specified foreground and background colors. Windows GUI and curses windowport only. The format is OPTION=windowcolors:style foreground/background - where style is one of "menu", "message", "status", or "text", and + where style is one of "menu", "message", "status", or "text", and foreground and background are colors, either numeric (hash sign fol- - lowed by three pairs of hexadecimal digits, #rrggbb), one of the + lowed by three pairs of hexadecimal digits, #rrggbb), one of the named colors (black, red, green, brown, blue, magenta, cyan, orange, - bright-green, yellow, bright-blue, bright-magenta, bright-cyan, - white, gray, purple, silver, maroon, fuchsia, lime, olive, navy, - teal, aqua), or (for Windows only) one of Windows UI colors (true- - black, activeborder, activecaption, appworkspace, background, btn- - face, btnshadow, btntext, captiontext, graytext, greytext, high- - light, highlighttext, inactiveborder, inactivecaption, menu, menu- + bright-green, yellow, bright-blue, bright-magenta, bright-cyan, + white, gray, purple, silver, maroon, fuchsia, lime, olive, navy, + teal, aqua), or (for Windows only) one of Windows UI colors (true- + black, activeborder, activecaption, appworkspace, background, btn- + face, btnshadow, btntext, captiontext, graytext, greytext, high- + light, highlighttext, inactiveborder, inactivecaption, menu, menu- text, scrollbar, window, windowframe, windowtext). - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5813,62 +5813,62 @@ wraptext - If NetHack can, it should wrap long lines of text if they don't fit + If NetHack can, it should wrap long lines of text if they don't fit in the visible area of the window. 9.6. Crash Report Options - Please note that NetHack does not send any information off your + Please note that NetHack does not send any information off your computer unless you manually click submit on a form. OPTION=crash_email:email_address OPTION=crash_name:your_name - These options are used only to save you some typing on the + These options are used only to save you some typing on the crash report and #bugreport forms. OPTION=crash_urlmax:bytes - This option is used to limit the length of the URLs generated - and is only needed if your browser cannot handle arbitrarily + This option is used to limit the length of the URLs generated + and is only needed if your browser cannot handle arbitrarily long URLs. 9.7. Platform-specific Customization options - Here are explanations of options that are used by specific plat- + Here are explanations of options that are used by specific plat- forms or ports to customize and change the port behavior. altkeyhandling - Select an alternate way to handle keystrokes (Win32 tty NetHack - only). The name of the handling type is one of "default", "ray", + Select an alternate way to handle keystrokes (Win32 tty NetHack + only). The name of the handling type is one of "default", "ray", "340". altmeta - On systems where this option is available, it can be set to tell - NetHack to convert a two character sequence beginning with ESC into + On systems where this option is available, it can be set to tell + NetHack to convert a two character sequence beginning with ESC into a meta-shifted version of the second character (default off). - This conversion is only done for commands, not for other input - prompts. Note that typing one or more digits as a count prefix - prior to a command--preceded by n if the number_pad option is set-- + This conversion is only done for commands, not for other input + prompts. Note that typing one or more digits as a count prefix + prior to a command--preceded by n if the number_pad option is set-- is also subject to this conversion, so attempting to abort the count - by typing ESC will leave NetHack waiting for another character to - complete the two character sequence. Type a second ESC to finish + by typing ESC will leave NetHack waiting for another character to + complete the two character sequence. Type a second ESC to finish cancelling such a count. At other prompts a single ESC suffices. BIOS - Use BIOS calls to update the screen display quickly and to read the - keyboard (allowing the use of arrow keys to move) on machines with + Use BIOS calls to update the screen display quickly and to read the + keyboard (allowing the use of arrow keys to move) on machines with an IBM PC compatible BIOS ROM (default off, OS/2, PC, and ST NetHack only). rawio - Force raw (non-cbreak) mode for faster output and more bulletproof - input (MS-DOS sometimes treats `^P' as a printer toggle without it) - (default off, OS/2, PC, and ST NetHack only). Note: DEC Rainbows + Force raw (non-cbreak) mode for faster output and more bulletproof + input (MS-DOS sometimes treats `^P' as a printer toggle without it) + (default off, OS/2, PC, and ST NetHack only). Note: DEC Rainbows hang if this is turned on. Cannot be set with the `O' command. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5879,21 +5879,21 @@ subkeyvalue - (Win32 tty NetHack only). May be used to alter the value of key- + (Win32 tty NetHack only). May be used to alter the value of key- strokes that the operating system returns to NetHack to help compen- - sate for international keyboard issues. OPTIONS=subkeyvalue:171/92 - will return 92 to NetHack, if 171 was originally going to be - returned. You can use multiple subkeyvalue assignments in the con- + sate for international keyboard issues. OPTIONS=subkeyvalue:171/92 + will return 92 to NetHack, if 171 was originally going to be + returned. You can use multiple subkeyvalue assignments in the con- figuration file if needed. Cannot be set with the `O' command. video Set the video mode used (PC NetHack only). Values are "autodetect", - "default", "vga", or "vesa". Setting "vesa" will cause the game to - display tiles, using the full capability of the VGA hardware. Set- + "default", "vga", or "vesa". Setting "vesa" will cause the game to + display tiles, using the full capability of the VGA hardware. Set- ting "vga" will cause the game to display tiles, fixed at 640x480 in - 16 colors, a mode that is compatible with all VGA hardware. Third - party tilesets will probably not work. Setting "autodetect" - attempts "vesa", then "vga", and finally sets "default" if neither + 16 colors, a mode that is compatible with all VGA hardware. Third + party tilesets will probably not work. Setting "autodetect" + attempts "vesa", then "vga", and finally sets "default" if neither of those modes works. Cannot be set with the `O' command. video_height @@ -5903,38 +5903,38 @@ Set the VGA mode resolution width (MS-DOS only, with video:vesa) videocolors - Set the color palette for PC systems using NO_TERMS (default - 4-2-6-1-5-3-15-12-10-14-9-13-11, (PC NetHack only). The order of - colors is red, green, brown, blue, magenta, cyan, bright.white, - bright.red, bright.green, yellow, bright.blue, bright.magenta, and + Set the color palette for PC systems using NO_TERMS (default + 4-2-6-1-5-3-15-12-10-14-9-13-11, (PC NetHack only). The order of + colors is red, green, brown, blue, magenta, cyan, bright.white, + bright.red, bright.green, yellow, bright.blue, bright.magenta, and bright.cyan. Cannot be set with the `O' command. videoshades - Set the intensity level of the three gray scales available (default - dark normal light, PC NetHack only). If the game display is diffi- - cult to read, try adjusting these scales; if this does not correct + Set the intensity level of the three gray scales available (default + dark normal light, PC NetHack only). If the game display is diffi- + cult to read, try adjusting these scales; if this does not correct the problem, try !color. Cannot be set with the `O' command. 9.8. Regular Expressions - Regular expressions are normally POSIX extended regular expres- - sions. It is possible to compile NetHack without regular expression - support on a platform where there is no regular expression library. - While this is not true of any modern platform, if your NetHack was - built this way, patterns are instead glob patterns; regardless, this - document refers to both as `regular expressions.' This applies to + Regular expressions are normally POSIX extended regular expres- + sions. It is possible to compile NetHack without regular expression + support on a platform where there is no regular expression library. + While this is not true of any modern platform, if your NetHack was + built this way, patterns are instead glob patterns; regardless, this + document refers to both as `regular expressions.' This applies to Autopickup exceptions, Message types, Menu colors, and User sounds. 9.9. Configuring Autopickup Exceptions - You can further refine the behavior of the autopickup option + You can further refine the behavior of the autopickup option beyond what is available through the pickup_types option. By placing autopickup_exception lines in your configuration file, - you can define patterns to be checked when the game is about to + you can define patterns to be checked when the game is about to - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5949,21 +5949,21 @@ autopickup_exception Sets an exception to the pickup_types option. The autopickup_excep- tion option should be followed by a regular expression to be used as - a pattern to match against the singular form of the description of + a pattern to match against the singular form of the description of an object at your location. - In addition, some characters are treated specially if they occur as + In addition, some characters are treated specially if they occur as the first character in the pattern, specifically: < - always pickup an object that matches rest of pattern; > - never pickup an object that matches rest of pattern. - The autopickup_exception rules are processed in the order in which - they appear in your configuration file, thus allowing a later rule + The autopickup_exception rules are processed in the order in which + they appear in your configuration file, thus allowing a later rule to override an earlier rule. Exceptions can be set with the `O' command, but because they are not - included in your configuration file, they won't be in effect if you + included in your configuration file, they won't be in effect if you save and then restore your game. autopickup_exception rules and not saved with the game. @@ -5973,18 +5973,18 @@ autopickup_exception=">*corpse" autopickup_exception=">* cursed*" - The first example above will result in autopickup of any type of + The first example above will result in autopickup of any type of arrow. The second example results in the exclusion of any corpse from - autopickup. The last example results in the exclusion of items known + autopickup. The last example results in the exclusion of items known to be cursed from autopickup. 9.10. Changing Key Bindings It is possible to change the default key bindings of some special - commands, menu accelerator keys, and extended commands, by using BIND - stanzas in the configuration file. Format is key, followed by the - command to bind to, separated by a colon. The key can be a single - character ("x"), a control key ("^X", "C-x"), a meta key ("M-x"), a + commands, menu accelerator keys, and extended commands, by using BIND + stanzas in the configuration file. Format is key, followed by the + command to bind to, separated by a colon. The key can be a single + character ("x"), a control key ("^X", "C-x"), a meta key ("M-x"), a mouse button, or a three-digit decimal ASCII code. For example: @@ -5994,13 +5994,13 @@ BIND=v:loot Extended command keys - You can bind multiple keys to the same extended command. Unbind a - key by using "nothing" as the extended command to bind to. You can + You can bind multiple keys to the same extended command. Unbind a + key by using "nothing" as the extended command to bind to. You can also bind the "", "", and "" keys. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6012,46 +6012,46 @@ Menu accelerator keys The menu control or accelerator keys can also be rebound via OPTIONS - lines in the configuration file. You cannot bind object symbols or + lines in the configuration file. You cannot bind object symbols or selection letters into menu accelerators. Some interfaces only sup- port some of the menu accelerators. Mouse buttons - You can bind "mouse1" or "mouse2" to "nothing", "therecmdmenu", + You can bind "mouse1" or "mouse2" to "nothing", "therecmdmenu", "clicklook", or "mouseaction". Special command keys - Below are the special commands you can rebind. Some of them can be - bound to same keys with no problems, others are in the same "con- + Below are the special commands you can rebind. Some of them can be + bound to same keys with no problems, others are in the same "con- text", and if bound to same keys, only one of those commands will be available. Special command can only be bound to a single key. count - Prefix key to start a count, to repeat a command this many times. + Prefix key to start a count, to repeat a command this many times. With number_pad only. Default is `n'. getdir.help - When asked for a direction, the key to show the help. Default is + When asked for a direction, the key to show the help. Default is `?'. getdir.mouse - When asked for a direction, the key to initiate a simulated mouse - click. You will be asked to pick a location. Use movement key- - strokes to move the cursor around the map, then type the get- + When asked for a direction, the key to initiate a simulated mouse + click. You will be asked to pick a location. Use movement key- + strokes to move the cursor around the map, then type the get- pos.pick.once key (default `,') or the getpos.pick key (default `.') - to finish as if performing a left or right click. Only useful when + to finish as if performing a left or right click. Only useful when using the #therecmdmenu command. Default is `_'. getdir.self - When asked for a direction, the key to target yourself. Default is + When asked for a direction, the key to target yourself. Default is `.'. getdir.self2 - When asked for a direction, an alternate key to target yourself. + When asked for a direction, an alternate key to target yourself. Default is `s'. getpos.autodescribe - When asked for a location, the key to toggle autodescribe. Default + When asked for a location, the key to toggle autodescribe. Default is `#'. getpos.all.next @@ -6059,14 +6059,14 @@ thing. Default is `a'. getpos.all.prev - When asked for a location, the key to go to previous closest inter- + When asked for a location, the key to go to previous closest inter- esting thing. Default is `A'. getpos.door.next - When asked for a location, the key to go to next closest door or + When asked for a location, the key to go to next closest door or - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6086,15 +6086,15 @@ When asked for a location, the key to show help. Default is `?'. getpos.mon.next - When asked for a location, the key to go to next closest monster. + When asked for a location, the key to go to next closest monster. Default is `m'. getpos.mon.prev - When asked for a location, the key to go to previous closest mon- + When asked for a location, the key to go to previous closest mon- ster. Default is `M'. getpos.obj.next - When asked for a location, the key to go to next closest object. + When asked for a location, the key to go to next closest object. Default is `o'. getpos.obj.prev @@ -6102,37 +6102,37 @@ Default is `O'. getpos.menu - When asked for a location, and using one of the next or previous - keys to cycle through targets, toggle showing a menu instead. + When asked for a location, and using one of the next or previous + keys to cycle through targets, toggle showing a menu instead. Default is `!'. getpos.moveskip - When asked for a location, and using the shifted movement keys or - meta-digit keys to fast-move around, move by skipping the same + When asked for a location, and using the shifted movement keys or + meta-digit keys to fast-move around, move by skipping the same glyphs instead of by 8 units. Default is `*'. getpos.filter - When asked for a location, change the filtering mode when using one - of the next or previous keys to cycle through targets. Toggles - between no filtering, in view only, and in the same area only. + When asked for a location, change the filtering mode when using one + of the next or previous keys to cycle through targets. Toggles + between no filtering, in view only, and in the same area only. Default is `"'. getpos.pick - When asked for a location, the key to choose the location, and pos- - sibly ask for more info. When simulating a mouse click after being - asked for a direction (see getdir.mouse above), the key to use to + When asked for a location, the key to choose the location, and pos- + sibly ask for more info. When simulating a mouse click after being + asked for a direction (see getdir.mouse above), the key to use to respond as right click. Default is `.'. getpos.pick.once - When asked for a location, the key to choose the location, and skip - asking for more info. When simulating a mouse click after being + When asked for a location, the key to choose the location, and skip + asking for more info. When simulating a mouse click after being asked for a direction, the key to respond as left click. Default is `,'. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6144,27 +6144,27 @@ getpos.pick.quick When asked for a location, the key to choose the location, skip ask- - ing for more info, and exit the location asking loop. Default is + ing for more info, and exit the location asking loop. Default is `;'. getpos.pick.verbose - When asked for a location, the key to choose the location, and show + When asked for a location, the key to choose the location, and show more info without asking. Default is `:'. getpos.self - When asked for a location, the key to go to your location. Default + When asked for a location, the key to go to your location. Default is `@'. getpos.unexplored.next - When asked for a location, the key to go to next closest unexplored + When asked for a location, the key to go to next closest unexplored location. Default is `x'. getpos.unexplored.prev - When asked for a location, the key to go to previous closest unex- + When asked for a location, the key to go to previous closest unex- plored location. Default is `X'. getpos.valid - When asked for a location, the key to go to show valid target loca- + When asked for a location, the key to go to show valid target loca- tions. Default is `$'. getpos.valid.next @@ -6172,15 +6172,15 @@ tion. Default is `z'. getpos.valid.prev - When asked for a location, the key to go to previous closest valid + When asked for a location, the key to go to previous closest valid location. Default is `Z'. 9.11. Configuring Message Types - You can change the way the messages are shown in the message + You can change the way the messages are shown in the message area, when the message matches a user-defined pattern. - In general, the configuration file entries to describe the mes- + In general, the configuration file entries to describe the mes- sage types look like this: MSGTYPE=type "pattern" type - how the message should be shown; @@ -6193,12 +6193,12 @@ show - show message normally; hide - never show the message; stop - wait for user with more-prompt; - norep - show the message once, but not again if no other message is + norep - show the message once, but not again if no other message is shown in between. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6208,14 +6208,14 @@ - Here's an example of message types using NetHack's internal pattern + Here's an example of message types using NetHack's internal pattern matching facility: MSGTYPE=stop "You feel hungry." MSGTYPE=hide "You displaced *." - specifies that whenever a message "You feel hungry" is shown, the - user is prompted with more-prompt, and a message matching "You dis- + specifies that whenever a message "You feel hungry" is shown, the + user is prompted with more-prompt, and a message matching "You dis- placed ." is not shown at all. The order of the defined MSGTYPE lines is important; the last match- @@ -6224,47 +6224,47 @@ 9.12. Configuring Menu Colors Some platforms allow you to define colors used in menu lines when - the line matches a user-defined pattern. At this time the tty, + the line matches a user-defined pattern. At this time the tty, curses, win32tty and win32gui interfaces support this. - In general, the configuration file entries to describe the menu + In general, the configuration file entries to describe the menu color mappings look like this: MENUCOLOR="pattern"=color&attribute pattern - the pattern to match; color - the color to use for lines matching the pattern; - attribute - the attribute to use for lines matching the pat- - tern. The attribute is optional, and if left out, - you must also leave out the preceding ampersand. + attribute - the attribute to use for lines matching the pat- + tern. The attribute is optional, and if left out, + you must also leave out the preceding ampersand. If no attribute is defined, no attribute is used. The pattern should be a regular expression. - Allowed colors are black, red, green, brown, blue, magenta, cyan, + Allowed colors are black, red, green, brown, blue, magenta, cyan, gray, orange, light-green, yellow, light-blue, light-magenta, light- - cyan, and white. And no-color, the default foreground color, which + cyan, and white. And no-color, the default foreground color, which isn't necessarily the same as any of the other colors. - Allowed attributes are none, bold, dim, italic, underline, blink, + Allowed attributes are none, bold, dim, italic, underline, blink, and inverse. "Normal" is a synonym for "none". Note that the plat- form used may interpret the attributes any way it wants. - Here's an example of menu colors using NetHack's internal pattern + Here's an example of menu colors using NetHack's internal pattern matching facility: MENUCOLOR="* blessed *"=green MENUCOLOR="* cursed *"=red MENUCOLOR="* cursed *(being worn)"=red&underline - specifies that any menu line with " blessed " contained in it will + specifies that any menu line with " blessed " contained in it will be shown in green color, lines with " cursed " will be shown in red, - and lines with " cursed " followed by "(being worn)" on the same + and lines with " cursed " followed by "(being worn)" on the same line will be shown in red color and underlined. You can have multi- ple MENUCOLOR entries in your configuration file, and the last MENU- - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6276,19 +6276,19 @@ COLOR line that matches a menu line will be used for the line. - Note that if you intend to have one or more color specifications + Note that if you intend to have one or more color specifications match " uncursed ", you will probably want to turn the - implicit_uncursed option off so that all items known to be uncursed + implicit_uncursed option off so that all items known to be uncursed are actually displayed with the "uncursed" description. 9.13. Configuring User Sounds - Some platforms allow you to define sound files to be played when + Some platforms allow you to define sound files to be played when a message that matches a user-defined pattern is delivered to the mes- - sage window. At this time the Qt port and the win32tty and win32gui + sage window. At this time the Qt port and the win32tty and win32gui ports support the use of user sounds. - The following configuration file entries are relevant to mapping + The following configuration file entries are relevant to mapping user sounds to messages: SOUNDDIR @@ -6298,9 +6298,9 @@ An entry that maps a sound file to a user-specified message pattern. Each SOUND entry is broken down into the following parts: - MESG - message window mapping (the only one supported in + MESG - message window mapping (the only one supported in 5.0.0); - msgtype - optional; message type to use, see "Configuring Mes- + msgtype - optional; message type to use, see "Configuring Mes- sage Types" pattern - the pattern to match; sound file - the sound file to play; @@ -6319,9 +6319,9 @@ 9.14. Configuring Status Hilites - Your copy of NetHack may have been compiled with support for - "Status Hilites". If so, you can customize your game display by set- - ting thresholds to change the color or appearance of fields in the + Your copy of NetHack may have been compiled with support for + "Status Hilites". If so, you can customize your game display by set- + ting thresholds to change the color or appearance of fields in the status display. The format for defining status colors is: @@ -6330,7 +6330,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6340,42 +6340,42 @@ - For example, the following line in your configuration file will - cause the hitpoints field to display in the color red if your hit- + For example, the following line in your configuration file will + cause the hitpoints field to display in the color red if your hit- points drop to or below a threshold of 30%: OPTION=hilite_status:hitpoints/<=30%/red/normal - (That example is actually specifying red&normal for <=30% and no- + (That example is actually specifying red&normal for <=30% and no- color&normal for >30%.) - For another example, the following line in your configuration + For another example, the following line in your configuration file will cause wisdom to be displayed red if it drops and green if it rises: OPTION=hilite_status:wisdom/down/red/up/green Allowed colors are black, red, green, brown, blue, magenta, cyan, - gray, orange, light-green, yellow, light-blue, light-magenta, light- - cyan, and white. And "no-color", the default foreground color on the + gray, orange, light-green, yellow, light-blue, light-magenta, light- + cyan, and white. And "no-color", the default foreground color on the display, which is not necessarily the same as black or white or any of the other colors. Allowed attributes are none, bold, dim, underline, italic, blink, - and inverse. "Normal" is a synonym for "none"; they should not be + and inverse. "Normal" is a synonym for "none"; they should not be used in combination with any of the other attributes. - To specify both a color and an attribute, use `&' to combine - them. To specify multiple attributes, use `+' to combine those. For + To specify both a color and an attribute, use `&' to combine + them. To specify multiple attributes, use `+' to combine those. For example: "magenta&inverse+dim". Note that the display may substitute or ignore particular - attributes depending upon its capabilities, and in general may inter- - pret the attributes any way it wants. For example, on some display - systems a request for bold might yield blink or vice versa. On oth- + attributes depending upon its capabilities, and in general may inter- + pret the attributes any way it wants. For example, on some display + systems a request for bold might yield blink or vice versa. On oth- ers, issuing an attribute request while another is already set up will - replace the earlier attribute rather than combine with it. Since - NetHack issues attribute requests sequentially (at least with the tty + replace the earlier attribute rather than combine with it. Since + NetHack issues attribute requests sequentially (at least with the tty interface) rather than all at once, the only way a situation like that can be controlled is to specify just one attribute. @@ -6389,14 +6389,14 @@ charisma armor-class condition alignment score - The pseudo-field "characteristics" can be used to set all six of - Str, Dex, Con, Int, Wis, and Cha at once. "HD" is "hit dice", an - approximation of experience level displayed when polymorphed. - "experience", "time", and "score" are conditionally displayed + The pseudo-field "characteristics" can be used to set all six of + Str, Dex, Con, Int, Wis, and Cha at once. "HD" is "hit dice", an + approximation of experience level displayed when polymorphed. + "experience", "time", and "score" are conditionally displayed depending upon your other option settings. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6406,63 +6406,63 @@ - Instead of a behavior, "condition" takes the following condition - flags: stone, slime, strngl, foodpois, termill, blind, deaf, stun, + Instead of a behavior, "condition" takes the following condition + flags: stone, slime, strngl, foodpois, termill, blind, deaf, stun, conf, hallu, lev, fly, and ride. You can use "major_troubles" as an - alias for stone through termill, "minor_troubles" for blind through + alias for stone through termill, "minor_troubles" for blind through hallu, "movement" for lev, fly, and ride, and "all" for every condi- tion. - Allowed behaviors are "always", "up", "down", "changed", a percent- + Allowed behaviors are "always", "up", "down", "changed", a percent- age or absolute number threshold, or text to match against. For the - hitpoints field, the additional behavior "criticalhp" is available. - It overrides other behavior rules if hit points are at or below the - major problem threshold (which varies depending upon maximum hit + hitpoints field, the additional behavior "criticalhp" is available. + It overrides other behavior rules if hit points are at or below the + major problem threshold (which varies depending upon maximum hit points and experience level). * "always" will set the default attributes for that field. - * "up", "down" set the field attributes for when the field value - changes upwards or downwards. This attribute times out after + * "up", "down" set the field attributes for when the field value + changes upwards or downwards. This attribute times out after statushilites turns. - * "changed" sets the field attribute for when the field value - changes. This attribute times out after statushilites turns. - (If a field has both a "changed" rule and an "up" or "down" - rule which matches a change in the field's value, the "up" or + * "changed" sets the field attribute for when the field value + changes. This attribute times out after statushilites turns. + (If a field has both a "changed" rule and an "up" or "down" + rule which matches a change in the field's value, the "up" or "down" one takes precedence.) - * percentage sets the field attribute when the field value - matches the percentage. It is specified as a number between 0 - and 100, followed by `%' (percent sign). If the percentage is + * percentage sets the field attribute when the field value + matches the percentage. It is specified as a number between 0 + and 100, followed by `%' (percent sign). If the percentage is prefixed with `<=' or `>=', it also matches when value is below - or above the percentage. Use prefix `<' or `>' to match when + or above the percentage. Use prefix `<' or `>' to match when strictly below or above. (The numeric limit is relaxed - slightly for those: >-1% and <101% are allowed.) Only four - fields support percentage rules. Percentages for "hitpoints" - and "power" are straightforward; they're based on the corre- - sponding maximum field. Percentage highlight rules are also - allowed for "experience level" and "experience points" (valid + slightly for those: >-1% and <101% are allowed.) Only four + fields support percentage rules. Percentages for "hitpoints" + and "power" are straightforward; they're based on the corre- + sponding maximum field. Percentage highlight rules are also + allowed for "experience level" and "experience points" (valid when the showexp option is enabled). For those, the percentage - is based on the progress from the start of the current experi- - ence level to the start of the next level. So if level 2 - starts at 20 points and level 3 starts at 40 points, having 30 - points is 50% and 35 points is 75%. 100% is unattainable for - experience because you'll gain a level and the calculations - will be reset for that new level, but a rule for =100% is + is based on the progress from the start of the current experi- + ence level to the start of the next level. So if level 2 + starts at 20 points and level 3 starts at 40 points, having 30 + points is 50% and 35 points is 75%. 100% is unattainable for + experience because you'll gain a level and the calculations + will be reset for that new level, but a rule for =100% is allowed and matches the special case of being exactly 1 experi- ence point short of the next level. - * absolute value sets the attribute when the field value matches - that number. The number must be 0 or higher, except for - "armor-class' which allows negative values, and may optionally - be preceded by `='. If the number is preceded by `<=' or `>=' - instead, it also matches when value is below or above. If the + * absolute value sets the attribute when the field value matches + that number. The number must be 0 or higher, except for + "armor-class' which allows negative values, and may optionally + be preceded by `='. If the number is preceded by `<=' or `>=' + instead, it also matches when value is below or above. If the prefix is `<' or `>', only match when strictly above or below. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6472,19 +6472,19 @@ - * criticalhp only applies to the hitpoints field and only when + * criticalhp only applies to the hitpoints field and only when current hit points are below a threshold (which varies by maxi- - mum hit points and experience level). When the threshold is - met, a criticalhp rule takes precedence over all other hit- + mum hit points and experience level). When the threshold is + met, a criticalhp rule takes precedence over all other hit- points rules. - * text match sets the attribute when the field value matches the - text. Text matches can only be used for "alignment", "carry- - ing-capacity", "hunger", "dungeon-level", and "title". For - title, only the role's rank title is tested; the character's + * text match sets the attribute when the field value matches the + text. Text matches can only be used for "alignment", "carry- + ing-capacity", "hunger", "dungeon-level", and "title". For + title, only the role's rank title is tested; the character's name is ignored. - The in-game options menu can help you determine the correct syn- + The in-game options menu can help you determine the correct syn- tax for a configuration file. The whole feature can be disabled by setting option statushilites @@ -6509,26 +6509,26 @@ NetHack can load entire symbol sets from the symbol file. - The options that are used to select a particular symbol set from + The options that are used to select a particular symbol set from the symbol file are: symset Set the name of the symbol set that you want to load. roguesymset - Set the name of the symbol set that you want to load for display on + Set the name of the symbol set that you want to load for display on the rogue level. - You can also override one or more symbols using the SYMBOLS and - ROGUESYMBOLS configuration file options. Symbols are specified as + You can also override one or more symbols using the SYMBOLS and + ROGUESYMBOLS configuration file options. Symbols are specified as name:value pairs. Note that NetHack escape-processes the value string - in conventional C fashion. This means that \ is a prefix to take the - following character literally. Thus \ needs to be represented as \\. - The special prefix form \m switches on the meta bit in the symbol - value, and the ^ prefix causes the following character to be treated + in conventional C fashion. This means that \ is a prefix to take the + following character literally. Thus \ needs to be represented as \\. + The special prefix form \m switches on the meta bit in the symbol + value, and the ^ prefix causes the following character to be treated - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6594,7 +6594,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6660,7 +6660,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6726,7 +6726,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6769,30 +6769,30 @@ Notes: - * Several symbols in this table appear to be blank. They are the + * Several symbols in this table appear to be blank. They are the space character, except for S_pet_override and S_hero_override which - don't have any default value and can only be used if enabled in the + don't have any default value and can only be used if enabled in the "sysconf" file. - * S_rock is misleadingly named; rocks and stones use S_gem. Statues - and boulders are the rock being referred to, but since version - 3.6.0, statues are displayed as the monster they depict. So S_rock - is only used for boulders and not used at all if overridden by the + * S_rock is misleadingly named; rocks and stones use S_gem. Statues + and boulders are the rock being referred to, but since version + 3.6.0, statues are displayed as the monster they depict. So S_rock + is only used for boulders and not used at all if overridden by the more specific S_boulder. 9.16. Customizing Map Glyph Representations Using Unicode - If your platform or terminal supports the display of UTF-8 char- + If your platform or terminal supports the display of UTF-8 char- acter sequences, you can customize your game display by assigning Uni- - code codepoint values and red-green-blue colors to glyph representa- - tions. The customizations can be specified for use with a symset that - has a UTF8 handler within the symbols file such as the enhanced1 set, + code codepoint values and red-green-blue colors to glyph representa- + tions. The customizations can be specified for use with a symset that + has a UTF8 handler within the symbols file such as the enhanced1 set, or individually within your nethack.rc file. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6806,51 +6806,51 @@ OPTIONS=glyph:glyphname/U+nnnn/R-G-B - The window port that is active needs to provide support for dis- - playing UTF-8 character sequences and explicit red-green-blue colors + The window port that is active needs to provide support for dis- + playing UTF-8 character sequences and explicit red-green-blue colors in order for the glyph representation to be visible. For example, the - following line in your configuration file will cause the glyph repre- + following line in your configuration file will cause the glyph repre- sentation for glyphname G_pool to use Unicode codepoint U+224B and the color represented by R-G-B value 0-0-160: OPTIONS=glyph:G_pool/U+224B/0-0-160 - The list of acceptable glyphnames can be produced by nethack --dumpg- - lyphnames. Individual NetHack glyphs can be specified using the G_ + The list of acceptable glyphnames can be produced by nethack --dumpg- + lyphnames. Individual NetHack glyphs can be specified using the G_ prefix, or you can use an S_ symbol for a glyphname and store the cus- - tom representation for all NetHack glyphs that would map to that par- + tom representation for all NetHack glyphs that would map to that par- ticular symbol. - You will need to select a symset with a UTF8 handler to enable + You will need to select a symset with a UTF8 handler to enable the display of the customizations, such as the Enhanced symset. 9.17. Configuring NetHack for Play by the Blind - NetHack can be set up to use only standard ASCII characters for - making maps of the dungeons. This makes even the MS-DOS versions of - NetHack (which use special line-drawing characters by default) com- - pletely accessible to the blind who use speech and/or Braille access - technologies. Players will require a good working knowledge of their + NetHack can be set up to use only standard ASCII characters for + making maps of the dungeons. This makes even the MS-DOS versions of + NetHack (which use special line-drawing characters by default) com- + pletely accessible to the blind who use speech and/or Braille access + technologies. Players will require a good working knowledge of their screen-reader's review features, and will have to know how to navigate - horizontally and vertically character by character. They will also + horizontally and vertically character by character. They will also find the search capabilities of their screen-readers to be quite valu- - able. Be certain to examine this Guidebook before playing so you have + able. Be certain to examine this Guidebook before playing so you have an idea what the screen layout is like. You'll also need to be able to - locate the PC cursor. It is always where your character is located. - Merely searching for an @-sign will not always find your character - since there are other humanoids represented by the same sign. Your - screen-reader should also have a function which gives you the row and - column of your review cursor and the PC cursor. These co-ordinates + locate the PC cursor. It is always where your character is located. + Merely searching for an @-sign will not always find your character + since there are other humanoids represented by the same sign. Your + screen-reader should also have a function which gives you the row and + column of your review cursor and the PC cursor. These co-ordinates are often useful in giving players a better sense of the overall loca- tion of items on the screen. - NetHack can also be compiled with support for sending the game + NetHack can also be compiled with support for sending the game messages to an external program, such as a text-to-speech synthesizer. - If the "#version" extended command shows "external program as a mes- - sage handler", your NetHack has been compiled with the capability. - When compiling NetHack from source on Linux and other POSIX systems, - define MSGHANDLER to enable it. To use the capability, set the envi- - ronment variable NETHACK_MSGHANDLER to an executable, which will be + If the "#version" extended command shows "external program as a mes- + sage handler", your NetHack has been compiled with the capability. + When compiling NetHack from source on Linux and other POSIX systems, + define MSGHANDLER to enable it. To use the capability, set the envi- + ronment variable NETHACK_MSGHANDLER to an executable, which will be executed with the game message as the program's only parameter. The most crucial settings to make the game more accessible are: @@ -6858,7 +6858,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6878,8 +6878,8 @@ Show menus on a cleared screen and aligned to the left edge. number_pad - A lot of speech access programs use the number-pad to review the - screen. If this is the case, disable the number_pad option and use + A lot of speech access programs use the number-pad to review the + screen. If this is the case, disable the number_pad option and use the traditional Rogue-like commands. paranoid_confirmation:swim @@ -6889,11 +6889,11 @@ Adds direction or location information to messages. spot_monsters - Shows a message when hero notices a monster; combine with accessi- + Shows a message when hero notices a monster; combine with accessi- blemsg. mon_movement - Shows a message when hero notices a monster movement; combine with + Shows a message when hero notices a monster movement; combine with spot_monsters and accessiblemsg. autodescribe @@ -6903,15 +6903,15 @@ Give feedback messages when interesting map locations change. mention_walls - Give feedback messages when walking towards a wall or when travel + Give feedback messages when walking towards a wall or when travel command was interrupted. whatis_coord:compass - When targeting with cursor, describe the cursor position with coor- + When targeting with cursor, describe the cursor position with coor- dinates relative to your character. whatis_filter:area - When targeting with cursor, filter possible locations so only those + When targeting with cursor, filter possible locations so only those in the same area (eg. same room, or same corridor) are considered. whatis_moveskip @@ -6919,12 +6919,12 @@ instead of moving 8 units at a time. nostatus_updates - Prevent updates to the status lines at the bottom of the screen, if - your screen-reader reads those lines. The same information can be + Prevent updates to the status lines at the bottom of the screen, if + your screen-reader reads those lines. The same information can be seen via the "#attributes" command. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6939,25 +6939,28 @@ 9.18. Global Configuration for System Administrators - If NetHack is compiled with the SYSCF option, a system adminis- - trator should set up a global configuration; this is a file in the - same format as the traditional per-user configuration file (see - above). This file should be named sysconf and placed in the same - directory as the other NetHack support files. The options recognized - in this file are listed below. Any option not set uses a compiled-in + If NetHack is compiled with the SYSCF option, a system adminis- + trator should set up a global configuration; this is a file in the + same format as the traditional per-user configuration file (see + above). This file should be named sysconf and placed in the same + directory as the other NetHack support files. The options recognized + in this file are listed below. Any option not set uses a compiled-in default (which may not be appropriate for your system). - WIZARDS = A space-separated list of user names who are allowed to - play in debug mode (commonly referred to as wizard mode). A value - of a single asterisk (*) allows anyone to start a game in debug + WIZARDS = A space-separated list of user names who are allowed to + play in debug mode (commonly referred to as wizard mode). A value + of a single asterisk (*) allows anyone to start a game in debug mode. - SHELLERS = A list of users who are allowed to use the shell escape + SHELLERS = A list of users who are allowed to use the shell escape command (!). The syntax is the same as WIZARDS. EXPLORERS = A list of users who are allowed to use the explore mode. The syntax is the same as WIZARDS. + GENERICUSERS = A list of user names that should prompt ``Who are + you?'' rather than become a character's name. + MSGHANDLER = A path and filename of executable. Whenever a message- window message is shown, NetHack runs this program. The program will get the message as the only parameter. @@ -6984,13 +6987,10 @@ The following four options affect the score file: - PERSMAX = Maximum number of entries for one person. - - ENTRYMAX = Maximum number of entries in the score file. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -7000,6 +7000,10 @@ + PERSMAX = Maximum number of entries for one person. + + ENTRYMAX = Maximum number of entries in the score file. + POINTSMIN = Minimum number of points to get an entry in the score file. @@ -7050,13 +7054,9 @@ https://www.nethack.org/links/cr-5.0.0.html and support is compiled in, brings up a browser window pre-populated with the information needed to report a problem if the game panics or ends up in an - internally inconsistent state, or if the #bugreport command is - invoked. - - - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -7066,6 +7066,9 @@ + internally inconsistent state, or if the #bugreport command is + invoked. + 10. Scoring NetHack maintains a list of the top scores or scorers on your @@ -7116,13 +7119,10 @@ the game with the -D command-line switch or with the playmode:debug option. - For some systems, the player must be logged in under a particular - user name to be allowed to use debug mode; for others, the hero must - be given a particular character name (but may be any role; there's no - connection between "wizard mode" and the Wizard role). Attempting to - NetHack 5.0.0 June 23, 2026 + + NetHack 5.0.0 July 4, 2026 @@ -7132,6 +7132,10 @@ + For some systems, the player must be logged in under a particular + user name to be allowed to use debug mode; for others, the hero must + be given a particular character name (but may be any role; there's no + connection between "wizard mode" and the Wizard role). Attempting to start a game in debug mode when not allowed or not available will result in falling back to explore mode instead. @@ -7181,14 +7185,10 @@ Eric Hendrickson, Izchak Miller, Eric S. Raymond, John Rupley, Mike Threepoint, and Janet Walz, to produce NetHack 3.0c. - NetHack 3.0 was ported to the Atari by Eric R. Smith, to OS/2 by - Timo Hakulinen, and to VMS by David Gentzel. The three of them and - Kevin Darcy later joined the main NetHack Development Team to produce - subsequent revisions of 3.0. - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -7198,6 +7198,11 @@ + NetHack 3.0 was ported to the Atari by Eric R. Smith, to OS/2 by + Timo Hakulinen, and to VMS by David Gentzel. The three of them and + Kevin Darcy later joined the main NetHack Development Team to produce + subsequent revisions of 3.0. + Olaf Seibert ported NetHack 2.3 and 3.0 to the Amiga. Norm Meluch, Stephen Spackman and Pierre Martineau designed overlay code for PC NetHack 3.0. Johnny Lee ported NetHack 3.0 to the Macintosh. @@ -7247,14 +7252,9 @@ don't extend to individual monster and object types, just replacements for monster and object classes (so one custom image for all "a" insects and another for all "[" armor and so forth, not separate - images for beetles and ants or for cloaks and boots). - - Warwick Allison wrote a graphically displayed version of NetHack - for the Atari where the tiny pictures were described as "icons" and - were distinct for specific types of monsters and objects rather than - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -7264,6 +7264,11 @@ + images for beetles and ants or for cloaks and boots). + + Warwick Allison wrote a graphically displayed version of NetHack + for the Atari where the tiny pictures were described as "icons" and + were distinct for specific types of monsters and objects rather than just their classes. He contributed them to the NetHack Development Team which rechristened them "tiles", original usage which has subse- quently been picked up by various other games. NetHack's tiles sup- @@ -7312,15 +7317,10 @@ source code patch only, without any ready-to-play distribution for systems that usually had such. - (To anyone considering resurrecting an old version: all versions - before 3.2.3 had a Y2K bug. The high scores file and the log file - contained dates which were formatted using a two-digit year, and - 1999's year 99 was followed by 2000's year 100. That got written out - successfully but it unintentionally introduced an extra column in the - file layout which prevented score entries from being read back in cor- - NetHack 5.0.0 June 23, 2026 + + NetHack 5.0.0 July 4, 2026 @@ -7330,6 +7330,12 @@ + (To anyone considering resurrecting an old version: all versions + before 3.2.3 had a Y2K bug. The high scores file and the log file + contained dates which were formatted using a two-digit year, and + 1999's year 99 was followed by 2000's year 100. That got written out + successfully but it unintentionally introduced an extra column in the + file layout which prevented score entries from being read back in cor- rectly, interfering with insertion of new high scores and with retrieval of old character names to use for random ghost and statue names in the current game.) @@ -7378,15 +7384,9 @@ Ron Van Iwaarden was the sole maintainer of NetHack for OS/2 the past several releases. Unfortunately Ron's last OS/2 machine stopped - working in early 2006. A great many thanks to Ron for keeping NetHack - alive on OS/2 all these years. - - Janne Salmijarvi and Teemu Suikki maintained and enhanced the - Amiga port of 3.4 after Janne Salmijarvi resurrected it for 3.3.1. - - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -7396,6 +7396,12 @@ + working in early 2006. A great many thanks to Ron for keeping NetHack + alive on OS/2 all these years. + + Janne Salmijarvi and Teemu Suikki maintained and enhanced the + Amiga port of 3.4 after Janne Salmijarvi resurrected it for 3.3.1. + Christian "Marvin" Bressler maintained 3.4 for the Atari after he resurrected it for 3.3.1. @@ -7444,15 +7450,9 @@ The NetHack Development Team, as well as Steve VanDevender and Kevin Smolkowski, ensured that NetHack 3.6 continued to operate on - various UNIX flavors and maintained the X11 interface. - - Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick maintained - the port of NetHack 3.6 for MacOS. - - - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -7462,6 +7462,11 @@ + various UNIX flavors and maintained the X11 interface. + + Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick maintained + the port of NetHack 3.6 for MacOS. + Michael Allison, David Cohrs, Bart House, Pasi Kallinen, Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir maintained the port of NetHack 3.6 for Microsoft Windows. @@ -7511,14 +7516,9 @@ end of April 2026. For the first time, that development was shared publicly on GitHub and SourceForge as it occurred. It was done under the label NetHack-3.7 work-in-progress (WIP), although the version - number for the next release had not yet been solidified. - - Exposure of the development to the public brought many good - things, and some challenges. People were able to observe and criticize - changes and new features almost immediately, and they often did. The - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -7528,6 +7528,11 @@ + number for the next release had not yet been solidified. + + Exposure of the development to the public brought many good + things, and some challenges. People were able to observe and criticize + changes and new features almost immediately, and they often did. The GitHub pull request system made it straightforward for people to con- tribute directly to development. Contributions resolved many, many bugs in the game and we thank all the contributors. @@ -7577,14 +7582,9 @@ Michael Allison, David Cohrs, Bart House, Pasi Kallinen, Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir. - With sadness, the devteam would like to acknowledge and remember - the past contributions from the late Ron Van Iwaarden, who was the - sole maintainer of NetHack for OS/2 for several past NetHack releases. - Ron will be missed. - - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -7594,6 +7594,11 @@ + With sadness, the devteam would like to acknowledge and remember + the past contributions from the late Ron Van Iwaarden, who was the + sole maintainer of NetHack for OS/2 for several past NetHack releases. + Ron will be missed. + The official NetHack web site is maintained by Ken Lorber at https://www.nethack.org/. @@ -7643,6 +7648,18 @@ again to M. Drew Streib and Pasi Kallinen for providing a public NetHack server at nethack.alt.org. Thanks to Keith Simpson and Andy Thomson for hardfought.org. Thanks to all those unnamed dungeoneers + + + NetHack 5.0.0 July 4, 2026 + + + + + + NetHack Guidebook 117 + + + who invest their time and effort into annual NetHack tournaments such as Junethack, The November NetHack Tournament, and in days past, devnull.net (gone for now, but not forgotten). @@ -7650,13 +7667,40 @@ - NetHack 5.0.0 June 23, 2026 - NetHack Guidebook 117 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -7672,37 +7716,13 @@ + NetHack 5.0.0 July 4, 2026 - - - - - - - - - - - - - - - - - - - - - - - - - - + NetHack Guidebook 118 @@ -7713,19 +7733,6 @@ Andy Church Janne Salmijarvi Nathan Eady Andy Swanson Jean-Christophe Collet Norm Meluch Andy Thomson Jeff Bailey Olaf Seibert - - - - NetHack 5.0.0 June 23, 2026 - - - - - - NetHack Guidebook 118 - - - Ari Huttunen Jochen Erwied Pasi Kallinen Bart House John Kallen Pat Rankin Benson I. Margulies John Rupley Patric Mueller @@ -7775,14 +7782,7 @@ - - - - - - - - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 @@ -7848,7 +7848,7 @@ - NetHack 5.0.0 June 23, 2026 + NetHack 5.0.0 July 4, 2026 From 12560f9b137e2da1ffff631ee1cc705a62b810d3 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sun, 5 Jul 2026 22:26:42 -0400 Subject: [PATCH 536/702] Add return value where needed. --- win/share/tileset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/share/tileset.c b/win/share/tileset.c index 385d26580..c3fbb209a 100644 --- a/win/share/tileset.c +++ b/win/share/tileset.c @@ -31,7 +31,7 @@ read_tiles(const char *filename, boolean true_color) boolean ok; if (tiles != NULL) - return; + return TRUE; /* Fill the image structure with known values */ image.width = 0; From f5f498eb9ecf12ab7660bfa15aa63b21f4f7b37b Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 6 Jul 2026 07:58:16 -0400 Subject: [PATCH 537/702] fixes5-0-1.txt entry for pull request #1617 --- doc/fixes5-0-1.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 77f7264a4..2891ebf31 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -198,7 +198,11 @@ MS-DOS: add U+2299, U+2601 and U+2980 to the bundled fonts, so that all MS-DOS: The 16 color mode loads the font specified in font_map, and accepts it only if its size is 8 by 16 pixels; avoid a null dereference if the font is not found (pr #1611 by chasonr) -musl: musl libc does not have __sighandler_t so don't use it in the +MS-DOS: some optimizations for tile handling; change 16-color mode and + VESA mode so that the tile is processed once, when it is first + displayed, with the result cached; Use memcpy when splitting the + image into tiles; only load the tileset once (pr #1617 by chasonr) +#1617musl: musl libc does not have __sighandler_t so don't use it in the macro definition for SIG_RET_TYPE with musl WASM: resolve some build failures in 'make CROSS_TO_WASM=1' WASM: hints file cross-pre2.500 update to CFLAGS to include -DNHUUID From a6308ad5dbfa9df0592b31bfa9b1f4ce31b3b847 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 6 Jul 2026 08:03:58 -0400 Subject: [PATCH 538/702] follow-up: eliminate a fall through warning --- src/cmd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cmd.c b/src/cmd.c index 83d5333b1..978e500b0 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -4859,6 +4859,7 @@ act_on_act( break; case MCMD_JUMP: cmdq_add_ec(CQ_CANNED, dojump); + break; default: break; } From 749646e8d336a8f49f24c9f5a327038e976cb5ea Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 6 Jul 2026 08:17:38 -0400 Subject: [PATCH 539/702] follow-up: fix a paste error --- doc/fixes5-0-1.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 2891ebf31..92d5f0349 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -202,7 +202,7 @@ MS-DOS: some optimizations for tile handling; change 16-color mode and VESA mode so that the tile is processed once, when it is first displayed, with the result cached; Use memcpy when splitting the image into tiles; only load the tileset once (pr #1617 by chasonr) -#1617musl: musl libc does not have __sighandler_t so don't use it in the +musl: musl libc does not have __sighandler_t so don't use it in the macro definition for SIG_RET_TYPE with musl WASM: resolve some build failures in 'make CROSS_TO_WASM=1' WASM: hints file cross-pre2.500 update to CFLAGS to include -DNHUUID From bb0016db0a8bd7d16931a221ca7a3242afe0a85c Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 6 Jul 2026 10:59:53 -0400 Subject: [PATCH 540/702] Windows:OPTIONS=windowtype:tty NetHackW.exe issue --- sys/windows/windmain.c | 11 ++++++++++- win/win32/NetHackW.c | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/sys/windows/windmain.c b/sys/windows/windmain.c index 2cc92ac2a..0fb6eadb0 100644 --- a/sys/windows/windmain.c +++ b/sys/windows/windmain.c @@ -192,8 +192,8 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ #endif #endif - set_emergency_io(); #ifndef MSWIN_GRAPHICS + set_emergency_io(); early_init(argc, argv); /* already in WinMain for MSWIN_GRAPHICS */ #endif @@ -243,6 +243,15 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ windowtype = "tty"; #endif } +#ifdef MSWIN_GRAPHICS + if (!strcmp(windowtype, "tty")) + windowtype = "mswin"; +#endif +#ifdef TTY_GRAPHICS + if (!strcmp(windowtype, "mswin")) + windowtype = "tty"; +#endif + choose_windows( windowtype); /* sets all the window port function pointers */ diff --git a/win/win32/NetHackW.c b/win/win32/NetHackW.c index bee362598..431e5ee99 100644 --- a/win/win32/NetHackW.c +++ b/win/win32/NetHackW.c @@ -216,6 +216,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, windowprocs.win_raw_print_bold = mswin_raw_print_bold; windowprocs.win_nhgetch = mswin_nhgetch; windowprocs.win_wait_synch = mswin_wait_synch; + windowprocs.win_number_pad = mswin_number_pad; /* let nethackw_main do the argument processing */ nethackw_main(argc, argv); From 98bb86ab337c9953306ba6e7d20357409662d1c1 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 6 Jul 2026 11:00:50 -0400 Subject: [PATCH 541/702] Windows: fix ascii map hilite_pet hilite_pet was working with tiles, but not with ascii map. --- win/win32/mhmap.c | 3 ++- win/win32/mswproc.c | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/win/win32/mhmap.c b/win/win32/mhmap.c index 390185674..263e33bd4 100644 --- a/win/win32/mhmap.c +++ b/win/win32/mhmap.c @@ -989,7 +989,8 @@ paintGlyph(PNHMapWindow data, int i, int j, RECT * rect) rgbcolor = nhcolor_to_RGB(color); } } - if (((data->map[i][j].gm.glyphflags & MG_PET) && iflags.hilite_pet) + if ((((data->map[i][j].gm.glyphflags & MG_PET) && iflags.hilite_pet) + || ((data->map[i][j].gm.glyphflags & MG_OBJPILE) && iflags.hilite_pile)) || ((data->map[i][j].gm.glyphflags & (MG_DETECT | MG_BW_LAVA | MG_BW_ICE | MG_BW_SINK | MG_BW_ENGR)) != 0)) { diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index 09c8cb4ad..976b8d765 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -2072,6 +2072,11 @@ mswin_preference_update(const char *pref) return; } + if (stricmp(pref, "hilite_pile") == 0) { + InvalidateRect(mswin_hwnd_from_winid(WIN_MAP), NULL, TRUE); + return; + } + if (stricmp(pref, "align_message") == 0 || stricmp(pref, "align_status") == 0) { mswin_layout_main_window(NULL); From 81ac4deb1ec0a4ac52f8af5f018e9e4080914a94 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 6 Jul 2026 11:04:13 -0400 Subject: [PATCH 542/702] follow-up: fixes5-0-1.txt update --- doc/fixes5-0-1.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 92d5f0349..2c64cfe1a 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -219,6 +219,9 @@ Windows: with SELECTSAVE don't display error messages to a regular player saved-game list to select from; the game doesn't offer any action to assist with them presently, and they would have to be dealt with external to the game, so try not to annoy +Windows: fix startup of GUI NetHackW.exe if there was an explicit + OPTIONS=windowtype:tty in the config file +Windows: fix hilite_pet on the GUI NetHackW.exe when ascii map was selected tty: allow custom glyph colors if they're basic 16 nethack colors on terminals with less than 256 colors X11: obey timed_delay From ac151181d2e5f322a0f0e5c7f36c3859aa55161c Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 6 Jul 2026 14:16:15 -0400 Subject: [PATCH 543/702] more u.ustuck issues on save/restore During a synchronous save operation initiated by the player (or other trigger for dosave0()), the u.usteed_mid and u.ustuck_mid values get set by savemonch(), and the monst pointers that u.ustuck and u.usteed point to are no longer valid, but not cleared. The checkpoint operation, which also needs to ensure that u.ustuck_mid and u.usteed_mid are set, must set them during the checkpoint, which is okay because the u.usteed and u.ustuck pointers _are_ valid during a checkpoint operation. So, we need to distinguish between a save game sequence, and a checkpoint sequence when writing out the u struct. --- src/mon.c | 2 ++ src/restore.c | 3 +-- src/save.c | 29 ++++++++++++++++++++++++----- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/mon.c b/src/mon.c index f04e2418c..6ad8a0fb5 100644 --- a/src/mon.c +++ b/src/mon.c @@ -3433,6 +3433,8 @@ set_ustuck(struct monst *mtmp) disp.botl = TRUE; u.ustuck = mtmp; + if (u.ustuck_mid) + u.ustuck_mid = 0; if (!u.ustuck) { u.uswallow = 0; u.uswldtim = 0; diff --git a/src/restore.c b/src/restore.c index 5ab2342c7..8a7ad8743 100644 --- a/src/restore.c +++ b/src/restore.c @@ -1219,8 +1219,7 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) u.usteed_mid = 0; } else { if (mtmp->m_id == u.ustuck_mid) { - set_ustuck(mtmp); - u.ustuck_mid = 0; + set_ustuck(mtmp); /* set_ustuck clears u.ustuck_mid */ } place_monster(mtmp, mtmp->mx, mtmp->my); if (mtmp->wormno) diff --git a/src/save.c b/src/save.c index d03000408..7eb7f5eb6 100644 --- a/src/save.c +++ b/src/save.c @@ -285,13 +285,32 @@ savegamestate(NHFILE *nhfp) Sfo_long(nhfp, &svw.wreserve, "wreserve"); Sfo_int32(nhfp, &svw.wtreserved, "wtreserved"); /* - * It is critical to ensure that u.ustuck_mid and u.usteed_mid - * hold current and correct data, in case this is needed by - * recover. + * In a normal save operation initiated by the player, + * the u.ustuck_mid and u.usteed_mid were already set + * by savemonchn() called from savelev_core(). Under + * that operation, u.ustuck and u.usteed pointers no longer + * point to valid locations here. Their non-zero values serve + * only to flag that they are were set, but the pointers + * must not be dereferenced. */ - u.ustuck_mid = (u.ustuck) ? u.ustuck->m_id : 0; - u.usteed_mid = (u.usteed) ? u.usteed->m_id : 0; + if (program_state.in_checkpoint) { + /* + * It is critical to ensure that u.ustuck_mid and u.usteed_mid + * hold current and correct data, in case this is needed by + * recover. The pointers, if set, are still pointing at + * valid data during a checkpoint operation, unlike during + * a synchronized save operation. + */ + u.ustuck_mid = (u.ustuck) ? u.ustuck->m_id : 0; + u.usteed_mid = (u.usteed) ? u.usteed->m_id : 0; + } Sfo_you(nhfp, &u, "gamestate-you"); + + /* clear the in-memory value of these, now that they have been + * successfully written out. + */ + u.ustuck_mid = 0; + u.usteed_mid = 0; Sfo_char(nhfp, yyyymmddhhmmss(ubirthday), "gamestate-ubirthday", 14); Sfo_long(nhfp, &urealtime.realtime, "gamestate-realtime"); Sfo_char(nhfp, yyyymmddhhmmss(urealtime.start_timing), "gamestate-start_timing", 14); From f3f39311e560eb6aee19b66483f150a4e0691182 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Tue, 7 Jul 2026 16:24:35 -0400 Subject: [PATCH 544/702] MS-DOS: Define a separate palette for VGA text In 16 color mode, text colors are mapped onto the colors available in the tileset. The mapping is a compromise, and is not one-to-one: cyan and bright cyan are the same, and magenta and bright magenta are the same. This change defines a separate palette for use by the text map, and switches palettes on any transition between text and tiled maps. --- sys/msdos/vidvga.c | 71 ++++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index a546d67c1..cedc9e6b8 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -182,31 +182,36 @@ extern int total_tiles_used, Tile_corr, Tile_unexplored; /* from tile.c */ } #define TOP_MAP_ROW 1 -static int vgacmap[CLR_MAX] = { 1, 4, 6, 10, 5, 9, 0, 15, - 12, 3, 7, 8, 2, 9, 0, 14 }; +static const int vgacmap[CLR_MAX] = { + 1, 4, 6, 10, 5, 9, 0, 15, + 12, 3, 7, 8, 2, 9, 0, 14 }; +static const int textcmap[CLR_MAX] = { + 1, 4, 6, 10, 5, 9, 0, 15, + 12, 3, 7, 8, 2, 11, 13, 14 }; static int viewport_size = 40; /* static char masktable[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; */ /* static char bittable[8]= {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; */ -#if 0 -static char defpalette[] = { /* Default VGA palette */ - 0x00, 0x00, 0x00, - 0x00, 0x00, 0xaa, - 0x00, 0xaa, 0x00, - 0x00, 0xaa, 0xaa, - 0xaa, 0x00, 0x00, - 0xaa, 0x00, 0xaa, - 0xaa, 0xaa, 0x00, - 0xaa, 0xaa, 0xaa, - 0x55, 0x55, 0x55, - 0xcc, 0xcc, 0xcc, - 0x00, 0x00, 0xff, - 0x00, 0xff, 0x00, - 0xff, 0x00, 0x00, - 0xff, 0xff, 0x00, - 0xff, 0x00, 0xff, - 0xff, 0xff, 0xff +/* When showing the text view, use this palette */ +static const struct Pixel text_palette[] = { + /* Permuted to mostly match the tileset */ + { 0x00, 0xaa, 0xaa, 0xff }, /* CLR_CYAN */ + { 0x00, 0x00, 0x00, 0xff }, /* CLR_BLACK */ + { 0x44, 0x44, 0xff, 0xff }, /* CLR_BRIGHT_BLUE */ + { 0xff, 0x90, 0x00, 0xff }, /* CLR_ORANGE */ + { 0xaa, 0x00, 0x00, 0xff }, /* CLR_RED */ + { 0x22, 0x22, 0xff, 0xff }, /* CLR_BLUE */ + { 0x00, 0xaa, 0x00, 0xff }, /* CLR_GREEN */ + { 0x00, 0xff, 0x00, 0xff }, /* CLR_BRIGHT_GREEN */ + { 0xff, 0xff, 0x00, 0xff }, /* CLR_YELLOW */ + { 0xaa, 0x00, 0xaa, 0xff }, /* CLR_MAGENTA */ + { 0x99, 0x40, 0x00, 0xff }, /* CLR_BROWN */ + { 0xff, 0x00, 0xff, 0xff }, /* CLR_BRIGHT_MAGENTA */ + { 0x55, 0x55, 0x55, 0xff }, /* NO_COLOR */ + { 0x00, 0xff, 0xff, 0xff }, /* CLR_BRIGHT_CYAN */ + { 0xff, 0xff, 0xff, 0xff }, /* CLR_WHITE */ + { 0xaa, 0xaa, 0xaa, 0xff }, /* CLR_GRAY */ + { 0x00, 0xff, 0xff, 0xff } /* CLR_BRIGHT_CYAN repeated */ }; -#endif #ifndef ALTERNATE_VIDEO_METHOD int vp[SCREENPLANES] = { 8, 4, 2, 1 }; @@ -552,6 +557,7 @@ void vga_overview(boolean on) { /* vga_HideCursor(); */ + vga_SetPalette(paletteptr); if (on) { iflags.over_view = TRUE; clipx = 0; @@ -572,10 +578,12 @@ vga_traditional(boolean on) if (on) { /* switch_symbols(FALSE); */ iflags.traditional_view = TRUE; + vga_SetPalette(text_palette); clipx = 0; clipxmax = CO - 1; } else { iflags.traditional_view = FALSE; + vga_SetPalette(paletteptr); if (!iflags.over_view) { clipx = max(0, (curcol - viewport_size / 2)); if (clipx > ((CO - 1) - viewport_size)) @@ -834,7 +842,7 @@ vga_Init(void) iflags.tile_view = TRUE; iflags.over_view = FALSE; #else - paletteptr = defpalette; + paletteptr = text_palette; #endif vga_SetPalette(paletteptr); g_attribute = attrib_gr_normal; @@ -1008,7 +1016,7 @@ vga_WriteChar(uint32 chr, int col, int row, int colour) char __far *cp; unsigned char fnt; - int actual_colour = vgacmap[colour]; + int actual_colour = colour; int bgcolor; int vplane; unsigned char bitmap[ROWS_PER_CELL]; @@ -1017,9 +1025,9 @@ vga_WriteChar(uint32 chr, int col, int row, int colour) vga_GetBitmap(chr, bitmap); if (curframecolor != NO_COLOR) - bgcolor = vgacmap[curframecolor]; + bgcolor = curframecolor; else - bgcolor = BACKGROUND_VGA_COLOR; + bgcolor = CLR_BLACK; if (inversed) { int tmpc = actual_colour; @@ -1027,6 +1035,19 @@ vga_WriteChar(uint32 chr, int col, int row, int colour) bgcolor = tmpc; } +#ifdef TILES_IN_GLYPHMAP + if (iflags.traditional_view) { +#endif + /* A one-to-one remapping to keep black at the same index either way */ + actual_colour = textcmap[actual_colour]; + bgcolor = textcmap[bgcolor]; +#ifdef TILES_IN_GLYPHMAP + } else { + actual_colour = vgacmap[actual_colour]; + bgcolor = vgacmap[bgcolor]; + } +#endif + x = min(col, (CO - 1)); /* min() used protection from callers */ pixy = min(row, (LI - 1)) * 16; /* assumes 8 x 16 char set */ vplane = ~actual_colour & ~bgcolor & 0xF; From 00ad0e6f76dbf7fcf48e1a98eb412ac0a823512e Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 8 Jul 2026 07:24:16 -0400 Subject: [PATCH 545/702] fixes5-0-1.txt entry for pull request #1620 --- doc/fixes5-0-1.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 2c64cfe1a..6517394d5 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -202,7 +202,8 @@ MS-DOS: some optimizations for tile handling; change 16-color mode and VESA mode so that the tile is processed once, when it is first displayed, with the result cached; Use memcpy when splitting the image into tiles; only load the tileset once (pr #1617 by chasonr) -musl: musl libc does not have __sighandler_t so don't use it in the +MS-DOS: Define a separate palette for VGA text (pr #1620 by chasonr) +#1620musl: musl libc does not have __sighandler_t so don't use it in the macro definition for SIG_RET_TYPE with musl WASM: resolve some build failures in 'make CROSS_TO_WASM=1' WASM: hints file cross-pre2.500 update to CFLAGS to include -DNHUUID From 05d1ed365fd1b409e46eb1accc9c1897a6c3c1f9 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 8 Jul 2026 07:38:37 -0400 Subject: [PATCH 546/702] follow-up fixes5-0-1.txt --- doc/fixes5-0-1.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 6517394d5..6a177f21b 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -203,7 +203,7 @@ MS-DOS: some optimizations for tile handling; change 16-color mode and displayed, with the result cached; Use memcpy when splitting the image into tiles; only load the tileset once (pr #1617 by chasonr) MS-DOS: Define a separate palette for VGA text (pr #1620 by chasonr) -#1620musl: musl libc does not have __sighandler_t so don't use it in the +musl: musl libc does not have __sighandler_t so don't use it in the macro definition for SIG_RET_TYPE with musl WASM: resolve some build failures in 'make CROSS_TO_WASM=1' WASM: hints file cross-pre2.500 update to CFLAGS to include -DNHUUID From f41f1aa09a76e6c40aacdb94e31a816426409b9b Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 9 Jul 2026 16:42:56 -0400 Subject: [PATCH 547/702] resolve a cross-compile link error --- sys/unix/Makefile.src | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index d89958d10..7347880e5 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -655,7 +655,7 @@ $(GAME): pregame $(MAKEDEFS) $(LUALIB) $(WAVS) $(SYSTEM) #$(info DATE_O=$(DATE_O)) #$(info GENTILEOFILE=$(GENTILEOFILE)) -Sysunix: $(GENTILEOFILE) $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) \ +Sysunix: $(HOSTOBJ) $(HOBJ) $(GENTILEOFILE) $(TARGET_HACKLIB) \ $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ @@ -664,7 +664,7 @@ Sysunix: $(GENTILEOFILE) $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) \ $(TARGET_LIBS) $(LUALIBS) $(AUTOLIBS) @touch Sysunix -Sys3B2: $(GENTILEOFILE) $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) \ +Sys3B2: $(HOSTOBJ) $(HOBJ) $(GENTILEOFILE) $(TARGET_HACKLIB) \ $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ @@ -672,7 +672,7 @@ Sys3B2: $(GENTILEOFILE) $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) \ $(TARGET_HACKLIB) $(WINLIB) $(LUALIBS) -lmalloc @touch Sys3B2 -Sysatt: $(GENTILEOFILE) $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) \ +Sysatt: $(HOSTOBJ) $(HOBJ) $(GENTILEOFILE) $(TARGET_HACKLIB) \ $(DATE_O) $(BUILDMORE) Makefile @echo "Loading $(GAME)." $(AT)$(LD) $(TARGET_LFLAGS) /lib/crt0s.o /lib/shlib.ifile \ @@ -680,7 +680,7 @@ Sysatt: $(GENTILEOFILE) $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) \ $(DATE_O) $(GENTILEOFILE) $(TARGET_HACKLIB) $(LUALIBS) @touch Sysatt -Systos: $(GENTILEOFILE) $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) \ +Systos: $(HOSTOBJ) $(HOBJ) $(GENTILEOFILE) $(TARGET_HACKLIB) \ $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ @@ -688,7 +688,7 @@ Systos: $(GENTILEOFILE) $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) \ $(WINLIB) $(LUALIBS) @touch Systos -SysV-AT: DUMB.Setup $(GENTILEOFILE) $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) \ +SysV-AT: DUMB.Setup $(HOSTOBJ) $(HOBJ) $(GENTILEOFILE) $(TARGET_HACKLIB) \ $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ @@ -696,7 +696,7 @@ SysV-AT: DUMB.Setup $(GENTILEOFILE) $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) \ $(WINLIB) $(LUALIBS) @touch SysV-AT -SysBe: $(GENTILEOFILE) $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) \ +SysBe: $(HOSTOBJ) $(HOBJ) $(GENTILEOFILE) $(TARGET_HACKLIB) \ $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAME) \ From 7889eedfa5546f68ad9af924faaefb8feede6884 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Thu, 9 Jul 2026 23:48:14 -0400 Subject: [PATCH 548/702] MS-DOS: Support no-tiles and no-graphics builds In previous versions of NetHack, setting -DUSE_TILES enabled the tile support, while setting -DSUPPRESS_GRAPHICS produced a NetHack that would write its TTY output to standard output, and rely on ANSI.SYS or similar to do screen control. (USE_TILES is now TILES_IN_GLYPHMAP.) This change ensures that the current NetHack can be built the same ways. One twist is that previous NetHacks would drop all support for graphical modes when tiles were not supported. Thus sys/msdos/vid{vga,vesa}.c have very disordered use of TILES_IN_GLYPHMAP. There was no need to check this. But now, the graphical modes also support Unicode. A non-tiled build should have the graphical modes, with only the text functions present, provided that ENHANCED_SYMBOLS is defined. Some unused and locally used symbols were cleaned up along the way. --- include/extern.h | 6 +-- include/optlist.h | 2 +- include/pcconf.h | 6 ++- src/glyphs.c | 6 ++- src/wizcmds.c | 6 +-- sys/msdos/Install.dos | 13 ++++- sys/msdos/msdos.c | 14 +---- sys/msdos/pckeys.c | 16 ++++-- sys/msdos/pcvideo.h | 3 +- sys/msdos/video.c | 26 +++++---- sys/msdos/vidtxt.c | 4 +- sys/msdos/vidvesa.c | 78 +++++++++++++++++++++++++-- sys/msdos/vidvga.c | 46 ++++++++++++++-- sys/share/pctty.c | 7 +++ sys/unix/hints/include/cross-post.500 | 4 +- sys/unix/hints/include/cross-pre2.500 | 48 +++++++++++++---- win/share/bmptiles.c | 5 ++ win/share/giftiles.c | 5 ++ win/share/tileset.c | 5 ++ win/tty/termcap.c | 14 ++--- win/tty/wintty.c | 6 +-- 21 files changed, 248 insertions(+), 72 deletions(-) diff --git a/include/extern.h b/include/extern.h index 5edd7ac7b..761450267 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1986,9 +1986,6 @@ extern void mplayer_talk(struct monst *) NONNULLARG1; #ifndef WIN32 extern int tgetch(void); #endif -#ifndef TOS -extern char switchar(void); -#endif #ifndef __GO32__ extern long freediskspace(char *); #ifdef MSDOS @@ -2424,6 +2421,9 @@ extern void gettty(void); extern void settty(const char *); extern void setftty(void); ATTRNORETURN extern void error(const char *, ...) PRINTF_F(1, 2) NORETURN; +#ifdef ENHANCED_SYMBOLS +extern void tty_utf8graphics_fixup(void); +#endif #if defined(TIMED_DELAY) && defined(_MSC_VER) extern void msleep(unsigned); #endif diff --git a/include/optlist.h b/include/optlist.h index a8c93ecd1..516d93e19 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -825,7 +825,7 @@ static int optfn_##a(int, int, boolean, char *, char *); (char *)0) NHOPTC(versinfo, Advanced, 80, opt_out, set_in_game, No, Yes, No, Yes, NoAlias, "extra information for 'showvers'") -#ifdef MSDOS +#if defined(MSDOS) && defined(NO_TERMS) NHOPTC(video, Advanced, 20, opt_in, set_in_config, No, Yes, No, No, NoAlias, "method of video updating") #endif diff --git a/include/pcconf.h b/include/pcconf.h index a4adbbd9f..904c250c7 100644 --- a/include/pcconf.h +++ b/include/pcconf.h @@ -75,7 +75,7 @@ */ #ifndef SUPPRESS_GRAPHICS #if (defined(SCREEN_BIOS) || defined(SCREEN_DJGPPFAST)) && !defined(PC9800) -#ifdef TILES_IN_GLYPHMAP +#if defined(TILES_IN_GLYPHMAP) || defined(ENHANCED_SYMBOLS) #define SCREEN_VGA /* Include VGA graphics routines in the build */ #define SCREEN_VESA #endif @@ -288,6 +288,10 @@ #endif #endif /* End of sanity check block */ +#if defined(MSDOS) && defined(SUPPRESS_GRAPHICS) +#define NO_TERMCAP_HEADERS +#endif + #if defined(MSDOS) && defined(DLB) #define FILENAME_CMP stricmp /* case insensitive */ #endif diff --git a/src/glyphs.c b/src/glyphs.c index 8e12da56d..2ef04a3a6 100644 --- a/src/glyphs.c +++ b/src/glyphs.c @@ -711,8 +711,10 @@ apply_customizations( struct customization_detail *details; struct symset_customization *sc; boolean at_least_one = FALSE, - do_colors = ((docustomize & do_custom_colors) != 0), - do_symbols = ((docustomize & do_custom_symbols) != 0); + do_colors = ((docustomize & do_custom_colors) != 0); +#ifdef ENHANCED_SYMBOLS + boolean do_symbols = ((docustomize & do_custom_symbols) != 0); +#endif int custs; for (custs = 0; custs < (int) custom_count; ++custs) { diff --git a/src/wizcmds.c b/src/wizcmds.c index 149607228..2d255c3d3 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -1990,10 +1990,8 @@ wizcustom_callback(winid win, int glyphnum, char *id) extern glyph_map glyphmap[MAX_GLYPH]; glyph_map *cgm; int clr = NO_COLOR; - char buf[BUFSZ], bufa[BUFSZ], bufb[BUFSZ], bufc[BUFSZ], bufd[BUFSZ], - bufu[BUFSZ]; + char buf[BUFSZ], bufa[BUFSZ], bufb[BUFSZ], bufc[BUFSZ], bufu[BUFSZ]; anything any; - uint8 *cp; if (win && id) { cgm = &glyphmap[glyphnum]; @@ -2009,9 +2007,11 @@ wizcustom_callback(winid win, int glyphnum, char *id) bufu[0] = '\0'; #ifdef ENHANCED_SYMBOLS if (cgm->u && cgm->u->utf8str) { + uint8 *cp; Sprintf(bufu, "U+%04lx", (unsigned long) cgm->u->utf32ch); cp = cgm->u->utf8str; while (*cp) { + char bufd[BUFSZ]; Sprintf(bufd, " <%d>", (int) *cp); Strcat(bufu, bufd); cp++; diff --git a/sys/msdos/Install.dos b/sys/msdos/Install.dos index a8091e607..7a13938a5 100644 --- a/sys/msdos/Install.dos +++ b/sys/msdos/Install.dos @@ -96,11 +96,22 @@ II. There once was a time when people built NetHack right on their DOS machine. make WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 WANT_DOSVGA=1 package + For the TTY interface, use NO_TILES=1 to drop support for tiles. The + resulting TTY interface can still support Unicode if that is enabled + in include/config.h. + + For the TTY interface, use NO_GRAPHICS=1 to drop all graphics support, and + build a NetHack that outputs through the standard output channel. This + configuration requires ANSI.SYS, or an equivalent driver such as NANSI.SYS. + The curses interface will still use graphics if WANT_DOSVGA=1 is set. + + NO_GRAPHICS=1 takes priority of NO_TILES=1. + Result: The "make package" target will bundle all of the necessary components to run NetHack on msdos into a folder: targets/msdos/pkg and then it zips the contents of that folder into: - targets/msdos/nh370dos.zip + targets/msdos/NH500DOS.ZIP Also note that building the msdos targets using the make command above, does not preclude you from building local linux or macOS diff --git a/sys/msdos/msdos.c b/sys/msdos/msdos.c index e2787b020..a26c86c2c 100644 --- a/sys/msdos/msdos.c +++ b/sys/msdos/msdos.c @@ -57,7 +57,7 @@ unsigned long sys_random_seed(void); static char *getdta(void); #endif static unsigned int dos_ioctl(int, int, unsigned); -#ifdef TILES_IN_GLYPHMAP +#ifdef NO_TERMS extern boolean pckeys(unsigned char, unsigned char); /* pckeys.c */ #endif @@ -280,7 +280,7 @@ BIOSgetch(void) else ch = kpad[scan - KEYPADLO].normal; } -#ifdef TILES_IN_GLYPHMAP +#ifdef NO_TERMS /* Check for special interface manipulation keys */ if (pckeys(scan, shift)) { ch = 0xFF; @@ -349,16 +349,6 @@ DOSgetch(void) return (ch); } -char -switchar(void) -{ - union REGS regs; - - regs.x.ax = GETSWITCHAR; - intdos(®s, ®s); - return regs.h.dl; -} - #if 0 static long freediskspace(char *path) diff --git a/sys/msdos/pckeys.c b/sys/msdos/pckeys.c index b8997f9c3..bc4649308 100644 --- a/sys/msdos/pckeys.c +++ b/sys/msdos/pckeys.c @@ -8,16 +8,17 @@ #include "hack.h" -#ifdef MSDOS -#ifdef TILES_IN_GLYPHMAP +#if defined(MSDOS) && defined(NO_TERMS) #include "wintty.h" #include "pcvideo.h" boolean pckeys(unsigned char, unsigned char); +#ifdef TILES_IN_GLYPHMAP static void userpan(enum vga_pan_direction pan); static void overview(boolean); static void traditional(boolean); static void refresh(void); +#endif extern struct WinDesc *wins[MAXWIN]; /* from wintty.c */ extern boolean inmap; /* from video.c */ @@ -34,9 +35,15 @@ extern boolean inmap; /* from video.c */ boolean pckeys(unsigned char scancode, unsigned char shift) { +#ifdef TILES_IN_GLYPHMAP boolean opening_dialog; opening_dialog = svp.pl_character[0] ? FALSE : TRUE; +#endif + +#ifndef TILES_IN_GLYPHMAP + nhUse(shift); +#endif switch (scancode) { #ifdef SIMULATE_CURSOR case 0x3d: /* F3 = toggle cursor type */ @@ -47,6 +54,7 @@ pckeys(unsigned char scancode, unsigned char shift) DrawCursor(); break; #endif +#ifdef TILES_IN_GLYPHMAP case 0x74: /* Control-right_arrow = scroll horizontal to right */ if ((shift & CTRL) && iflags.tile_view && !opening_dialog) userpan(pan_right); @@ -83,12 +91,14 @@ pckeys(unsigned char scancode, unsigned char shift) refresh(); } break; +#endif /* TILES_IN_GLYPHMAP */ default: return FALSE; } return TRUE; } +#ifdef TILES_IN_GLYPHMAP static void userpan(enum vga_pan_direction pan) { @@ -141,6 +151,6 @@ refresh(void) #endif } #endif /* TILES_IN_GLYPHMAP */ -#endif /* MSDOS */ +#endif /* MSDOS && NO_TERMS */ /*pckeys.c*/ diff --git a/sys/msdos/pcvideo.h b/sys/msdos/pcvideo.h index a9cce2bbb..a3a088058 100644 --- a/sys/msdos/pcvideo.h +++ b/sys/msdos/pcvideo.h @@ -237,12 +237,12 @@ extern void HideCursor(void); /* ### vidtxt.c ### */ +extern void txt_get_scr_size(void); #ifdef NO_TERMS extern void txt_backsp(void); extern void txt_clear_screen(void); extern void txt_cl_end(int, int); extern void txt_cl_eos(void); -extern void txt_get_scr_size(void); extern void txt_gotoxy(int, int); extern int txt_monoadapt_check(void); extern void txt_nhbell(void); @@ -267,7 +267,6 @@ extern void vga_show_cursor(void); extern void vga_DrawCursor(void); #endif extern void vga_Finish(void); -extern char __far *vga_FontPtrs(void); extern void vga_get_scr_size(void); extern void vga_gotoloc(int, int); #ifdef POSITIONBAR diff --git a/sys/msdos/video.c b/sys/msdos/video.c index 7d2a91ef5..ec21aa695 100644 --- a/sys/msdos/video.c +++ b/sys/msdos/video.c @@ -132,17 +132,17 @@ void cmov(int, int); void nocmov(int, int); static void init_ttycolor(void); -int savevmode; /* store the original video mode in here */ +#if defined(SCREEN_VGA) || defined(SCREEN_VESA) int curcol, currow; /* graphics mode current cursor locations */ +#endif int g_attribute; /* Current attribute to use */ -int monoflag; /* 0 = not monochrome, else monochrome */ +static int monoflag; /* 0 = not monochrome, else monochrome */ int inversed; int attrib_text_normal; /* text mode normal attribute */ int attrib_gr_normal; /* graphics mode normal attribute */ int attrib_text_intense; /* text mode intense attribute */ int attrib_gr_intense; /* graphics mode intense attribute */ uint32 curframecolor = NO_COLOR; /* current background text color */ -boolean traditional = FALSE; /* traditional TTY character mode */ boolean inmap = FALSE; /* in the map window */ char ttycolors[CLR_MAX]; /* also used/set in options.c */ @@ -183,8 +183,8 @@ term_curs_set(int visibility) #ifdef SCREEN_VESA } else if (iflags.usevesa) { vesa_hide_cursor(); - } #endif + } } else if (visibility) { if (!iflags.grmode) { txt_show_cursor(); @@ -195,8 +195,8 @@ term_curs_set(int visibility) #ifdef SCREEN_VESA } else if (iflags.usevesa) { vesa_show_cursor(); - } #endif + } } vis = visibility; } @@ -255,16 +255,16 @@ void cl_end(void) /* clear to end of line */ void cl_eos(void) /* clear to end of screen */ { - int cy = (int) ttyDisplay->cury + 1; - if (!iflags.grmode) { txt_cl_eos(); #ifdef SCREEN_VGA } else if (iflags.usevga) { + int cy = (int) ttyDisplay->cury + 1; vga_cl_eos(cy); #endif #ifdef SCREEN_VESA } else if (iflags.usevesa) { + int cy = (int) ttyDisplay->cury + 1; vesa_cl_eos(cy); #endif } @@ -683,6 +683,7 @@ xputc(int ch) /* write out character (and attribute) */ } /* write out a glyph picture at current location */ +#ifdef TILES_IN_GLYPHMAP void xputg(const glyph_info *glyphinfo, const glyph_info *bkglyphinfo) { if (!iflags.grmode || !iflags.tile_view) { @@ -697,6 +698,7 @@ void xputg(const glyph_info *glyphinfo, const glyph_info *bkglyphinfo) #endif } } +#endif /* TILES_IN_GLYPHMAP */ #ifdef POSITIONBAR void @@ -731,6 +733,8 @@ adjust_cursor_flags(struct WinDesc *cw) cursor_flag = 1; } #endif /* 0 */ +#else + nhUse(cw); #endif /* SIMULATE_CURSOR */ } @@ -796,9 +800,9 @@ HideCursor(void) /* assign_videocolors() is prototyped in extern.h */ /* assign_video() is prototyped in extern.h */ -int shadeflag; /* shades are initialized */ -int colorflag; /* colors are initialized */ -const char *schoice[3] = { "dark", "normal", "light" }; +static int shadeflag; /* shades are initialized */ +static int colorflag; /* colors are initialized */ +static const char *schoice[3] = { "dark", "normal", "light" }; const char *shade[3]; #endif /* VIDEOSHADES */ @@ -1068,6 +1072,7 @@ assign_video(char *sopt) return 1; } +#ifdef TILES_IN_GLYPHMAP void tileview(boolean enable) { @@ -1080,6 +1085,7 @@ tileview(boolean enable) vesa_traditional(enable ? FALSE : TRUE); #endif } +#endif /* TILES_IN_GLYPHMAP */ #endif /* NO_TERMS */ #else /* STUBVIDEO */ diff --git a/sys/msdos/vidtxt.c b/sys/msdos/vidtxt.c index f60b1c715..a97b45b24 100644 --- a/sys/msdos/vidtxt.c +++ b/sys/msdos/vidtxt.c @@ -109,7 +109,7 @@ txt_get_scr_size(void) void txt_gotoxy(int, int); #if defined(SCREEN_BIOS) && !defined(PC9800) -void txt_get_cursor(int *, int *); +static void txt_get_cursor(int *, int *); #endif #ifdef SCREEN_DJGPPFAST @@ -401,7 +401,7 @@ void txt_xputc(char ch, int attr) * * This is implemented as a macro under DJGPPFAST. */ -void txt_get_cursor(int *x, int *y) +static void txt_get_cursor(int *x, int *y) { union REGS regs; diff --git a/sys/msdos/vidvesa.c b/sys/msdos/vidvesa.c index 147e21da3..c07fc6877 100644 --- a/sys/msdos/vidvesa.c +++ b/sys/msdos/vidvesa.c @@ -15,12 +15,22 @@ #include "pctiles.h" #include "vesa.h" #include "wintty.h" -#include "tileset.h" #include "font.h" +#ifdef TILES_IN_GLYPHMAP +#include "tileset.h" +#else +/* For the palette */ +struct Pixel { + unsigned char r, g, b, a; +}; +#endif + #define FIRST_TEXT_COLOR 240 +#ifdef TILES_IN_GLYPHMAP extern int total_tiles_used, Tile_corr, Tile_unexplored; /* from tile.c */ +#endif struct VesaCharacter { uint32 colour, bgcolour; uint32 chr; @@ -37,8 +47,10 @@ static unsigned long vesa_MakeColor(struct Pixel); static void vesa_FillRect(unsigned left, unsigned top, unsigned width, unsigned height, unsigned color); +#ifdef TILES_IN_GLYPHMAP static void vesa_redrawmap(void); static void vesa_cliparound(int, int); +#endif #if 0 static void decal_packed(const struct TileImage *tile, unsigned special); #endif @@ -47,7 +59,9 @@ static void vesa_SetViewPort(void); static boolean vesa_SetPalette(const struct Pixel *); static boolean vesa_SetHardPalette(const struct Pixel *); static boolean vesa_SetSoftPalette(const struct Pixel *); +#ifdef TILES_IN_GLYPHMAP static void vesa_DisplayCell(int, int, int); +#endif static unsigned vesa_FindMode(unsigned long mode_addr, unsigned bits); static void vesa_WriteChar(uint32, int, int, uint32); static void vesa_WriteCharXY(uint32, int, int, uint32); @@ -60,8 +74,10 @@ static unsigned long vesa_DoublePixels(unsigned long); static unsigned long vesa_TriplePixels(unsigned long); static void vesa_WriteStr(const char *, int, int, int, int); static unsigned char __far *vesa_FontPtrs(void); +#ifdef TILES_IN_GLYPHMAP static unsigned char *vesa_tile(unsigned); static unsigned char *vesa_oview_tile(unsigned); +#endif /* static void vesa_process_tile(struct TileImage *tile); */ #ifdef POSITIONBAR @@ -84,6 +100,7 @@ extern boolean inmap; /* in the map window */ static unsigned char __far *font; +#ifdef TILES_IN_GLYPHMAP static struct map_struct { int glyph; uint32 ch; @@ -108,10 +125,13 @@ static struct map_struct { map[y][x].inverse = 0; \ } \ } +#endif /* TILES_IN_GLYPHMAP */ #define TOP_MAP_ROW 1 +#ifdef TILES_IN_GLYPHMAP static int viewport_cols = 40; static int viewport_rows = ROWNO; +#endif static const struct Pixel defpalette[] = { /* Colors for text and the position bar */ { 0x00, 0x00, 0x00, 0xff }, /* CLR_BLACK */ @@ -158,8 +178,10 @@ static unsigned char vesa_blue_shift; static unsigned long vesa_palette[256]; static unsigned vesa_char_width = 8, vesa_char_height = 16; static unsigned vesa_oview_width, vesa_oview_height; +#ifdef TILES_IN_GLYPHMAP static unsigned char **vesa_tiles; static unsigned char **vesa_oview_tiles; +#endif static struct BitmapFont *vesa_font; #ifdef SIMULATE_CURSOR @@ -564,8 +586,10 @@ void vesa_clear_screen(int colour) { vesa_FillRect(0, 0, vesa_x_res, vesa_y_res, colour); +#ifdef TILES_IN_GLYPHMAP if (iflags.tile_view) vesa_clearmap(); +#endif vesa_gotoloc(0, 0); /* is this needed? */ } @@ -893,6 +917,7 @@ vesa_redrawmap(void) #endif /* TILES_IN_GLYPHMAP && CLIPPING */ +#ifdef TILES_IN_GLYPHMAP void vesa_userpan(enum vga_pan_direction pan) { @@ -1040,6 +1065,7 @@ decal_packed(const struct TileImage *gp, unsigned special) } } #endif +#endif /* TILES_IN_GLYPHMAP */ DISABLE_WARNING_FORMAT_NONLITERAL @@ -1055,7 +1081,9 @@ vesa_Init(void) { static boolean inited = FALSE; const struct Pixel *paletteptr; +#ifdef TILES_IN_GLYPHMAP const char *tile_file; +#endif const char *font_name; int tilefailure = 0; @@ -1089,11 +1117,16 @@ vesa_Init(void) /* term_clear_screen() */ /* not vesa_clear_screen() */ return; } + paletteptr = get_palette(); +#else + /* This isn't actually used; it just keeps paletteptr from being NULL, + * so an 8 bit color mode will work */ + paletteptr = defpalette; #endif vesa_mode = 0xFFFF; /* might want an 8 bit mode after loading tiles */ vesa_detect(); - if (vesa_mode == 0xFFFF || (vesa_pixel_size == 8 && get_palette() == NULL)) { + if (vesa_mode == 0xFFFF || (vesa_pixel_size == 8 && paletteptr == NULL)) { raw_printf("%s (%d)", "Reverting to TTY mode, no VESA mode available.", tilefailure); wait_synch(); @@ -1108,25 +1141,26 @@ vesa_Init(void) vesa_SwitchMode(vesa_mode); vesa_SetViewPort(); +#ifdef TILES_IN_GLYPHMAP windowprocs.win_cliparound = vesa_cliparound; +#endif if (vesa_pixel_size > 8) { windowprocs.wincap2 |= WC2_EXTRACOLORS; } #ifdef TILES_IN_GLYPHMAP - paletteptr = get_palette(); iflags.tile_view = TRUE; iflags.over_view = FALSE; -#else - paletteptr = defpalette; #endif vesa_SetPalette(paletteptr); g_attribute = attrib_gr_normal; font = vesa_FontPtrs(); term_clear_screen(); +#ifdef TILES_IN_GLYPHMAP clipx = 0; clipxmax = clipx + (viewport_cols - 1); clipy = 0; clipymax = clipy + (viewport_rows - 1); +#endif /* Load a font of size appropriate to the screen size */ if (vesa_x_res >= 1280 && vesa_y_res >= 960) @@ -1185,15 +1219,18 @@ vesa_Init(void) } /* Process tiles for the current video mode */ +#ifdef TILES_IN_GLYPHMAP vesa_tiles = (unsigned char **) alloc(total_tiles_used * sizeof(void *)); memset(vesa_tiles, 0, total_tiles_used * sizeof(void *)); vesa_oview_tiles = (unsigned char **) alloc(total_tiles_used * sizeof(void *)); memset(vesa_oview_tiles, 0, total_tiles_used * sizeof(void *)); set_tile_type(vesa_pixel_size > 8); +#endif } RESTORE_WARNING_FORMAT_NONLITERAL +#ifdef TILES_IN_GLYPHMAP /* Return processed pixels for a normal tile */ static unsigned char * vesa_tile(unsigned index) @@ -1277,11 +1314,13 @@ vesa_oview_tile(unsigned index) return vesa_oview_tiles[index]; } +#endif /* TILES_IN_GLYPHMAP */ /* Set the size of the map viewport */ static void vesa_SetViewPort(void) { +#ifdef TILES_IN_GLYPHMAP unsigned y_reserved = (TOP_MAP_ROW + 5) * vesa_char_height; unsigned y_map = vesa_y_res - y_reserved; @@ -1289,6 +1328,7 @@ vesa_SetViewPort(void) viewport_rows = y_map / iflags.wc_tile_height; if (viewport_cols > COLNO) viewport_cols = COLNO; if (viewport_rows > ROWNO) viewport_rows = ROWNO; +#endif } /* @@ -1340,6 +1380,7 @@ vesa_SwitchMode(unsigned mode) void vesa_Finish(void) { +#ifdef TILES_IN_GLYPHMAP int i; for (i = 0; i < total_tiles_used; ++i) { @@ -1349,6 +1390,7 @@ vesa_Finish(void) free(vesa_tiles); free(vesa_oview_tiles); free_tiles(); +#endif vesa_SwitchMode(MODETEXT); windowprocs.win_cliparound = tty_cliparound; g_attribute = attrib_text_normal; @@ -1897,6 +1939,7 @@ vesa_TriplePixels(unsigned long fnt) * not the x,y pixel location. * */ +#ifdef TILES_IN_GLYPHMAP static void vesa_DisplayCell(int tilenum, int col, int row) { @@ -1932,6 +1975,7 @@ vesa_DisplayCell(int tilenum, int col, int row) tptr += p_row_width; } } +#endif /* TILES_IN_GLYPHMAP */ /* * Write the character string pointed to by 's', whose maximum length @@ -2009,6 +2053,8 @@ vesa_SetHardPalette(const struct Pixel *palette) p2[i*4 + 1] = palette[i].g >> shift; p2[i*4 + 2] = palette[i].r >> shift; } +#else + nhUse(palette); #endif for (i = FIRST_TEXT_COLOR; i < 256; ++i) { p2[i*4 + 0] = defpalette[i-FIRST_TEXT_COLOR].b >> shift; @@ -2077,6 +2123,8 @@ vesa_SetSoftPalette(const struct Pixel *palette) ++p; } } +#else + nhUse(palette); #endif p = defpalette; for (i = FIRST_TEXT_COLOR; i < 256; ++i) { @@ -2199,17 +2247,25 @@ positionbar(void) void vesa_DrawCursor(void) { +#ifdef TILES_IN_GLYPHMAP static boolean last_inmap = FALSE; +#endif unsigned x, y, left, top, right, bottom, width, height; +#ifdef TILES_IN_GLYPHMAP boolean isrogue = Is_rogue_level(&u.uz); boolean halfwidth = (isrogue || iflags.over_view || iflags.traditional_view || !inmap); +#else + const boolean halfwidth = TRUE; +#endif int curtyp; +#ifdef TILES_IN_GLYPHMAP if (inmap && !last_inmap) { vesa_redrawmap(); } last_inmap = inmap; +#endif if (!cursor_type && inmap) return; /* CURSOR_INVIS - nothing to do */ @@ -2232,9 +2288,12 @@ vesa_DrawCursor(void) y -= clipy; } /* convert to pixels */ +#ifdef TILES_IN_GLYPHMAP if (!inmap || iflags.traditional_view) { +#endif width = vesa_char_width; height = vesa_char_height; +#ifdef TILES_IN_GLYPHMAP } else if (iflags.over_view) { width = vesa_oview_width; height = vesa_oview_height; @@ -2242,6 +2301,7 @@ vesa_DrawCursor(void) width = iflags.wc_tile_width; height = iflags.wc_tile_height; } +#endif left = x * width + vesa_x_center; top = y * height + vesa_y_center; if (y >= TOP_MAP_ROW) { @@ -2315,9 +2375,13 @@ void vesa_HideCursor(void) { unsigned x, y, left, top, width, height; +#ifdef TILES_IN_GLYPHMAP boolean isrogue = Is_rogue_level(&u.uz); boolean halfwidth = (isrogue || iflags.over_view || iflags.traditional_view || !inmap); +#else + const boolean halfwidth = TRUE; +#endif if (!cursor_type && inmap) return; /* CURSOR_INVIS - nothing to do */ @@ -2336,9 +2400,12 @@ vesa_HideCursor(void) y -= clipy; } /* convert to pixels */ +#ifdef TILES_IN_GLYPHMAP if (!inmap || iflags.traditional_view) { +#endif width = vesa_char_width; height = vesa_char_height; +#ifdef TILES_IN_GLYPHMAP } else if (iflags.over_view) { width = vesa_oview_width; height = vesa_oview_height; @@ -2346,6 +2413,7 @@ vesa_HideCursor(void) width = iflags.wc_tile_width; height = iflags.wc_tile_height; } +#endif left = x * width + vesa_x_center; top = y * height + vesa_y_center; if (y >= TOP_MAP_ROW) { diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index cedc9e6b8..897588889 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -10,9 +10,17 @@ #ifdef SCREEN_VGA /* this file is for SCREEN_VGA only */ #include "pcvideo.h" #include "tile.h" -#include "tileset.h" #include "font.h" +#ifdef TILES_IN_GLYPHMAP +#include "tileset.h" +#else +/* For the palette */ +struct Pixel { + unsigned char r, g, b, a; +}; +#endif + #include #include "wintty.h" @@ -109,28 +117,35 @@ void vga_backsp(void); #ifdef SCROLLMAP static void vga_scrollmap(boolean); #endif +#ifdef TILES_IN_GLYPHMAP static void vga_redrawmap(boolean); static void vga_cliparound(int, int); static void decal_planar(struct planar_cell_struct *, unsigned); +#endif #ifdef POSITIONBAR static void positionbar(void); static void vga_special(int, int, int); #endif +#ifdef TILES_IN_GLYPHMAP static void vga_DisplayCell(struct planar_cell_struct *, int, int); static void vga_DisplayCell_O(struct overview_planar_cell_struct *, int, int); +#endif static void vga_SwitchMode(unsigned int); static void vga_SetPalette(const struct Pixel *); static void vga_WriteChar(uint32, int, int, int); static void vga_GetBitmap(uint32, unsigned char *); static void vga_WriteStr(char *, int, int, int, int); +static char __far *vga_FontPtrs(void); +#ifdef TILES_IN_GLYPHMAP static void read_planar_tile(unsigned, struct planar_cell_struct *); static void read_planar_tile_O(unsigned, struct overview_planar_cell_struct *); static void read_tile_indexes(unsigned, unsigned char (*)[TILE_X]); +#endif extern int clipx, clipxmax; /* current clipping column from wintty.c */ extern boolean clipping; /* clipping on? from wintty.c */ @@ -156,6 +171,7 @@ static struct BitmapFont *psf_font; static char *screentable[SCREENHEIGHT]; static const struct Pixel *paletteptr; +#ifdef TILES_IN_GLYPHMAP static struct map_struct { int glyph; uint32 ch; @@ -180,11 +196,14 @@ extern int total_tiles_used, Tile_corr, Tile_unexplored; /* from tile.c */ map[y][x].tileidx = Tile_unexplored; \ } \ } +#endif /* TILES_IN_GLYPHMAP */ #define TOP_MAP_ROW 1 +#ifdef TILES_IN_GLYPHMAP static const int vgacmap[CLR_MAX] = { 1, 4, 6, 10, 5, 9, 0, 15, 12, 3, 7, 8, 2, 9, 0, 14 }; +#endif static const int textcmap[CLR_MAX] = { 1, 4, 6, 10, 5, 9, 0, 15, 12, 3, 7, 8, 2, 11, 13, 14 }; @@ -214,12 +233,13 @@ static const struct Pixel text_palette[] = { }; #ifndef ALTERNATE_VIDEO_METHOD -int vp[SCREENPLANES] = { 8, 4, 2, 1 }; +static int vp[SCREENPLANES] = { 8, 4, 2, 1 }; #endif -int vp2[SCREENPLANES] = { 1, 2, 4, 8 }; +#ifdef TILES_IN_GLYPHMAP static struct planar_cell_struct **cell_cache; static struct overview_planar_cell_struct **cell_cache_O; +#endif /* static int g_attribute; */ /* Current attribute to use */ @@ -260,8 +280,10 @@ vga_clear_screen(int colour) WRITE_ABSOLUTE_DWORD(&pch[j], 0x00000000); } egawriteplane(15); +#ifdef TILES_IN_GLYPHMAP if (iflags.tile_view) vga_clearmap(); +#endif vga_gotoloc(0, 0); /* is this needed? */ } @@ -534,6 +556,7 @@ vga_redrawmap(boolean clearfirst) } #endif /* TILES_IN_GLYPHMAP && CLIPPING */ +#ifdef TILES_IN_GLYPHMAP void vga_userpan(enum vga_pan_direction pan) { @@ -774,6 +797,7 @@ decal_planar(struct planar_cell_struct *gpcs UNUSED, unsigned special) } else if (special & MG_RIDDEN) { } } +#endif /* TILES_IN_GLYPHMAP */ /* * Open tile files, @@ -834,7 +858,9 @@ vga_Init(void) } } vga_SwitchMode(MODE640x480); +#ifdef TILES_IN_GLYPHMAP windowprocs.win_cliparound = vga_cliparound; +#endif /* vga_NoBorder(BACKGROUND_VGA_COLOR); */ /* Not needed after palette mod */ #ifdef TILES_IN_GLYPHMAP @@ -904,6 +930,7 @@ vga_SwitchMode(unsigned int mode) void vga_Finish(void) { +#ifdef TILES_IN_GLYPHMAP int i; free_tiles(); @@ -915,6 +942,7 @@ vga_Finish(void) cell_cache = NULL; free(cell_cache_O); cell_cache_O = NULL; +#endif vga_SwitchMode(MODETEXT); windowprocs.win_cliparound = tty_cliparound; g_attribute = attrib_text_normal; @@ -954,7 +982,7 @@ vga_NoBorder(int bc) * address of the appropriate character definition table for * the current graphics mode into interrupt vector 0x43 (0000:010C). */ -char __far * +static char __far * vga_FontPtrs(void) { USHORT __far *tmp; @@ -1109,6 +1137,7 @@ vga_GetBitmap(uint32 chr, unsigned char *bitmap) } } +#ifdef TILES_IN_GLYPHMAP /* * This is the routine that displays a high-res "cell" pointed to by 'gp' * at the desired location (col,row). @@ -1172,6 +1201,7 @@ vga_DisplayCell_O(struct overview_planar_cell_struct *gpcs, int col, int row) } egawriteplane(15); } +#endif /* TILES_IN_GLYPHMAP */ /* * Write the character string pointed to by 's', whose maximum length @@ -1421,9 +1451,13 @@ vga_DrawCursor(void) unsigned char first, second; /* char on[2] = {0xFF,0xFF}; */ /* char off[2] = {0x00,0x00}; */ +#ifdef TILES_IN_GLYPHMAP boolean isrogue = Is_rogue_level(&u.uz); boolean singlebyte = (isrogue || iflags.over_view || iflags.traditional_view || !inmap); +#else + const boolean singlebyte = TRUE; +#endif int curtyp; if (!cursor_type && inmap) @@ -1633,9 +1667,13 @@ vga_HideCursor(void) int i, pixx, pixy, x, y; char __far *tmp1; char __far *tmp2; +#ifdef TILES_IN_GLYPHMAP boolean isrogue = Is_rogue_level(&u.uz); boolean singlebyte = (isrogue || iflags.over_view || iflags.traditional_view || !inmap); +#else + const boolean singlebyte = TRUE; +#endif int curtyp; if (inmap && !cursor_type) diff --git a/sys/share/pctty.c b/sys/share/pctty.c index f06dfe475..3d276fcc6 100644 --- a/sys/share/pctty.c +++ b/sys/share/pctty.c @@ -53,6 +53,13 @@ setftty(void) term_start_screen(); } +#ifdef ENHANCED_SYMBOLS +void +tty_utf8graphics_fixup(void) +{ +} +#endif + #if defined(TIMED_DELAY) && defined(_MSC_VER) void msleep(unsigned mseconds) diff --git a/sys/unix/hints/include/cross-post.500 b/sys/unix/hints/include/cross-post.500 index db5eebe6f..e0a28eb43 100644 --- a/sys/unix/hints/include/cross-post.500 +++ b/sys/unix/hints/include/cross-post.500 @@ -50,7 +50,7 @@ $(DOSFONT)/ter-u32b.psf: $(FONTTOP)/ter-u32b.bdf $(DOSFONT)/nh-u32b.bdf $(DOSFON # .PHONY: dodata dospkg dosfonts dosfonts: $(FONTTARGETS) -dospkg: dodata dosfonts $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp +dospkg: dodata dosfonts $(GAMEBIN) $(TARGETPFX)recover.exe $(NHTILES) $(TARGET_STUBEDIT) $(GAMEBIN) minstack=2048K mkdir -p $(TARGETPFX)pkg cp $(GAMEBIN) $(TARGETPFX)pkg/NETHACK.EXE @@ -58,7 +58,7 @@ dospkg: dodata dosfonts $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp -cp $(SFCTOOLBIN) $(TARGETPFX)pkg/SFCTOOL.EXE cp ../dat/nhdat $(TARGETPFX)pkg/NHDAT cp ../dat/license $(TARGETPFX)pkg/LICENSE - cp ../dat/nhtiles.bmp $(TARGETPFX)pkg/NHTILES.BMP + -cp ../dat/nhtiles.bmp $(TARGETPFX)pkg/NHTILES.BMP cp ../dat/symbols $(TARGETPFX)pkg/SYMBOLS cp ../sys/share/NetHack.cnf $(TARGETPFX)pkg/NETHACK.CNF cp ../sys/msdos/sysconf $(TARGETPFX)pkg/SYSCONF diff --git a/sys/unix/hints/include/cross-pre2.500 b/sys/unix/hints/include/cross-pre2.500 index b5efbb377..5fc642162 100644 --- a/sys/unix/hints/include/cross-pre2.500 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -177,8 +177,23 @@ MSDOS_GPP_CFLAGS = -Wall -Wextra -Wno-missing-field-initializers -Wreturn-type \ -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings -pedantic \ -Wmissing-declarations -Wformat-nonliteral -Wunreachable-code \ -Wno-maybe-uninitialized +ifdef NO_GRAPHICS + MSDOS_GRAPH_CONFIG = -DSUPPRESS_GRAPHICS + # Curses will need the fonts, but not font.c + ifndef WANT_DOSVGA + SKIP_FONTS = 1 + endif + SKIP_FONT_C = 1 + SKIP_TILES = 1 +else ifdef NO_TILES + MSDOS_GRAPH_CONFIG = + # without SKIP_FONT_C; if ENHANCED_SYMBOLS is set, we'll need the fonts + SKIP_TILES = 1 +else + MSDOS_GRAPH_CONFIG = -DTILES_IN_GLYPHMAP +endif MSDOS_TARGET_CFLAGS = -c -O $(DBGFLAGS) -I../include -I../sys/msdos -I../win/share \ - $(LUAINCL) -DDLB $(PDCURSESDEF) -DTILES_IN_GLYPHMAP \ + $(LUAINCL) -DDLB $(PDCURSESDEF) $(MSDOS_GRAPH_CONFIG) \ -DCROSSCOMPILE -DCROSSCOMPILE_TARGET -DCROSS_TO_MSDOS \ -D_NAIVE_DOS_REGS \ $(MSDOS_GCC_CFLAGS) $(SNDCFLAGS) @@ -190,7 +205,11 @@ MSDOS_TARGET_CXXFLAGS = -c -O $(DBGFLAGS) -I../include -I../sys/msdos -I../win/s PDCINCL += -I$(PDCPORT) PDC_TARGET_CFLAGS = $(MSDOS_TARGET_CFLAGS) -Wno-unused-parameter \ -Wno-missing-prototypes -ifndef SKIP_FONTS_IN_CI +ifdef SKIP_FONTS_IN_CI +FONTTARGETS= +else ifdef SKIP_FONTS +FONTTARGETS= +else FONTVER = terminus-font-4.49.1 FONTTOP = ../lib/$(FONTVER) DOSFONT = ../sys/msdos/fonts @@ -198,8 +217,6 @@ FONTTARGETS = $(DOSFONT)/ter-u16b.psf $(DOSFONT)/ter-u16v.psf \ $(DOSFONT)/ter-u18b.psf $(DOSFONT)/ter-u20b.psf \ $(DOSFONT)/ter-u22b.psf $(DOSFONT)/ter-u24b.psf \ $(DOSFONT)/ter-u28b.psf $(DOSFONT)/ter-u32b.psf -else -FONTTARGETS= endif LUABIN = ../lib/lua-$(LUA_VERSION)/src/lua LUA_TARGET_CFLAGS = $(MSDOS_TARGET_CFLAGS) @@ -216,18 +233,22 @@ override SYSSRC = ../sys/share/pcmain.c ../sys/msdos/msdos.c \ ../sys/share/pcsys.c ../sys/share/pctty.c \ ../sys/share/pcunix.c ../sys/msdos/video.c \ ../sys/msdos/vidtxt.c ../sys/msdos/pckeys.c \ - ../sys/msdos/vidvga.c ../sys/msdos/vidvesa.c \ - ../sys/msdos/font.c \ - ../win/share/bmptiles.c ../win/share/giftiles.c \ - ../win/share/tileset.c + ../sys/msdos/vidvga.c ../sys/msdos/vidvesa.c override SYSOBJ= $(TARGETPFX)pcmain.o $(TARGETPFX)msdos.o \ $(TARGETPFX)pcsys.o $(TARGETPFX)pctty.o \ $(TARGETPFX)pcunix.o $(TARGETPFX)video.o \ $(TARGETPFX)vidtxt.o $(TARGETPFX)pckeys.o \ - $(TARGETPFX)vidvga.o $(TARGETPFX)vidvesa.o \ - $(TARGETPFX)font.o \ - $(TARGETPFX)bmptiles.o $(TARGETPFX)giftiles.o \ + $(TARGETPFX)vidvga.o $(TARGETPFX)vidvesa.o +ifndef SKIP_FONT_C +override SYSSRC += ../sys/msdos/font.c +override SYSOBJ += $(TARGETPFX)font.o +endif +ifndef SKIP_TILES +override SYSSRC += ../win/share/bmptiles.c ../win/share/giftiles.c \ + ../win/share/tileset.c +override SYSOBJ += $(TARGETPFX)bmptiles.o $(TARGETPFX)giftiles.o \ $(TARGETPFX)tileset.o +endif override WINLIB= override LUALIB= override LUALIBS= @@ -250,7 +271,12 @@ GDBEXE= GDBBAT= GDBCMDLINE= endif +ifndef SKIP_TILES VARDATND += nhtiles.bmp +NHTILES = ../dat/nhtiles.bmp +else +NHTILES = +endif # ifdef WANT_WIN_CURSES # rules for pdcurses dos-specific files diff --git a/win/share/bmptiles.c b/win/share/bmptiles.c index a82ea651a..43d1bf814 100644 --- a/win/share/bmptiles.c +++ b/win/share/bmptiles.c @@ -3,6 +3,9 @@ /* NetHack may be freely redistributed. See license for details. */ #include "config.h" + +#ifdef TILES_IN_GLYPHMAP + #include "tileset.h" /* First BMP file header */ @@ -592,3 +595,5 @@ pixel_element(uint32 mask, uint32 color) color &= mask; return color * 255 / mask; } + +#endif /* TILES_IN_GLYPHMAP */ diff --git a/win/share/giftiles.c b/win/share/giftiles.c index cb026cc05..cccf206fd 100644 --- a/win/share/giftiles.c +++ b/win/share/giftiles.c @@ -7,6 +7,9 @@ * http://www.w3.org/Graphics/GIF/spec-gif89a.txt */ #include "config.h" + +#ifdef TILES_IN_GLYPHMAP + #include "tileset.h" #define MIN_LZW_BITS 3 @@ -497,3 +500,5 @@ free_data_block(struct DataBlock *block) block->size = 0; block->data = NULL; } + +#endif /* TILES_IN_GLYPHMAP */ diff --git a/win/share/tileset.c b/win/share/tileset.c index c3fbb209a..556298a7c 100644 --- a/win/share/tileset.c +++ b/win/share/tileset.c @@ -3,6 +3,9 @@ /* NetHack may be freely redistributed. See license for details. */ #include "config.h" + +#ifdef TILES_IN_GLYPHMAP + #include "objclass.h" #include "flag.h" #include "tileset.h" @@ -348,3 +351,5 @@ read_png_tiles(const char *filename UNUSED, struct TileSetImage *image UNUSED) /* stub */ return FALSE; } + +#endif /* TILES_IN_GLYPHMAP */ diff --git a/win/tty/termcap.c b/win/tty/termcap.c index 037f1bf0f..95dd0b27c 100644 --- a/win/tty/termcap.c +++ b/win/tty/termcap.c @@ -27,11 +27,13 @@ void term_end_extracolor(void); #if (!defined(UNIX) || !defined(TERMINFO)) && !defined(TOS) static void analyze_seq(char *, int *, int *); #endif +#if defined(UNIX) && defined(TERMINFO) +static int indexed_color_count(void); +#endif #endif #if (defined(TERMLIB) || defined(ANSI_DEFAULT)) static void init_hilite(void); static void kill_hilite(void); -static int indexed_color_count(void); #endif /* (see tcap.h) -- nh_CM, nh_ND, nh_CD, nh_HI,nh_HE, nh_US,nh_UE, ul_hack */ @@ -40,12 +42,16 @@ struct tc_lcl_data tc_lcl_data = { 0, 0, 0, 0, 0, 0, 0, FALSE }; static char *nh_VI = (char *) 0; /* cursor_invisible */ static char *nh_VE = (char *) 0; /* cursor_normal */ /*static char *nh_VS = (char *) 0;*/ /* cursor_visible (highlighted cursor) */ +#if defined(TERMLIB) || defined(CHANGE_COLOR) static char *nh_Ic = (char *) 0; /* initialize_color */ +#endif #if !defined(__NetBSD__) static char *UP, *BC; +#ifdef TERMLIB static char PC = '\0'; #endif +#endif static char *HO, *CL, *CE, *XD, *SO, *SE, *TI, *TE; static char *VS, *VE; @@ -1580,13 +1586,7 @@ tty_change_color(int color, long rgb, int reverse UNUSED) #ifndef SEP2 #define tcfmtstr "\033[38;2;%ld;%ld;%ldm" -#ifdef UNIX -#define tcfmtstr24bit "\033[38;2;%u;%u;%um" #define tcfmtstr256 "\033[38;5;%dm" -#else -#define tcfmtstr24bit "\033[38;2;%lu;%lu;%lum" -#define tcfmtstr256 "\033[38:5:%lum" -#endif #endif static void emit24bit(long mcolor); diff --git a/win/tty/wintty.c b/win/tty/wintty.c index c4aa816bd..9b545d8fd 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -182,7 +182,7 @@ static const char winpanicstr[] = "Bad window Id %d (%s)"; char defmorestr[] = "--More--"; #ifdef CLIPPING -#if defined(TILES_IN_GLYPHMAP) && defined(MSDOS) +#if (defined(TILES_IN_GLYPHMAP) || defined(ENHANCED_SYMBOLS)) && defined(MSDOS) boolean clipping = FALSE; /* clipping on? */ int clipx = 0, clipxmax = 0; int clipy = 0, clipymax = 0; @@ -193,7 +193,7 @@ static int clipy = 0, clipymax = 0; #endif #endif /* CLIPPING */ -#if defined(TILES_IN_GLYPHMAP) && defined(MSDOS) +#if defined(NO_TERMS) && defined(MSDOS) extern void adjust_cursor_flags(struct WinDesc *); #endif @@ -2072,7 +2072,7 @@ tty_curs( print_vt_code2(AVTC_SELECT_WINDOW, window); -#if defined(TILES_IN_GLYPHMAP) && defined(MSDOS) +#if defined(NO_TERMS) && defined(MSDOS) adjust_cursor_flags(cw); #endif From e00b32263e0c6b5f761490d7c92a974b48877658 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Fri, 10 Jul 2026 09:08:55 -0400 Subject: [PATCH 549/702] Support the Curses-only configuration --- include/pcconf.h | 2 +- sys/msdos/msdos.c | 2 ++ sys/msdos/video.c | 2 +- sys/share/pcsys.c | 2 ++ sys/share/pctty.c | 6 ++++++ sys/unix/hints/include/cross-pre2.500 | 10 +++++++++- 6 files changed, 21 insertions(+), 3 deletions(-) diff --git a/include/pcconf.h b/include/pcconf.h index 904c250c7..8b580b03a 100644 --- a/include/pcconf.h +++ b/include/pcconf.h @@ -73,7 +73,7 @@ * You may uncomment any/all of the options below. * */ -#ifndef SUPPRESS_GRAPHICS +#if defined(TTY_GRAPHICS) && !defined(SUPPRESS_GRAPHICS) #if (defined(SCREEN_BIOS) || defined(SCREEN_DJGPPFAST)) && !defined(PC9800) #if defined(TILES_IN_GLYPHMAP) || defined(ENHANCED_SYMBOLS) #define SCREEN_VGA /* Include VGA graphics routines in the build */ diff --git a/sys/msdos/msdos.c b/sys/msdos/msdos.c index a26c86c2c..e14210dfb 100644 --- a/sys/msdos/msdos.c +++ b/sys/msdos/msdos.c @@ -61,6 +61,7 @@ static unsigned int dos_ioctl(int, int, unsigned); extern boolean pckeys(unsigned char, unsigned char); /* pckeys.c */ #endif +#ifdef TTY_GRAPHICS int tgetch(void) { @@ -86,6 +87,7 @@ tgetch(void) #endif return ((ch == '\r') ? '\n' : ch); } +#endif /* TTY_GRAPHICS */ /* * Keyboard translation tables. diff --git a/sys/msdos/video.c b/sys/msdos/video.c index ec21aa695..bb94e83b6 100644 --- a/sys/msdos/video.c +++ b/sys/msdos/video.c @@ -89,7 +89,7 @@ get_scr_size(void) txt_get_scr_size(); } -#ifdef ENHANCED_SYMBOLS +#if defined(TTY_GRAPHICS) && defined(ENHANCED_SYMBOLS) void g_pututf8(uint8 *utf8str) { /* not implemented for msdos (yet) */ diff --git a/sys/share/pcsys.c b/sys/share/pcsys.c index 5ceaa4410..c26b1f4ea 100644 --- a/sys/share/pcsys.c +++ b/sys/share/pcsys.c @@ -271,7 +271,9 @@ msexit(void) restore_colors(); #endif wait_synch(); +#if !(defined(MSDOS) && !defined(TTY_GRAPHICS)) term_curs_set(1); +#endif return; } #endif /* MICRO || OS2 */ diff --git a/sys/share/pctty.c b/sys/share/pctty.c index 3d276fcc6..53f5bb45c 100644 --- a/sys/share/pctty.c +++ b/sys/share/pctty.c @@ -38,7 +38,9 @@ settty(const char *s) #if defined(MSDOS) && defined(NO_TERMS) gr_finish(); #endif +#if !(defined(MSDOS) && !defined(TTY_GRAPHICS)) term_end_screen(); +#endif if (s) raw_print(s); #if !defined(TOS) @@ -50,7 +52,9 @@ settty(const char *s) void setftty(void) { +#if !(defined(MSDOS) && !defined(TTY_GRAPHICS)) term_start_screen(); +#endif } #ifdef ENHANCED_SYMBOLS @@ -83,8 +87,10 @@ VA_DECL(const char *, s) VA_START(s); VA_INIT(s, const char *); /* error() may get called before tty is initialized */ +#if !(defined(MSDOS) && !defined(TTY_GRAPHICS)) if (iflags.window_inited) term_end_screen(); +#endif putchar('\n'); Vprintf(s, VA_ARGS); putchar('\n'); diff --git a/sys/unix/hints/include/cross-pre2.500 b/sys/unix/hints/include/cross-pre2.500 index 5fc642162..05803d7a9 100644 --- a/sys/unix/hints/include/cross-pre2.500 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -177,7 +177,15 @@ MSDOS_GPP_CFLAGS = -Wall -Wextra -Wno-missing-field-initializers -Wreturn-type \ -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings -pedantic \ -Wmissing-declarations -Wformat-nonliteral -Wunreachable-code \ -Wno-maybe-uninitialized -ifdef NO_GRAPHICS +ifndef WANT_WIN_TTY + # A Curses-only configuration + MSDOS_GRAPH_CONFIG = -DNOTTYGRAPHICS + SKIP_TILES = 1 + ifndef WANT_DOSVGA + SKIP_FONTS = 1 + endif + SKIP_FONT_C = 1 +else ifdef NO_GRAPHICS MSDOS_GRAPH_CONFIG = -DSUPPRESS_GRAPHICS # Curses will need the fonts, but not font.c ifndef WANT_DOSVGA From 1821a6b2e383826b30c2eec225ecbb013532e24d Mon Sep 17 00:00:00 2001 From: Francium-223 Date: Sat, 11 Jul 2026 15:40:30 -0400 Subject: [PATCH 550/702] a typo fix in data.base Close #1618 --- dat/data.base | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dat/data.base b/dat/data.base index ec1e5306e..f5008be1f 100644 --- a/dat/data.base +++ b/dat/data.base @@ -182,7 +182,7 @@ angel* shall come forth, and sever the wicked from among the just, and shall cast them into the furnace of fire; there shall be wailing and gnashing of teeth. - [ The Gospel According to Matthew, 13:37-42, 49-50 ] + [ The Gospel According to Matthew, 13:37-40, 49-50 ] angry god* Cold wind blows. The gods look down in anger on this poor child. From 85e080bb5d98841e02ce3817f235e5b62f2d2473 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 20 Jul 2026 16:11:01 -0400 Subject: [PATCH 551/702] windows calls genl_prag() during startup genl_prag() will process the prag@ command line options, if present Close #1634 --- include/extern.h | 1 + src/earlyarg.c | 83 ++++++++++++++++++++++++++++++++++++++++++ sys/windows/windmain.c | 3 ++ 3 files changed, 87 insertions(+) diff --git a/include/extern.h b/include/extern.h index 5edd7ac7b..14422d2e4 100644 --- a/include/extern.h +++ b/include/extern.h @@ -949,6 +949,7 @@ extern void early_options(int *argc_p, char ***argv_p, char **hackdir_p); #ifdef WIN32 int windows_early_options(const char *); #endif +extern void genl_prag(int, char **); /* profession, race, align, gender */ /* ### eat.c ### */ diff --git a/src/earlyarg.c b/src/earlyarg.c index 2209e9323..c64b6bfcd 100755 --- a/src/earlyarg.c +++ b/src/earlyarg.c @@ -359,6 +359,89 @@ early_options(int *argc_p, char ***argv_p, char **hackdir_p) config_error_done(); return; } + +/* profession (role), race, alignment, gender command line options */ +void +genl_prag(int argc, char *argv[]) +{ + char *arg; + int i; + + config_error_init(FALSE, "command line", FALSE); + + while (argc > 1 && argv[1][0] == '-') { + argv++; + argc--; + arg = argv[0]; + /* allow second dash if arg is longer than one character */ + if (arg[0] == '-' && arg[1] == '-' + && arg[2] != '\0' + /* "--a=b" violates the "--" ok when at least 2 chars long rule */ + && (arg[3] != '\0' && arg[3] != '=' && arg[3] != ':')) + ++arg; + if (strchr("prag@", arg[1])) { + switch (arg[1]) { + case 'a': + if (arg[2]) { + if ((i = str2align(&arg[2])) >= 0) + flags.initalign = i; + } else if (argc > 1) { + argc--; + argv++; + if ((i = str2align(argv[0])) >= 0) + flags.initalign = i; + } + break; + case 'g': + if (arg[2]) { + if ((i = str2gend(&arg[2])) >= 0) + flags.initgend = i; + } else if (argc > 1) { + argc--; + argv++; + if ((i = str2gend(argv[0])) >= 0) + flags.initgend = i; + } + break; + case 'p': /* profession (role) */ + if (arg[2]) { + if ((i = str2role(&arg[2])) >= 0) + flags.initrole = i; + } else if (argc > 1) { + argc--; + argv++; + if ((i = str2role(argv[0])) >= 0) + flags.initrole = i; + } + break; + case 'r': /* race */ + if (arg[2]) { + if ((i = str2race(&arg[2])) >= 0) + flags.initrace = i; + } else if (argc > 1) { + argc--; + argv++; + if ((i = str2race(argv[0])) >= 0) + flags.initrace = i; + } + break; + case '@': + flags.randomall = 1; + break; + } + } else { + /* default for "-x" is to play as the role that starts with "x" */ + if ((i = str2role(&argv[1][0])) >= 0) { + flags.initrole = i; + } + } + } + + /* empty or "N errors on command line" */ + config_error_done(); + return; +} + /* for command-line options that perform some immediate action and then terminate the program without starting play, like 'nethack --version' or 'nethack -s Zelda'; do some cleanup before that termination */ diff --git a/sys/windows/windmain.c b/sys/windows/windmain.c index 0fb6eadb0..bc8d3b661 100644 --- a/sys/windows/windmain.c +++ b/sys/windows/windmain.c @@ -289,6 +289,9 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ nethack_exit(EXIT_FAILURE); } + genl_prag(argc, argv); /* command line options for profession, race, + * alignment, gender */ + /* Finished processing options, lock all directory paths */ for (int i = 0; i < PREFIX_COUNT; i++) fqn_prefix_locked[i] = TRUE; From eb13f4de6d6b62d06563558bcee065f440714286 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 21 Jul 2026 12:07:45 -0400 Subject: [PATCH 552/702] LUA version checking in nhl_init() Use LUA_VERSION_NUM, not LUA_VERSION_RELEASE_NUM, for the check. Move the definitions of the versions supported by this release of NetHack to the top of nhlua.c, rather than 2300 lines into the file. Close #1633 --- src/nhlua.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/nhlua.c b/src/nhlua.c index 7cd1b9cd3..8ed3fd448 100644 --- a/src/nhlua.c +++ b/src/nhlua.c @@ -5,6 +5,14 @@ #include "hack.h" #include "dlb.h" +/* minimum and maximum LUA_VERSION_NUM expected by this version of NetHack */ \ +#ifndef NHL_MIN_VERSION_NUM_EXPECTED +#define NHL_MIN_VERSION_NUM_EXPECTED 504 +#endif +#ifndef NHL_MAX_VERSION_NUM_EXPECTED +#define NHL_MAX_VERSION_NUM_EXPECTED 505 +#endif + #ifndef LUA_VERSION_RELEASE_NUM #ifdef NHL_SANDBOX #undef NHL_SANDBOX @@ -2298,22 +2306,20 @@ DISABLE_WARNING_CONDEXPR_IS_CONSTANT lua_State * nhl_init(nhl_sandbox_info *sbi) { - /* It would be nice to import EXPECTED from each build system. XXX */ - /* And it would be nice to do it only once, but it's cheap. */ -#ifndef NHL_VERSION_EXPECTED -#if LUA_VERSION_NUM >= 505 -#define NHL_VERSION_EXPECTED 50500 -#else -#define NHL_VERSION_EXPECTED 50408 -#endif -#endif - #ifdef NHL_SANDBOX - if (NHL_VERSION_EXPECTED != LUA_VERSION_RELEASE_NUM) { - panic( - "sandbox doesn't know this Lua version: this=%d != expected=%d ", - LUA_VERSION_RELEASE_NUM, NHL_VERSION_EXPECTED); - } +#define SANDBOX_DOESNT_KNOW "sandbox doesn't know this Lua version: " +if (LUA_VERSION_NUM < NHL_MIN_VERSION_NUM_EXPECTED + || LUA_VERSION_NUM > NHL_MAX_VERSION_NUM_EXPECTED) { + if (NHL_MIN_VERSION_NUM_EXPECTED == NHL_MAX_VERSION_NUM_EXPECTED) + panic("%sthis=%d != expected=%d", SANDBOX_DOESNT_KNOW, + LUA_VERSION_NUM, NHL_MIN_VERSION_NUM_EXPECTED); + else + panic("%sthis=%d, but expected %d to %d", SANDBOX_DOESNT_KNOW, + LUA_VERSION_NUM, + NHL_MIN_VERSION_NUM_EXPECTED, + NHL_MAX_VERSION_NUM_EXPECTED); +} +#undef SANDBOX_DOESNT_KNOW #endif lua_State *L = nhlL_newstate(sbi, "nhl_init"); From c2a3321684270979d98ce80ed1fe59e7e56f1040 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 21 Jul 2026 12:13:17 -0400 Subject: [PATCH 553/702] follow-up bit --- src/nhlua.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nhlua.c b/src/nhlua.c index 8ed3fd448..46c4e9c5d 100644 --- a/src/nhlua.c +++ b/src/nhlua.c @@ -5,7 +5,7 @@ #include "hack.h" #include "dlb.h" -/* minimum and maximum LUA_VERSION_NUM expected by this version of NetHack */ \ +/* minimum and maximum LUA_VERSION_NUM expected by this version of NetHack */ #ifndef NHL_MIN_VERSION_NUM_EXPECTED #define NHL_MIN_VERSION_NUM_EXPECTED 504 #endif From 3b050126245408b7d9e30f638b5920388f5d4408 Mon Sep 17 00:00:00 2001 From: Ingo Paschke Date: Mon, 6 Jul 2026 08:09:12 +0200 Subject: [PATCH 554/702] sfstruct: buffered stdio writes on amiga and atari st Enable USE_BUFFERING for the structlevel savefile write path on AMIGA and TOS via a new SFSTRUCT_BUFFERING config define, with a 16 KB setvbuf on the fdopen'd write stream so many small bwrite()s coalesce into few dos.library Write() packets. Leaves mread() unbuffered. Mainline UNIX/WIN32 are unchanged (setvbuf is gated on the new define); MAC68K is not enabled, avoiding fdopen()/fclose() on its remapped non-libc file handles. --- include/amiconf.h | 1 + outdated/include/tosconf.h | 1 + src/sfstruct.c | 9 ++++++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/amiconf.h b/include/amiconf.h index 593f3e470..51342e44f 100644 --- a/include/amiconf.h +++ b/include/amiconf.h @@ -73,6 +73,7 @@ extern void ami_wininit_data(int); #define HACKFONT /* Use special hack.font */ #define MAIL /* Get mail at unexpected occasions */ #define AMIFLUSH /* toss typeahead (select flush in .cnf) */ +#define SFSTRUCT_BUFFERING /* buffered stdio writes for structlevel files */ /* new window system options */ /* WRONG - AMIGA_INTUITION should go away */ diff --git a/outdated/include/tosconf.h b/outdated/include/tosconf.h index 1ea893f4d..90ffb4fcb 100644 --- a/outdated/include/tosconf.h +++ b/outdated/include/tosconf.h @@ -42,6 +42,7 @@ #ifdef MINT #define SUSPEND /* allow suspending the game */ #endif +#define SFSTRUCT_BUFFERING /* buffered stdio writes for structlevel files */ #ifndef TERMLIB #define ANSI_DEFAULT /* use vt52 by default */ diff --git a/src/sfstruct.c b/src/sfstruct.c index 00888d8d8..4eb9a8ed2 100644 --- a/src/sfstruct.c +++ b/src/sfstruct.c @@ -320,7 +320,7 @@ static long floc = 0L; staticfn int getidx(int, int); -#if defined(UNIX) || defined(WIN32) +#if defined(UNIX) || defined(WIN32) || defined(SFSTRUCT_BUFFERING) #define USE_BUFFERING #endif @@ -329,6 +329,9 @@ struct restore_info restoreinfo = { }; #define MAXFD 5 +#ifdef SFSTRUCT_BUFFERING +#define BWBUFSZ 16384 +#endif enum {NOFLG = 0, NOSLOT = 1}; static int bw_sticky[MAXFD] = {-1,-1,-1,-1,-1}; static int bw_buffered[MAXFD] = {0,0,0,0,0}; @@ -431,6 +434,10 @@ bufon(int fd) if (!bw_FILE[idx]) { if ((bw_FILE[idx] = fdopen(fd, "w")) == 0) panic("buffering of file %d failed", fd); +#ifdef SFSTRUCT_BUFFERING + (void) setvbuf(bw_FILE[idx], (char *) 0, _IOFBF, + (size_t) BWBUFSZ); +#endif } bw_buffered[idx] = (bw_FILE[idx] != 0); #else From 1a4cdff17f55d204429bdff6468b2709d1aa7fdb Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 23 Jul 2026 09:34:33 -0400 Subject: [PATCH 555/702] update tested versions of Visual Studio 2026-07-23 --- sys/windows/Makefile.nmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index 5a0906c8b..91a769d98 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -8,8 +8,8 @@ # MS Visual Studio Visual C++ compiler # # Visual Studio Compilers Tested: -# - Microsoft Visual Studio Community 2022 v 17.14.35 -# - Microsoft Visual Studio Community 2026 v 18.7.1 +# - Microsoft Visual Studio Community 2022 v 17.14.37 +# - Microsoft Visual Studio Community 2026 v 18.8.1 # #============================================================================== # This is used for building two distinct executables of NetHack: @@ -1204,7 +1204,7 @@ rc=Rc.exe # # Recently tested versions: TESTEDVS2022 = 14.44.35225.0 -TESTEDVS2026 = 14.51.36248.0 +TESTEDVS2026 = 14.51.36252.0 VS20261ST = 1450000000 VS2026CUR = $(TESTEDVS2026:.=) From d6da7e9819392d59ed4aa51b91cada511ace39a7 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 23 Jul 2026 09:46:03 -0400 Subject: [PATCH 556/702] fixes entry for pull request #1632 --- doc/fixes5-0-1.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 6a177f21b..f7ea7e784 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -203,6 +203,9 @@ MS-DOS: some optimizations for tile handling; change 16-color mode and displayed, with the result cached; Use memcpy when splitting the image into tiles; only load the tileset once (pr #1617 by chasonr) MS-DOS: Define a separate palette for VGA text (pr #1620 by chasonr) +MS-DOS: some conditional cleanup for SUPPRESS_GRAPHICS, TILES_IN_GLYPHMAP, + NO_TILES, WANT_WIN_CURSES=1 without WANT_WIN_TTY=1 + (pr #1632 by chasonr) musl: musl libc does not have __sighandler_t so don't use it in the macro definition for SIG_RET_TYPE with musl WASM: resolve some build failures in 'make CROSS_TO_WASM=1' From 86cb47dd6bee27d86d904fcd427957a04dad2408 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 23 Jul 2026 10:01:55 -0400 Subject: [PATCH 557/702] address a warning in cmd.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cmd.c: In function ‘dokeylist’: cmd.c:2961:23: warning: ‘]’ directive writing 1 byte into a region of size between 0 and 255 [-Wformat-overflow=] 2961 | Sprintf(buf2, "[%s]", key2txt(key, buf)); | ^ --- src/cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd.c b/src/cmd.c index 978e500b0..6f67db776 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -2957,7 +2957,7 @@ dokeylist(void) Sprintf(buf, "%-7s", key2txt(key, buf2)); #else /* first of the keyless commands */ - Sprintf(buf2, "[%s]", key2txt(key, buf)); + Snprintf(buf2, sizeof buf2, "[%s]", key2txt(key, buf)); Sprintf(buf, "%-21s", buf2); #endif Strcat(buf, " interrupt: break out of NetHack (SIGINT)"); From 812a9f1435367a8951cbbe694a3cf7cd4881255f Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 24 Jul 2026 08:35:55 -0400 Subject: [PATCH 558/702] Cross-compiling doc bit --- Cross-compiling | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cross-compiling b/Cross-compiling index 148eb8451..cc54fdc79 100644 --- a/Cross-compiling +++ b/Cross-compiling @@ -18,7 +18,7 @@ Part B Contents: B2. What needs to be built and executed on the HOST? B3. What needs to be built for the TARGET? B4. Case sample: msdos - B5. Case sample: amiga (started but incomplete) + B5. Case sample: amiga B6. Case sample: Web Assembly, libnh B7. Case sample: mips From a3a587dcf3650590ee410dba348477b569991ee4 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 25 Jul 2026 13:33:39 -0700 Subject: [PATCH 559/702] fix #K4498 - stethoscope vs double trouble Wizard When the Wizard is diguised as some other monster, applying a stethscope described him as "that is really a ". --- doc/fixes5-0-1.txt | 3 +++ src/apply.c | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index f7ea7e784..75b411f79 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -74,6 +74,9 @@ Some optimizations of the glyph lookup - don't produce names for swallow glyph index in populate_glyphname_hash_indices; build a sorted index for loadsyms so that it can be searched with bsearch (pr #1612 by chasonr) +stethoscope applied to one monster disguised as another (double-trouble Wizard) + mis-described undisguised form (unintended side-effect of 5.0 commit + 064523e162f8e30bdb76186a854b9d8958f3b340) Platform- and/or Interface-Specific Fixes diff --git a/src/apply.c b/src/apply.c index 45cae0660..02bac8669 100644 --- a/src/apply.c +++ b/src/apply.c @@ -390,7 +390,10 @@ use_stethoscope(struct obj *obj) } if ((mtmp = m_at(rx, ry)) != 0) { const char *mnm = x_monnam(mtmp, ARTICLE_A, (const char *) 0, - SUPPRESS_IT | SUPPRESS_INVISIBLE, FALSE); + (SUPPRESS_IT | SUPPRESS_INVISIBLE + /* stethoscope reveals true form; seemimic + below will clear mtmp->mappearance */ + | SUPPRESS_MAPPEARANCE), FALSE); /* gb.bhitpos needed by mstatusline() iff mtmp is a long worm */ gb.bhitpos.x = rx, gb.bhitpos.y = ry; From 1d3178a1994e5e6f8749f64659a075d60a2696da Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 27 Jul 2026 16:27:20 -0400 Subject: [PATCH 560/702] build with Qt6 support on Linux with Qt 6.1 --- sys/unix/hints/include/compiler.500 | 3 ++ sys/unix/hints/linux.500 | 64 +++++++---------------------- 2 files changed, 18 insertions(+), 49 deletions(-) diff --git a/sys/unix/hints/include/compiler.500 b/sys/unix/hints/include/compiler.500 index aa140c413..59c6e29ef 100755 --- a/sys/unix/hints/include/compiler.500 +++ b/sys/unix/hints/include/compiler.500 @@ -138,6 +138,9 @@ CCXXFLAGS+=-Wall -Wextra -Wno-missing-field-initializers \ -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings CCXXFLAGS+=-pedantic CCXXFLAGS+=-Wmissing-declarations +ifdef ADDITIONAL_NO_WARN +CCXXFLAGS+=$(ADDITIONAL_NO_WARN) +endif #detection of clang++ vs g++ CXXISCLANG := $(shell echo `$(CXX) --version` | grep clang) ifeq "$(CXXISCLANG)" "" diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index 2823d2fad..fc9192516 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -74,6 +74,12 @@ USE_NOSTATICFN = 1 #-INCLUDE multiw-2.500 +#QT6 prior to compiler include +ifdef WANT_WIN_QT6 +CPLUSPLUS_NEED20=1 +ADDITIONAL_NO_WARN=-Wno-sfinae-incomplete +endif # WANT_WIN_QT6 + # compiler.500 contains compiler detection and adjustments common # to both linux and macOS @@ -415,67 +421,27 @@ LINK = $(CXX) ifndef CROSSCOMPILE GENTILEOFILE = $(SRCDIR)/tile.o endif +# QT4 ifdef WANT_WIN_QT4 QTCXXFLAGS += $(sort $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config QtGui --cflags)) -DQT_NO_SOUND=1 WINLIB += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config QtGui --libs) endif # WANT_WIN_QT4 +#QT5 ifdef WANT_WIN_QT5 QTCXXFLAGS += $(sort $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --cflags)) WINLIB += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --libs) endif # WANT_WIN_QT5 +#QT6 ifdef WANT_WIN_QT6 -ifdef QT6MANUAL -# Try some likely spots for a self-built Qt6. -# You'll have to change these manually before using the hints file -# if they don't match the installed location on your system. -ifneq "$(HOSTTYPE)" "" -QTHOST=$(HOSTTYPE) -else -QTHOST=x86_64 -endif -QTTOP=/usr/include/$(HOSTTYPE)-linux-gnu/qt6 -ifneq ($(wildcard $(QTTOP)/*),) -#we don't set QTLOCATED=1 for this -QTINCDIR=/usr/include/$(QTHOST)-linux-gnu/qt6 -QTLIBDIR=/usr/lib/$(QTHOST)-linux.gnu -QTCXXFLAGS += -DQT_WIDGETS_LIB -DQT_MULTIMEDIA_LIB -DQT_NETWORK_LIB -DQT_GUI_LIB -DQT_CORE_LIB -QTCXXFLAGS += -I$(QTINCDIR)/QtWidgets -I$(QTINCDIR) -I$(QTINCDIR)/QtMultimedia -QTCXXFLAGS += -I$(QTINCDIR)/QtNetwork -I$(QTINCDIR)/QtGui -I$(QTINCDIR)/QtCore -WINLIB += -L$(QTLIBDIR) -lQt6Widgets -lQt6Multimedia -lQt6Network -lQt6Gui -lQt6Core -MOCPATH = /usr/lib/qt6/libexec/moc -#/usr/lib/x86_64-linux-gnu/libQt6EglFSDeviceIntegration.so -endif # QTTOP/* -ifndef QTINCDIR -ifneq ($(wildcard /usr/local/Qt6/*),) -QTDIR=/usr/local/Qt6 -QTLOCATED=1 -endif # wildcard /usr/local/Qt6 -ifneq ($(wildcard /usr/local/qt6/*),) -QTDIR=/usr/local/qt6 -QTLOCATED=1 -endif # wildcard /usr/local/qt6 -endif # !QTINCDIR -ifdef QTLOCATED -QTCXXFLAGS += -I$(QTDIR)/include/QtCore -QTCXXFLAGS += -I$(QTDIR)/include/QtGui -QTCXXFLAGS += -I$(QTDIR)/include/QtMultimedia -QTCXXFLAGS += -I$(QTDIR)/include/QtWidgets -MOCPATH = $(QTDIR)/libexec/moc -WINLIB += -L$(QTDIR)/lib -lQt6Widgets -lQt6Multimedia -lQt6Network -lQt6Gui -lQt6Core -endif # QTLOCATED -else # !QT6MANUAL -MOCDIR = $(shell pkg-config Qt6Gui --variable=libexecdir) -ifneq ($(wildcard $(MOCDIR)/*),) -MOCPATH = $(MOCDIR)/moc -else -MOCPATH = /usr/lib/qt6/libexec/moc -endif # MOCDIR -QTCXXFLAGS += $(sort $(shell pkg-config Qt6Gui Qt6Widgets Qt6Multimedia --cflags)) -WINLIB += $(shell pkg-config Qt6Gui Qt6Widgets Qt6Multimedia --libs) -endif # QT6MANUAL +QTCXXFLAGS += $(shell pkg-config --cflags Qt6Multimedia) +WINLIB += $(shell pkg-config --libs Qt6Core Qt6Gui Qt6Widgets Qt6Multimedia) +MOCPATH = $(shell pkg-config --variable=libexecdir Qt6Core)/moc endif # WANT_WIN_QT6 + ifndef QTDIR +ifndef WANT_WIN_QT6 $(error QTDIR not defined in the environment or Makefile) +endif # not WANT_WIN_QT6 endif # QTDIR # XXX if /Developer/qt exists and QTDIR not set, use that # XXX make sure QTDIR points to something reasonable From de842ec483fc5b05cc35661c3942c47847cf6469 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 29 Jul 2026 20:47:50 -0400 Subject: [PATCH 561/702] add a set of decals to stock tileset win/share/decals.txt contains (initially) a decal_delimiter tile, a decal_pet tile, and a decal_pile tile. The latter two can be used for hilite_pet and hilite_pile implementations that don't have something in place already. The implementation would just need to apply (merge) the non-background decal pixels over a regular tile. The special decal_delimiter tile can be used to confirm the presence of the delimiter tiles in the tileset and mark the end of the regular tiles, and the start of the decal tiles. row 1 contains the background color whose pixels should be ignored when applying a decal to a tile. row 2 contains a row of pixels colored (0, 0, 0). row 3 contains a row of pixels colored pure green (0, 255, 0). row 3 contains a row of pixels colored pure blue (0, 0, 255). --- sys/unix/Makefile.dat | 6 ++- win/share/decals.txt | 95 +++++++++++++++++++++++++++++++++++++++++++ win/share/tile2bmp.c | 14 +++---- win/share/tilemap.c | 73 +++++++++++++++++++++++++++------ win/share/tiletext.c | 10 ++--- 5 files changed, 171 insertions(+), 27 deletions(-) create mode 100644 win/share/decals.txt diff --git a/sys/unix/Makefile.dat b/sys/unix/Makefile.dat index 85d40ef53..a339fa307 100644 --- a/sys/unix/Makefile.dat +++ b/sys/unix/Makefile.dat @@ -27,10 +27,12 @@ all: $(VARDAT) spec_levs quest_levs x11tiles: ../util/tile2x11 ../win/share/monsters.txt ../win/share/objects.txt \ ../win/share/other.txt \ - ../win/share/monsters.txt + ../win/share/monsters.txt \ + ../win/share/decals.txt ../util/tile2x11 ../win/share/monsters.txt ../win/share/objects.txt \ ../win/share/other.txt \ - -grayscale ../win/share/monsters.txt + -grayscale ../win/share/monsters.txt \ + ../win/share/decals.txt beostiles: ../util/tile2beos ../win/share/monsters.txt \ ../win/share/objects.txt \ diff --git a/win/share/decals.txt b/win/share/decals.txt new file mode 100644 index 000000000..bc1094912 --- /dev/null +++ b/win/share/decals.txt @@ -0,0 +1,95 @@ +# decals.txt - definitions for 'decals' +# to merge over top of another tile +# +# Note: lines beginning with '# tile ' are not comments; other +# lines beginning with '#' are. +. = (71, 108, 108) +A = (0, 0, 0) +B = (0, 182, 255) +C = (255, 108, 0) +D = (255, 0, 0) +E = (0, 0, 255) +F = (0, 145, 0) +G = (108, 255, 0) +H = (255, 255, 0) +I = (255, 0, 255) +J = (145, 71, 0) +K = (204, 79, 0) +L = (255, 182, 145) +M = (237, 237, 237) +N = (255, 255, 255) +O = (215, 215, 215) +P = (108, 145, 182) +Q = (18, 18, 18) +R = (54, 54, 54) +S = (73, 73, 73) +T = (82, 82, 82) +U = (205,205,205) +V = (104, 104, 104) +W = (131, 131, 131) +X = (140, 140, 140) +Y = (149, 149, 149) +Z = (195, 195, 195) +0 = (100, 100, 100) +1 = (72, 108, 108) +2 = (0, 255, 0) +# tile 0 (decal_delimiter) +{ + ................ + AAAAAAAAAAAAAAAA + 2222222222222222 + EEEEEEEEEEEEEEEE + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ +} +# decals that can be overlayed +# onto an object tile +# +# tile 1 (decal_pet) +{ + ............D.D. + ...........DDDDD + ............DDD. + .............D.. + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ +} +# tile 2 (decal_pile) +{ + ..N............. + ..N............. + NNNNN........... + ..N............. + ..N.N........... + .....N.......... + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ +} diff --git a/win/share/tile2bmp.c b/win/share/tile2bmp.c index f25950c84..d58c4402d 100644 --- a/win/share/tile2bmp.c +++ b/win/share/tile2bmp.c @@ -114,12 +114,9 @@ static void build_bmptile(pixel(*) [TILE_X]); #define TILESETS 1 static const char *const relative_tiledir = "../win/share/"; /* monsters must be first because main uses it twice */ -const char *const tilefilenames[TILESETS][3] = { - {"monsters.txt", "objects.txt", "other.txt"}, -#if 0 - {"mon32.txt", "obj32.txt", "oth32.txt"}, - {"mon64.txt", "obj64.txt", "oth64.txt"}, -#endif +const char *const tilefilenames[TILESETS][5] = { + { "monsters.txt", "objects.txt", "other.txt", + "monsters.txt", "decals.txt" }, }; int tilecnt[SIZE(tilefilenames[0])]; @@ -191,8 +188,8 @@ main(int argc, char *argv[]) printf("Error creating tile file %s, aborting.\n", bmpname); exit(EXIT_FAILURE); } - while (pass < 4) { - filenum = pass % SIZE(tilefilenames[tilefileset]); + filenum = 0; + while (pass < SIZE(tilefilenames[tilefileset])) { if (!set_tilefile_path(relative_tiledir, tilefilenames[tilefileset][filenum], tilefile_full_path, sizeof tilefile_full_path)) { @@ -248,6 +245,7 @@ main(int argc, char *argv[]) } (void) fclose_text_file(); ++pass; + ++filenum; } fwrite(newbmp, bmpsize, 1, fp); fclose(fp); diff --git a/win/share/tilemap.c b/win/share/tilemap.c index 11b067471..0fbfcb045 100644 --- a/win/share/tilemap.c +++ b/win/share/tilemap.c @@ -101,9 +101,9 @@ const char *zap_texts[] = { "death", "lightning", "poison gas", "acid", }; -enum tilesrc { monsters_file, objects_file, other_file, generated }; +enum tilesrc { monsters_file, objects_file, other_file, generated, decals_file }; const char *tilesrc_texts[] = { - "monsters.txt", "objects.txt", "other.txt", "generated", + "monsters.txt", "objects.txt", "other.txt", "generated", "decals.txt" }; struct tilemap_t { @@ -129,7 +129,11 @@ struct tiles_used *tilelist[2500] = { 0 }; int TILE_stone = 0, /* will get set to correct tile later */ TILE_unexplored = 0, /* will get set to correct tile later */ TILE_nothing = 0, /* will get set to correct tile later */ - TILE_corr = 0; /* will get set to correct tile later; X11 uses it */ + TILE_corr = 0, /* will get set to correct tile later; X11 uses it */ + TILE_delimiter = 0, /* reference tile to indicate the two below exist */ + TILE_petmark = 0, /* tile to overlay on another tile to mark pet */ + TILE_pilemark = 0, /* tile to overlay on another tile to mark piletop */ + TILE_very_last_tile = 0; /* prototypes for functions in this file */ const char *tilename(int, const int, int); @@ -195,6 +199,7 @@ tilename(int set, const int file_entry, int gend UNUSED) { int i, k, cmap, condnum, tilenum; static char buf[BUFSZ]; + boolean decal_flag = FALSE; #if 0 int offset, gendnum; #endif @@ -203,6 +208,10 @@ tilename(int set, const int file_entry, int gend UNUSED) tilenum = 0; buf[0] = '\0'; + if (set == 3) + set = MON_GLYPH; + else if (set == 4) + decal_flag = TRUE; if (set == MON_GLYPH) { for (i = 0; i < NUMMONS; i++) { if (tilenum == file_entry) { @@ -530,9 +539,28 @@ tilename(int set, const int file_entry, int gend UNUSED) } } } /* OTH_GLYPH */ + if (decal_flag) { + tilenum = 0; /* set-relative number */ + for (i = 0; i < 3; i++) { + if (tilenum == file_entry) + switch(i) { + case 0: + return "decal_delimiter"; + break; + case 1: + return "decal_pet"; + break; + case 2: + return "decal_pile"; + break; + } + tilenum++; + } + } /* DECALS */ Sprintf(buf, "unknown %d %d", set, file_entry); - return buf; + return buf; } + #endif /* TILETEXT || OBTAIN_TILEMAP */ #ifndef TILETEXT @@ -1282,16 +1310,31 @@ init_tilemap(void) tilenum++; file_entry++; } + laststatuetile = tilenum - 1; +#endif /* STATUES_DONT_LOOK_LIKE_MONSTERS */ /* go beyond NUMMONS to cover off the invisible tile at the end of monsters.txt so that the tile mapping matches things in the .bmp file (for example) */ - file_entry = 0; #if defined(OBTAIN_TILEMAP) - add_tileref(tilenum, NO_GLYPH, monsters_file, file_entry, + file_entry = 0; + add_tileref(tilenum, NO_GLYPH, generated, file_entry, "invisible statue", ""); #endif - laststatuetile = tilenum - 1; -#endif /* STATUES_DONT_LOOK_LIKE_MONSTERS */ + tilenum++; + + file_entry = 0; + TILE_delimiter = tilenum++; /* Used to init nul_glyphinfo tileidx entry */ + TILE_petmark = tilenum++; + TILE_pilemark = tilenum++; +#if defined(OBTAIN_TILEMAP) + add_tileref(TILE_delimiter, NO_GLYPH, decals_file, file_entry++, + "decal_delimiter",""); + add_tileref(TILE_petmark, NO_GLYPH, decals_file, file_entry++, + "decal_petmark",""); + add_tileref(TILE_pilemark, NO_GLYPH, decals_file, file_entry++, + "decal_pilemark",""); +#endif + TILE_very_last_tile = tilenum; #if defined(OBTAIN_TILEMAP) for (i = 0; i < MAX_GLYPH; ++i) { @@ -1347,12 +1390,18 @@ main(int argc, char *argv[]) Fprintf(ofp, "\nenum special_tiles {\n"); Fprintf(ofp, " TILE_CORR = %d,\n", TILE_corr); Fprintf(ofp, " TILE_STONE = %d,\n", TILE_stone); - Fprintf(ofp, " TILE_UNEXPLORED = %d\n", TILE_unexplored); + Fprintf(ofp, " TILE_UNEXPLORED = %d,\n", TILE_unexplored); + Fprintf(ofp, " TILE_DELIMITER = %d,\n", TILE_delimiter); + Fprintf(ofp, " TILE_PETMARK = %d,\n", TILE_petmark); + Fprintf(ofp, " TILE_PILEMARK = %d\n", TILE_pilemark); Fprintf(ofp, "};\n"); - Fprintf(ofp, "\nint total_tiles_used = %d,\n", laststatuetile + 1); + Fprintf(ofp, "\nint total_tiles_used = %d,\n", TILE_very_last_tile); Fprintf(ofp, "%sTile_corr = TILE_CORR,\n", indent); /* X11 uses it */ - Fprintf(ofp, "%sTile_stone = TILE_STONE,\n", indent); - Fprintf(ofp, "%sTile_unexplored = TILE_UNEXPLORED,\n", indent); + Fprintf(ofp, "%sTile_stone = TILE_STONE,\n", indent); + Fprintf(ofp, "%sTile_unexplored = TILE_UNEXPLORED,\n", indent); + Fprintf(ofp, "%sTile_delimiter = TILE_DELIMITER,\n", indent); + Fprintf(ofp, "%sTile_petmark = TILE_PETMARK,\n", indent); + Fprintf(ofp, "%sTile_pilemark = TILE_PILEMARK,\n", indent); Fprintf(ofp, "%smaxmontile = %d,\n", indent, lastmontile); Fprintf(ofp, "%smaxobjtile = %d,\n", indent, lastobjtile); Fprintf(ofp, "%smaxothtile = %d;\n\n", indent, lastothtile); diff --git a/win/share/tiletext.c b/win/share/tiletext.c index 09cab5935..47e3bbebe 100644 --- a/win/share/tiletext.c +++ b/win/share/tiletext.c @@ -20,9 +20,9 @@ static FILE *tile_file; static int tile_set, tile_set_indx; static const char *const text_sets[] = { #if (TILE_X == 8) - "monthin.txt", "objthin.txt", "oththin.txt" + "monthin.txt", "objthin.txt", "oththin.txt", "monthin.txt", "decthin.txt" #else - "monsters.txt", "objects.txt", "other.txt" + "monsters.txt", "objects.txt", "other.txt", "monsters.txt", "decals.txt" #endif }; @@ -36,7 +36,7 @@ static boolean write_text_colormap(FILE *); static boolean read_txttile(FILE *, pixel (*)[TILE_X]); static void write_txttile(FILE *, pixel (*)[TILE_X]); -enum { MONSTER_SET, OBJECT_SET, OTHER_SET}; +enum { MONSTER_SET, OBJECT_SET, OTHER_SET, STATUE_SET, DECAL_SET }; /* Ugh. DICE doesn't like %[A-Z], so we have to spell it out... */ #define FORMAT_STRING \ @@ -189,7 +189,7 @@ read_txttile(FILE *txtfile, pixel (*pixels)[TILE_X]) gend[0] = '\0'; reslt = 0; if (get_next_line(txtfile, FALSE)) { - if (tile_set == MONSTER_SET) + if (tile_set == MONSTER_SET || tile_set == STATUE_SET) reslt = sscanf(inbuf, "# %255s %d (%255[^,],%255[^)])", ttype, &i, buf, gend); else @@ -202,7 +202,7 @@ read_txttile(FILE *txtfile, pixel (*pixels)[TILE_X]) ttype[sizeof ttype - 1] = '\0'; buf[sizeof buf - 1] = '\0'; - if (tile_set == MONSTER_SET && gend[0] == 'f') + if ((tile_set == MONSTER_SET || tile_set == STATUE_SET) && gend[0] == 'f') gidx = 1; ph = strcmp(ttype, "placeholder") == 0; From ff87463e47761146113d401f1439b6e5b8230e28 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 29 Jul 2026 20:48:44 -0400 Subject: [PATCH 562/702] initial hilite_pet and hilite_pile msdos tiles This is an initial attempt at adding support for hilite_pet and hilite_pile to the msdos tile implementation, using the new decal.txt tiles. This initial attempt only supports a 16-bit vesa mode. Other vesa modes and vga have not been done as of yet. Hopefully, someone more familiar with vesa might contribute improvements and support of the other modes at some point. --- sys/msdos/vidvesa.c | 97 ++++++++++++++++++++++++++++++++++++++++++--- sys/msdos/vidvga.c | 6 ++- 2 files changed, 97 insertions(+), 6 deletions(-) diff --git a/sys/msdos/vidvesa.c b/sys/msdos/vidvesa.c index c07fc6877..be2a94902 100644 --- a/sys/msdos/vidvesa.c +++ b/sys/msdos/vidvesa.c @@ -29,7 +29,12 @@ struct Pixel { #define FIRST_TEXT_COLOR 240 #ifdef TILES_IN_GLYPHMAP -extern int total_tiles_used, Tile_corr, Tile_unexplored; /* from tile.c */ +extern int total_tiles_used, + Tile_corr, + Tile_unexplored, + Tile_delimiter, + Tile_petmark, + Tile_pilemark; /* from tile.c */ #endif struct VesaCharacter { uint32 colour, bgcolour; @@ -60,7 +65,8 @@ static boolean vesa_SetPalette(const struct Pixel *); static boolean vesa_SetHardPalette(const struct Pixel *); static boolean vesa_SetSoftPalette(const struct Pixel *); #ifdef TILES_IN_GLYPHMAP -static void vesa_DisplayCell(int, int, int); +static void vesa_DisplayCell(int, int, int, uint8_t); +static unsigned char const *tile_with_decal(unsigned char const *, unsigned char const *); #endif static unsigned vesa_FindMode(unsigned long mode_addr, unsigned bits); static void vesa_WriteChar(uint32, int, int, uint32); @@ -111,6 +117,11 @@ static struct map_struct { int inverse; } map[ROWNO][COLNO]; /* track the glyphs */ +enum { delimdecal, petdecal, piledecal, NUMDECALS }; +static unsigned char *vesa_decals[NUMDECALS] = { 0 }; +static unsigned char *tmptilebuf; +static unsigned short tilebackground; + #define vesa_clearmap() \ { \ int x, y; \ @@ -711,6 +722,18 @@ vesa_xputg(const glyph_info *glyphinfo, const glyph_info *bkglyphinfo UNUSED) uint32_t attr = (g_attribute == 0) ? attrib_gr_normal : g_attribute; int ry; + /* some decal initializations */ + if (!vesa_decals[delimdecal]) { + vesa_decals[delimdecal] = vesa_tile(Tile_delimiter); + /* The first pixel in Tile_delimiter is the background color */ + tilebackground = *((unsigned short *)vesa_decals[delimdecal]); + if (!vesa_decals[petdecal]) + vesa_decals[petdecal] = vesa_tile(Tile_petmark); + + if (!vesa_decals[piledecal]) + vesa_decals[piledecal] = vesa_tile(Tile_pilemark); + } + #ifdef ENHANCED_SYMBOLS if (SYMHANDLING(H_UTF8) && glyphinfo->gm.u && glyphinfo->gm.u->utf8str) { ch = glyphinfo->gm.u->utf32ch; @@ -755,7 +778,11 @@ vesa_xputg(const glyph_info *glyphinfo, const glyph_info *bkglyphinfo UNUSED) if (!iflags.over_view && map[ry][col].special) decal_packed(packcell, special); #endif - vesa_DisplayCell(glyphinfo->gm.tileidx, col - clipx, ry - clipy); + vesa_DisplayCell(glyphinfo->gm.tileidx, col - clipx, ry - clipy, + ((special & MG_PET) && iflags.hilite_pet) + ? petdecal + : ((special & MG_OBJPILE) && iflags.hilite_pile) + ? piledecal : 0); if (bkglyphinfo->framecolor != NO_COLOR) { int curtypbak = cursor_type; int cclr = cursor_color; @@ -1390,6 +1417,8 @@ vesa_Finish(void) free(vesa_tiles); free(vesa_oview_tiles); free_tiles(); + if (tmptilebuf) + free((genericptr_t) tmptilebuf), tmptilebuf = 0; #endif vesa_SwitchMode(MODETEXT); windowprocs.win_cliparound = tty_cliparound; @@ -1941,14 +1970,16 @@ vesa_TriplePixels(unsigned long fnt) */ #ifdef TILES_IN_GLYPHMAP static void -vesa_DisplayCell(int tilenum, int col, int row) +vesa_DisplayCell(int tilenum, int col, int row, uint8_t decalnum) { unsigned char const *tile; unsigned t_width, t_height; unsigned char const *tptr; + int /* px, */ py, pixx, pixy; unsigned long offset; unsigned p_row_width; + unsigned char const *decal; if (iflags.over_view) { tile = vesa_oview_tile(tilenum); @@ -1967,7 +1998,12 @@ vesa_DisplayCell(int tilenum, int col, int row) pixx += vesa_x_center; pixy += vesa_y_center; offset = pixy * (unsigned long)vesa_scan_line + pixx * vesa_pixel_bytes; - tptr = tile; + decal = (decalnum == petdecal) + ? vesa_decals[petdecal] + : (decalnum == piledecal) + ? vesa_decals[piledecal] + : NULL; + tptr = (decal == NULL) ? tile : tile_with_decal(tile, decal); for (py = 0; py < (int) t_height; ++py) { vesa_WritePixelRow(offset, tptr, p_row_width); @@ -1975,6 +2011,57 @@ vesa_DisplayCell(int tilenum, int col, int row) tptr += p_row_width; } } + +unsigned char const * +tile_with_decal(unsigned char const *tile, unsigned char const *decal) +{ + int tr, tc; + unsigned char const *tptr, *declptr; + unsigned char *dst; + + if (!tmptilebuf) + tmptilebuf = (unsigned char *) + alloc(iflags.wc_tile_width * vesa_pixel_bytes * iflags.wc_tile_height); + + tptr = tile; + declptr = decal; + dst = tmptilebuf; + for (tr = 0; tr < iflags.wc_tile_height; ++tr) { + for (tc = 0; tc < iflags.wc_tile_width; ++tc) { + switch(vesa_pixel_bytes) { + /* + * FIXME: add the other switch cases + */ + case 2: { + unsigned short *t1 = (unsigned short *) tptr, + *t2 = (unsigned short *) declptr, + *t3 = (unsigned short *) dst; + + /* + * ignore the "background" pixesl in decal, + * which is identified by the delim tile in the stock + * tile set which is 100% background. + */ + *t3 = (!(*t2 == tilebackground)) ? *t2 : *t1; + } + break; + default: { + unsigned char const *t1 = tptr; + unsigned char *t3 = dst; + + for (int i = 0; i < vesa_pixel_bytes; ++i) { + *t3 = *t1; + } + } + break; + } + tptr += vesa_pixel_bytes; + dst += vesa_pixel_bytes; + declptr += vesa_pixel_bytes; + } + } + return tmptilebuf; +} #endif /* TILES_IN_GLYPHMAP */ /* diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index 897588889..6052cb9fa 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -181,7 +181,11 @@ static struct map_struct { uint32 framecolor; } map[ROWNO][COLNO]; /* track the glyphs */ -extern int total_tiles_used, Tile_corr, Tile_unexplored; /* from tile.c */ +extern int total_tiles_used, + Tile_corr, Tile_unexplored, + Tile_delimiter, + Tile_petmark, + Tile_pilemark; /* from tile.c */ #define vga_clearmap() \ { \ From 5f1183d1ef5c1e70bb25e64a0c7ba092b971cd01 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Wed, 29 Jul 2026 21:16:07 -0400 Subject: [PATCH 563/702] This is cron-daily v1-May-7-2026. 000files updated: Files --- Files | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Files b/Files index 42dc61957..89e6cb0b9 100644 --- a/Files +++ b/Files @@ -626,10 +626,10 @@ NetHackTerm.applescript recover.pl win/share: (files for versions using optional tiles) -bmptiles.c gifread.c giftiles.c monsters.txt nhicns.uu -nhsplash.xpm objects.txt other.txt ppmwrite.c renumtiles.pl -thintile.c tile.doc tile.h tile2bmp.c tilemap.c -tileset.c tiletext.c tiletxt.c +bmptiles.c decals.txt gifread.c giftiles.c monsters.txt +nhicns.uu nhsplash.xpm objects.txt other.txt ppmwrite.c +renumtiles.pl thintile.c tile.doc tile.h tile2bmp.c +tilemap.c tileset.c tiletext.c tiletxt.c win/shim: (file in top directory) From 59080106b9feb7efcf9f2e3f7d6d0cfdd06c9892 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 30 Jul 2026 21:58:42 -0400 Subject: [PATCH 564/702] include clearing of MON_ENDGAME_FREE, MON_ENDGAME_MIGR bits in place_monster Issue reported by @ars3niy Fix #1647 --- src/steed.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/steed.c b/src/steed.c index c76c61696..a0366431d 100644 --- a/src/steed.c +++ b/src/steed.c @@ -935,11 +935,11 @@ place_monster(struct monst *mon, coordxy x, coordxy y) bits that may be set. We'll probably make MON_FLOOR an actual bit one day */ - mon->mstate &= ~(MON_OFFMAP | MON_DETACH | MON_LIMBO | MON_MIGRATING); + mon->mstate &= ~(MON_OFFMAP | MON_DETACH | MON_LIMBO | MON_MIGRATING + | MON_ENDGAME_FREE | MON_ENDGAME_MIGR); /* We don't mess with these bits above: - MON_BUBBLEMOVE | MON_ENDGAME_FREE | MON_ENDGAME_MIGR - | MON_OBLITERATE | MON_STILL_ARRIVING | MON_PARKED + MON_BUBBLEMOVE | MON_OBLITERATE | MON_STILL_ARRIVING | MON_PARKED */ } From 1e749c28ce8c5b92f12cbf3776b342ef39b8ff75 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 30 Jul 2026 22:30:34 -0400 Subject: [PATCH 565/702] follow-up adjust the mon_offmap(mon) macro to test any of the bits that constitute being off the map, while ignoring some of the other bits that do not. --- include/monst.h | 5 ++++- src/steed.c | 5 ++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/monst.h b/include/monst.h index 8e29c40b8..c16d3010b 100644 --- a/include/monst.h +++ b/include/monst.h @@ -257,7 +257,10 @@ struct monst { #define mon_perma_blind(mon) (!mon->mcansee && !mon->mblinded) -#define mon_offmap(mon) ((mon)->mstate != MON_FLOOR) +#define MON_OFF_MAP_BITS (MON_OFFMAP | MON_DETACH | MON_LIMBO | MON_MIGRATING \ + | MON_ENDGAME_FREE | MON_ENDGAME_MIGR | MON_BUBBLEMOVE) + +#define mon_offmap(mon) (((mon)->mstate & (MON_OFF_MAP_BITS)) != 0) /* Get the maximum difficulty monsters that can currently be generated, given the current level difficulty and the hero's level. */ diff --git a/src/steed.c b/src/steed.c index a0366431d..63b72e9e0 100644 --- a/src/steed.c +++ b/src/steed.c @@ -935,11 +935,10 @@ place_monster(struct monst *mon, coordxy x, coordxy y) bits that may be set. We'll probably make MON_FLOOR an actual bit one day */ - mon->mstate &= ~(MON_OFFMAP | MON_DETACH | MON_LIMBO | MON_MIGRATING - | MON_ENDGAME_FREE | MON_ENDGAME_MIGR); + mon->mstate &= ~(MON_OFF_MAP_BITS); /* We don't mess with these bits above: - MON_BUBBLEMOVE | MON_OBLITERATE | MON_STILL_ARRIVING | MON_PARKED + MON_OBLITERATE | MON_STILL_ARRIVING | MON_PARKED */ } From 404e949e95a74b05044dabe3a6358db976c02ce5 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 30 Jul 2026 22:35:47 -0400 Subject: [PATCH 566/702] one more follow-up --- include/monst.h | 2 +- src/steed.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/monst.h b/include/monst.h index c16d3010b..060995f86 100644 --- a/include/monst.h +++ b/include/monst.h @@ -258,7 +258,7 @@ struct monst { #define mon_perma_blind(mon) (!mon->mcansee && !mon->mblinded) #define MON_OFF_MAP_BITS (MON_OFFMAP | MON_DETACH | MON_LIMBO | MON_MIGRATING \ - | MON_ENDGAME_FREE | MON_ENDGAME_MIGR | MON_BUBBLEMOVE) + | MON_ENDGAME_FREE | MON_ENDGAME_MIGR | MON_BUBBLEMOVE | MON_PARKED) #define mon_offmap(mon) (((mon)->mstate & (MON_OFF_MAP_BITS)) != 0) diff --git a/src/steed.c b/src/steed.c index 63b72e9e0..4f24cdb5c 100644 --- a/src/steed.c +++ b/src/steed.c @@ -938,7 +938,7 @@ place_monster(struct monst *mon, coordxy x, coordxy y) mon->mstate &= ~(MON_OFF_MAP_BITS); /* We don't mess with these bits above: - MON_OBLITERATE | MON_STILL_ARRIVING | MON_PARKED + MON_OBLITERATE | MON_STILL_ARRIVING */ } From 05733d28f4a8279362c52bac83c6c97dee709b94 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 31 Jul 2026 06:25:58 -0400 Subject: [PATCH 567/702] food_disappears is missing a tin check #1648 Reported in GitHub issue #1648 by @janne-hmp --- src/eat.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/eat.c b/src/eat.c index 242429552..4e3d077e1 100644 --- a/src/eat.c +++ b/src/eat.c @@ -398,6 +398,11 @@ food_disappears(struct obj *obj) if (obj == svc.context.victual.piece) svc.context.victual = zero_victual; /* victual.piece = 0, .o_id = 0 */ + if (obj == svc.context.tin.tin) { + svc.context.tin.tin = (struct obj *) 0; + svc.context.tin.o_id = 0; + } + if (obj->timed) obj_stop_timers(obj); } From 193da97bac890b07867ca3b3dce06c32cab23494 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 31 Jul 2026 06:49:39 -0400 Subject: [PATCH 568/702] fixes5-0-1.txt catch-up --- doc/fixes5-0-1.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 75b411f79..fbf3448e8 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -77,6 +77,8 @@ Some optimizations of the glyph lookup - don't produce names for swallow stethoscope applied to one monster disguised as another (double-trouble Wizard) mis-described undisguised form (unintended side-effect of 5.0 commit 064523e162f8e30bdb76186a854b9d8958f3b340) +mon_offmap() and place_monster() needed to operate on the same mstate bits +food_disappears() needed to include a tin check Platform- and/or Interface-Specific Fixes @@ -142,6 +144,8 @@ Amiga: fix latent issue found in code review: (1L << i) for i==31 (or Amiga: fix latent issue found in code review: Drop unused cnt= from amii_display_nhwindow's DoMenuScroll call; the menu return value is consumed elsewhere, not here +Amiga & Atari: enable USE_BUFFERING for buffered stdio structlevel savefile + write path curses on Windows: the number of columns was being capped by default at 110 in cursinit.c; try to use the console width if no explicit setting was specified in the config file; impacted both wincon @@ -209,6 +213,7 @@ MS-DOS: Define a separate palette for VGA text (pr #1620 by chasonr) MS-DOS: some conditional cleanup for SUPPRESS_GRAPHICS, TILES_IN_GLYPHMAP, NO_TILES, WANT_WIN_CURSES=1 without WANT_WIN_TTY=1 (pr #1632 by chasonr) +MS-DOS: add some hilite_pet and hilite_pile support to tiled display musl: musl libc does not have __sighandler_t so don't use it in the macro definition for SIG_RET_TYPE with musl WASM: resolve some build failures in 'make CROSS_TO_WASM=1' @@ -229,6 +234,8 @@ Windows: with SELECTSAVE don't display error messages to a regular player Windows: fix startup of GUI NetHackW.exe if there was an explicit OPTIONS=windowtype:tty in the config file Windows: fix hilite_pet on the GUI NetHackW.exe when ascii map was selected +Windows: support -a (alignment) -g (gender) -p (profession) -r (race) + command line options via genl_prag() function in earlyarg.c tty: allow custom glyph colors if they're basic 16 nethack colors on terminals with less than 256 colors X11: obey timed_delay @@ -292,3 +299,7 @@ unix hints: the Makefiles distributed by sys/unix/setup.sh will now check share a single copy of nhuuid generation code between Amiga, Atari, and msdos by way of sys/share/pcmain.c (cherry-pick from pr #1541 by ingpaschke) nhgitset.pl: Set up future deprecation of PRE and POST hooks. +switch to using LUA_VERSION_NUM instead of LUA_VERSION_RELEASE_NUM for Lua + version checking +include a set of decals (petmark and pilemark) in win/share/decals.txt + and adjust tile processing to include it From 9447bba227c6cc227956f2986ae4a9348866f64c Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 31 Jul 2026 08:59:20 -0400 Subject: [PATCH 569/702] Windows: don't revert -D on command line Reported by @youbo0 in GitHub issue #1616 This issue text stated: "To enter wizard mode, I have a shortcut with -D -u wizard as suggested by the wiki for Windows players. However, the name is now overridden by a name in .nethackrc since 5.0, resulting in me not actually entering wizard mode due to having the wrong name despite using -u wizard. In the previous version, -u wizard was applying properly regardless." Closes #1616 --- src/options.c | 8 ++++++++ sys/windows/windmain.c | 2 -- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/options.c b/src/options.c index f3e7c3fdd..351c3903d 100644 --- a/src/options.c +++ b/src/options.c @@ -2559,6 +2559,14 @@ optfn_name( if ((op = string_for_env_opt(allopt[optidx].name, opts, FALSE)) != empty_optstr) { +#ifdef WIN32 + /* + * Under windows, if we already set flags.debug with -D + * on the command line, leave that alone. + */ + if (flags.debug && !strcmpi(svp.plname, "wizard")) + return optn_ok; +#endif nmcpy(svp.plname, op, PL_NSIZ); } else return optn_err; diff --git a/sys/windows/windmain.c b/sys/windows/windmain.c index bc8d3b661..fb21f8271 100644 --- a/sys/windows/windmain.c +++ b/sys/windows/windmain.c @@ -399,8 +399,6 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ setting of renameallowed; when False, player_selection() won't resent renaming as an option */ iflags.renameallowed = FALSE; - /* Obtain the name of the logged on user and incorporate - * it into the name. */ Sprintf(fnamebuf, "%s", svp.plname); (void) fname_encode( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-.", '%', From 29cb8b7d9af0704d4cbea0f57ef34bd53a7e437d Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 31 Jul 2026 14:53:19 -0400 Subject: [PATCH 570/702] Windows: group accelerator and menu item collision In the event that there is a collision between a menu group accelerator and an individual menu item's accelerator, disregard the group accelerator. '$' is the only known collision in NetHack 5.0 presently. Close #805 --- win/win32/mhmenu.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/win/win32/mhmenu.c b/win/win32/mhmenu.c index 908284e16..7579976a6 100644 --- a/win/win32/mhmenu.c +++ b/win/win32/mhmenu.c @@ -35,6 +35,7 @@ typedef struct mswin_menu_item { int color; char str[NHMENU_STR_SIZE]; boolean presel; + boolean group_accelerator_collision; unsigned int itemflags; int count; BOOL has_focus; @@ -191,7 +192,18 @@ mswin_menu_window_select_menu(HWND hWnd, int how, MENU_ITEM_P **_selected, /* collect group accelerators */ for (i = 0; i < data->menui.menu.size; i++) { if (data->how != PICK_NONE) { - if (data->menui.menu.items[i].group_accel + /* Check for conflict between a specific selectable + * menu item and its group accelerator. + */ + if (NHMENU_IS_SELECTABLE(data->menui.menu.items[i]) + && data->menui.menu.items[i].group_accel + == data->menui.menu.items[i].accelerator) { + /* collision between specific menu item + and its group accelerator */ + data->menui.menu.items[i].group_accelerator_collision = TRUE; + } + if (!data->menui.menu.items[i].group_accelerator_collision + && data->menui.menu.items[i].group_accel && !strchr(data->menui.menu.gacc, data->menui.menu.items[i].group_accel)) { *ap++ = data->menui.menu.items[i].group_accel; @@ -651,6 +663,7 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) /* prevent & being interpreted as a mnemonic start */ strNsubst(data->menui.menu.items[new_item].str, "&", "&&", 0); data->menui.menu.items[new_item].presel = msg_data->presel; + data->menui.menu.items[new_item].group_accelerator_collision = FALSE; data->menui.menu.items[new_item].itemflags = msg_data->itemflags; /* calculate tabstop size */ From a8a13bed810de3e1c55efeb8b16463844aa280c9 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 31 Jul 2026 15:07:53 -0400 Subject: [PATCH 571/702] fixes5-0-1.txt update for previous commit --- doc/fixes5-0-1.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index fbf3448e8..62494b1d3 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -216,6 +216,8 @@ MS-DOS: some conditional cleanup for SUPPRESS_GRAPHICS, TILES_IN_GLYPHMAP, MS-DOS: add some hilite_pet and hilite_pile support to tiled display musl: musl libc does not have __sighandler_t so don't use it in the macro definition for SIG_RET_TYPE with musl +tty: allow custom glyph colors if they're basic 16 nethack colors + on terminals with less than 256 colors WASM: resolve some build failures in 'make CROSS_TO_WASM=1' WASM: hints file cross-pre2.500 update to CFLAGS to include -DNHUUID Windows: don't demand keypress on intentional exit @@ -236,8 +238,9 @@ Windows: fix startup of GUI NetHackW.exe if there was an explicit Windows: fix hilite_pet on the GUI NetHackW.exe when ascii map was selected Windows: support -a (alignment) -g (gender) -p (profession) -r (race) command line options via genl_prag() function in earlyarg.c -tty: allow custom glyph colors if they're basic 16 nethack colors - on terminals with less than 256 colors +Windows: in the event that there is a collision between a menu group + accelerator and an individual menu item's accelerator, disregard + the group accelerator; only known collision is '$' at this time X11: obey timed_delay From bd68058327ac3cb475d389b71c6c16e09b0b9baf Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Mon, 3 Aug 2026 22:12:14 -0400 Subject: [PATCH 572/702] Extend decal support to all VESA modes --- sys/msdos/vidvesa.c | 90 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 15 deletions(-) diff --git a/sys/msdos/vidvesa.c b/sys/msdos/vidvesa.c index be2a94902..00bbf55f4 100644 --- a/sys/msdos/vidvesa.c +++ b/sys/msdos/vidvesa.c @@ -120,7 +120,7 @@ static struct map_struct { enum { delimdecal, petdecal, piledecal, NUMDECALS }; static unsigned char *vesa_decals[NUMDECALS] = { 0 }; static unsigned char *tmptilebuf; -static unsigned short tilebackground; +static uint32_t tilebackground; #define vesa_clearmap() \ { \ @@ -726,7 +726,20 @@ vesa_xputg(const glyph_info *glyphinfo, const glyph_info *bkglyphinfo UNUSED) if (!vesa_decals[delimdecal]) { vesa_decals[delimdecal] = vesa_tile(Tile_delimiter); /* The first pixel in Tile_delimiter is the background color */ - tilebackground = *((unsigned short *)vesa_decals[delimdecal]); + switch(vesa_pixel_bytes) { + case 1: + tilebackground = *((uint8_t *)vesa_decals[delimdecal]); + break; + + case 2: + tilebackground = *((uint16_t *)vesa_decals[delimdecal]); + break; + + case 3: + case 4: + tilebackground = *((uint32_t *)vesa_decals[delimdecal]) & 0x00FFFFFF; + break; + } if (!vesa_decals[petdecal]) vesa_decals[petdecal] = vesa_tile(Tile_petmark); @@ -2028,21 +2041,68 @@ tile_with_decal(unsigned char const *tile, unsigned char const *decal) dst = tmptilebuf; for (tr = 0; tr < iflags.wc_tile_height; ++tr) { for (tc = 0; tc < iflags.wc_tile_width; ++tc) { + /* + * ignore the "background" pixels in decal, + * which is identified by the delim tile in the stock + * tile set which is 100% background. + */ switch(vesa_pixel_bytes) { - /* - * FIXME: add the other switch cases - */ - case 2: { - unsigned short *t1 = (unsigned short *) tptr, - *t2 = (unsigned short *) declptr, - *t3 = (unsigned short *) dst; + case 1: { + uint8_t *t1 = (uint8_t *) tptr, + *t2 = (uint8_t *) declptr, + *t3 = (uint8_t *) dst; - /* - * ignore the "background" pixesl in decal, - * which is identified by the delim tile in the stock - * tile set which is 100% background. - */ - *t3 = (!(*t2 == tilebackground)) ? *t2 : *t1; + *t3 = (*t2 != tilebackground) ? *t2 : *t1; + } + break; + case 2: { + uint16_t *t1 = (uint16_t *) tptr, + *t2 = (uint16_t *) declptr, + *t3 = (uint16_t *) dst; + + *t3 = (*t2 != tilebackground) ? *t2 : *t1; + } + break; + case 3: { + uint16_t *t1a, *t2a, *t3a; + uint8_t *t1b, *t2b, *t3b; + uint32_t pix; + + if ((tc & 1) == 0) { + /* pixel column is even */ + t1a = (uint16_t *) (tptr + 0); + t2a = (uint16_t *) (declptr + 0); + t3a = (uint16_t *) (dst + 0); + t1b = (uint8_t *) (tptr + 2); + t2b = (uint8_t *) (declptr + 2); + t3b = (uint8_t *) (dst + 2); + pix = ((uint32_t) *t2b << 16) | *t2a; + } else { + /* pixel column is odd */ + t1b = (uint8_t *) (tptr + 0); + t2b = (uint8_t *) (declptr + 0); + t3b = (uint8_t *) (dst + 0); + t1a = (uint16_t *) (tptr + 1); + t2a = (uint16_t *) (declptr + 1); + t3a = (uint16_t *) (dst + 1); + pix = ((uint32_t) *t2a << 8) | *t2b; + } + + if (pix != tilebackground) { + *t3a = *t2a; + *t3b = *t2b; + } else { + *t3a = *t1a; + *t3b = *t1b; + } + } + break; + case 4: { + uint32_t *t1 = (uint32_t *) tptr, + *t2 = (uint32_t *) declptr, + *t3 = (uint32_t *) dst; + + *t3 = ((*t2 & 0x00FFFFFF) != tilebackground) ? *t2 : *t1; } break; default: { From 0c044e9c908dde44893135248a97bd3a1d1f2be1 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Mon, 3 Aug 2026 22:12:32 -0400 Subject: [PATCH 573/702] Add hilite flags --- sys/share/NetHack.cnf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/share/NetHack.cnf b/sys/share/NetHack.cnf index a34c68f13..3fbfb9978 100644 --- a/sys/share/NetHack.cnf +++ b/sys/share/NetHack.cnf @@ -30,6 +30,8 @@ OPTIONS=rawio,BIOS,symset:IBMGraphics_2,roguesymset:RogueEpyx #OPTIONS=video_width:1024 #OPTIONS=video_height:768 +# To show markers for pets and piles if this is supported +OPTIONS=hilite_pet,hilite_pile # If your machine is NEC PC-9800, use: #OPTIONS=rawio,BIOS,video:default From 85bb8c1fbccce1ed440cb8028d3eaee67f701bd6 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Mon, 3 Aug 2026 22:20:18 -0400 Subject: [PATCH 574/702] Simplify the 24-bit case --- sys/msdos/vidvesa.c | 39 ++++++++++++--------------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/sys/msdos/vidvesa.c b/sys/msdos/vidvesa.c index 00bbf55f4..c35320f47 100644 --- a/sys/msdos/vidvesa.c +++ b/sys/msdos/vidvesa.c @@ -2064,36 +2064,21 @@ tile_with_decal(unsigned char const *tile, unsigned char const *decal) } break; case 3: { - uint16_t *t1a, *t2a, *t3a; - uint8_t *t1b, *t2b, *t3b; - uint32_t pix; - - if ((tc & 1) == 0) { - /* pixel column is even */ - t1a = (uint16_t *) (tptr + 0); - t2a = (uint16_t *) (declptr + 0); - t3a = (uint16_t *) (dst + 0); - t1b = (uint8_t *) (tptr + 2); - t2b = (uint8_t *) (declptr + 2); - t3b = (uint8_t *) (dst + 2); - pix = ((uint32_t) *t2b << 16) | *t2a; - } else { - /* pixel column is odd */ - t1b = (uint8_t *) (tptr + 0); - t2b = (uint8_t *) (declptr + 0); - t3b = (uint8_t *) (dst + 0); - t1a = (uint16_t *) (tptr + 1); - t2a = (uint16_t *) (declptr + 1); - t3a = (uint16_t *) (dst + 1); - pix = ((uint32_t) *t2a << 8) | *t2b; - } + uint8_t *t1 = (uint8_t *) tptr, + *t2 = (uint8_t *) declptr, + *t3 = (uint8_t *) dst; + uint32_t pix = ((uint32_t) t2[2] << 16) + | ((uint32_t) t2[1] << 8) + | ((uint32_t) t2[0] << 0); if (pix != tilebackground) { - *t3a = *t2a; - *t3b = *t2b; + t3[0] = t2[0]; + t3[1] = t2[1]; + t3[2] = t2[2]; } else { - *t3a = *t1a; - *t3b = *t1b; + t3[0] = t1[0]; + t3[1] = t1[1]; + t3[2] = t1[2]; } } break; From 9d5184562ed32b65e0055572f7007364ae181150 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Tue, 4 Aug 2026 09:38:38 -0400 Subject: [PATCH 575/702] More decal support for VESA * Support decals in overview mode * Draw decals when redrawing the map --- sys/msdos/vidvesa.c | 256 +++++++++++++++++++++++++++----------------- 1 file changed, 155 insertions(+), 101 deletions(-) diff --git a/sys/msdos/vidvesa.c b/sys/msdos/vidvesa.c index c35320f47..80247797c 100644 --- a/sys/msdos/vidvesa.c +++ b/sys/msdos/vidvesa.c @@ -47,7 +47,9 @@ static unsigned long vesa_ReadPixel32(unsigned x, unsigned y); static void vesa_WritePixel32(unsigned x, unsigned y, unsigned long color); static void vesa_WritePixel(unsigned x, unsigned y, unsigned color); static void vesa_WritePixelRow(unsigned long offset, - unsigned char const *p_row, unsigned p_row_size); + unsigned char const *p_row, + unsigned char const *p_decal_row, + unsigned p_row_size); static unsigned long vesa_MakeColor(struct Pixel); static void vesa_FillRect(unsigned left, unsigned top, unsigned width, unsigned height, unsigned color); @@ -66,7 +68,7 @@ static boolean vesa_SetHardPalette(const struct Pixel *); static boolean vesa_SetSoftPalette(const struct Pixel *); #ifdef TILES_IN_GLYPHMAP static void vesa_DisplayCell(int, int, int, uint8_t); -static unsigned char const *tile_with_decal(unsigned char const *, unsigned char const *); +static uint8_t *add_transparent_row(uint8_t const *, uint8_t const *, unsigned, uint32_t); #endif static unsigned vesa_FindMode(unsigned long mode_addr, unsigned bits); static void vesa_WriteChar(uint32, int, int, uint32); @@ -112,13 +114,15 @@ static struct map_struct { uint32 ch; uint32 attr; unsigned special; - short int tileidx; + uint16_t tileidx; + uint16_t decalnum; int framecolor; int inverse; } map[ROWNO][COLNO]; /* track the glyphs */ enum { delimdecal, petdecal, piledecal, NUMDECALS }; static unsigned char *vesa_decals[NUMDECALS] = { 0 }; +static unsigned char *vesa_oview_decals[NUMDECALS] = { 0 }; static unsigned char *tmptilebuf; static uint32_t tilebackground; @@ -133,6 +137,7 @@ static uint32_t tilebackground; map[y][x].attr = 0; \ map[y][x].special = 0; \ map[y][x].tileidx = Tile_unexplored; \ + map[y][x].decalnum = 0; \ map[y][x].inverse = 0; \ } \ } @@ -496,8 +501,22 @@ vesa_WritePixel(unsigned x, unsigned y, unsigned color) static void vesa_WritePixelRow(unsigned long offset, - unsigned char const *p_row, unsigned p_row_size) + unsigned char const *p_row, + unsigned char const *p_decal_row, + unsigned p_row_size) { +#ifdef TILES_IN_GLYPHMAP + uint8_t *p_combined_row = NULL; /* custodial */ + + if (p_decal_row != NULL) { + p_combined_row = add_transparent_row( + p_row, p_decal_row, p_row_size, tilebackground); + p_row = p_combined_row; + } +#else + nhUse(p_decal_row); +#endif + if (vesa_segment != 0) { /* Linear frame buffer in use */ movedata(_go32_my_ds(), (unsigned)p_row, vesa_segment, offset, p_row_size); @@ -516,6 +535,10 @@ vesa_WritePixelRow(unsigned long offset, } dosmemput(p_row + i, p_row_size - i, addr); } + +#ifdef TILES_IN_GLYPHMAP + free(p_combined_row); +#endif } static unsigned long @@ -566,7 +589,7 @@ vesa_FillRect(unsigned left, unsigned top, unsigned width, } for (y = 0; y < height; ++y) { - vesa_WritePixelRow(offset, p_row, p_row_size); + vesa_WritePixelRow(offset, p_row, NULL, p_row_size); offset += vesa_scan_line; } @@ -745,7 +768,18 @@ vesa_xputg(const glyph_info *glyphinfo, const glyph_info *bkglyphinfo UNUSED) if (!vesa_decals[piledecal]) vesa_decals[piledecal] = vesa_tile(Tile_pilemark); + + if (!vesa_oview_decals[petdecal]) + vesa_oview_decals[petdecal] = vesa_oview_tile(Tile_petmark); + + if (!vesa_oview_decals[piledecal]) + vesa_oview_decals[piledecal] = vesa_oview_tile(Tile_pilemark); } + + unsigned decalnum = ((special & MG_PET) && iflags.hilite_pet) + ? petdecal + : ((special & MG_OBJPILE) && iflags.hilite_pile) + ? piledecal : 0; #ifdef ENHANCED_SYMBOLS if (SYMHANDLING(H_UTF8) && glyphinfo->gm.u && glyphinfo->gm.u->utf8str) { @@ -775,6 +809,7 @@ vesa_xputg(const glyph_info *glyphinfo, const glyph_info *bkglyphinfo UNUSED) map[ry][col].ch = ch; map[ry][col].special = special; map[ry][col].tileidx = glyphinfo->gm.tileidx; + map[ry][col].decalnum = decalnum; map[ry][col].attr = attr; map[ry][col].inverse = inversed; @@ -791,11 +826,7 @@ vesa_xputg(const glyph_info *glyphinfo, const glyph_info *bkglyphinfo UNUSED) if (!iflags.over_view && map[ry][col].special) decal_packed(packcell, special); #endif - vesa_DisplayCell(glyphinfo->gm.tileidx, col - clipx, ry - clipy, - ((special & MG_PET) && iflags.hilite_pet) - ? petdecal - : ((special & MG_OBJPILE) && iflags.hilite_pile) - ? piledecal : 0); + vesa_DisplayCell(glyphinfo->gm.tileidx, col - clipx, ry - clipy, decalnum); if (bkglyphinfo->framecolor != NO_COLOR) { int curtypbak = cursor_type; int cclr = cursor_color; @@ -908,15 +939,20 @@ vesa_redrawmap(void) } } else if (iflags.over_view) { /* Overview mode */ - const unsigned char *tile; p_row_width = vesa_oview_width * vesa_pixel_bytes; y = y_top; for (cy = 0; cy < ROWNO; ++cy) { for (py = 0; py < vesa_oview_height; ++py) { for (cx = 0; cx < COLNO; ++cx) { - tile = vesa_oview_tile(map[cy][cx].tileidx); - vesa_WritePixelRow(offset + p_row_width * cx, tile + p_row_width * py, p_row_width); + const uint8_t *tile = vesa_oview_tile(map[cy][cx].tileidx); + const uint8_t *decal = NULL; + unsigned decalnum = map[cy][cx].decalnum; + if (decalnum != 0 && decalnum < NUMDECALS) { + decal = vesa_oview_decals[decalnum]; + decal += p_row_width * py; + } + vesa_WritePixelRow(offset + p_row_width * cx, tile + p_row_width * py, decal, p_row_width); } x = COLNO * vesa_oview_width; if (x < vesa_x_res) { @@ -928,15 +964,20 @@ vesa_redrawmap(void) } } else { /* Normal tiled mode */ - const unsigned char *tile; p_row_width = iflags.wc_tile_width * vesa_pixel_bytes; y = y_top; for (cy = clipy; cy <= (unsigned) clipymax && cy < ROWNO; ++cy) { for (py = 0; py < (unsigned) iflags.wc_tile_height; ++py) { for (cx = clipx; cx <= (unsigned) clipxmax && cx < COLNO; ++cx) { - tile = vesa_tile(map[cy][cx].tileidx); - vesa_WritePixelRow(offset + p_row_width * (cx - clipx), tile + p_row_width * py, p_row_width); + const uint8_t *tile = vesa_tile(map[cy][cx].tileidx); + const uint8_t *decal = NULL; + unsigned decalnum = map[cy][cx].decalnum; + if (decalnum != 0 && decalnum < NUMDECALS) { + decal = vesa_decals[decalnum]; + decal += p_row_width * py; + } + vesa_WritePixelRow(offset + p_row_width * (cx - clipx), tile + p_row_width * py, decal, p_row_width); } x = (cx - clipx) * iflags.wc_tile_width; if (x < vesa_x_res) { @@ -1867,7 +1908,7 @@ vesa_WriteTextRow(int pixx, int pixy, struct VesaCharacter const *t_row, } } } - vesa_WritePixelRow(offset, p_row, p_row_width); + vesa_WritePixelRow(offset, p_row, NULL, p_row_width); offset += vesa_scan_line; } free(p_row); @@ -2011,101 +2052,114 @@ vesa_DisplayCell(int tilenum, int col, int row, uint8_t decalnum) pixx += vesa_x_center; pixy += vesa_y_center; offset = pixy * (unsigned long)vesa_scan_line + pixx * vesa_pixel_bytes; - decal = (decalnum == petdecal) - ? vesa_decals[petdecal] - : (decalnum == piledecal) - ? vesa_decals[piledecal] - : NULL; - tptr = (decal == NULL) ? tile : tile_with_decal(tile, decal); + if (decalnum != 0 && decalnum < NUMDECALS) { + if (iflags.over_view) { + decal = vesa_oview_decals[decalnum]; + } else { + decal = vesa_decals[decalnum]; + } + } else { + decal = NULL; + } + tptr = tile; for (py = 0; py < (int) t_height; ++py) { - vesa_WritePixelRow(offset, tptr, p_row_width); + vesa_WritePixelRow(offset, tptr, decal, p_row_width); offset += vesa_scan_line; tptr += p_row_width; + if (decal != NULL) { + decal += p_row_width; + } } } -unsigned char const * -tile_with_decal(unsigned char const *tile, unsigned char const *decal) +/* Overlay a transparent row onto the given pixel row */ +/* Return an allocated buffer containing the overlaid row */ +/* The caller is responsible for freeing the returned row */ +static uint8_t * +add_transparent_row( + uint8_t const *p_row, + uint8_t const *p_overlay, + unsigned p_row_size, + uint32_t transparent_pixel) { - int tr, tc; - unsigned char const *tptr, *declptr; - unsigned char *dst; + /* + * ignore the "background" pixels in decal, + * which is identified by the delim tile in the stock + * tile set which is 100% background. + */ + uint8_t *p_combined_row = (uint8_t *) alloc(p_row_size); + switch(vesa_pixel_bytes) { + case 1: { + uint8_t *t1 = (uint8_t *) p_row, + *t2 = (uint8_t *) p_overlay, + *t3 = (uint8_t *) p_combined_row; - if (!tmptilebuf) - tmptilebuf = (unsigned char *) - alloc(iflags.wc_tile_width * vesa_pixel_bytes * iflags.wc_tile_height); - - tptr = tile; - declptr = decal; - dst = tmptilebuf; - for (tr = 0; tr < iflags.wc_tile_height; ++tr) { - for (tc = 0; tc < iflags.wc_tile_width; ++tc) { - /* - * ignore the "background" pixels in decal, - * which is identified by the delim tile in the stock - * tile set which is 100% background. - */ - switch(vesa_pixel_bytes) { - case 1: { - uint8_t *t1 = (uint8_t *) tptr, - *t2 = (uint8_t *) declptr, - *t3 = (uint8_t *) dst; - - *t3 = (*t2 != tilebackground) ? *t2 : *t1; - } - break; - case 2: { - uint16_t *t1 = (uint16_t *) tptr, - *t2 = (uint16_t *) declptr, - *t3 = (uint16_t *) dst; - - *t3 = (*t2 != tilebackground) ? *t2 : *t1; - } - break; - case 3: { - uint8_t *t1 = (uint8_t *) tptr, - *t2 = (uint8_t *) declptr, - *t3 = (uint8_t *) dst; - uint32_t pix = ((uint32_t) t2[2] << 16) - | ((uint32_t) t2[1] << 8) - | ((uint32_t) t2[0] << 0); - - if (pix != tilebackground) { - t3[0] = t2[0]; - t3[1] = t2[1]; - t3[2] = t2[2]; - } else { - t3[0] = t1[0]; - t3[1] = t1[1]; - t3[2] = t1[2]; - } - } - break; - case 4: { - uint32_t *t1 = (uint32_t *) tptr, - *t2 = (uint32_t *) declptr, - *t3 = (uint32_t *) dst; - - *t3 = ((*t2 & 0x00FFFFFF) != tilebackground) ? *t2 : *t1; - } - break; - default: { - unsigned char const *t1 = tptr; - unsigned char *t3 = dst; - - for (int i = 0; i < vesa_pixel_bytes; ++i) { - *t3 = *t1; - } - } - break; + for (unsigned i = 0; i < p_row_size; i += vesa_pixel_bytes) { + *t3 = (*t2 != transparent_pixel) ? *t2 : *t1; + ++t1; + ++t2; + ++t3; + } } - tptr += vesa_pixel_bytes; - dst += vesa_pixel_bytes; - declptr += vesa_pixel_bytes; - } + break; + case 2: { + uint16_t *t1 = (uint16_t *) p_row, + *t2 = (uint16_t *) p_overlay, + *t3 = (uint16_t *) p_combined_row; + + for (unsigned i = 0; i < p_row_size; i += vesa_pixel_bytes) { + *t3 = (*t2 != transparent_pixel) ? *t2 : *t1; + ++t1; + ++t2; + ++t3; + } + } + break; + case 3: { + uint8_t *t1 = (uint8_t *) p_row, + *t2 = (uint8_t *) p_overlay, + *t3 = (uint8_t *) p_combined_row; + for (unsigned i = 0; i < p_row_size; i += vesa_pixel_bytes) { + uint32_t pix = ((uint32_t) t2[2] << 16) + | ((uint32_t) t2[1] << 8) + | ((uint32_t) t2[0] << 0); + + if (pix != transparent_pixel) { + t3[0] = t2[0]; + t3[1] = t2[1]; + t3[2] = t2[2]; + } else { + t3[0] = t1[0]; + t3[1] = t1[1]; + t3[2] = t1[2]; + } + t1 += 3; + t2 += 3; + t3 += 3; + } + } + break; + case 4: { + uint32_t *t1 = (uint32_t *) p_row, + *t2 = (uint32_t *) p_overlay, + *t3 = (uint32_t *) p_combined_row; + + for (unsigned i = 0; i < p_row_size; i += vesa_pixel_bytes) { + *t3 = ((*t2 & 0x00FFFFFF) != transparent_pixel) ? *t2 : *t1; + ++t1; + ++t2; + ++t3; + } + } + break; + default: + /* This isn't supposed to happen */ + memcpy(p_combined_row, p_row, p_row_size); + break; } - return tmptilebuf; + + return p_combined_row; } #endif /* TILES_IN_GLYPHMAP */ From 3e800b90d313acbefb9ef2d08ce9161978496bb2 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Tue, 4 Aug 2026 15:55:36 -0400 Subject: [PATCH 576/702] Support pet and tile decals in 16 color mode --- sys/msdos/vidvga.c | 173 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 147 insertions(+), 26 deletions(-) diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index 6052cb9fa..101862e10 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -121,6 +121,7 @@ static void vga_scrollmap(boolean); static void vga_redrawmap(boolean); static void vga_cliparound(int, int); static void decal_planar(struct planar_cell_struct *, unsigned); +static void decal_oview_planar(struct overview_planar_cell_struct *, unsigned); #endif #ifdef POSITIONBAR @@ -141,6 +142,7 @@ static void vga_WriteStr(char *, int, int, int, int); static char __far *vga_FontPtrs(void); #ifdef TILES_IN_GLYPHMAP +static int glyph_to_tilenum(unsigned); static void read_planar_tile(unsigned, struct planar_cell_struct *); static void read_planar_tile_O(unsigned, struct overview_planar_cell_struct *); @@ -243,6 +245,10 @@ static int vp[SCREENPLANES] = { 8, 4, 2, 1 }; #ifdef TILES_IN_GLYPHMAP static struct planar_cell_struct **cell_cache; static struct overview_planar_cell_struct **cell_cache_O; + +enum { delimdecal, petdecal, piledecal, NUMDECALS }; +static struct cellplane *decal_alpha[NUMDECALS] = { 0 }; +static struct overview_cellplane *decal_oview_alpha[NUMDECALS] = { 0 }; #endif /* static int g_attribute; */ /* Current attribute to use */ @@ -442,8 +448,8 @@ vga_xputg(const glyph_info *glyphinfo, } else if (!iflags.over_view) { if ((col >= clipx) && (col <= clipxmax)) { struct planar_cell_struct planecell; - read_planar_tile(glyphnum, &planecell); - if (map[ry][col].special) + read_planar_tile(glyph_to_tilenum(glyphnum), &planecell); + if (special) decal_planar(&planecell, special); vga_DisplayCell(&planecell, col - clipx, row); if (bkglyphinfo->framecolor != NO_COLOR) { @@ -459,7 +465,9 @@ vga_xputg(const glyph_info *glyphinfo, } } else { struct overview_planar_cell_struct planecell_O; - read_planar_tile_O(glyphnum, &planecell_O); + read_planar_tile_O(glyph_to_tilenum(glyphnum), &planecell_O); + if (special) + decal_oview_planar(&planecell_O, special); vga_DisplayCell_O(&planecell_O, col, row); } if (col < (CO - 1)) @@ -546,13 +554,15 @@ vga_redrawmap(boolean clearfirst) t = map[y][x].glyph; if (!iflags.over_view) { struct planar_cell_struct planecell; - read_planar_tile(t, &planecell); + read_planar_tile(glyph_to_tilenum(t), &planecell); if (map[y][x].special) decal_planar(&planecell, map[y][x].special); vga_DisplayCell(&planecell, x - clipx, y + TOP_MAP_ROW); } else { struct overview_planar_cell_struct planecell_O; - read_planar_tile_O(t, &planecell_O); + read_planar_tile_O(glyph_to_tilenum(t), &planecell_O); + if (map[y][x].special) + decal_oview_planar(&planecell_O, map[y][x].special); vga_DisplayCell_O(&planecell_O, x, y + TOP_MAP_ROW); } } @@ -684,7 +694,7 @@ boolean left; for (x = i; x < j; x += 2) { struct planar_cell_struct planecell; t = map[y][x].glyph; - read_planar_tile(t, &planecell); + read_planar_tile(glyph_to_tilenum(t), &planecell); if (map[y][x].special) decal_planar(&planecell, map[y][x].special); vga_DisplayCell(&planecell, x - clipx, y + TOP_MAP_ROW); @@ -693,13 +703,23 @@ boolean left; } #endif /* SCROLLMAP */ +static int +glyph_to_tilenum(unsigned glyph) +{ + /* We don't have enough colors to show the statues */ + if (glyph_is_statue(glyph)) { + glyph = GLYPH_OBJ_OFF + STATUE; + } + + return glyphmap[glyph].tileidx; +} + static void -read_planar_tile(unsigned glyph, struct planar_cell_struct *cell) +read_planar_tile(unsigned tilenum, struct planar_cell_struct *cell) { struct planar_cell_struct *pcell; unsigned char indexes[TILE_Y][TILE_X]; unsigned plane, y, byte, bit; - int tilenum = glyphmap[glyph].tileidx; /* Get the processed tile from the cache if we can */ pcell = cell_cache[tilenum]; @@ -707,7 +727,7 @@ read_planar_tile(unsigned glyph, struct planar_cell_struct *cell) /* Process the tile */ pcell = (struct planar_cell_struct *) alloc(sizeof(*pcell)); cell_cache[tilenum] = pcell; - read_tile_indexes(glyph, indexes); + read_tile_indexes(tilenum, indexes); /* pcell->plane[0..3].image[0..15][0..1] */ for (plane = 0; plane < SCREENPLANES; ++plane) { for (y = 0; y < TILE_Y; ++y) { @@ -729,12 +749,11 @@ read_planar_tile(unsigned glyph, struct planar_cell_struct *cell) } static void -read_planar_tile_O(unsigned glyph, struct overview_planar_cell_struct *cell) +read_planar_tile_O(unsigned tilenum, struct overview_planar_cell_struct *cell) { struct overview_planar_cell_struct *pcell; unsigned char indexes[TILE_Y][TILE_X]; unsigned plane, y, bit; - int tilenum = glyphmap[glyph].tileidx; /* Get the processed tile from the cache if we can */ pcell = cell_cache_O[tilenum]; @@ -742,7 +761,7 @@ read_planar_tile_O(unsigned glyph, struct overview_planar_cell_struct *cell) /* Process the tile */ pcell = (struct overview_planar_cell_struct *) alloc(sizeof(*pcell)); cell_cache_O[tilenum] = pcell; - read_tile_indexes(glyph, indexes); + read_tile_indexes(tilenum, indexes); /* pcell->plane[0..3].image[0..15][0..0] */ for (plane = 0; plane < SCREENPLANES; ++plane) { for (y = 0; y < TILE_Y; ++y) { @@ -762,19 +781,12 @@ read_planar_tile_O(unsigned glyph, struct overview_planar_cell_struct *cell) } static void -read_tile_indexes(unsigned glyph, unsigned char (*indexes)[TILE_X]) +read_tile_indexes(unsigned tilenum, unsigned char (*indexes)[TILE_X]) { const struct TileImage *tile; unsigned x, y; - int tilenum; - - /* We don't have enough colors to show the statues */ - if (glyph_is_statue(glyph)) { - glyph = GLYPH_OBJ_OFF + STATUE; - } /* Get the tile from the image */ - tilenum = glyphmap[glyph].tileidx; tile = get_tile(tilenum); /* Map to a 16 bit palette; assume colors laid out as in default tileset */ @@ -792,13 +804,122 @@ read_tile_indexes(unsigned glyph, unsigned char (*indexes)[TILE_X]) } static void -decal_planar(struct planar_cell_struct *gpcs UNUSED, unsigned special) +decal_planar(struct planar_cell_struct *gpcs, unsigned special) { - if (special & MG_CORPSE) { - } else if (special & MG_INVIS) { - } else if (special & MG_DETECT) { - } else if (special & MG_PET) { - } else if (special & MG_RIDDEN) { + int decalnum; /* indexes decal_alpha */ + int decal_tile; /* tile index of decal */ + + /* Which decal do we use? */ + if ((special & MG_PET) != 0 && iflags.hilite_pet) { + decalnum = petdecal; + decal_tile = Tile_petmark; + } else if ((special & MG_OBJPILE) != 0 && iflags.hilite_pile) { + decalnum = piledecal; + decal_tile = Tile_pilemark; + } else { + /* No decal */ + return; + } + + /* Read the decal */ + struct planar_cell_struct decal; + read_planar_tile(decal_tile, &decal); + + /* Build the alpha channel for the decal */ + struct cellplane *alpha = decal_alpha[decalnum]; + + if (alpha == NULL) { + /* Read the delimiter to get the background color */ + struct planar_cell_struct delim; + read_planar_tile(Tile_delimiter, &delim); + + /* Allocate space for the alpha channel */ + alpha = (struct cellplane *) alloc(sizeof(*alpha)); + decal_alpha[decalnum] = alpha; + memset(alpha, 0x00, sizeof(*alpha)); + + /* Alpha channel is 0 where all planes of the decal match the + background, and 1 otherwise */ + for (unsigned i = 0; i < SCREENPLANES; ++i) { + uint8_t background = (delim.plane[i].image[0][0] & 0x80) ? 0xFF : 0x00; + for (unsigned j = 0; j < MAX_ROWS_PER_CELL; ++j) { + for (unsigned k = 0; k < MAX_BYTES_PER_CELL; ++k) { + /* Set alpha to 1 wherever the decal doesn't match the + background */ + alpha->image[j][k] |= decal.plane[i].image[j][k] ^ background; + } + } + } + } + + /* Apply the decal to the tile */ + for (unsigned i = 0; i < SCREENPLANES; ++i) { + for (unsigned j = 0; j < MAX_ROWS_PER_CELL; ++j) { + for (unsigned k = 0; k < MAX_BYTES_PER_CELL; ++k) { + uint8_t b1 = gpcs->plane[i].image[j][k]; + uint8_t b2 = decal.plane[i].image[j][k]; + uint8_t a = alpha->image[j][k]; + gpcs->plane[i].image[j][k] = (b1 & ~a) | (b2 & a); + } + } + } +} + +static void +decal_oview_planar(struct overview_planar_cell_struct *gpcs, unsigned special) +{ + int decalnum; /* indexes decal_alpha */ + int decal_tile; /* tile index of decal */ + + /* Which decal do we use? */ + if ((special & MG_PET) != 0 && iflags.hilite_pet) { + decalnum = petdecal; + decal_tile = Tile_petmark; + } else if ((special & MG_OBJPILE) != 0 && iflags.hilite_pile) { + decalnum = piledecal; + decal_tile = Tile_pilemark; + } else { + /* No decal */ + return; + } + + /* Read the decal */ + struct overview_planar_cell_struct decal; + read_planar_tile_O(decal_tile, &decal); + + /* Build the alpha channel for the decal */ + struct overview_cellplane *alpha = decal_oview_alpha[decalnum]; + + if (alpha == NULL) { + /* Read the delimiter to get the background color */ + struct planar_cell_struct delim; /* not overview_planar_cell_struct */ + read_planar_tile(Tile_delimiter, &delim); + + /* Allocate space for the alpha channel */ + alpha = (struct overview_cellplane *) alloc(sizeof(*alpha)); + decal_oview_alpha[decalnum] = alpha; + memset(alpha, 0x00, sizeof(*alpha)); + + /* Alpha channel is 0 where all planes of the decal match the + background, and 1 otherwise */ + for (unsigned i = 0; i < SCREENPLANES; ++i) { + uint8_t background = (delim.plane[i].image[0][0] & 0x80) ? 0xFF : 0x00; + for (unsigned j = 0; j < MAX_ROWS_PER_CELL; ++j) { + /* Set alpha to 1 wherever the decal doesn't match the + background */ + alpha->image[j][0] |= decal.plane[i].image[j][0] ^ background; + } + } + } + + /* Apply the decal to the tile */ + for (unsigned i = 0; i < SCREENPLANES; ++i) { + for (unsigned j = 0; j < MAX_ROWS_PER_CELL; ++j) { + uint8_t b1 = gpcs->plane[i].image[j][0]; + uint8_t b2 = decal.plane[i].image[j][0]; + uint8_t a = alpha->image[j][0]; + gpcs->plane[i].image[j][0] = (b1 & ~a) | (b2 & a); + } } } #endif /* TILES_IN_GLYPHMAP */ From e0ecf0e5f21cb986a24287e3838c4360967ad27e Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Tue, 4 Aug 2026 16:05:27 -0400 Subject: [PATCH 577/702] Fix highlighting in 16 color text map vga_redrawmap did not have the inverse flag available. Provide it. --- sys/msdos/vidvga.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index 101862e10..eb32985cd 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -136,7 +136,7 @@ static void vga_DisplayCell_O(struct overview_planar_cell_struct *, int, #endif static void vga_SwitchMode(unsigned int); static void vga_SetPalette(const struct Pixel *); -static void vga_WriteChar(uint32, int, int, int); +static void vga_WriteChar(uint32, int, int, int, int); static void vga_GetBitmap(uint32, unsigned char *); static void vga_WriteStr(char *, int, int, int, int); static char __far *vga_FontPtrs(void); @@ -181,6 +181,7 @@ static struct map_struct { unsigned special; short int tileidx; uint32 framecolor; + int inverse; } map[ROWNO][COLNO]; /* track the glyphs */ extern int total_tiles_used, @@ -200,6 +201,7 @@ extern int total_tiles_used, map[y][x].attr = 0; \ map[y][x].special = 0; \ map[y][x].tileidx = Tile_unexplored; \ + map[y][x].inverse = 0; \ } \ } #endif /* TILES_IN_GLYPHMAP */ @@ -308,7 +310,7 @@ void vga_cl_end(int col, int row) * mode 2 methods as did term_clear_screen() */ for (count = col; count < (CO - 1); ++count) { - vga_WriteChar(' ', count, row, BACKGROUND_VGA_COLOR); + vga_WriteChar(' ', count, row, BACKGROUND_VGA_COLOR, FALSE); } } @@ -320,7 +322,7 @@ void vga_cl_eos(int cy) cl_end(); while (cy <= LI - 2) { for (count = 0; count < (CO - 1); ++count) { - vga_WriteChar(' ', count, cy, BACKGROUND_VGA_COLOR); + vga_WriteChar(' ', count, cy, BACKGROUND_VGA_COLOR, FALSE); } cy++; } @@ -392,7 +394,7 @@ void vga_xputc(char ch, int attr) ++row; break; default: - vga_WriteChar((unsigned char) ch, col, row, attr); + vga_WriteChar((unsigned char) ch, col, row, attr, FALSE); if (col < (CO - 1)) ++col; break; @@ -439,12 +441,13 @@ vga_xputg(const glyph_info *glyphinfo, attr = (g_attribute == 0) ? attrib_gr_normal : g_attribute; map[ry][col].attr = attr; map[ry][col].tileidx = glyphinfo->gm.tileidx; + map[ry][col].inverse = inversed; if (bkglyphinfo->framecolor != NO_COLOR) { map[ry][col].framecolor = bkglyphinfo->framecolor; } if (iflags.traditional_view) { - vga_WriteChar(ch, col, row, attr); + vga_WriteChar(ch, col, row, attr, inversed); } else if (!iflags.over_view) { if ((col >= clipx) && (col <= clipxmax)) { struct planar_cell_struct planecell; @@ -549,7 +552,8 @@ vga_redrawmap(boolean clearfirst) if (iflags.traditional_view) { if (!(clearfirst && map[y][x].ch == S_stone)) vga_WriteChar(map[y][x].ch, x, - y + TOP_MAP_ROW, map[y][x].attr); + y + TOP_MAP_ROW, map[y][x].attr, + map[y][x].inverse); } else { t = map[y][x].glyph; if (!iflags.over_view) { @@ -1162,7 +1166,7 @@ extern int curframecolor; /* video.c */ * */ static void -vga_WriteChar(uint32 chr, int col, int row, int colour) +vga_WriteChar(uint32 chr, int col, int row, int colour, int inverse) { int i; int x, pixy; @@ -1182,7 +1186,7 @@ vga_WriteChar(uint32 chr, int col, int row, int colour) else bgcolor = CLR_BLACK; - if (inversed) { + if (inverse) { int tmpc = actual_colour; actual_colour = bgcolor; bgcolor = tmpc; @@ -1346,7 +1350,7 @@ vga_WriteStr(char *s, int len, int col, int row, int colour) i = 0; us = (unsigned char *) s; while ((*us != 0) && (i < len) && (col < (CO - 1))) { - vga_WriteChar((uchar) *us, col, row, colour); + vga_WriteChar((uchar) *us, col, row, colour, FALSE); ++us; ++i; ++col; From 15cfe90d621b805a1d16295c1cde37797fdca9ad Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 6 Aug 2026 10:05:27 -0400 Subject: [PATCH 578/702] follow-up: build with Qt6 support on Linux with Qt 6.1 1d3178a quieted the g++ build, but made the warnings even worse with a clang build. The addition of the -Wno-sfinae-incomplete caused an unrecognized option warning using recent clang. Recent clang build with Qt6.1 also caused several warnings during the processing of the Qt6.1 header files related to c++26-extensions. This adds (under Linux) -Wnoc++-26-extensions to the clang++ command line to quiet those warnings and restricts the -Wno-sfinae-incomplete command line option to the g++ build. --- sys/unix/hints/include/compiler.500 | 9 ++++++--- sys/unix/hints/linux.500 | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/sys/unix/hints/include/compiler.500 b/sys/unix/hints/include/compiler.500 index 59c6e29ef..e0f5eb466 100755 --- a/sys/unix/hints/include/compiler.500 +++ b/sys/unix/hints/include/compiler.500 @@ -138,9 +138,6 @@ CCXXFLAGS+=-Wall -Wextra -Wno-missing-field-initializers \ -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings CCXXFLAGS+=-pedantic CCXXFLAGS+=-Wmissing-declarations -ifdef ADDITIONAL_NO_WARN -CCXXFLAGS+=$(ADDITIONAL_NO_WARN) -endif #detection of clang++ vs g++ CXXISCLANG := $(shell echo `$(CXX) --version` | grep clang) ifeq "$(CXXISCLANG)" "" @@ -179,6 +176,9 @@ else # g++ version greater than or equal to 9? (no follows) CCXX=g++ -std=c++17 endif # g++ version greater than or equal to 9 endif # CPLUSPLUS_NEED20 +ifdef ADDITIONAL_NO_WARN_GPPCCX +CCXXFLAGS+=$(ADDITIONAL_NO_WARN_GPPCCX) +endif else # g++ or clang++ ? @@ -219,6 +219,9 @@ ifeq "$(CLANGPPGTEQ17)" "1" CCXX=clang++ -std=c++20 endif # clang++ greater than or equal to 17 endif # CPLUSPLUS_NEED20 +ifdef ADDITIONAL_NO_WARN_CLANGCCX +CCXXFLAGS+=$(ADDITIONAL_NO_WARN_CLANGCCX) +endif endif # end of clang++-specific section CXX=$(CCXX) endif # CPLUSPLUS_NEEDED diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index fc9192516..c786f4f62 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -77,7 +77,8 @@ USE_NOSTATICFN = 1 #QT6 prior to compiler include ifdef WANT_WIN_QT6 CPLUSPLUS_NEED20=1 -ADDITIONAL_NO_WARN=-Wno-sfinae-incomplete +ADDITIONAL_NO_WARN_GPPCCX=-Wno-sfinae-incomplete +ADDITIONAL_NO_WARN_CLANGCCX=-Wno-c++26-extensions endif # WANT_WIN_QT6 # compiler.500 contains compiler detection and adjustments common From c3ce34143489ee9b9004279d5f121eaaecbddc68 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 6 Aug 2026 10:22:24 -0400 Subject: [PATCH 579/702] Re: "Key binding failed?!--More--"; Strcat to an empty character buffer, causing garbage This is intended to resolve GitHub Issue #1650, which I was unable to directly reproduce on my test system. This fix assumes that the reported issue was related to cmdstr[BUFSZ] buffer not getting initialized, thus containing random memory values. --- src/cmd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cmd.c b/src/cmd.c index 6f67db776..efa0288a6 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -2355,6 +2355,7 @@ handler_rebind_keys_add(boolean keyfirst) struct Cmd_bind *prevcmd; char cmdstr[BUFSZ]; + cmdstr[0] = '\0'; i = picks->item.a_int; free((genericptr_t) picks); From 411c8becb99f28d832c84c336c9ee4a10e426311 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 6 Aug 2026 10:35:46 -0400 Subject: [PATCH 580/702] follow-up scope of cmdstr --- src/cmd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cmd.c b/src/cmd.c index efa0288a6..cd77a6727 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -2299,7 +2299,9 @@ handler_rebind_keys_add(boolean keyfirst) char buf2[QBUFSZ]; uchar key = '\0'; int clr = NO_COLOR; + char cmdstr[BUFSZ]; + cmdstr[0] = '\0'; if (keyfirst) { pline("Bind which key? "); key = pgetchar(); @@ -2353,9 +2355,7 @@ handler_rebind_keys_add(boolean keyfirst) destroy_nhwindow(win); if (npick > 0) { struct Cmd_bind *prevcmd; - char cmdstr[BUFSZ]; - cmdstr[0] = '\0'; i = picks->item.a_int; free((genericptr_t) picks); From cd493962b1f7273d906bfca790a5c5d3cd3a5e64 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 7 Aug 2026 08:46:53 -0400 Subject: [PATCH 581/702] don't catch thrown objects while asleep Reported directly to devteam. --- src/mthrowu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mthrowu.c b/src/mthrowu.c index aea7a29ec..d54989c88 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -535,7 +535,7 @@ u_catch_thrown_obj(struct obj *otmp) int catch_chance = 100 - ACURR(A_DEX) - ((Role_if(PM_MONK) || Role_if(PM_ROGUE)) ? 20 : 0); - if (!Blind && !Confusion && !Stunned && !Fumbling + if (!Blind && !Confusion && !Stunned && !Fumbling && !Unaware && otmp->oclass != VENOM_CLASS && !nohands(gy.youmonst.data) && freehand() && calc_capacity(otmp->owt) <= SLT_ENCUMBER && !rn2(catch_chance)) { From c2b4ee53e59120f6e98c42e60d24b76b69666377 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Fri, 7 Aug 2026 10:41:43 -0400 Subject: [PATCH 582/702] Begin reimplemented TTY-style status --- win/X11/winstat.c | 291 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 287 insertions(+), 4 deletions(-) diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 1028ec2ad..29cde2327 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -98,6 +98,7 @@ static int condcolor(long, unsigned long *); static int condattr(long, unsigned long *); +#if 0 /*RLC*/ static void HiliteField(Widget, int, int, int, XFontStruct **); static void PrepStatusField(int, Widget, const char *); static void DisplayCond(int, unsigned long *); @@ -107,6 +108,7 @@ static void tt_reset_color(int, int, unsigned long *); #endif static void tt_status_fixup(void); static Widget create_tty_status_field(int, int, Widget, Widget); +#endif /*RLC*/ static Widget create_tty_status(Widget, Widget); static void stat_resized(Widget, XtPointer, XtPointer); static void update_fancy_status_field(int, int, int); @@ -119,6 +121,9 @@ static void destroy_status_window_fancy(struct xwindow *); static void destroy_status_window_tty(struct xwindow *); static void adjust_status_fancy(struct xwindow *, const char *); static void adjust_status_tty(struct xwindow *, const char *); +static void tty_status_exposed(Widget, XtPointer, XtPointer); +static void tty_status_redraw(Widget); +static int tty_render_text(Widget, int, int, const char *, int, int, boolean); extern const char *status_fieldfmt[MAXBLSTATS]; extern char *status_vals[MAXBLSTATS]; @@ -131,7 +136,9 @@ static int X11_status_colors[MAXBLSTATS], static int hpbar_percent, hpbar_color; /* Number of conditions displayed during this update and last update. When the last update had more, the excess need to be erased. */ +#if 0 /*RLC*/ static int next_cond_indx = 0, prev_cond_indx = 0; +#endif /*RLC*/ /* TODO: support statuslines:3 in addition to 2 for the tty-style status */ #define X11_NUM_STATUS_LINES 2 @@ -191,11 +198,26 @@ static const char *const fancy_status_hilite_colors[] = { "white", }; +struct tty_status_field { + char *text; + int color; + int chg; + int percent; +}; + +struct tty_cond_field { + const char *text; + int color; + unsigned attrs; +}; + static Widget X11_status_widget; -static Widget X11_status_labels[MAXBLSTATS]; -static Widget X11_cond_labels[32]; /* Ugh */ +static struct tty_status_field X11_status_labels[MAXBLSTATS]; +static struct tty_cond_field X11_cond_labels[32]; /* Ugh */ +#if 0 /*RLC*/ static XFontStruct *X11_status_font; static Pixel X11_status_fg, X11_status_bg; +#endif /*RLC*/ struct xwindow *xw_status_win; @@ -274,6 +296,11 @@ void X11_status_enablefield(int fieldidx, const char *nm, const char *fmt, boolean enable) { + if (X11_status_widget && !enable && 0 <= fieldidx && fieldidx < MAXBLSTATS) { + free(X11_status_labels[fieldidx].text); + X11_status_labels[fieldidx].text = NULL; + tty_status_redraw(X11_status_widget); + } genl_status_enablefield(fieldidx, nm, fmt, enable); } @@ -290,6 +317,7 @@ cond_bm2idx(unsigned long bm) } #endif +#if 0 /*RLC*/ /* highlight a tty-style status field (or condition) */ static void HiliteField(Widget label, @@ -650,6 +678,7 @@ tt_status_fixup(void) XtGetValues(xw_status_win->w, args, ONE); } } +#endif /*RLC*/ DISABLE_WARNING_FORMAT_NONLITERAL @@ -659,11 +688,65 @@ static void X11_status_update_tty( int fld, genericptr_t ptr, - int chg UNUSED, + int chg, int percent, int color, unsigned long *colormasks) /* bitmask of highlights for conditions */ { + printf("fld=%d\n", fld); fflush(stdout); + switch (fld) { + case BL_RESET: + case BL_FLUSH: + tty_status_redraw(X11_status_widget); + break; + + case BL_CONDITION: + { + unsigned long cond = *(unsigned long const *)ptr; + for (unsigned j = 0; j < SIZE(tt_condorder); ++j) { + struct tty_cond_field *fldp = &X11_cond_labels[j]; + fldp->color = NO_COLOR; + fldp->attrs = 0; + if ((cond & tt_condorder[j].mask) != 0) { + fldp->text = tt_condorder[j].text; + } else { + fldp->text = NULL; + } + } + for (unsigned i = 0; i < CLR_MAX; ++i) { + unsigned long mask = colormasks[i]; + for (unsigned j = 0; j < SIZE(tt_condorder); ++j) { + if ((mask & tt_condorder[j].mask) != 0) { + struct tty_cond_field *fldp = &X11_cond_labels[j]; + fldp->color = i; + } + } + } + for (unsigned i = CLR_MAX; i < BL_ATTCLR_MAX; ++i) { + unsigned long mask = colormasks[i]; + for (unsigned j = 0; j < SIZE(tt_condorder); ++j) { + if ((mask & tt_condorder[j].mask) != 0) { + struct tty_cond_field *fldp = &X11_cond_labels[j]; + fldp->attrs |= 0x1 << (i - CLR_MAX); + } + } + } + } + break; + + default: + if (0 <= fld && fld < SIZE(X11_status_labels)) { + struct tty_status_field *fldp = &X11_status_labels[fld]; + const char *str = (const char *) ptr; + free(fldp->text); + fldp->text = dupstr(str); + fldp->chg = chg; + fldp->percent = percent; + fldp->color = color; + } + break; + } +#if 0 /*RLC*/ static int xtra_space[MAXBLSTATS]; static unsigned long *cond_colormasks = (unsigned long *) 0; @@ -832,6 +915,7 @@ X11_status_update_tty( /* this probably doesn't buy us anything but it isn't a sure thing that nethack will immediately ask for input (triggering auto-flush) */ (void) XFlush(XtDisplay(X11_status_labels[0])); +#endif /*RLC*/ } RESTORE_WARNING_FORMAT_NONLITERAL @@ -951,6 +1035,7 @@ X11_status_update( X11_status_update_tty(fld, ptr, chg, percent, color, colormasks); } +#if 0 /*RLC*/ /* create a widget for a particular status field or potential condition */ static Widget create_tty_status_field(int fld, int condindx, Widget above, Widget left) @@ -991,6 +1076,7 @@ create_tty_status_field(int fld, int condindx, Widget above, Widget left) return XtCreateManagedWidget(labelname, labelWidgetClass, X11_status_widget, args, num_args); } +#endif /*RLC*/ /* create an overall status widget (X11_status_widget) and also separate widgets for all status fields and potential conditions */ @@ -998,10 +1084,14 @@ static Widget create_tty_status(Widget parent, Widget top) { Widget form; /* viewport that holds the form that surrounds everything */ +#if 0 /*RLC*/ Widget w, over_w, prev_w; +#endif /*RLC*/ Arg args[6]; Cardinal num_args; +#if 0 /*RLC*/ int x, y, i, fld; +#endif /*RLC*/ (void) memset((genericptr_t) args, 0, sizeof args); num_args = 0; @@ -1019,9 +1109,13 @@ create_tty_status(Widget parent, Widget top) num_args = 0; XtSetArg(args[num_args], XtNwidth, 400); num_args++; XtSetArg(args[num_args], XtNheight, 100); num_args++; - X11_status_widget = XtCreateManagedWidget("status_form", formWidgetClass, + X11_status_widget = XtCreateManagedWidget("status_form", windowWidgetClass, form, args, num_args); + XtAddCallback(X11_status_widget, XtNexposeCallback, tty_status_exposed, + (XtPointer) 0); + +#if 0 /*RLC*/ for (y = 0; y < X11_NUM_STATUS_LINES; y++) { fld = (y > 0) ? X11_fieldorder[y - 1][0] : 0; /* temp, for over_w */ /* for row(s) beyond the first, pick a widget in the previous @@ -1045,9 +1139,198 @@ create_tty_status(Widget parent, Widget top) } } } +#endif /*RLC*/ return X11_status_widget; } +/* + * TTY status window expose callback. + */ +/*ARGSUSED*/ +static void +tty_status_exposed(Widget w, XtPointer client_data, /* unused */ + XtPointer widget_data) /* expose event from Window widget */ +{ + tty_status_redraw(w); + nhUse(client_data); + nhUse(widget_data); +} + +static void +tty_status_redraw(Widget w) +{ + static struct stat_fmt { + const char *pre; + const char *post; + } formats[MAXBLSTATS] = { + /*@@@*/[BL_TITLE] = { NULL, NULL }, + /*@@@*/[BL_STR] = { "St:", NULL }, + /*@@@*/[BL_DX] = { "Dx:", NULL }, + /*@@@*/[BL_CO] = { "Co:", NULL }, + /*@@@*/[BL_IN] = { "In:", NULL }, + /*@@@*/[BL_WI] = { "Wi:", NULL }, + /*@@@*/[BL_CH] = { "Ch:", NULL }, + /*@@@*/[BL_ALIGN] = { NULL, NULL }, + /*@@@*/[BL_SCORE] = { "S:", NULL }, + /*@@@*/[BL_CAP] = { NULL, NULL }, + /*@@@*/[BL_GOLD] = { NULL, NULL }, + /*@@@*/[BL_ENE] = { "Pw:", NULL }, + /*@@@*/[BL_ENEMAX] = { "(", ")" }, + /*@@@*/[BL_XP] = { "Xp:", NULL }, + /*@@@*/[BL_AC] = { "AC:", NULL }, + /*@@@*/[BL_HD] = { "HD:", NULL }, + /*@@@*/[BL_TIME] = { "T:", NULL }, + /*@@@*/[BL_HUNGER] = { NULL, NULL }, + /*@@@*/[BL_HP] = { "HP:", NULL }, + /*@@@*/[BL_HPMAX] = { "(", ")" }, + /*@@@*/[BL_LEVELDESC] = { NULL, NULL }, + /*@@@*/[BL_EXP] = { "/", NULL }, + /*@@@*/[BL_CONDITION] = { NULL, NULL }, + [BL_WEAPON] = { NULL, NULL }, /* not in 2-line */ + [BL_ARMOR] = { NULL, NULL }, /* not in 2-line */ + [BL_TERRAIN] = { NULL, NULL }, /* not in 2-line */ + /*@@@*/[BL_VERS] = { NULL, NULL }, + }; + Arg args[5]; + int num_args; + XFontStruct *font; + Dimension width; + + /* Get the height of the font and the width of the widget */ + num_args = 0; + XtSetArg(args[num_args], XtNfont, &font); num_args++; + XtSetArg(args[num_args], XtNwidth, &width); num_args++; + XtGetValues(w, args, num_args); + int height = font->max_bounds.ascent + font->max_bounds.descent; + + int x = 0; + int y = 0; + XClearWindow(XtDisplay(w), XtWindow(w)); + for (unsigned row = 0; row < X11_NUM_STATUS_LINES; ++row) { + for (unsigned i = 0; i < X11_NUM_STATUS_FIELD; ++i) { + enum statusfields fld = X11_fieldorder[row][i]; + switch (fld) { + case BL_FLUSH: + break; + + case BL_CONDITION: + for (unsigned j = 0; j < SIZE(X11_cond_labels); ++j) { + struct tty_cond_field const *fldp = &X11_cond_labels[j]; + if (fldp->text != NULL) { + x += tty_render_text(w, x, y, " ", NO_COLOR, 0, FALSE); + x += tty_render_text(w, x, y, fldp->text, fldp->color, fldp->attrs, FALSE); + } + } + break; + + default: + { + struct tty_status_field const *fldp = &X11_status_labels[fld]; + if (fldp->text != NULL && fldp->text[0] != '\0') { + if (x != 0 && (formats[fld].pre == NULL || strchr("(/", formats[fld].pre[0]) == NULL)) { + x += tty_render_text(w, x, y, " ", NO_COLOR, 0, FALSE); + } + if (formats[fld].pre != NULL) { + x += tty_render_text(w, x, y, formats[fld].pre, NO_COLOR, 0, FALSE); + } + x += tty_render_text(w, x, y, fldp->text, fldp->color, + fldp->chg ? HL_INVERSE : 0, fld == BL_GOLD); + if (formats[fld].post != NULL) { + x += tty_render_text(w, x, y, formats[fld].post, NO_COLOR, 0, FALSE); + } + /* @@@TODO: do the percent field */ + } + } + break; + } + } + x = 0; + y += height; + } +} + +/* Render text as part of the TTY status */ +static int +tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, + boolean is_gold) +{ + Arg args[5]; + Cardinal num_args; + XGCValues values; + Pixel fgpixel, bgpixel; + XFontStruct *font; + int goldwidth = 0; +#ifdef ENHANCED_SYMBOLS + XFontStruct *unifont = NULL; +#endif + + /* Get default foreground and background colors, and font */ + num_args = 0; + XtSetArg(args[num_args], XtNforeground, &fgpixel); num_args++; + XtSetArg(args[num_args], XtNbackground, &bgpixel); num_args++; + XtSetArg(args[num_args], XtNfont, &font); num_args++; + XtGetValues(w, args, num_args); + + /* Get a graphics context */ + if (attr & HL_INVERSE) { + values.foreground = bgpixel; + values.background = fgpixel; + } else { + values.foreground = fgpixel; + values.background = bgpixel; + } + values.font = font->fid; + values.function = GXcopy; + GC ggc = XtGetGC(w, + GCFunction | GCForeground | GCBackground | GCFont, + &values); + + /* Gold will begin with a glyph string. Convert this to the proper + character, which might possibly be Unicode */ + if (is_gold && memcmp(text, "\\G", 2) == 0) { + char *end; + unsigned long glyphcode = strtoul(text+2, &end, 16); + if ((glyphcode >> 16) == svc.context.rndencode && *end == ':') { + /* We have a proper glyph code */ + glyph_info glyphinfo; + glyphcode &= 0xFFFF; + map_glyphinfo(0, 0, glyphcode, 0, &glyphinfo); + { + char goldstr[2]; + goldstr[0] = glyphinfo.ttychar; + goldstr[1] = 0; + goldwidth = XTextWidth(font, goldstr, strlen(goldstr)); + + /* Render the string */ + XDrawImageString(XtDisplay(w), XtWindow(w), ggc, + x, y + font->max_bounds.ascent, + goldstr, strlen(goldstr)); + } + + text = end; + } + } + + /* Get the width of the rendered string */ + int width = XTextWidth(font, text, strlen(text)); + + /* Render the string */ + XDrawImageString(XtDisplay(w), XtWindow(w), ggc, + x + goldwidth, y + font->max_bounds.ascent, + text, strlen(text)); + + /* Release resources */ + XtReleaseGC(w, ggc); +#ifdef ENHANCED_SYMBOLS + if (unifont != NULL) { + XFreeFont(XtDisplay(w), unifont); + } +#endif + + /* Caller will advance x by the width */ + return goldwidth + width; +} + /*ARGSUSED*/ void create_status_window_tty(struct xwindow *wp, /* window pointer */ From 725bb3d05fd41acb0941139d71d77bbec244312d Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Fri, 7 Aug 2026 11:21:11 -0400 Subject: [PATCH 583/702] Display gold symbol as Unicode if so configured Some Unicode bits from winmap.c are moved to winX.c, so that winstat.c can also use them. --- include/winX.h | 4 ++ win/X11/winX.c | 122 +++++++++++++++++++++++++++++++++++++++++++++ win/X11/winmap.c | 124 ++-------------------------------------------- win/X11/winstat.c | 52 +++++++++++++------ 4 files changed, 167 insertions(+), 135 deletions(-) diff --git a/include/winX.h b/include/winX.h index f408aee04..9cc55e09a 100644 --- a/include/winX.h +++ b/include/winX.h @@ -513,5 +513,9 @@ extern void genl_outrip(winid, int, time_t); extern void X11_preference_update(const char *); extern void X11_update_inventory(int); extern win_request_info *X11_ctrl_nhwindow(winid, int, win_request_info *); +extern X11_map_symbol X11_glyph_char(const glyph_info *); +#ifdef ENHANCED_SYMBOLS +extern XFontStruct *X11_unicode_font(Display *, XFontStruct *); +#endif #endif /* WINX_H */ diff --git a/win/X11/winX.c b/win/X11/winX.c index 59cbb933e..28d3e4da5 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -2925,4 +2925,126 @@ nh_keyscroll(Widget viewport, XEvent *event, String *params, } } +/* Convert CP437 or DECgraphics to Unicode */ +X11_map_symbol +X11_glyph_char(const glyph_info *glyphinfo) +{ +#ifdef ENHANCED_SYMBOLS + /* CP437 to Unicode mapping according to the Unicode Consortium */ + static const uint16 cp437[256] = { + 0x0020, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, + 0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C, + 0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8, + 0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 + }; + /* Display DECgraphics as Unicode */ + static const uint16 decgraphics[128] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x2192, 0x2190, 0x2191, 0x2193, 0x002F, + 0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x2666, 0x2592, 0x0062, 0x0063, 0x0064, 0x0065, 0x00B0, 0x00B1, + 0x2591, 0x00A4, 0x2518, 0x2510, 0x250C, 0x2514, 0x253C, 0x23BA, + 0x23BB, 0x2500, 0x23BC, 0x23BD, 0x251C, 0x2524, 0x2534, 0x252C, + 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00B7, 0x007F + }; + X11_map_symbol och; + + if (SYMHANDLING(H_UTF8) && glyphinfo->gm.u != NULL && glyphinfo->gm.u->utf8str != NULL) { + och = glyphinfo->gm.u->utf32ch; + } else { + och = (uchar) glyphinfo->ttychar; + if (SYMHANDLING(H_IBM)) { + och = cp437[och]; + } else if ((SYMHANDLING(H_DEC) || SYMHANDLING(H_CURS)) && och >= 0x80) { + och = decgraphics[och & 0x7F]; + } + } + + return och; +#else + return (char) glyphinfo->ttychar; +#endif +} + +#ifdef ENHANCED_SYMBOLS +/* Given an XFontStruct, return a corresponding font that supports Unicode */ +XFontStruct * +X11_unicode_font(Display *display, XFontStruct *font) +{ + Atom font_atom; + if (!XGetFontProperty(font, XA_FONT, &font_atom)) { + return NULL; + } + + const char *font_name = XGetAtomName(display, font_atom); + if (font_name == NULL) { + return NULL; + } + + /* Proceed to the registry name */ + unsigned dashes = 13; + const char *p = font_name; + while (dashes != 0) { + const char *q = strchr(p, '-'); + if (q == NULL) { + break; + } + p = q + 1; + --dashes; + } + + /* Substitute "iso10646-1" for the registry name and encoding */ + size_t len = (size_t) (p - font_name); + char unicode_font[BUFSZ]; + if (dashes != 0 || len + 11 > sizeof(unicode_font)) { + return NULL; + } + + memcpy(unicode_font, font_name, len); + strcpy(unicode_font + len, "iso10646-1"); + font_name = unicode_font; + + Font font_id = XLoadFont(display, font_name); + XFontStruct *unifont = XQueryFont(display, font_id); + return unifont; +} +#endif /* ENHANCED_SYMBOLS */ + /*winX.c*/ diff --git a/win/X11/winmap.c b/win/X11/winmap.c index 1ee30626e..a99ebef5a 100644 --- a/win/X11/winmap.c +++ b/win/X11/winmap.c @@ -59,7 +59,6 @@ extern int total_tiles_used, Tile_corr; #define NH_INVERSE_COLOR 0x40000000 #define NH_ENHANCED_COLOR 0x80000000 -static X11_map_symbol glyph_char(const glyph_info *glyphinfo); static GC X11_make_gc(struct xwindow *wp, struct text_map_info_t *text_map, X11_color color, boolean inverted); #ifdef ENHANCED_SYMBOLS @@ -136,7 +135,7 @@ X11_print_glyph( color = glyphinfo->gm.sym.color; special = glyphinfo->gm.glyphflags; - ch = glyph_char(glyphinfo); + ch = X11_glyph_char(glyphinfo); if (glyphinfo->gm.customcolor != 0) { if ((glyphinfo->gm.customcolor & NH_BASIC_COLOR) != 0) { @@ -196,83 +195,6 @@ X11_print_glyph( } } -static X11_map_symbol -glyph_char(const glyph_info *glyphinfo) -{ -#ifdef ENHANCED_SYMBOLS - /* CP437 to Unicode mapping according to the Unicode Consortium */ - static const uint16 cp437[256] = { - 0x0020, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, - 0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C, - 0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8, - 0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, - 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, - 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, - 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, - 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, - 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302, - 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, - 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, - 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, - 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, - 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, - 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, - 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, - 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, - 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, - 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, - 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, - 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, - 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, - 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, - 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 - }; - /* Display DECgraphics as Unicode */ - static const uint16 decgraphics[128] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, - 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, - 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, - 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, - 0x0028, 0x0029, 0x002A, 0x2192, 0x2190, 0x2191, 0x2193, 0x002F, - 0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, - 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, - 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, - 0x2666, 0x2592, 0x0062, 0x0063, 0x0064, 0x0065, 0x00B0, 0x00B1, - 0x2591, 0x00A4, 0x2518, 0x2510, 0x250C, 0x2514, 0x253C, 0x23BA, - 0x23BB, 0x2500, 0x23BC, 0x23BD, 0x251C, 0x2524, 0x2534, 0x252C, - 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00B7, 0x007F - }; - X11_map_symbol och; - - if (SYMHANDLING(H_UTF8) && glyphinfo->gm.u != NULL && glyphinfo->gm.u->utf8str != NULL) { - och = glyphinfo->gm.u->utf32ch; - } else { - och = (uchar) glyphinfo->ttychar; - if (SYMHANDLING(H_IBM)) { - och = cp437[och]; - } else if ((SYMHANDLING(H_DEC) || SYMHANDLING(H_CURS)) && och >= 0x80) { - och = decgraphics[och & 0x7F]; - } - } - - return och; -#else - return (char) glyphinfo->ttychar; -#endif -} - #ifdef CLIPPING /* * The is the tty clip call. Since X can resize at any time, we can't depend @@ -1806,50 +1728,14 @@ X11_set_map_font(struct xwindow *wp) { struct map_info_t *map_info = wp->map_information; XFontStruct *fs; - Atom font_atom; - const char *font_name; - unsigned dashes; - const char *p; - size_t len; - char unicode_font[BUFSZ]; - Font font_id; /* Query the configured font for the map */ fs = WindowFontStruct(wp->w); - map_info->text_map.font = fs; - if (!XGetFontProperty(fs, XA_FONT, &font_atom)) { - return; - } - font_name = XGetAtomName(XtDisplay(wp->w), font_atom); - if (font_name == NULL) { - return; - } - /* Proceed to the registry name */ - dashes = 13; - p = font_name; - while (dashes != 0) { - const char *q = strchr(p, '-'); - if (q == NULL) { - break; - } - p = q + 1; - --dashes; - } - - /* Substitute "iso10646-1" for the registry name and encoding */ - len = (size_t) (p - font_name); - if (dashes != 0 || len + 11 > sizeof(unicode_font)) { - return; - } - - memcpy(unicode_font, font_name, len); - strcpy(unicode_font + len, "iso10646-1"); - font_name = unicode_font; - - font_id = XLoadFont(XtDisplay(wp->w), font_name); - map_info->text_map.font = XQueryFont(XtDisplay(wp->w), font_id); - if (map_info->text_map.font == NULL) { + XFontStruct *unifont = X11_unicode_font(XtDisplay(wp->w), fs); + if (unifont != NULL) { + map_info->text_map.font = unifont; + } else { /* Fallback in case no iso10646 */ map_info->text_map.font = fs; } diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 29cde2327..ea464a329 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -693,7 +693,6 @@ X11_status_update_tty( int color, unsigned long *colormasks) /* bitmask of highlights for conditions */ { - printf("fld=%d\n", fld); fflush(stdout); switch (fld) { case BL_RESET: case BL_FLUSH: @@ -1260,9 +1259,6 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, Pixel fgpixel, bgpixel; XFontStruct *font; int goldwidth = 0; -#ifdef ENHANCED_SYMBOLS - XFontStruct *unifont = NULL; -#endif /* Get default foreground and background colors, and font */ num_args = 0; @@ -1290,21 +1286,50 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, if (is_gold && memcmp(text, "\\G", 2) == 0) { char *end; unsigned long glyphcode = strtoul(text+2, &end, 16); - if ((glyphcode >> 16) == svc.context.rndencode && *end == ':') { + if ((glyphcode >> 16) == (unsigned) svc.context.rndencode && *end == ':') { /* We have a proper glyph code */ glyph_info glyphinfo; glyphcode &= 0xFFFF; map_glyphinfo(0, 0, glyphcode, 0, &glyphinfo); - { - char goldstr[2]; - goldstr[0] = glyphinfo.ttychar; - goldstr[1] = 0; - goldwidth = XTextWidth(font, goldstr, strlen(goldstr)); + X11_map_symbol goldsym = X11_glyph_char(&glyphinfo); +#ifdef ENHANCED_SYMBOLS + if (goldsym > 0xFFFF) { + /* No support for supplementary planes */ + goldsym = GOLD_SYM; + } + if (goldsym > 0x7F) { + XFontStruct *unifont = X11_unicode_font(XtDisplay(w), font); + + if (unifont != NULL) { + XChar2b goldstr[1]; + values.font = unifont->fid; + GC ggc2 = XtGetGC(w, + GCFunction | GCForeground | GCBackground | GCFont, + &values); + + goldstr[0].byte1 = goldsym >> 8; + goldstr[0].byte2 = goldsym & 0xFF; + goldwidth = XTextWidth16(font, goldstr, 1); + + /* Render the string */ + XDrawImageString16(XtDisplay(w), XtWindow(w), ggc, + x, y + font->max_bounds.ascent, + goldstr, 1); + + XFreeFont(XtDisplay(w), unifont); + XtReleaseGC(w, ggc2); + } + } +#endif + if (goldwidth == 0) { + char goldstr[1]; + goldstr[0] = (char) goldsym; + goldwidth = XTextWidth(font, goldstr, 1); /* Render the string */ XDrawImageString(XtDisplay(w), XtWindow(w), ggc, x, y + font->max_bounds.ascent, - goldstr, strlen(goldstr)); + goldstr, 1); } text = end; @@ -1321,11 +1346,6 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, /* Release resources */ XtReleaseGC(w, ggc); -#ifdef ENHANCED_SYMBOLS - if (unifont != NULL) { - XFreeFont(XtDisplay(w), unifont); - } -#endif /* Caller will advance x by the width */ return goldwidth + width; From 5dd16736789b7163de2ace8915cd83d6836be21a Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Fri, 7 Aug 2026 11:54:07 -0400 Subject: [PATCH 584/702] Implement colors --- win/X11/winstat.c | 68 +++++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/win/X11/winstat.c b/win/X11/winstat.c index ea464a329..4168bf88a 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -201,6 +201,7 @@ static const char *const fancy_status_hilite_colors[] = { struct tty_status_field { char *text; int color; + unsigned attrs; int chg; int percent; }; @@ -741,7 +742,8 @@ X11_status_update_tty( fldp->text = dupstr(str); fldp->chg = chg; fldp->percent = percent; - fldp->color = color; + fldp->color = color & 0xFF; + fldp->attrs = color >> 8; } break; } @@ -1162,33 +1164,33 @@ tty_status_redraw(Widget w) const char *pre; const char *post; } formats[MAXBLSTATS] = { - /*@@@*/[BL_TITLE] = { NULL, NULL }, - /*@@@*/[BL_STR] = { "St:", NULL }, - /*@@@*/[BL_DX] = { "Dx:", NULL }, - /*@@@*/[BL_CO] = { "Co:", NULL }, - /*@@@*/[BL_IN] = { "In:", NULL }, - /*@@@*/[BL_WI] = { "Wi:", NULL }, - /*@@@*/[BL_CH] = { "Ch:", NULL }, - /*@@@*/[BL_ALIGN] = { NULL, NULL }, - /*@@@*/[BL_SCORE] = { "S:", NULL }, - /*@@@*/[BL_CAP] = { NULL, NULL }, - /*@@@*/[BL_GOLD] = { NULL, NULL }, - /*@@@*/[BL_ENE] = { "Pw:", NULL }, - /*@@@*/[BL_ENEMAX] = { "(", ")" }, - /*@@@*/[BL_XP] = { "Xp:", NULL }, - /*@@@*/[BL_AC] = { "AC:", NULL }, - /*@@@*/[BL_HD] = { "HD:", NULL }, - /*@@@*/[BL_TIME] = { "T:", NULL }, - /*@@@*/[BL_HUNGER] = { NULL, NULL }, - /*@@@*/[BL_HP] = { "HP:", NULL }, - /*@@@*/[BL_HPMAX] = { "(", ")" }, - /*@@@*/[BL_LEVELDESC] = { NULL, NULL }, - /*@@@*/[BL_EXP] = { "/", NULL }, - /*@@@*/[BL_CONDITION] = { NULL, NULL }, + [BL_TITLE] = { NULL, NULL }, + [BL_STR] = { "St:", NULL }, + [BL_DX] = { "Dx:", NULL }, + [BL_CO] = { "Co:", NULL }, + [BL_IN] = { "In:", NULL }, + [BL_WI] = { "Wi:", NULL }, + [BL_CH] = { "Ch:", NULL }, + [BL_ALIGN] = { NULL, NULL }, + [BL_SCORE] = { "S:", NULL }, + [BL_CAP] = { NULL, NULL }, + [BL_GOLD] = { NULL, NULL }, + [BL_ENE] = { "Pw:", NULL }, + [BL_ENEMAX] = { "(", ")" }, + [BL_XP] = { "Xp:", NULL }, + [BL_AC] = { "AC:", NULL }, + [BL_HD] = { "HD:", NULL }, + [BL_TIME] = { "T:", NULL }, + [BL_HUNGER] = { NULL, NULL }, + [BL_HP] = { "HP:", NULL }, + [BL_HPMAX] = { "(", ")" }, + [BL_LEVELDESC] = { NULL, NULL }, + [BL_EXP] = { "/", NULL }, + [BL_CONDITION] = { NULL, NULL }, [BL_WEAPON] = { NULL, NULL }, /* not in 2-line */ [BL_ARMOR] = { NULL, NULL }, /* not in 2-line */ [BL_TERRAIN] = { NULL, NULL }, /* not in 2-line */ - /*@@@*/[BL_VERS] = { NULL, NULL }, + [BL_VERS] = { NULL, NULL }, }; Arg args[5]; int num_args; @@ -1233,7 +1235,7 @@ tty_status_redraw(Widget w) x += tty_render_text(w, x, y, formats[fld].pre, NO_COLOR, 0, FALSE); } x += tty_render_text(w, x, y, fldp->text, fldp->color, - fldp->chg ? HL_INVERSE : 0, fld == BL_GOLD); + fldp->attrs, fld == BL_GOLD); if (formats[fld].post != NULL) { x += tty_render_text(w, x, y, formats[fld].post, NO_COLOR, 0, FALSE); } @@ -1267,6 +1269,20 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, XtSetArg(args[num_args], XtNfont, &font); num_args++; XtGetValues(w, args, num_args); + /* Implement color if requested */ + if (color != NO_COLOR) { + XrmValue source; + XrmValue dest; + Pixel pixel; + const char *cname = fancy_status_hilite_colors[color]; + source.addr = (XPointer) cname; + source.size = (unsigned int) strlen(cname) + 1; + dest.size = (unsigned int) sizeof (Pixel); + dest.addr = (XPointer) &pixel; + if (XtConvertAndStore(w, XtRString, &source, XtRPixel, &dest)) + fgpixel = pixel; + } + /* Get a graphics context */ if (attr & HL_INVERSE) { values.foreground = bgpixel; From 647fd71a2debcd5f48a531b0932856b993a9863d Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Fri, 7 Aug 2026 13:19:50 -0400 Subject: [PATCH 585/702] Implement bold and dim attributes --- win/X11/winstat.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 4168bf88a..b5bdc1072 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -1283,6 +1283,19 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, fgpixel = pixel; } + /* Implement bold font */ + if (attr & HL_BOLD) { + struct xwindow *wp = find_widget(w); + load_boldfont(wp, w); + font = wp->boldfs; + } + + /* Implement dim text */ + if (attr & HL_DIM) { + fgpixel = (fgpixel & 0xFEFEFE) >> 1; + bgpixel = (bgpixel & 0xFEFEFE) >> 1; + } + /* Get a graphics context */ if (attr & HL_INVERSE) { values.foreground = bgpixel; From a7eb50fb3621e3b46602e054940fd7c5ba6673c9 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 8 Aug 2026 15:56:28 -0400 Subject: [PATCH 586/702] Query font for status window height --- win/X11/winX.c | 19 ++++++++++--------- win/X11/winstat.c | 10 +++++++--- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/win/X11/winX.c b/win/X11/winX.c index 28d3e4da5..1b3089e9e 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -749,27 +749,28 @@ nhFreePixel( Dimension nhFontHeight(Widget w) { + Arg args[1]; + XFontStruct *fs; + #ifdef _XawTextSink_h - Widget sink; + Widget sink = NULL; XawTextPosition pos = 0; int resWidth, resHeight; - Arg args[1]; XtSetArg(args[0], XtNtextSink, &sink); XtGetValues(w, args, 1); - XawTextSinkFindPosition(sink, pos, 0, 0, 0, &pos, &resWidth, &resHeight); - return resHeight; -#else - XFontStruct *fs; - Arg args[1]; + if (sink != NULL) { + XawTextSinkFindPosition(sink, pos, 0, 0, 0, &pos, &resWidth, &resHeight); + return resHeight; + } +#endif XtSetArg(args[0], XtNfont, &fs); XtGetValues(w, args, 1); /* Assume font height is ascent + descent. */ - return = fs->ascent + fs->descent; -#endif + return fs->ascent + fs->descent; } static String *default_resource_data = 0, /* NULL-terminated arrays */ diff --git a/win/X11/winstat.c b/win/X11/winstat.c index b5bdc1072..8d7f3230c 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -1113,6 +1113,12 @@ create_tty_status(Widget parent, Widget top) X11_status_widget = XtCreateManagedWidget("status_form", windowWidgetClass, form, args, num_args); + int height = nhFontHeight(X11_status_widget) * 3; + num_args = 0; + XtSetArg(args[num_args], XtNheight, height); num_args++; + XtSetValues(form, args, num_args); + XtSetValues(X11_status_widget, args, num_args); + XtAddCallback(X11_status_widget, XtNexposeCallback, tty_status_exposed, (XtPointer) 0); @@ -1194,15 +1200,13 @@ tty_status_redraw(Widget w) }; Arg args[5]; int num_args; - XFontStruct *font; Dimension width; /* Get the height of the font and the width of the widget */ num_args = 0; - XtSetArg(args[num_args], XtNfont, &font); num_args++; XtSetArg(args[num_args], XtNwidth, &width); num_args++; XtGetValues(w, args, num_args); - int height = font->max_bounds.ascent + font->max_bounds.descent; + int height = nhFontHeight(w); int x = 0; int y = 0; From 0f39437315f04841f4e804818dce8baa5c5f629f Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 8 Aug 2026 18:01:06 -0400 Subject: [PATCH 587/702] Implement underline and italic --- include/winX.h | 1 + win/X11/winX.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ win/X11/winstat.c | 24 ++++++++++++++++++++++-- 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/include/winX.h b/include/winX.h index 9cc55e09a..935fd5f5c 100644 --- a/include/winX.h +++ b/include/winX.h @@ -514,6 +514,7 @@ extern void X11_preference_update(const char *); extern void X11_update_inventory(int); extern win_request_info *X11_ctrl_nhwindow(winid, int, win_request_info *); extern X11_map_symbol X11_glyph_char(const glyph_info *); +extern XFontStruct *X11_italic_font(Display *, XFontStruct *); #ifdef ENHANCED_SYMBOLS extern XFontStruct *X11_unicode_font(Display *, XFontStruct *); #endif diff --git a/win/X11/winX.c b/win/X11/winX.c index 1b3089e9e..2abf03c20 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -3004,6 +3004,51 @@ X11_glyph_char(const glyph_info *glyphinfo) #endif } +/* Given an XFontStruct, return a corresponding italic font */ +XFontStruct * +X11_italic_font(Display *display, XFontStruct *font) +{ + Atom font_atom; + if (!XGetFontProperty(font, XA_FONT, &font_atom)) { + return NULL; + } + + const char *font_name = XGetAtomName(display, font_atom); + if (font_name == NULL) { + return NULL; + } + + /* Proceed to the slant */ + unsigned dashes = 4; + const char *p = font_name; + while (dashes != 0) { + const char *q = strchr(p, '-'); + if (q == NULL) { + break; + } + p = q + 1; + --dashes; + } + + /* Try substituting "i" for the slant */ + char italic_font[BUFSZ]; + int pre = (int)(p - font_name); + p += strcspn(p, "-"); + Snprintf(italic_font, sizeof(italic_font), "%.*sI%s", pre, font_name, p); + XFontStruct *font2 = XLoadQueryFont(display, italic_font); + printf("italic font=%p\n", (void *)font2); + if (font2 != NULL) { + return font2; + } + + /* Try substituting "o" */ + Snprintf(italic_font, sizeof(italic_font), "%.*sO%s", pre, font_name, p); + font2 = XLoadQueryFont(display, italic_font); + printf("oblique font=%p\n", (void *)font2); + + return font2; +} + #ifdef ENHANCED_SYMBOLS /* Given an XFontStruct, return a corresponding font that supports Unicode */ XFontStruct * diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 8d7f3230c..8d09f3ae2 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -1264,6 +1264,7 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, XGCValues values; Pixel fgpixel, bgpixel; XFontStruct *font; + XFontStruct *font_italic = NULL; /* custodial */ int goldwidth = 0; /* Get default foreground and background colors, and font */ @@ -1294,6 +1295,15 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, font = wp->boldfs; } + /* Implement italic font */ + if (attr & HL_ITALIC) { + /* font may also be bold */ + font_italic = X11_italic_font(XtDisplay(w), font); + if (font_italic != NULL) { + font = font_italic; + } + } + /* Implement dim text */ if (attr & HL_DIM) { fgpixel = (fgpixel & 0xFEFEFE) >> 1; @@ -1370,18 +1380,28 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, } /* Get the width of the rendered string */ - int width = XTextWidth(font, text, strlen(text)); + int width = XTextWidth(font, text, strlen(text)) + goldwidth; /* Render the string */ XDrawImageString(XtDisplay(w), XtWindow(w), ggc, x + goldwidth, y + font->max_bounds.ascent, text, strlen(text)); + /* Implement underline */ + if (attr & HL_ULINE) { + XDrawLine(XtDisplay(w), XtWindow(w), ggc, + x, y + font->max_bounds.ascent, + x + width - 1, y + font->max_bounds.ascent); + } + /* Release resources */ XtReleaseGC(w, ggc); + if (font_italic != NULL) { + XFreeFont(XtDisplay(w), font_italic); + } /* Caller will advance x by the width */ - return goldwidth + width; + return width; } /*ARGSUSED*/ From 8137f6cf3d1e89815e763f5690b43cf3903f9127 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 8 Aug 2026 18:01:33 -0400 Subject: [PATCH 588/702] Remove some debug code --- win/X11/winX.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/win/X11/winX.c b/win/X11/winX.c index 2abf03c20..2371fb76c 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -3036,7 +3036,6 @@ X11_italic_font(Display *display, XFontStruct *font) p += strcspn(p, "-"); Snprintf(italic_font, sizeof(italic_font), "%.*sI%s", pre, font_name, p); XFontStruct *font2 = XLoadQueryFont(display, italic_font); - printf("italic font=%p\n", (void *)font2); if (font2 != NULL) { return font2; } @@ -3044,7 +3043,6 @@ X11_italic_font(Display *display, XFontStruct *font) /* Try substituting "o" */ Snprintf(italic_font, sizeof(italic_font), "%.*sO%s", pre, font_name, p); font2 = XLoadQueryFont(display, italic_font); - printf("oblique font=%p\n", (void *)font2); return font2; } From 7521e7120a5e8516a1929d09f6706e131a09b852 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 8 Aug 2026 18:17:06 -0400 Subject: [PATCH 589/702] Implement blink --- win/X11/winstat.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 8d09f3ae2..7aee5fbb4 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -122,6 +122,7 @@ static void destroy_status_window_tty(struct xwindow *); static void adjust_status_fancy(struct xwindow *, const char *); static void adjust_status_tty(struct xwindow *, const char *); static void tty_status_exposed(Widget, XtPointer, XtPointer); +static void tty_status_blink(XtPointer client_data, XtIntervalId *timer); static void tty_status_redraw(Widget); static int tty_render_text(Widget, int, int, const char *, int, int, boolean); @@ -215,6 +216,8 @@ struct tty_cond_field { static Widget X11_status_widget; static struct tty_status_field X11_status_labels[MAXBLSTATS]; static struct tty_cond_field X11_cond_labels[32]; /* Ugh */ +static boolean blink; +static const unsigned long blink_interval = 500; /* milliseconds */ #if 0 /*RLC*/ static XFontStruct *X11_status_font; static Pixel X11_status_fg, X11_status_bg; @@ -1121,6 +1124,8 @@ create_tty_status(Widget parent, Widget top) XtAddCallback(X11_status_widget, XtNexposeCallback, tty_status_exposed, (XtPointer) 0); + XtAppAddTimeOut(app_context, blink_interval, tty_status_blink, + (XtPointer) X11_status_widget); #if 0 /*RLC*/ for (y = 0; y < X11_NUM_STATUS_LINES; y++) { @@ -1163,6 +1168,30 @@ tty_status_exposed(Widget w, XtPointer client_data, /* unused */ nhUse(widget_data); } +static void +tty_status_blink(XtPointer client_data, XtIntervalId *timer) +{ + Widget w = (Widget) client_data; + nhUse(timer); + + /* Do we have any active blink attributes? */ + boolean have_blink = FALSE; + for (unsigned i = 0; i < SIZE(X11_status_labels) && !have_blink; ++i) { + have_blink = (X11_status_labels[i].attrs & HL_BLINK) != 0; + } + for (unsigned i = 0; i < SIZE(X11_cond_labels) && !have_blink; ++i) { + have_blink = (X11_cond_labels[i].attrs & HL_BLINK) != 0; + } + + if (have_blink) { + tty_status_redraw(w); + blink = !blink; + } + + /* Do it again */ + XtAppAddTimeOut(app_context, blink_interval, tty_status_blink, client_data); +} + static void tty_status_redraw(Widget w) { @@ -1310,6 +1339,11 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, bgpixel = (bgpixel & 0xFEFEFE) >> 1; } + /* Implement blink */ + if ((attr & HL_BLINK) && blink) { + fgpixel = bgpixel; + } + /* Get a graphics context */ if (attr & HL_INVERSE) { values.foreground = bgpixel; From b763944fb4247650cbb94a5f370f42121871c94c Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 8 Aug 2026 18:59:09 -0400 Subject: [PATCH 590/702] Implement three line status --- win/X11/winX.c | 1 + win/X11/winstat.c | 171 +++++++++++++++++++++++++++++----------------- 2 files changed, 110 insertions(+), 62 deletions(-) diff --git a/win/X11/winX.c b/win/X11/winX.c index 2371fb76c..b009ab865 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -135,6 +135,7 @@ struct window_procs X11_procs = { #ifdef STATUS_HILITES | WC2_RESET_STATUS | WC2_HILITE_STATUS #endif + | WC2_EXTRASTATUS | WC2_MENU_SHIFT ), {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */ X11_init_nhwindows, diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 7aee5fbb4..aebd7e83a 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -124,7 +124,8 @@ static void adjust_status_tty(struct xwindow *, const char *); static void tty_status_exposed(Widget, XtPointer, XtPointer); static void tty_status_blink(XtPointer client_data, XtIntervalId *timer); static void tty_status_redraw(Widget); -static int tty_render_text(Widget, int, int, const char *, int, int, boolean); +static int tty_render_field(Widget, int, int, enum statusfields); +static int tty_render_text(Widget, int, int, const char *, int, int, enum statusfields); extern const char *status_fieldfmt[MAXBLSTATS]; extern char *status_vals[MAXBLSTATS]; @@ -141,17 +142,22 @@ static int hpbar_percent, hpbar_color; static int next_cond_indx = 0, prev_cond_indx = 0; #endif /*RLC*/ -/* TODO: support statuslines:3 in addition to 2 for the tty-style status */ -#define X11_NUM_STATUS_LINES 2 -#define X11_NUM_STATUS_FIELD 16 - -static enum statusfields X11_fieldorder[][X11_NUM_STATUS_FIELD] = { +static enum statusfields X11_fieldorder_2[][18] = { { BL_TITLE, BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH, BL_ALIGN, BL_SCORE, BL_FLUSH, BL_FLUSH, BL_FLUSH, BL_FLUSH, BL_FLUSH, - BL_FLUSH, BL_FLUSH }, + BL_FLUSH, BL_FLUSH, BL_FLUSH, BL_FLUSH }, { BL_LEVELDESC, BL_GOLD, BL_HP, BL_HPMAX, BL_ENE, BL_ENEMAX, - BL_AC, BL_XP, BL_EXP, BL_HD, BL_TIME, BL_HUNGER, - BL_CAP, BL_CONDITION, BL_VERS, BL_FLUSH } + BL_AC, BL_XP, BL_EXP, BL_HD, BL_TIME, BL_HUNGER, BL_CAP, + BL_CONDITION, BL_WEAPON, BL_ARMOR, BL_TERRAIN, BL_VERS } +}; + +static enum statusfields X11_fieldorder_3[][13] = { + { BL_TITLE, BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH, BL_SCORE, BL_FLUSH }, + { BL_ALIGN, BL_GOLD, BL_HP, BL_HPMAX, BL_ENE, BL_ENEMAX, + BL_AC, BL_XP, BL_EXP, BL_HD, BL_HUNGER, BL_CAP, + BL_FLUSH }, + { BL_LEVELDESC, BL_TIME, BL_CONDITION, BL_WEAPON, BL_ARMOR, BL_TERRAIN, + BL_VERS, BL_FLUSH } }; /* condition list for tty-style display, roughly in order of importance */ @@ -1194,6 +1200,50 @@ tty_status_blink(XtPointer client_data, XtIntervalId *timer) static void tty_status_redraw(Widget w) +{ + Arg args[5]; + int num_args; + Dimension width; + + /* Get the height of the font and the width of the widget */ + num_args = 0; + XtSetArg(args[num_args], XtNwidth, &width); num_args++; + XtGetValues(w, args, num_args); + int height = nhFontHeight(w); + + int x = 0; + int y = 0; + XClearWindow(XtDisplay(w), XtWindow(w)); + if (iflags.wc2_statuslines <= 2) { + for (unsigned row = 0; row < SIZE(X11_fieldorder_2); ++row) { + for (unsigned i = 0; i < SIZE(X11_fieldorder_2[0]); ++i) { + enum statusfields fld = X11_fieldorder_2[row][i]; + if (fld == BL_FLUSH) { + break; + } + x += tty_render_field(w, x, y, fld); + } + x = 0; + y += height; + } + } else { + for (unsigned row = 0; row < SIZE(X11_fieldorder_3); ++row) { + for (unsigned i = 0; i < SIZE(X11_fieldorder_3[0]); ++i) { + enum statusfields fld = X11_fieldorder_3[row][i]; + if (fld == BL_FLUSH) { + break; + } + x += tty_render_field(w, x, y, fld); + } + x = 0; + y += height; + } + } +} + +/* Render one field of the TTY status */ +static int +tty_render_field(Widget w, int x, int y, enum statusfields fld) { static struct stat_fmt { const char *pre; @@ -1222,71 +1272,56 @@ tty_status_redraw(Widget w) [BL_LEVELDESC] = { NULL, NULL }, [BL_EXP] = { "/", NULL }, [BL_CONDITION] = { NULL, NULL }, - [BL_WEAPON] = { NULL, NULL }, /* not in 2-line */ - [BL_ARMOR] = { NULL, NULL }, /* not in 2-line */ - [BL_TERRAIN] = { NULL, NULL }, /* not in 2-line */ + [BL_WEAPON] = { NULL, NULL }, + [BL_ARMOR] = { NULL, NULL }, + [BL_TERRAIN] = { NULL, NULL }, [BL_VERS] = { NULL, NULL }, }; - Arg args[5]; - int num_args; - Dimension width; - /* Get the height of the font and the width of the widget */ - num_args = 0; - XtSetArg(args[num_args], XtNwidth, &width); num_args++; - XtGetValues(w, args, num_args); - int height = nhFontHeight(w); + int width = 0; - int x = 0; - int y = 0; - XClearWindow(XtDisplay(w), XtWindow(w)); - for (unsigned row = 0; row < X11_NUM_STATUS_LINES; ++row) { - for (unsigned i = 0; i < X11_NUM_STATUS_FIELD; ++i) { - enum statusfields fld = X11_fieldorder[row][i]; - switch (fld) { - case BL_FLUSH: - break; + switch (fld) { + case BL_FLUSH: + break; - case BL_CONDITION: - for (unsigned j = 0; j < SIZE(X11_cond_labels); ++j) { - struct tty_cond_field const *fldp = &X11_cond_labels[j]; - if (fldp->text != NULL) { - x += tty_render_text(w, x, y, " ", NO_COLOR, 0, FALSE); - x += tty_render_text(w, x, y, fldp->text, fldp->color, fldp->attrs, FALSE); - } - } - break; - - default: - { - struct tty_status_field const *fldp = &X11_status_labels[fld]; - if (fldp->text != NULL && fldp->text[0] != '\0') { - if (x != 0 && (formats[fld].pre == NULL || strchr("(/", formats[fld].pre[0]) == NULL)) { - x += tty_render_text(w, x, y, " ", NO_COLOR, 0, FALSE); - } - if (formats[fld].pre != NULL) { - x += tty_render_text(w, x, y, formats[fld].pre, NO_COLOR, 0, FALSE); - } - x += tty_render_text(w, x, y, fldp->text, fldp->color, - fldp->attrs, fld == BL_GOLD); - if (formats[fld].post != NULL) { - x += tty_render_text(w, x, y, formats[fld].post, NO_COLOR, 0, FALSE); - } - /* @@@TODO: do the percent field */ - } - } - break; + case BL_CONDITION: + for (unsigned j = 0; j < SIZE(X11_cond_labels); ++j) { + struct tty_cond_field const *fldp = &X11_cond_labels[j]; + if (fldp->text != NULL) { + width += tty_render_text(w, x + width, y, " ", NO_COLOR, 0, BL_FLUSH); + width += tty_render_text(w, x + width, y, fldp->text, fldp->color, fldp->attrs, BL_FLUSH); } } - x = 0; - y += height; + break; + + default: + { + struct tty_status_field const *fldp = &X11_status_labels[fld]; + if (fldp->text != NULL && fldp->text[0] != '\0') { + if (x != 0 && (formats[fld].pre == NULL || strchr("(/", formats[fld].pre[0]) == NULL)) { + width += tty_render_text(w, x + width, y, " ", NO_COLOR, 0, BL_FLUSH); + } + if (formats[fld].pre != NULL) { + width += tty_render_text(w, x + width, y, formats[fld].pre, NO_COLOR, 0, BL_FLUSH); + } + width += tty_render_text(w, x + width, y, fldp->text, fldp->color, + fldp->attrs, fld); + if (formats[fld].post != NULL) { + width += tty_render_text(w, x + width, y, formats[fld].post, NO_COLOR, 0, BL_FLUSH); + } + /* @@@TODO: do the percent field */ + } + } + break; } + + return width; } /* Render text as part of the TTY status */ static int tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, - boolean is_gold) + enum statusfields fld) { Arg args[5]; Cardinal num_args; @@ -1360,7 +1395,7 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, /* Gold will begin with a glyph string. Convert this to the proper character, which might possibly be Unicode */ - if (is_gold && memcmp(text, "\\G", 2) == 0) { + if (fld == BL_GOLD && memcmp(text, "\\G", 2) == 0) { char *end; unsigned long glyphcode = strtoul(text+2, &end, 16); if ((glyphcode >> 16) == (unsigned) svc.context.rndencode && *end == ':') { @@ -1416,6 +1451,18 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, /* Get the width of the rendered string */ int width = XTextWidth(font, text, strlen(text)) + goldwidth; + /* Place version on the right */ + if (fld == BL_VERS) { + num_args = 0; + Dimension wwidth; + XtSetArg(args[num_args], XtNwidth, &wwidth); num_args++; + XtGetValues(w, args, num_args); + int x2 = wwidth - width; + if (x2 > x) { + x = x2; + } + } + /* Render the string */ XDrawImageString(XtDisplay(w), XtWindow(w), ggc, x + goldwidth, y + font->max_bounds.ascent, From ba2c99f28c828554923e86be92b4adb5dd0a7f85 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 8 Aug 2026 19:05:17 -0400 Subject: [PATCH 591/702] Remove old code --- win/X11/winstat.c | 627 ---------------------------------------------- 1 file changed, 627 deletions(-) diff --git a/win/X11/winstat.c b/win/X11/winstat.c index aebd7e83a..4b49b60b4 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -98,17 +98,6 @@ static int condcolor(long, unsigned long *); static int condattr(long, unsigned long *); -#if 0 /*RLC*/ -static void HiliteField(Widget, int, int, int, XFontStruct **); -static void PrepStatusField(int, Widget, const char *); -static void DisplayCond(int, unsigned long *); -static int render_conditions(int, int); -#ifdef STATUS_HILITES -static void tt_reset_color(int, int, unsigned long *); -#endif -static void tt_status_fixup(void); -static Widget create_tty_status_field(int, int, Widget, Widget); -#endif /*RLC*/ static Widget create_tty_status(Widget, Widget); static void stat_resized(Widget, XtPointer, XtPointer); static void update_fancy_status_field(int, int, int); @@ -136,11 +125,6 @@ static int X11_status_colors[MAXBLSTATS], old_field_colors[MAXBLSTATS], old_cond_colors[32]; static int hpbar_percent, hpbar_color; -/* Number of conditions displayed during this update and last update. - When the last update had more, the excess need to be erased. */ -#if 0 /*RLC*/ -static int next_cond_indx = 0, prev_cond_indx = 0; -#endif /*RLC*/ static enum statusfields X11_fieldorder_2[][18] = { { BL_TITLE, BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH, BL_ALIGN, @@ -224,10 +208,6 @@ static struct tty_status_field X11_status_labels[MAXBLSTATS]; static struct tty_cond_field X11_cond_labels[32]; /* Ugh */ static boolean blink; static const unsigned long blink_interval = 500; /* milliseconds */ -#if 0 /*RLC*/ -static XFontStruct *X11_status_font; -static Pixel X11_status_fg, X11_status_bg; -#endif /*RLC*/ struct xwindow *xw_status_win; @@ -327,369 +307,6 @@ cond_bm2idx(unsigned long bm) } #endif -#if 0 /*RLC*/ -/* highlight a tty-style status field (or condition) */ -static void -HiliteField(Widget label, - int fld, int cond, int colrattr, - XFontStruct **font_p) -{ -#ifdef STATUS_HILITES - static Pixel grayPxl, blackPxl, whitePxl; - Arg args[6]; - Cardinal num_args; - XFontStruct *font = X11_status_font; - Pixel px, fg = X11_status_fg, bg = X11_status_bg; - struct xwindow *xw = xw_status_win; - int colr, attr; - - if ((colrattr & 0x00ff) >= CLR_MAX) - colrattr = (colrattr & ~0x00ff) | NO_COLOR; - colr = colrattr & 0x00ff; /* guaranteed to be >= 0 and < CLR_MAX */ - attr = (colrattr >> 8) & 0x00ff; - - if (!grayPxl) {/* one-time init */ - grayPxl = get_nhcolor(xw, CLR_GRAY).pixel; - blackPxl = get_nhcolor(xw, CLR_BLACK).pixel; - whitePxl = get_nhcolor(xw, CLR_WHITE).pixel; - } - /* [shouldn't be necessary; setting up gray will set up all colors] */ - if (colr != NO_COLOR && !xw->nh_colors[colr].pixel) - (void) get_nhcolor(xw, colr); - - /* handle highlighting if caller has specified that; set foreground, - background, and font even if not specified this time in case they - used modified values last time (which would stick if not reset) */ - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - if (colr != NO_COLOR) - fg = xw->nh_colors[colr].pixel; - if ((attr & HL_INVERSE) != 0) { - px = fg; - fg = bg; - bg = px; - } - /* foreground and background might both default to black, so we - need to force one to be different if/when they're the same - (actually, tt_status_fixup() takes care of that nowadays); - using gray to implement 'dim' only works for black and white - (or color+'inverse' when former background was black or white) */ - if (fg == bg - || ((attr & HL_DIM) != 0 && (fg == whitePxl || fg == blackPxl))) - fg = (fg != grayPxl) ? grayPxl - : (fg != blackPxl) ? blackPxl - : whitePxl; - XtSetArg(args[num_args], nhStr(XtNforeground), fg); num_args++; - XtSetArg(args[num_args], nhStr(XtNbackground), bg); num_args++; - if (attr & HL_BOLD) { - load_boldfont(xw_status_win, label); - if (xw_status_win->boldfs) - font = xw_status_win->boldfs; - } - XtSetArg(args[num_args], nhStr(XtNfont), font); num_args++; - XtSetValues(label, args, num_args); - - /* return possibly modified font to caller so that text width - measurement can use it */ - if (font_p) - *font_p = font; -#else /*!STATUS_HILITES*/ - nhUse(label); - nhUse(font_p); -#endif /*?STATUS_HILITES*/ - if (fld != BL_CONDITION) - old_field_colors[fld] = colrattr; - else - old_cond_colors[cond] = colrattr; -} - -/* set up a specific field other than 'condition'; its general location - was specified during widget creation but it might need adjusting */ -static void -PrepStatusField(int fld, Widget label, const char *text) -{ - Arg args[6]; - Cardinal num_args; - Dimension lbl_wid; - XFontStruct *font = X11_status_font; - int colrattr = X11_status_colors[fld]; - struct status_info_t *si = xw_status_win->Win_info.Status_info; - - /* highlight if color and/or attribute(s) are different from last time */ - if (colrattr != old_field_colors[fld]) - HiliteField(label, fld, 0, colrattr, &font); - - num_args = 0; - (void) memset((genericptr_t) args, 0, sizeof args); - /* set up the current text to be displayed */ - if (text && *text) { - lbl_wid = 2 * si->in_wd + XTextWidth(font, text, (int) strlen(text)); - } else { - text = ""; - lbl_wid = 1; - } - XtSetArg(args[num_args], nhStr(XtNlabel), text); num_args++; - /*XtSetArg(args[num_args], nhStr(XtNwidth), lbl_wid); num_args++;*/ - XtSetValues(label, args, num_args); - XtResizeWidget(label, lbl_wid, si->ht, si->brd); -} - -/* set up one status condition for tty-style status display */ -static void -DisplayCond( - int c_idx, /* index into tt_condorder[] */ - unsigned long *colormasks) -{ - Widget label; - Arg args[6]; - Cardinal num_args; - Dimension lbl_wid; - XFontStruct *font = X11_status_font; - int coloridx, attrmask, colrattr, idx; - unsigned long bm = tt_condorder[c_idx].mask; - const char *text = tt_condorder[c_idx].text; - struct status_info_t *si = xw_status_win->Win_info.Status_info; - - if ((X11_condition_bits & bm) == 0) - return; - - /* widgets have been created for every condition; we allocate them - from left to right rather than keeping their original assignments */ - idx = next_cond_indx; - label = X11_cond_labels[idx]; - - /* handle highlighting if caller requests it */ - coloridx = condcolor(bm, colormasks); - attrmask = condattr(bm, colormasks); - colrattr = (attrmask << 8) | coloridx; - if (colrattr != old_cond_colors[c_idx]) - HiliteField(label, BL_CONDITION, c_idx, colrattr, &font); - - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - /* set the condition text and its width; this widget might have - been displaying a different condition last time around */ - XtSetArg(args[num_args], nhStr(XtNlabel), text); num_args++; - /* measure width after maybe changing font [HiliteField()] */ - lbl_wid = 2 * si->in_wd + XTextWidth(font, text, (int) strlen(text)); - /*XtSetArg(args[num_args], nhStr(XtNwidth), lbl_wid); num_args++;*/ - - /* make this condition widget be ready for display */ - XtSetValues(label, args, num_args); - XtResizeWidget(label, lbl_wid, si->ht, si->brd); - - ++next_cond_indx; -} - -/* display the tty-style status conditions; the number shown varies and - we might be showing more, same, or fewer than during previous status */ -static int -render_conditions(int row, int dx) -{ - Widget label; - Arg args[6]; - Cardinal num_args; - Position lbl_x; - int i, gap = 5; - struct status_info_t *si = xw_status_win->Win_info.Status_info; - Dimension lbl_wid, brd_wid = si->brd; - - for (i = 0; i < next_cond_indx; i++) { - label = X11_cond_labels[i]; - - /* width of this widget was set in DisplayCond(); fetch it */ - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - XtSetArg(args[num_args], nhStr(XtNwidth), &lbl_wid); num_args++; - XtGetValues(label, args, num_args); - - /* figure out where to draw this widget and place it there */ - lbl_x = (Position) (dx + 1 + gap); - - XtConfigureWidget(label, lbl_x, si->y[row], lbl_wid, si->ht, brd_wid); - - /* keep track of where the end of our text appears */ - dx = (int) lbl_x + (int) (lbl_wid + 2 * brd_wid) - 1; - } - - /* if we have fewer conditions shown now than last time, set the - excess ones to blank; unlike the set drawn above, these haven't - been prepared in advance by DisplayCond because they aren't - being displayed; they might have been highlighted last time so - we need to specify more than just an empty text string */ - if (next_cond_indx < prev_cond_indx) { - XFontStruct *font = X11_status_font; - Pixel fg = X11_status_fg, bg = X11_status_bg; - - lbl_x = dx + 1; - lbl_wid = 1 + 2 * brd_wid; - for (i = next_cond_indx; i < prev_cond_indx; ++i) { - label = X11_cond_labels[i]; - - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - XtSetArg(args[num_args], nhStr(XtNlabel), ""); num_args++; - XtSetArg(args[num_args], nhStr(XtNfont), font); num_args++; - XtSetArg(args[num_args], nhStr(XtNforeground), fg); num_args++; - XtSetArg(args[num_args], nhStr(XtNbackground), bg); num_args++; - /*XtSetArg(args[num_args], nhStr(XtNwidth), lbl_wid); num_args++;*/ - /*XtSetArg(args[num_args], nhStr(XtNx), lbl_x); num_args++;*/ - XtSetValues(label, args, num_args); - old_cond_colors[i] = NO_COLOR; /* fg, bg, font were just reset */ - XtConfigureWidget(label, lbl_x, si->y[row], lbl_wid, si->ht, 0); - /* don't advance 'dx' here */ - } - } - - return dx; -} - -#ifdef STATUS_HILITES -/* reset status_hilite for BL_RESET; if highlighting has been disabled or - this field is disabled, clear highlighting for this field or condition */ -static void -tt_reset_color( - int fld, - int cond, - unsigned long *colormasks) -{ - Widget label; - int colrattr = NO_COLOR; - - if (fld != BL_CONDITION) { - if (iflags.hilite_delta != 0L && status_activefields[fld]) - colrattr = X11_status_colors[fld]; - cond = 0; - label = X11_status_labels[fld]; - } else { - unsigned long bm = tt_condorder[cond].mask; - - if (iflags.hilite_delta != 0L && (X11_condition_bits & bm) != 0) { - /* BL_RESET before first BL_CONDITION will have colormasks==Null - but condcolor() and condattr() can cope with that */ - colrattr = condcolor(bm, colormasks); - colrattr |= (condattr(bm, colormasks) << 8); - } - label = X11_cond_labels[cond]; - } - HiliteField(label, fld, cond, colrattr, (XFontStruct **) 0); -} -#endif - -/* make sure foreground, background, and font have reasonable values, - then explicitly set them for all the status widgets; - also cache some geometry settings in (*xw_status_win).Status_info */ -static void -tt_status_fixup(void) -{ - Arg args[6]; - Cardinal num_args; - Widget w; - Position lbl_y; - int x, y, ci, fld; - XFontStruct *font = 0; - Pixel fg = 0, bg = 0; - struct status_info_t *si = xw_status_win->Win_info.Status_info; - - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - XtSetArg(args[num_args], nhStr(XtNfont), &font); num_args++; - XtSetArg(args[num_args], nhStr(XtNforeground), &fg); num_args++; - XtSetArg(args[num_args], nhStr(XtNbackground), &bg); num_args++; - XtGetValues(X11_status_widget, args, num_args); - if (fg == bg) { - XColor black = get_nhcolor(xw_status_win, CLR_BLACK), - white = get_nhcolor(xw_status_win, CLR_WHITE); - - fg = (bg == white.pixel) ? black.pixel : white.pixel; - } - X11_status_fg = si->fg = fg, X11_status_bg = si->bg = bg; - - if (!font) { - w = X11_status_widget; - XtSetArg(args[0], nhStr(XtNfont), &font); - do { - XtGetValues(w, args, ONE); - } while (!font && (w = XtParent(w)) != 0); - - if (!font) { - /* trial and error time -- this is where we've actually - been obtaining the font even though we aren't setting - it for any of the field widgets (until for(y,x) below) */ - XtGetValues(X11_status_labels[0], args, ONE); - - if (!font) { /* this bit is untested... */ - /* write some text and hope Xaw sets up font for us */ - XtSetArg(args[0], nhStr(XtNlabel), "NetHack"); - XtSetValues(X11_status_labels[0], args, ONE); - (void) XFlush(XtDisplay(X11_status_labels[0])); - - XtSetArg(args[0], nhStr(XtNfont), &font); - XtGetValues(X11_status_labels[0], args, ONE); - - /* if still Null, XTextWidth() would crash so bail out */ - if (!font) - panic("X11 status can't determine font."); - } - } - } - X11_status_font = si->fs = font; - - /* amount of space to advance a widget's location by one space; - increase width a tiny bit beyond the actual space */ - si->spacew = XTextWidth(X11_status_font, " ", 1) + (Dimension) 1; - - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - XtSetArg(args[num_args], nhStr(XtNfont), font); num_args++; - XtSetArg(args[num_args], nhStr(XtNforeground), fg); num_args++; - XtSetArg(args[num_args], nhStr(XtNbackground), bg); num_args++; - XtSetValues(X11_status_widget, args, num_args); - - for (y = 0; y < X11_NUM_STATUS_LINES; y++) { - for (x = 0; x < X11_NUM_STATUS_FIELD; x++) { - fld = X11_fieldorder[y][x]; /* next field to handle */ - if (fld <= BL_FLUSH) - continue; /* skip fieldorder[][] padding */ - - XtSetValues(X11_status_labels[fld], args, num_args); - old_field_colors[fld] = NO_COLOR; - - if (fld == BL_CONDITION) { - for (ci = 0; ci < SIZE(X11_cond_labels); ++ci) { /* 0..31 */ - XtSetValues(X11_cond_labels[ci], args, num_args); - old_cond_colors[ci] = NO_COLOR; - } - } - } - } - - /* cache the y coordinate of each row for XtConfigureWidget() */ - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - XtSetArg(args[0], nhStr(XtNy), &lbl_y); num_args++; - for (y = 0; y < X11_NUM_STATUS_LINES; y++) { - fld = X11_fieldorder[y][0]; - XtGetValues(X11_status_labels[fld], args, num_args); - si->y[y] = lbl_y; - } - - /* cache height, borderWidth, and internalWidth for XtResizeWidget() */ - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - XtSetArg(args[num_args], nhStr(XtNheight), &si->ht); num_args++; - XtSetArg(args[num_args], nhStr(XtNborderWidth), &si->brd); num_args++; - XtSetArg(args[num_args], nhStr(XtNinternalWidth), &si->in_wd); num_args++; - XtGetValues(X11_status_labels[0], args, num_args); - - /* X11_status_update_tty() wants this in order to right justify 'vers' */ - if (!xw_status_win->pixel_width) { - XtSetArg(args[0], nhStr(XtNwidth), &xw_status_win->pixel_width); - XtGetValues(xw_status_win->w, args, ONE); - } -} -#endif /*RLC*/ - DISABLE_WARNING_FORMAT_NONLITERAL /* core requests updating one status field (or is indicating that it's time @@ -756,176 +373,6 @@ X11_status_update_tty( } break; } -#if 0 /*RLC*/ - static int xtra_space[MAXBLSTATS]; - static unsigned long *cond_colormasks = (unsigned long *) 0; - - Arg args[6]; - Cardinal num_args; - Position lbl_x; - Dimension lbl_wid, brd_wid; - Widget label; - - struct status_info_t *si; - char goldbuf[40]; - const char *fmt; - const char *text; - unsigned long *condptr; - int f, x, y, dx; - - if (X11_status_fg == X11_status_bg || !X11_status_font) - tt_status_fixup(); - - if (fld == BL_RESET) { -#ifdef STATUS_HILITES - for (y = 0; y < X11_NUM_STATUS_LINES; y++) { - for (x = 0; x < X11_NUM_STATUS_FIELD; x++) { - f = X11_fieldorder[y][x]; - if (f <= BL_FLUSH) - continue; /* skip padding in the fieldorder[][] layout */ - if (f != BL_CONDITION) { - tt_reset_color(f, 0, (unsigned long *) 0); - } else { - int c_i; - - for (c_i = 0; c_i < SIZE(tt_condorder); ++c_i) - tt_reset_color(f, c_i, cond_colormasks); - } - } - } -#endif - fld = BL_FLUSH; - } - - if (fld == BL_CONDITION) { - condptr = (unsigned long *) ptr; - X11_condition_bits = *condptr; - cond_colormasks = colormasks; /* expected to be non-Null */ - - prev_cond_indx = next_cond_indx; - next_cond_indx = 0; - /* if any conditions are active, set up their widgets */ - if (X11_condition_bits) - for (f = 0; f < SIZE(tt_condorder); ++f) - DisplayCond(f, cond_colormasks); - return; - - } else if (fld != BL_FLUSH) { - /* set up a specific field other than 'condition' */ - text = (char *) ptr; - if (fld == BL_GOLD) - text = decode_mixed(goldbuf, text); - xtra_space[fld] = 0; - if (status_activefields[fld]) { - fmt = (fld == BL_TITLE && iflags.wc2_hitpointbar) ? "%-30s" - : status_fieldfmt[fld] ? status_fieldfmt[fld] : "%s"; - if (*fmt == ' ') { - ++xtra_space[fld]; - ++fmt; - } - Sprintf(status_vals[fld], fmt, text); - } else { - /* don't expect this since core won't call status_update() - for a field which isn't active */ - *status_vals[fld] = '\0'; - } -#ifdef STATUS_HILITES - if (!iflags.hilite_delta) - color = NO_COLOR; -#endif - X11_status_colors[fld] = color; - if (iflags.wc2_hitpointbar && fld == BL_HP) { - hpbar_percent = percent; - hpbar_color = color; - } - - label = X11_status_labels[fld]; - text = status_vals[fld]; - PrepStatusField(fld, label, text); - return; - } - - /* - * BL_FLUSH: draw all the status fields. - */ - si = xw_status_win->Win_info.Status_info; /* for cached geometry */ - - for (y = 0; y < X11_NUM_STATUS_LINES; y++) { /* row */ - dx = 0; /* no pixels written to this row yet */ - - for (x = 0; x < X11_NUM_STATUS_FIELD; x++) { /* 'column' */ - f = X11_fieldorder[y][x]; - if (f <= BL_FLUSH) - continue; /* skip padding in the fieldorder[][] layout */ - - if (f == BL_CONDITION) { - if (next_cond_indx > 0 || prev_cond_indx > 0) - dx = render_conditions(y, dx); - continue; - } - - label = X11_status_labels[f]; - text = status_vals[f]; - - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - XtSetArg(args[num_args], nhStr(XtNwidth), &lbl_wid); num_args++; - XtGetValues(label, args, num_args); - brd_wid = si->brd; - - /* for a field which shouldn't be shown, we can't just skip - it because we might need to remove its previous content - if it has just been toggled off */ - if (!status_activefields[f]) { - if (lbl_wid <= 1) - continue; - text = ""; - lbl_wid = (Dimension) 1; - brd_wid = (Dimension) 0; - } else if (xtra_space[f]) { - /* if this field was to be formatted with a leading space - to separate it from the preceding field, we suppressed - that space during formatting; insert separation between - fields here; this prevents inverse video highlighting - from inverting the separating space along with the text */ - dx += xtra_space[f] * si->spacew; - } - - /* where to display the current widget */ - lbl_x = (Position) (dx + 1); - if (f == BL_VERS) { - Dimension win_wid = xw_status_win->pixel_width, - fld_wid = lbl_wid + 2 * brd_wid; - - /* in case the doodad for resizing the window via click and - drag is in the lower right corner; justifying all the way - to the edge results in the last character being obscured; - avoid that by treating the 'vers' widget as one char - bigger than it actually is (an implicit trailing space) */ - fld_wid += si->spacew; - /* right justify if there's room */ - if (dx < win_wid - fld_wid) - lbl_x = win_wid - fld_wid; - } - - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - XtSetArg(args[num_args], nhStr(XtNlabel), text); num_args++; - /*XtSetArg(args[num_args], nhStr(XtNwidth), lbl_wid); num_args++;*/ - /*XtSetArg(args[num_args], nhStr(XtNx), lbl_x); num_args++;*/ - XtSetValues(label, args, num_args); - XtConfigureWidget(label, lbl_x, si->y[y], - lbl_wid, si->ht, brd_wid); - - /* track the right-most pixel written so far */ - dx = (int) lbl_x + (int) (lbl_wid + 2 * brd_wid) - 1; - } /* [x] fields/columns in current row */ - } /* [y] rows */ - - /* this probably doesn't buy us anything but it isn't a sure thing - that nethack will immediately ask for input (triggering auto-flush) */ - (void) XFlush(XtDisplay(X11_status_labels[0])); -#endif /*RLC*/ } RESTORE_WARNING_FORMAT_NONLITERAL @@ -1045,63 +492,14 @@ X11_status_update( X11_status_update_tty(fld, ptr, chg, percent, color, colormasks); } -#if 0 /*RLC*/ -/* create a widget for a particular status field or potential condition */ -static Widget -create_tty_status_field(int fld, int condindx, Widget above, Widget left) -{ - Arg args[16]; - Cardinal num_args; - char labelname[40]; - int gap = condindx ? 5 : 0; - - if (!condindx) - Sprintf(labelname, "label_%s", bl_idx_to_fldname(fld)); - else - Sprintf(labelname, "cond_%02d", condindx); - - /* set up widget attributes which (mostly) aren't going to be changing */ - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - if (above) { - XtSetArg(args[num_args], nhStr(XtNfromVert), above); num_args++; - } - if (left) { - XtSetArg(args[num_args], nhStr(XtNfromHoriz), left); num_args++; - } - - XtSetArg(args[num_args], nhStr(XtNhorizDistance), gap); num_args++; - XtSetArg(args[num_args], nhStr(XtNvertDistance), 0); num_args++; - - XtSetArg(args[num_args], nhStr(XtNtopMargin), 0); num_args++; - XtSetArg(args[num_args], nhStr(XtNbottomMargin), 0); num_args++; - XtSetArg(args[num_args], nhStr(XtNleftMargin), 0); num_args++; - XtSetArg(args[num_args], nhStr(XtNrightMargin), 0); num_args++; - XtSetArg(args[num_args], nhStr(XtNjustify), XtJustifyLeft); num_args++; - /* internalWidth: default is 4; cut that it half and adjust regular - width to have it on both left and right instead of just on the left */ - XtSetArg(args[num_args], nhStr(XtNinternalWidth), 2); num_args++; - XtSetArg(args[num_args], nhStr(XtNborderWidth), 0); num_args++; - XtSetArg(args[num_args], nhStr(XtNlabel), ""); num_args++; - return XtCreateManagedWidget(labelname, labelWidgetClass, - X11_status_widget, args, num_args); -} -#endif /*RLC*/ - /* create an overall status widget (X11_status_widget) and also separate widgets for all status fields and potential conditions */ static Widget create_tty_status(Widget parent, Widget top) { Widget form; /* viewport that holds the form that surrounds everything */ -#if 0 /*RLC*/ - Widget w, over_w, prev_w; -#endif /*RLC*/ Arg args[6]; Cardinal num_args; -#if 0 /*RLC*/ - int x, y, i, fld; -#endif /*RLC*/ (void) memset((genericptr_t) args, 0, sizeof args); num_args = 0; @@ -1133,31 +531,6 @@ create_tty_status(Widget parent, Widget top) XtAppAddTimeOut(app_context, blink_interval, tty_status_blink, (XtPointer) X11_status_widget); -#if 0 /*RLC*/ - for (y = 0; y < X11_NUM_STATUS_LINES; y++) { - fld = (y > 0) ? X11_fieldorder[y - 1][0] : 0; /* temp, for over_w */ - /* for row(s) beyond the first, pick a widget in the previous - row to put this one underneath (in 'y' terms; 'x' is fluid) */ - over_w = (y > 0) ? X11_status_labels[fld] : (Widget) 0; - /* widget on current row to put the next one to the right of ('x') */ - prev_w = (Widget) 0; - for (x = 0; x < X11_NUM_STATUS_FIELD; x++) { - fld = X11_fieldorder[y][x]; /* next field to handle */ - if (fld <= BL_FLUSH) - continue; /* skip fieldorder[][] padding */ - - w = create_tty_status_field(fld, 0, over_w, prev_w); - X11_status_labels[fld] = prev_w = w; - - if (fld == BL_CONDITION) { - for (i = 1; i <= SIZE(X11_cond_labels); ++i) { /* 1..32 */ - w = create_tty_status_field(fld, i, over_w, prev_w); - X11_cond_labels[i - 1] = prev_w = w; - } - } - } - } -#endif /*RLC*/ return X11_status_widget; } From ac169e7100ef1092700979dec32a81204b686e3f Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 8 Aug 2026 19:36:23 -0400 Subject: [PATCH 592/702] Clean up, and block out with STATUS_HILITES --- win/X11/winstat.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 4b49b60b4..326a37473 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -111,15 +111,13 @@ static void destroy_status_window_tty(struct xwindow *); static void adjust_status_fancy(struct xwindow *, const char *); static void adjust_status_tty(struct xwindow *, const char *); static void tty_status_exposed(Widget, XtPointer, XtPointer); +#ifdef STATUS_HILITES static void tty_status_blink(XtPointer client_data, XtIntervalId *timer); +#endif static void tty_status_redraw(Widget); static int tty_render_field(Widget, int, int, enum statusfields); static int tty_render_text(Widget, int, int, const char *, int, int, enum statusfields); -extern const char *status_fieldfmt[MAXBLSTATS]; -extern char *status_vals[MAXBLSTATS]; -extern boolean status_activefields[MAXBLSTATS]; - static unsigned long X11_condition_bits, old_condition_bits; static int X11_status_colors[MAXBLSTATS], old_field_colors[MAXBLSTATS], @@ -206,10 +204,12 @@ struct tty_cond_field { static Widget X11_status_widget; static struct tty_status_field X11_status_labels[MAXBLSTATS]; static struct tty_cond_field X11_cond_labels[32]; /* Ugh */ +#ifdef STATUS_HILITES static boolean blink; static const unsigned long blink_interval = 500; /* milliseconds */ +#endif -struct xwindow *xw_status_win; +static struct xwindow *xw_status_win; static int condcolor(long bm, unsigned long *bmarray) @@ -320,6 +320,10 @@ X11_status_update_tty( int color, unsigned long *colormasks) /* bitmask of highlights for conditions */ { +#ifndef STATUS_HILITES + nhUse(colormasks); +#endif + switch (fld) { case BL_RESET: case BL_FLUSH: @@ -339,6 +343,7 @@ X11_status_update_tty( fldp->text = NULL; } } +#ifdef STATUS_HILITES for (unsigned i = 0; i < CLR_MAX; ++i) { unsigned long mask = colormasks[i]; for (unsigned j = 0; j < SIZE(tt_condorder); ++j) { @@ -357,6 +362,7 @@ X11_status_update_tty( } } } +#endif } break; @@ -528,8 +534,10 @@ create_tty_status(Widget parent, Widget top) XtAddCallback(X11_status_widget, XtNexposeCallback, tty_status_exposed, (XtPointer) 0); +#ifdef STATUS_HILITES XtAppAddTimeOut(app_context, blink_interval, tty_status_blink, (XtPointer) X11_status_widget); +#endif return X11_status_widget; } @@ -547,6 +555,7 @@ tty_status_exposed(Widget w, XtPointer client_data, /* unused */ nhUse(widget_data); } +#ifdef STATUS_HILITES static void tty_status_blink(XtPointer client_data, XtIntervalId *timer) { @@ -570,6 +579,7 @@ tty_status_blink(XtPointer client_data, XtIntervalId *timer) /* Do it again */ XtAppAddTimeOut(app_context, blink_interval, tty_status_blink, client_data); } +#endif /* STATUS_HILITES */ static void tty_status_redraw(Widget w) @@ -696,6 +706,11 @@ static int tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, enum statusfields fld) { +#ifndef STATUS_HILITES + nhUse(color); + nhUse(attr); +#endif + Arg args[5]; Cardinal num_args; XGCValues values; @@ -712,6 +727,7 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, XtGetValues(w, args, num_args); /* Implement color if requested */ +#ifdef STATUS_HILITES if (color != NO_COLOR) { XrmValue source; XrmValue dest; @@ -760,6 +776,11 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, values.foreground = fgpixel; values.background = bgpixel; } +#else /* !STATUS_HILITES */ + values.foreground = fgpixel; + values.background = bgpixel; +#endif /* ?STATUS_HILITES */ + values.font = font->fid; values.function = GXcopy; GC ggc = XtGetGC(w, @@ -841,12 +862,14 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, x + goldwidth, y + font->max_bounds.ascent, text, strlen(text)); +#ifdef STATUS_HILITES /* Implement underline */ if (attr & HL_ULINE) { XDrawLine(XtDisplay(w), XtWindow(w), ggc, x, y + font->max_bounds.ascent, x + width - 1, y + font->max_bounds.ascent); } +#endif /* STATUS_HILITES */ /* Release resources */ XtReleaseGC(w, ggc); From b9bf8231004ff735decda7ca44adcca12d64587d Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 8 Aug 2026 20:08:42 -0400 Subject: [PATCH 593/702] Implement a hit point bar --- win/X11/winX.c | 2 +- win/X11/winstat.c | 142 +++++++++++++++++++++++++++++++--------------- 2 files changed, 98 insertions(+), 46 deletions(-) diff --git a/win/X11/winX.c b/win/X11/winX.c index b009ab865..f641cfb56 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -135,7 +135,7 @@ struct window_procs X11_procs = { #ifdef STATUS_HILITES | WC2_RESET_STATUS | WC2_HILITE_STATUS #endif - | WC2_EXTRASTATUS + | WC2_EXTRASTATUS | WC2_HITPOINTBAR | WC2_MENU_SHIFT ), {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */ X11_init_nhwindows, diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 326a37473..263a16c99 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -116,6 +116,7 @@ static void tty_status_blink(XtPointer client_data, XtIntervalId *timer); #endif static void tty_status_redraw(Widget); static int tty_render_field(Widget, int, int, enum statusfields); +static void tty_status_colors(Widget, int, int, Pixel *, Pixel *); static int tty_render_text(Widget, int, int, const char *, int, int, enum statusfields); static unsigned long X11_condition_bits, old_condition_bits; @@ -588,6 +589,11 @@ tty_status_redraw(Widget w) int num_args; Dimension width; + /* Name is placed here */ + int name_x = 0; + int name_y = 0; + int name_width = 0; + /* Get the height of the font and the width of the widget */ num_args = 0; XtSetArg(args[num_args], XtNwidth, &width); num_args++; @@ -604,7 +610,13 @@ tty_status_redraw(Widget w) if (fld == BL_FLUSH) { break; } - x += tty_render_field(w, x, y, fld); + int wid = tty_render_field(w, x, y, fld); + if (fld == BL_TITLE) { + name_x = x; + name_y = y; + name_width = wid; + } + x += wid; } x = 0; y += height; @@ -616,12 +628,37 @@ tty_status_redraw(Widget w) if (fld == BL_FLUSH) { break; } - x += tty_render_field(w, x, y, fld); + int wid = tty_render_field(w, x, y, fld); + if (fld == BL_TITLE) { + name_x = x; + name_y = y; + name_width = wid; + } + x += wid; } x = 0; y += height; } } + + if (name_width != 0 && iflags.wc2_hitpointbar) { + XGCValues values; + Pixel fgpixel, bgpixel; + struct tty_status_field const *fldp = &X11_status_labels[BL_TITLE]; + tty_status_colors(w, fldp->color, fldp->attrs, &fgpixel, &bgpixel); + values.foreground = fgpixel ^ bgpixel; + values.background = fgpixel ^ bgpixel; + values.function = GXxor; + values.fill_style = FillSolid; + GC ggc = XtGetGC(w, + GCFunction | GCForeground | GCBackground | GCFillStyle, + &values); + XFillRectangle(XtDisplay(w), XtWindow(w), ggc, + name_x, name_y, + name_width * X11_status_labels[BL_HP].percent / 100, + height); + XtReleaseGC(w, ggc); + } } /* Render one field of the TTY status */ @@ -692,7 +729,6 @@ tty_render_field(Widget w, int x, int y, enum statusfields fld) if (formats[fld].post != NULL) { width += tty_render_text(w, x + width, y, formats[fld].post, NO_COLOR, 0, BL_FLUSH); } - /* @@@TODO: do the percent field */ } } break; @@ -719,28 +755,17 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, XFontStruct *font_italic = NULL; /* custodial */ int goldwidth = 0; - /* Get default foreground and background colors, and font */ + /* Get the colors */ + tty_status_colors(w, color, attr, &fgpixel, &bgpixel); + + values.foreground = fgpixel; + values.background = bgpixel; + + /* Get the font */ num_args = 0; - XtSetArg(args[num_args], XtNforeground, &fgpixel); num_args++; - XtSetArg(args[num_args], XtNbackground, &bgpixel); num_args++; XtSetArg(args[num_args], XtNfont, &font); num_args++; XtGetValues(w, args, num_args); - /* Implement color if requested */ -#ifdef STATUS_HILITES - if (color != NO_COLOR) { - XrmValue source; - XrmValue dest; - Pixel pixel; - const char *cname = fancy_status_hilite_colors[color]; - source.addr = (XPointer) cname; - source.size = (unsigned int) strlen(cname) + 1; - dest.size = (unsigned int) sizeof (Pixel); - dest.addr = (XPointer) &pixel; - if (XtConvertAndStore(w, XtRString, &source, XtRPixel, &dest)) - fgpixel = pixel; - } - /* Implement bold font */ if (attr & HL_BOLD) { struct xwindow *wp = find_widget(w); @@ -757,30 +782,6 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, } } - /* Implement dim text */ - if (attr & HL_DIM) { - fgpixel = (fgpixel & 0xFEFEFE) >> 1; - bgpixel = (bgpixel & 0xFEFEFE) >> 1; - } - - /* Implement blink */ - if ((attr & HL_BLINK) && blink) { - fgpixel = bgpixel; - } - - /* Get a graphics context */ - if (attr & HL_INVERSE) { - values.foreground = bgpixel; - values.background = fgpixel; - } else { - values.foreground = fgpixel; - values.background = bgpixel; - } -#else /* !STATUS_HILITES */ - values.foreground = fgpixel; - values.background = bgpixel; -#endif /* ?STATUS_HILITES */ - values.font = font->fid; values.function = GXcopy; GC ggc = XtGetGC(w, @@ -881,6 +882,57 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, return width; } +static void +tty_status_colors(Widget w, int color, int attr, Pixel *fgpixel, Pixel *bgpixel) +{ + Cardinal num_args; + Arg args[5]; + + /* Get the default colors */ + num_args = 0; + XtSetArg(args[num_args], XtNforeground, fgpixel); num_args++; + XtSetArg(args[num_args], XtNbackground, bgpixel); num_args++; + XtGetValues(w, args, num_args); + + /* Implement color if requested */ +#ifdef STATUS_HILITES + if (color != NO_COLOR) { + XrmValue source; + XrmValue dest; + Pixel pixel; + const char *cname = fancy_status_hilite_colors[color]; + source.addr = (XPointer) cname; + source.size = (unsigned int) strlen(cname) + 1; + dest.size = (unsigned int) sizeof (Pixel); + dest.addr = (XPointer) &pixel; + if (XtConvertAndStore(w, XtRString, &source, XtRPixel, &dest)) + *fgpixel = pixel; + } + + /* Implement dim text */ + if (attr & HL_DIM) { + *fgpixel = (*fgpixel & 0xFEFEFE) >> 1; + *bgpixel = (*bgpixel & 0xFEFEFE) >> 1; + } + + /* Implement blink */ + if ((attr & HL_BLINK) && blink) { + *fgpixel = *bgpixel; + } + + /* Get a graphics context */ + if (attr & HL_INVERSE) { + Pixel swap; + swap = *fgpixel; + *fgpixel = *bgpixel; + *bgpixel = swap; + } +#else + nhUse(color); + nhUse(attr); +#endif +} + /*ARGSUSED*/ void create_status_window_tty(struct xwindow *wp, /* window pointer */ From c50f9d817654c38c45b19c69b359351a90a45932 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sun, 9 Aug 2026 07:50:28 -0400 Subject: [PATCH 594/702] Draw the hitpoint bar in the hitpoint colors --- win/X11/winstat.c | 61 ++++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 263a16c99..1c48a53be 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -117,7 +117,8 @@ static void tty_status_blink(XtPointer client_data, XtIntervalId *timer); static void tty_status_redraw(Widget); static int tty_render_field(Widget, int, int, enum statusfields); static void tty_status_colors(Widget, int, int, Pixel *, Pixel *); -static int tty_render_text(Widget, int, int, const char *, int, int, enum statusfields); +static int tty_render_text(Widget, const XRectangle *, int, int, const char *, + int, int, enum statusfields); static unsigned long X11_condition_bits, old_condition_bits; static int X11_status_colors[MAXBLSTATS], @@ -641,23 +642,26 @@ tty_status_redraw(Widget w) } } + /* + * Draw the hit point bar using: + * * the colors for hit points + * * the opposite of the HL_INVERSE bit for the title + * * the font for the title + */ if (name_width != 0 && iflags.wc2_hitpointbar) { - XGCValues values; - Pixel fgpixel, bgpixel; - struct tty_status_field const *fldp = &X11_status_labels[BL_TITLE]; - tty_status_colors(w, fldp->color, fldp->attrs, &fgpixel, &bgpixel); - values.foreground = fgpixel ^ bgpixel; - values.background = fgpixel ^ bgpixel; - values.function = GXxor; - values.fill_style = FillSolid; - GC ggc = XtGetGC(w, - GCFunction | GCForeground | GCBackground | GCFillStyle, - &values); - XFillRectangle(XtDisplay(w), XtWindow(w), ggc, - name_x, name_y, - name_width * X11_status_labels[BL_HP].percent / 100, - height); - XtReleaseGC(w, ggc); + XRectangle clip = { + .x = name_x, + .y = name_y, + .width = name_width * X11_status_labels[BL_HP].percent / 100, + .height = height + }; + struct tty_status_field const *title = &X11_status_labels[BL_TITLE]; + struct tty_status_field const *hitp = &X11_status_labels[BL_HP]; + int attrs = ((title->attrs & ~HL_DIM) ^ HL_INVERSE) + | (hitp->attrs & HL_DIM); + tty_render_text(w, &clip, name_x, name_y, + title->text, hitp->color, attrs, + BL_TITLE); } } @@ -708,8 +712,8 @@ tty_render_field(Widget w, int x, int y, enum statusfields fld) for (unsigned j = 0; j < SIZE(X11_cond_labels); ++j) { struct tty_cond_field const *fldp = &X11_cond_labels[j]; if (fldp->text != NULL) { - width += tty_render_text(w, x + width, y, " ", NO_COLOR, 0, BL_FLUSH); - width += tty_render_text(w, x + width, y, fldp->text, fldp->color, fldp->attrs, BL_FLUSH); + width += tty_render_text(w, NULL, x + width, y, " ", NO_COLOR, 0, BL_FLUSH); + width += tty_render_text(w, NULL, x + width, y, fldp->text, fldp->color, fldp->attrs, BL_FLUSH); } } break; @@ -719,15 +723,15 @@ tty_render_field(Widget w, int x, int y, enum statusfields fld) struct tty_status_field const *fldp = &X11_status_labels[fld]; if (fldp->text != NULL && fldp->text[0] != '\0') { if (x != 0 && (formats[fld].pre == NULL || strchr("(/", formats[fld].pre[0]) == NULL)) { - width += tty_render_text(w, x + width, y, " ", NO_COLOR, 0, BL_FLUSH); + width += tty_render_text(w, NULL, x + width, y, " ", NO_COLOR, 0, BL_FLUSH); } if (formats[fld].pre != NULL) { - width += tty_render_text(w, x + width, y, formats[fld].pre, NO_COLOR, 0, BL_FLUSH); + width += tty_render_text(w, NULL, x + width, y, formats[fld].pre, NO_COLOR, 0, BL_FLUSH); } - width += tty_render_text(w, x + width, y, fldp->text, fldp->color, + width += tty_render_text(w, NULL, x + width, y, fldp->text, fldp->color, fldp->attrs, fld); if (formats[fld].post != NULL) { - width += tty_render_text(w, x + width, y, formats[fld].post, NO_COLOR, 0, BL_FLUSH); + width += tty_render_text(w, NULL, x + width, y, formats[fld].post, NO_COLOR, 0, BL_FLUSH); } } } @@ -739,8 +743,8 @@ tty_render_field(Widget w, int x, int y, enum statusfields fld) /* Render text as part of the TTY status */ static int -tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, - enum statusfields fld) +tty_render_text(Widget w, const XRectangle *clip, int x, int y, + const char *text, int color, int attr, enum statusfields fld) { #ifndef STATUS_HILITES nhUse(color); @@ -788,6 +792,13 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, GCFunction | GCForeground | GCBackground | GCFont, &values); + /* If drawing a hitpoint bar, we'll need a clipping rectangle */ + if (clip != NULL) { + /* @#$% non-const-correct Xlib functions */ + XRectangle clip2 = *clip; + XSetClipRectangles(XtDisplay(w), ggc, 0, 0, &clip2, 1, Unsorted); + } + /* Gold will begin with a glyph string. Convert this to the proper character, which might possibly be Unicode */ if (fld == BL_GOLD && memcmp(text, "\\G", 2) == 0) { From e9a9f63b4fa6be6520e82edbfb66eb674f9f3d04 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 10 Aug 2026 09:36:40 +0300 Subject: [PATCH 595/702] fixes-5-0-1.txt update --- doc/fixes5-0-1.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 62494b1d3..5393f619a 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -242,6 +242,8 @@ Windows: in the event that there is a collision between a menu group accelerator and an individual menu item's accelerator, disregard the group accelerator; only known collision is '$' at this time X11: obey timed_delay +X11: improve TTY-style status line with text attributes for status hilites, + hitpointbar, some unicode support, 3-line status General New Features From f019d03a2fba8da973689ab6fcfb166c5ea662e0 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 11 Aug 2026 11:46:21 +0300 Subject: [PATCH 596/702] X11: fix menu windows being taller than the screen Menu windows with lots of entries (such as #optionsfull) were taller than the screen, making them awkward to use. The widget needs to be realized before we can get the size. Also, we need to set the size of the parent popup, not the acting widget. --- doc/fixes5-0-1.txt | 1 + win/X11/winmenu.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 5393f619a..17fb06f49 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -244,6 +244,7 @@ Windows: in the event that there is a collision between a menu group X11: obey timed_delay X11: improve TTY-style status line with text attributes for status hilites, hitpointbar, some unicode support, 3-line status +X11: fix menu windows being taller than the screen General New Features diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index 1c6885648..4e2210966 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -1062,6 +1062,7 @@ X11_select_menu(winid window, int how, menu_item **menu_list) menu_create_entries(wp, &menu_info->curr_menu); /* if viewport will be bigger than the screen, limit its height */ + XtRealizeWidget(wp->popup); /* need to realize before we get size/pos */ num_args = 0; XtSetArg(args[num_args], XtNwidth, &v_pixel_width); num_args++; XtSetArg(args[num_args], XtNheight, &v_pixel_height); num_args++; @@ -1076,9 +1077,8 @@ X11_select_menu(winid window, int how, menu_item **menu_list) num_args = 0; XtSetArg(args[num_args], XtNwidth, v_pixel_width); num_args++; XtSetArg(args[num_args], XtNheight, v_pixel_height); num_args++; - XtSetValues(wp->w, args, num_args); + XtSetValues(wp->popup, args, num_args); } - XtRealizeWidget(wp->popup); /* need to realize before we position */ /* if menu is not up, position it */ if (!menu_info->is_up) { From feaa9ed334a128e36af2a9db6a89c666d7a14d2a Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 11 Aug 2026 14:15:24 -0400 Subject: [PATCH 597/702] update tested versions of Visual Studio 2026-08-11 --- sys/windows/Makefile.nmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index 91a769d98..dbf49775e 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -8,8 +8,8 @@ # MS Visual Studio Visual C++ compiler # # Visual Studio Compilers Tested: -# - Microsoft Visual Studio Community 2022 v 17.14.37 -# - Microsoft Visual Studio Community 2026 v 18.8.1 +# - Microsoft Visual Studio Community 2022 v 17.14.38 +# - Microsoft Visual Studio Community 2026 v 18.9.0 # #============================================================================== # This is used for building two distinct executables of NetHack: @@ -1203,8 +1203,8 @@ rc=Rc.exe # is too old or untested. # # Recently tested versions: -TESTEDVS2022 = 14.44.35225.0 -TESTEDVS2026 = 14.51.36252.0 +TESTEDVS2022 = 14.44.35228.0 +TESTEDVS2026 = 14.51.36256.0 VS20261ST = 1450000000 VS2026CUR = $(TESTEDVS2026:.=) From a64c7c64e59648b0b038136852e41f92ef26e4c2 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 12 Aug 2026 12:27:12 +0300 Subject: [PATCH 598/702] X11: Allow scrolling menus with PageUp/PageDown/Home/End Change the menu_key() translation table command so it accepts a parameter, and we can pass a (default) menu control key to it. --- doc/fixes5-0-1.txt | 1 + win/X11/winmenu.c | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 17fb06f49..fd3944165 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -245,6 +245,7 @@ X11: obey timed_delay X11: improve TTY-style status line with text attributes for status hilites, hitpointbar, some unicode support, 3-line status X11: fix menu windows being taller than the screen +X11: allow menu scrolling by pageup/pagedown/home/end keys General New Features diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index 4e2210966..927e99e77 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -77,6 +77,10 @@ static const char menu_translations[] = "#override\n\ Right: scroll(6)\n\ Up: scroll(8)\n\ Down: scroll(2)\n\ + Prior: menu_key(<)\n\ + Next: menu_key(>)\n\ + Home: menu_key(^)\n\ + End: menu_key(|)\n\ : scroll(8)\n\ : scroll(2)\n\ : menu_key()"; @@ -233,14 +237,14 @@ menu_key(Widget w, XEvent *event, String *params, Cardinal *num_params) int count; boolean selected_something, perminv_scrolling = (event == &fake_perminv_event); - - nhUse(params); - nhUse(num_params); + Cardinal in_nparams = (num_params ? *num_params : 0); wp = find_widget(w); menu_info = wp->menu_information; - if (!perminv_scrolling) + if (in_nparams) { + ch = get_menu_cmd_key(*params[0]); + } else if (!perminv_scrolling) ch = key_event_to_char((XKeyEvent *) event); else ch = (char) fake_perminv_event.type; From b56189cfcd048792a22f348bb25e4c9201a64787 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 13 Aug 2026 11:16:42 +0300 Subject: [PATCH 599/702] X11: toggle off perm_invent if the window is closed manually --- doc/fixes5-0-1.txt | 1 + win/X11/winmenu.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index fd3944165..c39fb8b45 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -246,6 +246,7 @@ X11: improve TTY-style status line with text attributes for status hilites, hitpointbar, some unicode support, 3-line status X11: fix menu windows being taller than the screen X11: allow menu scrolling by pageup/pagedown/home/end keys +X11: toggle off perm_invent if user closes the perm inventory window General New Features diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index 927e99e77..09bcd50a3 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -616,6 +616,8 @@ menu_popdown(struct xwindow *wp) wp->w = wp->popup = (Widget) 0; if (wp->menu_information->is_active) exit_x_event = TRUE; /* exit our event handler */ + if (wp->menu_information->permi) + iflags.perm_invent = FALSE; wp->menu_information->is_up = FALSE; /* menu is down */ } From f7bb4eaae8e6ef1fa0bf8aed3b9d8503f9bc6ca3 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Mon, 10 Aug 2026 13:02:15 -0400 Subject: [PATCH 600/702] Fix timeout of fancy status colors This was trying to retrieve the foreground color of the form created in create_value(). Forms don't have colors, and so this was failing, and update_color() didn't update the color. --- win/X11/winstat.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 1c48a53be..4075d4a4e 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -1633,8 +1633,10 @@ update_val(struct X_status_value *attr_rec, long new_value) } attr_rec->turn_count = 0; } else { + Widget w = (attr_rec->type == SV_LABEL || attr_rec->type == SV_NAME) ? attr_rec->w + : get_value_widget(attr_rec->w); XtSetArg(args[0], XtNforeground, &attr_rec->default_fg); - XtGetValues(attr_rec->w, args, ONE); + XtGetValues(w, args, ONE); attr_rec->after_init = TRUE; } } From 6043d189e1bc2f5a79d4eac70ec0f548dbe8caa0 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Tue, 11 Aug 2026 09:31:11 -0400 Subject: [PATCH 601/702] Define wrapper for Label widgets Renders to a Pixmap and then sets the Pixmap. This in itself does not change the appearance, but provides a means to do percentage bars, italics and more. --- include/winX.h | 5 + sys/unix/Makefile.src | 6 +- win/X11/winX.c | 21 ++ win/X11/winlabel.c | 445 ++++++++++++++++++++++++++++++++++++++++++ win/X11/winstat.c | 6 + win/X11/winval.c | 9 +- 6 files changed, 488 insertions(+), 4 deletions(-) create mode 100644 win/X11/winlabel.c diff --git a/include/winX.h b/include/winX.h index 935fd5f5c..2bd73d679 100644 --- a/include/winX.h +++ b/include/winX.h @@ -514,9 +514,14 @@ extern void X11_preference_update(const char *); extern void X11_update_inventory(int); extern win_request_info *X11_ctrl_nhwindow(winid, int, win_request_info *); extern X11_map_symbol X11_glyph_char(const glyph_info *); +extern XFontStruct *X11_bold_font(Display *, XFontStruct *); extern XFontStruct *X11_italic_font(Display *, XFontStruct *); #ifdef ENHANCED_SYMBOLS extern XFontStruct *X11_unicode_font(Display *, XFontStruct *); #endif +/* Functions for management of enhanced labels */ +extern void X11_wrap_widget(Widget); +extern void X11_update_label(Widget); + #endif /* WINX_H */ diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 7347880e5..2bac600b8 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -259,11 +259,11 @@ WINCURSESOBJ ?= $(TARGETPFX)cursmain.o $(TARGETPFX)curswins.o \ WINX11SRC ?= ../win/X11/Window.c ../win/X11/dialogs.c ../win/X11/winX.c \ ../win/X11/winmap.c ../win/X11/winmenu.c ../win/X11/winmesg.c \ ../win/X11/winmisc.c ../win/X11/winstat.c ../win/X11/wintext.c \ - ../win/X11/winval.c $(GENTILECFILE) + ../win/X11/winval.c ../win/X11/winlabel.c $(GENTILECFILE) WINX11OBJ ?= $(TARGETPFX)Window.o $(TARGETPFX)dialogs.o $(TARGETPFX)winX.o \ $(TARGETPFX)winmap.o $(TARGETPFX)winmenu.o $(TARGETPFX)winmesg.o \ $(TARGETPFX)winmisc.o $(TARGETPFX)winstat.o $(TARGETPFX)wintext.o \ - $(TARGETPFX)winval.o + $(TARGETPFX)winval.o $(TARGETPFX)winlabel.o # # Files for a Qt 3 interface (renamed since nethack 3.6.x) # @@ -1080,6 +1080,8 @@ $(TARGETPFX)winX.o: ../win/X11/winX.c $(HACK_H) ../include/dlb.h \ ../include/winX.h ../include/xwindow.h ../win/X11/nh32icon \ ../win/X11/nh56icon ../win/X11/nh72icon $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winX.c +$(TARGETPFX)winlabel.o: ../win/X11/winlabel.c $(HACK_H) + $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winlabel.c $(TARGETPFX)winmap.o: ../win/X11/winmap.c $(HACK_H) ../include/dlb.h \ ../include/tile2x11.h ../include/winX.h ../include/xwindow.h $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winmap.c diff --git a/win/X11/winX.c b/win/X11/winX.c index f641cfb56..e247a7c82 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -3005,6 +3005,27 @@ X11_glyph_char(const glyph_info *glyphinfo) #endif } +/* Given an XFontStruct, return a corresponding bold font */ +XFontStruct * +X11_bold_font(Display *display, XFontStruct *font) +{ + Atom font_atom; + if (!XGetFontProperty(font, XA_FONT, &font_atom)) { + return NULL; + } + + const char *font_name = XGetAtomName(display, font_atom); + if (font_name == NULL) { + return NULL; + } + + char *bold_font = fontname_boldify(font_name); + XFontStruct *font2 = XLoadQueryFont(display, bold_font); + free(bold_font); + + return font2; +} + /* Given an XFontStruct, return a corresponding italic font */ XFontStruct * X11_italic_font(Display *display, XFontStruct *font) diff --git a/win/X11/winlabel.c b/win/X11/winlabel.c new file mode 100644 index 000000000..476bedcdd --- /dev/null +++ b/win/X11/winlabel.c @@ -0,0 +1,445 @@ +/* NetHack 5.0 winlabel.c $NHDT-Date: 1781973110 2026/06/20 16:31:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.50 $ */ +/* Copyright (c) Ray Chason, 2026 */ +/* NetHack may be freely redistributed. See license for details. */ + +#include +#include +#include + +#include + +#ifdef PRESERVE_NO_SYSV +#ifdef SYSV +#undef SYSV +#endif +#undef PRESERVE_NO_SYSV +#endif + +#include "hack.h" +#include "winX.h" + +/* Data attached to a wrapped widget */ +typedef struct WidgetData { + /* Displayed text */ + Pixmap pixmap; + + /* Attributes */ + unsigned attrs; + + /* Fonts for italic, bold and bold-italic */ + XFontStruct *font[4]; /* To use the fonts */ + XFontStruct *font_ptr[4]; /* To free the fonts */ + + /* Percentage bar */ + unsigned percent; + Pixel bar_color; +} WidgetData; + +/* Bits for WidgetData::font */ +enum { font_bold = 1, font_italic = 2 }; + +static boolean check_label(Widget); +static void delete_callback(Widget, XtPointer, XtPointer); +static void update_label(Widget, WidgetData *); +static void allocate_font(Widget, WidgetData *, unsigned); +static void free_fonts(Widget, WidgetData *); + +static WidgetData *add_widget(Widget w); +static void delete_widget(Widget w); +static WidgetData *get_widget_data(Widget w); + +/* + * Create a wrapper for labelWidgetClass and its descendant classes. + * + * A table is maintained to associate each widget with a data block. + * The block contains additional fonts for italic, bold and bold-italic, + * attribute flags and a percentage bar. + */ +void +X11_wrap_widget(Widget w) +{ + /* We shouldn't use this for anything other than labels and subclasses + of labels */ + if (!check_label(w)) { + impossible("Widget is not a Label or of a class derived from Label"); + return; + } + + /* Only wrap once */ + if (get_widget_data(w)) { + impossible("Tried to wrap a widget twice"); + return; + } + + /* Attach a destroy callback to reclaim resources attached to the widget */ + XtAddCallback(w, XtNdestroyCallback, delete_callback, NULL); + + /* Create the structure with its initial settings */ + WidgetData *data = add_widget(w); + + /* Copy resources from the created widget */ + Cardinal num_args2 = 0; + Arg args2[1]; + XtSetArg(args2[num_args2], XtNfont, &data->font[0]); num_args2++; + XtGetValues(w, args2, num_args2); + + /* Create the pixmap for the first time */ + update_label(w, data); + + return w; +} + +/* Callback when the widget is deleted */ +static void +delete_callback(Widget w, XtPointer client_data, XtPointer call_data) +{ + nhUse(client_data); + nhUse(call_data); + + /* + * We shouldn't get here with any widget for which check_label returns + * false, because such widgets will not have this callback set + */ + WidgetData *data = get_widget_data(w); + if (data != NULL) { + Display *display = XtDisplay(w); + if (data->pixmap != 0) { + XFreePixmap(display, data->pixmap); + } + free_fonts(w, data); + free(data); + } + + delete_widget(w); +} + +/* Return true if the widget is a Label or of a class derived from Label */ +static boolean +check_label(Widget w) +{ + return XtIsSubclass(w, labelWidgetClass); +} + +/* Update the label's pixmap */ +void +X11_update_label(Widget w) +{ + if (check_label(w)) { + WidgetData *data = get_widget_data(w); + update_label(w, data); + } +} + +/* Update the label's pixmap */ +/* This is called from functions that have altered the data block, and already + have a pointer to it */ +static void +update_label(Widget w, WidgetData *data) +{ + Display *display = XtDisplay(w); + Screen *screen = DefaultScreenOfDisplay(display); + int depth = DefaultDepthOfScreen(screen); + + Pixmap new_pixmap = 0; + Cardinal num_args; + Arg args[10]; + + /* Select the font */ + unsigned font_idx = 0; + if (data->attrs & HL_BOLD) { + font_idx |= font_bold; + allocate_font(w, data, font_idx); + } + if (data->attrs & HL_ITALIC) { + font_idx |= font_italic; + allocate_font(w, data, font_idx); + } + XFontStruct *font = data->font[font_idx]; + + String label; + Boolean sens; /* Make dim if not sensitive */ + XtJustify justify; /* Left, center, right */ + Pixel fgpixel; /* Colors for the first pass */ + Pixel bgpixel; + Boolean resize; /* Resizable? */ + num_args = 0; + XtSetArg(args[num_args], XtNlabel, &label); num_args++; + XtSetArg(args[num_args], XtNsensitive, &sens); num_args++; + XtSetArg(args[num_args], XtNjustify, &justify); num_args++; + XtSetArg(args[num_args], XtNforeground, &fgpixel); num_args++; + XtSetArg(args[num_args], XtNbackground, &bgpixel); num_args++; + XtSetArg(args[num_args], XtNresize, &resize); num_args++; + XtGetValues(w, args, num_args); + unsigned attrs = data->attrs; + if (!sens) { + attrs |= HL_DIM; + } + + /* Dimensions of pixmap */ + Dimension width; + Dimension height; + if (resize) { + /* Render the widest width and the total height of the lines */ + size_t i = 0; + width = 0; + height = 0; + while (label[i] != '\0') { + size_t line1 = strcspn(label + i, "\n"); + size_t line2 = line1; + /* Exclude \r from the rendering */ + if (line2 != 0 && label[i + line2 - 1] == '\r') { + --line2; + } + + /* Get the width of the line */ + int lwidth = XTextWidth(font, label + i, line2); + + /* Update pixmap dimensions */ + width = max(lwidth, width); + height += font->ascent + font->descent; + + /* Advance to next line */ + i += line1; + if (label[i] == '\n') { + ++i; + } + } + + /* Always size for at least one line */ + height = max(height, font->ascent + font->descent); + } else { + num_args = 0; + XtSetArg(args[num_args], XtNwidth, &width); num_args++; + XtSetArg(args[num_args], XtNheight, &height); num_args++; + XtGetValues(w, args, num_args); + } + width = max(width, 1); + height = max(height, 1); + + /* Create the pixmap */ + new_pixmap = XCreatePixmap(display, RootWindowOfScreen(screen), + width, height, depth); + + /* If a percent bar is specified, make two passes over the text and render + the percent bar in the second pass */ + for (unsigned pass = 0; pass < 2; ++pass) { + XGCValues values; + + if (attrs & HL_INVERSE) { + values.foreground = bgpixel; + values.background = fgpixel; + } else { + values.foreground = fgpixel; + values.background = bgpixel; + } + if (attrs & HL_DIM) { + values.foreground = (values.foreground & 0xFEFEFE) >> 1; + values.background = (values.background & 0xFEFEFE) >> 1; + } + values.font = font->fid; + values.function = GXcopy; + GC ggc = XtGetGC(w, + GCFunction | GCForeground | GCBackground | GCFont, + &values); + if (pass == 1) { + /* Percent bar will occupy this area */ + XRectangle clip = { + .x = 0, + .y = 0, + .width = width * data->percent / 100, + .height = height + }; + XSetClipRectangles(display, ggc, 0, 0, &clip, 1, Unsorted); + } + + XSetForeground(display, ggc, values.background); + XFillRectangle(display, new_pixmap, ggc, 0, 0, width, height); + XSetForeground(display, ggc, values.foreground); + + int y = font->max_bounds.ascent; + size_t i = 0; + while (label[i] != '\0') { + size_t line1 = strcspn(label + i, "\n"); + size_t line2 = line1; + /* Exclude \r from the rendering */ + if (line2 != 0 && label[i + line2 - 1] == '\r') { + --line2; + } + + /* Get the width of the line */ + int lwidth = XTextWidth(font, label + i, line2); + + /* Place the line horizontally */ + int x = 0; + switch (justify) { + case XtJustifyLeft: + x = 0; + break; + + case XtJustifyCenter: + x = (width - lwidth) / 2; + break; + + case XtJustifyRight: + x = width - lwidth; + break; + } + + /* Render the line */ + XDrawString(display, new_pixmap, ggc, + x, y, + label + i, line2); + + y += font->ascent + font->descent; + + /* Advance to next line */ + i += line1; + if (label[i] == '\n') { + ++i; + } + } + + XtReleaseGC(w, ggc); + + /* Set up to display the percent bar on the second pass */ + if (data->percent == 0) { + break; + } + fgpixel = bgpixel; + bgpixel = data->bar_color; + } + + /* Update the pixmap */ + num_args = 0; + XtSetArg(args[num_args], XtNbitmap, new_pixmap); num_args++; + //XtSetArg(args[num_args], XtNwidth, width); num_args++; + //XtSetArg(args[num_args], XtNheight, height); num_args++; + XtSetValues(w, args, num_args); + if (data->pixmap != 0) { + XFreePixmap(display, data->pixmap); + } + data->pixmap = new_pixmap; +} + +/* Allocate a bold or italic font */ +static void +allocate_font(Widget w, WidgetData *data, unsigned font_idx) +{ + Display *display = XtDisplay(w); + + XFontStruct *font1 = (font_idx == (font_bold | font_italic)) + ? data->font[font_bold] + : data->font[0]; + data->font_ptr[font_idx] = (font_idx == font_bold) + ? X11_bold_font(display, font1) + : X11_italic_font(display, font1); + data->font[font_idx] = data->font_ptr[font_idx] + ? data->font_ptr[font_idx] + : font1; +} + +/* Free any allocated fonts */ +static void +free_fonts(Widget w, WidgetData *data) +{ + Display *display = XtDisplay(w); + for (unsigned i = 0; i < 4; ++i) { + XFreeFont(display, data->font_ptr[i]); + data->font[i] = NULL; + data->font_ptr[i] = NULL; + } +} + +////////////////////////////////////////////////////////////////////////////// +// A table of widgets and their data blocks // +////////////////////////////////////////////////////////////////////////////// + +typedef struct WidgetBucket { + Widget w; + WidgetData *data; +} WidgetBucket; + +#define MAX_WIDGETS 1024 +static WidgetBucket widget_table[MAX_WIDGETS]; +static unsigned num_widgets; + +/* bsearch compare function to search widget-table */ +static int +widget_compare(const void *key_, const void *value_) +{ + const Widget *key = key_; + const WidgetBucket *value = value_; + + if ((uintptr_t)key < (uintptr_t)value->w) { + return -1; + } + if ((uintptr_t)key > (uintptr_t)value->w) { + return +1; + } + return 0; +} + +/* Given the widget, return the entry in widget_table, or NULL if not found */ +static WidgetBucket * +find_widget_bucket(Widget w) +{ + WidgetBucket *bucket = + bsearch(w, widget_table, num_widgets, sizeof(WidgetBucket), + widget_compare); + return bucket; +} + +/* Given the widget, return the WidgetData structure, or NULL if not found */ +static WidgetData * +get_widget_data(Widget w) +{ + WidgetBucket *bucket = find_widget_bucket(w); + return (bucket != NULL) ? bucket->data : NULL; +} + +/* Add a widget to the table, set its normal and bold fonts and provide for + its removal from the table */ +static WidgetData * +add_widget(Widget w) +{ + /* Panic rather than overflow the array */ + if (num_widgets >= MAX_WIDGETS) { + panic("Widget table is full\n"); + } + + /* Insert the widget into the table, maintaining its order */ + unsigned i; + for (i = num_widgets; + i != 0 && (uintptr_t)widget_table[i-1].w > (uintptr_t)w; + --i) { + widget_table[i] = widget_table[i-1]; + } + ++num_widgets; + widget_table[i].w = w; + + /* Create the data block */ + WidgetData *data = (WidgetData *)alloc(sizeof(*data)); + memset(data, 0, sizeof(*data)); + widget_table[i].data = data; + + return data; +} + +/* Remove the widget from the table */ +static void +delete_widget(Widget w) +{ + /* Find its location in the table */ + WidgetBucket *bucket = find_widget_bucket(w); + if (bucket == NULL) { + return; + } + + /* Remove the widget from the table */ + for (unsigned i = (unsigned)(bucket - widget_table); + i + 1 < MAX_WIDGETS; + ++i) { + widget_table[i] = widget_table[i+1]; + } + --num_widgets; +} diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 4075d4a4e..304be9579 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -1398,6 +1398,7 @@ null_out_status(void) case SV_NAME: XtSetArg(args[0], XtNlabel, ""); XtSetValues(sv->w, args, ONE); + X11_update_label(sv->w); break; default: @@ -1473,6 +1474,7 @@ update_val(struct X_status_value *attr_rec, long new_value) Strcpy((char *) attr_rec->name, buf); XtSetArg(args[0], XtNlabel, buf); XtSetValues(attr_rec->w, args, ONE); + X11_update_label(attr_rec->w); } else if (attr_rec->type == SV_NAME) { if (attr_rec->last_value == new_value) @@ -1494,6 +1496,7 @@ update_val(struct X_status_value *attr_rec, long new_value) XtSetArg(args[0], XtNlabel, buf); XtSetValues(attr_rec->w, args, ONE); + X11_update_label(attr_rec->w); } else { /* a value pair */ boolean force_update = FALSE; @@ -1687,6 +1690,7 @@ update_color(struct X_status_value *sv, int color) XtSetArg(args[0], arg_name, pixel); XtSetValues(w, args, ONE); + X11_update_label(w); } } @@ -2096,6 +2100,7 @@ create_widget(Widget parent, struct X_status_value *sv, int sv_index) : "dlevel", labelWidgetClass, parent, args, num_args); + X11_wrap_widget(sv->w); break; case SV_NAME: { char buf[BUFSZ]; @@ -2132,6 +2137,7 @@ create_widget(Widget parent, struct X_status_value *sv, int sv_index) XtSetArg(args[num_args], XtNinternalHeight, 0); num_args++; sv->w = XtCreateManagedWidget(sv->name, labelWidgetClass, parent, args, num_args); + X11_wrap_widget(sv->w); break; } default: diff --git a/win/X11/winval.c b/win/X11/winval.c index 9abd40f72..daea9812d 100644 --- a/win/X11/winval.c +++ b/win/X11/winval.c @@ -57,6 +57,7 @@ create_value(Widget parent, const char *name_value) num_args++; name = XtCreateManagedWidget(WNAME, labelWidgetClass, form, args, num_args); + X11_wrap_widget(name); num_args = 0; XtSetArg(args[num_args], XtNjustify, XtJustifyRight); @@ -67,8 +68,9 @@ create_value(Widget parent, const char *name_value) num_args++; XtSetArg(args[num_args], XtNinternalHeight, 0); num_args++; - (void) XtCreateManagedWidget(WVALUE, labelWidgetClass, form, args, - num_args); + Widget value = XtCreateManagedWidget(WVALUE, labelWidgetClass, form, args, + num_args); + X11_wrap_widget(value); return form; } @@ -81,6 +83,7 @@ set_name(Widget w, const char *new_label) name = XtNameToWidget(w, WNAME); XtSetArg(args[0], XtNlabel, new_label); XtSetValues(name, args, ONE); + X11_update_label(name); } void @@ -122,6 +125,7 @@ set_value(Widget w, const char *new_value) val = get_value_widget(w); XtSetArg(args[0], XtNlabel, new_value); XtSetValues(val, args, ONE); + X11_update_label(val); } void @@ -170,4 +174,5 @@ swap_fg_bg(Widget w) XtSetArg(args[0], XtNforeground, bg); XtSetArg(args[1], XtNbackground, fg); XtSetValues(w, args, TWO); + X11_update_label(w); } From 0ee7eef3eff49650d8d17642d8a6446db2261533 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Tue, 11 Aug 2026 12:25:02 -0400 Subject: [PATCH 602/702] Implement a hit point bar --- include/winX.h | 2 ++ win/X11/winlabel.c | 36 +++++++++++++++++++++++++++++---- win/X11/winstat.c | 50 +++++++++++++++++++++++++++++++++++++--------- 3 files changed, 75 insertions(+), 13 deletions(-) diff --git a/include/winX.h b/include/winX.h index 2bd73d679..5c97ee5ff 100644 --- a/include/winX.h +++ b/include/winX.h @@ -523,5 +523,7 @@ extern XFontStruct *X11_unicode_font(Display *, XFontStruct *); /* Functions for management of enhanced labels */ extern void X11_wrap_widget(Widget); extern void X11_update_label(Widget); +extern void X11_set_attrs(Widget, unsigned); +extern void X11_set_percent(Widget, unsigned, Pixel); #endif /* WINX_H */ diff --git a/win/X11/winlabel.c b/win/X11/winlabel.c index 476bedcdd..a9e56d915 100644 --- a/win/X11/winlabel.c +++ b/win/X11/winlabel.c @@ -85,8 +85,6 @@ X11_wrap_widget(Widget w) /* Create the pixmap for the first time */ update_label(w, data); - - return w; } /* Callback when the widget is deleted */ @@ -124,8 +122,29 @@ check_label(Widget w) void X11_update_label(Widget w) { - if (check_label(w)) { - WidgetData *data = get_widget_data(w); + WidgetData *data = get_widget_data(w); + if (data != NULL) { + update_label(w, data); + } +} + +void +X11_set_attrs(Widget w, unsigned attrs) +{ + WidgetData *data = get_widget_data(w); + if (data != NULL) { + data->attrs = attrs; + update_label(w, data); + } +} + +void +X11_set_percent(Widget w, unsigned percent, Pixel color) +{ + WidgetData *data = get_widget_data(w); + if (data != NULL) { + data->percent = percent; + data->bar_color = color; update_label(w, data); } } @@ -216,6 +235,15 @@ update_label(Widget w, WidgetData *data) width = max(width, 1); height = max(height, 1); + /* Use the full width of the widget if a percentage bar is set */ + if (data->percent != 0) { + Dimension wwidth; + num_args = 0; + XtSetArg(args[num_args], XtNwidth, &wwidth); num_args++; + XtGetValues(w, args, num_args); + width = max(width, wwidth); + } + /* Create the pixmap */ new_pixmap = XCreatePixmap(display, RootWindowOfScreen(screen), width, height, depth); diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 304be9579..64ca38a02 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -110,6 +110,7 @@ static void destroy_status_window_fancy(struct xwindow *); static void destroy_status_window_tty(struct xwindow *); static void adjust_status_fancy(struct xwindow *, const char *); static void adjust_status_tty(struct xwindow *, const char *); +static void set_percent(int, int, int); static void tty_status_exposed(Widget, XtPointer, XtPointer); #ifdef STATUS_HILITES static void tty_status_blink(XtPointer client_data, XtIntervalId *timer); @@ -390,7 +391,7 @@ static void X11_status_update_fancy( int fld, genericptr_t ptr, - int chg UNUSED, int percent UNUSED, + int chg UNUSED, int percent, int colrattr, unsigned long *colormasks UNUSED) { @@ -480,6 +481,11 @@ X11_status_update_fancy( update_fancy_status_field(bl_to_fancyfield[i].ff, colr, attr); break; } + + /* Hit point bar */ + if (fld == BL_HP) { + set_percent(F_NAME, iflags.wc2_hitpointbar ? percent : 0, colr); + } } } @@ -1221,6 +1227,7 @@ static void hilight_label(Widget); static void update_val(struct X_status_value *, long); static void skip_cond_val(struct X_status_value *); static void update_color(struct X_status_value *, int); +static Pixel color_to_pixel(Widget, int); static boolean name_widget_has_label(struct X_status_value *); static void apply_hilite_attributes(struct X_status_value *, int); static const char *width_string(int); @@ -1667,8 +1674,6 @@ update_color(struct X_status_value *sv, int color) { Pixel pixel = 0; Arg args[1]; - XrmValue source; - XrmValue dest; Widget w = (sv->type == SV_LABEL || sv->type == SV_NAME) ? sv->w : get_value_widget(sv->w); @@ -1677,12 +1682,8 @@ update_color(struct X_status_value *sv, int color) pixel = sv->default_fg; sv->colr = NO_COLOR; } else { - source.addr = (XPointer) fancy_status_hilite_colors[color]; - source.size = (unsigned int) strlen((const char *) source.addr) + 1; - dest.size = (unsigned int) sizeof (Pixel); - dest.addr = (XPointer) &pixel; - if (XtConvertAndStore(w, XtRString, &source, XtRPixel, &dest)) - sv->colr = color; + pixel = color_to_pixel(w, color); + sv->colr = color; } if (pixel != 0) { char *arg_name = (sv->set || sv->inverted_hilite) ? XtNbackground @@ -1694,6 +1695,30 @@ update_color(struct X_status_value *sv, int color) } } +static Pixel +color_to_pixel(Widget w, int color) +{ + Pixel pixel; + + if (fancy_status_hilite_colors[color][0] != '\0') { + XrmValue source; + XrmValue dest; + source.addr = (XPointer) fancy_status_hilite_colors[color]; + source.size = (unsigned int) strlen((const char *) source.addr) + 1; + dest.size = (unsigned int) sizeof (Pixel); + dest.addr = (XPointer) &pixel; + if (XtConvertAndStore(w, XtRString, &source, XtRPixel, &dest)) { + return pixel; + } + } + + pixel = 0xFFFFFF; + Arg args[1]; + XtSetArg(args[0], XtNforeground, &pixel); + XtGetValues(toplevel, args, ONE); + return pixel; +} + static boolean name_widget_has_label(struct X_status_value *sv) { @@ -1728,6 +1753,13 @@ apply_hilite_attributes(struct X_status_value *sv, int attributes) and each other attribute into its own to keep the code clean. */ } +static void +set_percent(int index, int percent, int color) +{ + Widget w = shown_stats[index].w; + X11_set_percent(w, percent, color_to_pixel(w, color)); +} + /* * Update the displayed status. The current code in botl.c updates * two lines of information. Both lines are always updated one after From 8d7d609a56c87c0f735a03f652257f5d35fe7587 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Tue, 11 Aug 2026 14:54:36 -0400 Subject: [PATCH 603/702] Implement attributes: bold, dim, italic, inverse Track highlighting of recent changes separately from inverse, and display highlight plus inverse as bordered text --- include/winX.h | 2 +- win/X11/winX.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/include/winX.h b/include/winX.h index 5c97ee5ff..fc26f48e0 100644 --- a/include/winX.h +++ b/include/winX.h @@ -454,7 +454,6 @@ extern int get_name_width(Widget); extern Widget get_value_widget(Widget); extern void set_value_width(Widget, int); extern int get_value_width(Widget); -extern void hilight_value(Widget); extern void swap_fg_bg(Widget); extern void set_value(Widget w, const char *new_value); /* external declarations */ @@ -524,6 +523,7 @@ extern XFontStruct *X11_unicode_font(Display *, XFontStruct *); extern void X11_wrap_widget(Widget); extern void X11_update_label(Widget); extern void X11_set_attrs(Widget, unsigned); +extern void X11_set_highlight(Widget, boolean); extern void X11_set_percent(Widget, unsigned, Pixel); #endif /* WINX_H */ diff --git a/win/X11/winX.c b/win/X11/winX.c index e247a7c82..bf030ab37 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -3021,7 +3021,6 @@ X11_bold_font(Display *display, XFontStruct *font) char *bold_font = fontname_boldify(font_name); XFontStruct *font2 = XLoadQueryFont(display, bold_font); - free(bold_font); return font2; } From 514669823bfc22daa23e6fe3559803bf6c78458c Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Tue, 11 Aug 2026 15:28:34 -0400 Subject: [PATCH 604/702] Implement bold, dim, italic, inverse, underline Didn't get everything the last time. --- win/X11/winlabel.c | 56 ++++++++++++++++++++++++++------- win/X11/winstat.c | 77 +++++++++------------------------------------- win/X11/winval.c | 8 ----- 3 files changed, 59 insertions(+), 82 deletions(-) diff --git a/win/X11/winlabel.c b/win/X11/winlabel.c index a9e56d915..e94bb7cc8 100644 --- a/win/X11/winlabel.c +++ b/win/X11/winlabel.c @@ -25,6 +25,7 @@ typedef struct WidgetData { /* Attributes */ unsigned attrs; + boolean highlight; /* Fonts for italic, bold and bold-italic */ XFontStruct *font[4]; /* To use the fonts */ @@ -138,6 +139,16 @@ X11_set_attrs(Widget w, unsigned attrs) } } +void +X11_set_highlight(Widget w, boolean highlight) +{ + WidgetData *data = get_widget_data(w); + if (data != NULL) { + data->highlight = highlight; + update_label(w, data); + } +} + void X11_set_percent(Widget w, unsigned percent, Pixel color) { @@ -232,16 +243,23 @@ update_label(Widget w, WidgetData *data) XtSetArg(args[num_args], XtNheight, &height); num_args++; XtGetValues(w, args, num_args); } - width = max(width, 1); - height = max(height, 1); + if (width < 2 || height < 2) { + /* Pixmap must not have zero size, or a crash will ensue; + minimum size 2 simplifies border logic */ + width = max(width, 2); + height = max(height, 2); + fgpixel = bgpixel; + } - /* Use the full width of the widget if a percentage bar is set */ - if (data->percent != 0) { - Dimension wwidth; + /* Use the full width of the widget if a percentage bar is set or inverse + is in effect */ + if (data->percent != 0 || (attrs & HL_INVERSE) != 0 || data->highlight) { + Dimension wwidth, iwidth; num_args = 0; XtSetArg(args[num_args], XtNwidth, &wwidth); num_args++; + XtSetArg(args[num_args], XtNinternalWidth, &iwidth); num_args++; XtGetValues(w, args, num_args); - width = max(width, wwidth); + width = max(width, wwidth - iwidth*2); } /* Create the pixmap */ @@ -253,7 +271,7 @@ update_label(Widget w, WidgetData *data) for (unsigned pass = 0; pass < 2; ++pass) { XGCValues values; - if (attrs & HL_INVERSE) { + if (!!(attrs & HL_INVERSE) ^ !!data->highlight) { values.foreground = bgpixel; values.background = fgpixel; } else { @@ -280,7 +298,11 @@ update_label(Widget w, WidgetData *data) XSetClipRectangles(display, ggc, 0, 0, &clip, 1, Unsorted); } - XSetForeground(display, ggc, values.background); + /* Draw a border for inverse and highlight together */ + /* Otherwise, fill with the background color */ + if (!((attrs & HL_INVERSE) && data->highlight)) { + XSetForeground(display, ggc, values.background); + } XFillRectangle(display, new_pixmap, ggc, 0, 0, width, height); XSetForeground(display, ggc, values.foreground); @@ -314,9 +336,16 @@ update_label(Widget w, WidgetData *data) } /* Render the line */ - XDrawString(display, new_pixmap, ggc, - x, y, - label + i, line2); + XDrawImageString(display, new_pixmap, ggc, + x, y, + label + i, line2); + + /* Draw the underline if requested */ + if (attrs & HL_ULINE) { + XDrawLine(display, new_pixmap, ggc, + x, y, + x + lwidth - 1, y); + } y += font->ascent + font->descent; @@ -327,6 +356,11 @@ update_label(Widget w, WidgetData *data) } } + /* Ensure a one-pixel border if both inverse and highlight */ + if ((attrs & HL_INVERSE) && data->highlight) { + XDrawRectangle(display, new_pixmap, ggc, 0, 0, width-1, height-1); + } + XtReleaseGC(w, ggc); /* Set up to display the percent bar on the second pass */ diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 64ca38a02..e08e968f5 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -1223,12 +1223,10 @@ struct f_overload { static const struct f_overload *ff_ovld_from_mask(unsigned long); static const struct f_overload *ff_ovld_from_indx(int); -static void hilight_label(Widget); static void update_val(struct X_status_value *, long); static void skip_cond_val(struct X_status_value *); static void update_color(struct X_status_value *, int); static Pixel color_to_pixel(Widget, int); -static boolean name_widget_has_label(struct X_status_value *); static void apply_hilite_attributes(struct X_status_value *, int); static const char *width_string(int); static void create_widget(Widget, struct X_status_value *, int); @@ -1415,18 +1413,6 @@ null_out_status(void) } } -/* this is almost an exact duplicate of hilight_value() */ -static void -hilight_label(Widget w) /* label widget */ -{ - /* - * This predates STATUS_HILITES. - * It is used to show any changed item in inverse and gets - * reset on the next turn. - */ - swap_fg_bg(w); -} - DISABLE_WARNING_FORMAT_NONLITERAL static void @@ -1631,14 +1617,10 @@ update_val(struct X_status_value *attr_rec, long new_value) if (attr_rec != &shown_stats[F_TIME] && attr_rec != &shown_stats[F_VERS] && !attr_rec->set ^ !*buf) { - /* But don't hilite if inverted from status_hilite since - it will already be hilited by apply_hilite_attributes(). */ - if (!attr_rec->inverted_hilite) { - if (attr_rec->type == SV_VALUE) - hilight_value(attr_rec->w); - else - hilight_label(attr_rec->w); - } + if (attr_rec->type == SV_VALUE) + X11_set_highlight(get_value_widget(attr_rec->w), TRUE); + else + X11_set_highlight(attr_rec->w, TRUE); attr_rec->set = !attr_rec->set; } attr_rec->turn_count = 0; @@ -1664,7 +1646,7 @@ skip_cond_val(struct X_status_value *sv) also requested to be highlighted, it used its own copy of 'set' but the same widget so the highlighting got toggled off; this will turn in back on in that exceptional case */ - hilight_label(sv->w); + X11_set_highlight(sv->w, FALSE); sv->set = FALSE; } } @@ -1686,10 +1668,7 @@ update_color(struct X_status_value *sv, int color) sv->colr = color; } if (pixel != 0) { - char *arg_name = (sv->set || sv->inverted_hilite) ? XtNbackground - : XtNforeground; - - XtSetArg(args[0], arg_name, pixel); + XtSetArg(args[0], XtNforeground, pixel); XtSetValues(w, args, ONE); X11_update_label(w); } @@ -1719,38 +1698,14 @@ color_to_pixel(Widget w, int color) return pixel; } -static boolean -name_widget_has_label(struct X_status_value *sv) -{ - Arg args[1]; - const char *label; - - XtSetArg(args[0], XtNlabel, &label); - XtGetValues(sv->w, args, ONE); - return (*label != '\0'); -} - static void apply_hilite_attributes(struct X_status_value *sv, int attributes) { - boolean attr_inversion = ((HL_INVERSE & attributes) - && (sv->type != SV_NAME - || name_widget_has_label(sv))); - - if (sv->inverted_hilite != attr_inversion) { - sv->inverted_hilite = attr_inversion; - if (!sv->set) { - if (sv->type == SV_VALUE) - hilight_value(sv->w); - else - hilight_label(sv->w); - } + Widget w = sv->w; + if (sv->type == SV_VALUE) { + w = get_value_widget(w); } - sv->attr = attributes; - /* Could possibly add more attributes here: HL_ATTCLR_DIM, - HL_ATTCLR_BLINK, HL_ATTCLR_ULINE, and HL_ATTCLR_BOLD. If so, - extract the above into its own function apply_hilite_inverse() - and each other attribute into its own to keep the code clean. */ + X11_set_attrs(w, attributes); } static void @@ -2021,14 +1976,10 @@ check_turn_events(void) continue; if (sv->turn_count++ >= hilight_time) { - /* unhighlights by toggling a highlighted item back off again, - unless forced inverted by a status_hilite rule */ - if (!sv->inverted_hilite) { - if (sv->type == SV_VALUE) - hilight_value(sv->w); - else - hilight_label(sv->w); - } + if (sv->type == SV_VALUE) + X11_set_highlight(get_value_widget(sv->w), FALSE); + else + X11_set_highlight(sv->w, FALSE); sv->set = FALSE; } } diff --git a/win/X11/winval.c b/win/X11/winval.c index daea9812d..59a2c3a5b 100644 --- a/win/X11/winval.c +++ b/win/X11/winval.c @@ -152,14 +152,6 @@ get_value_width(Widget w) return (int) width; } -/* Swap foreground and background colors (this is the best I can do with */ -/* a label widget, unless I can get some init hook in there). */ -void -hilight_value(Widget w) -{ - swap_fg_bg(get_value_widget(w)); -} - /* Swap the foreground and background colors of the given widget */ void swap_fg_bg(Widget w) From 24d9c19378c755d2f3ea42ebba7d6fda8f27d170 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Tue, 11 Aug 2026 16:26:37 -0400 Subject: [PATCH 605/702] Parenthesize the HL_ATTCLR_* symbols --- include/botl.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/botl.h b/include/botl.h index a097c9eff..83539424b 100644 --- a/include/botl.h +++ b/include/botl.h @@ -238,14 +238,14 @@ extern int cond_idx[CONDITION_COUNT]; #define BL_TH_ALWAYS_HILITE 105 /* highlight regardless of value */ #define BL_TH_CRITICALHP 106 /* highlight critically low HP */ -#define HL_ATTCLR_NONE CLR_MAX + 1 -#define HL_ATTCLR_BOLD CLR_MAX + 2 -#define HL_ATTCLR_DIM CLR_MAX + 3 -#define HL_ATTCLR_ITALIC CLR_MAX + 4 -#define HL_ATTCLR_ULINE CLR_MAX + 5 -#define HL_ATTCLR_BLINK CLR_MAX + 6 -#define HL_ATTCLR_INVERSE CLR_MAX + 7 -#define BL_ATTCLR_MAX CLR_MAX + 8 +#define HL_ATTCLR_NONE (CLR_MAX + 1) +#define HL_ATTCLR_BOLD (CLR_MAX + 2) +#define HL_ATTCLR_DIM (CLR_MAX + 3) +#define HL_ATTCLR_ITALIC (CLR_MAX + 4) +#define HL_ATTCLR_ULINE (CLR_MAX + 5) +#define HL_ATTCLR_BLINK (CLR_MAX + 6) +#define HL_ATTCLR_INVERSE (CLR_MAX + 7) +#define BL_ATTCLR_MAX (CLR_MAX + 8) enum hlattribs { HL_UNDEF = 0x00, From 3398d250aa64e5c9ee4175d56b3584bb667336f2 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Tue, 11 Aug 2026 16:27:17 -0400 Subject: [PATCH 606/702] Implement blink on fancy status and fix a bug with condition labels on the TTY status --- include/winX.h | 8 ++++++++ win/X11/winX.c | 19 +++++++++++++++++++ win/X11/winlabel.c | 17 +++++++++++++++++ win/X11/winstat.c | 28 +++++----------------------- 4 files changed, 49 insertions(+), 23 deletions(-) diff --git a/include/winX.h b/include/winX.h index fc26f48e0..2a62f892e 100644 --- a/include/winX.h +++ b/include/winX.h @@ -331,6 +331,9 @@ extern void (*input_func)(Widget, XEvent *, String *, Cardinal *); extern struct window_procs X11_procs; +/* Flag maintained by the blink callback */ +extern boolean X11_blink; + /* Check for an invalid window id. */ #define check_winid(window) \ do { \ @@ -424,6 +427,9 @@ extern void destroy_status_window(struct xwindow *); extern void adjust_status(struct xwindow *, const char *); extern void null_out_status(void); extern void check_turn_events(void); +#ifdef STATUS_HILITES +extern void X11_tty_status_blink(void); +#endif /* ### wintext.c ### */ extern void delete_text(Widget, XEvent *, String *, Cardinal *); @@ -519,11 +525,13 @@ extern XFontStruct *X11_italic_font(Display *, XFontStruct *); extern XFontStruct *X11_unicode_font(Display *, XFontStruct *); #endif +/* ### winlabel.c ### */ /* Functions for management of enhanced labels */ extern void X11_wrap_widget(Widget); extern void X11_update_label(Widget); extern void X11_set_attrs(Widget, unsigned); extern void X11_set_highlight(Widget, boolean); extern void X11_set_percent(Widget, unsigned, Pixel); +extern void X11_blink_labels(void); #endif /* WINX_H */ diff --git a/win/X11/winX.c b/win/X11/winX.c index bf030ab37..77b84ae78 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -112,6 +112,9 @@ static void X11_error_handler(String) __attribute__((noreturn)); ATTRNORETURN static XtErrorHandler X11_error_handler(String); #endif +boolean X11_blink; +static unsigned blink_interval = 500; /* milliseconds */ + static int X11_io_error_handler(Display *); static int (*old_error_handler)(Display *, XErrorEvent *); @@ -200,6 +203,7 @@ static void release_yn_widgets(void); static int input_event(int); static void win_visible(Widget, XtPointer, XEvent *, Boolean *); static void init_standard_windows(void); +static void blink_callback(XtPointer client_data, XtIntervalId *timer); /* * Local variables. @@ -1611,6 +1615,7 @@ X11_init_nhwindows(int *argcp, char **argv) (ArgList) args, num_args); XtOverrideTranslations(toplevel, XtParseTranslationTable("WM_PROTOCOLS: X11_hangup()")); + XtAppAddTimeOut(app_context, blink_interval, blink_callback, NULL); /* We don't need to realize the top level widget. */ @@ -1667,6 +1672,20 @@ X11_init_nhwindows(int *argcp, char **argv) X11_putstr(WIN_MESSAGE, 0, copyright_banner_line(i)); } +static void +blink_callback(XtPointer client_data, XtIntervalId *timer) +{ + nhUse(timer); +#ifdef STATUS_HILITES + X11_tty_status_blink(); +#endif + X11_blink_labels(); + + X11_blink = !X11_blink; + /* Do it again */ + XtAppAddTimeOut(app_context, blink_interval, blink_callback, client_data); +} + /* * All done. */ diff --git a/win/X11/winlabel.c b/win/X11/winlabel.c index e94bb7cc8..76fa007e7 100644 --- a/win/X11/winlabel.c +++ b/win/X11/winlabel.c @@ -282,6 +282,9 @@ update_label(Widget w, WidgetData *data) values.foreground = (values.foreground & 0xFEFEFE) >> 1; values.background = (values.background & 0xFEFEFE) >> 1; } + if ((attrs & HL_BLINK) && X11_blink) { + values.foreground = values.background; + } values.font = font->fid; values.function = GXcopy; GC ggc = XtGetGC(w, @@ -505,3 +508,17 @@ delete_widget(Widget w) } --num_widgets; } + +////////////////////////////////////////////////////////////////////////////// + +/* Call every time the blink flag changes */ +void +X11_blink_labels(void) +{ + for (unsigned i = 0; i < num_widgets; ++i) { + WidgetBucket *bucket = &widget_table[i]; + if (bucket->data->attrs & HL_BLINK) { + update_label(bucket->w, bucket->data); + } + } +} diff --git a/win/X11/winstat.c b/win/X11/winstat.c index e08e968f5..5e5d34cc5 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -112,9 +112,6 @@ static void adjust_status_fancy(struct xwindow *, const char *); static void adjust_status_tty(struct xwindow *, const char *); static void set_percent(int, int, int); static void tty_status_exposed(Widget, XtPointer, XtPointer); -#ifdef STATUS_HILITES -static void tty_status_blink(XtPointer client_data, XtIntervalId *timer); -#endif static void tty_status_redraw(Widget); static int tty_render_field(Widget, int, int, enum statusfields); static void tty_status_colors(Widget, int, int, Pixel *, Pixel *); @@ -207,10 +204,6 @@ struct tty_cond_field { static Widget X11_status_widget; static struct tty_status_field X11_status_labels[MAXBLSTATS]; static struct tty_cond_field X11_cond_labels[32]; /* Ugh */ -#ifdef STATUS_HILITES -static boolean blink; -static const unsigned long blink_interval = 500; /* milliseconds */ -#endif static struct xwindow *xw_status_win; @@ -361,7 +354,7 @@ X11_status_update_tty( for (unsigned j = 0; j < SIZE(tt_condorder); ++j) { if ((mask & tt_condorder[j].mask) != 0) { struct tty_cond_field *fldp = &X11_cond_labels[j]; - fldp->attrs |= 0x1 << (i - CLR_MAX); + fldp->attrs |= 0x1 << (i - HL_ATTCLR_NONE); } } } @@ -542,10 +535,6 @@ create_tty_status(Widget parent, Widget top) XtAddCallback(X11_status_widget, XtNexposeCallback, tty_status_exposed, (XtPointer) 0); -#ifdef STATUS_HILITES - XtAppAddTimeOut(app_context, blink_interval, tty_status_blink, - (XtPointer) X11_status_widget); -#endif return X11_status_widget; } @@ -564,12 +553,9 @@ tty_status_exposed(Widget w, XtPointer client_data, /* unused */ } #ifdef STATUS_HILITES -static void -tty_status_blink(XtPointer client_data, XtIntervalId *timer) +void +X11_tty_status_blink(void) { - Widget w = (Widget) client_data; - nhUse(timer); - /* Do we have any active blink attributes? */ boolean have_blink = FALSE; for (unsigned i = 0; i < SIZE(X11_status_labels) && !have_blink; ++i) { @@ -580,12 +566,8 @@ tty_status_blink(XtPointer client_data, XtIntervalId *timer) } if (have_blink) { - tty_status_redraw(w); - blink = !blink; + tty_status_redraw(X11_status_widget); } - - /* Do it again */ - XtAppAddTimeOut(app_context, blink_interval, tty_status_blink, client_data); } #endif /* STATUS_HILITES */ @@ -933,7 +915,7 @@ tty_status_colors(Widget w, int color, int attr, Pixel *fgpixel, Pixel *bgpixel) } /* Implement blink */ - if ((attr & HL_BLINK) && blink) { + if ((attr & HL_BLINK) && X11_blink) { *fgpixel = *bgpixel; } From 84ff4f8b7eeb9fd9fa484525507619f7ad42577d Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Tue, 11 Aug 2026 17:55:36 -0400 Subject: [PATCH 607/702] Fix a null dereference when freeing fonts --- win/X11/winlabel.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/win/X11/winlabel.c b/win/X11/winlabel.c index 76fa007e7..1d5508847 100644 --- a/win/X11/winlabel.c +++ b/win/X11/winlabel.c @@ -409,7 +409,9 @@ free_fonts(Widget w, WidgetData *data) { Display *display = XtDisplay(w); for (unsigned i = 0; i < 4; ++i) { - XFreeFont(display, data->font_ptr[i]); + if (data->font_ptr[i] != NULL) { + XFreeFont(display, data->font_ptr[i]); + } data->font[i] = NULL; data->font_ptr[i] = NULL; } From 2d261f13989c53595fb50363732540ddaf67ce6e Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Tue, 11 Aug 2026 17:56:12 -0400 Subject: [PATCH 608/702] Implement all text attributes for menus --- win/X11/winmenu.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index 09bcd50a3..f3bf05127 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -172,6 +172,7 @@ menu_select(Widget w, XtPointer client_data, XtPointer call_data) XtSetArg(args[0], nhStr(XtNlabel), curr->str); XtSetValues(w, args, ONE); + X11_update_label(w); if (menu_info->how == PICK_ONE) menu_popdown(wp); @@ -218,6 +219,7 @@ invert_line(struct xwindow *wp, x11_menu_item *curr, int which, long how_many) XtSetValues(curr->w, args, ONE); curr->pick_count = -1L; } + X11_update_label(curr->w); } static XEvent fake_perminv_event; @@ -1356,14 +1358,8 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu) ? commandWidgetClass : labelWidgetClass, wp->w, args, num_args); - - if (attr == ATR_BOLD) { - load_boldfont(wp, curr->w); - num_args = 0; - XtSetArg(args[num_args], nhStr(XtNfont), - wp->boldfs); num_args++; - XtSetValues(curr->w, args, num_args); - } + X11_wrap_widget(curr->w); + X11_set_attrs(curr->w, 0x1 << attr); if (canpick) XtAddCallback(linewidget, XtNcallback, menu_select, From fbfac21aacc2e0c9c07a9a3d600e6bae635e4db9 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Tue, 11 Aug 2026 18:11:00 -0400 Subject: [PATCH 609/702] Fix menu group accelerators If there are, say, two or more potions in the menu, and multiple selections are allowed, then '!' should select all potions. Such keys were selecting only the first matching item. --- win/X11/winmenu.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index f3bf05127..abc646938 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -262,10 +262,14 @@ menu_key(Widget w, XEvent *event, String *params, Cardinal *num_params) overridden if it happens to duplicate a mapped menu command (':' to look inside a container vs ':' to select via search string); check for group accelerator match too */ - for (curr = menu_info->curr_menu.base; curr; curr = curr->next) - if (curr->identifier.a_void != 0 - && (curr->selector == ch || curr->gselector == ch)) - goto make_selection; + for (curr = menu_info->curr_menu.base; curr; curr = curr->next) { + if (curr->identifier.a_void != 0) { + if (curr->selector == ch) + goto make_selection; + if (curr->gselector == ch) + goto group_accel; + } + } ch = map_menu_cmd(ch); if (ch == '\033') { /* quit */ From ddbea3b72701acd513be3d4a18b1514a453fdd03 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Wed, 12 Aug 2026 02:23:23 -0400 Subject: [PATCH 610/702] Implement remaining status labels --- win/X11/winstat.c | 181 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 146 insertions(+), 35 deletions(-) diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 5e5d34cc5..08d5f7e22 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -94,13 +94,28 @@ #define F_HALLU 40 #define F_VERS 41 /* version info */ -#define NUM_STATS 42 + +#define F_WEAPON 42 +#define F_ARMOR 43 +#define F_TERRAIN 44 +#define F_BAREH 45 +#define F_GLOWHANDS 46 +#define F_ICY 47 +#define F_BUSY 48 +#define F_PARALYZED 49 +#define F_SLEEPING 50 +#define F_UNCONSCIOUS 51 +#define F_IRON 52 +#define F_SLIPPERY 53 +#define F_SUBMERGED 54 +#define F_WOUNDEDL 55 +#define NUM_STATS 56 static int condcolor(long, unsigned long *); static int condattr(long, unsigned long *); static Widget create_tty_status(Widget, Widget); static void stat_resized(Widget, XtPointer, XtPointer); -static void update_fancy_status_field(int, int, int); +static void update_fancy_status_field(int, const char *, int, int); static void update_fancy_status(boolean); static Widget create_fancy_status(Widget, Widget); static void destroy_fancy_status(struct xwindow *); @@ -412,6 +427,9 @@ X11_status_update_fancy( { BL_HPMAX, F_MAXHP }, { BL_LEVELDESC, F_DLEVEL }, { BL_VERS, F_VERS }, + { BL_WEAPON, F_WEAPON }, + { BL_ARMOR, F_ARMOR }, + { BL_TERRAIN, F_TERRAIN }, { BL_EXP, F_EXP_PTS } }; static const struct mask_to_ff { @@ -436,6 +454,17 @@ X11_status_update_fancy( { BL_MASK_TETHERED, F_TETHERED }, { BL_MASK_LEV, F_LEV }, { BL_MASK_FLY, F_FLY }, + { BL_MASK_BAREH, F_BAREH }, + { BL_MASK_GLOWHANDS, F_GLOWHANDS }, + { BL_MASK_ICY, F_ICY }, + { BL_MASK_BUSY, F_BUSY }, + { BL_MASK_PARLYZ, F_PARALYZED }, + { BL_MASK_SLEEPING, F_SLEEPING }, + { BL_MASK_UNCONSC, F_UNCONSCIOUS }, + { BL_MASK_ELF_IRON, F_IRON }, + { BL_MASK_SLIPPERY, F_SLIPPERY }, + { BL_MASK_SUBMERGED, F_SUBMERGED }, + { BL_MASK_WOUNDEDL, F_WOUNDEDL }, { BL_MASK_RIDE, F_RIDE } }; int i; @@ -457,6 +486,7 @@ X11_status_update_fancy( for (i = 0; i < SIZE(mask_to_fancyfield); i++) if ((changed_bits & mask_to_fancyfield[i].mask) != 0L) update_fancy_status_field(mask_to_fancyfield[i].ff, + NULL, condcolor(mask_to_fancyfield[i].mask, colormasks), condattr(mask_to_fancyfield[i].mask, colormasks)); old_condition_bits = X11_condition_bits; /* remember 'On' bits */ @@ -471,7 +501,8 @@ X11_status_update_fancy( for (i = 0; i < SIZE(bl_to_fancyfield); i++) if (bl_to_fancyfield[i].bl == fld) { - update_fancy_status_field(bl_to_fancyfield[i].ff, colr, attr); + update_fancy_status_field(bl_to_fancyfield[i].ff, + (const char *) ptr, colr, attr); break; } @@ -1205,7 +1236,7 @@ struct f_overload { static const struct f_overload *ff_ovld_from_mask(unsigned long); static const struct f_overload *ff_ovld_from_indx(int); -static void update_val(struct X_status_value *, long); +static void update_val(struct X_status_value *, long, const char *); static void skip_cond_val(struct X_status_value *); static void update_color(struct X_status_value *, int); static Pixel color_to_pixel(Widget, int); @@ -1293,6 +1324,20 @@ static struct X_status_value shown_stats[NUM_STATS] = { { "Hallucinat", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, /* F_VERS; optionally shown, generally treated as a pseudo-condition */ { "Version 1.2.3", SV_LABEL, W0, 0L, 0, FALSE, FALSE, FALSE, P0, 0, 0 }, + { "Weapon", SV_NAME, W0, -1L, 0, FALSE, FALSE, FALSE, P0, 0, 0 }, + { "Armor", SV_NAME, W0, -1L, 0, FALSE, FALSE, FALSE, P0, 0, 0 }, + { "Terrain", SV_NAME, W0, -1L, 0, FALSE, FALSE, FALSE, P0, 0, 0 }, + { "BareHands", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "GlowHands", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "Icy", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "Busy", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "Paralyzed", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "Sleeping", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "Unconsc", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "ElfIron", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "Slippery", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "Submerged", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "HurtLegs", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, }; #undef W0 #undef P0 @@ -1325,14 +1370,12 @@ static const struct f_overload cond_ovl[] = { { { BL_MASK_HELD, F_HELD }, { BL_MASK_HOLDING, F_HOLDING } }, }, -#if 0 /* not yet implemented */ - { (BL_MASK_BUSY | BL_MASK_PARALYZ | BL_MASK_SLEEPING | BL_MASK_UNCONSC), + { (BL_MASK_BUSY | BL_MASK_PARLYZ | BL_MASK_SLEEPING | BL_MASK_UNCONSC), { { BL_MASK_BUSY, F_BUSY }, /* can't move but none of the below... */ - { BL_MASK_PARALYZ, F_PARALYZED } - { BL_MASK_SLEEPING, F_SLEEPING } + { BL_MASK_PARLYZ, F_PARALYZED }, + { BL_MASK_SLEEPING, F_SLEEPING }, { BL_MASK_UNCONSC, F_UNCONSCIOUS } }, }, -#endif }; static const struct f_overload * @@ -1398,7 +1441,7 @@ null_out_status(void) DISABLE_WARNING_FORMAT_NONLITERAL static void -update_val(struct X_status_value *attr_rec, long new_value) +update_val(struct X_status_value *attr_rec, long new_value, const char *new_valuestr) { static boolean Exp_shown = TRUE, time_shown = TRUE, score_shown = TRUE, Xp_was_HD = FALSE; @@ -1452,7 +1495,10 @@ update_val(struct X_status_value *attr_rec, long new_value) X11_update_label(attr_rec->w); } else if (attr_rec->type == SV_NAME) { - if (attr_rec->last_value == new_value) + boolean direct = attr_rec == &shown_stats[F_ARMOR] + || attr_rec == &shown_stats[F_WEAPON] + || attr_rec == &shown_stats[F_TERRAIN]; + if (!direct && attr_rec->last_value == new_value) return; /* no change */ attr_rec->last_value = new_value; @@ -1465,6 +1511,11 @@ update_val(struct X_status_value *attr_rec, long new_value) Strcpy(buf, enc_stat[new_value]); } else if (new_value) { Strcpy(buf, attr_rec->name); /* condition name On */ + /* Special cases: weapon, armor and terrain */ + } else if (direct) { + if (new_valuestr == NULL) + return; + Strcpy(buf, new_valuestr); } else { *buf = '\0'; /* condition name Off */ } @@ -1537,7 +1588,7 @@ update_val(struct X_status_value *attr_rec, long new_value) /* core won't call status_update() for Exp when it hasn't changed so do so ourselves (to get Exp_shown flag to match display) */ if (force_update) - update_fancy_status_field(F_EXP_PTS, NO_COLOR, HL_UNDEF); + update_fancy_status_field(F_EXP_PTS, NULL, NO_COLOR, HL_UNDEF); } if (attr_rec->last_value == new_value && !force_update) /* same */ @@ -1598,6 +1649,7 @@ update_val(struct X_status_value *attr_rec, long new_value) already highlighted and being set to blank */ if (attr_rec != &shown_stats[F_TIME] && attr_rec != &shown_stats[F_VERS] + && attr_rec != &shown_stats[F_TERRAIN] && !attr_rec->set ^ !*buf) { if (attr_rec->type == SV_VALUE) X11_set_highlight(get_value_widget(attr_rec->w), TRUE); @@ -1716,7 +1768,7 @@ set_percent(int index, int percent, int color) * [***] version is optional, right-justified after conditions */ static void -update_fancy_status_field(int i, int color, int attributes) +update_fancy_status_field(int i, const char *valstr, int color, int attributes) { struct X_status_value *sv = &shown_stats[i]; unsigned long condmask = 0L; @@ -1816,6 +1868,39 @@ update_fancy_status_field(int i, int color, int attributes) case F_HALLU: condmask = BL_MASK_HALLU; break; + case F_BAREH: + condmask = BL_MASK_BAREH; + break; + case F_GLOWHANDS: + condmask = BL_MASK_GLOWHANDS; + break; + case F_ICY: + condmask = BL_MASK_ICY; + break; + case F_BUSY: + condmask = BL_MASK_BUSY; + break; + case F_PARALYZED: + condmask = BL_MASK_PARLYZ; + break; + case F_SLEEPING: + condmask = BL_MASK_SLEEPING; + break; + case F_UNCONSCIOUS: + condmask = BL_MASK_UNCONSC; + break; + case F_IRON: + condmask = BL_MASK_ELF_IRON; + break; + case F_SLIPPERY: + condmask = BL_MASK_SLIPPERY; + break; + case F_SUBMERGED: + condmask = BL_MASK_SUBMERGED; + break; + case F_WOUNDEDL: + condmask = BL_MASK_WOUNDEDL; + break; /* pseudo-condition */ case F_VERS: @@ -1867,6 +1952,11 @@ update_fancy_status_field(int i, int color, int attributes) val = 0L; #endif break; + case F_WEAPON: + case F_ARMOR: + case F_TERRAIN: + /* valstr is the value */ + break; default: { /* * There is a possible infinite loop that occurs with: @@ -1900,7 +1990,7 @@ update_fancy_status_field(int i, int color, int attributes) return; } } - update_val(sv, val); + update_val(sv, val, valstr); if (color != sv->colr) update_color(sv, color); if (attributes != sv->attr) @@ -1928,7 +2018,7 @@ update_fancy_status(boolean force_update) the no longer displayed field; we're a bit more conservative than that and do this when toggling on as well as off */ for (i = 0; i < NUM_STATS; i++) - update_fancy_status_field(i, NO_COLOR, HL_UNDEF); + update_fancy_status_field(i, NULL, NO_COLOR, HL_UNDEF); old_condition_bits = X11_condition_bits; old_upolyd = Upolyd; @@ -2010,6 +2100,17 @@ width_string(int sv_index) case F_STUN: case F_CONF: case F_HALLU: + case F_BAREH: + case F_GLOWHANDS: + case F_BUSY: + case F_PARALYZED: + case F_SLEEPING: + case F_UNCONSCIOUS: + case F_IRON: + case F_SLIPPERY: + case F_SUBMERGED: + case F_WOUNDEDL: + case F_ICY: return shown_stats[sv_index].name; case F_NAME: @@ -2035,6 +2136,12 @@ width_string(int sv_index) return "123456789"; /* a tenth digit will still fit legibly */ case F_ALIGN: return "Neutral"; + case F_WEAPON: + return "Dual+joust"; + case F_ARMOR: + return "GCAUHBS"; + case F_TERRAIN: + return "Portcullis"; } impossible("width_string: unknown index %d\n", sv_index); return ""; @@ -2224,32 +2331,36 @@ init_column( * two columns and might expand to more if 'hitpointbar' is implemented. * Version is optional, right justified, and much wider than the others. * - Title ("Plname the Rank") <> <> <> <> - Dungeon-Branch-and-Level <> Hunger Grabbed Held - Hit-points Max-HP Strength Encumbrance Petrifying Blind - Power-points Max-Power Dexterity Trapped Slimed Deaf - Armor-class Alignment Constitution Levitation Strangled Stunned - Xp-level [Exp-points] Intelligence Flying Food-Pois Confused - Gold [Score] Wisdom Riding Term-Ill Hallucinat - <> [Time] Charisma <> Sinking Version + Title ("Plname the Rank") <> <> <> <> <> + Dungeon-Branch-and-Level <> Weapon Hunger Grabbed Held + Hit-points Max-HP Strength Armor Encumbrance Petrifying Blind + Power-points Max-Power Dexterity Terrain Trapped Slimed Deaf + Armor-class Alignment Constitution <> Levitation Strangled Stunned + Xp-level [Exp-points] Intelligence <> Flying Food-Pois Confused + Gold [Score] Wisdom <> Riding Term-Ill Hallucinat + <> [Time] Charisma <> <> Sinking Version * - * A seventh column is going to be needed to fit in more conditions. + * An eighth column is going to be needed to fit in more conditions. */ -/* including F_DUMMY makes the three status condition columns evenly +/* including F_DUMMY makes the status condition columns evenly spaced with regard to the adjacent characteristics (Str,Dex,&c) column; we lose track of the Widget pointer for F_DUMMY, each use clobbering the one before, leaving the one from leftover_indices[]; since they're never updated, that shouldn't matter */ -static int status_indices[3][11] = { +static int status_indices[][11] = { + { F_DUMMY, F_WEAPON, F_ARMOR, F_TERRAIN, + F_BAREH, F_GLOWHANDS, F_ICY, F_DUMMY, -1, 0, 0 }, { F_DUMMY, F_HUNGER, F_ENCUMBER, F_TRAPPED, F_LEV, F_FLY, F_RIDE, F_DUMMY, -1, 0, 0 }, { F_DUMMY, F_GRABBED, F_STONE, F_SLIME, F_STRNGL, F_FOODPOIS, F_TERMILL, F_IN_LAVA, -1, 0, 0 }, { F_DUMMY, F_HELD, F_BLIND, F_DEAF, F_STUN, - F_CONF, F_HALLU, F_VERS, -1, 0, 0 }, + F_CONF, F_HALLU, F_DUMMY, -1, 0, 0 }, + { F_DUMMY, F_BUSY, F_IRON, F_SLIPPERY, + F_SUBMERGED, F_WOUNDEDL, F_DUMMY, F_VERS, -1, 0, 0 } }; -/* used to fill up the empty space to right of 3rd status condition column */ +/* used to fill up the empty space to right of last status condition column */ static int leftover_indices[] = { F_DUMMY, -1, 0, 0 }; /* -2: top two rows of these columns are reserved for title and location */ static int col1_indices[11 - 2] = { @@ -2335,7 +2446,7 @@ init_info_form(Widget parent, Widget top, Widget left) return form; } -/* give the three status condition columns the same width */ +/* give the status condition columns the same width */ static void fixup_cond_widths(void) { @@ -2343,7 +2454,7 @@ fixup_cond_widths(void) w1 = w2 = 0; for (pass = 1; pass <= 2; ++pass) { /* two passes... */ - for (i = 0; i < 3; i++) { /* three columns */ + for (i = 0; i < SIZE(status_indices); i++) { for (ip = status_indices[i]; *ip != -1; ++ip) { /* X fields */ /* pass 1: find -1; pass 2: update field widths, find -1 */ if (pass == 2) @@ -2373,11 +2484,11 @@ fixup_cond_widths(void) Dimension vers_width = 0; struct X_status_value *sv = &shown_stats[F_VERS]; - if (sv) { + if (sv->w) { XtSetArg(args[0], XtNwidth, &vers_width); XtGetValues(sv->w, args, ONE); if (vers_width) { - vers_width *= 3; + vers_width *= 2; XtSetArg(args[0], XtNwidth, vers_width); XtSetArg(args[1], nhStr(XtNjustify), XtJustifyRight); XtSetValues(sv->w, args, TWO); @@ -2416,15 +2527,15 @@ create_fancy_status(Widget parent, Widget top) w = init_column("status_characteristics", form, (Widget) 0, w, characteristics_indices, 15); #endif - for (i = 0; i < 3; i++) { + for (i = 0; i < SIZE(status_indices); i++) { Sprintf(buf, "status_condition%d", i + 1); w = init_column(buf, form, (Widget) 0, w, status_indices[i], 0); } - fixup_cond_widths(); /* make all 3 status_conditionN columns same width + fixup_cond_widths(); /* make all status_conditionN columns same width * (actually, the slot for F_VERS is much wider) */ /* TODO: * Calculate and set the width of the F_VERS widjet to be from the - * start of the third condition column through the right edge and + * start of the last condition column through the right edge and * get rid of the dummy column. */ From 0454838d134f5f8589213eba52db9525b2211ad4 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Thu, 13 Aug 2026 00:54:14 -0400 Subject: [PATCH 611/702] Arrange labels more compactly --- win/X11/winstat.c | 69 ++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 30 deletions(-) diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 08d5f7e22..f44f701ee 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -1513,8 +1513,9 @@ update_val(struct X_status_value *attr_rec, long new_value, const char *new_valu Strcpy(buf, attr_rec->name); /* condition name On */ /* Special cases: weapon, armor and terrain */ } else if (direct) { - if (new_valuestr == NULL) + if (new_valuestr == NULL) { return; + } Strcpy(buf, new_valuestr); } else { *buf = '\0'; /* condition name Off */ @@ -2331,16 +2332,19 @@ init_column( * two columns and might expand to more if 'hitpointbar' is implemented. * Version is optional, right justified, and much wider than the others. * - Title ("Plname the Rank") <> <> <> <> <> - Dungeon-Branch-and-Level <> Weapon Hunger Grabbed Held - Hit-points Max-HP Strength Armor Encumbrance Petrifying Blind - Power-points Max-Power Dexterity Terrain Trapped Slimed Deaf - Armor-class Alignment Constitution <> Levitation Strangled Stunned - Xp-level [Exp-points] Intelligence <> Flying Food-Pois Confused - Gold [Score] Wisdom <> Riding Term-Ill Hallucinat - <> [Time] Charisma <> <> Sinking Version + Title ("Plname the Rank") <> <> <> <> + Dungeon-Branch-and-Level <> <> <> <> + Hit-points Max-HP Strength Hunger Grabbed Held + Power-points Max-Power Dexterity Encumbrance Petrifying Blind + Armor-class Alignment Constitution Trapped Slimed Deaf + Xp-level [Exp-points] Intelligence Levitation Strangled Stunned + Gold [Score] Wisdom Flying Food-Pois Confused + <> [Time] Charisma Riding Term-Ill Hallucinat + BareHands <> <> HurtLegs Sinking GlowHands + Weapon Armor Terrain Elf-Iron Busy Icy + <> <> <> Slippery Submerged Version * - * An eighth column is going to be needed to fit in more conditions. + * A seventh column is going to be needed to fit in more conditions. */ /* including F_DUMMY makes the status condition columns evenly @@ -2348,29 +2352,34 @@ init_column( we lose track of the Widget pointer for F_DUMMY, each use clobbering the one before, leaving the one from leftover_indices[]; since they're never updated, that shouldn't matter */ -static int status_indices[][11] = { - { F_DUMMY, F_WEAPON, F_ARMOR, F_TERRAIN, - F_BAREH, F_GLOWHANDS, F_ICY, F_DUMMY, -1, 0, 0 }, +static int status_indices[][13] = { { F_DUMMY, F_HUNGER, F_ENCUMBER, F_TRAPPED, - F_LEV, F_FLY, F_RIDE, F_DUMMY, -1, 0, 0 }, + F_LEV, F_FLY, F_RIDE, F_WOUNDEDL, F_IRON, F_SLIPPERY, + -1, 0, 0 }, { F_DUMMY, F_GRABBED, F_STONE, F_SLIME, F_STRNGL, - F_FOODPOIS, F_TERMILL, F_IN_LAVA, -1, 0, 0 }, + F_FOODPOIS, F_TERMILL, F_IN_LAVA, F_BUSY, F_SUBMERGED, + -1, 0, 0 }, { F_DUMMY, F_HELD, F_BLIND, F_DEAF, F_STUN, - F_CONF, F_HALLU, F_DUMMY, -1, 0, 0 }, - { F_DUMMY, F_BUSY, F_IRON, F_SLIPPERY, - F_SUBMERGED, F_WOUNDEDL, F_DUMMY, F_VERS, -1, 0, 0 } + F_CONF, F_HALLU, F_GLOWHANDS, F_ICY, F_VERS, + -1, 0, 0 }, }; /* used to fill up the empty space to right of last status condition column */ static int leftover_indices[] = { F_DUMMY, -1, 0, 0 }; /* -2: top two rows of these columns are reserved for title and location */ -static int col1_indices[11 - 2] = { - F_HP, F_POWER, F_AC, F_XP_LEVL, F_GOLD, F_DUMMY, -1, 0, 0 +static int col1_indices[13 - 2] = { + F_HP, F_POWER, F_AC, F_XP_LEVL, F_GOLD, F_DUMMY, + F_BAREH, F_WEAPON, F_DUMMY, + -1, 0, 0 }; -static int col2_indices[11 - 2] = { - F_MAXHP, F_MAXPOWER, F_ALIGN, F_EXP_PTS, F_SCORE, F_TIME, -1, 0, 0 +static int col2_indices[13 - 2] = { + F_MAXHP, F_MAXPOWER, F_ALIGN, F_EXP_PTS, F_SCORE, F_TIME, + F_DUMMY, F_ARMOR, F_DUMMY, + -1, 0, 0 }; -static int characteristics_indices[11 - 2] = { - F_STR, F_DEX, F_CON, F_INT, F_WIS, F_CHA, -1, 0, 0 +static int characteristics_indices[13 - 2] = { + F_STR, F_DEX, F_CON, F_INT, F_WIS, F_CHA, + F_DUMMY, F_TERRAIN, F_DUMMY, + -1, 0, 0 }; /* @@ -2378,10 +2387,10 @@ static int characteristics_indices[11 - 2] = { * * title * location - * col1_indices[0] col2_indices[0] col3_indices[0] - * col1_indices[1] col2_indices[1] col3_indices[1] - * ... ... ... - * col1_indices[5] col2_indices[5] col3_indices[5] + * col1_indices[0] col2_indices[0] col3_indices[0] col4_indices[0] + * col1_indices[1] col2_indices[1] col3_indices[1] col4_indices[1] + * ... ... ... ... + * col1_indices[5] col2_indices[5] col3_indices[5] col4_indices[5] * * The status conditions are managed separately and appear to the right * of this form. @@ -2420,7 +2429,7 @@ init_info_form(Widget parent, Widget top, Widget left) XtSetArg(args[num_args], nhStr(XtNfromVert), sv_name->w); num_args++; XtSetValues(sv_dlevel->w, args, num_args); - /* there are 3 columns beneath but top 2 rows are centered over first 2 */ + /* there are 4 columns beneath but top 2 rows are centered over first 2 */ col1 = init_column("name_col1", form, sv_dlevel->w, (Widget) 0, col1_indices, 0); col2 = init_column("name_col2", form, sv_dlevel->w, col1, @@ -2488,7 +2497,7 @@ fixup_cond_widths(void) XtSetArg(args[0], XtNwidth, &vers_width); XtGetValues(sv->w, args, ONE); if (vers_width) { - vers_width *= 2; + vers_width *= 3; XtSetArg(args[0], XtNwidth, vers_width); XtSetArg(args[1], nhStr(XtNjustify), XtJustifyRight); XtSetValues(sv->w, args, TWO); From 4652cd3ae74e1b41e361709d66c13ba1028d35c9 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 14 Aug 2026 11:07:35 +0300 Subject: [PATCH 612/702] Remove extra array indices --- win/X11/winstat.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/win/X11/winstat.c b/win/X11/winstat.c index f44f701ee..ed8f5da42 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -2369,17 +2369,17 @@ static int leftover_indices[] = { F_DUMMY, -1, 0, 0 }; static int col1_indices[13 - 2] = { F_HP, F_POWER, F_AC, F_XP_LEVL, F_GOLD, F_DUMMY, F_BAREH, F_WEAPON, F_DUMMY, - -1, 0, 0 + -1 }; static int col2_indices[13 - 2] = { F_MAXHP, F_MAXPOWER, F_ALIGN, F_EXP_PTS, F_SCORE, F_TIME, F_DUMMY, F_ARMOR, F_DUMMY, - -1, 0, 0 + -1 }; static int characteristics_indices[13 - 2] = { F_STR, F_DEX, F_CON, F_INT, F_WIS, F_CHA, F_DUMMY, F_TERRAIN, F_DUMMY, - -1, 0, 0 + -1 }; /* From 0a6c355678c4f674abb1e0c6d2e7a6cf9e143f54 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 14 Aug 2026 11:07:53 +0300 Subject: [PATCH 613/702] fixes update --- doc/fixes5-0-1.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index c39fb8b45..bfec3b18d 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -242,11 +242,13 @@ Windows: in the event that there is a collision between a menu group accelerator and an individual menu item's accelerator, disregard the group accelerator; only known collision is '$' at this time X11: obey timed_delay -X11: improve TTY-style status line with text attributes for status hilites, +X11: improve status lines with text attributes for status hilites, hitpointbar, some unicode support, 3-line status X11: fix menu windows being taller than the screen X11: allow menu scrolling by pageup/pagedown/home/end keys X11: toggle off perm_invent if user closes the perm inventory window +X11: fix menu group accelerators +X11: implement all text attributes for menus General New Features From 9cf2b1bac9d0253ea85ab54da6102508f7147233 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 16 Aug 2026 07:09:22 -0400 Subject: [PATCH 614/702] early arg support for older platforms The startup had fallen behind NetHack 5.0 startup for other platforms, and lacked support for some of the early command line options. Following this, if PC_EARLY_OPTIONS is defined in pcconf.h, the port will support those options, such as --version, --showpaths, --dumpenums, etc.) Currently, MSDOS #defines's PC_EARLY_OPTIONS, but AMIGA, ATARI, and MAC68K do not. --- include/pcconf.h | 6 +++++- sys/share/pcmain.c | 13 +++++++++++++ sys/share/pcsys.c | 7 +++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/include/pcconf.h b/include/pcconf.h index 8b580b03a..bdcc8e56b 100644 --- a/include/pcconf.h +++ b/include/pcconf.h @@ -148,9 +148,13 @@ LEVELDIR, SAVEDIR, BONESDIR, DATADIR, \ SCOREDIR, LOCKDIR, CONFIGDIR, and TROUBLEDIR. \ */ - #endif /* MSDOS configuration stuff */ +/* include early argument processing --dumpenums etc. */ +#if defined(MSDOS) +#define PC_EARLY_OPTIONS +#endif + #ifndef PATHLEN #define PATHLEN 64 /* maximum pathlength */ #endif diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index 50e7316ab..3f5e2fd5f 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -116,6 +116,10 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ startup(); #endif +#if defined(PC_EARLY_OPTIONS) + program_state.early_options = 1; +#endif + #ifdef TOS if (*argv[0]) { /* only a CLI can give us argv[0] */ gh.hname = argv[0]; @@ -124,6 +128,9 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ #endif gh.hname = "NetHack"; /* used for syntax messages */ +#if defined(PC_EARLY_OPTIONS) + early_init(argc, argv); +#endif choose_windows(DEFAULT_WINDOW_SYS); @@ -266,6 +273,12 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ #endif ami_wininit_data(WININIT); #endif + +#if defined(PC_EARLY_OPTIONS) + early_options(&argc, &argv, &dir); + program_state.early_options = 0; +#endif + initoptions(); #ifdef NOCWD_ASSUMPTIONS diff --git a/sys/share/pcsys.c b/sys/share/pcsys.c index c26b1f4ea..9e9f9aab0 100644 --- a/sys/share/pcsys.c +++ b/sys/share/pcsys.c @@ -155,8 +155,11 @@ getreturn(const char *str) msmsg("Hit %s.", str); #endif #endif - while (pgetchar() != '\n') - ; +#if defined(PC_EARLY_OPTIONS) + if (isatty(STDOUT_FILENO)) +#endif + while (pgetchar() != '\n') + ; return; } From 845603e2d83f15b53bccffd0eb51cec546c47d69 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Fri, 14 Aug 2026 04:16:06 -0400 Subject: [PATCH 615/702] This is cron-daily v1-May-7-2026. 000files updated: Files --- Files | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Files b/Files index 89e6cb0b9..4b1a0c08e 100644 --- a/Files +++ b/Files @@ -606,8 +606,9 @@ Install.X11 NetHack.ad Window.c X11-issues.txt dialogs.c ibm.bdf nethack.rc nh10.bdf nh32icon nh56icon nh72icon nh_icon.xpm pet_mark.xbm pilemark.xbm rip.xpm tile2x11.c -winX.c winmap.c winmenu.c winmesg.c -winmisc.c winstat.c wintext.c winval.c +winX.c winlabel.c winmap.c winmenu.c +winmesg.c winmisc.c winstat.c wintext.c +winval.c win/chain: (files for stacking window systems) From f11b65c6802ab8294d88f8dd94cf75d34781bc91 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 16 Aug 2026 10:31:31 -0400 Subject: [PATCH 616/702] don't call it "your pet" until after it is tamed Reported directly to devteam, the code was using "Your little dog devours the tripe ration" during the taming process, prior to the pet becoming yours. --- include/extern.h | 2 ++ src/do_name.c | 18 ++++++++++++++++++ src/dogmove.c | 6 ++++-- src/zap.c | 2 +- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/include/extern.h b/include/extern.h index a2ff304da..ade96f43c 100644 --- a/include/extern.h +++ b/include/extern.h @@ -707,9 +707,11 @@ extern char *x_monnam(struct monst *, int, const char *, int, boolean) NONNULLAR extern char *l_monnam(struct monst *) NONNULLARG1; extern char *mon_nam(struct monst *) NONNULLARG1; extern char *noit_mon_nam(struct monst *) NONNULLARG1; +extern char *noit_or_your_mon_nam(struct monst *) NONNULLARG1; extern char *some_mon_nam(struct monst *) NONNULLARG1; extern char *Monnam(struct monst *) NONNULLARG1; extern char *noit_Monnam(struct monst *) NONNULLARG1; +extern char *noit_or_your_Monnam(struct monst *) NONNULLARG1; extern char *Some_Monnam(struct monst *) NONNULLARG1; extern char *noname_monnam(struct monst *, int) NONNULLARG1; extern char *m_monnam(struct monst *) NONNULLARG1; diff --git a/src/do_name.c b/src/do_name.c index d3943b7cf..76dbae9bc 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1059,6 +1059,15 @@ noit_mon_nam(struct monst *mtmp) FALSE); } +char * +noit_or_your_mon_nam(struct monst *mtmp) +{ + return x_monnam(mtmp, ARTICLE_THE, (char *) 0, + (has_mgivenname(mtmp) ? (SUPPRESS_SADDLE | SUPPRESS_IT) + : SUPPRESS_IT), + FALSE); +} + /* in between noit_mon_nam() and mon_nam(); if the latter would pick "it", use "someone" (for humanoids) or "something" (for others) instead */ char * @@ -1088,6 +1097,15 @@ noit_Monnam(struct monst *mtmp) return bp; } +char * +noit_or_your_Monnam(struct monst *mtmp) +{ + char *bp = noit_or_your_mon_nam(mtmp); + + *bp = highc(*bp); + return bp; +} + char * Some_Monnam(struct monst *mtmp) { diff --git a/src/dogmove.c b/src/dogmove.c index ad499b7f4..9c18b93ff 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -286,8 +286,10 @@ dog_eat(struct monst *mtmp, if (tunnels(mtmp->data)) pline_mon(mtmp, "%s digs in.", noit_Monnam(mtmp)); else - pline_mon(mtmp, "%s %s %s.", noit_Monnam(mtmp), - devour ? "devours" : "eats", obj_name); + pline_mon(mtmp, "%s %s %s.", + devour ? noit_or_your_Monnam(mtmp) + : noit_Monnam(mtmp), + devour ? "devours" : "eats", obj_name); } else if (seeobj) { obj_name = distant_name(obj, doname); pline("It %s %s.", devour ? "devours" : "eats", obj_name); diff --git a/src/zap.c b/src/zap.c index dca9a97c0..261fd3914 100644 --- a/src/zap.c +++ b/src/zap.c @@ -3586,7 +3586,7 @@ miss(const char *str, struct monst *mtmp) { pline("%s %s %s.", The(str), vtense(str, "miss"), ((cansee(gb.bhitpos.x, gb.bhitpos.y) || canspotmon(mtmp)) - && flags.verbose) ? mon_nam(mtmp) : "it"); + && flags.verbose) ? ((mtmp->mtame) ? noit_mon_nam(mtmp) : mon_nam(mtmp)) : "it"); } staticfn void From d8ea2087bc5255a761ea50137a2f5e8019a1abd4 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 16 Aug 2026 10:35:31 -0400 Subject: [PATCH 617/702] fixes5-0-1.txt update for prior commit --- doc/fixes5-0-1.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index bfec3b18d..67cfaed49 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -79,6 +79,7 @@ stethoscope applied to one monster disguised as another (double-trouble Wizard) 064523e162f8e30bdb76186a854b9d8958f3b340) mon_offmap() and place_monster() needed to operate on the same mstate bits food_disappears() needed to include a tin check +don't refer to pet as "Your pet" until after the taming process has finished Platform- and/or Interface-Specific Fixes From 370c282240f97d36032d5fa0caa2524dd0633886 Mon Sep 17 00:00:00 2001 From: k21971 Date: Tue, 18 Aug 2026 00:30:23 +0000 Subject: [PATCH 618/702] Fix: first INSURANCE checkpoint is never written. savestateinlock() returns early unless program_state.something_worth_saving is set, but both call sites that are meant to lay down the initial checkpoint run before that flag is set: newgame() calls save_currentstate() two lines early, and dorecover() calls savestateinlock() 73 lines before it, ahead of the pass that writes out the level files. Both calls are therefore no-ops, and the .0 lock file holds nothing but the pid written by getlock() until the hero first changes dungeon level. A game that dies without a chance to save during that window (SIGKILL, OOM killer, watchdog, host reboot) cannot be rebuilt: recover has no save file name, no current level number and no game state, and reports "Checkpointing was not in effect", which is true of the outcome but misleading about the cause. The window covers the whole of a long stay on one level, and in particular the entire period right after a restore. Set the flag before the call in newgame(). In dorecover(), drop the ineffective call and checkpoint once the restore is complete instead; at the original spot no level file for this session has been written yet, so a checkpoint there would name a current level and save file that are not on disk. The new call goes after program_state.restoring is cleared, so that stairs and traps are written with the same relative dlevel encoding a normal save uses, and it is save_currentstate() rather than savestateinlock() so that in_checkpoint is set while savegamestate() writes u.ustuck_mid and u.usteed_mid. This arrived with the something_worth_saving guard; 3.4.3, which has no guard, is unaffected. Looks like this issue has been around since version 3.6.0. --- src/allmain.c | 2 +- src/restore.c | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/allmain.c b/src/allmain.c index 8f747564a..4177cd0cd 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -872,10 +872,10 @@ newgame(void) urealtime.realtime = 0L; urealtime.start_timing = getnow(); + program_state.something_worth_saving++; /* useful data now exists */ #ifdef INSURANCE save_currentstate(); #endif - program_state.something_worth_saving++; /* useful data now exists */ /* Success! */ welcome(TRUE); diff --git a/src/restore.c b/src/restore.c index 8a7ad8743..48e851dc6 100644 --- a/src/restore.c +++ b/src/restore.c @@ -843,9 +843,6 @@ dorecover(NHFILE *nhfp) init_oclass_probs(); /* recompute go.oclass_prob_totals[] */ restlevelstate(); -#ifdef INSURANCE - savestateinlock(); -#endif rtmp = restlevelfile(ledger_no(&u.uz)); if (rtmp < 2) return rtmp; /* dorecover called recursively */ @@ -953,6 +950,12 @@ dorecover(NHFILE *nhfp) run_timers(); /* expire all timers that have gone off while away */ program_state.restoring = 0; /* affects bot() so clear before docrt() */ +#ifdef INSURANCE + /* first checkpoint of the restored session; every level file has been + written and the current level has been read back in, so recover has + something to work with even if the player never changes level */ + save_currentstate(); +#endif if (ge.early_raw_messages && !program_state.beyond_savefile_load) { /* From 7c13477d33be7ac075e445e8a99522ef6affb7fa Mon Sep 17 00:00:00 2001 From: k21971 Date: Tue, 18 Aug 2026 00:30:41 +0000 Subject: [PATCH 619/702] Fix: don't leak in_checkpoint on a failed level write. save_currentstate() increments program_state.in_checkpoint and then returns early without decrementing it when currentlevel_rewrite() fails (full disk, quota, unwritable directory). The guard at the top of the function suppresses every later checkpoint for the rest of the game, leaving recover with nothing newer than the last checkpoint that did get written, and nothing says so. --- src/do.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/do.c b/src/do.c index 5de166814..bd1e18286 100644 --- a/src/do.c +++ b/src/do.c @@ -1385,8 +1385,10 @@ save_currentstate(void) if (flags.ins_chkpt) { /* write out just-attained level, with pets and everything */ nhfp = currentlevel_rewrite(); - if (!nhfp) + if (!nhfp) { + program_state.in_checkpoint--; return; + } if (nhfp->structlevel) bufon(nhfp->fd); nhfp->mode = WRITING; From ef5beb917af81ab1a955b50bf583e18fb976722f Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 17 Aug 2026 21:25:34 -0400 Subject: [PATCH 620/702] fixes5-0-1.txt catch-up --- doc/fixes5-0-1.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 67cfaed49..6e4038f84 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -79,7 +79,10 @@ stethoscope applied to one monster disguised as another (double-trouble Wizard) 064523e162f8e30bdb76186a854b9d8958f3b340) mon_offmap() and place_monster() needed to operate on the same mstate bits food_disappears() needed to include a tin check +cmdstr[] buffer was not being initialized in handler_rebind_keys_add() +don't catch thrown objects while asleep don't refer to pet as "Your pet" until after the taming process has finished +checkpoint fixes (pr #1660 by k21971) Platform- and/or Interface-Specific Fixes @@ -214,7 +217,11 @@ MS-DOS: Define a separate palette for VGA text (pr #1620 by chasonr) MS-DOS: some conditional cleanup for SUPPRESS_GRAPHICS, TILES_IN_GLYPHMAP, NO_TILES, WANT_WIN_CURSES=1 without WANT_WIN_TTY=1 (pr #1632 by chasonr) -MS-DOS: add some hilite_pet and hilite_pile support to tiled display +MS-DOS: support decals in all VESA modes and in 16 color mode; support + decals in the overview modes as well as the normal map mode; + provide correct highlighting for vga_redrawmap and vesa_redrawmap; + provide the hilite_pet and hilite_pile flags in the default + configuration file (pr #1649 by chasonr) musl: musl libc does not have __sighandler_t so don't use it in the macro definition for SIG_RET_TYPE with musl tty: allow custom glyph colors if they're basic 16 nethack colors From 23315cf8571977bd02210fcdbf1abb7bb122a4b3 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Mon, 17 Aug 2026 19:27:00 -0400 Subject: [PATCH 621/702] Combine XLoadFont and XQueryFont calls The separate calls crash if the font does not exist; the combined call returns NULL, as the caller expects. Resolves #1508 and possibly #569. --- win/X11/winX.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/win/X11/winX.c b/win/X11/winX.c index 77b84ae78..1a86c3b3d 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -3125,8 +3125,7 @@ X11_unicode_font(Display *display, XFontStruct *font) strcpy(unicode_font + len, "iso10646-1"); font_name = unicode_font; - Font font_id = XLoadFont(display, font_name); - XFontStruct *unifont = XQueryFont(display, font_id); + XFontStruct *unifont = XLoadQueryFont(display, font_name); return unifont; } #endif /* ENHANCED_SYMBOLS */ From 9de03944e8f411539c7d31c382acc39c8bd26e3d Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 18 Aug 2026 13:42:24 +0300 Subject: [PATCH 622/702] fixes update --- doc/fixes5-0-1.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 6e4038f84..56675db80 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -257,6 +257,7 @@ X11: allow menu scrolling by pageup/pagedown/home/end keys X11: toggle off perm_invent if user closes the perm inventory window X11: fix menu group accelerators X11: implement all text attributes for menus +X11: fix crash when loading a nonexistent font General New Features From 4474d3cb2ae58f5be37ea96ba4335c70caccb034 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 18 Aug 2026 07:54:46 -0400 Subject: [PATCH 623/702] pcmain.c: remove added second early_init() call early_init() was already being called at pcmain.c line 70, so the recently added call at line 132 was problematic because it cleared program_state values that had been intentionally set since the call at line 70. --- sys/share/pcmain.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index 3f5e2fd5f..d0f671930 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -128,12 +128,8 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ #endif gh.hname = "NetHack"; /* used for syntax messages */ -#if defined(PC_EARLY_OPTIONS) - early_init(argc, argv); -#endif choose_windows(DEFAULT_WINDOW_SYS); - #if !defined(AMIGA) && !defined(GNUDOS) /* Save current directory and make sure it gets restored when * the game is exited. From f6a592b7f9c86d68c609e45642d3952afbb274e7 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 18 Aug 2026 10:24:35 -0400 Subject: [PATCH 624/702] glob nutrition should match owt reduction reported directly to devteam as an impossible() call within eaten_stat() (internal tracking number 3216) --- doc/fixes5-0-1.txt | 2 ++ src/mkobj.c | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 56675db80..2feee9be0 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -83,6 +83,8 @@ cmdstr[] buffer was not being initialized in handler_rebind_keys_add() don't catch thrown objects while asleep don't refer to pet as "Your pet" until after the taming process has finished checkpoint fixes (pr #1660 by k21971) +upon return to a level, catch up on remaining nutrition value by the same + percentage as the catch up for the weight Platform- and/or Interface-Specific Fixes diff --git a/src/mkobj.c b/src/mkobj.c index 47bfc4108..2ed92d009 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1510,7 +1510,7 @@ shrink_glob( shrink = FALSE, gone = FALSE, updinv = FALSE; struct obj *contnr = (obj->where == OBJ_CONTAINED) ? obj->ocontainer : 0, *topcontnr = 0; - unsigned old_top_owt = 0; + unsigned old_top_owt = 0, old_owt = obj->owt; if (!obj->globby) { impossible("shrink_glob for non-glob [%d: %s]?", @@ -1539,12 +1539,25 @@ shrink_glob( obj->owt = 0; /* not required; accurately reflects obj's state */ shrinking_glob_gone(obj); } else { - /* shrank but not gone; reduce remaining weight */ + + /* shrank but not gone; reduce remaining weight + and food-content (if needed) */ obj->owt -= (unsigned) delta; /* when contained, update container's weight (recursively if nested); won't be in a container carried by hero (since catching up for lost time never applies in that situation) but might be in one on floor or one carried by a monster */ + if (old_owt && obj->oeaten) { + unsigned percent_reduction = 100 - ((obj->owt * 100) / old_owt), + oeaten_reduction; + + /* reduce remaining nutrition by same percentage */ + oeaten_reduction = (percent_reduction * obj->oeaten + 50) / 100; + + if (oeaten_reduction <= obj->oeaten) + obj->oeaten -= oeaten_reduction; + + } if (contnr) container_weight(contnr); /* resume regular shrinking */ @@ -1674,6 +1687,8 @@ shrinking_glob_gone(struct obj *obj) { xint16 owhere = obj->where; + /* obfree() should take care of eating_glob() food fixups */ + if (owhere == OBJ_INVENT) { if (obj->owornmask) { remove_worn_item(obj, FALSE); From d44b6385d7fd3a063c3416c1a870c15d8da01a90 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 18 Aug 2026 19:44:45 +0300 Subject: [PATCH 625/702] Don't complain about MAXPLAYERS with unknown command line param Unix command line handling treated an unknown command line parameter as a maximum number of allowed concurrent players. This emitted a complaint about expected MAXPLAYERS, and as it can be now set in sysconf, remove this - most likely unused - functionality. --- doc/fixes5-0-1.txt | 1 + sys/unix/unixmain.c | 18 ++---------------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 2feee9be0..8a827c5d2 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -260,6 +260,7 @@ X11: toggle off perm_invent if user closes the perm inventory window X11: fix menu group accelerators X11: implement all text attributes for menus X11: fix crash when loading a nonexistent font +Unix: don't complain about MAXPLAYERS with unknown command line param General New Features diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 6cad795d8..c712b08e6 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -454,22 +454,8 @@ process_options(int argc, char *argv[]) } } - if (argc > 1) { - int mxplyrs = atoi(argv[1]); - boolean mx_ok = (mxplyrs > 0); -#ifdef SYSCF - config_error_add("%s%s%s", - mx_ok ? "MAXPLAYERS are set in sysconf file" - : "Expected MAXPLAYERS, found \"", - mx_ok ? "" : argv[1], mx_ok ? "" : "\""); -#else - /* XXX This is deprecated in favor of SYSCF with MAXPLAYERS */ - if (mx_ok) - gl.locknum = mxplyrs; - else - config_error_add("Invalid MAXPLAYERS \"%s\"", argv[1]); -#endif - } + if (argc > 1) + config_error_add("Unknown option: %.60s", origarg); #ifdef MAX_NR_OF_PLAYERS /* limit to compile-time limit */ if (!gl.locknum || gl.locknum > MAX_NR_OF_PLAYERS) From fbc586bf44047abdcd81182d2a3fb0d5cf0c05fd Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Fri, 14 Aug 2026 19:03:13 -0400 Subject: [PATCH 626/702] Convert map to use Xft --- include/winX.h | 20 ++++ sys/unix/hints/linux.500 | 5 + sys/unix/hints/macOS.500 | 5 + win/X11/NetHack.ad | 12 +++ win/X11/winX.c | 144 ++++++++++++++++++++++++++++ win/X11/winmap.c | 197 ++++++++++++++++++++++++++++++--------- 6 files changed, 341 insertions(+), 42 deletions(-) diff --git a/include/winX.h b/include/winX.h index 2a62f892e..0754ffaef 100644 --- a/include/winX.h +++ b/include/winX.h @@ -9,6 +9,10 @@ #ifndef WINX_H #define WINX_H +#ifdef USE_XFT +#include +#endif + #ifndef COLOR_H #include "color.h" /* CLR_MAX */ #endif @@ -317,6 +321,16 @@ typedef struct { Pixel pet_mark_color; /* color of pet mark */ String pilemark_bitmap; /* X11 bitmap file used to mark item piles */ Pixel pilemark_color; /* color of item pile mark */ +#ifdef USE_XFT + String font_map; /* font for the map */ + String font_menu; /* font for menus */ + String font_message; /* font for the message window */ + String font_status; /* font for the status window */ + String font_text; /* font for text windows */ +#ifdef GRAPHIC_TOMBSTONE + String font_rip; /* font for tombstone */ +#endif +#endif #ifdef GRAPHIC_TOMBSTONE String tombstone; /* name of XPM file for tombstone */ int tombtext_x; /* x-coord of center of first tombstone text */ @@ -525,6 +539,12 @@ extern XFontStruct *X11_italic_font(Display *, XFontStruct *); extern XFontStruct *X11_unicode_font(Display *, XFontStruct *); #endif +#ifdef USE_XFT +extern XftFont *X11_new_font(Widget w, boolean bold, int win_type); +extern void X11_release_font(Widget w, XftFont *font); +extern void X11_new_color(Widget w, Pixel pixel, XftColor *color); +#endif + /* ### winlabel.c ### */ /* Functions for management of enhanced labels */ extern void X11_wrap_widget(Widget); diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index c786f4f62..45da9ee12 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -397,6 +397,7 @@ endif # MAKEFILE_SRC ifdef WANT_WIN_X11 USE_XPM=1 +USE_XFT=1 WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm ifndef CROSSCOMPILE @@ -408,6 +409,10 @@ POSTINSTALL += bdftopcf win/X11/nh10.bdf > $(HACKDIR)/nh10.pcf; ( cd $(HACKDIR); X11CFLAGS = -I/opt/X11/include # avoid repeated complaints about _X_NONNULL(args...) in X11CFLAGS += -Wno-variadic-macros +ifdef USE_XFT +X11CFLAGS += -DUSE_XFT $(shell pkg-config --cflags xft fontconfig) +WINX11LIB += $(shell pkg-config --libs xft fontconfig) +endif ifdef USE_XPM CFLAGS += -DUSE_XPM WINX11LIB += -lXpm diff --git a/sys/unix/hints/macOS.500 b/sys/unix/hints/macOS.500 index be6402ace..223dfb7c3 100755 --- a/sys/unix/hints/macOS.500 +++ b/sys/unix/hints/macOS.500 @@ -277,6 +277,7 @@ HINTOBJ=$(CHAINOBJ) endif # WANT_WIN_CHAIN ifdef WANT_WIN_X11 +USE_XFT=1 USE_XPM=1 WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm @@ -287,6 +288,10 @@ POSTINSTALL += bdftopcf win/X11/nh10.bdf > $(HACKDIR)/nh10.pcf; ( cd $(HACKDIR); X11CFLAGS = -I/opt/X11/include # avoid repeated complaints about _X_NONNULL(args...) in X11CFLAGS += -Wno-variadic-macros +ifdef USE_XFT +X11CFLAGS += -DUSE_XFT $(shell pkg-config --cflags xft fontconfig) +WINX11LIB += $(shell pkg-config --libs xft fontconfig) +endif ifdef USE_XPM CFLAGS += -DUSE_XPM WINX11LIB += -lXpm diff --git a/win/X11/NetHack.ad b/win/X11/NetHack.ad index ecd654034..f12110f6f 100644 --- a/win/X11/NetHack.ad +++ b/win/X11/NetHack.ad @@ -27,6 +27,18 @@ NetHack*tombstone*font: NETHACK_FONT NetHack*text*rip*font: -*-times-medium-r-*-*-12-*-*-*-*-*-*-* NetHack*text*borderWidth: 0 +! Vector font to be used if Xft support is enabled +! These correspond to the .nethackrc settings font_map, font_menu, +! font_message, font_status and font_text +NetHack.font_map: mono-10 +NetHack.font_menu: mono-10 +NetHack.font_message: sans-10 +NetHack.font_status: sans-10 +NetHack.font_text: mono-10 + +! No .nethackrc setting for this, but it gets the right size +NetHack.font_rip: sans-9 + ! tile_file names a file containing full-color tiles for the map. ! If you use a 100dpi (or greater) monitor you may wish to double the ! tile size so you can see the figures. If NetHack was compiled to diff --git a/win/X11/winX.c b/win/X11/winX.c index 1a86c3b3d..4596190b4 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -1513,6 +1513,22 @@ static XtResource resources[] = { { nhStr("pilemark_color"), nhStr("Pilemark_color"), XtRPixel, sizeof(XtRPixel), XtOffset(AppResources *, pilemark_color), XtRString, nhStr("Green") }, +#ifdef USE_XFT + { nhStr("font_map"), nhStr("Font_map"), XtRString, sizeof(String), + XtOffset(AppResources *, font_map), XtRString, nhStr("mono-10") }, + { nhStr("font_menu"), nhStr("Font_menu"), XtRString, sizeof(String), + XtOffset(AppResources *, font_menu), XtRString, nhStr("mono-10") }, + { nhStr("font_message"), nhStr("Font_message"), XtRString, sizeof(String), + XtOffset(AppResources *, font_message), XtRString, nhStr("sans-10") }, + { nhStr("font_status"), nhStr("Font_status"), XtRString, sizeof(String), + XtOffset(AppResources *, font_status), XtRString, nhStr("sans-10") }, + { nhStr("font_text"), nhStr("Font_text"), XtRString, sizeof(String), + XtOffset(AppResources *, font_text), XtRString, nhStr("mono-10") }, +#ifdef GRAPHIC_TOMBSTONE + { nhStr("font_rip"), nhStr("Font_rip"), XtRString, sizeof(String), + XtOffset(AppResources *, font_rip), XtRString, nhStr("sans-9") }, +#endif +#endif #ifdef GRAPHIC_TOMBSTONE { nhStr("tombstone"), nhStr("Tombstone"), XtRString, sizeof(String), XtOffset(AppResources *, tombstone), XtRString, nhStr("rip.xpm") }, @@ -3130,4 +3146,132 @@ X11_unicode_font(Display *display, XFontStruct *font) } #endif /* ENHANCED_SYMBOLS */ +#ifdef USE_XFT + +/* Open a vector font for the given widget */ + +extern XftFont * +X11_new_font(Widget w, boolean bold, int win_type) +{ + const char *font_name = NULL; + const char *iflags_font_name = NULL; + int font_size = 0; + char name[512]; + + switch (win_type) { + case NHW_MESSAGE: + font_name = appResources.font_message; + iflags_font_name = iflags.wc_font_message; + font_size = iflags.wc_fontsiz_message; + break; + + case NHW_STATUS: + font_name = appResources.font_status; + iflags_font_name = iflags.wc_font_status; + font_size = iflags.wc_fontsiz_status; + break; + + case NHW_MAP: + font_name = appResources.font_map; + iflags_font_name = iflags.wc_font_map; + font_size = iflags.wc_fontsiz_map; + break; + + case NHW_MENU: + case NHW_PERMINVENT: + font_name = appResources.font_menu; + iflags_font_name = iflags.wc_font_menu; + font_size = iflags.wc_fontsiz_menu; + break; + + case NHW_TEXT: + font_name = appResources.font_text; + iflags_font_name = iflags.wc_font_text; + font_size = iflags.wc_fontsiz_text; + break; + + default: + break; + } + + if (font_name == NULL) { + font_name = "mono-10"; + } + + /* Override the font name if specified in the configuration file */ + if (iflags_font_name != NULL) { + font_name = iflags_font_name; + } + + /* + * Specify font size as follows: + * * Use any font size specified in the configuration file + * * If no such size is specified, use the one in the font name; + * e.g., "Courier-14" specifies 14 points + * * If still no size, use 10 points + */ + size_t name_len = strlen(font_name); + const char *dash = strrchr(font_name, '-'); + if (dash) { + char *end; + long size = strtol(dash + 1, &end, 10); + if (*end == '\0') { + /* The name ends in a size */ + name_len = (size_t) (dash - font_name); + /* Use font_size if specified; + else use the size from font_name */ + if (font_size <= 0) { + font_size = (int) size; + } + } + } + + /* Use 10 if no size specified */ + if (font_size <= 0) { + font_size = 10; + } + + /* Set reasonable bounds on the font size */ + font_size = min(max(font_size, 6), 50); + + Snprintf(name, sizeof(name), "%.*s-%d:%s", + (int) name_len, font_name, font_size, + bold ? "bold" : "medium"); + + Display *display = XtDisplay(w); + XftFont *font = XftFontOpenName(display, DefaultScreen(display), name); + + return font; +} + +/* Free the font returned by X11_new_font */ + +void +X11_release_font(Widget w, XftFont *font) +{ + Display *display = XtDisplay(w); + XftFontClose(display, font); +} + +/* Assign a new color having the given RGB components */ + +void +X11_new_color(Widget w, Pixel pixel, XftColor *color) +{ + XRenderColor rcolor; + rcolor.red = ((pixel >> 16) & 0xFF) * 0x0101; + rcolor.green = ((pixel >> 8) & 0xFF) * 0x0101; + rcolor.blue = ((pixel >> 0) & 0xFF) * 0x0101; + rcolor.alpha = 0xFFFF; + + Display *display = XtDisplay(w); + Screen *screen = DefaultScreenOfDisplay(display); + Visual *visual = DefaultVisualOfScreen(screen); + Colormap cmap = DefaultColormapOfScreen(screen); + + XftColorAllocValue(display, visual, cmap, &rcolor, color); +} + +#endif /* USE_XFT */ + /*winX.c*/ diff --git a/win/X11/winmap.c b/win/X11/winmap.c index a99ebef5a..3befe1887 100644 --- a/win/X11/winmap.c +++ b/win/X11/winmap.c @@ -59,17 +59,23 @@ extern int total_tiles_used, Tile_corr; #define NH_INVERSE_COLOR 0x40000000 #define NH_ENHANCED_COLOR 0x80000000 +#ifdef USE_XFT +static void X11_get_color(struct xwindow *wp, X11_color nhcolor, XftColor *color); +static void X11_draw_image_string(XftDraw *draw, XftFont *font, + XftColor *fgcolor, XftColor *bgcolor, + int x, int y, + const X11_map_symbol *string, int length); +#else /* !USE_XFT */ static GC X11_make_gc(struct xwindow *wp, struct text_map_info_t *text_map, X11_color color, boolean inverted); -#ifdef ENHANCED_SYMBOLS static void X11_free_gc(struct xwindow *wp, GC gc, X11_color color); -#endif -#ifdef ENHANCED_SYMBOLS -static void X11_set_map_font(struct xwindow *wp); -#endif static void X11_draw_image_string(Display *display, Drawable d, GC ggc, int x, int y, const X11_map_symbol *string, int length); +#endif /* ?USE_XFT */ +#ifdef ENHANCED_SYMBOLS +static void X11_set_map_font(struct xwindow *wp); +#endif static Font X11_get_map_font(struct xwindow *wp); static XFontStruct *X11_get_map_font_struct(struct xwindow *wp); static boolean init_tiles(struct xwindow *); @@ -1031,6 +1037,16 @@ clear_map_window(struct xwindow *wp) static void get_char_info(struct xwindow *wp) { +#ifdef USE_XFT + struct map_info_t *map_info = wp->map_information; + struct text_map_info_t *text_map = &map_info->text_map; + XftFont *font = X11_new_font(wp->w, FALSE, NHW_MAP); + text_map->square_width = font->max_advance_width; + text_map->square_height = font->height; + text_map->square_ascent = 0; + text_map->square_lbearing = 0; + X11_release_font(wp->w, font); +#else /* !USE_XFT */ XFontStruct *fs; struct map_info_t *map_info = wp->map_information; struct text_map_info_t *text_map = &map_info->text_map; @@ -1062,6 +1078,7 @@ get_char_info(struct xwindow *wp) if (fs->min_bounds.width != fs->max_bounds.width) X11_raw_print("Warning: map font is not monospaced!"); +#endif /* ?USE_XFT */ } /* @@ -1400,48 +1417,142 @@ map_update(struct xwindow *wp, int start_row, int stop_row, int start_col, int s } else { struct text_map_info_t *text_map = &map_info->text_map; - { - X11_color *c_ptr; - X11_map_symbol *t_ptr; - int cur_col, win_ystart; - X11_color color; - GC ggc; +#ifdef USE_XFT + /* Set up font and background color */ + Display *display = XtDisplay(wp->w); + Screen *screen = DefaultScreenOfDisplay(display); + Visual *visual = DefaultVisualOfScreen(screen); + Colormap cmap = DefaultColormapOfScreen(screen); - for (row = start_row; row <= stop_row; row++) { - win_ystart = - text_map->square_ascent + (row * text_map->square_height); + Pixel bgpixel; + Arg arg[1]; + XtSetArg(arg[0], XtNbackground, &bgpixel); + XtGetValues(wp->w, arg, 1); - t_ptr = &(text_map->text[row][start_col]); - c_ptr = &(text_map->colors[row][start_col]); - cur_col = start_col; - while (cur_col <= stop_col) { - color = *c_ptr++; - count = 1; - while ((cur_col + count) <= stop_col && *c_ptr == color) { - count++; - c_ptr++; - } + XftDraw *draw = XftDrawCreate(display, XtWindow(wp->w), visual, cmap); + XftFont *font = X11_new_font(wp->w, FALSE, NHW_MAP); + XftColor bgcolor; + X11_new_color(wp->w, bgpixel, &bgcolor); +#endif /* USE_XFT */ - ggc = X11_make_gc(wp, text_map, color, inverted); - X11_draw_image_string(XtDisplay(wp->w), XtWindow(wp->w), - ggc, - text_map->square_lbearing - + (text_map->square_width - * (cur_col - COL0_OFFSET)), - win_ystart, t_ptr, count); -#ifdef ENHANCED_SYMBOLS - X11_free_gc(wp, ggc, color); -#endif + for (row = start_row; row <= stop_row; row++) { + int win_ystart = + text_map->square_ascent + (row * text_map->square_height); - /* move text pointer and column count */ - t_ptr += count; - cur_col += count; - } /* col loop */ - } /* row loop */ - } + X11_map_symbol *t_ptr = &(text_map->text[row][start_col]); + X11_color *c_ptr = &(text_map->colors[row][start_col]); + int cur_col = start_col; + while (cur_col <= stop_col) { + X11_color color = *c_ptr++; + count = 1; + while ((cur_col + count) <= stop_col && *c_ptr == color) { + count++; + c_ptr++; + } + +#ifdef USE_XFT + XftColor fgcolor; + X11_get_color(wp, color, &fgcolor); + boolean cur_inv = !!inverted ^ ((color & NH_INVERSE_COLOR) != 0); + X11_draw_image_string(draw, font, + cur_inv ? &bgcolor : &fgcolor, + cur_inv ? &fgcolor : &bgcolor, + text_map->square_lbearing + + (text_map->square_width + * (cur_col - COL0_OFFSET)), + win_ystart, t_ptr, count); + XftColorFree(display, visual, cmap, &fgcolor); +#else /* !USE_XFT */ + GC ggc = X11_make_gc(wp, text_map, color, inverted); + X11_draw_image_string(XtDisplay(wp->w), XtWindow(wp->w), + ggc, + text_map->square_lbearing + + (text_map->square_width + * (cur_col - COL0_OFFSET)), + win_ystart, t_ptr, count); + X11_free_gc(wp, ggc, color); +#endif /* ?USE_XFT */ + + /* move text pointer and column count */ + t_ptr += count; + cur_col += count; + } /* col loop */ + } /* row loop */ + +#ifdef USE_XFT + /* Free resources from Xft */ + XftColorFree(display, visual, cmap, &bgcolor); + X11_release_font(wp->w, font); + XftDrawDestroy(draw); +#endif /* USE_XFT */ } } +#ifdef USE_XFT +static void +X11_get_color(struct xwindow *wp, X11_color nhcolor, XftColor *color) +{ + Pixel pixel; + + if ((nhcolor & NH_ENHANCED_COLOR) != 0) { + pixel = COLORVAL(nhcolor); + } else { + static struct { + const char *name; + Pixel rgb; + } map_colors[] = { + { XtNblack, 0xFFFFFFFF }, /* CLR_BLACK */ + { XtNred, 0xFFFFFFFF }, /* CLR_RED */ + { XtNgreen, 0xFFFFFFFF }, /* CLR_GREEN */ + { XtNbrown, 0xFFFFFFFF }, /* CLR_BROWN */ + { XtNblue, 0xFFFFFFFF }, /* CLR_BLUE */ + { XtNmagenta, 0xFFFFFFFF }, /* CLR_MAGENTA */ + { XtNcyan, 0xFFFFFFFF }, /* CLR_CYAN */ + { XtNgray, 0xFFFFFFFF }, /* CLR_GRAY */ + { XtNforeground, 0xFFFFFFFF }, /* NO_COLOR */ + { XtNorange, 0xFFFFFFFF }, /* CLR_ORANGE */ + { XtNbright_green, 0xFFFFFFFF }, /* CLR_BRIGHT_GREEN */ + { XtNyellow, 0xFFFFFFFF }, /* CLR_YELLOW */ + { XtNbright_blue, 0xFFFFFFFF }, /* CLR_BRIGHT_BLUE */ + { XtNbright_magenta, 0xFFFFFFFF }, /* CLR_BRIGHT_MAGENTA */ + { XtNbright_cyan, 0xFFFFFFFF }, /* CLR_BRIGHT_CYAN */ + { XtNwhite, 0xFFFFFFFF }, /* CLR_WHITE */ + }; + pixel = map_colors[nhcolor & 0xF].rgb; + if (pixel == 0xFFFFFFFF) { + /* Retrieve resource */ + Arg arg[1]; + XtSetArg(arg[0], (char *) map_colors[nhcolor & 0xF].name, &pixel); + XtGetValues(wp->w, arg, 1); + map_colors[nhcolor & 0xF].rgb = pixel; + } + } + + X11_new_color(wp->w, pixel, color); +} + +static void +X11_draw_image_string( + XftDraw *draw, XftFont *font, + XftColor *fgcolor, XftColor *bgcolor, + int x, int y, + const X11_map_symbol *string, int length) +{ + XftDrawRect(draw, bgcolor, x, y, + length * font->max_advance_width, + font->height); + + int xt = x; + int yt = y + font->ascent; +#ifdef ENHANCED_SYMBOLS + XftDrawString32(draw, fgcolor, font, xt, yt, string, length); +#else /* !ENHANCED_SYMBOLS */ + XftDrawString8(draw, fgcolor, font, xt, yt, string, length); +#endif /* ?ENHANCED_SYMBOLS */ +} + +#else /* !USE_XFT */ + static GC X11_make_gc( struct xwindow *wp UNUSED, @@ -1503,16 +1614,16 @@ X11_make_gc( return ggc; } -#ifdef ENHANCED_SYMBOLS static void X11_free_gc(struct xwindow *wp, GC ggc, X11_color color) { +#ifdef ENHANCED_SYMBOLS if ((color & NH_ENHANCED_COLOR) != 0 && iflags.use_color) { /* X11_make_gc allocated a new GC */ XtReleaseGC(wp->w, ggc); } -} #endif +} static void X11_draw_image_string( @@ -1546,6 +1657,8 @@ X11_draw_image_string( #endif /* ?ENHANCED_SYMBOLS */ } +#endif /* ?USE_XFT */ + /* Adjust the number of rows and columns on the given map window */ void set_map_size(struct xwindow *wp, Dimension cols, Dimension rows) From e53b76b0e5e08aa01c9d5b05321fcc7f4e8cfeb6 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Fri, 14 Aug 2026 19:20:15 -0400 Subject: [PATCH 627/702] Convert message window to use Xft --- include/winX.h | 4 ++++ win/X11/winmesg.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/include/winX.h b/include/winX.h index 0754ffaef..d56c23e4a 100644 --- a/include/winX.h +++ b/include/winX.h @@ -139,7 +139,11 @@ struct mesg_info_t { /* bottom of screen */ struct line_element *last_pause_head; /* pointer to head of previous */ /* turn */ +#ifdef USE_XFT + Pixel fgpixel; /* Color for text drawing */ +#else GC gc; /* GC for text drawing */ +#endif int char_width, /* Saved font information so we can */ char_height, /* calculate the correct placement */ char_ascent, /* of changes. */ diff --git a/win/X11/winmesg.c b/win/X11/winmesg.c index 1e3539c8d..861e280d4 100644 --- a/win/X11/winmesg.c +++ b/win/X11/winmesg.c @@ -158,11 +158,20 @@ create_message_window(struct xwindow *wp, /* window pointer */ XtGetValues(wp->w, args, num_args); /* Save character information for fast use later. */ +#ifdef USE_XFT + XftFont *font = X11_new_font(wp->w, FALSE, NHW_MESSAGE); + mesg_info->char_width = font->max_advance_width; + mesg_info->char_height = font->height; + mesg_info->char_ascent = font->ascent; + mesg_info->char_lbearing = 0; + X11_release_font(wp->w, font); +#else mesg_info->char_width = mesg_info->fs->max_bounds.width; mesg_info->char_height = mesg_info->fs->max_bounds.ascent + mesg_info->fs->max_bounds.descent; mesg_info->char_ascent = mesg_info->fs->max_bounds.ascent; mesg_info->char_lbearing = -mesg_info->fs->min_bounds.lbearing; +#endif get_gc(wp->w, mesg_info); @@ -466,21 +475,51 @@ redraw_message_window(struct xwindow *wp) } /* For now, just update the whole shootn' match. */ +#ifdef USE_XFT + Display *display = XtDisplay(wp->w); + Screen *screen = DefaultScreenOfDisplay(display); + Visual *visual = DefaultVisualOfScreen(screen); + Colormap cmap = DefaultColormapOfScreen(screen); + XftDraw *draw = XftDrawCreate(display, XtWindow(wp->w), visual, cmap); + XftFont *font = X11_new_font(wp->w, FALSE, NHW_MESSAGE); + XftColor fgcolor; + X11_new_color(wp->w, mesg_info->fgpixel, &fgcolor); +#endif /* USE_XFT */ + for (y_base = row = 0, curr = mesg_info->head; row < mesg_info->num_lines; row++, y_base += mesg_info->char_height, curr = curr->next) { +#ifdef USE_XFT + if (curr->line != NULL) { + XftDrawString8(draw, &fgcolor, font, + mesg_info->char_lbearing, mesg_info->char_ascent + y_base, + (const FcChar8 *) curr->line, curr->str_length); + } +#else /* !USE_XFT */ XDrawString(XtDisplay(wp->w), XtWindow(wp->w), mesg_info->gc, mesg_info->char_lbearing, mesg_info->char_ascent + y_base, curr->line, curr->str_length); +#endif /* ?USE_XFT */ /* * This draws a line at the _top_ of the line of text pointed to by * mesg_info->last_pause. */ if (appResources.message_line && curr == mesg_info->line_here) { +#ifdef USE_XFT + XftDrawRect(draw, &fgcolor, 0, + y_base, wp->pixel_width, y_base); +#else /* !USE_XFT */ XDrawLine(XtDisplay(wp->w), XtWindow(wp->w), mesg_info->gc, 0, y_base, wp->pixel_width, y_base); +#endif /* ?USE_XFT */ } } +#ifdef USE_XFT + XftColorFree(display, visual, cmap, &fgcolor); + XftFontClose(display, font); + XftDrawDestroy(draw); +#endif /* USE_XFT */ + mesg_info->dirty = False; } @@ -549,6 +588,12 @@ mesg_exposed(Widget w, static void get_gc(Widget w, struct mesg_info_t *mesg_info) { +#ifdef USE_XFT + Arg arg[1]; + + XtSetArg(arg[0], XtNforeground, &mesg_info->fgpixel); + XtGetValues(w, arg, ONE); +#else /* !USE_XFT */ XGCValues values; XtGCMask mask = GCFunction | GCForeground | GCBackground | GCFont; Pixel fgpixel, bgpixel; @@ -563,6 +608,7 @@ get_gc(Widget w, struct mesg_info_t *mesg_info) values.function = GXcopy; values.font = WindowFont(w); mesg_info->gc = XtGetGC(w, mask, &values); +#endif /* ?USE_XFT */ } /* From 9d1aac189e6e581e5c15ccff239ba4e8a59f7648 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Fri, 14 Aug 2026 21:15:36 -0400 Subject: [PATCH 628/702] Convert TTY status to Xft --- include/winX.h | 2 +- win/X11/winX.c | 15 +++++- win/X11/winstat.c | 119 ++++++++++++++++++++++++++++++++++++++++++---- win/X11/wintext.c | 2 +- 4 files changed, 126 insertions(+), 12 deletions(-) diff --git a/include/winX.h b/include/winX.h index d56c23e4a..952ddcec4 100644 --- a/include/winX.h +++ b/include/winX.h @@ -382,7 +382,7 @@ extern Boolean nhCvtStringToPixel(Display *, XrmValuePtr, Cardinal *, extern void get_window_frame_extents(Widget, long *, long *, long *, long *); extern void get_widget_window_geometry(Widget, int *, int *, int *, int *); extern char *fontname_boldify(const char *); -extern Dimension nhFontHeight(Widget); +extern Dimension nhFontHeight(Widget, int); extern char key_event_to_char(XKeyEvent *); extern void msgkey(Widget, XtPointer, XEvent *, Boolean *); extern void highlight_yn(boolean); diff --git a/win/X11/winX.c b/win/X11/winX.c index 4596190b4..4889ac74a 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -752,11 +752,22 @@ nhFreePixel( * assumption of ascent + descent is not always valid. */ Dimension -nhFontHeight(Widget w) +nhFontHeight(Widget w, int win_type) { +#ifdef USE_XFT + + XftFont *font = X11_new_font(w, 0, win_type); + Dimension height = font->height; + X11_release_font(w, font); + return height; + +#else /* !USE_XFT */ + Arg args[1]; XFontStruct *fs; + nhUse(win_type); + #ifdef _XawTextSink_h Widget sink = NULL; XawTextPosition pos = 0; @@ -776,6 +787,8 @@ nhFontHeight(Widget w) /* Assume font height is ascent + descent. */ return fs->ascent + fs->descent; + +#endif /* ?USE_XFT */ } static String *default_resource_data = 0, /* NULL-terminated arrays */ diff --git a/win/X11/winstat.c b/win/X11/winstat.c index ed8f5da42..024045e6f 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -558,7 +558,7 @@ create_tty_status(Widget parent, Widget top) X11_status_widget = XtCreateManagedWidget("status_form", windowWidgetClass, form, args, num_args); - int height = nhFontHeight(X11_status_widget) * 3; + int height = nhFontHeight(X11_status_widget, NHW_STATUS) * 3; num_args = 0; XtSetArg(args[num_args], XtNheight, height); num_args++; XtSetValues(form, args, num_args); @@ -618,7 +618,7 @@ tty_status_redraw(Widget w) num_args = 0; XtSetArg(args[num_args], XtNwidth, &width); num_args++; XtGetValues(w, args, num_args); - int height = nhFontHeight(w); + int height = nhFontHeight(w, NHW_STATUS); int x = 0; int y = 0; @@ -770,17 +770,116 @@ tty_render_text(Widget w, const XRectangle *clip, int x, int y, nhUse(attr); #endif - Arg args[5]; - Cardinal num_args; - XGCValues values; - Pixel fgpixel, bgpixel; - XFontStruct *font; - XFontStruct *font_italic = NULL; /* custodial */ int goldwidth = 0; /* Get the colors */ + Pixel fgpixel, bgpixel; tty_status_colors(w, color, attr, &fgpixel, &bgpixel); +#ifdef USE_XPM + + /* Get the font */ + XftFont *font = X11_new_font(w, (attr & HL_BOLD) != 0, NHW_STATUS); + + /* Get the drawing resources */ + Display *display = XtDisplay(w); + Screen *screen = DefaultScreenOfDisplay(display); + Visual *visual = DefaultVisualOfScreen(screen); + Colormap cmap = DefaultColormapOfScreen(screen); + XftDraw *draw = XftDrawCreate(display, XtWindow(w), visual, cmap); + + /* Convert the colors to Xft form */ + XftColor fgcolor, bgcolor; + X11_new_color(w, fgpixel, &fgcolor); + X11_new_color(w, bgpixel, &bgcolor); + + /* If drawing a hitpoint bar, we'll need a clipping rectangle */ + if (clip != NULL) { + XftDrawSetClipRectangles(draw, 0, 0, clip, 1); + } + + /* Gold will begin with a glyph string. Convert this to the proper + character, which might possibly be Unicode */ + if (fld == BL_GOLD && memcmp(text, "\\G", 2) == 0) { + char *end; + unsigned long glyphcode = strtoul(text+2, &end, 16); + if ((glyphcode >> 16) == (unsigned) svc.context.rndencode && *end == ':') { + /* We have a proper glyph code */ + glyph_info glyphinfo; + glyphcode &= 0xFFFF; + map_glyphinfo(0, 0, glyphcode, 0, &glyphinfo); + X11_map_symbol goldsym = X11_glyph_char(&glyphinfo); + + /* Get the width of the gold symbol */ + XGlyphInfo extents; +#ifdef ENHANCED_SYMBOLS + FcChar32 goldch = goldsym; + XftTextExtents32(display, font, &goldch, 1, &extents); +#else /* !ENHANCED_SYMBOLS */ + FcChar8 goldch = goldsym; + XftTextExtents8(display, font, &goldch, 1, &extents); +#endif /* ?ENHANCED_SYMBOLS */ + goldwidth = extents.width - extents.x; + + /* Render the gold symbol */ + XftDrawRect(draw, &bgcolor, x, y, goldwidth, font->height); +#ifdef ENHANCED_SYMBOLS + XftDrawString32(draw, &fgcolor, font, x, y + font->ascent, &goldch, 1); +#else /* !ENHANCED_SYMBOLS */ + XftDrawString8(draw, &fgcolor, font, x, y + font->ascent, &goldch, 1); +#endif /* ?ENHANCED_SYMBOLS */ + + text = end; + } + } + + /* Get the width of the rendered string, not including goldwidth */ + XGlyphInfo extents; + XftTextExtents8(display, font, (const FcChar8 *) text, strlen(text), &extents); + int width = extents.width - extents.x; + + /* Place version on the right */ + if (fld == BL_VERS) { + Cardinal num_args = 0; + Arg args[1]; + Dimension wwidth; + XtSetArg(args[num_args], XtNwidth, &wwidth); num_args++; + XtGetValues(w, args, num_args); + int x2 = wwidth - width; + if (x2 > x) { + x = x2; + } + } + + /* Render the string */ + XftDrawRect(draw, &bgcolor, x + goldwidth, y, width, font->height); + XftDrawString8(draw, &fgcolor, font, + x + goldwidth, y + font->ascent, + (const FcChar8 *) text, strlen(text)); + width += goldwidth; + +#ifdef STATUS_HILITES + /* Implement underline */ + if (attr & HL_ULINE) { + XftDrawRect(draw, &fgcolor, x, y + font->ascent, width, 1); + } +#endif /* STATUS_HILITES */ + + /* Release resources */ + + XftColorFree(display, visual, cmap, &fgcolor); + XftColorFree(display, visual, cmap, &bgcolor); + XftDrawDestroy(draw); + X11_release_font(w, font); + +#else /* !USE_XPM */ + + Arg args[5]; + Cardinal num_args; + XGCValues values; + XFontStruct *font; + XFontStruct *font_italic = NULL; /* custodial */ + values.foreground = fgpixel; values.background = bgpixel; @@ -805,6 +904,7 @@ tty_render_text(Widget w, const XRectangle *clip, int x, int y, } } + /* Get a graphics context */ values.font = font->fid; values.function = GXcopy; GC ggc = XtGetGC(w, @@ -907,6 +1007,7 @@ tty_render_text(Widget w, const XRectangle *clip, int x, int y, if (font_italic != NULL) { XFreeFont(XtDisplay(w), font_italic); } +#endif /* ?USE_XPM */ /* Caller will advance x by the width */ return width; @@ -1139,7 +1240,7 @@ create_status_window_fancy(struct xwindow *wp, /* window pointer */ &right_margin); num_args++; XtGetValues(wp->w, args, num_args); - wp->pixel_height = 2 * nhFontHeight(wp->w) + top_margin + bottom_margin; + wp->pixel_height = 2 * nhFontHeight(wp->w, NHW_STATUS) + top_margin + bottom_margin; wp->pixel_width = COLNO * fs->max_bounds.width + left_margin + right_margin; diff --git a/win/X11/wintext.c b/win/X11/wintext.c index 9c7b98a2b..57c45540b 100644 --- a/win/X11/wintext.c +++ b/win/X11/wintext.c @@ -154,7 +154,7 @@ display_text_window(struct xwindow *wp, boolean blocking) width = text_info->max_width + text_info->extra_width; text_info->blocked = blocking; text_info->destroy_on_ack = FALSE; - font_height = nhFontHeight(wp->w); + font_height = nhFontHeight(wp->w, NHW_TEXT); /* * Calculate the number of lines to use. First, find the number of From 737b3ac89aa6868cc69de36f8f3da98a5198b279 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Fri, 14 Aug 2026 21:29:40 -0400 Subject: [PATCH 629/702] Implement italic fonts --- include/winX.h | 2 +- win/X11/winX.c | 7 ++++--- win/X11/winmap.c | 4 ++-- win/X11/winmesg.c | 4 ++-- win/X11/winstat.c | 2 +- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/include/winX.h b/include/winX.h index 952ddcec4..4e97de267 100644 --- a/include/winX.h +++ b/include/winX.h @@ -544,7 +544,7 @@ extern XFontStruct *X11_unicode_font(Display *, XFontStruct *); #endif #ifdef USE_XFT -extern XftFont *X11_new_font(Widget w, boolean bold, int win_type); +extern XftFont *X11_new_font(Widget w, unsigned attrs, int win_type); extern void X11_release_font(Widget w, XftFont *font); extern void X11_new_color(Widget w, Pixel pixel, XftColor *color); #endif diff --git a/win/X11/winX.c b/win/X11/winX.c index 4889ac74a..86691d15b 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -3164,7 +3164,7 @@ X11_unicode_font(Display *display, XFontStruct *font) /* Open a vector font for the given widget */ extern XftFont * -X11_new_font(Widget w, boolean bold, int win_type) +X11_new_font(Widget w, unsigned attrs, int win_type) { const char *font_name = NULL; const char *iflags_font_name = NULL; @@ -3247,9 +3247,10 @@ X11_new_font(Widget w, boolean bold, int win_type) /* Set reasonable bounds on the font size */ font_size = min(max(font_size, 6), 50); - Snprintf(name, sizeof(name), "%.*s-%d:%s", + Snprintf(name, sizeof(name), "%.*s-%d%s%s", (int) name_len, font_name, font_size, - bold ? "bold" : "medium"); + (attrs & HL_BOLD) ? ":bold" : "", + (attrs & HL_ITALIC) ? ":italic" : ""); Display *display = XtDisplay(w); XftFont *font = XftFontOpenName(display, DefaultScreen(display), name); diff --git a/win/X11/winmap.c b/win/X11/winmap.c index 3befe1887..c6733f76c 100644 --- a/win/X11/winmap.c +++ b/win/X11/winmap.c @@ -1040,7 +1040,7 @@ get_char_info(struct xwindow *wp) #ifdef USE_XFT struct map_info_t *map_info = wp->map_information; struct text_map_info_t *text_map = &map_info->text_map; - XftFont *font = X11_new_font(wp->w, FALSE, NHW_MAP); + XftFont *font = X11_new_font(wp->w, 0, NHW_MAP); text_map->square_width = font->max_advance_width; text_map->square_height = font->height; text_map->square_ascent = 0; @@ -1430,7 +1430,7 @@ map_update(struct xwindow *wp, int start_row, int stop_row, int start_col, int s XtGetValues(wp->w, arg, 1); XftDraw *draw = XftDrawCreate(display, XtWindow(wp->w), visual, cmap); - XftFont *font = X11_new_font(wp->w, FALSE, NHW_MAP); + XftFont *font = X11_new_font(wp->w, 0, NHW_MAP); XftColor bgcolor; X11_new_color(wp->w, bgpixel, &bgcolor); #endif /* USE_XFT */ diff --git a/win/X11/winmesg.c b/win/X11/winmesg.c index 861e280d4..69df458b0 100644 --- a/win/X11/winmesg.c +++ b/win/X11/winmesg.c @@ -159,7 +159,7 @@ create_message_window(struct xwindow *wp, /* window pointer */ /* Save character information for fast use later. */ #ifdef USE_XFT - XftFont *font = X11_new_font(wp->w, FALSE, NHW_MESSAGE); + XftFont *font = X11_new_font(wp->w, 0, NHW_MESSAGE); mesg_info->char_width = font->max_advance_width; mesg_info->char_height = font->height; mesg_info->char_ascent = font->ascent; @@ -481,7 +481,7 @@ redraw_message_window(struct xwindow *wp) Visual *visual = DefaultVisualOfScreen(screen); Colormap cmap = DefaultColormapOfScreen(screen); XftDraw *draw = XftDrawCreate(display, XtWindow(wp->w), visual, cmap); - XftFont *font = X11_new_font(wp->w, FALSE, NHW_MESSAGE); + XftFont *font = X11_new_font(wp->w, 0, NHW_MESSAGE); XftColor fgcolor; X11_new_color(wp->w, mesg_info->fgpixel, &fgcolor); #endif /* USE_XFT */ diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 024045e6f..c8e7c353e 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -779,7 +779,7 @@ tty_render_text(Widget w, const XRectangle *clip, int x, int y, #ifdef USE_XPM /* Get the font */ - XftFont *font = X11_new_font(w, (attr & HL_BOLD) != 0, NHW_STATUS); + XftFont *font = X11_new_font(w, attr, NHW_STATUS); /* Get the drawing resources */ Display *display = XtDisplay(w); From 9e57c85b165cac47446e42313b6daf79852484ce Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Fri, 14 Aug 2026 21:46:02 -0400 Subject: [PATCH 630/702] Condition should be USE_XFT, not USE_XPM --- win/X11/winstat.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/win/X11/winstat.c b/win/X11/winstat.c index c8e7c353e..3cc3d28f1 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -776,7 +776,7 @@ tty_render_text(Widget w, const XRectangle *clip, int x, int y, Pixel fgpixel, bgpixel; tty_status_colors(w, color, attr, &fgpixel, &bgpixel); -#ifdef USE_XPM +#ifdef USE_XFT /* Get the font */ XftFont *font = X11_new_font(w, attr, NHW_STATUS); @@ -872,7 +872,7 @@ tty_render_text(Widget w, const XRectangle *clip, int x, int y, XftDrawDestroy(draw); X11_release_font(w, font); -#else /* !USE_XPM */ +#else /* !USE_XFT */ Arg args[5]; Cardinal num_args; @@ -1007,7 +1007,7 @@ tty_render_text(Widget w, const XRectangle *clip, int x, int y, if (font_italic != NULL) { XFreeFont(XtDisplay(w), font_italic); } -#endif /* ?USE_XPM */ +#endif /* ?USE_XFT */ /* Caller will advance x by the width */ return width; From 7c9cf20d1dd5514a3fefff4a0d448ac71909fe11 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Fri, 14 Aug 2026 23:01:28 -0400 Subject: [PATCH 631/702] Convert fancy status and menus to Xft --- include/winX.h | 2 +- win/X11/winlabel.c | 109 ++++++++++++++++++++++++++++++++++++++++++--- win/X11/winmenu.c | 2 +- win/X11/winstat.c | 4 +- win/X11/winval.c | 4 +- 5 files changed, 109 insertions(+), 12 deletions(-) diff --git a/include/winX.h b/include/winX.h index 4e97de267..02b993f42 100644 --- a/include/winX.h +++ b/include/winX.h @@ -551,7 +551,7 @@ extern void X11_new_color(Widget w, Pixel pixel, XftColor *color); /* ### winlabel.c ### */ /* Functions for management of enhanced labels */ -extern void X11_wrap_widget(Widget); +extern void X11_wrap_widget(Widget, int); extern void X11_update_label(Widget); extern void X11_set_attrs(Widget, unsigned); extern void X11_set_highlight(Widget, boolean); diff --git a/win/X11/winlabel.c b/win/X11/winlabel.c index 1d5508847..8ac2cd41e 100644 --- a/win/X11/winlabel.c +++ b/win/X11/winlabel.c @@ -28,8 +28,13 @@ typedef struct WidgetData { boolean highlight; /* Fonts for italic, bold and bold-italic */ +#ifdef USE_XFT + int win_type; + XftFont *vfont[4]; +#else /* !USE_XFT */ XFontStruct *font[4]; /* To use the fonts */ XFontStruct *font_ptr[4]; /* To free the fonts */ +#endif /* ?USE_XFT */ /* Percentage bar */ unsigned percent; @@ -57,7 +62,7 @@ static WidgetData *get_widget_data(Widget w); * attribute flags and a percentage bar. */ void -X11_wrap_widget(Widget w) +X11_wrap_widget(Widget w, int win_type) { /* We shouldn't use this for anything other than labels and subclasses of labels */ @@ -79,10 +84,16 @@ X11_wrap_widget(Widget w) WidgetData *data = add_widget(w); /* Copy resources from the created widget */ +#ifdef USE_XFT + data->win_type = win_type; + allocate_font(w, data, 0); +#else /* !USE_XFT */ Cardinal num_args2 = 0; Arg args2[1]; XtSetArg(args2[num_args2], XtNfont, &data->font[0]); num_args2++; XtGetValues(w, args2, num_args2); + nhUse(win_type); +#endif /* ?USE_XFT */ /* Create the pixmap for the first time */ update_label(w, data); @@ -184,7 +195,11 @@ update_label(Widget w, WidgetData *data) font_idx |= font_italic; allocate_font(w, data, font_idx); } +#ifdef USE_XFT + XftFont *vfont = data->vfont[font_idx]; +#else XFontStruct *font = data->font[font_idx]; +#endif String label; Boolean sens; /* Make dim if not sensitive */ @@ -222,11 +237,17 @@ update_label(Widget w, WidgetData *data) } /* Get the width of the line */ +#ifdef USE_XFT + XGlyphInfo extents; + XftTextExtents8(display, vfont, (const FcChar8*) (label + i), line2, &extents); + int lwidth = extents.width - extents.x; +#else int lwidth = XTextWidth(font, label + i, line2); +#endif /* Update pixmap dimensions */ width = max(lwidth, width); - height += font->ascent + font->descent; + ++height; /* Advance to next line */ i += line1; @@ -236,7 +257,14 @@ update_label(Widget w, WidgetData *data) } /* Always size for at least one line */ - height = max(height, font->ascent + font->descent); + height = max(height, 1); + + /* Convert height to pixels */ +#ifdef USE_XFT + height *= vfont->height; +#else + height *= font->ascent + font->descent; +#endif } else { num_args = 0; XtSetArg(args[num_args], XtNwidth, &width); num_args++; @@ -285,11 +313,20 @@ update_label(Widget w, WidgetData *data) if ((attrs & HL_BLINK) && X11_blink) { values.foreground = values.background; } +#ifdef USE_XFT + Visual *visual = DefaultVisualOfScreen(screen); + Colormap cmap = DefaultColormapOfScreen(screen); + XftDraw *draw = XftDrawCreate(display, new_pixmap, visual, cmap); + XftColor fgcolor, bgcolor; + X11_new_color(w, values.foreground, &fgcolor); + X11_new_color(w, values.background, &bgcolor); +#else /* !USE_XFT */ values.font = font->fid; values.function = GXcopy; GC ggc = XtGetGC(w, GCFunction | GCForeground | GCBackground | GCFont, &values); +#endif /* ?USE_XFT */ if (pass == 1) { /* Percent bar will occupy this area */ XRectangle clip = { @@ -298,18 +335,34 @@ update_label(Widget w, WidgetData *data) .width = width * data->percent / 100, .height = height }; +#ifdef USE_XFT + XftDrawSetClipRectangles(draw, 0, 0, &clip, 1); +#else /* !USE_XFT */ XSetClipRectangles(display, ggc, 0, 0, &clip, 1, Unsorted); +#endif /* ?USE_XFT */ } /* Draw a border for inverse and highlight together */ /* Otherwise, fill with the background color */ +#ifdef USE_XFT + if (!((attrs & HL_INVERSE) && data->highlight)) { + XftDrawRect(draw, &bgcolor, 0, 0, width, height); + } else { + XftDrawRect(draw, &fgcolor, 0, 0, width, height); + } +#else /* !USE_XFT */ if (!((attrs & HL_INVERSE) && data->highlight)) { XSetForeground(display, ggc, values.background); } XFillRectangle(display, new_pixmap, ggc, 0, 0, width, height); XSetForeground(display, ggc, values.foreground); +#endif /* ?USE_XFT */ +#ifdef USE_XFT + int y = vfont->ascent; +#else /* !USE_XFT */ int y = font->max_bounds.ascent; +#endif /* ?USE_XFT */ size_t i = 0; while (label[i] != '\0') { size_t line1 = strcspn(label + i, "\n"); @@ -320,7 +373,13 @@ update_label(Widget w, WidgetData *data) } /* Get the width of the line */ +#ifdef USE_XFT + XGlyphInfo extents; + XftTextExtents8(display, vfont, (const FcChar8*) (label + i), line2, &extents); + int lwidth = extents.width - extents.x; +#else int lwidth = XTextWidth(font, label + i, line2); +#endif /* Place the line horizontally */ int x = 0; @@ -339,18 +398,32 @@ update_label(Widget w, WidgetData *data) } /* Render the line */ +#ifdef USE_XFT + XftDrawRect(draw, &bgcolor, x, y - vfont->ascent, lwidth, vfont->height); + XftDrawString8(draw, &fgcolor, vfont, x, y, + (const FcChar8 *) (label + i), line2); +#else XDrawImageString(display, new_pixmap, ggc, x, y, label + i, line2); +#endif /* Draw the underline if requested */ if (attrs & HL_ULINE) { +#ifdef USE_XFT + XftDrawRect(draw, &fgcolor, x, y, lwidth, 1); +#else XDrawLine(display, new_pixmap, ggc, x, y, x + lwidth - 1, y); +#endif } +#ifdef USE_XFT + y += vfont->height; +#else y += font->ascent + font->descent; +#endif /* Advance to next line */ i += line1; @@ -361,10 +434,23 @@ update_label(Widget w, WidgetData *data) /* Ensure a one-pixel border if both inverse and highlight */ if ((attrs & HL_INVERSE) && data->highlight) { +#ifdef USE_XFT + XftDrawRect(draw, &fgcolor, 0, 0, width, 1); + XftDrawRect(draw, &fgcolor, 0, height-1, width, 1); + XftDrawRect(draw, &fgcolor, 0, 0, 1, height); + XftDrawRect(draw, &fgcolor, 0, height-1, 1, height); +#else XDrawRectangle(display, new_pixmap, ggc, 0, 0, width-1, height-1); +#endif } +#ifdef USE_XFT + XftColorFree(display, visual, cmap, &fgcolor); + XftColorFree(display, visual, cmap, &bgcolor); + XftDrawDestroy(draw); +#else XtReleaseGC(w, ggc); +#endif /* Set up to display the percent bar on the second pass */ if (data->percent == 0) { @@ -377,8 +463,6 @@ update_label(Widget w, WidgetData *data) /* Update the pixmap */ num_args = 0; XtSetArg(args[num_args], XtNbitmap, new_pixmap); num_args++; - //XtSetArg(args[num_args], XtNwidth, width); num_args++; - //XtSetArg(args[num_args], XtNheight, height); num_args++; XtSetValues(w, args, num_args); if (data->pixmap != 0) { XFreePixmap(display, data->pixmap); @@ -390,8 +474,13 @@ update_label(Widget w, WidgetData *data) static void allocate_font(Widget w, WidgetData *data, unsigned font_idx) { +#ifdef USE_XFT + static const unsigned attrs[4] = { + 0, HL_BOLD, HL_ITALIC, HL_BOLD | HL_ITALIC + }; + data->vfont[font_idx] = X11_new_font(w, attrs[font_idx], data->win_type); +#else Display *display = XtDisplay(w); - XFontStruct *font1 = (font_idx == (font_bold | font_italic)) ? data->font[font_bold] : data->font[0]; @@ -401,6 +490,7 @@ allocate_font(Widget w, WidgetData *data, unsigned font_idx) data->font[font_idx] = data->font_ptr[font_idx] ? data->font_ptr[font_idx] : font1; +#endif } /* Free any allocated fonts */ @@ -409,11 +499,18 @@ free_fonts(Widget w, WidgetData *data) { Display *display = XtDisplay(w); for (unsigned i = 0; i < 4; ++i) { +#ifdef USE_XFT + if (data->vfont[i] != NULL) { + XftFontClose(display, data->vfont[i]); + } + data->vfont[i] = NULL; +#else if (data->font_ptr[i] != NULL) { XFreeFont(display, data->font_ptr[i]); } data->font[i] = NULL; data->font_ptr[i] = NULL; +#endif } } diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index abc646938..7b065a00c 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -1362,7 +1362,7 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu) ? commandWidgetClass : labelWidgetClass, wp->w, args, num_args); - X11_wrap_widget(curr->w); + X11_wrap_widget(curr->w, NHW_MENU); X11_set_attrs(curr->w, 0x1 << attr); if (canpick) diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 3cc3d28f1..4fde169d0 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -2274,7 +2274,7 @@ create_widget(Widget parent, struct X_status_value *sv, int sv_index) : "dlevel", labelWidgetClass, parent, args, num_args); - X11_wrap_widget(sv->w); + X11_wrap_widget(sv->w, NHW_STATUS); break; case SV_NAME: { char buf[BUFSZ]; @@ -2311,7 +2311,7 @@ create_widget(Widget parent, struct X_status_value *sv, int sv_index) XtSetArg(args[num_args], XtNinternalHeight, 0); num_args++; sv->w = XtCreateManagedWidget(sv->name, labelWidgetClass, parent, args, num_args); - X11_wrap_widget(sv->w); + X11_wrap_widget(sv->w, NHW_STATUS); break; } default: diff --git a/win/X11/winval.c b/win/X11/winval.c index 59a2c3a5b..65bdeb312 100644 --- a/win/X11/winval.c +++ b/win/X11/winval.c @@ -57,7 +57,7 @@ create_value(Widget parent, const char *name_value) num_args++; name = XtCreateManagedWidget(WNAME, labelWidgetClass, form, args, num_args); - X11_wrap_widget(name); + X11_wrap_widget(name, NHW_STATUS); num_args = 0; XtSetArg(args[num_args], XtNjustify, XtJustifyRight); @@ -70,7 +70,7 @@ create_value(Widget parent, const char *name_value) num_args++; Widget value = XtCreateManagedWidget(WVALUE, labelWidgetClass, form, args, num_args); - X11_wrap_widget(value); + X11_wrap_widget(value, NHW_STATUS); return form; } From 8ae58f934717056c31e0a2663b82a75a252ecf30 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Fri, 14 Aug 2026 23:49:21 -0400 Subject: [PATCH 632/702] Convert the one line message prompt to Xft --- include/winX.h | 32 ++++++++++++++++++++++++++++++++ win/X11/winX.c | 5 +++++ 2 files changed, 37 insertions(+) diff --git a/include/winX.h b/include/winX.h index 02b993f42..26e2440d0 100644 --- a/include/winX.h +++ b/include/winX.h @@ -558,4 +558,36 @@ extern void X11_set_highlight(Widget, boolean); extern void X11_set_percent(Widget, unsigned, Pixel); extern void X11_blink_labels(void); +/* + * These are for widgets that use the enhanced label services only for text + * rendering; not for percentage bars, underlines and such. They only need + * these services if XFT is in use. + */ +#ifdef USE_XFT +static inline void +X11_wrap_widget_if_Xft(Widget w, int win_type) +{ + X11_wrap_widget(w, win_type); +} + +static inline void +X11_update_label_if_Xft(Widget w) +{ + X11_update_label(w); +} +#else /* !USE_XFT */ +static inline void +X11_wrap_widget_if_Xft(Widget w, int win_type) +{ + nhUse(w); + nhUse(win_type); +} + +static inline void +X11_update_label_if_Xft(Widget w) +{ + nhUse(w); +} +#endif /* ?USE_XFT */ + #endif /* WINX_H */ diff --git a/win/X11/winX.c b/win/X11/winX.c index 86691d15b..5ab8ab587 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -2446,6 +2446,7 @@ X11_yn_function_core( (void) memset(buf2, 'X', 25), buf2[25] = '\0'; /* 25 'X's */ yn_minwidth = (Dimension) XTextWidth(yn_font, buf2, (int) strlen(buf2)); + X11_wrap_widget_if_Xft(yn_label, NHW_MESSAGE); } } @@ -2454,6 +2455,7 @@ X11_yn_function_core( num_args = 0; XtSetArg(args[num_args], XtNlabel, buf); num_args++; XtSetValues(yn_label, args, num_args); + X11_update_label_if_Xft(yn_label); /* for !slow, pop up the prompt+response widget */ if (!appResources.slow) { @@ -2497,6 +2499,7 @@ X11_yn_function_core( num_args = 0; XtSetArg(args[num_args], XtNlabel, " "); num_args++; XtSetValues(yn_label, args, num_args); + X11_update_label_if_Xft(yn_label); input_func = 0; /* keystrokes now belong to the map */ highlight_yn(FALSE); /* disguise yn_label as part of map */ @@ -2620,6 +2623,7 @@ highlight_yn(boolean init) XtSetArg(args[0], XtNforeground, vals.foreground); XtSetArg(args[1], XtNbackground, vals.background); XtSetValues(yn_label, args, TWO); + X11_update_label_if_Xft(yn_label); } } else swap_fg_bg(yn_label); @@ -2687,6 +2691,7 @@ init_standard_windows(void) XtSetArg(args[num_args], nhStr(XtNresizable), True); num_args++; XtSetArg(args[num_args], nhStr(XtNlabel), " "); num_args++; XtSetValues(yn_label, args, num_args); + X11_wrap_widget_if_Xft(yn_label, NHW_MESSAGE); } /* From cfe67ecc62b1022e994ff40f3f25d13f7e93f71d Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Fri, 14 Aug 2026 23:49:50 -0400 Subject: [PATCH 633/702] Convert dialogs to Xft --- win/X11/dialogs.c | 4 ++++ win/X11/winmenu.c | 9 +++++++++ win/X11/winmisc.c | 40 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/win/X11/dialogs.c b/win/X11/dialogs.c index 11664c198..48047852d 100644 --- a/win/X11/dialogs.c +++ b/win/X11/dialogs.c @@ -132,6 +132,7 @@ CreateDialog(Widget parent, String name, XtCallbackProc okay_callback, XtSetArg(args[num_args], nhStr(XtNborderWidth), 0); num_args++; prompt = XtCreateManagedWidget("prompt", labelWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(prompt, NHW_MENU); num_args = 0; #ifdef SPECIAL_CMAP @@ -169,6 +170,7 @@ CreateDialog(Widget parent, String name, XtCallbackProc okay_callback, XtParseAcceleratorTable(okay_accelerators)); num_args++; okay = XtCreateManagedWidget("okay", commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(okay, NHW_MENU); XtAddCallback(okay, XtNcallback, okay_callback, form); XtSetArg(args[0], XtNwidth, &owidth); XtGetValues(okay, args, ONE); @@ -193,6 +195,7 @@ CreateDialog(Widget parent, String name, XtCallbackProc okay_callback, XtParseAcceleratorTable(cancel_accelerators)); num_args++; cancel = XtCreateManagedWidget("cancel", commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(cancel, NHW_MENU); XtAddCallback(cancel, XtNcallback, cancel_callback, form); XtInstallAccelerators(response, cancel); XtSetArg(args[0], XtNwidth, &cwidth); @@ -241,6 +244,7 @@ SetDialogPrompt(Widget w, String newprompt) label = XtNameToWidget(w, "prompt"); XtSetArg(args[0], nhStr(XtNlabel), newprompt); XtSetValues(label, args, ONE); + X11_update_label_if_Xft(label); } /* get what the user typed; caller must free the response */ diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index 7b065a00c..596578912 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -1025,6 +1025,9 @@ X11_select_menu(winid window, int how, menu_item **menu_list) labelWidgetClass, form, args, num_args) : (Widget) 0; + if (label) { + X11_wrap_widget_if_Xft(label, NHW_MENU); + } all = menu_create_buttons(wp, form, label); @@ -1194,6 +1197,7 @@ menu_create_buttons(struct xwindow *wp, Widget form, Widget under) XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft); num_args++; ok = XtCreateManagedWidget("OK", commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(ok, NHW_MENU); XtAddCallback(ok, XtNcallback, menu_ok, (XtPointer) wp); XtSetArg(args[0], XtNwidth, &lblwidth[0]); XtGetValues(lblwidget[0] = ok, args, ONE); @@ -1212,6 +1216,7 @@ menu_create_buttons(struct xwindow *wp, Widget form, Widget under) XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft); num_args++; cancel = XtCreateManagedWidget("cancel", commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(cancel, NHW_MENU); XtAddCallback(cancel, XtNcallback, menu_cancel, (XtPointer) wp); XtSetArg(args[0], XtNwidth, &lblwidth[1]); XtGetValues(lblwidget[1] = cancel, args, ONE); @@ -1229,6 +1234,7 @@ menu_create_buttons(struct xwindow *wp, Widget form, Widget under) XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft); num_args++; all = XtCreateManagedWidget("all", commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(all, NHW_MENU); XtAddCallback(all, XtNcallback, menu_all, (XtPointer) wp); XtSetArg(args[0], XtNwidth, &lblwidth[2]); XtGetValues(lblwidget[2] = all, args, ONE); @@ -1245,6 +1251,7 @@ menu_create_buttons(struct xwindow *wp, Widget form, Widget under) XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft); num_args++; none = XtCreateManagedWidget("none", commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(none, NHW_MENU); XtAddCallback(none, XtNcallback, menu_none, (XtPointer) wp); XtSetArg(args[0], XtNwidth, &lblwidth[3]); XtGetValues(lblwidget[3] = none, args, ONE); @@ -1261,6 +1268,7 @@ menu_create_buttons(struct xwindow *wp, Widget form, Widget under) XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft); num_args++; invert = XtCreateManagedWidget("invert", commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(invert, NHW_MENU); XtAddCallback(invert, XtNcallback, menu_invert, (XtPointer) wp); XtSetArg(args[0], XtNwidth, &lblwidth[4]); XtGetValues(lblwidget[4] = invert, args, ONE); @@ -1278,6 +1286,7 @@ menu_create_buttons(struct xwindow *wp, Widget form, Widget under) XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft); num_args++; search = XtCreateManagedWidget("search", commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(search, NHW_MENU); XtAddCallback(search, XtNcallback, menu_search, (XtPointer) wp); XtSetArg(args[0], XtNwidth, &lblwidth[5]); XtGetValues(lblwidget[5] = search, args, ONE); diff --git a/win/X11/winmisc.c b/win/X11/winmisc.c index af1f64d4a..023213502 100644 --- a/win/X11/winmisc.c +++ b/win/X11/winmisc.c @@ -416,6 +416,7 @@ plsel_set_play_button(boolean state) XtSetArg(args[0], nhStr(XtNsensitive), !state); XtSetValues(plsel_btn_play, args, ONE); + X11_update_label_if_Xft(plsel_btn_play); } static void @@ -441,6 +442,7 @@ plsel_set_sensitivities(boolean setcurr) c = j; XtSetArg(args[0], nhStr(XtNsensitive), v); XtSetValues(plsel_role_radios[j], args, ONE); + X11_update_label_if_Xft(plsel_role_radios[j]); if (valid < 0 && v) valid = j; } @@ -459,6 +461,7 @@ plsel_set_sensitivities(boolean setcurr) c = j; XtSetArg(args[0], nhStr(XtNsensitive), v); XtSetValues(plsel_race_radios[j], args, ONE); + X11_update_label_if_Xft(plsel_race_radios[j]); if (valid < 0 && v) valid = j; } @@ -566,6 +569,7 @@ X11_player_selection_setupOthers(void) c = j; XtSetArg(args[0], nhStr(XtNsensitive), v); XtSetValues(plsel_gend_radios[j], args, ONE); + X11_update_label_if_Xft(plsel_gend_radios[j]); if (valid < 0 && v) valid = j; } @@ -583,6 +587,7 @@ X11_player_selection_setupOthers(void) c = j; XtSetArg(args[0], nhStr(XtNsensitive), v); XtSetValues(plsel_align_radios[j], args, ONE); + X11_update_label_if_Xft(plsel_align_radios[j]); if (valid < 0 && v) valid = j; } @@ -619,6 +624,7 @@ racetoggleCallback(Widget w, XtPointer client, XtPointer call) c = j; XtSetArg(args[0], nhStr(XtNsensitive), v); XtSetValues(plsel_role_radios[j], args, ONE); + X11_update_label_if_Xft(plsel_role_radios[j]); if (valid < 0 && v) valid = j; } @@ -658,6 +664,7 @@ roletoggleCallback(Widget w, XtPointer client, XtPointer call) c = j; XtSetArg(args[0], nhStr(XtNsensitive), v); XtSetValues(plsel_race_radios[j], args, ONE); + X11_update_label_if_Xft(plsel_race_radios[j]); if (valid < 0 && v) valid = j; } @@ -688,6 +695,7 @@ gendertoggleCallback(Widget w, XtPointer client, XtPointer call) XtSetArg(args[0], XtNlabel, (r < 1) ? roles[i].name.m : roles[i].name.f); XtSetValues(plsel_role_radios[i], args, ONE); + X11_update_label_if_Xft(plsel_role_radios[i]); } } } @@ -770,6 +778,7 @@ X11_create_player_selection_name(Widget form) namelabel = XtCreateManagedWidget("name_label", labelWidgetClass, name_form, args, num_args); + X11_wrap_widget_if_Xft(namelabel, NHW_MENU); num_args = 0; XtSetArg(args[num_args], nhStr(XtNfromVert), namelabel); num_args++; @@ -899,6 +908,7 @@ X11_player_selection_dialog(void) racelabel = XtCreateManagedWidget("race_label", labelWidgetClass, race_form, args, num_args); + X11_wrap_widget_if_Xft(racelabel, NHW_MENU); num_args = 0; XtSetArg(args[num_args], nhStr(XtNtopMargin), 0); num_args++; @@ -939,6 +949,7 @@ X11_player_selection_dialog(void) toggleWidgetClass, race_form2, args, num_args); + X11_wrap_widget_if_Xft(racewidget, NHW_MENU); XtAddCallback(racewidget, XtNcallback, racetoggleCallback, i2xtp(i)); tmpwidget = racewidget; plsel_race_radios[i] = racewidget; @@ -963,6 +974,7 @@ X11_player_selection_dialog(void) XtSetArg(args[num_args], nhStr(XtNlabel), "Role"); num_args++; rolelabel = XtCreateManagedWidget("role_label", labelWidgetClass, role_form, args, num_args); + X11_wrap_widget_if_Xft(rolelabel, NHW_MENU); num_args = 0; XtSetArg(args[num_args], nhStr(XtNtopMargin), 0); num_args++; @@ -998,9 +1010,11 @@ X11_player_selection_dialog(void) plsel_role_radios[0]); num_args++; } XtSetArg(args[num_args], nhStr(XtNradioData), (i + 1)); num_args++; + XtSetArg(args[num_args], nhStr(XtNresizable), True); num_args++; rolewidget = XtCreateManagedWidget(roles[i].name.m, toggleWidgetClass, role_form2, args, num_args); + X11_wrap_widget_if_Xft(rolewidget, NHW_MENU); XtAddCallback(rolewidget, XtNcallback, roletoggleCallback, i2xtp(i)); tmpwidget = rolewidget; plsel_role_radios[i] = rolewidget; @@ -1027,6 +1041,7 @@ X11_player_selection_dialog(void) XtSetArg(args[num_args], nhStr(XtNlabel), "Gender"); num_args++; gendlabel = XtCreateManagedWidget("gender_label", labelWidgetClass, gend_form, args, num_args); + X11_wrap_widget_if_Xft(gendlabel, NHW_MENU); num_args = 0; XtSetArg(args[num_args], nhStr(XtNtopMargin), 0); num_args++; @@ -1048,6 +1063,7 @@ X11_player_selection_dialog(void) plsel_gend_radios[0] = gend_radio_m = XtCreateManagedWidget("Male", toggleWidgetClass, gend_form2, args, num_args); + X11_wrap_widget_if_Xft(plsel_gend_radios[0], NHW_MENU); num_args = 0; XtSetArg(args[num_args], nhStr(XtNfromVert), gend_radio_m); num_args++; XtSetArg(args[num_args], XtNwidth, cwid); num_args++; @@ -1057,6 +1073,7 @@ X11_player_selection_dialog(void) plsel_gend_radios[1] = gend_radio_f = XtCreateManagedWidget("Female", toggleWidgetClass, gend_form2, args, num_args); + X11_wrap_widget_if_Xft(plsel_gend_radios[1], NHW_MENU); XawToggleUnsetCurrent(plsel_gend_radios[0]); @@ -1086,6 +1103,7 @@ X11_player_selection_dialog(void) XtSetArg(args[num_args], nhStr(XtNlabel), "Alignment"); num_args++; alignlabel = XtCreateManagedWidget("align_label", labelWidgetClass, align_form, args, num_args); + X11_wrap_widget_if_Xft(alignlabel, NHW_MENU); num_args = 0; XtSetArg(args[num_args], nhStr(XtNtopMargin), 0); num_args++; @@ -1106,6 +1124,7 @@ X11_player_selection_dialog(void) plsel_align_radios[0] = align_radio_l = XtCreateManagedWidget("Lawful", toggleWidgetClass, align_form2, args, num_args); + X11_wrap_widget_if_Xft(plsel_align_radios[0], NHW_MENU); num_args = 0; XtSetArg(args[num_args], nhStr(XtNfromVert), align_radio_l); num_args++; XtSetArg(args[num_args], XtNwidth, cwid); num_args++; @@ -1115,6 +1134,7 @@ X11_player_selection_dialog(void) plsel_align_radios[1] = align_radio_n = XtCreateManagedWidget("Neutral", toggleWidgetClass, align_form2, args, num_args); + X11_wrap_widget_if_Xft(plsel_align_radios[1], NHW_MENU); num_args = 0; XtSetArg(args[num_args], nhStr(XtNfromVert), align_radio_n); num_args++; XtSetArg(args[num_args], XtNwidth, cwid); num_args++; @@ -1124,6 +1144,7 @@ X11_player_selection_dialog(void) plsel_align_radios[2] = align_radio_c = XtCreateManagedWidget("Chaotic", toggleWidgetClass, align_form2, args, num_args); + X11_wrap_widget_if_Xft(plsel_align_radios[2], NHW_MENU); XawToggleUnsetCurrent(plsel_align_radios[0]); @@ -1159,10 +1180,13 @@ X11_player_selection_dialog(void) XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop); num_args++; XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft); num_args++; XtSetArg(args[num_args], nhStr(XtNright), XtChainRight); num_args++; - XtSetArg(args[num_args], XtNwidth, cwid); num_args++; XtSetArg(args[num_args], nhStr(XtNlabel), "Random"); num_args++; random_btn = XtCreateManagedWidget("random", commandWidgetClass, btn_form, args, num_args); + X11_wrap_widget_if_Xft(random_btn, NHW_MENU); + num_args = 0; + XtSetArg(args[num_args], XtNwidth, cwid); num_args++; + XtSetValues(random_btn, args, num_args); XtAddCallback(random_btn, XtNcallback, plsel_random_btn_callback, form); /* "Play" button */ @@ -1171,11 +1195,14 @@ X11_player_selection_dialog(void) XtSetArg(args[num_args], nhStr(XtNfromVert), random_btn); num_args++; XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft); num_args++; XtSetArg(args[num_args], nhStr(XtNright), XtChainRight); num_args++; - XtSetArg(args[num_args], XtNwidth, cwid); num_args++; XtSetArg(args[num_args], nhStr(XtNlabel), "Play"); num_args++; plsel_btn_play = play_btn = XtCreateManagedWidget("play", commandWidgetClass, btn_form, args, num_args); + X11_wrap_widget_if_Xft(play_btn, NHW_MENU); + num_args = 0; + XtSetArg(args[num_args], XtNwidth, cwid); num_args++; + XtSetValues(play_btn, args, num_args); XtAddCallback(play_btn, XtNcallback, plsel_play_btn_callback, form); /* "Quit" button */ @@ -1185,10 +1212,13 @@ X11_player_selection_dialog(void) XtSetArg(args[num_args], nhStr(XtNbottom), XtChainBottom); num_args++; XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft); num_args++; XtSetArg(args[num_args], nhStr(XtNright), XtChainRight); num_args++; - XtSetArg(args[num_args], XtNwidth, cwid); num_args++; XtSetArg(args[num_args], nhStr(XtNlabel), "Quit"); num_args++; quit_btn = XtCreateManagedWidget("quit", commandWidgetClass, btn_form, args, num_args); + X11_wrap_widget_if_Xft(quit_btn, NHW_MENU); + num_args = 0; + XtSetArg(args[num_args], XtNwidth, cwid); num_args++; + XtSetValues(quit_btn, args, num_args); XtAddCallback(quit_btn, XtNcallback, plsel_quit_btn_callback, form); /********************************************/ @@ -2039,6 +2069,7 @@ make_menu(const char *popup_name, const char *popup_label, XtSetArg(args[num_args], XtNborderWidth, 0); num_args++; label = XtCreateManagedWidget(popup_label, labelWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(label, NHW_MENU); cumulative_height = 0; XtSetArg(args[0], XtNheight, &height); @@ -2058,6 +2089,7 @@ make_menu(const char *popup_name, const char *popup_label, Sprintf(btnname, "btn_%s", left_name); left = XtCreateManagedWidget(btnname, commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(left, NHW_MENU); XtAddCallback(left, XtNcallback, left_callback, (XtPointer) 0); skip = (distance < 4) ? 8 : 2 * distance; @@ -2081,6 +2113,7 @@ make_menu(const char *popup_name, const char *popup_label, Sprintf(btnname, "btn_%s", right_name); right = XtCreateManagedWidget(btnname, commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(right, NHW_MENU); XtAddCallback(right, XtNcallback, right_callback, (XtPointer) 0); XtInstallAccelerators(form, left); @@ -2106,6 +2139,7 @@ make_menu(const char *popup_name, const char *popup_label, *curr = XtCreateManagedWidget(widget_names[i], commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(*curr, NHW_MENU); XtAddCallback(*curr, XtNcallback, name_callback, (XtPointer) (ptrdiff_t) i); above = *curr++; From 31f5ca334da4df4c2c5703d66ece8b5693403f43 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 15 Aug 2026 01:26:35 -0400 Subject: [PATCH 634/702] Convert the text window to Xft --- win/X11/wintext.c | 104 +++++++++++++--------------------------------- 1 file changed, 29 insertions(+), 75 deletions(-) diff --git a/win/X11/wintext.c b/win/X11/wintext.c index 57c45540b..21db6199f 100644 --- a/win/X11/wintext.c +++ b/win/X11/wintext.c @@ -17,7 +17,8 @@ #include #include #include -#include +#include +#include #include #include @@ -43,12 +44,16 @@ */ static const char text_translations[] = "#override\n\ - : dismiss_text()\n\ + : dismiss_text()\n\ + : scroll(8)\n\ + : scroll(2)\n\ : key_dismiss_text()"; #ifdef GRAPHIC_TOMBSTONE static const char rip_translations[] = "#override\n\ - : rip_dismiss_text()\n\ + : rip_dismiss_text()\n\ + : scroll(8)\n\ + : scroll(2)\n\ : rip_dismiss_text()"; static Widget create_ripout_widget(Widget); @@ -147,42 +152,13 @@ display_text_window(struct xwindow *wp, boolean blocking) struct text_info_t *text_info; Arg args[8]; Cardinal num_args; - Dimension width, height, font_height; - int nlines; text_info = wp->text_information; - width = text_info->max_width + text_info->extra_width; text_info->blocked = blocking; text_info->destroy_on_ack = FALSE; - font_height = nhFontHeight(wp->w, NHW_TEXT); - - /* - * Calculate the number of lines to use. First, find the number of - * lines that would fit on the screen. Next, remove four of these - * lines to give room for a possible window manager titlebar (some - * wm's put a titlebar on transient windows). Make sure we have - * _some_ lines. Finally, use the number of lines in the text if - * there are fewer than the max. - */ - nlines = (XtScreen(wp->w)->height - text_info->extra_height) / font_height; - nlines -= 4; - - if (nlines > text_info->text.num_lines) - nlines = text_info->text.num_lines; - if (nlines <= 0) - nlines = 1; - - height = nlines * font_height + text_info->extra_height; num_args = 0; - if (nlines < text_info->text.num_lines) { - /* add on width of scrollbar. Really should look this up, - * but can't until the window is realized. Chicken-and-egg problem. - */ - width += 20; - } - #ifdef GRAPHIC_TOMBSTONE if (text_info->is_rip) { Widget rip = create_ripout_widget(XtParent(wp->w)); @@ -195,18 +171,10 @@ display_text_window(struct xwindow *wp, boolean blocking) } #endif - if (width > (Dimension) XtScreen(wp->w)->width) { /* too wide for screen */ - /* Back off some amount - we really need to back off the scrollbar */ - /* width plus some extra. */ - width = XtScreen(wp->w)->width - 20; - } - XtSetArg(args[num_args], XtNstring, text_info->text.text); - num_args++; - XtSetArg(args[num_args], XtNwidth, width); - num_args++; - XtSetArg(args[num_args], XtNheight, height); + XtSetArg(args[num_args], XtNlabel, text_info->text.text); num_args++; XtSetValues(wp->w, args, num_args); + X11_update_label_if_Xft(wp->w); #ifdef TRANSIENT_TEXT XtRealizeWidget(wp->popup); @@ -217,22 +185,6 @@ display_text_window(struct xwindow *wp, boolean blocking) nh_XtPopup(wp->popup, (int) XtGrabNone, wp->w); - /* Kludge alert. Scrollbars are not sized correctly by the Text widget */ - /* if added before the window is displayed, so do it afterward. */ - num_args = 0; - if (nlines < text_info->text.num_lines) { /* add vert scrollbar */ - XtSetArg(args[num_args], nhStr(XtNscrollVertical), - XawtextScrollAlways); - num_args++; - } - if (width >= (Dimension)(XtScreen(wp->w)->width - 20)) { /* too wide */ - XtSetArg(args[num_args], nhStr(XtNscrollHorizontal), - XawtextScrollAlways); - num_args++; - } - if (num_args) - XtSetValues(wp->w, args, num_args); - /* We want the user to acknowledge. */ if (blocking) { (void) x_event(EXIT_ON_EXIT); @@ -246,7 +198,6 @@ create_text_window(struct xwindow *wp) struct text_info_t *text_info; Arg args[8]; Cardinal num_args; - Position top_margin, bottom_margin, left_margin, right_margin; Widget form; wp->type = NHW_TEXT; @@ -280,46 +231,49 @@ create_text_window(struct xwindow *wp) wp->popup, XtParseTranslationTable("WM_PROTOCOLS: delete_text()")); + /* Create the viewport */ + num_args = 0; + XtSetArg(args[num_args], XtNallowVert, True); + num_args++; + XtSetArg(args[num_args], XtNallowHoriz, True); + num_args++; + Widget viewport = XtCreateManagedWidget( + "text_viewport", /* name */ + viewportWidgetClass, /* widget class from Window.h */ + wp->popup, /* parent widget */ + args, /* set some values */ + num_args); /* number of values to set */ + num_args = 0; XtSetArg(args[num_args], XtNallowShellResize, True), num_args++; XtSetArg(args[num_args], XtNtranslations, XtParseTranslationTable(text_translations)), num_args++; - form = XtCreateManagedWidget("form", formWidgetClass, wp->popup, args, + form = XtCreateManagedWidget("form", formWidgetClass, viewport, args, num_args); num_args = 0; - XtSetArg(args[num_args], nhStr(XtNdisplayCaret), False); - num_args++; - XtSetArg(args[num_args], XtNresize, XawtextResizeBoth); - num_args++; XtSetArg(args[num_args], XtNtranslations, XtParseTranslationTable(text_translations)); num_args++; + XtSetArg(args[num_args], XtNjustify, XtJustifyLeft); num_args++; wp->w = XtCreateManagedWidget(svk.killer.name[0] && WIN_MAP == WIN_ERR ? "tombstone" : "text_text", /* name */ - asciiTextWidgetClass, + labelWidgetClass, form, /* parent widget */ args, /* set some values */ num_args); /* number of values to set */ + X11_wrap_widget_if_Xft(wp->w, NHW_TEXT); /* Get the font and margin information. */ num_args = 0; XtSetArg(args[num_args], XtNfont, &text_info->fs); num_args++; - XtSetArg(args[num_args], nhStr(XtNtopMargin), &top_margin); - num_args++; - XtSetArg(args[num_args], nhStr(XtNbottomMargin), &bottom_margin); - num_args++; - XtSetArg(args[num_args], nhStr(XtNleftMargin), &left_margin); - num_args++; - XtSetArg(args[num_args], nhStr(XtNrightMargin), &right_margin); - num_args++; XtGetValues(wp->w, args, num_args); - text_info->extra_width = left_margin + right_margin; - text_info->extra_height = top_margin + bottom_margin; + text_info->extra_width = 0; + text_info->extra_height = 0; } void From 6e80039c4935585f8dce69d77193c2b38f94c72b Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 15 Aug 2026 04:56:34 -0400 Subject: [PATCH 635/702] Convert the tombstone window to Xft --- win/X11/wintext.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/win/X11/wintext.c b/win/X11/wintext.c index 21db6199f..cf2e93789 100644 --- a/win/X11/wintext.c +++ b/win/X11/wintext.c @@ -506,6 +506,33 @@ rip_exposed(Widget w, XtPointer client_data UNUSED, x = appResources.tombtext_x; y = appResources.tombtext_y; +#ifdef USE_XFT + Display *display = XtDisplay(w); + Screen *screen = DefaultScreenOfDisplay(display); + Visual *visual = DefaultVisualOfScreen(screen); + Colormap cmap = DefaultColormapOfScreen(screen); + XftDraw *draw = XftDrawCreate(display, XtWindow(w), visual, cmap); + XftFont *font = XftFontOpenName(display, DefaultScreen(display), + appResources.font_rip); + XftColor foreground; + X11_new_color(w, values.foreground, &foreground); + for (i = 0; i <= YEAR_LINE; i++) { + size_t len = strlen(rip_line[i]); + XGlyphInfo extents; + XftTextExtents8(display, font, + (const FcChar8 *) rip_line[i], len, + &extents); + int width = extents.width - extents.x; + + XftDrawString8(draw, &foreground, font, x - width / 2, y, + (const FcChar8 *) rip_line[i], len); + x += appResources.tombtext_dx; + y += appResources.tombtext_dy; + } + XftFontClose(display, font); + XftDrawDestroy(draw); + XftColorFree(display, visual, cmap, &foreground); +#else /* !USE_XFT */ for (i = 0; i <= YEAR_LINE; i++) { int len = strlen(rip_line[i]); XFontStruct *font = WindowFontStruct(w); @@ -515,6 +542,7 @@ rip_exposed(Widget w, XtPointer client_data UNUSED, x += appResources.tombtext_dx; y += appResources.tombtext_dy; } +#endif /* ?USE_XFT */ XtReleaseGC(w, ggc); } From faba01dd25c7f5040e239b948d80963b7f40159a Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 15 Aug 2026 04:57:07 -0400 Subject: [PATCH 636/702] Dismiss the text window on key press --- win/X11/wintext.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/win/X11/wintext.c b/win/X11/wintext.c index cf2e93789..0008687b7 100644 --- a/win/X11/wintext.c +++ b/win/X11/wintext.c @@ -237,6 +237,8 @@ create_text_window(struct xwindow *wp) num_args++; XtSetArg(args[num_args], XtNallowHoriz, True); num_args++; + XtSetArg(args[num_args], XtNtranslations, + XtParseTranslationTable(text_translations)), num_args++; Widget viewport = XtCreateManagedWidget( "text_viewport", /* name */ viewportWidgetClass, /* widget class from Window.h */ From 7e39b3faf179b89ad6a09827db8135c18e0b4fc8 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 15 Aug 2026 04:57:38 -0400 Subject: [PATCH 637/702] Note Xft support in option window --- src/mdlib.c | 3 +++ sys/unix/hints/linux.500 | 3 ++- sys/unix/hints/macOS.500 | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/mdlib.c b/src/mdlib.c index 6648717d4..9599ad8a0 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -576,6 +576,9 @@ static const char *const build_opts[] = { #ifdef USE_XPM "tiles file in XPM format", #endif +#ifdef USE_XFT + "font rendering with Xft", +#endif #ifdef GRAPHIC_TOMBSTONE "graphical RIP screen", #endif diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index 45da9ee12..656e831e6 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -410,7 +410,8 @@ X11CFLAGS = -I/opt/X11/include # avoid repeated complaints about _X_NONNULL(args...) in X11CFLAGS += -Wno-variadic-macros ifdef USE_XFT -X11CFLAGS += -DUSE_XFT $(shell pkg-config --cflags xft fontconfig) +CFLAGS += -DUSE_XFT +X11CFLAGS += $(shell pkg-config --cflags xft fontconfig) WINX11LIB += $(shell pkg-config --libs xft fontconfig) endif ifdef USE_XPM diff --git a/sys/unix/hints/macOS.500 b/sys/unix/hints/macOS.500 index 223dfb7c3..06646dab0 100755 --- a/sys/unix/hints/macOS.500 +++ b/sys/unix/hints/macOS.500 @@ -289,7 +289,8 @@ X11CFLAGS = -I/opt/X11/include # avoid repeated complaints about _X_NONNULL(args...) in X11CFLAGS += -Wno-variadic-macros ifdef USE_XFT -X11CFLAGS += -DUSE_XFT $(shell pkg-config --cflags xft fontconfig) +CFLAGS += -DUSE_XFT +X11CFLAGS += $(shell pkg-config --cflags xft fontconfig) WINX11LIB += $(shell pkg-config --libs xft fontconfig) endif ifdef USE_XPM From 5883fe4abbfe76a9b4c9b4e1808324e03e5b8dcd Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 15 Aug 2026 07:32:48 -0400 Subject: [PATCH 638/702] Declutter the rendering code a bit --- win/X11/winlabel.c | 101 +++++++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 44 deletions(-) diff --git a/win/X11/winlabel.c b/win/X11/winlabel.c index 8ac2cd41e..2c76c8f38 100644 --- a/win/X11/winlabel.c +++ b/win/X11/winlabel.c @@ -18,6 +18,15 @@ #include "hack.h" #include "winX.h" +/* Declarations depending on Xft support or none */ +#ifdef USE_XFT +typedef XftFont X11_Font; +#else +typedef XFontStruct X11_Font; +#endif +static int X11_text_width(Display *, X11_Font *, const char *, size_t); +static int X11_font_height(X11_Font *); + /* Data attached to a wrapped widget */ typedef struct WidgetData { /* Displayed text */ @@ -28,12 +37,11 @@ typedef struct WidgetData { boolean highlight; /* Fonts for italic, bold and bold-italic */ + X11_Font *font[4]; /* To use the fonts */ #ifdef USE_XFT int win_type; - XftFont *vfont[4]; #else /* !USE_XFT */ - XFontStruct *font[4]; /* To use the fonts */ - XFontStruct *font_ptr[4]; /* To free the fonts */ + X11_Font *font_ptr[4]; /* To free the fonts */ #endif /* ?USE_XFT */ /* Percentage bar */ @@ -195,11 +203,7 @@ update_label(Widget w, WidgetData *data) font_idx |= font_italic; allocate_font(w, data, font_idx); } -#ifdef USE_XFT - XftFont *vfont = data->vfont[font_idx]; -#else - XFontStruct *font = data->font[font_idx]; -#endif + X11_Font *font = data->font[font_idx]; String label; Boolean sens; /* Make dim if not sensitive */ @@ -237,13 +241,7 @@ update_label(Widget w, WidgetData *data) } /* Get the width of the line */ -#ifdef USE_XFT - XGlyphInfo extents; - XftTextExtents8(display, vfont, (const FcChar8*) (label + i), line2, &extents); - int lwidth = extents.width - extents.x; -#else - int lwidth = XTextWidth(font, label + i, line2); -#endif + int lwidth = X11_text_width(display, font, label + i, line2); /* Update pixmap dimensions */ width = max(lwidth, width); @@ -260,11 +258,7 @@ update_label(Widget w, WidgetData *data) height = max(height, 1); /* Convert height to pixels */ -#ifdef USE_XFT - height *= vfont->height; -#else - height *= font->ascent + font->descent; -#endif + height *= X11_font_height(font); } else { num_args = 0; XtSetArg(args[num_args], XtNwidth, &width); num_args++; @@ -358,11 +352,7 @@ update_label(Widget w, WidgetData *data) XSetForeground(display, ggc, values.foreground); #endif /* ?USE_XFT */ -#ifdef USE_XFT - int y = vfont->ascent; -#else /* !USE_XFT */ - int y = font->max_bounds.ascent; -#endif /* ?USE_XFT */ + int y = font->ascent; size_t i = 0; while (label[i] != '\0') { size_t line1 = strcspn(label + i, "\n"); @@ -373,13 +363,7 @@ update_label(Widget w, WidgetData *data) } /* Get the width of the line */ -#ifdef USE_XFT - XGlyphInfo extents; - XftTextExtents8(display, vfont, (const FcChar8*) (label + i), line2, &extents); - int lwidth = extents.width - extents.x; -#else - int lwidth = XTextWidth(font, label + i, line2); -#endif + int lwidth = X11_text_width(display, font, label + i, line2); /* Place the line horizontally */ int x = 0; @@ -399,8 +383,8 @@ update_label(Widget w, WidgetData *data) /* Render the line */ #ifdef USE_XFT - XftDrawRect(draw, &bgcolor, x, y - vfont->ascent, lwidth, vfont->height); - XftDrawString8(draw, &fgcolor, vfont, x, y, + XftDrawRect(draw, &bgcolor, x, y - font->ascent, lwidth, font->height); + XftDrawString8(draw, &fgcolor, font, x, y, (const FcChar8 *) (label + i), line2); #else XDrawImageString(display, new_pixmap, ggc, @@ -419,11 +403,7 @@ update_label(Widget w, WidgetData *data) #endif } -#ifdef USE_XFT - y += vfont->height; -#else - y += font->ascent + font->descent; -#endif + y += X11_font_height(font); /* Advance to next line */ i += line1; @@ -478,10 +458,10 @@ allocate_font(Widget w, WidgetData *data, unsigned font_idx) static const unsigned attrs[4] = { 0, HL_BOLD, HL_ITALIC, HL_BOLD | HL_ITALIC }; - data->vfont[font_idx] = X11_new_font(w, attrs[font_idx], data->win_type); + data->font[font_idx] = X11_new_font(w, attrs[font_idx], data->win_type); #else Display *display = XtDisplay(w); - XFontStruct *font1 = (font_idx == (font_bold | font_italic)) + X11_Font *font1 = (font_idx == (font_bold | font_italic)) ? data->font[font_bold] : data->font[0]; data->font_ptr[font_idx] = (font_idx == font_bold) @@ -500,10 +480,10 @@ free_fonts(Widget w, WidgetData *data) Display *display = XtDisplay(w); for (unsigned i = 0; i < 4; ++i) { #ifdef USE_XFT - if (data->vfont[i] != NULL) { - XftFontClose(display, data->vfont[i]); + if (data->font[i] != NULL) { + XftFontClose(display, data->font[i]); } - data->vfont[i] = NULL; + data->font[i] = NULL; #else if (data->font_ptr[i] != NULL) { XFreeFont(display, data->font_ptr[i]); @@ -514,6 +494,39 @@ free_fonts(Widget w, WidgetData *data) } } +////////////////////////////////////////////////////////////////////////////// +// Functions that depend on the font rendering API // +////////////////////////////////////////////////////////////////////////////// + +#ifdef USE_XFT +static int +X11_text_width(Display *display, X11_Font *font, const char *text, size_t length) +{ + XGlyphInfo extents; + XftTextExtents8(display, font, (const FcChar8*) text, length, &extents); + return extents.width - extents.x; +} + +static int +X11_font_height(X11_Font *font) +{ + return font->height; +} +#else /* !USE_XFT */ +static int +X11_text_width(Display *display, X11_Font *font, const char *text, size_t length) +{ + nhUse(display); + return XTextWidth(font, text, length); +} + +static int +X11_font_height(X11_Font *font) +{ + return font->ascent + font->descent; +} +#endif /* !USE_XFT */ + ////////////////////////////////////////////////////////////////////////////// // A table of widgets and their data blocks // ////////////////////////////////////////////////////////////////////////////// From cada45a786cae9a5f2a9c704b8deabf48c1152c8 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 15 Aug 2026 15:10:19 -0400 Subject: [PATCH 639/702] Apply appropriate #ifdefs and static declarations --- include/winX.h | 42 +++---------------- win/X11/winX.c | 105 +++++++++++++++++++++++++++++++--------------- win/X11/winmenu.c | 6 +-- win/X11/winmisc.c | 18 ++++---- win/X11/winstat.c | 8 ++++ win/X11/wintext.c | 4 +- 6 files changed, 100 insertions(+), 83 deletions(-) diff --git a/include/winX.h b/include/winX.h index 26e2440d0..76b4a58f4 100644 --- a/include/winX.h +++ b/include/winX.h @@ -374,23 +374,15 @@ extern void positionpopup(Widget, boolean); /* ### winX.c ### */ extern struct xwindow *find_widget(Widget); extern XColor get_nhcolor(struct xwindow *, int); -extern void init_menu_nhcolors(struct xwindow *); extern void load_boldfont(struct xwindow *, Widget); -extern Boolean nhApproxColor(Screen *, Colormap, char *, XColor *); -extern Boolean nhCvtStringToPixel(Display *, XrmValuePtr, Cardinal *, - XrmValuePtr, XrmValuePtr, XtPointer *); -extern void get_window_frame_extents(Widget, long *, long *, long *, long *); extern void get_widget_window_geometry(Widget, int *, int *, int *, int *); -extern char *fontname_boldify(const char *); extern Dimension nhFontHeight(Widget, int); extern char key_event_to_char(XKeyEvent *); -extern void msgkey(Widget, XtPointer, XEvent *, Boolean *); extern void highlight_yn(boolean); extern void nh_XtPopup(Widget, int, Widget); extern void nh_XtPopdown(Widget); extern void win_X11_init(int); extern void find_scrollbars(Widget, Widget, Widget *, Widget *); -extern void nh_keyscroll(Widget, XEvent *, String *, Cardinal *); /* ### winmesg.c ### */ extern void set_message_slider(struct xwindow *); @@ -420,8 +412,6 @@ extern void create_menu_window(struct xwindow *); extern void destroy_menu_window(struct xwindow *); /* ### winmisc.c ### */ -extern XtPointer i2xtp(int); -extern int xtp2i(XtPointer); extern void ps_key(Widget, XEvent *, String *, Cardinal *); /* player selection action */ extern void race_key(Widget, XEvent *, String *, @@ -442,7 +432,9 @@ extern void release_extended_cmds(void); /* ### winstatus.c ### */ extern void create_status_window(struct xwindow *, boolean, Widget); extern void destroy_status_window(struct xwindow *); +#ifndef STATUS_HILITES extern void adjust_status(struct xwindow *, const char *); +#endif extern void null_out_status(void); extern void check_turn_events(void); #ifdef STATUS_HILITES @@ -465,7 +457,6 @@ extern void append_text_buffer(struct text_buffer *, const char *, boolean); /* text buffer routines */ extern void init_text_buffer(struct text_buffer *); extern void clear_text_buffer(struct text_buffer *); -extern void free_text_buffer(struct text_buffer *); #ifdef GRAPHIC_TOMBSTONE extern void calculate_rip_text(int, time_t); #endif @@ -481,64 +472,41 @@ extern int get_value_width(Widget); extern void swap_fg_bg(Widget); extern void set_value(Widget w, const char *new_value); /* external declarations */ -extern char *X11_getmsghistory(boolean); -extern void X11_putmsghistory(const char *, boolean); -extern void X11_init_nhwindows(int *, char **); extern void X11_player_selection(void); -extern void X11_askname(void); -extern void X11_get_nh_event(void); extern void X11_exit_nhwindows(const char *); -extern void X11_suspend_nhwindows(const char *); -extern void X11_resume_nhwindows(void); extern winid X11_create_nhwindow(int); -extern void X11_clear_nhwindow(winid); -extern void X11_display_nhwindow(winid, boolean); extern void X11_destroy_nhwindow(winid); -extern void X11_curs(winid, int, int); -extern void X11_putstr(winid, int, const char *); -extern void X11_display_file(const char *, boolean); extern void X11_start_menu(winid, unsigned long); extern void X11_add_menu(winid, const glyph_info *, const ANY_P *, char, char, int, int, const char *, unsigned int); extern void X11_end_menu(winid, const char *); extern int X11_select_menu(winid, int, MENU_ITEM_P **); -extern void X11_mark_synch(void); -extern void X11_wait_synch(void); #ifdef CLIPPING extern void X11_cliparound(int, int); #endif extern void X11_print_glyph(winid, coordxy, coordxy, const glyph_info *, const glyph_info *); extern void X11_raw_print(const char *); -extern void X11_raw_print_bold(const char *); -extern int X11_nhgetch(void); -extern int X11_nh_poskey(coordxy *, coordxy *, int *); extern void X11_nhbell(void); -extern int X11_doprev_message(void); extern char X11_yn_function_core(const char *, const char *, char, unsigned); -extern char X11_yn_function(const char *, const char *, char); extern void X11_getlin(const char *, char *); extern int X11_get_ext_cmd(void); -extern void X11_number_pad(int); -extern void X11_delay_output(void); extern void X11_status_init(void); extern void X11_status_finish(void); extern void X11_status_enablefield(int, const char *, const char *, boolean); extern void X11_status_update(int, genericptr_t, int, int, int, unsigned long *); -#ifdef GRAPHIC_TOMBSTONE -extern void X11_outrip(winid, int, time_t); -#else +#ifndef GRAPHIC_TOMBSTONE extern void genl_outrip(winid, int, time_t); #endif -extern void X11_preference_update(const char *); extern void X11_update_inventory(int); -extern win_request_info *X11_ctrl_nhwindow(winid, int, win_request_info *); extern X11_map_symbol X11_glyph_char(const glyph_info *); +#ifndef USE_XFT extern XFontStruct *X11_bold_font(Display *, XFontStruct *); extern XFontStruct *X11_italic_font(Display *, XFontStruct *); +#endif /* !USE_XFT */ #ifdef ENHANCED_SYMBOLS extern XFontStruct *X11_unicode_font(Display *, XFontStruct *); #endif diff --git a/win/X11/winX.c b/win/X11/winX.c index 5ab8ab587..79adc1d6b 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -98,7 +98,7 @@ void (*input_func)(Widget, XEvent *, String *, Cardinal *); int click_x, click_y, click_button; /* Click position on a map window * (filled by set_button_values()). */ int updated_inventory; /* used to indicate perm_invent updating */ -color_attr X11_menu_promptstyle = { NO_COLOR, ATR_NONE }; +static color_attr X11_menu_promptstyle = { NO_COLOR, ATR_NONE }; /* X11/Intrinsic.h prototype has an issue if [[NORETURN]] is used * rather than the old __attribute((noreturn)) under c23 */ @@ -128,6 +128,41 @@ static XtSignalId X11_sig_id; #endif #endif +static void init_menu_nhcolors(struct xwindow *); +static Boolean nhApproxColor(Screen *, Colormap, char *, XColor *); +static Boolean nhCvtStringToPixel(Display *, XrmValuePtr, Cardinal *, + XrmValuePtr, XrmValuePtr, XtPointer *); +static void get_window_frame_extents(Widget, long *, long *, long *, long *); +#ifndef USE_XFT +static char *fontname_boldify(const char *); +#endif +static void msgkey(Widget, XtPointer, XEvent *, Boolean *); +static void nh_keyscroll(Widget, XEvent *, String *, Cardinal *); +static char *X11_getmsghistory(boolean); +static void X11_putmsghistory(const char *, boolean); +static void X11_init_nhwindows(int *, char **); +static void X11_askname(void); +static void X11_get_nh_event(void); +static void X11_suspend_nhwindows(const char *); +static void X11_resume_nhwindows(void); +static void X11_clear_nhwindow(winid); +static void X11_display_nhwindow(winid, boolean); +static void X11_curs(winid, int, int); +static void X11_putstr(winid, int, const char *); +static void X11_display_file(const char *, boolean); +static void X11_mark_synch(void); +static void X11_wait_synch(void); +static void X11_raw_print_bold(const char *); +static int X11_nhgetch(void); +static int X11_nh_poskey(coordxy *, coordxy *, int *); +static int X11_doprev_message(void); +static char X11_yn_function(const char *, const char *, char); +static void X11_number_pad(int); +static void X11_delay_output(void); +static void X11_outrip(winid, int, time_t); +static void X11_preference_update(const char *); +static win_request_info *X11_ctrl_nhwindow(winid, int, win_request_info *); + /* Interface definition, for windows.c */ struct window_procs X11_procs = { WPID(X11), @@ -214,7 +249,7 @@ static winid message_win = WIN_ERR, /* These are the winids of the message, */ status_win = WIN_ERR; /* are created in init_windows(). */ static Pixmap icon_pixmap = None; /* Pixmap for icon. */ -void +static void X11_putmsghistory(const char *msg, boolean is_restoring) { if (WIN_MESSAGE != WIN_ERR) { @@ -225,7 +260,7 @@ X11_putmsghistory(const char *msg, boolean is_restoring) } } -char * +static char * X11_getmsghistory(boolean init) { if (WIN_MESSAGE != WIN_ERR) { @@ -308,7 +343,7 @@ get_nhcolor(struct xwindow *wp, int clr) return wp->nh_colors[0]; } -void +static void init_menu_nhcolors(struct xwindow *wp) { static const char *mapCLR_to_res[CLR_MAX] = { @@ -392,7 +427,7 @@ init_menu_nhcolors(struct xwindow *wp) * allocate the exact color, they puke and give you something stupid. * This is an attempt to find some close readonly cell and use it. */ -XtConvertArgRec const nhcolorConvertArgs[] = { +static XtConvertArgRec const nhcolorConvertArgs[] = { { XtWidgetBaseOffset, (XtPointer) (ptrdiff_t) XtOffset(Widget, core.screen), sizeof (Screen *) }, @@ -425,7 +460,7 @@ XtConvertArgRec const nhcolorConvertArgs[] = { * The approximate color found is returned in color as well. * Return True if something close was found. */ -Boolean +static Boolean nhApproxColor( Screen *screen, /* screen to use */ Colormap colormap, /* the colormap to use */ @@ -501,7 +536,7 @@ nhApproxColor( return True; } -Boolean +static Boolean nhCvtStringToPixel( Display *dpy, XrmValuePtr args, Cardinal *num_args, @@ -594,7 +629,7 @@ nhCvtStringToPixel( } /* Ask the WM for window frame size */ -void +static void get_window_frame_extents( Widget w, long *top, long *bottom, @@ -670,8 +705,9 @@ get_widget_window_geometry( *y -= top; } +#ifndef USE_XFT /* Change the full font name string so the weight is "bold" */ -char * +static char * fontname_boldify(const char *fontname) { static char buf[BUFSZ]; @@ -719,6 +755,7 @@ load_boldfont(struct xwindow *wp, Widget w) fontname = fontname_boldify(XGetAtomName(dpy, (Atom)ret)); wp->boldfs = XLoadQueryFont(dpy, fontname); } +#endif /* !USE_XFT */ /* ARGSUSED */ static void @@ -960,13 +997,13 @@ X11_raw_print(const char *str) (void) puts(str); } -void +static void X11_raw_print_bold(const char *str) { (void) puts(str); } -void +static void X11_curs(winid window, int x, int y) { check_winid(window); @@ -984,7 +1021,7 @@ X11_curs(winid window, int x, int y) window_list[window].cursy = y; } -void +static void X11_putstr(winid window, int attr, const char *str) { winid new_win; @@ -1032,19 +1069,19 @@ X11_putstr(winid window, int attr, const char *str) } /* We do event processing as a callback, so this is a null routine. */ -void +static void X11_get_nh_event(void) { return; } -int +static int X11_nhgetch(void) { return input_event(EXIT_ON_KEY_PRESS); } -int +static int X11_nh_poskey(coordxy *x, coordxy *y, int *mod) { int val = input_event(EXIT_ON_KEY_OR_BUTTON_PRESS); @@ -1151,7 +1188,7 @@ X11_create_nhwindow(int type) return window; } -void +static void X11_clear_nhwindow(winid window) { struct xwindow *wp; @@ -1177,7 +1214,7 @@ X11_clear_nhwindow(winid window) } } -void +static void X11_display_nhwindow(winid window, boolean blocking) { struct xwindow *wp; @@ -1328,7 +1365,7 @@ X11_update_inventory(int arg) return; } -win_request_info * +static win_request_info * X11_ctrl_nhwindow( winid window UNUSED, int request UNUSED, @@ -1351,7 +1388,7 @@ X11_ctrl_nhwindow( } /* The current implementation has all of the saved lines on the screen. */ -int +static int X11_doprev_message(void) { return 0; @@ -1374,7 +1411,7 @@ X11_nhbell(void) } } -void +static void X11_mark_synch(void) { if (x_inited) { @@ -1391,7 +1428,7 @@ X11_mark_synch(void) } } -void +static void X11_wait_synch(void) { if (x_inited) { @@ -1401,13 +1438,13 @@ X11_wait_synch(void) } /* Both resume_ and suspend_ are called from ioctl.c and unixunix.c. */ -void +static void X11_resume_nhwindows(void) { return; } /* ARGSUSED */ -void +static void X11_suspend_nhwindows(const char *str) { nhUse(str); @@ -1417,7 +1454,7 @@ X11_suspend_nhwindows(const char *str) /* Under X, we don't need to initialize the number pad. */ /* ARGSUSED */ -void +static void X11_number_pad(int state) /* called from options.c */ { nhUse(state); @@ -1426,7 +1463,7 @@ X11_number_pad(int state) /* called from options.c */ } #ifdef GRAPHIC_TOMBSTONE -void +static void X11_outrip(winid window, int how, time_t when) { struct xwindow *wp; @@ -1597,7 +1634,7 @@ X11_io_error_handler(Display *display) return 0; } -void +static void X11_init_nhwindows(int *argcp, char **argv) { int i; @@ -1812,7 +1849,7 @@ d_timeout(XtPointer client_data, XtIntervalId *id) * function will send an event to the map window which will be waiting * for a sent event. */ -void +static void X11_delay_output(void) { if (!x_inited) @@ -1902,7 +1939,7 @@ askname_done(Widget w, XtPointer client_data, XtPointer call_data) /* ask player for character's name to replace generic name "player" (or other values; see config.h) after 'nethack -u player' or OPTIONS=name:player */ -void +static void X11_askname(void) { Widget popup, dialog; @@ -2120,7 +2157,7 @@ X11_getlin( /* uses a menu (with no selectors specified) rather than a text window to allow previous_page and first_menu actions to move backwards */ -void +static void X11_display_file(const char *str, boolean complain) { dlb *fp; @@ -2518,7 +2555,7 @@ X11_yn_function_core( /* X11-specific edition of yn_function(), the routine called by the core to show a prompt and get a single key answer, often 'y' vs 'n' */ -char +static char X11_yn_function( const char *ques, /* prompt text */ const char *choices, /* allowed response chars; any char if Null */ @@ -2531,7 +2568,7 @@ X11_yn_function( /* used when processing window-capability-specific run-time options; we support toggling tiles on and off via iflags.wc_tiled_map */ -void +static void X11_preference_update(const char *pref) { if (!strcmp(pref, "tiled_map")) { @@ -2562,7 +2599,7 @@ input_event(int exit_condition) } /*ARGSUSED*/ -void +static void msgkey(Widget w, XtPointer data, XEvent *event, Boolean *continue_to_dispatch) { Cardinal num = 0; @@ -2893,7 +2930,7 @@ find_scrollbars( * Scroll a viewport, using standard NH 1,2,3,4,6,7,8,9 directions. */ /*ARGSUSED*/ -void +static void nh_keyscroll(Widget viewport, XEvent *event, String *params, Cardinal *num_params) { @@ -3058,6 +3095,7 @@ X11_glyph_char(const glyph_info *glyphinfo) #endif } +#ifndef USE_XFT /* Given an XFontStruct, return a corresponding bold font */ XFontStruct * X11_bold_font(Display *display, XFontStruct *font) @@ -3120,6 +3158,7 @@ X11_italic_font(Display *display, XFontStruct *font) return font2; } +#endif /* !USE_XFT */ #ifdef ENHANCED_SYMBOLS /* Given an XFontStruct, return a corresponding font that supports Unicode */ diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index 596578912..0addf7c39 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -89,9 +89,9 @@ static const char menu_entry_translations[] = "#override\n\ : scroll(8)\n\ : scroll(2)"; -XtTranslations menu_entry_translation_table = (XtTranslations) 0; -XtTranslations menu_translation_table = (XtTranslations) 0; -XtTranslations menu_del_translation_table = (XtTranslations) 0; +static XtTranslations menu_entry_translation_table = (XtTranslations) 0; +static XtTranslations menu_translation_table = (XtTranslations) 0; +static XtTranslations menu_del_translation_table = (XtTranslations) 0; static void create_menu_translation_tables(void) diff --git a/win/X11/winmisc.c b/win/X11/winmisc.c index 023213502..0a4bb4d09 100644 --- a/win/X11/winmisc.c +++ b/win/X11/winmisc.c @@ -124,13 +124,13 @@ static Widget make_menu(const char *, const char *, const char *, const char *, const char **, Widget **, XtCallbackProc, Widget *); /* Bad Hack alert. Using integers instead of XtPointers */ -XtPointer +static XtPointer i2xtp(int i) { return (XtPointer) (ptrdiff_t) i; } -int +static int xtp2i(XtPointer x) { return (int) (ptrdiff_t) x; @@ -328,15 +328,15 @@ algn_key(Widget w, XEvent *event, String *params, Cardinal *num_params) exit_x_event = TRUE; } -int plsel_n_races, plsel_n_roles; -Widget *plsel_race_radios = (Widget *) 0; -Widget *plsel_role_radios = (Widget *) 0; -Widget *plsel_gend_radios = (Widget *) 0; -Widget *plsel_align_radios = (Widget *) 0; +static int plsel_n_races, plsel_n_roles; +static Widget *plsel_race_radios = (Widget *) 0; +static Widget *plsel_role_radios = (Widget *) 0; +static Widget *plsel_gend_radios = (Widget *) 0; +static Widget *plsel_align_radios = (Widget *) 0; -Widget plsel_name_input; +static Widget plsel_name_input; -Widget plsel_btn_play; +static Widget plsel_btn_play; static void plsel_dialog_acceptvalues(void) diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 4fde169d0..b9a81c337 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -123,8 +123,10 @@ static void create_status_window_fancy(struct xwindow *, boolean, Widget); static void create_status_window_tty(struct xwindow *, boolean, Widget); static void destroy_status_window_fancy(struct xwindow *); static void destroy_status_window_tty(struct xwindow *); +#ifndef STATUS_HILITES static void adjust_status_fancy(struct xwindow *, const char *); static void adjust_status_tty(struct xwindow *, const char *); +#endif static void set_percent(int, int, int); static void tty_status_exposed(Widget, XtPointer, XtPointer); static void tty_status_redraw(Widget); @@ -1092,6 +1094,7 @@ destroy_status_window_tty(struct xwindow *wp) wp->type = NHW_NONE; } +#ifndef STATUS_HILITES /*ARGSUSED*/ void adjust_status_tty(struct xwindow *wp UNUSED, const char *str UNUSED) @@ -1099,6 +1102,7 @@ adjust_status_tty(struct xwindow *wp UNUSED, const char *str UNUSED) /* nothing */ return; } +#endif void create_status_window( @@ -1162,6 +1166,7 @@ destroy_status_window(struct xwindow *wp) destroy_status_window_tty(wp); } +#ifndef STATUS_HILITES void adjust_status(struct xwindow *wp, const char *str) { @@ -1170,6 +1175,7 @@ adjust_status(struct xwindow *wp, const char *str) else adjust_status_tty(wp, str); } +#endif void create_status_window_fancy(struct xwindow *wp, /* window pointer */ @@ -1270,6 +1276,7 @@ destroy_status_window_fancy(struct xwindow *wp) wp->type = NHW_NONE; } +#ifndef STATUS_HILITES /* * This assumes several things: * + Status has only 2 lines @@ -1300,6 +1307,7 @@ adjust_status_fancy(struct xwindow *wp, const char *str) wp->status_information->text.text); num_args++; XtSetValues(wp->w, args, num_args); } +#endif /* Fancy ================================================================== */ extern const char *const hu_stat[]; /* from eat.c */ diff --git a/win/X11/wintext.c b/win/X11/wintext.c index 0008687b7..8a5e61cd7 100644 --- a/win/X11/wintext.c +++ b/win/X11/wintext.c @@ -59,6 +59,8 @@ static const char rip_translations[] = "#override\n\ static Widget create_ripout_widget(Widget); #endif +static void free_text_buffer(struct text_buffer *); + /*ARGSUSED*/ void delete_text(Widget w, XEvent *event, String *params, Cardinal *num_params) @@ -388,7 +390,7 @@ clear_text_buffer(struct text_buffer *tb) } /* Free up allocated memory. */ -void +static void free_text_buffer(struct text_buffer *tb) { free(tb->text); From 3f8e704231563c1f164f729a2b6e1be98089da08 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 15 Aug 2026 19:34:03 -0400 Subject: [PATCH 640/702] More ifdefs; use Xft font to split messages --- include/winX.h | 24 ++++++++++------- win/X11/Window.c | 2 ++ win/X11/winX.c | 6 ++++- win/X11/winmap.c | 31 ++++++++++++++++----- win/X11/winmesg.c | 68 ++++++++++++++++++++++++++++++++++------------- win/X11/wintext.c | 24 ++++------------- 6 files changed, 101 insertions(+), 54 deletions(-) diff --git a/include/winX.h b/include/winX.h index 76b4a58f4..dc34bd572 100644 --- a/include/winX.h +++ b/include/winX.h @@ -84,7 +84,7 @@ struct text_map_info_t { square_ascent, /* placement of changes. */ square_lbearing; -#ifdef ENHANCED_SYMBOLS +#if defined(ENHANCED_SYMBOLS) && !defined(USE_XFT) XFontStruct *font; #endif }; @@ -131,7 +131,12 @@ struct line_element { }; struct mesg_info_t { +#ifdef USE_XFT + Pixel fgpixel; /* Color for text drawing */ +#else + GC gc; /* GC for text drawing */ XFontStruct *fs; /* Font for the window. */ +#endif int num_lines; /* line count */ struct line_element *head; /* head of circular line queue */ struct line_element *line_here; /* current drawn line position */ @@ -139,11 +144,6 @@ struct mesg_info_t { /* bottom of screen */ struct line_element *last_pause_head; /* pointer to head of previous */ /* turn */ -#ifdef USE_XFT - Pixel fgpixel; /* Color for text drawing */ -#else - GC gc; /* GC for text drawing */ -#endif int char_width, /* Saved font information so we can */ char_height, /* calculate the correct placement */ char_ascent, /* of changes. */ @@ -161,7 +161,9 @@ struct mesg_info_t { struct status_info_t { struct text_buffer text; /* Just a text buffer. */ Pixel fg, bg; /* foreground and background */ +#ifndef USE_XFT XFontStruct *fs; /* Status window font structure. */ +#endif Dimension spacew; /* width of one space */ Position x, y[3]; /* x coord (not used), y for up to three lines */ Dimension wd, ht; /* width (not used), height (same for all lines) */ @@ -202,7 +204,9 @@ struct menu_info_t { struct menu curr_menu; /* Menu being displayed. */ struct menu new_menu; /* New menu being built. */ +#ifndef USE_XFT XFontStruct *fs; /* Font for the window. */ +#endif long menu_count; /* number entered by user */ Dimension line_height; /* Total height of a line of text. */ Dimension internal_height; /* Internal height between widget & border */ @@ -225,10 +229,6 @@ struct menu_info_t { */ struct text_info_t { struct text_buffer text; - XFontStruct *fs; /* Font for the text window. */ - int max_width; /* Width of widest line so far. */ - int extra_width, /* Sum of left and right border widths. */ - extra_height; /* Sum of top and bottom border widths. */ boolean blocked; /* */ boolean destroy_on_ack; /* Destroy this window when acknowledged. */ #ifdef GRAPHIC_TOMBSTONE @@ -250,8 +250,10 @@ struct xwindow { boolean nh_colors_inited; XColor nh_colors[CLR_MAX]; +#ifndef USE_XFT XFontStruct *boldfs; /* Bold font */ Display *boldfs_dpy; /* Bold font display */ +#endif char *title; union { @@ -361,8 +363,10 @@ extern boolean X11_blink; } while (0) /* ### Window.c ### */ +#ifndef USE_XFT extern Font WindowFont(Widget); extern XFontStruct *WindowFontStruct(Widget); +#endif /* ### dialogs.c ### */ extern Widget CreateDialog(Widget, String, XtCallbackProc, XtCallbackProc); diff --git a/win/X11/Window.c b/win/X11/Window.c index d9b4f3edb..401caaa2d 100644 --- a/win/X11/Window.c +++ b/win/X11/Window.c @@ -168,6 +168,7 @@ WindowClassRec windowClassRec = { WidgetClass windowWidgetClass = (WidgetClass) &windowClassRec; +#ifndef USE_XFT Font WindowFont(Widget w) { @@ -179,3 +180,4 @@ WindowFontStruct(Widget w) { return ((WindowWidget) w)->window.font; } +#endif diff --git a/win/X11/winX.c b/win/X11/winX.c index 79adc1d6b..c59ab5fab 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -1161,8 +1161,10 @@ X11_create_nhwindow(int type) wp->pixel_height = 0; wp->keep_window = FALSE; wp->nh_colors_inited = FALSE; +#ifndef USE_XFT wp->boldfs = (XFontStruct *) 0; wp->boldfs_dpy = (Display *) 0; +#endif wp->title = (char *) 0; switch (type) { @@ -1304,11 +1306,13 @@ X11_destroy_nhwindow(winid window) WIN_INVEN = WIN_ERR; } +#ifndef USE_XFT if (wp->boldfs) { XFreeFont(wp->boldfs_dpy, wp->boldfs); wp->boldfs = (XFontStruct *) 0; wp->boldfs_dpy = (Display *) 0; } +#endif if (wp->title) { free(wp->title); @@ -3158,7 +3162,6 @@ X11_italic_font(Display *display, XFontStruct *font) return font2; } -#endif /* !USE_XFT */ #ifdef ENHANCED_SYMBOLS /* Given an XFontStruct, return a corresponding font that supports Unicode */ @@ -3202,6 +3205,7 @@ X11_unicode_font(Display *display, XFontStruct *font) return unifont; } #endif /* ENHANCED_SYMBOLS */ +#endif /* !USE_XFT */ #ifdef USE_XFT diff --git a/win/X11/winmap.c b/win/X11/winmap.c index c6733f76c..a09691957 100644 --- a/win/X11/winmap.c +++ b/win/X11/winmap.c @@ -72,12 +72,15 @@ static void X11_free_gc(struct xwindow *wp, GC gc, X11_color color); static void X11_draw_image_string(Display *display, Drawable d, GC ggc, int x, int y, const X11_map_symbol *string, int length); -#endif /* ?USE_XFT */ #ifdef ENHANCED_SYMBOLS static void X11_set_map_font(struct xwindow *wp); #endif +#endif /* ?USE_XFT */ static Font X11_get_map_font(struct xwindow *wp); +#ifndef USE_XFT static XFontStruct *X11_get_map_font_struct(struct xwindow *wp); +#endif +static void get_text_gc(struct xwindow *, Font); static boolean init_tiles(struct xwindow *); static void set_button_values(Widget, int, int, unsigned); static void map_check_size_change(struct xwindow *); @@ -85,7 +88,6 @@ static void map_update(struct xwindow *, int, int, int, int, boolean); static void init_text(struct xwindow *); static void map_exposed(Widget, XtPointer, XtPointer); static void set_gc(Widget, Font, const char *, Pixel, GC *, GC *); -static void get_text_gc(struct xwindow *, Font); static void map_all_unexplored(struct map_info_t *); static void get_char_info(struct xwindow *); static void display_cursor(struct xwindow *); @@ -844,7 +846,11 @@ set_gc( GC *regular, GC *inverse) { XGCValues values; +#ifdef USE_XFT + XtGCMask mask = GCFunction | GCForeground | GCBackground; +#else XtGCMask mask = GCFunction | GCForeground | GCBackground | GCFont; +#endif Pixel curpixel; Arg arg[1]; @@ -1587,10 +1593,16 @@ X11_make_gc( values.background = bgpixel; } values.function = GXcopy; +#ifdef USE_XFT + ggc = XtGetGC(wp->w, + GCFunction | GCForeground | GCBackground, + &values); +#else values.font = X11_get_map_font(wp); ggc = XtGetGC(wp->w, GCFunction | GCForeground | GCBackground | GCFont, &values); +#endif } else { ggc = (cur_inv ? text_map->inv_copy_gc : text_map->copy_gc); } @@ -1784,7 +1796,7 @@ create_map_window( map_info = wp->map_information = (struct map_info_t *) alloc(sizeof (struct map_info_t)); -#ifdef ENHANCED_SYMBOLS +#if defined(ENHANCED_SYMBOLS) && !defined(USE_XFT) X11_set_map_font(wp); #endif @@ -1835,7 +1847,7 @@ create_map_window( map_all_unexplored(map_info); } -#ifdef ENHANCED_SYMBOLS +#if defined(ENHANCED_SYMBOLS) && !defined(USE_XFT) static void X11_set_map_font(struct xwindow *wp) { @@ -1853,14 +1865,20 @@ X11_set_map_font(struct xwindow *wp) map_info->text_map.font = fs; } } -#endif +#endif /* ENHANCED_SYMBOLS && !USE_XFT */ static Font X11_get_map_font(struct xwindow *wp) { +#ifdef USE_XFT + nhUse(wp); + return 0; +#else /* !USE_XFT */ return X11_get_map_font_struct(wp)->fid; +#endif /* ?USE_XFT */ } +#ifndef USE_XFT static XFontStruct * X11_get_map_font_struct(struct xwindow *wp) { @@ -1876,6 +1894,7 @@ X11_get_map_font_struct(struct xwindow *wp) return WindowFontStruct(wp->w); #endif } +#endif /* USE_XFT */ /* * Destroy this map window. @@ -1900,7 +1919,7 @@ destroy_map_window(struct xwindow *wp) } /* Free the font structure if we allocated one */ -#ifdef ENHANCED_SYMBOLS +#if defined(ENHANCED_SYMBOLS) && !defined(USE_XFT) XFreeFont(XtDisplay(wp->w), text_map->font); #endif diff --git a/win/X11/winmesg.c b/win/X11/winmesg.c index 69df458b0..aa707a186 100644 --- a/win/X11/winmesg.c +++ b/win/X11/winmesg.c @@ -37,7 +37,7 @@ static struct line_element *get_previous(struct line_element *); static void set_circle_buf(struct mesg_info_t *, int); -static char *split(char *, XFontStruct *, Dimension); +static char *split(char *, struct xwindow *, Dimension); static void add_line(struct mesg_info_t *, const char *); static void redraw_message_window(struct xwindow *); static void mesg_check_size_change(struct xwindow *); @@ -83,7 +83,9 @@ create_message_window(struct xwindow *wp, /* window pointer */ wp->mesg_information = mesg_info = (struct mesg_info_t *) alloc(sizeof (struct mesg_info_t)); +#ifndef USE_XFT mesg_info->fs = 0; +#endif mesg_info->num_lines = 0; mesg_info->head = mesg_info->line_here = mesg_info->last_pause = mesg_info->last_pause_head = (struct line_element *) 0; @@ -151,26 +153,37 @@ create_message_window(struct xwindow *wp, /* window pointer */ * is appResources.message_lines high and DEFAULT_MESSAGE_WIDTH wide. */ + /* Save character information for fast use later. */ +#ifdef USE_XFT + XftFont *font = X11_new_font(wp->w, 0, NHW_MESSAGE); + XGlyphInfo extents; + mesg_info->char_width = font->max_advance_width; + mesg_info->char_height = font->height; + mesg_info->char_ascent = font->ascent; + mesg_info->char_lbearing = 0; + /* Xft seems to offer no direct way to distinguish proportional from + monospaced fonts. Assume that "!" will be narrower than maximum. */ + XftTextExtents8(XtDisplay(wp->w), font, (const FcChar8*) "!", 1, &extents); + int min_width = extents.width - extents.x; + /* "Maximum" is likely to include things like Chinese characters that + * display at double width. Use the width of "M". */ + XftTextExtents8(XtDisplay(wp->w), font, (const FcChar8*) "M", 1, &extents); + int max_width = extents.width - extents.x; + X11_release_font(wp->w, font); +#else /* Get the font information. */ num_args = 0; XtSetArg(args[num_args], XtNfont, &mesg_info->fs); num_args++; XtGetValues(wp->w, args, num_args); - /* Save character information for fast use later. */ -#ifdef USE_XFT - XftFont *font = X11_new_font(wp->w, 0, NHW_MESSAGE); - mesg_info->char_width = font->max_advance_width; - mesg_info->char_height = font->height; - mesg_info->char_ascent = font->ascent; - mesg_info->char_lbearing = 0; - X11_release_font(wp->w, font); -#else mesg_info->char_width = mesg_info->fs->max_bounds.width; mesg_info->char_height = mesg_info->fs->max_bounds.ascent + mesg_info->fs->max_bounds.descent; mesg_info->char_ascent = mesg_info->fs->max_bounds.ascent; mesg_info->char_lbearing = -mesg_info->fs->min_bounds.lbearing; + int min_width = mesg_info->fs->min_bounds.width; + int max_width = mesg_info->fs->max_bounds.width; #endif get_gc(wp->w, mesg_info); @@ -178,12 +191,11 @@ create_message_window(struct xwindow *wp, /* window pointer */ wp->pixel_height = ((int) iflags.msg_history) * mesg_info->char_height; /* If a variable spaced font, only use 2/3 of the default size */ - if (mesg_info->fs->min_bounds.width != mesg_info->fs->max_bounds.width) { + if (min_width != max_width) { wp->pixel_width = ((2 * DEFAULT_MESSAGE_WIDTH) / 3) - * mesg_info->fs->max_bounds.width; + * max_width; } else - wp->pixel_width = - (DEFAULT_MESSAGE_WIDTH * mesg_info->fs->max_bounds.width); + wp->pixel_width = (DEFAULT_MESSAGE_WIDTH * max_width); /* Set the new width and height. */ num_args = 0; @@ -259,7 +271,7 @@ append_message(struct xwindow *wp, const char *str) remainder = buf; do { mark = remainder; - remainder = split(mark, wp->mesg_information->fs, wp->pixel_width); + remainder = split(mark, wp, wp->pixel_width); add_line(wp->mesg_information, mark); } while (remainder); } @@ -366,10 +378,16 @@ set_circle_buf(struct mesg_info_t *mesg_info, int count) * not, back up from the end by words until we find a place to split. */ static char * -split(char *s, - XFontStruct *fs, /* Font for the window. */ +split( + char *s, + struct xwindow *wp, Dimension pixel_width) { +#ifdef USE_XFT + XftFont *font = X11_new_font(wp->w, 0, NHW_MESSAGE); +#else + XFontStruct *fs = wp->mesg_information->fs; /* Font for the window. */ +#endif char save, *end, *remainder; save = '\0'; @@ -377,7 +395,18 @@ split(char *s, end = eos(s); /* point to null at end of string */ /* assume that if end == s, XXXXXX returns 0) */ - while ((Dimension) XTextWidth(fs, s, (int) strlen(s)) > pixel_width) { + while (TRUE) { +#ifdef USE_XFT + XGlyphInfo extents; + XftTextExtents8(XtDisplay(wp->w), font, (const FcChar8*) s, strlen(s), &extents); + if (extents.width - extents.x < pixel_width) { + break; + } +#else + if ((Dimension) XTextWidth(fs, s, (int) strlen(s)) < pixel_width) { + break; + } +#endif *end-- = save; while (*end != ' ') { if (end == s) @@ -388,6 +417,9 @@ split(char *s, *end = '\0'; remainder = end + 1; } +#ifdef USE_XFT + X11_release_font(wp->w, font); +#endif return remainder; } diff --git a/win/X11/wintext.c b/win/X11/wintext.c index 8a5e61cd7..ee6247029 100644 --- a/win/X11/wintext.c +++ b/win/X11/wintext.c @@ -136,16 +136,10 @@ add_to_text_window(struct xwindow *wp, int attr, /* currently unused */ const char *str) { struct text_info_t *text_info = wp->text_information; - int width; nhUse(attr); append_text_buffer(&text_info->text, str, FALSE); - - /* Calculate text width and save longest line */ - width = XTextWidth(text_info->fs, str, (int) strlen(str)); - if (width > text_info->max_width) - text_info->max_width = width; } void @@ -208,9 +202,6 @@ create_text_window(struct xwindow *wp) (struct text_info_t *) alloc(sizeof(struct text_info_t)); init_text_buffer(&text_info->text); - text_info->max_width = 0; - text_info->extra_width = 0; - text_info->extra_height = 0; text_info->blocked = FALSE; text_info->destroy_on_ack = TRUE; /* Ok to destroy before display */ #ifdef GRAPHIC_TOMBSTONE @@ -269,15 +260,6 @@ create_text_window(struct xwindow *wp) args, /* set some values */ num_args); /* number of values to set */ X11_wrap_widget_if_Xft(wp->w, NHW_TEXT); - - /* Get the font and margin information. */ - num_args = 0; - XtSetArg(args[num_args], XtNfont, &text_info->fs); - num_args++; - XtGetValues(wp->w, args, num_args); - - text_info->extra_width = 0; - text_info->extra_height = 0; } void @@ -495,12 +477,16 @@ rip_exposed(Widget w, XtPointer client_data UNUSED, XDestroyImage(rip_image); /* data bytes free'd also */ } - mask = GCFunction | GCForeground | GCGraphicsExposures | GCFont; values.graphics_exposures = False; XtSetArg(args[0], XtNforeground, &values.foreground); XtGetValues(w, args, 1); values.function = GXcopy; +#ifdef USE_XFT + mask = GCFunction | GCForeground | GCGraphicsExposures; +#else + mask = GCFunction | GCForeground | GCGraphicsExposures | GCFont; values.font = WindowFont(w); +#endif ggc = XtGetGC(w, mask, &values); if (rip_pixmap != None) { From e3170cdedc9132d8d1a5fdb02ed350369ad3a427 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Mon, 17 Aug 2026 05:24:54 -0400 Subject: [PATCH 641/702] Provide more space between TTY-style status fields --- sys/unix/Makefile.src | 2 +- win/X11/winstat.c | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 2bac600b8..cb669d80d 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -1080,7 +1080,7 @@ $(TARGETPFX)winX.o: ../win/X11/winX.c $(HACK_H) ../include/dlb.h \ ../include/winX.h ../include/xwindow.h ../win/X11/nh32icon \ ../win/X11/nh56icon ../win/X11/nh72icon $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winX.c -$(TARGETPFX)winlabel.o: ../win/X11/winlabel.c $(HACK_H) +$(TARGETPFX)winlabel.o: ../win/X11/winlabel.c $(HACK_H) ../include/winX.h $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winlabel.c $(TARGETPFX)winmap.o: ../win/X11/winmap.c $(HACK_H) ../include/dlb.h \ ../include/tile2x11.h ../include/winX.h ../include/xwindow.h diff --git a/win/X11/winstat.c b/win/X11/winstat.c index b9a81c337..2fa32ae6b 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -130,7 +130,7 @@ static void adjust_status_tty(struct xwindow *, const char *); static void set_percent(int, int, int); static void tty_status_exposed(Widget, XtPointer, XtPointer); static void tty_status_redraw(Widget); -static int tty_render_field(Widget, int, int, enum statusfields); +static int tty_render_field(Widget, int, int, int, enum statusfields); static void tty_status_colors(Widget, int, int, Pixel *, Pixel *); static int tty_render_text(Widget, const XRectangle *, int, int, const char *, int, int, enum statusfields); @@ -622,6 +622,9 @@ tty_status_redraw(Widget w) XtGetValues(w, args, num_args); int height = nhFontHeight(w, NHW_STATUS); + /* Space between fields. For now, this is equal to one half the height. */ + int spacing = height/2; + int x = 0; int y = 0; XClearWindow(XtDisplay(w), XtWindow(w)); @@ -632,7 +635,7 @@ tty_status_redraw(Widget w) if (fld == BL_FLUSH) { break; } - int wid = tty_render_field(w, x, y, fld); + int wid = tty_render_field(w, x, y, spacing, fld); if (fld == BL_TITLE) { name_x = x; name_y = y; @@ -650,7 +653,7 @@ tty_status_redraw(Widget w) if (fld == BL_FLUSH) { break; } - int wid = tty_render_field(w, x, y, fld); + int wid = tty_render_field(w, x, y, spacing, fld); if (fld == BL_TITLE) { name_x = x; name_y = y; @@ -688,7 +691,7 @@ tty_status_redraw(Widget w) /* Render one field of the TTY status */ static int -tty_render_field(Widget w, int x, int y, enum statusfields fld) +tty_render_field(Widget w, int x, int y, int spacing, enum statusfields fld) { static struct stat_fmt { const char *pre; @@ -733,7 +736,7 @@ tty_render_field(Widget w, int x, int y, enum statusfields fld) for (unsigned j = 0; j < SIZE(X11_cond_labels); ++j) { struct tty_cond_field const *fldp = &X11_cond_labels[j]; if (fldp->text != NULL) { - width += tty_render_text(w, NULL, x + width, y, " ", NO_COLOR, 0, BL_FLUSH); + width += spacing; width += tty_render_text(w, NULL, x + width, y, fldp->text, fldp->color, fldp->attrs, BL_FLUSH); } } @@ -744,7 +747,7 @@ tty_render_field(Widget w, int x, int y, enum statusfields fld) struct tty_status_field const *fldp = &X11_status_labels[fld]; if (fldp->text != NULL && fldp->text[0] != '\0') { if (x != 0 && (formats[fld].pre == NULL || strchr("(/", formats[fld].pre[0]) == NULL)) { - width += tty_render_text(w, NULL, x + width, y, " ", NO_COLOR, 0, BL_FLUSH); + width += spacing; } if (formats[fld].pre != NULL) { width += tty_render_text(w, NULL, x + width, y, formats[fld].pre, NO_COLOR, 0, BL_FLUSH); From 9179d5d960a77e168ee806d79a40d7fa12112fb7 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Mon, 17 Aug 2026 17:39:34 -0400 Subject: [PATCH 642/702] Adjustments for MacOS compile per comments by Michael Allison --- sys/unix/NewInstall.unx | 3 +++ sys/unix/hints/macOS.500 | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/sys/unix/NewInstall.unx b/sys/unix/NewInstall.unx index 9ced987c1..538b18497 100644 --- a/sys/unix/NewInstall.unx +++ b/sys/unix/NewInstall.unx @@ -98,6 +98,9 @@ additional interfaces. See below. | | | | | | | | | One possible way: | | | | | brew install xquartz | +| | | | brew install libxft | +| | | | brew install fontconfig | +| | | | brew install freetype | |----------+-------+-----------------+--------------------------------------| | MacOS | Qt | WANT_WIN_QT | You will need to obtain and | | | | | install Qt if you want Qt | diff --git a/sys/unix/hints/macOS.500 b/sys/unix/hints/macOS.500 index 06646dab0..97d82388a 100755 --- a/sys/unix/hints/macOS.500 +++ b/sys/unix/hints/macOS.500 @@ -290,8 +290,8 @@ X11CFLAGS = -I/opt/X11/include X11CFLAGS += -Wno-variadic-macros ifdef USE_XFT CFLAGS += -DUSE_XFT -X11CFLAGS += $(shell pkg-config --cflags xft fontconfig) -WINX11LIB += $(shell pkg-config --libs xft fontconfig) +X11CFLAGS += $(shell pkg-config --cflags xft fontconfig freetype2) +WINX11LIB += $(shell pkg-config --libs xft fontconfig freetype2) endif ifdef USE_XPM CFLAGS += -DUSE_XPM From 392142d3222327cc5165d3acfb5398775b371955 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Tue, 18 Aug 2026 09:47:29 -0400 Subject: [PATCH 643/702] For menu items, set up pixmap and then manage The widget is created with a label but not a pixmap, and then a pixmap is set up for display. If the label is already realized and managed, it will not resize when the pixmap is set up. This causes problems when the inventory window is updated: unlike other menus, the parent Form widget is already realized. The fix is to create the item widget in an unmanaged state (XtCreateWidget), set up the pixmap (X11_wrap_widget and X11_set_attrs), and then manage it (XtManageChild). --- win/X11/winmenu.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index 0addf7c39..4604b78a0 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -1366,13 +1366,17 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu) menulineidx++; Sprintf(tmpbuf, "menuline_%s", (canpick) ? "command" : "label"); - curr->w = linewidget = XtCreateManagedWidget(tmpbuf, - canpick - ? commandWidgetClass - : labelWidgetClass, - wp->w, args, num_args); + /* Need to create the widget unmanaged, set up the pixmap, and then + manage it, or else items in the inventory window get the wrong + size */ + curr->w = linewidget = XtCreateWidget(tmpbuf, + canpick + ? commandWidgetClass + : labelWidgetClass, + wp->w, args, num_args); X11_wrap_widget(curr->w, NHW_MENU); X11_set_attrs(curr->w, 0x1 << attr); + XtManageChild(curr->w); if (canpick) XtAddCallback(linewidget, XtNcallback, menu_select, From b8dc070d075b096ed93ca096ec87bf6f20e3e571 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Tue, 18 Aug 2026 09:51:33 -0400 Subject: [PATCH 644/702] Fix right side of border rectangle --- win/X11/winlabel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/X11/winlabel.c b/win/X11/winlabel.c index 2c76c8f38..e7a673a7a 100644 --- a/win/X11/winlabel.c +++ b/win/X11/winlabel.c @@ -418,7 +418,7 @@ update_label(Widget w, WidgetData *data) XftDrawRect(draw, &fgcolor, 0, 0, width, 1); XftDrawRect(draw, &fgcolor, 0, height-1, width, 1); XftDrawRect(draw, &fgcolor, 0, 0, 1, height); - XftDrawRect(draw, &fgcolor, 0, height-1, 1, height); + XftDrawRect(draw, &fgcolor, width-1, 0, 1, height); #else XDrawRectangle(display, new_pixmap, ggc, 0, 0, width-1, height-1); #endif From 6dc9ac1c314feb1ce86384048607150c50345dde Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Tue, 18 Aug 2026 13:14:23 -0400 Subject: [PATCH 645/702] Adjust font hights so underscores are not cut off --- include/winX.h | 4 ++++ win/X11/winX.c | 2 +- win/X11/winlabel.c | 14 ++++---------- win/X11/winmap.c | 4 ++-- win/X11/winmesg.c | 2 +- win/X11/winstat.c | 5 +++-- 6 files changed, 15 insertions(+), 16 deletions(-) diff --git a/include/winX.h b/include/winX.h index dc34bd572..1c1521074 100644 --- a/include/winX.h +++ b/include/winX.h @@ -11,6 +11,9 @@ #ifdef USE_XFT #include +typedef XftFont X11_Font; +#else +typedef XFontStruct X11_Font; #endif #ifndef COLOR_H @@ -529,6 +532,7 @@ extern void X11_set_attrs(Widget, unsigned); extern void X11_set_highlight(Widget, boolean); extern void X11_set_percent(Widget, unsigned, Pixel); extern void X11_blink_labels(void); +extern int X11_font_height(X11_Font *); /* * These are for widgets that use the enhanced label services only for text diff --git a/win/X11/winX.c b/win/X11/winX.c index c59ab5fab..0f63a5761 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -794,7 +794,7 @@ nhFontHeight(Widget w, int win_type) #ifdef USE_XFT XftFont *font = X11_new_font(w, 0, win_type); - Dimension height = font->height; + Dimension height = X11_font_height(font); X11_release_font(w, font); return height; diff --git a/win/X11/winlabel.c b/win/X11/winlabel.c index e7a673a7a..662644f13 100644 --- a/win/X11/winlabel.c +++ b/win/X11/winlabel.c @@ -19,13 +19,7 @@ #include "winX.h" /* Declarations depending on Xft support or none */ -#ifdef USE_XFT -typedef XftFont X11_Font; -#else -typedef XFontStruct X11_Font; -#endif static int X11_text_width(Display *, X11_Font *, const char *, size_t); -static int X11_font_height(X11_Font *); /* Data attached to a wrapped widget */ typedef struct WidgetData { @@ -383,7 +377,7 @@ update_label(Widget w, WidgetData *data) /* Render the line */ #ifdef USE_XFT - XftDrawRect(draw, &bgcolor, x, y - font->ascent, lwidth, font->height); + XftDrawRect(draw, &bgcolor, x, y - font->ascent, lwidth, X11_font_height(font)); XftDrawString8(draw, &fgcolor, font, x, y, (const FcChar8 *) (label + i), line2); #else @@ -507,10 +501,10 @@ X11_text_width(Display *display, X11_Font *font, const char *text, size_t length return extents.width - extents.x; } -static int +int X11_font_height(X11_Font *font) { - return font->height; + return max(font->height, font->ascent + font->descent); } #else /* !USE_XFT */ static int @@ -520,7 +514,7 @@ X11_text_width(Display *display, X11_Font *font, const char *text, size_t length return XTextWidth(font, text, length); } -static int +int X11_font_height(X11_Font *font) { return font->ascent + font->descent; diff --git a/win/X11/winmap.c b/win/X11/winmap.c index a09691957..6e92eda63 100644 --- a/win/X11/winmap.c +++ b/win/X11/winmap.c @@ -1048,7 +1048,7 @@ get_char_info(struct xwindow *wp) struct text_map_info_t *text_map = &map_info->text_map; XftFont *font = X11_new_font(wp->w, 0, NHW_MAP); text_map->square_width = font->max_advance_width; - text_map->square_height = font->height; + text_map->square_height = X11_font_height(font); text_map->square_ascent = 0; text_map->square_lbearing = 0; X11_release_font(wp->w, font); @@ -1546,7 +1546,7 @@ X11_draw_image_string( { XftDrawRect(draw, bgcolor, x, y, length * font->max_advance_width, - font->height); + X11_font_height(font)); int xt = x; int yt = y + font->ascent; diff --git a/win/X11/winmesg.c b/win/X11/winmesg.c index aa707a186..ed172c4f8 100644 --- a/win/X11/winmesg.c +++ b/win/X11/winmesg.c @@ -158,7 +158,7 @@ create_message_window(struct xwindow *wp, /* window pointer */ XftFont *font = X11_new_font(wp->w, 0, NHW_MESSAGE); XGlyphInfo extents; mesg_info->char_width = font->max_advance_width; - mesg_info->char_height = font->height; + mesg_info->char_height = X11_font_height(font); mesg_info->char_ascent = font->ascent; mesg_info->char_lbearing = 0; /* Xft seems to offer no direct way to distinguish proportional from diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 2fa32ae6b..5224522b3 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -785,6 +785,7 @@ tty_render_text(Widget w, const XRectangle *clip, int x, int y, /* Get the font */ XftFont *font = X11_new_font(w, attr, NHW_STATUS); + int height = X11_font_height(font); /* Get the drawing resources */ Display *display = XtDisplay(w); @@ -827,7 +828,7 @@ tty_render_text(Widget w, const XRectangle *clip, int x, int y, goldwidth = extents.width - extents.x; /* Render the gold symbol */ - XftDrawRect(draw, &bgcolor, x, y, goldwidth, font->height); + XftDrawRect(draw, &bgcolor, x, y, goldwidth, height); #ifdef ENHANCED_SYMBOLS XftDrawString32(draw, &fgcolor, font, x, y + font->ascent, &goldch, 1); #else /* !ENHANCED_SYMBOLS */ @@ -857,7 +858,7 @@ tty_render_text(Widget w, const XRectangle *clip, int x, int y, } /* Render the string */ - XftDrawRect(draw, &bgcolor, x + goldwidth, y, width, font->height); + XftDrawRect(draw, &bgcolor, x + goldwidth, y, width, height); XftDrawString8(draw, &fgcolor, font, x + goldwidth, y + font->ascent, (const FcChar8 *) text, strlen(text)); From 94336e6b63e6cf0ac9a4dd88dab94dc5f8b0bf1a Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 19 Aug 2026 09:47:11 +0300 Subject: [PATCH 646/702] fixes update --- doc/fixes5-0-1.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 8a827c5d2..a174242ba 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -260,6 +260,7 @@ X11: toggle off perm_invent if user closes the perm inventory window X11: fix menu group accelerators X11: implement all text attributes for menus X11: fix crash when loading a nonexistent font +X11: use xft to render fonts Unix: don't complain about MAXPLAYERS with unknown command line param From f61709ab36f47d05636ce08eb1100efb07f3ad15 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 19 Aug 2026 06:07:11 -0400 Subject: [PATCH 647/702] update CI Linux versions --- azure-pipelines.yml | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c2ac01944..b7434b90b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -4,18 +4,14 @@ strategy: imageName: 'ubuntu-latest' toolchainName: gcc14 buildTargetName: minimal - linux_noble_clang_all: - imageName: 'ubuntu-24.04' + linux_latest_gcc14: + imageName: 'ubuntu-latest' + toolchainName: gcc14 + buildTargetName: all + linux_latest_clang_all: + imageName: 'ubuntu-latest' toolchainName: clang buildTargetName: all - linux_jammy_gcc9_all: - imageName: 'ubuntu-22.04' - toolchainName: gcc9 - buildTargetName: all - linux_noble_gcc13_all: - imageName: 'ubuntu-24.04' - toolchainName: gcc13 - buildTargetName: all macOS_latest_clang_all: imageName: 'macOS-latest' toolchainName: clang @@ -41,8 +37,8 @@ strategy: imageName: 'ubuntu-latest' toolchainName: cross buildTargetName: msdos - linux_noble_docs: - imageName: 'ubuntu-24.04' + linux_latest_docs: + imageName: 'ubuntu-latest' toolchainName: docs buildTargetName: all continueOnError: true @@ -65,16 +61,6 @@ variables: steps: - bash: | - if [ "$(toolchain)" == "gcc9" ] - then - echo "##vso[task.setvariable variable=CC]gcc-9" - echo "##vso[task.setvariable variable=CXX]g++-9" - fi - if [ "$(toolchain)" == "gcc13" ] - then - echo "##vso[task.setvariable variable=CC]gcc-13" - echo "##vso[task.setvariable variable=CXX]g++-13" - fi if [ "$(toolchain)" == "gcc14" ] then echo "##vso[task.setvariable variable=CC]gcc-14" From dd94830c10fde0e2e273628ab5b5912f1b39742b Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 19 Aug 2026 06:39:36 -0400 Subject: [PATCH 648/702] CI: add libxft-dev --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b7434b90b..b88372b5f 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -158,7 +158,7 @@ steps: - bash: | sudo apt-get -qq -y update sudo apt-get -qq -y install libncurses-dev - sudo apt-get -qq -y install libx11-dev libxaw7-dev xfonts-utils qtbase5-dev qtmultimedia5-dev qtbase5-dev-tools + sudo apt-get -qq -y install libx11-dev libxaw7-dev libxft-dev xfonts-utils qtbase5-dev qtmultimedia5-dev qtbase5-dev-tools condition: and(eq( variables['Agent.OS'], 'Linux' ), eq( variables.buildTarget, 'all')) workingDirectory: $(Agent.BuildDirectory)/$(netHackPath) displayName: 'Getting linux build dependencies' From a2e805aee2a0e132633c89695c27b77beaf68039 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 19 Aug 2026 06:43:27 -0400 Subject: [PATCH 649/702] CI: fontconfig --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b88372b5f..3378224e7 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -158,7 +158,7 @@ steps: - bash: | sudo apt-get -qq -y update sudo apt-get -qq -y install libncurses-dev - sudo apt-get -qq -y install libx11-dev libxaw7-dev libxft-dev xfonts-utils qtbase5-dev qtmultimedia5-dev qtbase5-dev-tools + sudo apt-get -qq -y install libx11-dev libxaw7-dev libxft-dev fontconfig xfonts-utils qtbase5-dev qtmultimedia5-dev qtbase5-dev-tools condition: and(eq( variables['Agent.OS'], 'Linux' ), eq( variables.buildTarget, 'all')) workingDirectory: $(Agent.BuildDirectory)/$(netHackPath) displayName: 'Getting linux build dependencies' From 4c4867d586961dbc2611ce4a3e7839808be93c65 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 19 Aug 2026 07:16:57 -0400 Subject: [PATCH 650/702] map_mode may appear more than once without a gripe --- include/optlist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/optlist.h b/include/optlist.h index 516d93e19..efb26982e 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -430,7 +430,7 @@ static int optfn_##a(int, int, boolean, char *, char *); On, Yes, No, No, NoAlias, &flags.biff, Term_False, "enable the mail daemon") NHOPTC(map_mode, Advanced, 20, opt_in, set_gameview, - Yes, Yes, No, No, NoAlias, "map display mode under Windows") + Yes, Yes, Yes, No, NoAlias, "map display mode under Windows") NHOPTB(mention_decor, Advanced, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &flags.mention_decor, Term_False, "give feedback when walking over interesting features") From 6950543bb97a4c993e5b4e5ddb1910eef5ca367d Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 19 Aug 2026 07:36:21 -0400 Subject: [PATCH 651/702] build fix under MSYS2 ../src/pline.c: In function 'execplinehandler': ../src/pline.c:678:15: error: implicit declaration of function '_spawnv' [-Wimplicit-function-declaration] 678 | ret = _spawnv(_P_NOWAIT, sysopt.msghandler, args); | ^~~~~~~ ../src/pline.c:678:23: error: '_P_NOWAIT' undeclared (first use in this function); did you mean 'MM_NOWAIT'? 678 | ret = _spawnv(_P_NOWAIT, sysopt.msghandler, args); | ^~~~~~~~~ | MM_NOWAIT ../src/pline.c:678:23: note: each undeclared identifier is reported only once for each function it appears in make: *** [GNUmakefile:1376: o/nethack/pline.o] Error 1 --- include/windconf.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/windconf.h b/include/windconf.h index 2ba5b182e..792df39cf 100644 --- a/include/windconf.h +++ b/include/windconf.h @@ -108,6 +108,7 @@ extern char *windows_exepath(void); */ #ifdef __GNUC__ +#include #define MD_USE_TMPFILE_S # #ifdef strncasecmp From 540c0549d8cd818b72515db3dd81dd91ac76166d Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 19 Aug 2026 08:00:15 -0400 Subject: [PATCH 652/702] follow-up: MSYS2 build fix --- include/windconf.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/windconf.h b/include/windconf.h index 792df39cf..415bb31ef 100644 --- a/include/windconf.h +++ b/include/windconf.h @@ -108,7 +108,6 @@ extern char *windows_exepath(void); */ #ifdef __GNUC__ -#include #define MD_USE_TMPFILE_S # #ifdef strncasecmp @@ -164,7 +163,7 @@ typedef SSIZE_T ssize_t; #endif /* _MSC_VER */ /* The following is needed for prototypes of certain functions */ -#if defined(_MSC_VER) +#if defined(_MSC_VER) || defined(__GNUC__) #include /* Provides prototypes of exit(), spawn() */ #endif From c5181b9cb861f9f2e3b1afbd2782f61ca288a098 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Thu, 20 Aug 2026 07:25:36 -0400 Subject: [PATCH 653/702] Improve support for tabbed columns * Set the menu font to proportional * Do not consider the last column of a line when calculating maximum column widths * Use U+200A HAIR SPACE for finer column padding * Track errors in column padding and adjust subsequent columns so that these errors do not accumulate across a row --- win/Qt/qt_menu.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index f469597e2..f61833dcf 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -165,7 +165,7 @@ NetHackQtMenuWindow::NetHackQtMenuWindow(QWidget *parent) : { // setFont() was in SelectMenu(), in time to be rendered but too late // when measuring the width and height that will be needed - QFont tablefont(qt_settings->normalFixedFont()); + QFont tablefont(qt_settings->normalFont()); table->setFont(tablefont); QGridLayout *grid = new QGridLayout(); @@ -400,9 +400,8 @@ void NetHackQtMenuWindow::PadMenuColumns(bool split_descr) continue; // determine column widths of sub-fields within description QStringList columns = itemlist[row].str.split("\t"); - for (int fld = 0; fld < (int) columns.size(); ++fld) { - bool lastcol = (fld == (int) columns.size() - 1); - int w = fm.QFM_WIDTH(columns[fld] + (lastcol ? "" : " ")); + for (int fld = 0; fld < (int) columns.size() - 1; ++fld) { + int w = fm.QFM_WIDTH(columns[fld] + " "); if (fld >= (int) col_widths.size()) { col_widths.push_back(w); // add another element } else if (col_widths[fld] < w) { @@ -432,12 +431,21 @@ void NetHackQtMenuWindow::PadMenuColumns(bool split_descr) continue; QString text = twi->text(); if (split_descr) { + static const QChar u_200A(0x200A); // U+200A HAIR SPACE QStringList columns = text.split("\t"); + int spc0020_width = fm.QFM_WIDTH(" "); + int spc200A_width = fm.QFM_WIDTH(u_200A); + // Track errors in column widths and adjust subsequent columns so + // that these errors do not accumulate across a row + int error = 0; for (int fld = 0; fld < (int) columns.size() - 1; ++fld) { //columns[fld] += "\t"; /* (used to pad with tabs) */ int width = col_widths[fld]; - while (fm.QFM_WIDTH(columns[fld]) < width) + while (fm.QFM_WIDTH(columns[fld]) + error + spc0020_width <= width) columns[fld] += " "; //"\t"; + while (fm.QFM_WIDTH(columns[fld]) + error + spc200A_width/2 < width) + columns[fld] += u_200A; + error += fm.QFM_WIDTH(columns[fld]) - width; } text = columns.join(""); twi->setText(text); From b52ea09e25d01c37969ac4d03e5d7a27a9b77bb4 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Thu, 20 Aug 2026 07:28:01 -0400 Subject: [PATCH 654/702] Tabify the extended command list --- src/cmd.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/cmd.c b/src/cmd.c index cd77a6727..beeba8780 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -674,10 +674,15 @@ doextlist(void) add_menu_heading(menuwin, buf); menushown[pass] = 1; } - /* longest ef_txt at present is "wizrumorcheck" (13 chars); - 2nd field will be " " or " [A]" or " [m]" or "[mA]" */ - Sprintf(buf, " %-14s %4s %s", efp->ef_txt, - doc_extcmd_flagstr(menuwin, efp), cmd_desc); + if (iflags.menu_tab_sep) { + Sprintf(buf, " %s\t%s\t%s", efp->ef_txt, + doc_extcmd_flagstr(menuwin, efp), cmd_desc); + } else { + /* longest ef_txt at present is "wizrumorcheck" (13 chars); + 2nd field will be " " or " [A]" or " [m]" or "[mA]" */ + Sprintf(buf, " %-14s %4s %s", efp->ef_txt, + doc_extcmd_flagstr(menuwin, efp), cmd_desc); + } add_menu_str(menuwin, buf); ++n; } From b08c4f92b266e142024b92c053d297c80b160e87 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Thu, 20 Aug 2026 08:14:13 -0400 Subject: [PATCH 655/702] Tabify more menus * Status hilites * Disclose option * Symbol set selection --- src/botl.c | 8 ++++++-- src/options.c | 9 +++++++-- src/symbols.c | 13 ++++++------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/botl.c b/src/botl.c index 4447cbb5e..301dc2b4c 100644 --- a/src/botl.c +++ b/src/botl.c @@ -4539,9 +4539,13 @@ status_hilite_menu(void) #endif any = cg.zeroany; any.a_int = fld + 1; - Sprintf(buf, "%-18s", initblstats[i].fldname); + if (iflags.menu_tab_sep) { + Sprintf(buf, "%s\t", initblstats[i].fldname); + } else { + Sprintf(buf, "%-18s ", initblstats[i].fldname); + } if (count) - Sprintf(eos(buf), " (%d defined)", count); + Sprintf(eos(buf), "(%d defined)", count); add_menu(tmpwin, &nul_glyphinfo, &any, 0, 0, ATR_NONE, clr, buf, MENU_ITEMFLAGS_NONE); } diff --git a/src/options.c b/src/options.c index 351c3903d..aa555bad1 100644 --- a/src/options.c +++ b/src/options.c @@ -5703,8 +5703,13 @@ handler_disclose(void) start_menu(tmpwin, MENU_BEHAVE_STANDARD); any = cg.zeroany; for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++) { - Sprintf(buf, "%-12s[%c%c]", disclosure_names[i], - flags.end_disclose[i], disclosure_options[i]); + if (iflags.menu_tab_sep) { + Sprintf(buf, "%s\t[%c%c]", disclosure_names[i], + flags.end_disclose[i], disclosure_options[i]); + } else { + Sprintf(buf, "%-12s[%c%c]", disclosure_names[i], + flags.end_disclose[i], disclosure_options[i]); + } any.a_int = i + 1; add_menu(tmpwin, &nul_glyphinfo, &any, disclosure_options[i], 0, ATR_NONE, clr, buf, MENU_ITEMFLAGS_NONE); diff --git a/src/symbols.c b/src/symbols.c index bd9596a1c..99382b721 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -979,8 +979,6 @@ symparse_find(const void *bstr_, const void *rec_) return 0; } -DISABLE_WARNING_FORMAT_NONLITERAL - /* * this is called from options.c to do the symset work. */ @@ -994,7 +992,7 @@ do_symset(boolean rogueflag) menu_item *symset_pick = (menu_item *) 0; boolean ready_to_switch = FALSE, nothing_to_do = FALSE; - char *symset_name, fmtstr[20]; + char *symset_name; struct symsetentry *sl; int res, which_set, setcount = 0, chosen = -2, defindx = 0; int clr = NO_COLOR; @@ -1041,7 +1039,6 @@ do_symset(boolean rogueflag) return TRUE; } - Sprintf(fmtstr, "%%-%ds %%s", biggest + 2); tmpwin = create_nhwindow(NHW_MENU); start_menu(tmpwin, MENU_BEHAVE_STANDARD); any = cg.zeroany; @@ -1072,7 +1069,11 @@ do_symset(boolean rogueflag) any.a_int = sl->idx + 2; if (symset_name && !strcmpi(sl->name, symset_name)) defindx = any.a_int; - Sprintf(buf, fmtstr, sl->name, sl->desc ? sl->desc : ""); + if (iflags.menu_tab_sep) { + Sprintf(buf, "%s\t%s", sl->name, sl->desc ? sl->desc : ""); + } else { + Sprintf(buf, "%-*s %s", biggest + 2, sl->name, sl->desc ? sl->desc : ""); + } add_menu(tmpwin, &nul_glyphinfo, &any, 0, 0, ATR_NONE, clr, buf, (any.a_int == defindx) ? MENU_ITEMFLAGS_SELECTED @@ -1177,6 +1178,4 @@ do_symset(boolean rogueflag) return TRUE; } -RESTORE_WARNING_FORMAT_NONLITERAL - /*symbols.c*/ From c99b485c78551773d46bee3d96d367e699438de0 Mon Sep 17 00:00:00 2001 From: 0xb1aded Date: Fri, 21 Aug 2026 19:54:05 +0800 Subject: [PATCH 656/702] fix: init color256 value to prevent color flickering --- win/curses/curswins.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/win/curses/curswins.c b/win/curses/curswins.c index 1044cd61b..92ef4baa9 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -883,21 +883,25 @@ curses_draw_map(int sx, int sy, int ex, int ey) #ifdef MAP_SCROLLBARS hsb_back.ch = '-'; hsb_back.color = SCROLLBAR_BACK_COLOR; + hsb_back.color256 = 0; hsb_back.framecolor = NO_COLOR; hsb_back.attr = A_NORMAL; hsb_back.unicode_representation = NULL; hsb_bar.ch = '*'; hsb_bar.color = SCROLLBAR_COLOR; + hsb_bar.color256 = 0; hsb_bar.framecolor = NO_COLOR; hsb_bar.attr = A_NORMAL; hsb_bar.unicode_representation = NULL; vsb_back.ch = '|'; vsb_back.color = SCROLLBAR_BACK_COLOR; + vsb_back.color256 = 0; vsb_back.framecolor = NO_COLOR; vsb_back.attr = A_NORMAL; vsb_back.unicode_representation = NULL; vsb_bar.ch = '*'; vsb_bar.color = SCROLLBAR_COLOR; + vsb_bar.color256 = 0; vsb_bar.framecolor = NO_COLOR; vsb_bar.attr = A_NORMAL; vsb_bar.unicode_representation = NULL; @@ -965,6 +969,8 @@ clear_map(void) for (y = 0; y < ROWNO; y++) { map[y][x].ch = ' '; map[y][x].color = NO_COLOR; + map[y][x].color256 = 0; + map[y][x].framecolor = NO_COLOR; map[y][x].attr = A_NORMAL; map[y][x].unicode_representation = NULL; } From 94834df5d1bc5a6d956d719dfdaf6c248f06ff7e Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Fri, 21 Aug 2026 08:19:04 -0400 Subject: [PATCH 657/702] Revise the column width calculation The last column in a line continues to the end of the line, and may overhang any subsequent columns in other lines. --- win/win32/mhmenu.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/win/win32/mhmenu.c b/win/win32/mhmenu.c index 7579976a6..47204025f 100644 --- a/win/win32/mhmenu.c +++ b/win/win32/mhmenu.c @@ -684,11 +684,16 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) DrawText(hDC, NH_A2W(p1, wbuf, BUFSZ), strlen(p1), &drawRect, DT_CALCRECT | DT_LEFT | DT_VCENTER | DT_EXPANDTABS | DT_SINGLELINE); - data->menui.menu.tab_stop_size[column] = - max(data->menui.menu.tab_stop_size[column], - drawRect.right - drawRect.left); - - menuitemwidth += data->menui.menu.tab_stop_size[column]; + int width = drawRect.right - drawRect.left; + /* The last column overhangs any subsequent columns in other + lines */ + if (p != NULL) { + data->menui.menu.tab_stop_size[column] = + max(data->menui.menu.tab_stop_size[column], width); + menuitemwidth += data->menui.menu.tab_stop_size[column]; + } else { + menuitemwidth += width; + } if (p != NULL) *p = '\t'; @@ -1182,7 +1187,8 @@ onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam) p = strchr(item->str, '\t'); column = 0; SetRect(&drawRect, x, lpdis->rcItem.top, - min(x + data->menui.menu.tab_stop_size[0], lpdis->rcItem.right), + p != NULL ? x + data->menui.menu.tab_stop_size[0] + : lpdis->rcItem.right, lpdis->rcItem.bottom); for (;;) { TCHAR wbuf2[BUFSZ]; @@ -1199,8 +1205,8 @@ onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam) p = strchr(p1, '\t'); drawRect.left = drawRect.right + TAB_SEPARATION; ++column; - drawRect.right = min(drawRect.left + data->menui.menu.tab_stop_size[column], - lpdis->rcItem.right); + drawRect.right = p != NULL ? drawRect.left + data->menui.menu.tab_stop_size[column] + : lpdis->rcItem.right; } /* draw focused item */ From 44b04064be9fcf0658d248ab13314f5b0dd5c688 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 21 Aug 2026 09:36:17 -0400 Subject: [PATCH 658/702] static analyzer: use of uninitialized value 'origarg' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ../sys/unix/unixmain.c: In function ‘process_options’: ../sys/unix/unixmain.c:458:9: warning: use of uninitialized value ‘origarg’ [CWE-457] [-Wanalyzer-use-of-uninitialized-value] 458 | config_error_add("Unknown option: %.60s", origarg); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- sys/unix/unixmain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index c712b08e6..7a0354d17 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -328,7 +328,7 @@ main(int argc, char *argv[]) static void process_options(int argc, char *argv[]) { - char *arg, *origarg; + char *arg, *origarg = 0; int i, l; config_error_init(FALSE, "command line", FALSE); @@ -454,7 +454,7 @@ process_options(int argc, char *argv[]) } } - if (argc > 1) + if (argc > 1 && origarg) config_error_add("Unknown option: %.60s", origarg); #ifdef MAX_NR_OF_PLAYERS /* limit to compile-time limit */ From ae8b4bf12a464a3dbbbf611116620ecb96a01ee2 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Wed, 19 Aug 2026 15:58:33 -0400 Subject: [PATCH 659/702] Add support for tabbed menu columns --- include/winX.h | 2 + win/X11/NetHack.ad | 2 +- win/X11/winX.c | 5 ++- win/X11/winlabel.c | 105 +++++++++++++++++++++++++++++++++++++++------ win/X11/winmenu.c | 78 ++++++++++++++++++++++++++++++++- 5 files changed, 177 insertions(+), 15 deletions(-) diff --git a/include/winX.h b/include/winX.h index 1c1521074..88d61df9a 100644 --- a/include/winX.h +++ b/include/winX.h @@ -531,8 +531,10 @@ extern void X11_update_label(Widget); extern void X11_set_attrs(Widget, unsigned); extern void X11_set_highlight(Widget, boolean); extern void X11_set_percent(Widget, unsigned, Pixel); +extern void X11_set_column_widths(Widget, const int *, unsigned); extern void X11_blink_labels(void); extern int X11_font_height(X11_Font *); +extern int X11_column_width(Display *, X11_Font *, const char *, size_t); /* * These are for widgets that use the enhanced label services only for text diff --git a/win/X11/NetHack.ad b/win/X11/NetHack.ad index f12110f6f..10f1e7a73 100644 --- a/win/X11/NetHack.ad +++ b/win/X11/NetHack.ad @@ -31,7 +31,7 @@ NetHack*text*borderWidth: 0 ! These correspond to the .nethackrc settings font_map, font_menu, ! font_message, font_status and font_text NetHack.font_map: mono-10 -NetHack.font_menu: mono-10 +NetHack.font_menu: sans-10 NetHack.font_message: sans-10 NetHack.font_status: sans-10 NetHack.font_text: mono-10 diff --git a/win/X11/winX.c b/win/X11/winX.c index 0f63a5761..ace3f1124 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -1571,7 +1571,7 @@ static XtResource resources[] = { { nhStr("font_map"), nhStr("Font_map"), XtRString, sizeof(String), XtOffset(AppResources *, font_map), XtRString, nhStr("mono-10") }, { nhStr("font_menu"), nhStr("Font_menu"), XtRString, sizeof(String), - XtOffset(AppResources *, font_menu), XtRString, nhStr("mono-10") }, + XtOffset(AppResources *, font_menu), XtRString, nhStr("sans-10") }, { nhStr("font_message"), nhStr("Font_message"), XtRString, sizeof(String), XtOffset(AppResources *, font_message), XtRString, nhStr("sans-10") }, { nhStr("font_status"), nhStr("Font_status"), XtRString, sizeof(String), @@ -1646,6 +1646,9 @@ X11_init_nhwindows(int *argcp, char **argv) Arg args[4]; uid_t savuid; + /* Request tabbed menu columns */ + iflags.menu_tab_sep = TRUE; + /* Init windows to nothing. */ for (i = 0; i < MAX_WINDOWS; i++) window_list[i].type = NHW_NONE; diff --git a/win/X11/winlabel.c b/win/X11/winlabel.c index 662644f13..e045f2007 100644 --- a/win/X11/winlabel.c +++ b/win/X11/winlabel.c @@ -19,7 +19,8 @@ #include "winX.h" /* Declarations depending on Xft support or none */ -static int X11_text_width(Display *, X11_Font *, const char *, size_t); +static int X11_text_width(Display *, X11_Font *, const char *, size_t, + const int *, unsigned); /* Data attached to a wrapped widget */ typedef struct WidgetData { @@ -41,6 +42,10 @@ typedef struct WidgetData { /* Percentage bar */ unsigned percent; Pixel bar_color; + + /* Columns */ + int *columns; + unsigned num_cols; } WidgetData; /* Bits for WidgetData::font */ @@ -119,6 +124,7 @@ delete_callback(Widget w, XtPointer client_data, XtPointer call_data) XFreePixmap(display, data->pixmap); } free_fonts(w, data); + free(data->columns); free(data); } @@ -173,6 +179,25 @@ X11_set_percent(Widget w, unsigned percent, Pixel color) } } +void +X11_set_column_widths(Widget w, const int *col_widths, unsigned num_cols) +{ + WidgetData *data = get_widget_data(w); + if (data != NULL) { + int col_spacing = X11_font_height(data->font[0]) * 2; + free(data->columns); + data->columns = (int *) alloc(sizeof(data->columns[0]) * num_cols); + if (num_cols != 0) { + data->columns[0] = 0; + for (unsigned i = 1; i < num_cols; ++i) { + data->columns[i] = data->columns[i-1] + col_spacing + col_widths[i-1]; + } + } + data->num_cols = num_cols; + update_label(w, data); + } +} + /* Update the label's pixmap */ /* This is called from functions that have altered the data block, and already have a pointer to it */ @@ -235,7 +260,8 @@ update_label(Widget w, WidgetData *data) } /* Get the width of the line */ - int lwidth = X11_text_width(display, font, label + i, line2); + int lwidth = X11_text_width(display, font, label + i, line2, + data->columns, data->num_cols); /* Update pixmap dimensions */ width = max(lwidth, width); @@ -301,6 +327,7 @@ update_label(Widget w, WidgetData *data) if ((attrs & HL_BLINK) && X11_blink) { values.foreground = values.background; } + #ifdef USE_XFT Visual *visual = DefaultVisualOfScreen(screen); Colormap cmap = DefaultColormapOfScreen(screen); @@ -357,7 +384,8 @@ update_label(Widget w, WidgetData *data) } /* Get the width of the line */ - int lwidth = X11_text_width(display, font, label + i, line2); + int lwidth = X11_text_width(display, font, label + i, line2, + data->columns, data->num_cols); /* Place the line horizontally */ int x = 0; @@ -378,13 +406,38 @@ update_label(Widget w, WidgetData *data) /* Render the line */ #ifdef USE_XFT XftDrawRect(draw, &bgcolor, x, y - font->ascent, lwidth, X11_font_height(font)); - XftDrawString8(draw, &fgcolor, font, x, y, - (const FcChar8 *) (label + i), line2); #else - XDrawImageString(display, new_pixmap, ggc, - x, y, - label + i, line2); + XSetForeground(display, ggc, values.background); + XFillRectangle(display, new_pixmap, ggc, x, y - font->ascent, lwidth, X11_font_height(font)); + XSetForeground(display, ggc, values.foreground); #endif + size_t j = 0; + unsigned col = 0; + while (j < line2) { + size_t line3; + int pos; + if (data->num_cols == 0) { + /* Columns not set */ + line3 = line2; + pos = 0; + } else { + line3 = min(strcspn(label + i + j, "\t\n"), line2); + pos = data->columns[min(col, data->num_cols-1)]; + } +#ifdef USE_XFT + XftDrawString8(draw, &fgcolor, font, x + pos, y, + (const FcChar8 *) (label + i + j), line3); +#else + XDrawString(display, new_pixmap, ggc, + x + pos, y, + label + i + j, line3); +#endif + j += line3; + if (j < line2) { + ++j; + } + ++col; + } /* Draw the underline if requested */ if (attrs & HL_ULINE) { @@ -488,13 +541,41 @@ free_fonts(Widget w, WidgetData *data) } } +static int +X11_text_width(Display *display, X11_Font *font, const char *text, size_t length, + const int *columns, unsigned num_cols) +{ + if (num_cols == 0) { + /* Columns have not been set */ + return X11_column_width(display, font, text, length); + } + + /* Width is the position of the last column, plus the width of the string + in the last column */ + + unsigned col = 0; + size_t i = 0; + while (col < num_cols) { + size_t len = strcspn(text + i, "\t\n"); + if (i+len >= length || text[i+len] != '\t') { + break; + } + ++col; + i += len + 1; + } + + int pos = columns[col] + X11_column_width(display, font, text + i, length - i); + + return pos; +} + ////////////////////////////////////////////////////////////////////////////// // Functions that depend on the font rendering API // ////////////////////////////////////////////////////////////////////////////// #ifdef USE_XFT -static int -X11_text_width(Display *display, X11_Font *font, const char *text, size_t length) +int +X11_column_width(Display *display, X11_Font *font, const char *text, size_t length) { XGlyphInfo extents; XftTextExtents8(display, font, (const FcChar8*) text, length, &extents); @@ -507,8 +588,8 @@ X11_font_height(X11_Font *font) return max(font->height, font->ascent + font->descent); } #else /* !USE_XFT */ -static int -X11_text_width(Display *display, X11_Font *font, const char *text, size_t length) +int +X11_column_width(Display *display, X11_Font *font, const char *text, size_t length) { nhUse(display); return XTextWidth(font, text, length); diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index 4604b78a0..371124a62 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -60,6 +60,7 @@ static unsigned menu_scrollmask(struct xwindow *); static void menu_unscroll(struct xwindow *); static Widget menu_create_buttons(struct xwindow *, Widget, Widget); static void menu_create_entries(struct xwindow *, struct menu *); +static unsigned get_col_widths(Widget, X11_Font *, const char *, int **); static void destroy_menu_entry_widgets(struct xwindow *); static void create_menu_translation_tables(void); @@ -1317,6 +1318,13 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu) Cardinal num_args; Dimension cwidth, maxwidth = 0; + int *col_widths = NULL; + unsigned num_cols = 0; + X11_Font *font; +#ifdef USE_XFT + font = X11_new_font(wp->w, 0, NHW_MENU); +#endif + for (curr = curr_menu->base; curr; curr = curr->next) { char tmpbuf[BUFSZ]; Widget linewidget; @@ -1376,13 +1384,42 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu) wp->w, args, num_args); X11_wrap_widget(curr->w, NHW_MENU); X11_set_attrs(curr->w, 0x1 << attr); - XtManageChild(curr->w); if (canpick) XtAddCallback(linewidget, XtNcallback, menu_select, (XtPointer) curr); prevlinewidget = linewidget; +#ifndef USE_XFT /* If Xft, the font is acquired at the start of the loop */ + num_args = 0; + XtSetArg(args[num_args], XtNfont, &font); num_args++; + XtGetValues(curr->w, args, num_args); +#endif + /* Get column widths for this line */ + if (strchr(str, '\t') != NULL) { /* Might be a header if no tab */ + int *col_widths0; + unsigned num_cols0 = get_col_widths(curr->w, font, str, &col_widths0); + if (num_cols0 > num_cols) { + col_widths = (int *) re_alloc((long *) col_widths, num_cols0 * sizeof(col_widths[0])); + memset(col_widths + num_cols, 0, sizeof(col_widths[0]) * (num_cols0 - num_cols)); + num_cols = num_cols0; + } + for (unsigned i = 0; i < num_cols0; ++i) { + col_widths[i] = max(col_widths[i], col_widths0[i]); + } + free(col_widths0); + } + } +#ifdef USE_XFT + X11_release_font(wp->w, font); +#endif + + /* Set the column widths */ + for (curr = curr_menu->base; curr; curr = curr->next) { + X11_set_column_widths(curr->w, col_widths, num_cols); + XtManageChild(curr->w); + + boolean canpick = (how != PICK_NONE && curr->identifier.a_void); if (canpick) { /* get the current line width */ XtSetArg(args[0], XtNwidth, &cwidth); @@ -1392,6 +1429,8 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu) } } + free(col_widths); + /* set all selectable menu entries to the maximum width */ if (how != PICK_NONE) { XtSetArg(args[0], XtNwidth, maxwidth); @@ -1401,6 +1440,43 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu) } } +/* Determine widths of columns */ +static unsigned +get_col_widths(Widget w, X11_Font *font, const char *str, int **col_widths) +{ + /* Determine the number of columns */ + unsigned num_cols = 1; + size_t i = 0; + while (str[i] != '\0') { + size_t len = strcspn(str + i, "\t"); + if (str[i+len] == '\0') { + break; + } + ++num_cols; + i += len + 1; + } + + /* Allocate width array */ + int *cwidths = (int *) alloc(sizeof(cwidths[0]) * num_cols); + memset(cwidths, 0, sizeof(cwidths[0]) * num_cols); + + /* Get the widths of the columns */ + unsigned col = 0; + i = 0; + while (str[i] != '\0') { + size_t len = strcspn(str + i, "\t"); + cwidths[col++] = X11_column_width(XtDisplay(w), font, str + i, len); + i += len; + if (str[i] == '\t') { + ++i; + } + } + + /* Return */ + *col_widths = cwidths; + return num_cols; +} + static void destroy_menu_entry_widgets(struct xwindow *wp) { From bc14bd7f30e8973ab30e16a52bc483e0e19c3586 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Wed, 19 Aug 2026 17:48:09 -0400 Subject: [PATCH 660/702] Adjust extra menu width --- win/X11/winmenu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index 371124a62..e34c2b885 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -1084,8 +1084,8 @@ X11_select_menu(winid window, int how, menu_item **menu_list) XtSetArg(args[num_args], XtNheight, &v_pixel_height); num_args++; XtGetValues(wp->w, args, num_args); if ((Dimension) XtScreen(wp->w)->height * 5 / 6 < v_pixel_height) { - /* scrollbar is 14 pixels wide. Widen the form to accommodate it. */ - v_pixel_width += 14; + /* scrollbar is 17 pixels wide. Widen the form to accommodate it. */ + v_pixel_width += 17; /* shrink to fit vertically */ v_pixel_height = XtScreen(wp->w)->height * 5 / 6; From ffb08d3be62946ddb42cabfb828ab382d80c63d5 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Wed, 19 Aug 2026 18:19:04 -0400 Subject: [PATCH 661/702] Don't set columns for rows without tabs --- win/X11/winmenu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index e34c2b885..f51a740a9 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -1416,7 +1416,9 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu) /* Set the column widths */ for (curr = curr_menu->base; curr; curr = curr->next) { - X11_set_column_widths(curr->w, col_widths, num_cols); + if (strchr(curr->str, '\t') != NULL) { /* Might be a header if no tab */ + X11_set_column_widths(curr->w, col_widths, num_cols); + } XtManageChild(curr->w); boolean canpick = (how != PICK_NONE && curr->identifier.a_void); From 84bf23640c407b4bb0900cc596ba1eb7c72fdafb Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Wed, 19 Aug 2026 19:56:41 -0400 Subject: [PATCH 662/702] Line up selectable items --- win/X11/winlabel.c | 3 +-- win/X11/winmenu.c | 39 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/win/X11/winlabel.c b/win/X11/winlabel.c index e045f2007..075346dde 100644 --- a/win/X11/winlabel.c +++ b/win/X11/winlabel.c @@ -184,13 +184,12 @@ X11_set_column_widths(Widget w, const int *col_widths, unsigned num_cols) { WidgetData *data = get_widget_data(w); if (data != NULL) { - int col_spacing = X11_font_height(data->font[0]) * 2; free(data->columns); data->columns = (int *) alloc(sizeof(data->columns[0]) * num_cols); if (num_cols != 0) { data->columns[0] = 0; for (unsigned i = 1; i < num_cols; ++i) { - data->columns[i] = data->columns[i-1] + col_spacing + col_widths[i-1]; + data->columns[i] = data->columns[i-1] + col_widths[i-1]; } } data->num_cols = num_cols; diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index f51a740a9..7b8b3450c 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -854,7 +854,7 @@ X11_add_menu(winid window, impossible("Menu item too long (%d).", len); len = BUFSZ - 1; } - Sprintf(buf, "%c %c ", ch ? ch : ' ', preselected ? '+' : '-'); + Sprintf(buf, "%c\t%c\t", ch ? ch : ' ', preselected ? '+' : '-'); (void) strncpy(buf + 4, str, len); buf[4 + len] = '\0'; item->str = copy_of(buf); @@ -1318,6 +1318,17 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu) Cardinal num_args; Dimension cwidth, maxwidth = 0; + /* Does any line have a selector? */ + boolean any_canpick = FALSE; + if (how != PICK_NONE) { + for (curr = curr_menu->base; curr; curr = curr->next) { + if (curr->identifier.a_void != NULL) { + any_canpick = TRUE; + break; + } + } + } + int *col_widths = NULL; unsigned num_cols = 0; X11_Font *font; @@ -1333,6 +1344,23 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu) int color = NO_COLOR; boolean canpick = (how != PICK_NONE && curr->identifier.a_void); + /* Add tabs if needed to align non-selector lines with selector lines */ + if (any_canpick && !canpick) { + char *buf; + if (strncmp(str, " ", 4) == 0) { + size_t buf_len = strlen(str); + buf = (char *) alloc(buf_len); + Snprintf(buf, buf_len, "\t\t%s", str + 4); + } else { + size_t buf_len = strlen(str) + 3; + buf = (char *) alloc(buf_len); + Snprintf(buf, buf_len, "\t\t%s", str); + } + free(curr->str); + curr->str = buf; + str = buf; + } + num_args = 0; XtSetArg(args[num_args], nhStr(XtNlabel), str); num_args++; XtSetArg(args[num_args], nhStr(XtNjustify), XtJustifyLeft); num_args++; @@ -1446,6 +1474,8 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu) static unsigned get_col_widths(Widget w, X11_Font *font, const char *str, int **col_widths) { + int col_spacing = X11_column_width(XtDisplay(w), font, "# ", 2); + /* Determine the number of columns */ unsigned num_cols = 1; size_t i = 0; @@ -1467,7 +1497,12 @@ get_col_widths(Widget w, X11_Font *font, const char *str, int **col_widths) i = 0; while (str[i] != '\0') { size_t len = strcspn(str + i, "\t"); - cwidths[col++] = X11_column_width(XtDisplay(w), font, str + i, len); + cwidths[col] = X11_column_width(XtDisplay(w), font, str + i, len); + if (len > 1) { + col_spacing = X11_font_height(font) * 2; + } + cwidths[col] += col_spacing; + ++col; i += len; if (str[i] == '\t') { ++i; From cadde6d317ec54168e56b9020a14fecc8dde7271 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Thu, 20 Aug 2026 00:59:46 -0400 Subject: [PATCH 663/702] Use text window for display_file The text window is assumed to use a monospaced font. --- win/X11/winX.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/win/X11/winX.c b/win/X11/winX.c index ace3f1124..07fccccdd 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -2170,11 +2170,8 @@ X11_display_file(const char *str, boolean complain) dlb *fp; winid newwin; struct xwindow *wp; - anything any; - menu_item *menu_list; #define LLEN 128 char line[LLEN]; - int clr = 0; /* Use the port-independent file opener to see if the file exists. */ fp = dlb_fopen(str, RDTMODE); @@ -2184,14 +2181,11 @@ X11_display_file(const char *str, boolean complain) return; /* it doesn't exist, ignore */ } - newwin = X11_create_nhwindow(NHW_MENU); + newwin = X11_create_nhwindow(NHW_TEXT); wp = &window_list[newwin]; - X11_start_menu(newwin, MENU_BEHAVE_STANDARD); - any = cg.zeroany; while (dlb_fgets(line, LLEN, fp)) { - X11_add_menu(newwin, &nul_glyphinfo, &any, 0, 0, ATR_NONE, - clr, line, MENU_ITEMFLAGS_NONE); + X11_putstr(newwin, 0, line); } (void) dlb_fclose(fp); @@ -2199,9 +2193,7 @@ X11_display_file(const char *str, boolean complain) if (str) wp->title = dupstr(str); - wp->menu_information->permi = FALSE; - wp->menu_information->disable_mcolors = TRUE; - (void) X11_select_menu(newwin, PICK_NONE, &menu_list); + (void) X11_display_nhwindow(newwin, TRUE); X11_destroy_nhwindow(newwin); } From db32a639a7a4dc603c6f81e0959ce0165b451576 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Thu, 20 Aug 2026 01:56:58 -0400 Subject: [PATCH 664/702] Extend last column to end of line If a line in the menu has fewer columns than the others, the last one is deemed to extend to the right margin, and does not count toward the maximum width of that column. Also, revert the change to NetHack.font_menu. --- win/X11/NetHack.ad | 2 +- win/X11/winlabel.c | 10 +++++----- win/X11/winmenu.c | 12 +++++++----- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/win/X11/NetHack.ad b/win/X11/NetHack.ad index 10f1e7a73..f12110f6f 100644 --- a/win/X11/NetHack.ad +++ b/win/X11/NetHack.ad @@ -31,7 +31,7 @@ NetHack*text*borderWidth: 0 ! These correspond to the .nethackrc settings font_map, font_menu, ! font_message, font_status and font_text NetHack.font_map: mono-10 -NetHack.font_menu: sans-10 +NetHack.font_menu: mono-10 NetHack.font_message: sans-10 NetHack.font_status: sans-10 NetHack.font_text: mono-10 diff --git a/win/X11/winlabel.c b/win/X11/winlabel.c index 075346dde..2f9e5e68c 100644 --- a/win/X11/winlabel.c +++ b/win/X11/winlabel.c @@ -185,11 +185,11 @@ X11_set_column_widths(Widget w, const int *col_widths, unsigned num_cols) WidgetData *data = get_widget_data(w); if (data != NULL) { free(data->columns); - data->columns = (int *) alloc(sizeof(data->columns[0]) * num_cols); + data->columns = (int *) alloc(sizeof(data->columns[0]) * (num_cols + 1)); + data->columns[0] = 0; if (num_cols != 0) { - data->columns[0] = 0; - for (unsigned i = 1; i < num_cols; ++i) { - data->columns[i] = data->columns[i-1] + col_widths[i-1]; + for (unsigned i = 0; i < num_cols; ++i) { + data->columns[i+1] = data->columns[i] + col_widths[i]; } } data->num_cols = num_cols; @@ -421,7 +421,7 @@ update_label(Widget w, WidgetData *data) pos = 0; } else { line3 = min(strcspn(label + i + j, "\t\n"), line2); - pos = data->columns[min(col, data->num_cols-1)]; + pos = data->columns[min(col, data->num_cols)]; } #ifdef USE_XFT XftDrawString8(draw, &fgcolor, font, x + pos, y, diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index 7b8b3450c..e8d0eead2 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -1471,13 +1471,15 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu) } /* Determine widths of columns */ +/* The last column is deemed to extend to the right margin, and is not included + in the returned array */ static unsigned get_col_widths(Widget w, X11_Font *font, const char *str, int **col_widths) { int col_spacing = X11_column_width(XtDisplay(w), font, "# ", 2); /* Determine the number of columns */ - unsigned num_cols = 1; + unsigned num_cols = 0; size_t i = 0; while (str[i] != '\0') { size_t len = strcspn(str + i, "\t"); @@ -1497,16 +1499,16 @@ get_col_widths(Widget w, X11_Font *font, const char *str, int **col_widths) i = 0; while (str[i] != '\0') { size_t len = strcspn(str + i, "\t"); + if (str[i+len] == '\0') { + break; + } cwidths[col] = X11_column_width(XtDisplay(w), font, str + i, len); if (len > 1) { col_spacing = X11_font_height(font) * 2; } cwidths[col] += col_spacing; ++col; - i += len; - if (str[i] == '\t') { - ++i; - } + i += len + 1; } /* Return */ From f913cb3704167d06d0fbd1a8d2dd2af3f58a7aaa Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 22 Aug 2026 10:59:12 +0300 Subject: [PATCH 665/702] X11: support tab-separated menu columns --- doc/fixes5-0-1.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index a174242ba..c6cbcfb88 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -261,6 +261,7 @@ X11: fix menu group accelerators X11: implement all text attributes for menus X11: fix crash when loading a nonexistent font X11: use xft to render fonts +X11: support tab-separated menu columns Unix: don't complain about MAXPLAYERS with unknown command line param From 7840d75365f3f0c4c1cbc998a3d86a1a3cbccb75 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 22 Aug 2026 20:43:46 -0400 Subject: [PATCH 666/702] X11: set menu font to proportional Menus that needed to be tabified now are. --- win/X11/NetHack.ad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/X11/NetHack.ad b/win/X11/NetHack.ad index f12110f6f..10f1e7a73 100644 --- a/win/X11/NetHack.ad +++ b/win/X11/NetHack.ad @@ -31,7 +31,7 @@ NetHack*text*borderWidth: 0 ! These correspond to the .nethackrc settings font_map, font_menu, ! font_message, font_status and font_text NetHack.font_map: mono-10 -NetHack.font_menu: mono-10 +NetHack.font_menu: sans-10 NetHack.font_message: sans-10 NetHack.font_status: sans-10 NetHack.font_text: mono-10 From b61aef834ef4fd06adeb8e6528fca4983ab9a66c Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 22 Aug 2026 20:46:13 -0400 Subject: [PATCH 667/702] Set menu font to proportional --- win/X11/winX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/X11/winX.c b/win/X11/winX.c index 0f63a5761..4b370b6c1 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -1571,7 +1571,7 @@ static XtResource resources[] = { { nhStr("font_map"), nhStr("Font_map"), XtRString, sizeof(String), XtOffset(AppResources *, font_map), XtRString, nhStr("mono-10") }, { nhStr("font_menu"), nhStr("Font_menu"), XtRString, sizeof(String), - XtOffset(AppResources *, font_menu), XtRString, nhStr("mono-10") }, + XtOffset(AppResources *, font_menu), XtRString, nhStr("sans-10") }, { nhStr("font_message"), nhStr("Font_message"), XtRString, sizeof(String), XtOffset(AppResources *, font_message), XtRString, nhStr("sans-10") }, { nhStr("font_status"), nhStr("Font_status"), XtRString, sizeof(String), From 9b4a8dfb05a3a14d4e700930f998d51d484307cc Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 23 Aug 2026 18:51:13 -0400 Subject: [PATCH 668/702] mon interaction with terrain was postponed Fix #576 Reported initially by @copperwater for polymorphed monsters: "observe how the [polymorphed-monster] hovers placidly above the water for several turns like Wile E. Coyote before it gets a move, realizes it's above water, and drowns. Ditto for lava." A comment in the GitHub issue thread by @Tomsod pointed out that a revived corpse could do the same. This should set things up for other terrain fallout if discovered or implemented in the future. - consume an additional bit in enum mon_terrain_effects (hack.h) - include the additional bit in TERRAIN_FALLOUT_MASK (monst.h) - add detection to maybe_set_terrain_effects (mon.c) - add action to terrain_effects (mon.c) Implemented by stealing some upper unused mstate bits to avoid invalidating existing save and bones. --- doc/fixes5-0-1.txt | 2 ++ include/decl.h | 3 +++ include/extern.h | 3 +++ include/hack.h | 8 ++++++ include/monst.h | 28 +++++++++++++-------- src/allmain.c | 5 ++++ src/decl.c | 2 ++ src/do.c | 1 + src/dog.c | 2 ++ src/mon.c | 63 +++++++++++++++++++++++++++++++++++++++++++++- src/restore.c | 9 ++++--- src/vault.c | 1 + src/wizcmds.c | 3 ++- 13 files changed, 114 insertions(+), 16 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index c6cbcfb88..6e1c22cc1 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -85,6 +85,8 @@ don't refer to pet as "Your pet" until after the taming process has finished checkpoint fixes (pr #1660 by k21971) upon return to a level, catch up on remaining nutrition value by the same percentage as the catch up for the weight +after polymorph or revival from corpse, monsters were not interacting with + the terrain until that monster's next move Platform- and/or Interface-Specific Fixes diff --git a/include/decl.h b/include/decl.h index 86ec5b977..49f9e17c8 100644 --- a/include/decl.h +++ b/include/decl.h @@ -786,6 +786,9 @@ struct instance_globals_p { unsigned pline_flags; char prevmsg[BUFSZ]; + /* mon.c */ + enum mon_terrain_effects pending_terrain_effects; + /* potion.c */ int potion_nothing; int potion_unkn; diff --git a/include/extern.h b/include/extern.h index ade96f43c..3b859bed1 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1869,6 +1869,9 @@ extern void see_monster_closeup(struct monst *, boolean) NONNULLARG1; extern void see_nearby_monsters(void); extern void shieldeff_mon(struct monst *) NONNULLARG1; extern void flash_mon(struct monst *) NONNULLARG1; +extern boolean maybe_set_terrain_effects(struct monst *, + struct permonst *) NONNULLARG1; +extern void terrain_effects(void); /* ### mondata.c ### */ diff --git a/include/hack.h b/include/hack.h index 0d140e8b1..a7c28315d 100644 --- a/include/hack.h +++ b/include/hack.h @@ -725,6 +725,14 @@ struct plinemsg_type { /* bitmask for callers of hide_unhide_msgtypes() */ #define MSGTYP_MASK_REP_SHOW ((1 << MSGTYP_NOREP) | (1 << MSGTYP_NOSHOW)) +enum mon_terrain_effects { + no_terrain_effects = 0x00000000, + /* these bit values must be beyond the MON_ ranges in monst.h + since they get set on mon->mstate */ + nonflyer_vs_liquid = 0x10000000, + candrown_vs_liquid = 0x20000000, +}; + /* polyself flags */ enum polyself_flags { POLY_NOFLAGS = 0x00, diff --git a/include/monst.h b/include/monst.h index 060995f86..5cd6aa64d 100644 --- a/include/monst.h +++ b/include/monst.h @@ -55,17 +55,23 @@ enum m_ap_types { M_AP_MONSTER = 3 /* a monster; mostly used for cloned Wizard */ }; -#define MON_FLOOR 0x0000 -#define MON_OFFMAP 0x0001 -#define MON_DETACH 0x0002 -#define MON_MIGRATING 0x0004 -#define MON_LIMBO 0x0008 -#define MON_BUBBLEMOVE 0x0010 -#define MON_ENDGAME_FREE 0x0020 -#define MON_ENDGAME_MIGR 0x0040 -#define MON_OBLITERATE 0x0080 -#define MON_STILL_ARRIVING 0x0100 -#define MON_PARKED 0x0200 +#define MON_FLOOR 0x00000000 +#define MON_OFFMAP 0x00000001 +#define MON_DETACH 0x00000002 +#define MON_MIGRATING 0x00000004 +#define MON_LIMBO 0x00000008 +#define MON_BUBBLEMOVE 0x00000010 +#define MON_ENDGAME_FREE 0x00000020 +#define MON_ENDGAME_MIGR 0x00000040 +#define MON_OBLITERATE 0x00000080 +#define MON_STILL_ARRIVING 0x00000100 +#define MON_PARKED 0x00000200 +/* 0x10000000 through 0x40000000 match enum pending_terrain_effects */ +/* 0x10000000 */ /* nonflyer_vs_liquid */ +/* 0x20000000 */ /* candrown_vs_liquid */ +/* 0x40000000 */ +#define TERRAIN_FALLOUT_MASK 0x70000000 + #define M_AP_TYPMASK 0x7 #define M_AP_F_DKNOWN 0x8 diff --git a/src/allmain.c b/src/allmain.c index 4177cd0cd..0ca4d41d3 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -204,6 +204,11 @@ moveloop_core(void) encumber_msg(); svc.context.mon_moving = TRUE; + /* call terrain_effects during mon_moving phase */ + if (gp.pending_terrain_effects) { + terrain_effects(); + gp.pending_terrain_effects = no_terrain_effects; + } do { monscanmove = movemon(); if (u.umovement >= NORMAL_SPEED) diff --git a/src/decl.c b/src/decl.c index 6263eb708..64c829ce2 100644 --- a/src/decl.c +++ b/src/decl.c @@ -637,6 +637,8 @@ static const struct instance_globals_p g_init_p = { /* pline.c */ 0U, /* pline_flags */ UNDEFINED_VALUES, /* prevmsg */ + /* mon.c */ + no_terrain_effects, /* pending_terrain_effects */ /* potion.c */ UNDEFINED_VALUE, /* potion_nothing */ UNDEFINED_VALUE, /* potion_unkn */ diff --git a/src/do.c b/src/do.c index bd1e18286..ab179765f 100644 --- a/src/do.c +++ b/src/do.c @@ -2185,6 +2185,7 @@ revive_corpse(struct obj *corpse) pline("%s disappears%s!", The(cname), effect); } } + (void) maybe_set_terrain_effects(mtmp, 0); break; case OBJ_MINVENT: /* probably a nymph's */ diff --git a/src/dog.c b/src/dog.c index 1bbee167e..63783be37 100644 --- a/src/dog.c +++ b/src/dog.c @@ -427,6 +427,7 @@ mon_arrive(struct monst *mtmp, int when) stairway *stway; d_level fromdlev; + mtmp->mstate &= ~TERRAIN_FALLOUT_MASK; /* shouldn't be set anyway */ mtmp->mstate |= MON_STILL_ARRIVING; mtmp->nmon = fmon; fmon = mtmp; @@ -905,6 +906,7 @@ migrate_to_level( /* prepare to take mtmp off the map */ num_segs = mon_leave(mtmp); /* take off map and move mtmp from fmon list to migrating_mons */ + mtmp->mstate &= ~TERRAIN_FALLOUT_MASK; relmon(mtmp, &gm.migrating_mons); /* mtmp->mx,my retain their value */ mtmp->mstate |= MON_MIGRATING; diff --git a/src/mon.c b/src/mon.c index 6ad8a0fb5..4bd6b1b07 100644 --- a/src/mon.c +++ b/src/mon.c @@ -2790,9 +2790,9 @@ m_detach( shkgone(mtmp); if (mtmp->wormno) wormgone(mtmp); + mtmp->mstate &= ~TERRAIN_FALLOUT_MASK; if (In_endgame(&u.uz)) mtmp->mstate |= MON_ENDGAME_FREE; - if ((mtmp->mstate & MON_DETACH) != 0) { impossible("m_detach: %s is already detached?", minimal_monnam(mtmp, FALSE)); @@ -3936,6 +3936,7 @@ elemental_clog(struct monst *mon) if (mtmp) { int mx = mtmp->mx, my = mtmp->my; + mtmp->mstate &= ~TERRAIN_FALLOUT_MASK; mtmp->mstate |= MON_OBLITERATE; mongone(mtmp); /* places in the code might still reference mtmp->mx, mtmp->my */ @@ -4055,6 +4056,7 @@ mnearto( but for the moment it is leaving */ mon_leaving_level(othermon); othermon->mx = othermon->my = 0; /* 'othermon' is not on the map */ + othermon->mstate &= ~TERRAIN_FALLOUT_MASK; othermon->mstate |= MON_OFFMAP; } @@ -5493,6 +5495,7 @@ newcham( if (!(mtmp->misc_worn_check & W_ARMG)) mselftouch(mtmp, "No longer petrify-resistant, ", !svc.context.mon_moving); + (void) maybe_set_terrain_effects(mtmp, olddata); check_gear_next_turn(mtmp); /* This ought to re-test can_carry() on each item in the inventory @@ -5541,6 +5544,64 @@ newcham( return 1; } +boolean +maybe_set_terrain_effects(struct monst *mtmp, struct permonst *oldmdat) +{ + struct permonst *mdat = mtmp->data; + boolean changed = FALSE; + + /* mtmp is in liquid */ + if (is_pool(mtmp->mx, mtmp->my) || Is_waterlevel(&u.uz) + || is_lava(mtmp->mx, mtmp->my) + || IS_FOUNTAIN(levl[mtmp->mx][mtmp->my].typ)) { + + /* mtmp is a non-flyer/floater/levitator */ + if (!is_flyer(mdat)) { + changed = (!oldmdat || + (((is_flyer(oldmdat) != is_flyer(mdat)) + || (is_floater(oldmdat) != is_floater(mdat))) + && !(mtmp == u.usteed && (Flying || Levitation)))); + gp.pending_terrain_effects |= nonflyer_vs_liquid; + mtmp->mstate |= (long) nonflyer_vs_liquid; + } + + /* swimmer/amphibious/breathless to something that is not */ + if (!cant_drown(mdat)) { + changed = (!oldmdat || ((cant_drown(oldmdat) != cant_drown(mdat)))); + gp.pending_terrain_effects |= candrown_vs_liquid; + mtmp->mstate |= (long) candrown_vs_liquid; + } + } + /* TODO: handle other terrains that could be harmful to a + revived mon or polymorphed mon */ + + return changed; +} + +/* + * The terrain is what it is, but the monster changed + * in some way (polymorphed or newly revived), and has + * been flagged as problematic with the terrain. + */ +void +terrain_effects(void) +{ + struct monst *mtmp, *mtmp2; + + for (mtmp = fmon; mtmp; mtmp = mtmp2) { + mtmp2 = mtmp->nmon; + if ((mtmp->mstate & TERRAIN_FALLOUT_MASK) != 0) { + /* nonflyer_vs_liquid */ + if (!DEADMONSTER(mtmp) + && ((mtmp->mstate & (long) (nonflyer_vs_liquid | candrown_vs_liquid)) != 0)) + (void) minliquid(mtmp); + + /* always clear these bits, even if DEADMONSTER */ + mtmp->mstate &= ~TERRAIN_FALLOUT_MASK; + } + } +} + /* sometimes an egg will be special */ #define BREEDER_EGG (!rn2(77)) diff --git a/src/restore.c b/src/restore.c index 48e851dc6..cd6e86d0c 100644 --- a/src/restore.c +++ b/src/restore.c @@ -450,10 +450,11 @@ restmonchn(NHFILE *nhfp) restpriest(mtmp, ghostly); if (mtmp->isgd) { /* fixup for new bit MON_PARKED added post 5.0.0 */ - if (!mtmp->mx - && (mtmp->mstate & MON_PARKED) == 0L - && (mtmp->mstate & MON_MIGRATING) == 0L) + if (!mtmp->mx && (mtmp->mstate & MON_PARKED) == 0L + && (mtmp->mstate & MON_MIGRATING) == 0L) { + mtmp->mstate &= ~TERRAIN_FALLOUT_MASK; mtmp->mstate |= MON_PARKED; + } } if (!ghostly) { @@ -1210,6 +1211,8 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) for (y = 0; y < ROWNO; y++) svl.level.monsters[x][y] = (struct monst *) 0; for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { + if ((mtmp->mstate & TERRAIN_FALLOUT_MASK) != 0) + gp.pending_terrain_effects |= (mtmp->mstate & TERRAIN_FALLOUT_MASK); if (mtmp->isshk) set_residency(mtmp, FALSE); /* set some monst fields to sane values when coming from a bones file */ diff --git a/src/vault.c b/src/vault.c index 6de691f73..1f2d97a53 100644 --- a/src/vault.c +++ b/src/vault.c @@ -164,6 +164,7 @@ parkguard(struct monst *grd) newsym(grd->mx, grd->my); } if (m_at(0, 0) != grd) { + grd->mstate &= ~TERRAIN_FALLOUT_MASK; grd->mstate |= MON_PARKED; place_monster(grd, 0, 0); } diff --git a/src/wizcmds.c b/src/wizcmds.c index 2d255c3d3..fd0568120 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -97,7 +97,8 @@ makemap_unmakemon(struct monst *mtmp, boolean migratory) monsters won't get out of sync; it is not on the map but mongone() -> m_detach() -> mon_leaving_level() copes with that */ mtmp->mstate |= MON_OFFMAP; - mtmp->mstate &= ~(MON_MIGRATING | MON_LIMBO | MON_ENDGAME_MIGR); + mtmp->mstate &= ~(MON_MIGRATING | MON_LIMBO | MON_ENDGAME_MIGR + | TERRAIN_FALLOUT_MASK); /* FIXME: will post-5.0.0 MON_PARKED need to be dealt with here? */ mtmp->nmon = fmon; fmon = mtmp; From b67553ccc729ea58d7c71f7fc1ec6b7a7a4007d4 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 23 Aug 2026 19:33:39 -0400 Subject: [PATCH 669/702] follow-up --- src/mon.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/mon.c b/src/mon.c index 4bd6b1b07..71d773f2e 100644 --- a/src/mon.c +++ b/src/mon.c @@ -5554,20 +5554,25 @@ maybe_set_terrain_effects(struct monst *mtmp, struct permonst *oldmdat) if (is_pool(mtmp->mx, mtmp->my) || Is_waterlevel(&u.uz) || is_lava(mtmp->mx, mtmp->my) || IS_FOUNTAIN(levl[mtmp->mx][mtmp->my].typ)) { - - /* mtmp is a non-flyer/floater/levitator */ - if (!is_flyer(mdat)) { - changed = (!oldmdat || - (((is_flyer(oldmdat) != is_flyer(mdat)) - || (is_floater(oldmdat) != is_floater(mdat))) - && !(mtmp == u.usteed && (Flying || Levitation)))); + /* mtmp is a non-flyer/floater/levitator */ + boolean above_water = + ((is_flyer(mdat) || is_floater(mdat)) + && !(mtmp == u.usteed && (Flying || Levitation))), + was_above_water = + (oldmdat + && ((is_flyer(oldmdat) || is_floater(oldmdat)) + && !(mtmp == u.usteed && (Flying || Levitation)))); + if (!above_water) { + changed = (!oldmdat || (above_water != was_above_water)); gp.pending_terrain_effects |= nonflyer_vs_liquid; mtmp->mstate |= (long) nonflyer_vs_liquid; } /* swimmer/amphibious/breathless to something that is not */ if (!cant_drown(mdat)) { - changed = (!oldmdat || ((cant_drown(oldmdat) != cant_drown(mdat)))); + if (!changed) + changed = + (!oldmdat || ((cant_drown(oldmdat) != cant_drown(mdat)))); gp.pending_terrain_effects |= candrown_vs_liquid; mtmp->mstate |= (long) candrown_vs_liquid; } From cc47605531bf26c3884648d69fed17b44584c053 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sun, 23 Aug 2026 09:25:38 -0400 Subject: [PATCH 670/702] Add BMP and GIF support --- include/tileset.h | 19 ++- include/winX.h | 1 + sys/unix/Makefile.src | 16 +- win/X11/winX.c | 3 +- win/X11/winmap.c | 367 ++++++++++++++++++++++++++++++++---------- win/share/tileset.c | 138 +++++++++------- 6 files changed, 396 insertions(+), 148 deletions(-) diff --git a/include/tileset.h b/include/tileset.h index 20c5fe6a7..f6f394ac8 100644 --- a/include/tileset.h +++ b/include/tileset.h @@ -9,6 +9,9 @@ struct Pixel { unsigned char r, g, b, a; }; +/* To let the tileset interface split the tiles into separate images, use + * these functions */ + struct TileImage { /* Image data */ unsigned width, height; @@ -22,12 +25,8 @@ void set_tile_type(boolean true_color); void free_tiles(void); const struct TileImage *get_tile(unsigned tile_index); -/* For resizing tiles */ -struct TileImage *stretch_tile(const struct TileImage *, unsigned, - unsigned); -void free_tile(struct TileImage *); +/* To read the tileset as a single image, use these functions */ -/* Used internally by the tile set code */ struct TileSetImage { /* Image data */ unsigned width, height; @@ -42,6 +41,16 @@ struct TileSetImage { unsigned tile_width, tile_height; }; +boolean read_tile_image(struct TileSetImage *image, + const char *filename, boolean true_color); +void free_tile_image(struct TileSetImage *image); + +/* For resizing tiles */ +struct TileImage *stretch_tile(const struct TileImage *, unsigned, + unsigned); +void free_tile(struct TileImage *); + +/* Used internally by the tile set code */ boolean read_bmp_tiles(const char *filename, struct TileSetImage *image); boolean read_gif_tiles(const char *filename, struct TileSetImage *image); boolean read_png_tiles(const char *filename, struct TileSetImage *image); diff --git a/include/winX.h b/include/winX.h index 88d61df9a..0133c3d44 100644 --- a/include/winX.h +++ b/include/winX.h @@ -390,6 +390,7 @@ extern void nh_XtPopup(Widget, int, Widget); extern void nh_XtPopdown(Widget); extern void win_X11_init(int); extern void find_scrollbars(Widget, Widget, Widget *, Widget *); +extern Boolean nhApproxColor(Screen *, Colormap, char *, XColor *); /* ### winmesg.c ### */ extern void set_message_slider(struct xwindow *); diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index cb669d80d..7064cef64 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -259,11 +259,14 @@ WINCURSESOBJ ?= $(TARGETPFX)cursmain.o $(TARGETPFX)curswins.o \ WINX11SRC ?= ../win/X11/Window.c ../win/X11/dialogs.c ../win/X11/winX.c \ ../win/X11/winmap.c ../win/X11/winmenu.c ../win/X11/winmesg.c \ ../win/X11/winmisc.c ../win/X11/winstat.c ../win/X11/wintext.c \ - ../win/X11/winval.c ../win/X11/winlabel.c $(GENTILECFILE) + ../win/X11/winval.c ../win/X11/winlabel.c \ + ../win/share/tileset.c ../win/share/bmptiles.c ../win/share/giftiles.c \ + $(GENTILECFILE) WINX11OBJ ?= $(TARGETPFX)Window.o $(TARGETPFX)dialogs.o $(TARGETPFX)winX.o \ $(TARGETPFX)winmap.o $(TARGETPFX)winmenu.o $(TARGETPFX)winmesg.o \ $(TARGETPFX)winmisc.o $(TARGETPFX)winstat.o $(TARGETPFX)wintext.o \ - $(TARGETPFX)winval.o $(TARGETPFX)winlabel.o + $(TARGETPFX)winval.o $(TARGETPFX)winlabel.o \ + $(TARGETPFX)tileset.o $(TARGETPFX)bmptiles.o $(TARGETPFX)giftiles.o # # Files for a Qt 3 interface (renamed since nethack 3.6.x) # @@ -1101,6 +1104,15 @@ $(TARGETPFX)wintext.o: ../win/X11/wintext.c $(HACK_H) ../include/winX.h \ $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/wintext.c $(TARGETPFX)winval.o: ../win/X11/winval.c $(HACK_H) ../include/winX.h $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winval.c +$(TARGETPFX)tileset.o: ../win/share/tileset.c $(CONFIG_H) \ + ../include/objclass.h ../include/flag.h ../include/tileset.h + $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/share/tileset.c +$(TARGETPFX)bmptiles.o: ../win/share/bmptiles.c $(CONFIG_H) \ + ../include/objclass.h ../include/tileset.h + $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/share/bmptiles.c +$(TARGETPFX)giftiles.o: ../win/share/giftiles.c $(CONFIG_H) \ + ../include/objclass.h ../include/tileset.h + $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/share/giftiles.c $(TARGETPFX)wc_chainin.o: ../win/chain/wc_chainin.c $(HACK_H) $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/chain/wc_chainin.c $(TARGETPFX)wc_chainout.o: ../win/chain/wc_chainout.c $(HACK_H) diff --git a/win/X11/winX.c b/win/X11/winX.c index 07fccccdd..507cd138e 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -129,7 +129,6 @@ static XtSignalId X11_sig_id; #endif static void init_menu_nhcolors(struct xwindow *); -static Boolean nhApproxColor(Screen *, Colormap, char *, XColor *); static Boolean nhCvtStringToPixel(Display *, XrmValuePtr, Cardinal *, XrmValuePtr, XrmValuePtr, XtPointer *); static void get_window_frame_extents(Widget, long *, long *, long *, long *); @@ -460,7 +459,7 @@ static XtConvertArgRec const nhcolorConvertArgs[] = { * The approximate color found is returned in color as well. * Return True if something close was found. */ -static Boolean +Boolean nhApproxColor( Screen *screen, /* screen to use */ Colormap colormap, /* the colormap to use */ diff --git a/win/X11/winmap.c b/win/X11/winmap.c index 6e92eda63..be7fbcfdc 100644 --- a/win/X11/winmap.c +++ b/win/X11/winmap.c @@ -39,6 +39,7 @@ #include "hack.h" #include "dlb.h" #include "winX.h" +#include "tileset.h" #ifdef USE_XPM #include @@ -82,6 +83,9 @@ static XFontStruct *X11_get_map_font_struct(struct xwindow *wp); #endif static void get_text_gc(struct xwindow *, Font); static boolean init_tiles(struct xwindow *); +static unsigned long color_to_rgb(unsigned, unsigned, unsigned, + const Visual *); +static unsigned long shift_color(unsigned color, unsigned long mask); static void set_button_values(Widget, int, int, unsigned); static void map_check_size_change(struct xwindow *); static void map_update(struct xwindow *, int, int, int, int, boolean); @@ -92,6 +96,13 @@ static void map_all_unexplored(struct map_info_t *); static void get_char_info(struct xwindow *); static void display_cursor(struct xwindow *); +static boolean read_any_tiles(const char *tile_file); +#ifdef USE_XPM +static boolean read_xpm_tiles(const char *tile_file); +#else +static boolean read_binary_tiles(const char *tile_file); +#endif + /* Global functions ======================================================= */ void @@ -315,22 +326,6 @@ post_process_tiles(void) static boolean init_tiles(struct xwindow *wp) { -#ifdef USE_XPM - XpmAttributes attributes; - int errorcode; -#else - FILE *fp = (FILE *) 0; - x11_header header; - unsigned char *cp, *colormap = (unsigned char *) 0; - unsigned char *tb, *tile_bytes = (unsigned char *) 0; - int size; - XColor *colors = (XColor *) 0; - unsigned i; - int x, y; - int bitmap_pad; - int ddepth; -#endif - char buf[BUFSZ]; Display *dpy = XtDisplay(toplevel); Screen *screen = DefaultScreenOfDisplay(dpy); struct map_info_t *map_info = (struct map_info_t *) 0; @@ -339,53 +334,285 @@ init_tiles(struct xwindow *wp) boolean result = TRUE; XGCValues values; XtGCMask mask; + const char *tile_file; /* already have tile information */ if (tile_pixmap != None) goto tiledone; + /* honor the user's tile file setting */ + if (iflags.wc_tile_file != NULL && iflags.wc_tile_file[0] != '\0') { + tile_file = iflags.wc_tile_file; + } else { + tile_file = appResources.tile_file; + } + map_info = wp->map_information; tile_info = &map_info->tile_map; (void) memset((genericptr_t) tile_info, 0, sizeof (struct tile_map_info_t)); /* no tile file name, no tile information */ - if (!appResources.tile_file[0]) { + if (!tile_file[0]) { result = FALSE; goto tiledone; } + result = read_any_tiles(tile_file); + if (!result) { #ifdef USE_XPM + result = read_xpm_tiles(tile_file); + #else + result = read_binary_tiles(tile_file); +#endif + } + + if (!result) + goto tiledone; + + /* fake an inverted tile by drawing a border around the edges */ +#ifdef USE_WHITE + /* use white or black as the border */ + mask = GCFunction | GCForeground | GCGraphicsExposures; + values.graphics_exposures = False; + values.foreground = WhitePixelOfScreen(screen); + values.function = GXcopy; + tile_info->white_gc = XtGetGC(wp->w, mask, &values); + values.graphics_exposures = False; + values.foreground = BlackPixelOfScreen(screen); + values.function = GXcopy; + tile_info->black_gc = XtGetGC(wp->w, mask, &values); +#else + /* + * Use xor so we don't have to check for special colors. Xor white + * against the upper left pixel of the corridor so that we have a + * white rectangle when in a corridor. + */ + mask = GCFunction | GCForeground | GCGraphicsExposures; + values.graphics_exposures = False; + values.foreground = + WhitePixelOfScreen(screen) + ^ XGetPixel(tile_image, 0, + tile_height * T_corr); + values.function = GXxor; + tile_info->white_gc = XtGetGC(wp->w, mask, &values); + + mask = GCFunction | GCGraphicsExposures; + values.function = GXCopy; + values.graphics_exposures = False; + tile_info->black_gc = XtGetGC(wp->w, mask, &values); +#endif /* USE_WHITE */ + + tiledone: + if (result) { /* succeeded */ + tile_info->square_height = tile_height; + tile_info->square_width = tile_width; + tile_info->square_ascent = 0; + tile_info->square_lbearing = 0; + tile_info->image_width = image_width; + tile_info->image_height = image_height; + } + + return result; +} + +static boolean +read_any_tiles(const char *tile_file) +{ + Display *dpy = XtDisplay(toplevel); + int ddepth = DefaultDepth(dpy, DefaultScreen(dpy)); + + /* Read the image */ + struct TileSetImage image; + boolean result = read_tile_image(&image, tile_file, ddepth >= 15); + if (!result) { + /* Format not recognized */ + return FALSE; + } + + /* Set the tile dimensions */ + unsigned image_width = image.width; + unsigned image_height = image.height; + tile_width = (iflags.wc_tile_width != 0) + ? iflags.wc_tile_width + : (int) image.tile_width; + tile_height = (iflags.wc_tile_height != 0) + ? iflags.wc_tile_height + : (int) image.tile_height; + + /* Set the tile count */ + int tile_cols = image.width / tile_width; + int tile_rows = image.height / tile_height; + tile_count = tile_cols * tile_rows; + + /* Double the size if requested */ + if (appResources.double_tile_size) { + tile_width *= 2; + tile_height *= 2; + image_height *= 2; + image_width *= 2; + } + + /* calculate bitmap_pad */ + int bitmap_pad; + if (ddepth > 16) + bitmap_pad = 32; + else if (ddepth > 8) + bitmap_pad = 16; + else + bitmap_pad = 8; + + /* Convert to XImage */ + Screen *screen = DefaultScreenOfDisplay(dpy); + Visual *visual = DefaultVisualOfScreen(screen); + tile_image = XCreateImage( + dpy, visual, + ddepth, /* depth */ + ZPixmap, /* format */ + 0, /* offset */ + (char *) 0, /* data */ + image_width, /* width */ + image_height, /* height */ + bitmap_pad, /* bit pad */ + 0); /* bytes_per_line */ + + if (tile_image == NULL) { + X11_raw_print("Failed to allocate XImage"); + goto tile_error; + } + + /* now we know the physical memory requirements, we can allocate space */ + tile_image->data = + (char *) alloc((unsigned) tile_image->bytes_per_line * image_height); + + unsigned char *tile_bytes = image.indexes; + XColor colors[256]; + if (tile_bytes != NULL) { /* tileset uses a palette */ + size_t size = (size_t) image.width * (size_t) image.height; + unsigned num_colors = 0; + for (unsigned j = 0; j < size; ++j) { + num_colors = max(num_colors, tile_bytes[j] + 1U); + } + for (unsigned i = 0; i < num_colors; i++) { + struct Pixel *cp = &image.palette[i]; + colors[i].red = cp->r * 256; + colors[i].green = cp->g * 256; + colors[i].blue = cp->b * 256; + colors[i].flags = 0; + colors[i].pixel = 0; + + if (!XAllocColor(dpy, DefaultColormapOfScreen(screen), &colors[i]) + && !nhApproxColor(screen, DefaultColormapOfScreen(screen), + (char *) 0, &colors[i])) { + char buf[BUFSZ]; + Snprintf(buf, sizeof (buf), "%dth of %u color allocation failed", i, + num_colors); + X11_raw_print(buf); + goto tile_error; + } + } + } + + /* Convert the pixels */ + unsigned char *tb = image.indexes; + struct Pixel *cp = image.pixels; + for (unsigned y = 0; y < image.height; y++) { + for (unsigned x = 0; x < image.width; x++) { + unsigned long pixel; + if (tb == NULL) { + pixel = color_to_rgb(cp->r, cp->g, cp->b, visual); + ++cp; + } else { + pixel = colors[*tb++].pixel; + } + if (appResources.double_tile_size) { + XPutPixel(tile_image, x * 2 + 0, y * 2 + 0, pixel); + XPutPixel(tile_image, x * 2 + 1, y * 2 + 0, pixel); + XPutPixel(tile_image, x * 2 + 0, y * 2 + 1, pixel); + XPutPixel(tile_image, x * 2 + 1, y * 2 + 1, pixel); + } else { + XPutPixel(tile_image, x, y, pixel); + } + } + } + + free_tile_image(&image); + return TRUE; + +tile_error: + free_tile_image(&image); + return FALSE; +} + +static unsigned long +color_to_rgb(unsigned red, unsigned green, unsigned blue, const Visual *visual) +{ + return shift_color(red, visual->red_mask ) + | shift_color(green, visual->green_mask) + | shift_color(blue, visual->blue_mask ); +} + +static unsigned long +shift_color(unsigned color, unsigned long mask) +{ + unsigned long mask1; + unsigned long color1; + + /* Shift color to match mask */ + mask1 = mask; + color1 = color; + while (mask1 > 0xFF) { + mask1 >>= 1; + color1 <<= 1; + } + while (mask1 < 0x80) { + mask1 <<= 1; + color1 >>= 1; + } + + return mask & color1; +} + +#ifdef USE_XPM +static boolean +read_xpm_tiles(const char *tile_file) +{ + XpmAttributes attributes; + int errorcode; + + char buf[BUFSZ]; + Display *dpy = XtDisplay(toplevel); + unsigned int image_height = 0, image_width = 0; + attributes.valuemask = XpmCloseness; attributes.closeness = 25000; - errorcode = XpmReadFileToImage(dpy, appResources.tile_file, &tile_image, + errorcode = XpmReadFileToImage(dpy, tile_file, &tile_image, 0, &attributes); if (errorcode == XpmColorFailed) { Sprintf(buf, "Insufficient colors available to load %s.", - appResources.tile_file); + tile_file); X11_raw_print(buf); X11_raw_print("Try closing other colorful applications and restart."); X11_raw_print("Attempting to load with inferior colors."); attributes.closeness = 50000; - errorcode = XpmReadFileToImage(dpy, appResources.tile_file, + errorcode = XpmReadFileToImage(dpy, tile_file, &tile_image, 0, &attributes); } if (errorcode != XpmSuccess) { if (errorcode == XpmColorFailed) { Sprintf(buf, "Insufficient colors available to load %s.", - appResources.tile_file); + tile_file); X11_raw_print(buf); } else { - Sprintf(buf, "Failed to load %s: %s", appResources.tile_file, + Sprintf(buf, "Failed to load %s: %s", tile_file, XpmGetErrorString(errorcode)); X11_raw_print(buf); } - result = FALSE; X11_raw_print("Switching to text-based mode."); - goto tiledone; + return FALSE; } /* assume a fixed number of tiles per row */ @@ -393,12 +620,11 @@ init_tiles(struct xwindow *wp) || tile_image->width <= TILES_PER_ROW) { Sprintf(buf, "%s is not a multiple of %d (number of tiles/row) pixels wide", - appResources.tile_file, TILES_PER_ROW); + tile_file, TILES_PER_ROW); X11_raw_print(buf); XDestroyImage(tile_image); tile_image = 0; - result = FALSE; - goto tiledone; + return FALSE; } /* infer tile dimensions from image size and TILES_PER_ROW */ @@ -411,25 +637,47 @@ init_tiles(struct xwindow *wp) } tile_width = image_width / TILES_PER_ROW; tile_height = image_height / (tile_count / TILES_PER_ROW); + + return TRUE; +} + #else /* !USE_XPM */ + +static boolean +read_binary_tiles(const char *tile_file) +{ + FILE *fp = (FILE *) 0; + x11_header header; + unsigned char *cp, *colormap = (unsigned char *) 0; + unsigned char *tb, *tile_bytes = (unsigned char *) 0; + int size; + XColor *colors = (XColor *) 0; + unsigned i; + int x, y; + int bitmap_pad; + int ddepth; + + char buf[BUFSZ]; + Display *dpy = XtDisplay(toplevel); + Screen *screen = DefaultScreenOfDisplay(dpy); + unsigned int image_height = 0, image_width = 0; + boolean result = FALSE; + /* any less than 16 colours makes tiles useless */ ddepth = DefaultDepthOfScreen(screen); if (ddepth < 4) { X11_raw_print("need a screen depth of at least 4"); - result = FALSE; goto tiledone; } - fp = fopen_datafile(appResources.tile_file, RDBMODE, FALSE); + fp = fopen_datafile(tile_file, RDBMODE, FALSE); if (!fp) { X11_raw_print("can't open tile file"); - result = FALSE; goto tiledone; } if ((int) fread((char *) &header, sizeof(header), 1, fp) != 1) { X11_raw_print("read of header failed"); - result = FALSE; goto tiledone; } @@ -437,7 +685,6 @@ init_tiles(struct xwindow *wp) Sprintf(buf, "Wrong tile file version, expected 2, got %lu", header.version); X11_raw_print(buf); - result = FALSE; goto tiledone; } #ifdef VERBOSE @@ -453,7 +700,6 @@ ntiles %ld\n", colormap = (unsigned char *) alloc((unsigned) size); if ((int) fread((char *) colormap, 1, size, fp) != size) { X11_raw_print("read of colormap failed"); - result = FALSE; goto tiledone; } @@ -472,7 +718,6 @@ ntiles %ld\n", Sprintf(buf, "%dth out of %ld color allocation failed", i, header.ncolors); X11_raw_print(buf); - result = FALSE; goto tiledone; } } @@ -490,7 +735,6 @@ ntiles %ld\n", if ((int) fread((char *) tile_bytes, size, tile_count, fp) != tile_count) { X11_raw_print("read of tile bytes failed"); - result = FALSE; goto tiledone; } @@ -498,7 +742,6 @@ ntiles %ld\n", Sprintf(buf, "tile file incomplete, expecting %d tiles, found %lu", total_tiles_used, header.ntiles); X11_raw_print(buf); - result = FALSE; goto tiledone; } @@ -534,7 +777,6 @@ ntiles %ld\n", if (!tile_image) { impossible("init_tiles: insufficient memory to create image"); X11_raw_print("Resorting to text map."); - result = FALSE; goto tiledone; } @@ -566,47 +808,10 @@ ntiles %ld\n", for (x = 0; x < (int) image_width; x++, tb++) XPutPixel(tile_image, x, y, colors[*tb].pixel); } -#endif /* ?USE_XPM */ - /* fake an inverted tile by drawing a border around the edges */ -#ifdef USE_WHITE - /* use white or black as the border */ - mask = GCFunction | GCForeground | GCGraphicsExposures; - values.graphics_exposures = False; - values.foreground = WhitePixelOfScreen(screen); - values.function = GXcopy; - tile_info->white_gc = XtGetGC(wp->w, mask, &values); - values.graphics_exposures = False; - values.foreground = BlackPixelOfScreen(screen); - values.function = GXcopy; - tile_info->black_gc = XtGetGC(wp->w, mask, &values); -#else - /* - * Use xor so we don't have to check for special colors. Xor white - * against the upper left pixel of the corridor so that we have a - * white rectangle when in a corridor. - */ - mask = GCFunction | GCForeground | GCGraphicsExposures; - values.graphics_exposures = False; - values.foreground = - WhitePixelOfScreen(screen) - ^ XGetPixel(tile_image, 0, -#if 0 - tile_height * glyph2tile[cmap_to_glyph(S_corr)]); -#else - tile_height * T_corr); -#endif - values.function = GXxor; - tile_info->white_gc = XtGetGC(wp->w, mask, &values); - - mask = GCFunction | GCGraphicsExposures; - values.function = GXCopy; - values.graphics_exposures = False; - tile_info->black_gc = XtGetGC(wp->w, mask, &values); -#endif /* USE_WHITE */ + result = TRUE; tiledone: -#ifndef USE_XPM if (fp) (void) fclose(fp); if (colormap) @@ -615,20 +820,12 @@ ntiles %ld\n", free((genericptr_t) tile_bytes); if (colors) free((genericptr_t) colors); -#endif - - if (result) { /* succeeded */ - tile_info->square_height = tile_height; - tile_info->square_width = tile_width; - tile_info->square_ascent = 0; - tile_info->square_lbearing = 0; - tile_info->image_width = image_width; - tile_info->image_height = image_height; - } return result; } +#endif /* ?USE_XPM */ + /* * Make sure the map's cursor is always visible. */ diff --git a/win/share/tileset.c b/win/share/tileset.c index 556298a7c..355b6b210 100644 --- a/win/share/tileset.c +++ b/win/share/tileset.c @@ -10,10 +10,15 @@ #include "flag.h" #include "tileset.h" +/* Define this for systems that use the tile-splitting functions */ +#if defined(MSDOS) +#define USE_TILE_SPLITTING +#endif + static void get_tile_map(const char *); +#ifdef USE_TILE_SPLITTING static unsigned gcd(unsigned, unsigned); static void split_tiles(const struct TileSetImage *); -static void free_image(struct TileSetImage *); static struct TileImage *tiles; static unsigned num_tiles; @@ -25,25 +30,57 @@ static struct Pixel palette[256]; boolean read_tiles(const char *filename, boolean true_color) { - static const unsigned char png_sig[] = { - 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A - }; struct TileSetImage image; - FILE *fp; - char header[16]; - boolean ok; if (tiles != NULL) return TRUE; + if (!read_tile_image(&image, filename, true_color)) { + return FALSE; + } + + /* Save the palette if present */ + have_palette = image.indexes != NULL; + memcpy(palette, image.palette, sizeof(palette)); + + /* Set the tile dimensions if the user has not done so */ + if (iflags.wc_tile_width == 0) { + iflags.wc_tile_width = image.tile_width; + } + if (iflags.wc_tile_height == 0) { + iflags.wc_tile_height = image.tile_height; + } + + /* Split the image into tiles */ + split_tiles(&image); + + free_tile_image(&image); + return TRUE; +} +#endif /* USE_TILE_SPLITTING */ + +boolean +read_tile_image(struct TileSetImage *image, const char *filename, boolean true_color) +{ + static const unsigned char png_sig[] = { + 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A + }; + FILE *fp; + char header[16]; + boolean ok; + /* Fill the image structure with known values */ - image.width = 0; - image.height = 0; - image.pixels = NULL; /* custodial */ - image.indexes = NULL; /* custodial */ - image.image_desc = NULL; /* custodial */ - image.tile_width = 0; - image.tile_height = 0; + image->width = 0; + image->height = 0; + image->pixels = NULL; /* custodial, returned */ + image->indexes = NULL; /* custodial, returned */ + image->image_desc = NULL; /* custodial, returned */ + image->tile_width = 0; + image->tile_height = 0; + + if (filename == NULL || filename[0] == '\0') { + filename = "nhtiles.bmp"; + } /* Identify the image type */ fp = fopen(filename, "rb"); @@ -55,12 +92,12 @@ read_tiles(const char *filename, boolean true_color) /* Call the loader appropriate for the image */ if (memcmp(header, "BM", 2) == 0) { - ok = read_bmp_tiles(filename, &image); + ok = read_bmp_tiles(filename, image); } else if (memcmp(header, "GIF87a", 6) == 0 || memcmp(header, "GIF89a", 6) == 0) { - ok = read_gif_tiles(filename, &image); + ok = read_gif_tiles(filename, image); } else if (memcmp(header, png_sig, sizeof(png_sig)) == 0) { - ok = read_png_tiles(filename, &image); + ok = read_png_tiles(filename, image); } else { ok = FALSE; } @@ -69,44 +106,30 @@ read_tiles(const char *filename, boolean true_color) /* Reject if the interface cannot handle direct color and the image does not use a palette */ - if (!true_color && image.indexes == NULL) + if (!true_color && image->indexes == NULL) goto error; - /* Save the palette if present */ - have_palette = image.indexes != NULL; - memcpy(palette, image.palette, sizeof(palette)); + /* Parse the tile map */ + get_tile_map(image->image_desc); /* Set defaults for tile metadata */ - if (image.tile_width == 0) { - image.tile_width = image.width / 40; + if (image->tile_width == 0) { + image->tile_width = image->width / 40; } - if (image.tile_height == 0) { - image.tile_height = image.tile_width; - } - /* Set the tile dimensions if the user has not done so */ - if (iflags.wc_tile_width == 0) { - iflags.wc_tile_width = image.tile_width; - } - if (iflags.wc_tile_height == 0) { - iflags.wc_tile_height = image.tile_height; + if (image->tile_height == 0) { + image->tile_height = image->tile_width; } - /* Parse the tile map */ - get_tile_map(image.image_desc); - - /* Split the image into tiles */ - split_tiles(&image); - - free_image(&image); return TRUE; error: if (fp) fclose(fp); - free_image(&image); + free_tile_image(image); return FALSE; } +#ifdef USE_TILE_SPLITTING /* Free tile memory not required by the chosen display mode */ void set_tile_type(boolean true_color) @@ -134,6 +157,7 @@ get_palette(void) { return have_palette ? palette : NULL; } +#endif /* USE_TILE_SPLITTING */ /* TODO: derive tile_map from image_desc */ static void @@ -142,6 +166,7 @@ get_tile_map(const char *image_desc UNUSED) return; } +#ifdef USE_TILE_SPLITTING void free_tiles(void) { @@ -161,9 +186,10 @@ free_tiles(void) if (blank_tile.indexes) free((genericptr_t) blank_tile.indexes), blank_tile.indexes = NULL; } +#endif /* USE_TILE_SPLITTING */ -static void -free_image(struct TileSetImage *image) +void +free_tile_image(struct TileSetImage *image) { if (image->pixels) free((genericptr_t) image->pixels), image->pixels = NULL; @@ -173,6 +199,7 @@ free_image(struct TileSetImage *image) free((genericptr_t) image->image_desc), image->image_desc = NULL; } +#ifdef USE_TILE_SPLITTING const struct TileImage * get_tile(unsigned tile_index) { @@ -292,10 +319,10 @@ split_tiles(const struct TileSetImage *image) unsigned x1, y1, y2; /* Get the number of tiles */ - tile_rows = image->height / iflags.wc_tile_height; - tile_cols = image->width / iflags.wc_tile_width; + tile_rows = image->height / image->tile_height; + tile_cols = image->width / image->tile_width; num_tiles = tile_rows * tile_cols; - tile_size = (size_t) iflags.wc_tile_height * (size_t) iflags.wc_tile_width; + tile_size = (size_t) image->tile_height * (size_t) image->tile_width; /* Allocate the tile array */ tiles = (struct TileImage *) alloc(num_tiles * sizeof(tiles[0])); @@ -306,31 +333,31 @@ split_tiles(const struct TileSetImage *image) for (x1 = 0; x1 < tile_cols; ++x1) { struct TileImage *tile = &tiles[y1 * tile_cols + x1]; - tile->width = iflags.wc_tile_width; - tile->height = iflags.wc_tile_height; + tile->width = image->tile_width; + tile->height = image->tile_height; tile->pixels = (struct Pixel *) alloc(tile_size * sizeof (struct Pixel)); if (image->indexes != NULL) { tile->indexes = (unsigned char *) alloc(tile_size); } - for (y2 = 0; y2 < (unsigned) iflags.wc_tile_height; ++y2) { - unsigned y = y1 * iflags.wc_tile_height + y2; - unsigned x = x1 * iflags.wc_tile_width; + for (y2 = 0; y2 < (unsigned) image->tile_height; ++y2) { + unsigned y = y1 * image->tile_height + y2; + unsigned x = x1 * image->tile_width; i = y * image->width; j = y2 * tile->width; memcpy(tile->pixels + j, image->pixels + i + x, - sizeof(tile->pixels[0]) * iflags.wc_tile_width); + sizeof(tile->pixels[0]) * image->tile_width); if (image->indexes != NULL) { memcpy(tile->indexes + j, image->indexes + i + x, - iflags.wc_tile_width); + image->tile_width); } } } } /* Create a blank tile for use when the tile index is invalid */ - blank_tile.width = iflags.wc_tile_width; - blank_tile.height = iflags.wc_tile_height; + blank_tile.width = image->tile_width; + blank_tile.height = image->tile_height; blank_tile.pixels = (struct Pixel *) alloc(tile_size * sizeof (struct Pixel)); for (i = 0; i < tile_size; ++i) { @@ -344,12 +371,15 @@ split_tiles(const struct TileSetImage *image) memset(blank_tile.indexes, 0, tile_size); } } +#endif /* USE_TILE_SPLITTING */ +#ifndef USE_PNG boolean read_png_tiles(const char *filename UNUSED, struct TileSetImage *image UNUSED) { /* stub */ return FALSE; } +#endif /* !USE_PNG */ #endif /* TILES_IN_GLYPHMAP */ From a575fccf08e031a8725e8d7b19e9e88d8341757e Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sun, 23 Aug 2026 10:32:27 -0400 Subject: [PATCH 671/702] Add PNG support --- sys/unix/Makefile.src | 8 ++- sys/unix/hints/linux.500 | 5 ++ sys/unix/hints/macOS.500 | 5 ++ win/share/pngtiles.c | 150 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 166 insertions(+), 2 deletions(-) create mode 100644 win/share/pngtiles.c diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 7064cef64..1def499ba 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -261,12 +261,13 @@ WINX11SRC ?= ../win/X11/Window.c ../win/X11/dialogs.c ../win/X11/winX.c \ ../win/X11/winmisc.c ../win/X11/winstat.c ../win/X11/wintext.c \ ../win/X11/winval.c ../win/X11/winlabel.c \ ../win/share/tileset.c ../win/share/bmptiles.c ../win/share/giftiles.c \ - $(GENTILECFILE) + ../win/share/pngtiles.c $(GENTILECFILE) WINX11OBJ ?= $(TARGETPFX)Window.o $(TARGETPFX)dialogs.o $(TARGETPFX)winX.o \ $(TARGETPFX)winmap.o $(TARGETPFX)winmenu.o $(TARGETPFX)winmesg.o \ $(TARGETPFX)winmisc.o $(TARGETPFX)winstat.o $(TARGETPFX)wintext.o \ $(TARGETPFX)winval.o $(TARGETPFX)winlabel.o \ - $(TARGETPFX)tileset.o $(TARGETPFX)bmptiles.o $(TARGETPFX)giftiles.o + $(TARGETPFX)tileset.o $(TARGETPFX)bmptiles.o $(TARGETPFX)giftiles.o \ + $(TARGETPFX)pngtiles.o # # Files for a Qt 3 interface (renamed since nethack 3.6.x) # @@ -1113,6 +1114,9 @@ $(TARGETPFX)bmptiles.o: ../win/share/bmptiles.c $(CONFIG_H) \ $(TARGETPFX)giftiles.o: ../win/share/giftiles.c $(CONFIG_H) \ ../include/objclass.h ../include/tileset.h $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/share/giftiles.c +$(TARGETPFX)pngtiles.o: ../win/share/pngtiles.c $(CONFIG_H) \ + ../include/objclass.h ../include/tileset.h + $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/share/pngtiles.c $(TARGETPFX)wc_chainin.o: ../win/chain/wc_chainin.c $(HACK_H) $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/chain/wc_chainin.c $(TARGETPFX)wc_chainout.o: ../win/chain/wc_chainout.c $(HACK_H) diff --git a/sys/unix/hints/linux.500 b/sys/unix/hints/linux.500 index 656e831e6..b81a37517 100755 --- a/sys/unix/hints/linux.500 +++ b/sys/unix/hints/linux.500 @@ -398,6 +398,7 @@ endif # MAKEFILE_SRC ifdef WANT_WIN_X11 USE_XPM=1 USE_XFT=1 +USE_PNG=1 WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm ifndef CROSSCOMPILE @@ -419,6 +420,10 @@ CFLAGS += -DUSE_XPM WINX11LIB += -lXpm VARDATND0 += rip.xpm endif +ifdef USE_PNG +CFLAGS += -DUSE_PNG +WINX11LIB += -lpng +endif WINLIB += $(WINX11LIB) LFLAGS+=-L/opt/X11/lib endif # WANT_WIN_X11 diff --git a/sys/unix/hints/macOS.500 b/sys/unix/hints/macOS.500 index 97d82388a..3fd074841 100755 --- a/sys/unix/hints/macOS.500 +++ b/sys/unix/hints/macOS.500 @@ -279,6 +279,7 @@ endif # WANT_WIN_CHAIN ifdef WANT_WIN_X11 USE_XFT=1 USE_XPM=1 +USE_PNG=1 WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm GENTILEOFILE = $(SRCDIR)/tile.o @@ -298,6 +299,10 @@ CFLAGS += -DUSE_XPM WINX11LIB += -lXpm VARDATND0 += rip.xpm endif +ifdef USE_PNG +CFLAGS += -DUSE_PNG +WINX11LIB += -lpng +endif WINLIB += $(WINX11LIB) LFLAGS += -L/opt/X11/lib endif # WANT_WIN_X11 diff --git a/win/share/pngtiles.c b/win/share/pngtiles.c new file mode 100644 index 000000000..0c77d399f --- /dev/null +++ b/win/share/pngtiles.c @@ -0,0 +1,150 @@ +#include "config.h" +#include "tileset.h" + +#ifdef USE_PNG + +#include + +boolean +read_png_tiles(const char *filename, struct TileSetImage *image) +{ + png_structp read_png_ptr = NULL; /* custodial */ + png_infop read_info_ptr = NULL; /* custodial */ + png_infop read_end_info = NULL; /* custodial */ + + FILE *fp; + unsigned char header[8]; + size_t size, num_pixels; + unsigned x, y; + png_bytepp pixels; + png_byte color_type; + int palette_size = 0; + png_textp text_chunks; + int num_text_chunks, i; + + image->width = 0; + image->height = 0; + image->indexes = NULL; /* custodial, returned */ + image->pixels = NULL; /* custodial, returned */ + image->image_desc = NULL; /* custodial, returned */ + image->tile_width = 0; + image->tile_height = 0; + + /* Open the file */ + fp = fopen(filename, "rb"); + if (fp == NULL) goto error; + + /* Check for PNG format */ + memset(header, 0, sizeof(header)); + size = fread(header, 1, sizeof(header), fp); + if (size < sizeof(header)) goto error; + if (png_sig_cmp(header, 0, sizeof(header)) != 0) goto error; + + /* Create read info structures */ + read_png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, + NULL, NULL); + if (read_png_ptr == NULL) goto error; + if (setjmp(png_jmpbuf(read_png_ptr)) != 0) goto error; + read_info_ptr = png_create_info_struct(read_png_ptr); + read_end_info = png_create_info_struct(read_png_ptr); + + /* Link the file we opened to the read info */ + png_init_io(read_png_ptr, fp); + png_set_sig_bytes(read_png_ptr, sizeof(header)); + + /* Read the image */ + png_read_png(read_png_ptr, read_info_ptr, + PNG_TRANSFORM_PACKING | PNG_TRANSFORM_STRIP_16, NULL); + + pixels = png_get_rows(read_png_ptr, read_info_ptr); + image->width = png_get_image_width(read_png_ptr, read_info_ptr); + image->height = png_get_image_height(read_png_ptr, read_info_ptr); + color_type = png_get_color_type(read_png_ptr, read_info_ptr); + + /* Read the palette, if there is one */ + if (color_type & PNG_COLOR_MASK_PALETTE) { + png_colorp palette = NULL; + png_bytep trans_alpha; + int num_trans; + + png_get_PLTE(read_png_ptr, read_info_ptr, &palette, &palette_size); + for (i = 0; i < 256; ++i) { + image->palette[i].r = palette[i].red; + image->palette[i].g = palette[i].green; + image->palette[i].b = palette[i].blue; + image->palette[i].a = 255; + } + if (png_get_tRNS(read_png_ptr, read_info_ptr, &trans_alpha, &num_trans, + NULL) != 0) { + for (i = 0; i < num_trans; ++i) { + image->palette[i].a = trans_alpha[i]; + } + } + } + + /* Allocate pixel area; watch out for overflow */ + num_pixels = (size_t) image->width * (size_t) image->height; + if (num_pixels / image->width != image->height) goto error; /* overflow */ + size = num_pixels * sizeof(image->pixels[0]); + if (size / sizeof(image->pixels[0]) != num_pixels) goto error; /* overflow */ + image->pixels = (struct Pixel *) alloc(size); + if (color_type & PNG_COLOR_MASK_PALETTE) { + image->indexes = (unsigned char *) alloc(num_pixels); + } + + /* Convert the pixels */ + for (y = 0; y < image->height; ++y) { + png_bytep png_row = pixels[y]; + size_t index = y * image->width; + for (x = 0; x < image->width; ++x) { + if (color_type & PNG_COLOR_MASK_PALETTE) { + png_byte b = *png_row++; + image->indexes[index] = b; + image->pixels[index] = image->palette[b]; + } else { + if (color_type & PNG_COLOR_MASK_COLOR) { + image->pixels[index].r = *png_row++; + image->pixels[index].g = *png_row++; + image->pixels[index].b = *png_row++; + } else { + image->pixels[index].r = *png_row++; + image->pixels[index].g = image->pixels[index].r; + image->pixels[index].b = image->pixels[index].r; + } + if (color_type & PNG_COLOR_MASK_ALPHA) { + image->pixels[index].a = *png_row++; + } else { + image->pixels[index].a = 255; + } + } + ++index; + } + } + + /* Look for the tile information */ + png_get_text(read_png_ptr, read_info_ptr, &text_chunks, &num_text_chunks); + for (i = 0; i < num_text_chunks; ++i) { + if (strcmp(text_chunks[i].key, "NH_image_desc") == 0) { + image->image_desc = (char *) alloc(text_chunks[i].text_length + 1); + memcpy(image->image_desc, text_chunks[i].text, text_chunks[i].text_length); + text_chunks[i].text[text_chunks[i].text_length] = '\0'; + } + } + + png_destroy_read_struct(&read_png_ptr, &read_info_ptr, &read_end_info); + return 1; + +error: + if (read_png_ptr) { + png_destroy_read_struct(&read_png_ptr, &read_info_ptr, &read_end_info); + } + free(image->indexes); + image->indexes = NULL; + free(image->pixels); + image->pixels = NULL; + free(image->image_desc); + image->image_desc = NULL; + return 0; +} + +#endif From f3e0dc49b89b9e14c15abc6bc9c68305f7f1de8a Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Mon, 24 Aug 2026 04:15:34 -0400 Subject: [PATCH 672/702] Adjust screen height to allow for a task bar --- win/X11/winX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/X11/winX.c b/win/X11/winX.c index 507cd138e..e66172f5b 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -2792,7 +2792,7 @@ init_standard_windows(void) * Resize to at most full-screen. */ { -#define TITLEBAR_SPACE 18 /* Leave SOME screen for window decorations */ +#define TITLEBAR_SPACE 100 /* Leave SOME screen for window decorations and task bar */ int screen_width = WidthOfScreen(XtScreen(wp->w)); int screen_height = HeightOfScreen(XtScreen(wp->w)) - TITLEBAR_SPACE; From 15a017c030ceb4b7c8ef78a40351142d17cdca54 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 24 Aug 2026 21:56:18 -0400 Subject: [PATCH 673/702] fix undead corpses being edible now In 3.6.x, zombie corpses were always aged an extra 100: NetHack/src/mon.c Line 375 in 23d331a obj->age -= 100; /* this is an *OLD* corpse */ in 5.0.x, zombie corpses are always aged TAINT_AGE, which is only 50: NetHack/src/mon.c Line 648 in 97a6c13 obj->age -= (TAINT_AGE + 1); /* this is an *OLD* corpse */ This is the result of commit 408321b. The accompanying comment states that the purpose of that patch was meant to just replace hard-coded numbers with symbolic values, but the commit set two differing numeric values to the same symbol name, thus causing the regression reported in: https://github.com/NetHack/NetHack/issues/1664 Revert the values to match those of 3.6, and add the additional symbolic value. Closes #1664 --- doc/fixes5-0-1.txt | 1 + include/hack.h | 3 ++- src/mklev.c | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 6e1c22cc1..3ae31483f 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -87,6 +87,7 @@ upon return to a level, catch up on remaining nutrition value by the same percentage as the catch up for the weight after polymorph or revival from corpse, monsters were not interacting with the terrain until that monster's next move +fix undead corpses (zombies, etc.) now being edible Platform- and/or Interface-Specific Fixes diff --git a/include/hack.h b/include/hack.h index a7c28315d..cc7a0e5b5 100644 --- a/include/hack.h +++ b/include/hack.h @@ -1417,7 +1417,8 @@ typedef uint32_t mmflags_nht; /* makemon MM_ flags */ #define HEALTHY_TIN (-3) /* Corpse aging */ -#define TAINT_AGE (50L) /* age when corpses go bad */ +#define INEDIBLE_AGE (50L) /* age when corpses go bad */ +#define TAINT_AGE (100L) /* This was the 3.6 value */ #define TROLL_REVIVE_CHANCE 37 /* 1/37 chance for 50 turns ~ 75% chance */ #define ROT_AGE (250L) /* age when corpses rot away */ diff --git a/src/mklev.c b/src/mklev.c index c3d7a8a54..210dd90ce 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -1934,7 +1934,7 @@ mktrap_victim(struct trap *ttmp) if (victim_mnum == PM_HUMAN && rn2(25)) victim_mnum = rn1(PM_WIZARD - PM_ARCHEOLOGIST, PM_ARCHEOLOGIST); otmp = mkcorpstat(CORPSE, NULL, &mons[victim_mnum], x, y, CORPSTAT_INIT); - otmp->age -= (TAINT_AGE + 1); /* died too long ago to safely eat */ + otmp->age -= (INEDIBLE_AGE + 1); /* died too long ago to safely eat */ } /* pick a random trap type, return NO_TRAP if "too hard" */ From ebe14f87d91e65231e58e03e8896b407cf7fb854 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 26 Aug 2026 10:22:46 -0400 Subject: [PATCH 674/702] corpse age comment cleanup --- include/hack.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/hack.h b/include/hack.h index cc7a0e5b5..3a6cc96c2 100644 --- a/include/hack.h +++ b/include/hack.h @@ -1417,10 +1417,10 @@ typedef uint32_t mmflags_nht; /* makemon MM_ flags */ #define HEALTHY_TIN (-3) /* Corpse aging */ -#define INEDIBLE_AGE (50L) /* age when corpses go bad */ -#define TAINT_AGE (100L) /* This was the 3.6 value */ +#define INEDIBLE_AGE (50L) /* age when corpse becomes unsafe to eat */ +#define TAINT_AGE (100L) /* age when corpse becomes tainted */ +#define ROT_AGE (250L) /* age when corpse rots away */ #define TROLL_REVIVE_CHANCE 37 /* 1/37 chance for 50 turns ~ 75% chance */ -#define ROT_AGE (250L) /* age when corpses rot away */ /* Some misc definitions */ #define POTION_OCCUPANT_CHANCE(n) (13 + 2 * (n)) From d9194cb4dfe4138ca4e1aa3b820afc24b5a6d594 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Thu, 27 Aug 2026 18:10:26 -0400 Subject: [PATCH 675/702] Make hero visible at start Scroll to make the hero visible when starting and when the main window is resized. --- win/X11/winmap.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/win/X11/winmap.c b/win/X11/winmap.c index be7fbcfdc..0d2c6b709 100644 --- a/win/X11/winmap.c +++ b/win/X11/winmap.c @@ -90,6 +90,7 @@ static void set_button_values(Widget, int, int, unsigned); static void map_check_size_change(struct xwindow *); static void map_update(struct xwindow *, int, int, int, int, boolean); static void init_text(struct xwindow *); +static void report_callback(Widget, XtPointer, XtPointer); static void map_exposed(Widget, XtPointer, XtPointer); static void set_gc(Widget, Font, const char *, Pixel, GC *, GC *); static void map_all_unexplored(struct map_info_t *); @@ -1420,6 +1421,21 @@ set_button_values(Widget w, int x, int y, unsigned int button) click_button = (button == Button1) ? CLICK_1 : CLICK_2; } +/* This ensures that the cursor is visible when we first see the map */ +static void +report_callback(Widget w, XtPointer client_data, + XtPointer widget_data) +{ + nhUse(w); + XawPannerReport *report = (XawPannerReport *) widget_data; + if (report->changed & (XawPRSliderWidth | XawPRSliderHeight)) { + struct xwindow *wp = (struct xwindow *) client_data; + if (wp->map_information != NULL) { + check_cursor_visibility(wp); + } + } +} + /* * Map window expose callback. */ @@ -1990,6 +2006,7 @@ create_map_window( num_args); /* number of values to set */ XtAddCallback(map, XtNexposeCallback, map_exposed, (XtPointer) 0); + XtAddCallback(viewport, XtNreportCallback, report_callback, wp); map_info = wp->map_information = (struct map_info_t *) alloc(sizeof (struct map_info_t)); From 988eaa44b442e788e72cc3a557d0ec5dea0914d7 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 28 Aug 2026 10:46:50 -0400 Subject: [PATCH 676/702] relocate declaration of sounddir It shouldn't have been located inside an #ifdef USER_SOUNDS block. --- src/sounds.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sounds.c b/src/sounds.c index 4fcd1c9de..999574562 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1538,6 +1538,8 @@ tiphat(void) return res; } +char *sounddir = 0; /* set in files.c */ + #ifdef USER_SOUNDS typedef struct audio_mapping_rec { @@ -1551,7 +1553,6 @@ typedef struct audio_mapping_rec { static audio_mapping *soundmap = 0; static audio_mapping *sound_matches_message(const char *); -char *sounddir = 0; /* set in files.c */ /* adds a sound file mapping, returns 0 on failure, 1 on success */ int From 845be15439293cf80c97827baf2980961dccee36 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 28 Aug 2026 11:19:00 -0400 Subject: [PATCH 677/702] follow-up: stale comment removed altogether The external reference was moved out of files.c elsewhere, so the comment was no longer accurate. --- src/sounds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sounds.c b/src/sounds.c index 999574562..224eeb5b3 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1538,7 +1538,7 @@ tiphat(void) return res; } -char *sounddir = 0; /* set in files.c */ +char *sounddir = 0; #ifdef USER_SOUNDS From 9c8b8249eb683e126a009d5e06072c54d3f3171e Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 30 Aug 2026 09:59:10 -0400 Subject: [PATCH 678/702] Linux build doc and a comment update --- sys/unix/Makefile.src | 2 +- sys/unix/Makefile.utl | 2 +- sys/unix/NewInstall.unx | 145 ++++++++++++++++++++-------------------- 3 files changed, 73 insertions(+), 76 deletions(-) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index cb669d80d..ea065d710 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -153,7 +153,7 @@ SYSOBJ ?= $(TARGETPFX)ioctl.o $(TARGETPFX)unixmain.o $(TARGETPFX)unixtty.o \ # flags for Linux # compile normally # CFLAGS = -O2 -fomit-frame-pointer -I../include -# LFLAGS = -L/usr/X11R6/lib +# LFLAGS = -L/usr/lib64 # OR compile backwards compatible a.out format # CFLAGS = -O2 -b i486-linuxaout -fomit-frame-pointer -I../include # LFLAGS = -b i486-linuxaout -L/usr/X11R6/lib diff --git a/sys/unix/Makefile.utl b/sys/unix/Makefile.utl index 4370ad61d..2bb835766 100644 --- a/sys/unix/Makefile.utl +++ b/sys/unix/Makefile.utl @@ -89,7 +89,7 @@ SRCDIR = $(NHSROOT)/src # flags for Linux # compile normally # CFLAGS = -O2 -fomit-frame-pointer -I../include -# LFLAGS = -L/usr/X11R6/lib +# LFLAGS = -L/usr/lib64 # OR compile backwards compatible a.out format # CFLAGS = -O2 -b i486-linuxaout -fomit-frame-pointer -I../include # LFLAGS = -b i486-linuxaout -L/usr/X11R6/lib diff --git a/sys/unix/NewInstall.unx b/sys/unix/NewInstall.unx index 538b18497..f4a3e8f4d 100644 --- a/sys/unix/NewInstall.unx +++ b/sys/unix/NewInstall.unx @@ -83,80 +83,77 @@ Note that curses, X11, and Qt will almost certainly require the installation of prerequisite packages in order to successfully build with support for additional interfaces. See below. -+----------+-------+-----------------+--------------------------------------+ -| Platform |Interf.| Build Variable | Prerequisite package | -|----------+-------+-----------------+--------------------------------------| -| MacOS | tty | WANT_WIN_TTY | none | -|----------+-------+-----------------+--------------------------------------| -| MacOS | curses| WANT_WIN_CURSES | ncurses development libraries | -|----------+-------+-----------------+--------------------------------------| -| MacOS | X11 | WANT_WIN_X11 | You will need to obtain and | -| | | | install XQuartz if you want X11 | -| | | | support in your build. | -| | | | (Attempting to run X11.app will | -| | | | describe where to get it) | -| | | | | -| | | | One possible way: | -| | | | brew install xquartz | -| | | | brew install libxft | -| | | | brew install fontconfig | -| | | | brew install freetype | -|----------+-------+-----------------+--------------------------------------| -| MacOS | Qt | WANT_WIN_QT | You will need to obtain and | -| | | | install Qt if you want Qt | -| | | | support in your build. | -| | | | | -| | | | One possible way: | -| | | | brew install pkg-config | -| | | | brew install Qt6 | -|----------+-------+-----------------+--------------------------------------| -| Linux | tty | WANT_WIN_TTY | | -| (Ubuntu) | | | | -|----------+-------+-----------------+--------------------------------------| -| Linux | curses|WANT_WIN_CURSES=1| If it isn't already included | -| (Ubuntu) | | | in your distribution, here is one | -| | | | possible way: | -| | | | | -| | | | sudo apt-get install libncurses-dev | -|----------+-------+-----------------+--------------------------------------| -| Linux | X11 | WANT_WIN_X11=1 | Here is one possible way to obtain | -| (Ubuntu) | | | the required packages: | -| | | | | -| | | |sudo apt-get install libx11-dev | -| | | |sudo apt-get install libmotif-dev | -| | | |sudo apt-get install libxaw7-dev | -| | | |sudo apt install xfonts-utils | -| | | |(That last one is for bdftopcf and | -| | | | mkfontdir utils) | -| | | | | -|----------+-------+-----------------+--------------------------------------| -| Linux | Qt5 | WANT_WIN_QT=1 | Here is one possible way to obtain | -| (Ubuntu) | | | the required packages: | -| | | | | -| | | |sudo apt-get install qtbase5-dev | -| | | |sudo apt-get install qtmultimedia5-dev| -| | | | | -| | | |Another odd note about Qt on Linux is | -| | | |that if you find you are getting the | -| | | |following error trying to run NetHack | -| | | |after you build it with Qt support: | -| | | |"error while loading shared | -| | | |libraries: libQt5Core.so.5: cannot | -| | | |open shared object file: No such file | -| | | |or directory", | -| | | |you may have to fix that (one-time) | -| | | |by issuing the command below: | -| | | | | -| sudo strip \ | -| --remove-section=.note.ABI-tag/usr/lib/x86_64-linux-gnu/libQt5Core.so.5 | -|----------+-------+-----------------+--------------------------------------| -| Linux | Qt6 | WANT_WIN_QT6=1 | Here is one possible way to obtain | -| (Ubuntu) | | | the required packages: | -| | | | | -| | | |sudo apt-get install qt6-base-dev | -| | | |sudo apt-get install \ | -| | | | qt6-multimedia-dev | -+----------+-------+-----------------+--------------------------------------+ ++----------+-------+------------------+-------------------------------------+ +| Platform |Interf.| make variable | Prerequisite package | +|----------+-------+------------------+-------------------------------------| +| MacOS | tty | WANT_WIN_TTY=1 | none | +|----------+-------+------------------+-------------------------------------| +| MacOS | curses| WANT_WIN_CURSES=1| ncurses development libraries | +|----------+-------+------------------+-------------------------------------| +| MacOS | X11 | WANT_WIN_X11=1 | You will need to obtain and | +| | | | install XQuartz if you want X11 | +| | | | support in your build. | +| | | | (Attempting to run X11.app will | +| | | | describe where to get it) | +| | | | | +| | | | One possible way: | +| | | | brew install xquartz | +| | | | brew install libxft | +| | | | brew install fontconfig | +| | | | brew install freetype | +|----------+-------+------------------+-------------------------------------| +| MacOS | Qt | WANT_WIN_QT=1 | You will need to obtain and | +| | | | install Qt if you want Qt | +| | | | support in your build. | +| | | | | +| | | | One possible way: | +| | | | brew install pkg-config | +| | | | brew install Qt6 | +|----------+-------+------------------+-------------------------------------| +| Linux | tty | WANT_WIN_TTY=1 | sudo apt install libncurses-dev | +| (Ubuntu) | | | | +|----------+-------+------------------+-------------------------------------| +| Linux | tty | WANT_WIN_TTY=1 | sudo dnf install make gcc g++ | +| (Fedora) | | | sudo dnf install ncurses-devel | +|----------+-------+------------------+-------------------------------------| +| Linux | curses|WANT_WIN_CURSES=1 | If it isn't already included | +| (Ubuntu) | | | in your distribution, here is one | +| | | | possible way: | +| | | | | +| | | | sudo apt install libncurses-dev | +|----------+-------+------------------+-------------------------------------| +| Linux | X11 | WANT_WIN_X11=1 | Here is one possible way to obtain | +| (Ubuntu) | | | the required packages: | +| | | | | +| | | | sudo apt install libx11-dev | +| | | | sudo apt install libmotif-dev | +| | | | sudo apt install libxaw7-dev | +| | | | sudo apt install xfonts-utils | +| | | | (That last one is for bdftopcf | +| | | | and mkfontdir utils) | +| | | | | +|----------+-------+------------------+-------------------------------------| +| Linux | X11 | WANT_WIN_X11=1 | Here is a possible way to obtain | +|(Fedora) | | | all prerequisite packages required | +| | | | (in addition to those needed for | +| | | | tty above) on a fresh installation | +| | | | of Fedora 44 workstation: | +| | | | | +| | | | sudo dnf install libX11-devel | +| | | | sudo dnf install libXt-devel | +| | | | sudo dnf install libXaw | +| | | | sudo dnf install libXaw-devel | +| | | | sudo dnf install libXft-devel | +| | | | sudo dnf install xorg-x11-font-utils| +| | | | sudo dnf install mkfontscale | +| | | | | +|----------+-------+------------------+-------------------------------------| +| Linux | Qt | WANT_WIN_QT=1 | Here is one possible way to obtain | +| (Ubuntu) | | | the required packages: | +| | | | | +| | | |sudo apt install qt6-base-dev | +| | | |sudo apt install qt6-multimedia-dev | ++----------+-------+------------------+-------------------------------------+ There are other hints file options that are meant to impact your NetHack build in various other ways too. A reference list can be found in From 1b752f0e114e6f8de1e6d3569cbd1a760fad553d Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 30 Aug 2026 10:29:53 -0400 Subject: [PATCH 679/702] follow-up --- sys/unix/NewInstall.unx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/unix/NewInstall.unx b/sys/unix/NewInstall.unx index f4a3e8f4d..e6b276e91 100644 --- a/sys/unix/NewInstall.unx +++ b/sys/unix/NewInstall.unx @@ -148,7 +148,7 @@ additional interfaces. See below. | | | | sudo dnf install mkfontscale | | | | | | |----------+-------+------------------+-------------------------------------| -| Linux | Qt | WANT_WIN_QT=1 | Here is one possible way to obtain | +| Linux | Qt | WANT_WIN_QT6=1 | Here is one possible way to obtain | | (Ubuntu) | | | the required packages: | | | | | | | | | |sudo apt install qt6-base-dev | From 564affea88cd7653b6e336501e123d863b6d07fe Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sun, 30 Aug 2026 15:52:15 -0400 Subject: [PATCH 680/702] Remove limit in size of widget_table It is difficult, but possible, to exceed 1024 widgets. One way is to set a very large Unicode symbol set, and then use #wizcustom. As there is no limit to how many objects can occupy a square, this limit is a possible hazard even to a normal game. --- win/X11/winlabel.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/win/X11/winlabel.c b/win/X11/winlabel.c index 2f9e5e68c..f8e99510c 100644 --- a/win/X11/winlabel.c +++ b/win/X11/winlabel.c @@ -610,9 +610,9 @@ typedef struct WidgetBucket { WidgetData *data; } WidgetBucket; -#define MAX_WIDGETS 1024 -static WidgetBucket widget_table[MAX_WIDGETS]; -static unsigned num_widgets; +static WidgetBucket *widget_table = NULL; +static unsigned num_widgets = 0; +static unsigned max_widgets = 0; /* bsearch compare function to search widget-table */ static int @@ -653,9 +653,12 @@ get_widget_data(Widget w) static WidgetData * add_widget(Widget w) { - /* Panic rather than overflow the array */ - if (num_widgets >= MAX_WIDGETS) { - panic("Widget table is full\n"); + /* If the array is full (or unallocated), add some new space to it */ + if (num_widgets >= max_widgets) { + max_widgets = num_widgets + 1024; + widget_table = (WidgetBucket *) re_alloc( + (long *) widget_table, + max_widgets * sizeof(widget_table[0])); } /* Insert the widget into the table, maintaining its order */ @@ -688,7 +691,7 @@ delete_widget(Widget w) /* Remove the widget from the table */ for (unsigned i = (unsigned)(bucket - widget_table); - i + 1 < MAX_WIDGETS; + i + 1 < num_widgets; ++i) { widget_table[i] = widget_table[i+1]; } From c88403f4ecd3699dbc080b4f2474afd7818ffdb7 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sun, 30 Aug 2026 16:44:26 -0400 Subject: [PATCH 681/702] Correct display of tabified PICK_NONE menu --- win/X11/winmenu.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index e8d0eead2..4d0c71c2f 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -1320,12 +1320,10 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu) /* Does any line have a selector? */ boolean any_canpick = FALSE; - if (how != PICK_NONE) { - for (curr = curr_menu->base; curr; curr = curr->next) { - if (curr->identifier.a_void != NULL) { - any_canpick = TRUE; - break; - } + for (curr = curr_menu->base; curr; curr = curr->next) { + if (curr->identifier.a_void != NULL) { + any_canpick = TRUE; + break; } } @@ -1342,7 +1340,7 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu) String str = (String) curr->str; int attr = ATR_NONE; int color = NO_COLOR; - boolean canpick = (how != PICK_NONE && curr->identifier.a_void); + boolean canpick = curr->identifier.a_void != NULL; /* Add tabs if needed to align non-selector lines with selector lines */ if (any_canpick && !canpick) { From 98815bc7390ae4b494eb4d08f9850ce069440e0a Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sun, 30 Aug 2026 16:44:44 -0400 Subject: [PATCH 682/702] Tabify the #wizcustom menu --- src/wizcmds.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/wizcmds.c b/src/wizcmds.c index fd0568120..41b49da8d 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -1952,9 +1952,11 @@ wiz_custom(void) win = create_nhwindow(NHW_MENU); start_menu(win, MENU_BEHAVE_STANDARD); - add_menu_heading(win, - " glyph glyph identifier " - " sym clr customcolor unicode utf8"); + const char *heading = iflags.menu_tab_sep + ? "glyph\tglyph identifier\tsym\tclr\tcustomcolor\tunicode\tutf8" + : " glyph glyph identifier " + " sym clr customcolor unicode utf8"; + add_menu_heading(win, heading); Sprintf(bufa, "%s: colorcount=%ld %s", wizcustom, (long) iflags.colorcount, gs.symset[PRIMARYSET].name ? gs.symset[PRIMARYSET].name @@ -2001,26 +2003,35 @@ wizcustom_callback(winid win, int glyphnum, char *id) cgm->u || #endif cgm->customcolor != 0) { - Sprintf(bufa, "[%04d] %-44s", glyphnum, id); - Sprintf(bufb, "'\\%03d' %02d", - gs.showsyms[cgm->sym.symidx], cgm->sym.color); - Sprintf(bufc, "%011lx", (unsigned long) cgm->customcolor); + if (iflags.menu_tab_sep) { + Sprintf(bufa, "[%04d]\t%s\t", glyphnum, id); + Sprintf(bufb, "'\\%03d'\t%02d\t", + gs.showsyms[cgm->sym.symidx], cgm->sym.color); + Sprintf(bufc, "%011lx\t", (unsigned long) cgm->customcolor); + } else { + Sprintf(bufa, "[%04d] %-45s", glyphnum, id); + Sprintf(bufb, "'\\%03d' %02d ", + gs.showsyms[cgm->sym.symidx], cgm->sym.color); + Sprintf(bufc, "%011lx ", (unsigned long) cgm->customcolor); + } bufu[0] = '\0'; #ifdef ENHANCED_SYMBOLS if (cgm->u && cgm->u->utf8str) { uint8 *cp; + char sep = iflags.menu_tab_sep ? '\t' : ' '; Sprintf(bufu, "U+%04lx", (unsigned long) cgm->u->utf32ch); cp = cgm->u->utf8str; while (*cp) { char bufd[BUFSZ]; - Sprintf(bufd, " <%d>", (int) *cp); + Sprintf(bufd, "%c<%d>", sep, (int) *cp); Strcat(bufu, bufd); cp++; + sep = ' '; } } #endif any.a_int = glyphnum + 1; /* avoid 0 */ - Snprintf(buf, sizeof buf, "%s %s %s %s", bufa, bufb, bufc, bufu); + Snprintf(buf, sizeof buf, "%s%s%s%s", bufa, bufb, bufc, bufu); add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE, clr, buf, MENU_ITEMFLAGS_NONE); } From 393130a6293584807cb5e494d833d089dcfcc121 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sun, 30 Aug 2026 17:51:10 -0400 Subject: [PATCH 683/702] Handle tabs in the message window --- win/X11/winmesg.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/win/X11/winmesg.c b/win/X11/winmesg.c index ed172c4f8..1678e5da7 100644 --- a/win/X11/winmesg.c +++ b/win/X11/winmesg.c @@ -520,16 +520,42 @@ redraw_message_window(struct xwindow *wp) for (y_base = row = 0, curr = mesg_info->head; row < mesg_info->num_lines; row++, y_base += mesg_info->char_height, curr = curr->next) { -#ifdef USE_XFT - if (curr->line != NULL) { - XftDrawString8(draw, &fgcolor, font, - mesg_info->char_lbearing, mesg_info->char_ascent + y_base, - (const FcChar8 *) curr->line, curr->str_length); + if (curr->line == NULL) { + continue; } + /* Deal with any tabs in the output. These will just be single strings, + * not needing to align columns, so just convert to spaces */ + const char *str = curr->line; + int str_length = curr->str_length; + char buf[BUFSZ]; + if (memchr(str, '\t', str_length) != NULL) { + int i2 = 0; + for (int i1 = 0; i1 < str_length; ++i1) { + if (str[i1] == '\t') { + if (i2 + 4 > BUFSZ) { + break; + } + memcpy(buf + i2, " ", 4); + i2 += 4; + } else { + if (i2 >= BUFSZ) { + break; + } + buf[i2++] = str[i1]; + } + } + /* buf does not need to be null terminated */ + str = buf; + str_length = i2; + } +#ifdef USE_XFT + XftDrawString8(draw, &fgcolor, font, + mesg_info->char_lbearing, mesg_info->char_ascent + y_base, + (const FcChar8 *) str, str_length); #else /* !USE_XFT */ XDrawString(XtDisplay(wp->w), XtWindow(wp->w), mesg_info->gc, mesg_info->char_lbearing, mesg_info->char_ascent + y_base, - curr->line, curr->str_length); + str, str_length); #endif /* ?USE_XFT */ /* * This draws a line at the _top_ of the line of text pointed to by From 2f42bd7e2752730b9580da7dc441943b8561742a Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sun, 30 Aug 2026 19:03:45 -0400 Subject: [PATCH 684/702] Display tabs in the text window Actually a menu, but menu windows convert to text if only displaying text. --- win/X11/winlabel.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++ win/X11/wintext.c | 4 +-- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/win/X11/winlabel.c b/win/X11/winlabel.c index f8e99510c..5842ef49f 100644 --- a/win/X11/winlabel.c +++ b/win/X11/winlabel.c @@ -54,6 +54,7 @@ enum { font_bold = 1, font_italic = 2 }; static boolean check_label(Widget); static void delete_callback(Widget, XtPointer, XtPointer); static void update_label(Widget, WidgetData *); +static void set_tab_stops(Widget, WidgetData *, const char *); static void allocate_font(Widget, WidgetData *, unsigned); static void free_fonts(Widget, WidgetData *); @@ -242,6 +243,11 @@ update_label(Widget w, WidgetData *data) attrs |= HL_DIM; } + /* Set the tab stops if needed */ + if (data->columns == NULL && strchr(label, '\t') != NULL) { + set_tab_stops(w, data, label); + } + /* Dimensions of pixmap */ Dimension width; Dimension height; @@ -496,6 +502,66 @@ update_label(Widget w, WidgetData *data) data->pixmap = new_pixmap; } +/* Set tab stops for text window */ +static void +set_tab_stops(Widget w, WidgetData *data, const char *label) +{ + /* Count columns */ + unsigned col = 0; + unsigned num_cols = 0; + size_t i = 0; + while (label[i] != '\0') { + size_t len = strcspn(label + i, "\t\n"); + ++col; + i += len; + if (label[i] != '\t') { + /* The last column on its line */ + num_cols = max(num_cols, col); + col = 0; + } + if (label[i] != '\0') { + ++i; + } + } + + int *columns = (int *) alloc(num_cols * sizeof(columns[0])); + memset(columns, 0, num_cols * sizeof(columns[0])); + + /* Determine column sizes */ + col = 0; + i = 0; + Display *display = XtDisplay(w); + while (label[i] != '\0') { + size_t len = strcspn(label + i, "\t\n"); + if (label[i+len] == '\t') { + /* A column from label+i to label+i+len */ + int width = X11_column_width(display, data->font[0], label + i, len); + columns[col] = max(columns[col], width); + ++col; + } else { + /* Last column of the line */ + /* This does not participate in sizing the column */ + col = 0; + } + i += len; + if (label[i] != '\0') { + ++i; + } + } + + /* Convert to column positions */ + int pos = 0; + for (unsigned j = 0; j < num_cols; ++j) { + int rpos = pos + columns[j]; + columns[j] = pos; + pos = rpos; + } + + free(data->columns); + data->columns = columns; + data->num_cols = num_cols; +} + /* Allocate a bold or italic font */ static void allocate_font(Widget w, WidgetData *data, unsigned font_idx) diff --git a/win/X11/wintext.c b/win/X11/wintext.c index ee6247029..a80b6540d 100644 --- a/win/X11/wintext.c +++ b/win/X11/wintext.c @@ -170,7 +170,7 @@ display_text_window(struct xwindow *wp, boolean blocking) XtSetArg(args[num_args], XtNlabel, text_info->text.text); num_args++; XtSetValues(wp->w, args, num_args); - X11_update_label_if_Xft(wp->w); + X11_update_label(wp->w); #ifdef TRANSIENT_TEXT XtRealizeWidget(wp->popup); @@ -259,7 +259,7 @@ create_text_window(struct xwindow *wp) form, /* parent widget */ args, /* set some values */ num_args); /* number of values to set */ - X11_wrap_widget_if_Xft(wp->w, NHW_TEXT); + X11_wrap_widget(wp->w, NHW_TEXT); } void From cc4768f1c9cbc288bf47c6ea807bdb191e25bc34 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 1 Sep 2026 13:38:05 -0400 Subject: [PATCH 685/702] adjust some Makefile dependencies Reported by @benknoble in https://github.com/NetHack/NetHack/issues/1669 Some undeclared dependencies could arise when building with make --shuffle This attempts to resolve those. --- sys/unix/Makefile.dat | 2 + sys/unix/Makefile.src | 10 +++-- sys/unix/Makefile.utl | 58 +++++++++++++++-------------- sys/unix/hints/include/response.500 | 2 +- 4 files changed, 40 insertions(+), 32 deletions(-) diff --git a/sys/unix/Makefile.dat b/sys/unix/Makefile.dat index a339fa307..982e55e9f 100644 --- a/sys/unix/Makefile.dat +++ b/sys/unix/Makefile.dat @@ -95,6 +95,8 @@ GEM_RSC.RSC: # cp ../win/gem/GEM_RSC.RSC GEM_RSC.RSC $(UUDECODE) ../win/gem/gem_rsc.uu +nhdat: $(DATDLB) + ( LC_ALL=C ; ../util/dlb cf nhdat $(DATDLB) ) data: data.base ../util/makedefs ../util/makedefs -d diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index ea065d710..9de766166 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -642,8 +642,10 @@ DATE_O = $(TARGETPFX)date.o all: $(GAME) @echo "" -create_responsefiles: +../src/nethack_cc.rsp: echo $(CC_COMPILER_SWITCHES) >$(CC_RESPONSEFILE) + +../src/nethack_cxx.rsp: echo $(CXX_COMPILER_SWITCHES) >$(CXX_RESPONSEFILE) pregame: $(RESPONSEFILES) @@ -752,7 +754,7 @@ qt3tableview.moc: ../win/Qt3/qt3tableview.h $(QTDIR)/bin/moc -o qt3tableview.moc ../win/Qt3/qt3tableview.h # build monst.o and objects.o before executing '$(MAKE) makedefs' -$(MAKEDEFS): $(FIRSTOBJ) \ +$(MAKEDEFS): $(RESPONSEFILES) $(FIRSTOBJ) \ ../util/makedefs.c ../src/mdlib.c $(CONFIG_H) \ ../include/permonst.h ../include/monsters.h \ ../include/objclass.h ../include/objects.h ../include/sym.h \ @@ -770,7 +772,7 @@ $(MAKEDEFS): $(FIRSTOBJ) \ @( cd ../util ; $(MAKE) ../include/pm.h ) # Created at build time for configurations which support tiles, # but not by makedefs so not connected to the others. -../src/tile.c: ../win/share/tilemap.c $(HACK_H) +../src/tile.c: $(RESPONSEFILES) ../win/share/tilemap.c $(HACK_H) @( cd ../util ; $(MAKE) ../src/tile.c ) # @@ -799,7 +801,7 @@ $(TARGETPFX)date.o: date.c $(GENTILECFILE) $(HACK_H) $(HACKCSRC) $(HOBJ) $(TARG # Do NOT include ../dat/gitinfo.txt as either a prerequisite or target. # 'makedefs -v' processes it when present and ignores it if not. # -../include/date.h: ../util/makedefs $(VERSOURCES) $(HACK_H) +../include/date.h: $(RESPONSEFILES) ../util/makedefs $(VERSOURCES) $(HACK_H) -$(SHELL) ../sys/unix/gitinfo.sh $(GITINFO) #before 'makedefs -v' ../util/makedefs -v diff --git a/sys/unix/Makefile.utl b/sys/unix/Makefile.utl index 2bb835766..fb8f32c8c 100644 --- a/sys/unix/Makefile.utl +++ b/sys/unix/Makefile.utl @@ -144,6 +144,8 @@ QUIETCC=0 CLINK=$(CC) CXXLINK=$(CXX) +CCRESP=$(CC_RESPONSEFILE) + # ---------------------------------------- # # Nothing below this line should have to be changed. @@ -234,7 +236,7 @@ TARGET_AR ?= $(AR) # # dependencies for makedefs # -makedefs: $(HACKLIB) $(MAKEOBJS) mdgrep.h +makedefs: $(CCRESP) $(HACKLIB) $(MAKEOBJS) mdgrep.h $(CLINK) $(LFLAGS) -o makedefs $(MAKEOBJS) $(HACKLIB) @@ -276,9 +278,11 @@ $(HACKLIB): $(CONFIG_H) $(HACKLIBSRC) panic.o @( cd ../src ; $(MAKE) hacklib.a ) # support code used by several of the utility programs (but not makedefs) -panic.o: panic.c $(CONFIG_H) +panic.o: $(CCRESP) panic.c $(CONFIG_H) $(CC) $(CFLAGS) $(CSTD) -c panic.c -o $@ +../src/nethack_cc.rsp: + ( cd ../src; $(MAKE) ../src/nethack_cc.rsp ) # with all of extern.h's functions to complain about, we drown in # 'defined but not used' without -u @@ -289,7 +293,7 @@ lintdgn: # dependencies for recover # -recover: $(RECOVOBJS) $(HACKLIB) +recover: $(CCRESP) $(RECOVOBJS) $(HACKLIB) $(CLINK) $(LFLAGS) -o recover \ $(RECOVOBJS) $(HACKLIB) $(LIBS) @@ -325,7 +329,7 @@ SFCTOOLBIN = sfctool SFFLAGS=-DSFCTOOL -DNOPANICTRACE -DNOCRASHREPORT -DNO_CHRONICLE sfutil: $(SFCTOOLBIN) @echo '$(SFCTOOLBIN) is up to date.' -$(SFCTOOLBIN): $(SFCTOOLOBJS) $(HACKLIB) +$(SFCTOOLBIN): $(CCRESP) $(SFCTOOLOBJS) $(HACKLIB) $(TARGET_CLINK) $(TARGET_LFLAGS) -o $@ $(SFCTOOLOBJS) $(HACKLIB) $(TARGET_LIBS) $(TARGETPFX)sfctool.o: sfctool.c $(HACK_H) ../include/sfprocs.h $(TARGET_CC) $(TARGET_CFLAGS) $(SFFLAGS) -o $@ -c sfctool.c @@ -399,7 +403,7 @@ sftags: sftags.o $(HACKLIB) $(TARGETPFX)sf-alloc.o $(TARGETPFX)panic.o $(CLINK) $(LFLAGS) -o $@ sftags.o \ $(TARGETPFX)sf-alloc.o $(TARGETPFX)panic.o \ $(HACKLIB) $(LIBS) -sftags.o: sftags.c $(HACK_H) +sftags.o: $(CCRESP) sftags.c $(HACK_H) $(CC) $(CFLAGS) -c sftags.c ../include/sfproto.h: sf.tags sftags ./sftags @@ -468,13 +472,13 @@ sf.tags: $(CTAGDEP) dlb: $(DLBOBJS) $(HACKLIB) $(CLINK) $(LFLAGS) -o dlb $(DLBOBJS) $(HACKLIB) $(LIBS) -dlb_main.o: dlb_main.c $(CONFIG_H) ../include/dlb.h +dlb_main.o: $(CCRESP) dlb_main.c $(CONFIG_H) ../include/dlb.h $(CC) $(CFLAGS) $(CSTD) -c dlb_main.c -o $@ stripbs: stripbs.o $(CC) $(LFLAGS) -o stripbs stripbs.o -stripbs.o: stripbs.c +stripbs.o: $(CCRESP) stripbs.c $(CC) $(CFLAGS) -c stripbs.c # dependencies for tile utilities @@ -521,38 +525,38 @@ tilemap: tilemap.o $(OBJDIR)/objects.o $(OBJDIR)/monst.o $(OBJDIR)/drawing.o \ ../src/tile.c: tilemap ./tilemap -tiletext.o: ../win/share/tiletext.c $(CONFIG_H) ../win/share/tile.h +tiletext.o: $(CCRESP) ../win/share/tiletext.c $(CONFIG_H) ../win/share/tile.h $(CC) $(CFLAGS) $(NO_WARN_DISCARDED_QUALIFIERS) $(CSTD) -I../win/share -c ../win/share/tiletext.c -o $@ -tiletxt.o: ../win/share/tiletxt.c ../win/share/tilemap.c $(HACK_H) +tiletxt.o: $(CCRESP) ../win/share/tiletxt.c ../win/share/tilemap.c $(HACK_H) $(CC) $(CFLAGS) $(CSTD) -I../win/share -c ../win/share/tiletxt.c -o $@ -tilemap.o: ../win/share/tilemap.c $(HACK_H) +tilemap.o: $(CCRESP) ../win/share/tilemap.c $(HACK_H) $(CC) $(CFLAGS) $(CSTD) -c ../win/share/tilemap.c -o $@ -gifread.o: ../win/share/gifread.c $(CONFIG_H) ../win/share/tile.h +gifread.o: $(CCRESP) ../win/share/gifread.c $(CONFIG_H) ../win/share/tile.h $(CC) $(CFLAGS) $(CSTD) -I../win/share -c ../win/share/gifread.c -o $@ -ppmwrite.o: ../win/share/ppmwrite.c $(CONFIG_H) ../win/share/tile.h +ppmwrite.o: $(CCRESP) ../win/share/ppmwrite.c $(CONFIG_H) ../win/share/tile.h $(CC) $(CFLAGS) $(CSTD) -I../win/share -c ../win/share/ppmwrite.c -o $@ -tile2bmp.o: ../win/share/tile2bmp.c $(HACK_H) ../win/share/tile.h +tile2bmp.o: $(CCRESP) ../win/share/tile2bmp.c $(HACK_H) ../win/share/tile.h $(CC) $(CFLAGS) $(CSTD) -I../win/share -c ../win/share/tile2bmp.c -o $@ -tile2x11.o: ../win/X11/tile2x11.c $(HACK_H) ../win/share/tile.h \ +tile2x11.o: $(CCRESP) ../win/X11/tile2x11.c $(HACK_H) ../win/share/tile.h \ ../include/tile2x11.h $(CC) $(CFLAGS) $(CSTD) -I../win/share -c ../win/X11/tile2x11.c -o $@ -tile2img.o: ../win/gem/tile2img.c $(HACK_H) ../win/share/tile.h \ +tile2img.o: $(CCRESP) ../win/gem/tile2img.c $(HACK_H) ../win/share/tile.h \ ../include/bitmfile.h $(CC) $(CFLAGS) $(CSTD) -I../win/share -c ../win/gem/tile2img.c -o $@ -xpm2img.o: ../win/gem/xpm2img.c $(HACK_H) ../include/bitmfile.h +xpm2img.o: $(CCRESP) ../win/gem/xpm2img.c $(HACK_H) ../include/bitmfile.h $(CC) $(CFLAGS) $(CSTD) -c ../win/gem/xpm2img.c -o $@ -bitmfile.o: ../win/gem/bitmfile.c ../include/bitmfile.h +bitmfile.o: $(CCRESP) ../win/gem/bitmfile.c ../include/bitmfile.h $(CC) $(CFLAGS) $(CSTD) -c ../win/gem/bitmfile.c -o $@ -tile2beos.o: ../win/BeOS/tile2beos.cpp $(HACK_H) ../win/share/tile.h +tile2beos.o: $(CCRESP) ../win/BeOS/tile2beos.cpp $(HACK_H) ../win/share/tile.h $(CXX) $(CFLAGS) $(CSTD) -I../win/share -c ../win/BeOS/tile2beos.cpp -o $@ # note: tileedit.cpp was developed for Qt2 and will not compile using Qt5 -tileedit.o: ../win/Qt/tileedit.cpp +tileedit.o: $(CCRESP) ../win/Qt/tileedit.cpp $(CXX) -I../include -I$(QTDIR)/include ../win/Qt/tileedit.cpp tileedit: tileedit.o $(TEXT_IO) $(QTDIR)/bin/moc -o tileedit.moc tileedit.h @@ -560,7 +564,7 @@ tileedit: tileedit.o $(TEXT_IO) uudecode: uudecode.o $(CLINK) $(LFLAGS) -o uudecode uudecode.o $(LIBS) -uudecode.o: ../sys/share/uudecode.c +uudecode.o: $(CCRESP) ../sys/share/uudecode.c $(CC) $(CFLAGS) $(CSTD) -c -o uudecode.o ../sys/share/uudecode.c # using dependencies like @@ -577,27 +581,27 @@ uudecode.o: ../sys/share/uudecode.c # make sure host object files from src are available when needed # (note: these dependencies have been copied from Makefile.src so only come # indirectly from 'make depend', hence are subject to bit rot as src changes) -$(OBJDIR)/alloc.o: ../src/alloc.c $(CONFIG_H) ../include/nhlua.h +$(OBJDIR)/alloc.o: $(CCRESP) ../src/alloc.c $(CONFIG_H) ../include/nhlua.h $(CC) $(CFLAGS) $(CSTD) -c ../src/alloc.c -o $@ -$(OBJDIR)/drawing.o: ../src/drawing.c $(CONFIG_H) ../include/color.h \ +$(OBJDIR)/drawing.o: $(CCRESP) ../src/drawing.c $(CONFIG_H) ../include/color.h \ ../include/rm.h ../include/objclass.h ../include/defsym.h \ ../include/objects.h ../include/sym.h $(CC) $(CFLAGS) $(CSTD) -c ../src/drawing.c -o $@ -$(OBJDIR)/decl.o: ../src/decl.c $(HACK_H) +$(OBJDIR)/decl.o: $(CCRESP) ../src/decl.c $(HACK_H) $(CC) $(CFLAGS) $(CSTD) -c ../src/decl.c -o $@ -$(OBJDIR)/monst.o: ../src/monst.c $(CONFIG_H) ../include/permonst.h \ +$(OBJDIR)/monst.o: $(CCRESP) ../src/monst.c $(CONFIG_H) ../include/permonst.h \ ../include/align.h ../include/monattk.h ../include/monflag.h \ ../include/monsters.h ../include/wintype.h ../include/sym.h \ ../include/defsym.h ../include/color.h $(CC) $(CFLAGS) $(CSTD) -c ../src/monst.c -o $@ -$(OBJDIR)/objects.o: ../src/objects.c $(CONFIG_H) ../include/obj.h \ +$(OBJDIR)/objects.o: $(CCRESP) ../src/objects.c $(CONFIG_H) ../include/obj.h \ ../include/prop.h ../include/skills.h ../include/color.h \ ../include/objclass.h ../include/defsym.h ../include/objects.h $(CC) $(CFLAGS) $(CSTD) -c ../src/objects.c -o $@ -$(OBJDIR)/dlb.o: ../src/dlb.c $(CONFIG_H) ../include/dlb.h +$(OBJDIR)/dlb.o: $(CCRESP) ../src/dlb.c $(CONFIG_H) ../include/dlb.h $(CC) $(CFLAGS) $(CSTD) -c ../src/dlb.c -o $@ # this differs substantially from what Makefile.src specifies -$(OBJDIR)/date.o: ../src/date.c $(CONFIG_H) +$(OBJDIR)/date.o: $(CCRESP) ../src/date.c $(CONFIG_H) $(CC) $(CFLAGS) $(CSTD) -c ../src/date.c -o $@ ../include/nhlua.h: @( cd .. ; $(MAKE) lua_support ) diff --git a/sys/unix/hints/include/response.500 b/sys/unix/hints/include/response.500 index 0781323e0..24b5d8822 100644 --- a/sys/unix/hints/include/response.500 +++ b/sys/unix/hints/include/response.500 @@ -15,7 +15,6 @@ USE_RESPONSEFILE=1 endif ifeq "$(USE_RESPONSEFILE)" "1" -RESPONSEFILES=create_responsefiles CXXFLAGS = $(CCXXFLAGS) -I. -I$(QTDIR)/include $(QTCXXFLAGS) CC_COMPILER_SWITCHES := $(subst \,\\,$(CFLAGS)) CC_COMPILER_SWITCHES := $(subst ",\",$(CC_COMPILER_SWITCHES)) @@ -23,6 +22,7 @@ CXX_COMPILER_SWITCHES := $(subst \,\\,$(CXXFLAGS)) CXX_COMPILER_SWITCHES := $(subst ",\",$(CXX_COMPILER_SWITCHES)) CC_RESPONSEFILE=../src/nethack_cc.rsp CXX_RESPONSEFILE=../src/nethack_cxx.rsp +RESPONSEFILES=$(CC_RESPONSEFILE) $(CXX_RESPONSEFILE) CFLAGS=@$(CC_RESPONSEFILE) CXXFLAGS=@$(CXX_RESPONSEFILE) CLEAN_CC_RESPONSEFILE=rm -f $(CC_RESPONSEFILE); From 04834a93165482a28257bac282543e3583658622 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 1 Sep 2026 13:48:47 -0400 Subject: [PATCH 686/702] follow-up: Makefile.top was left out of previous commit --- sys/unix/Makefile.top | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 1dba21622..6cb097348 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -278,7 +278,7 @@ check-dlb: options dlb: ( cd util ; $(MAKE) dlb ) - ( cd dat ; LC_ALL=C ; ../util/dlb cf nhdat $(DATDLB) ) + ( cd dat ; $(MAKE) DATDLB="$(DATDLB)" nhdat ) wasm: ( cd src ; $(MAKE) CROSS_TO_WASM=1 ../targets/wasm/nethack.js ) From 8695c4959cd2089c06d2e28b7ee386561661f3b0 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 5 Sep 2026 15:09:45 +0300 Subject: [PATCH 687/702] Add some wishing aliases Things people playing on NAO have wished for which should give a correct item --- doc/fixes5-0-1.txt | 2 ++ src/objnam.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 3ae31483f..05606c5d1 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -88,6 +88,8 @@ upon return to a level, catch up on remaining nutrition value by the same after polymorph or revival from corpse, monsters were not interacting with the terrain until that monster's next move fix undead corpses (zombies, etc.) now being edible +alias rings of constitution, strength, and damage, spellbook/scroll of + identification Platform- and/or Interface-Specific Fixes diff --git a/src/objnam.c b/src/objnam.c index 35bb6bc7d..3405a6b68 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -3424,6 +3424,8 @@ static const struct alt_spellings { { "silver shield", SHIELD_OF_REFLECTION }, { "potion of sleep", POT_SLEEPING }, { "scroll of recharging", SCR_CHARGING }, + { "scroll of identification", SCR_IDENTIFY }, + { "spellbook of identification", SPE_IDENTIFY }, { "recharging", SCR_CHARGING }, { "stone", ROCK }, { "camera", EXPENSIVE_CAMERA }, @@ -3445,6 +3447,9 @@ static const struct alt_spellings { { "grapple", GRAPPLING_HOOK }, { "protection from shape shifters", RIN_PROTECTION_FROM_SHAPE_CHAN }, { "accuracy", RIN_INCREASE_ACCURACY }, + { "ring of constitution", RIN_GAIN_CONSTITUTION }, + { "ring of strength", RIN_GAIN_STRENGTH }, + { "ring of damage", RIN_INCREASE_DAMAGE }, /* if we ever add other sizes, move this to o_ranges[] with "bag" */ { "box", LARGE_BOX }, /* normally we wouldn't have to worry about unnecessary , but From 50b868f67a2c62af044b1eeac338c39113a9989a Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 6 Sep 2026 13:52:20 -0400 Subject: [PATCH 688/702] remove obsolete VISION_TABLES reference VISION_TABLES removed as part of commit 3ffd330c31ecbec0356237262ad9c38136cca311. --- src/mdlib.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/mdlib.c b/src/mdlib.c index 9599ad8a0..2668b856c 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -588,9 +588,6 @@ static const char *const build_opts[] = { #ifdef PREFIXES_IN_USE "variable playground", #endif -#ifdef VISION_TABLES - "vision tables", -#endif #ifdef SYSCF "system configuration at run-time", #endif From 0d64c3f1fd878e0a5f82c1fe5afd0689f7c69510 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 8 Sep 2026 09:21:29 -0400 Subject: [PATCH 689/702] attempt to fix a reported regression in consoletty.c --- sys/windows/consoletty.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index 93dd8a966..62b5cf28a 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -162,6 +162,8 @@ extern void (*ibmgraphics_mode_callback)(void); /* symbols.c */ extern void (*utf8graphics_mode_callback)(void); /* symbols.c */ #endif /* VIRTUAL_TERMINAL_SEQUENCES */ +static boolean OnWindows95_98_Me(void); + static void init_custom_colors(void); static void free_custom_colors(void); @@ -892,6 +894,12 @@ void buffer_write(cell_t * buffer, cell_t * cell, COORD pos) back_buffer_flip(); } +static boolean +OnWindows95_98_Me(void) +{ + return ((GetVersion() & 0x80000000) != 0); +} + /* * Called after returning from ! or ^Z */ @@ -2525,7 +2533,8 @@ void nethack_enter_consoletty(void) buffer_fill_to_end(console.back_buffer, &clear_cell, 0, 0); /* determine whether OS version has unicode support */ - console.has_unicode = (IsWindows8OrGreater()); + /* console.has_unicode = (IsWindows8OrGreater()); */ + console.has_unicode = !OnWindows95_98_Me(); #ifdef VIRTUAL_TERMINAL_SEQUENCES /* store the original code page*/ From 2c9600713ddc7ae54652325b9523478cdb62b0fe Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 9 Sep 2026 11:17:42 -0400 Subject: [PATCH 690/702] X11: several bug fixes pr #1668 by chasonr --- doc/fixes5-0-1.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 05606c5d1..19b4ecb43 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -267,6 +267,11 @@ X11: implement all text attributes for menus X11: fix crash when loading a nonexistent font X11: use xft to render fonts X11: support tab-separated menu columns +X11: Remove the limit on the number of widgets managed in winlabel.c; it was + possible, though difficult, to exceed the limit; tabify the + #wizcustom menu and fix X11's handling of that menu; correctly + display tabs produced by the unpaid inventory command + (pr #1668 by chasonr) Unix: don't complain about MAXPLAYERS with unknown command line param From 05d2e88950bc2187e59a93222e475c9d9d719ce7 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 9 Sep 2026 11:21:30 -0400 Subject: [PATCH 691/702] style uppercase tidbit --- doc/fixes5-0-1.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 19b4ecb43..7deb9c404 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -267,7 +267,7 @@ X11: implement all text attributes for menus X11: fix crash when loading a nonexistent font X11: use xft to render fonts X11: support tab-separated menu columns -X11: Remove the limit on the number of widgets managed in winlabel.c; it was +X11: remove the limit on the number of widgets managed in winlabel.c; it was possible, though difficult, to exceed the limit; tabify the #wizcustom menu and fix X11's handling of that menu; correctly display tabs produced by the unpaid inventory command From 2d3aa590652c18f8eddfa21aee983371590343ff Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 9 Sep 2026 11:25:38 -0400 Subject: [PATCH 692/702] X11: support BMP, GIF and PNG tiles pr #1666 "This plugs into the same code that provides support for BMP and GIF tiles for MS-DOS, and also populates the stub to read PNG tiles. PNG is a compile-time option, and depends on libpng." pull request #1666 by chasonr --- doc/fixes5-0-1.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 7deb9c404..e324c0502 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -267,6 +267,7 @@ X11: implement all text attributes for menus X11: fix crash when loading a nonexistent font X11: use xft to render fonts X11: support tab-separated menu columns +X11: support BMP, GIF and PNG tiles (pr #1666 by chasonr) X11: remove the limit on the number of widgets managed in winlabel.c; it was possible, though difficult, to exceed the limit; tabify the #wizcustom menu and fix X11's handling of that menu; correctly From 3a496219f3140267ab7e90dfa260a7e78641d71e Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 9 Sep 2026 19:55:33 -0400 Subject: [PATCH 693/702] macOS generated tile build fix --- sys/unix/hints/macOS.500 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/unix/hints/macOS.500 b/sys/unix/hints/macOS.500 index 3fd074841..b7ee27abb 100755 --- a/sys/unix/hints/macOS.500 +++ b/sys/unix/hints/macOS.500 @@ -282,7 +282,9 @@ USE_XPM=1 USE_PNG=1 WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm +ifndef CROSSCOMPILE GENTILEOFILE = $(SRCDIR)/tile.o +endif # -x: if built without dodlb, some versions of mkfontdir think *.lev are fonts POSTINSTALL += bdftopcf win/X11/nh10.bdf > $(HACKDIR)/nh10.pcf; ( cd $(HACKDIR); mkfontdir -x .lev ); # separate from CFLAGS so that we don't pass it to every file @@ -310,6 +312,9 @@ endif # WANT_WIN_X11 ifdef WANT_WIN_QT LINK = $(CXX) ifdef WANT_WIN_QT5 +ifndef CROSSCOMPILE +GENTILEOFILE = $(SRCDIR)/tile.o +endif # Qt5 requires C++11 QTCXXFLAGS += $(sort $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig \ pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --cflags)) From 017fbcf5103c8cf049b26c21435826b79368227c Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 9 Sep 2026 20:00:58 -0400 Subject: [PATCH 694/702] follow-up --- sys/unix/hints/macOS.500 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/unix/hints/macOS.500 b/sys/unix/hints/macOS.500 index b7ee27abb..049666ab7 100755 --- a/sys/unix/hints/macOS.500 +++ b/sys/unix/hints/macOS.500 @@ -311,10 +311,10 @@ endif # WANT_WIN_X11 ifdef WANT_WIN_QT LINK = $(CXX) -ifdef WANT_WIN_QT5 ifndef CROSSCOMPILE GENTILEOFILE = $(SRCDIR)/tile.o endif +ifdef WANT_WIN_QT5 # Qt5 requires C++11 QTCXXFLAGS += $(sort $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig \ pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --cflags)) From fc75a55d863b23f80ae8881303e5afe80d13a29c Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 9 Sep 2026 21:15:43 -0400 Subject: [PATCH 695/702] fix "killed by a died" This is a follow-up to commit 9114a33 that was intended to fix a "killed by a died" situation. In that commit, the generic case could be encountered with variable str set to "explosion", but that never got copied to svk.killer.name, and svk.killer.name remained set to "died" during testing. svk.killer.format = KILLED_BY_AN; is done whether the generic case, or not. Close #1676 --- src/explode.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/explode.c b/src/explode.c index e2e5fa90b..0a8eec530 100644 --- a/src/explode.c +++ b/src/explode.c @@ -643,10 +643,14 @@ explode( rehumanize(); } else { if (olet == MON_EXPLODE) { - if (generic) /* explosion was unseen; str=="explosion", */ - ; /* svk.killer.name=="gas spore's explosion". */ - else if (str != svk.killer.name && str != hallu_buf) + if (generic) { + /* explosion was unseen; str=="explosion", */ + /* svk.killer.name=="gas spore's explosion" */ + if (!strcmp(str, "explosion")) + Strcpy(svk.killer.name, str); + } else if (str != svk.killer.name && str != hallu_buf) { Strcpy(svk.killer.name, str); + } svk.killer.format = KILLED_BY_AN; } else if (olet == TRAP_EXPLODE) { svk.killer.format = NO_KILLER_PREFIX; From 02dda03f56d526eb7ef98938098114177ebb17b2 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 10 Sep 2026 08:09:09 -0400 Subject: [PATCH 696/702] update tested versions of Visual Studio 2026-09-10 --- sys/windows/Makefile.nmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index dbf49775e..a49ba992f 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -8,8 +8,8 @@ # MS Visual Studio Visual C++ compiler # # Visual Studio Compilers Tested: -# - Microsoft Visual Studio Community 2022 v 17.14.38 -# - Microsoft Visual Studio Community 2026 v 18.9.0 +# - Microsoft Visual Studio Community 2022 v 17.14.40 +# - Microsoft Visual Studio Community 2026 v 18.10.0 # #============================================================================== # This is used for building two distinct executables of NetHack: @@ -1204,7 +1204,7 @@ rc=Rc.exe # # Recently tested versions: TESTEDVS2022 = 14.44.35228.0 -TESTEDVS2026 = 14.51.36256.0 +TESTEDVS2026 = 14.51.36257.0 VS20261ST = 1450000000 VS2026CUR = $(TESTEDVS2026:.=) From 1106456195eb149edc5e519d000f63f75a24bde3 Mon Sep 17 00:00:00 2001 From: Crissman Loomis Date: Fri, 11 Sep 2026 09:37:45 -0400 Subject: [PATCH 697/702] Preserve inactive level clocks on save pr #1677 Close #1677 --- doc/fixes5-0-1.txt | 2 ++ src/save.c | 20 ++++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index e324c0502..7dd6d9c30 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -338,3 +338,5 @@ switch to using LUA_VERSION_NUM instead of LUA_VERSION_RELEASE_NUM for Lua version checking include a set of decals (petmark and pilemark) in win/share/decals.txt and adjust tile processing to include it +preserve inactive level timestamps across saving and restoring so that + monster catch-up, including tameness loss, retains time spent away diff --git a/src/save.c b/src/save.c index 7eb7f5eb6..dea871d54 100644 --- a/src/save.c +++ b/src/save.c @@ -31,7 +31,7 @@ staticfn void save_gamelog(NHFILE *); staticfn void savegamestate(NHFILE *); staticfn void savelev_core(NHFILE *, xint8); staticfn void save_msghistory(NHFILE *); -staticfn void save_adjust_levelflags(void); +staticfn void save_adjust_levelflags(long); #if defined(HANGUPHANDLING) #define HUP if (!program_state.done_hup) #else @@ -484,6 +484,7 @@ savelev_core(NHFILE *nhfp, xint8 lev) short tlev; #endif int i, c, r; + long timestamp; coord *tmpc; program_state.saving++; /* even if current mode is FREEING */ @@ -541,14 +542,17 @@ savelev_core(NHFILE *nhfp, xint8 lev) Sfo_schar(nhfp, &svl.lastseentyp[c][r], "lastseentyp"); } } - /* svm.moves will actually be read back into svo.omoves on restore */ - Sfo_long(nhfp, &svm.moves, "lev-timestmp"); + /* preserve idle time when copying levels; match getlev()'s + monster catch-up guard */ + timestamp = (!u.uz.dlevel || program_state.restoring == REST_LEVELS) + ? svo.omoves : svm.moves; + Sfo_long(nhfp, ×tamp, "lev-timestmp"); save_stairs(nhfp); Sfo_dest_area(nhfp, &svu.updest, "lev-updest"); Sfo_dest_area(nhfp, &svd.dndest, "lev-dndest"); - save_adjust_levelflags(); + save_adjust_levelflags(timestamp); Sfo_levelflags(nhfp, &svl.level.flags, "lev-level_flags"); - rest_adjust_levelflags(0L); + rest_adjust_levelflags(svm.moves - timestamp); Sfo_int(nhfp, &svd.doors_alloc, "lev-doors_alloc"); /* don't rely on underlying write() behavior to write @@ -596,10 +600,10 @@ savelev_core(NHFILE *nhfp, xint8 lev) } void -save_adjust_levelflags(void) +save_adjust_levelflags(long timestamp) { - /* adjust any timestamps */ - moves_to_relative_time(&svl.level.flags.stasis_until); + /* use the same time base as lev-timestmp */ + svl.level.flags.stasis_until -= timestamp; } staticfn void From 55769ca9f03e959f7ddfaec224690fb062f48da1 Mon Sep 17 00:00:00 2001 From: Crissman Loomis Date: Fri, 11 Sep 2026 10:02:18 -0400 Subject: [PATCH 698/702] fix Qt use-after-free reading the player name Closes #1673 --- win/Qt/qt_plsel.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/win/Qt/qt_plsel.cpp b/win/Qt/qt_plsel.cpp index a280f07fc..baaf49f6f 100644 --- a/win/Qt/qt_plsel.cpp +++ b/win/Qt/qt_plsel.cpp @@ -559,7 +559,10 @@ void NetHackQtPlayerSelector::plnamePlayVsQuit() // the line edit widget for the name field has received input void NetHackQtPlayerSelector::selectName(const QString& n) { - const char *name_str = n.toLatin1().constData(); + // the QByteArray has to outlive name_str; calling constData() on + // the temporary returned by toLatin1() leaves it dangling + QByteArray name_bytes = n.toLatin1(); + const char *name_str = name_bytes.constData(); // skip any leading spaces // (it would be better to set up a validator that rejects leading spaces) while (*name_str == ' ') From aec687db2c141282d08dee6dfe76c1cdd87ea42a Mon Sep 17 00:00:00 2001 From: Crissman Loomis Date: Fri, 11 Sep 2026 10:06:18 -0400 Subject: [PATCH 699/702] Qt: use idClicked(); buttonClicked(int) is gone in Qt 6 Closes #1670 --- win/Qt/qt_plsel.cpp | 10 ++++++++++ win/Qt/qt_yndlg.cpp | 8 +++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/win/Qt/qt_plsel.cpp b/win/Qt/qt_plsel.cpp index baaf49f6f..b646d347b 100644 --- a/win/Qt/qt_plsel.cpp +++ b/win/Qt/qt_plsel.cpp @@ -358,8 +358,13 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector( genderbox->layout()->addWidget(gender[i]); gendergroup->addButton(gender[i], i); } +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) + connect(gendergroup, SIGNAL(idClicked(int)), + this, SLOT(selectGender(int))); +#else connect(gendergroup, SIGNAL(buttonClicked(int)), this, SLOT(selectGender(int))); +#endif QLabel *alignlabel = new QLabel("Alignment"); alignbox->layout()->addWidget(alignlabel); @@ -369,8 +374,13 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector( alignbox->layout()->addWidget(alignment[i]); aligngroup->addButton(alignment[i], i); } +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) + connect(aligngroup, SIGNAL(idClicked(int)), + this, SLOT(selectAlignment(int))); +#else connect(aligngroup, SIGNAL(buttonClicked(int)), this, SLOT(selectAlignment(int))); +#endif l->addWidget(rand_btn, 4, 2); connect(rand_btn, SIGNAL(clicked()), this, SLOT(Randomize())); diff --git a/win/Qt/qt_yndlg.cpp b/win/Qt/qt_yndlg.cpp index 57e2f212f..a7dea6b68 100644 --- a/win/Qt/qt_yndlg.cpp +++ b/win/Qt/qt_yndlg.cpp @@ -292,7 +292,13 @@ char NetHackQtYnDialog::Exec() bgroup->addButton(button, i); } - connect(bgroup, SIGNAL(buttonClicked(int)), this, SLOT(doneItem(int))); +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) + connect(bgroup, SIGNAL(idClicked(int)), this, + SLOT(doneItem(int))); +#else + connect(bgroup, SIGNAL(buttonClicked(int)), this, + SLOT(doneItem(int))); +#endif QLabel *lb = 0; if (allow_count) { From c63ee6ac7ef78639db31660c52aaa2e60cb6afd0 Mon Sep 17 00:00:00 2001 From: Crissman Loomis Date: Mon, 14 Sep 2026 15:57:14 +0900 Subject: [PATCH 700/702] Account for pet hunger while away from a level --- doc/fixes5-0-1.txt | 2 ++ src/restore.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt index 7dd6d9c30..e20471335 100644 --- a/doc/fixes5-0-1.txt +++ b/doc/fixes5-0-1.txt @@ -90,6 +90,8 @@ after polymorph or revival from corpse, monsters were not interacting with fix undead corpses (zombies, etc.) now being edible alias rings of constitution, strength, and damage, spellbook/scroll of identification +pets left on another level no longer have their hunger postponed by the + time spent away Platform- and/or Interface-Specific Fixes diff --git a/src/restore.c b/src/restore.c index cd6e86d0c..d5e7cca19 100644 --- a/src/restore.c +++ b/src/restore.c @@ -1246,6 +1246,9 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) : peace_minded(mtmp->data); set_malign(mtmp); } else if (elapsed > 0L) { + /* restmon() based hunger on now; account for time away */ + if (has_edog(mtmp)) + EDOG(mtmp)->hungrytime -= elapsed; mon_catchup_elapsed_time(mtmp, elapsed); } /* update shape-changers in case protection against From f11a4b168bd934bd4a285257bd5704ab59ef89ac Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 19 Sep 2026 14:53:45 +0300 Subject: [PATCH 701/702] More strict checking of dishonourable attacks Move the caitiff check into thitmonst, the code responsible for object hitting a monster, intead of checking the caitiff in multiple places before calling that. Previously there were some cases where caitiff was not checked, eg. samurai could fire arrows at a peaceful monster without the dishonourable behaviour check. Now you will get the check even if you miss with the projectile. This may need to be adjusted for throwing beneficial potions at monsters... --- doc/fixes5-0-0.txt | 1 + src/apply.c | 2 -- src/dothrow.c | 2 ++ 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/fixes5-0-0.txt b/doc/fixes5-0-0.txt index cba31fa8f..d96ae4910 100644 --- a/doc/fixes5-0-0.txt +++ b/doc/fixes5-0-0.txt @@ -1604,6 +1604,7 @@ when starting a new game as a monk, newsym(0,0) was being called (adjabil -> on the map yet) incorporate a fix to prevent segfault due to rolling boulder trap wands of digging generate less often lategame +more strict checking of dishonourable attacks Fixes to 5.0.0-x General Problems Exposed Via git Repository diff --git a/src/apply.c b/src/apply.c index 02bac8669..5c7ac71ac 100644 --- a/src/apply.c +++ b/src/apply.c @@ -3508,7 +3508,6 @@ use_pole(struct obj *obj, boolean autohit) return ECMD_FAIL; } - check_caitiff(mtmp); gn.notonhead = (gb.bhitpos.x != mtmp->mx || gb.bhitpos.y != mtmp->my); /* Snickersnee allows one free hit from a distance per turn */ @@ -3847,7 +3846,6 @@ use_grapple(struct obj *obj) flags.confirm = FALSE; (void) attack_checks(mtmp, uwep); flags.confirm = save_confirm; - check_caitiff(mtmp); (void) thitmonst(mtmp, uwep); return ECMD_TIME; } diff --git a/src/dothrow.c b/src/dothrow.c index 5c8997bcf..9a33e7a1b 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -2207,6 +2207,8 @@ thitmonst( dieroll = rnd(20); + check_caitiff(mon); + if (obj->oclass == WEAPON_CLASS || is_weptool(obj) || obj->oclass == GEM_CLASS) { if (hmode == HMON_KICKED) { From c94fd5225beef48143244bfb7bc42682aad58741 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 20 Sep 2026 17:30:04 +0300 Subject: [PATCH 702/702] Vault guard shouldn't be heard from too far away When you were asked for a name and teleported out of the vault without any gold on you, the vault guard says "Well, begone" - which could be heard from anywhere on the level. Limit that verbalization to 10 tiles away. --- doc/fixes5-0-0.txt | 1 + src/vault.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/fixes5-0-0.txt b/doc/fixes5-0-0.txt index d96ae4910..7171ab1f6 100644 --- a/doc/fixes5-0-0.txt +++ b/doc/fixes5-0-0.txt @@ -1605,6 +1605,7 @@ when starting a new game as a monk, newsym(0,0) was being called (adjabil -> incorporate a fix to prevent segfault due to rolling boulder trap wands of digging generate less often lategame more strict checking of dishonourable attacks +vault guard verbalization shouldn't be heard from too far away Fixes to 5.0.0-x General Problems Exposed Via git Repository diff --git a/src/vault.c b/src/vault.c index 1f2d97a53..597c4b267 100644 --- a/src/vault.c +++ b/src/vault.c @@ -1000,7 +1000,7 @@ gd_move(struct monst *grd) gd_letknow(grd); return -1; } else { - if (!Deaf) { + if (!Deaf && mdistu(grd) <= 10*10) { SetVoice(grd, 0, 80, 0); verbalize("Well, begone."); }